diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/llvm-objdump/ELFDump.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/llvm-objdump/ELFDump.cpp')
| -rw-r--r-- | gnu/llvm/tools/llvm-objdump/ELFDump.cpp | 91 |
1 files changed, 90 insertions, 1 deletions
diff --git a/gnu/llvm/tools/llvm-objdump/ELFDump.cpp b/gnu/llvm/tools/llvm-objdump/ELFDump.cpp index 7f5fe5a9d3b..f4d36656a6c 100644 --- a/gnu/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/gnu/llvm/tools/llvm-objdump/ELFDump.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief This file implements the ELF-specific dumper for llvm-objdump. +/// This file implements the ELF-specific dumper for llvm-objdump. /// //===----------------------------------------------------------------------===// @@ -21,6 +21,77 @@ using namespace llvm; using namespace llvm::object; +template <class ELFT> +Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> *Elf) { + typedef ELFFile<ELFT> ELFO; + + auto DynamicEntriesOrError = Elf->dynamicEntries(); + if (!DynamicEntriesOrError) + return DynamicEntriesOrError.takeError(); + + for (const typename ELFO::Elf_Dyn &Dyn : *DynamicEntriesOrError) { + if (Dyn.d_tag == ELF::DT_STRTAB) { + auto MappedAddrOrError = Elf->toMappedAddr(Dyn.getPtr()); + if (!MappedAddrOrError) + consumeError(MappedAddrOrError.takeError()); + return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError)); + } + } + + // If the dynamic segment is not present, we fall back on the sections. + auto SectionsOrError = Elf->sections(); + if (!SectionsOrError) + return SectionsOrError.takeError(); + + for (const typename ELFO::Elf_Shdr &Sec : *SectionsOrError) { + if (Sec.sh_type == ELF::SHT_DYNSYM) + return Elf->getStringTableForSymtab(Sec); + } + + return createError("dynamic string table not found"); +} + +template <class ELFT> +void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) { + auto ProgramHeaderOrError = Elf->program_headers(); + if (!ProgramHeaderOrError) + report_error(Filename, ProgramHeaderOrError.takeError()); + + auto DynamicEntriesOrError = Elf->dynamicEntries(); + if (!DynamicEntriesOrError) + report_error(Filename, DynamicEntriesOrError.takeError()); + + outs() << "Dynamic Section:\n"; + for (const auto &Dyn : *DynamicEntriesOrError) { + if (Dyn.d_tag == ELF::DT_NULL) + continue; + + StringRef Str = StringRef(Elf->getDynamicTagAsString(Dyn.d_tag)); + + if (Str.empty()) { + std::string HexStr = utohexstr(static_cast<uint64_t>(Dyn.d_tag), true); + outs() << format(" 0x%-19s", HexStr.c_str()); + } else { + // We use "-21" in order to match GNU objdump's output. + outs() << format(" %-21s", Str.data()); + } + + const char *Fmt = + ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n"; + if (Dyn.d_tag == ELF::DT_NEEDED) { + Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf); + if (StrTabOrErr) { + const char *Data = StrTabOrErr.get().data(); + outs() << (Data + Dyn.d_un.d_val) << "\n"; + continue; + } + warn(errorToErrorCode(StrTabOrErr.takeError()).message()); + consumeError(StrTabOrErr.takeError()); + } + outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val); + } +} + template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) { typedef ELFFile<ELFT> ELFO; outs() << "Program Header:\n"; @@ -103,3 +174,21 @@ void llvm::printELFFileHeader(const object::ObjectFile *Obj) { if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) printProgramHeaders(ELFObj->getELFFile()); } + +void llvm::printELFDynamicSection(const object::ObjectFile *Obj) { + // Little-endian 32-bit + if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) + printDynamicSection(ELFObj->getELFFile(), Obj->getFileName()); + + // Big-endian 32-bit + if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) + printDynamicSection(ELFObj->getELFFile(), Obj->getFileName()); + + // Little-endian 64-bit + if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) + printDynamicSection(ELFObj->getELFFile(), Obj->getFileName()); + + // Big-endian 64-bit + if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) + printDynamicSection(ELFObj->getELFFile(), Obj->getFileName()); +} |
