summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objdump
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objdump')
-rw-r--r--llvm/tools/llvm-objdump/ELFDump.cpp29
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp45
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h3
3 files changed, 68 insertions, 9 deletions
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index f0618fc8571..7157469d13f 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -133,6 +133,35 @@ llvm::getELFRelocationValueString(const ELFObjectFileBase *Obj,
}
template <class ELFT>
+static uint64_t getSectionLMA(const ELFFile<ELFT> *Obj,
+ const object::ELFSectionRef &Sec) {
+ auto PhdrRangeOrErr = Obj->program_headers();
+ if (!PhdrRangeOrErr)
+ report_fatal_error(errorToErrorCode(PhdrRangeOrErr.takeError()).message());
+
+ // Search for a PT_LOAD segment containing the requested section. Use this
+ // segment's p_addr to calculate the section's LMA.
+ for (const typename ELFFile<ELFT>::Elf_Phdr &Phdr : *PhdrRangeOrErr)
+ if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_vaddr <= Sec.getAddress()) &&
+ (Phdr.p_vaddr + Phdr.p_memsz > Sec.getAddress()))
+ return Sec.getAddress() - Phdr.p_vaddr + Phdr.p_paddr;
+
+ // Return section's VMA if it isn't in a PT_LOAD segment.
+ return Sec.getAddress();
+}
+
+uint64_t llvm::getELFSectionLMA(const object::ELFSectionRef &Sec) {
+ if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Sec.getObject()))
+ return getSectionLMA(ELFObj->getELFFile(), Sec);
+ else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Sec.getObject()))
+ return getSectionLMA(ELFObj->getELFFile(), Sec);
+ else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Sec.getObject()))
+ return getSectionLMA(ELFObj->getELFFile(), Sec);
+ const auto *ELFObj = cast<ELF64BEObjectFile>(Sec.getObject());
+ return getSectionLMA(ELFObj->getELFFile(), Sec);
+}
+
+template <class ELFT>
void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) {
auto ProgramHeaderOrError = Elf->program_headers();
if (!ProgramHeaderOrError)
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index c84d8b65021..1ba0cfc3928 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -185,6 +185,10 @@ static cl::alias SectionHeadersShorter("h",
cl::NotHidden,
cl::aliasopt(SectionHeaders));
+static cl::opt<bool>
+ ShowLMA("show-lma",
+ cl::desc("Display LMA column when dumping ELF section headers"));
+
cl::list<std::string>
llvm::FilterSections("section", cl::desc("Operate on the specified sections only. "
"With -macho dump segment,section"));
@@ -1517,25 +1521,48 @@ void llvm::printDynamicRelocations(const ObjectFile *Obj) {
}
}
+// Returns true if we need to show LMA column when dumping section headers. We
+// show it only when the platform is ELF and either we have at least one section
+// whose VMA and LMA are different and/or when --show-lma flag is used.
+static bool shouldDisplayLMA(const ObjectFile *Obj) {
+ if (!Obj->isELF())
+ return false;
+ for (const SectionRef &S : ToolSectionFilter(*Obj))
+ if (S.getAddress() != getELFSectionLMA(S))
+ return true;
+ return ShowLMA;
+}
+
void llvm::printSectionHeaders(const ObjectFile *Obj) {
- outs() << "Sections:\n"
- "Idx Name Size Address Type\n";
+ bool HasLMAColumn = shouldDisplayLMA(Obj);
+ if (HasLMAColumn)
+ outs() << "Sections:\n"
+ "Idx Name Size VMA LMA "
+ "Type\n";
+ else
+ outs() << "Sections:\n"
+ "Idx Name Size VMA Type\n";
+
for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
StringRef Name;
error(Section.getName(Name));
- uint64_t Address = Section.getAddress();
- if (shouldAdjustVA(Section))
- Address += AdjustVMA;
-
+ uint64_t VMA = Section.getAddress();
uint64_t Size = Section.getSize();
bool Text = Section.isText();
bool Data = Section.isData();
bool BSS = Section.isBSS();
std::string Type = (std::string(Text ? "TEXT " : "") +
(Data ? "DATA " : "") + (BSS ? "BSS" : ""));
- outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
- (unsigned)Section.getIndex(), Name.str().c_str(), Size,
- Address, Type.c_str());
+
+ if (HasLMAColumn)
+ outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %016" PRIx64
+ " %s\n",
+ (unsigned)Section.getIndex(), Name.str().c_str(), Size,
+ VMA, getELFSectionLMA(Section), Type.c_str());
+ else
+ outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
+ (unsigned)Section.getIndex(), Name.str().c_str(), Size,
+ VMA, Type.c_str());
}
outs() << "\n";
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 03c72b74dbb..e559b72aeb7 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -21,6 +21,7 @@ namespace object {
class COFFObjectFile;
class COFFImportFile;
class ELFObjectFileBase;
+class ELFSectionRef;
class MachOObjectFile;
class MachOUniversalBinary;
class ObjectFile;
@@ -137,6 +138,8 @@ getMachORelocationValueString(const object::MachOObjectFile *Obj,
const object::RelocationRef &RelRef,
llvm::SmallVectorImpl<char> &Result);
+uint64_t getELFSectionLMA(const object::ELFSectionRef& Sec);
+
void error(std::error_code ec);
bool isRelocAddressLess(object::RelocationRef A, object::RelocationRef B);
void parseInputMachO(StringRef Filename);
OpenPOWER on IntegriCloud