diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-readobj')
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/COFFDumper.cpp | 126 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/ELFDumper.cpp | 427 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/MachODumper.cpp | 75 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp | 7 |
4 files changed, 353 insertions, 282 deletions
diff --git a/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp b/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp index 94aafa7..2f309e3 100644 --- a/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -60,6 +60,8 @@ private: void printRelocation(section_iterator SecI, relocation_iterator RelI); + void printDataDirectory(uint32_t Index, const std::string &FieldName); + void printX64UnwindInfo(); void printRuntimeFunction( @@ -201,8 +203,7 @@ static error_code resolveSymbol(const std::vector<RelocationRef> &Rels, return EC; if (Ofs == Offset) { - if (error_code EC = RelI->getSymbol(Sym)) - return EC; + Sym = *RelI->getSymbol(); return readobj_error::success; } } @@ -263,6 +264,31 @@ static const EnumEntry<COFF::Characteristics> ImageFileCharacteristics[] = { LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI ) }; +static const EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = { + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_UNKNOWN ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_NATIVE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_GUI ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CUI ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_POSIX_CUI ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_APPLICATION ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_ROM ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_XBOX ), +}; + +static const EnumEntry<COFF::DLLCharacteristics> PEDLLCharacteristics[] = { + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_SEH ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_BIND ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE), +}; + static const EnumEntry<COFF::SectionCharacteristics> ImageSectionCharacteristics[] = { LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD ), @@ -455,15 +481,15 @@ static std::string formatSymbol(const std::vector<RelocationRef> &Rels, StringRef Sym; if (resolveSymbolName(Rels, Offset, Sym)) { - Str << format(" (0x%X)", Offset); + Str << format(" (0x%" PRIX64 ")", Offset); return Str.str(); } Str << Sym; if (Disp > 0) { - Str << format(" +0x%X (0x%X)", Disp, Offset); + Str << format(" +0x%X (0x%" PRIX64 ")", Disp, Offset); } else { - Str << format(" (0x%X)", Offset); + Str << format(" (0x%" PRIX64 ")", Offset); } return Str.str(); @@ -536,27 +562,90 @@ void COFFDumper::cacheRelocations() { } } +void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName) { + const data_directory *Data; + if (Obj->getDataDirectory(Index, Data)) + return; + W.printHex(FieldName + "RVA", Data->RelativeVirtualAddress); + W.printHex(FieldName + "Size", Data->Size); +} + void COFFDumper::printFileHeaders() { - const coff_file_header *Header = 0; - if (error(Obj->getHeader(Header))) + // Print COFF header + const coff_file_header *COFFHeader = 0; + if (error(Obj->getCOFFHeader(COFFHeader))) return; - time_t TDS = Header->TimeDateStamp; + time_t TDS = COFFHeader->TimeDateStamp; char FormattedTime[20] = { }; strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS)); { DictScope D(W, "ImageFileHeader"); - W.printEnum ("Machine", Header->Machine, + W.printEnum ("Machine", COFFHeader->Machine, makeArrayRef(ImageFileMachineType)); - W.printNumber("SectionCount", Header->NumberOfSections); - W.printHex ("TimeDateStamp", FormattedTime, Header->TimeDateStamp); - W.printHex ("PointerToSymbolTable", Header->PointerToSymbolTable); - W.printNumber("SymbolCount", Header->NumberOfSymbols); - W.printNumber("OptionalHeaderSize", Header->SizeOfOptionalHeader); - W.printFlags ("Characteristics", Header->Characteristics, + W.printNumber("SectionCount", COFFHeader->NumberOfSections); + W.printHex ("TimeDateStamp", FormattedTime, COFFHeader->TimeDateStamp); + W.printHex ("PointerToSymbolTable", COFFHeader->PointerToSymbolTable); + W.printNumber("SymbolCount", COFFHeader->NumberOfSymbols); + W.printNumber("OptionalHeaderSize", COFFHeader->SizeOfOptionalHeader); + W.printFlags ("Characteristics", COFFHeader->Characteristics, makeArrayRef(ImageFileCharacteristics)); } + + // Print PE header. This header does not exist if this is an object file and + // not an executable. + const pe32_header *PEHeader = 0; + if (error(Obj->getPE32Header(PEHeader))) + return; + + if (PEHeader) { + DictScope D(W, "ImageOptionalHeader"); + W.printNumber("MajorLinkerVersion", PEHeader->MajorLinkerVersion); + W.printNumber("MinorLinkerVersion", PEHeader->MinorLinkerVersion); + W.printNumber("SizeOfCode", PEHeader->SizeOfCode); + W.printNumber("SizeOfInitializedData", PEHeader->SizeOfInitializedData); + W.printNumber("SizeOfUninitializedData", PEHeader->SizeOfUninitializedData); + W.printHex ("AddressOfEntryPoint", PEHeader->AddressOfEntryPoint); + W.printHex ("BaseOfCode", PEHeader->BaseOfCode); + W.printHex ("BaseOfData", PEHeader->BaseOfData); + W.printHex ("ImageBase", PEHeader->ImageBase); + W.printNumber("SectionAlignment", PEHeader->SectionAlignment); + W.printNumber("FileAlignment", PEHeader->FileAlignment); + W.printNumber("MajorOperatingSystemVersion", + PEHeader->MajorOperatingSystemVersion); + W.printNumber("MinorOperatingSystemVersion", + PEHeader->MinorOperatingSystemVersion); + W.printNumber("MajorImageVersion", PEHeader->MajorImageVersion); + W.printNumber("MinorImageVersion", PEHeader->MinorImageVersion); + W.printNumber("MajorSubsystemVersion", PEHeader->MajorSubsystemVersion); + W.printNumber("MinorSubsystemVersion", PEHeader->MinorSubsystemVersion); + W.printNumber("SizeOfImage", PEHeader->SizeOfImage); + W.printNumber("SizeOfHeaders", PEHeader->SizeOfHeaders); + W.printEnum ("Subsystem", PEHeader->Subsystem, + makeArrayRef(PEWindowsSubsystem)); + W.printFlags ("Subsystem", PEHeader->DLLCharacteristics, + makeArrayRef(PEDLLCharacteristics)); + W.printNumber("SizeOfStackReserve", PEHeader->SizeOfStackReserve); + W.printNumber("SizeOfStackCommit", PEHeader->SizeOfStackCommit); + W.printNumber("SizeOfHeapReserve", PEHeader->SizeOfHeapReserve); + W.printNumber("SizeOfHeapCommit", PEHeader->SizeOfHeapCommit); + W.printNumber("NumberOfRvaAndSize", PEHeader->NumberOfRvaAndSize); + + if (PEHeader->NumberOfRvaAndSize > 0) { + DictScope D(W, "DataDirectory"); + static const char * const directory[] = { + "ExportTable", "ImportTable", "ResourceTable", "ExceptionTable", + "CertificateTable", "BaseRelocationTable", "Debug", "Architecture", + "GlobalPtr", "TLSTable", "LoadConfigTable", "BoundImport", "IAT", + "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved" + }; + + for (uint32_t i = 0; i < PEHeader->NumberOfRvaAndSize; ++i) { + printDataDirectory(i, directory[i]); + } + } + } } void COFFDumper::printSections() { @@ -670,14 +759,13 @@ void COFFDumper::printRelocation(section_iterator SecI, uint64_t Offset; uint64_t RelocType; SmallString<32> RelocName; - SymbolRef Symbol; StringRef SymbolName; StringRef Contents; if (error(RelI->getOffset(Offset))) return; if (error(RelI->getType(RelocType))) return; if (error(RelI->getTypeName(RelocName))) return; - if (error(RelI->getSymbol(Symbol))) return; - if (error(Symbol.getName(SymbolName))) return; + symbol_iterator Symbol = RelI->getSymbol(); + if (error(Symbol->getName(SymbolName))) return; if (error(SecI->getContents(Contents))) return; if (opts::ExpandRelocs) { @@ -836,7 +924,7 @@ void COFFDumper::printSymbol(symbol_iterator SymI) { void COFFDumper::printUnwindInfo() { const coff_file_header *Header; - if (error(Obj->getHeader(Header))) + if (error(Obj->getCOFFHeader(Header))) return; ListScope D(W, "UnwindInformation"); diff --git a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp index ea1b83f..07a9083 100644 --- a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -18,7 +18,7 @@ #include "StreamWriter.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Object/ELF.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" @@ -28,7 +28,6 @@ using namespace llvm; using namespace llvm::object; using namespace ELF; - #define LLVM_READOBJ_ENUM_CASE(ns, enum) \ case ns::enum: return #enum; @@ -37,9 +36,8 @@ namespace { template<typename ELFT> class ELFDumper : public ObjDumper { public: - ELFDumper(const ELFObjectFile<ELFT> *Obj, StreamWriter& Writer) - : ObjDumper(Writer) - , Obj(Obj) { } + ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) + : ObjDumper(Writer), Obj(Obj) {} virtual void printFileHeaders() LLVM_OVERRIDE; virtual void printSections() LLVM_OVERRIDE; @@ -53,65 +51,62 @@ public: virtual void printProgramHeaders() LLVM_OVERRIDE; private: - typedef ELFObjectFile<ELFT> ELFO; + typedef ELFFile<ELFT> ELFO; typedef typename ELFO::Elf_Shdr Elf_Shdr; typedef typename ELFO::Elf_Sym Elf_Sym; - void printSymbol(symbol_iterator SymI, bool IsDynamic = false); + void printSymbol(typename ELFO::Elf_Sym_Iter Symbol); - void printRelocation(section_iterator SecI, relocation_iterator RelI); + void printRelocations(const Elf_Shdr *Sec); + void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel); const ELFO *Obj; }; -} // namespace +template <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) { + if (!Val) { + error(Val); + return Default; + } + return *Val; +} +} // namespace namespace llvm { +template <class ELFT> +static error_code createELFDumper(const ELFFile<ELFT> *Obj, + StreamWriter &Writer, + OwningPtr<ObjDumper> &Result) { + Result.reset(new ELFDumper<ELFT>(Obj, Writer)); + return readobj_error::success; +} + error_code createELFDumper(const object::ObjectFile *Obj, StreamWriter& Writer, OwningPtr<ObjDumper> &Result) { - typedef ELFType<support::little, 4, false> Little32ELF; - typedef ELFType<support::big, 4, false> Big32ELF; - typedef ELFType<support::little, 4, true > Little64ELF; - typedef ELFType<support::big, 8, true > Big64ELF; - - typedef ELFObjectFile<Little32ELF> LittleELF32Obj; - typedef ELFObjectFile<Big32ELF > BigELF32Obj; - typedef ELFObjectFile<Little64ELF> LittleELF64Obj; - typedef ELFObjectFile<Big64ELF > BigELF64Obj; - // Little-endian 32-bit - if (const LittleELF32Obj *ELFObj = dyn_cast<LittleELF32Obj>(Obj)) { - Result.reset(new ELFDumper<Little32ELF>(ELFObj, Writer)); - return readobj_error::success; - } + if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) + return createELFDumper(ELFObj->getELFFile(), Writer, Result); // Big-endian 32-bit - if (const BigELF32Obj *ELFObj = dyn_cast<BigELF32Obj>(Obj)) { - Result.reset(new ELFDumper<Big32ELF>(ELFObj, Writer)); - return readobj_error::success; - } + if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) + return createELFDumper(ELFObj->getELFFile(), Writer, Result); // Little-endian 64-bit - if (const LittleELF64Obj *ELFObj = dyn_cast<LittleELF64Obj>(Obj)) { - Result.reset(new ELFDumper<Little64ELF>(ELFObj, Writer)); - return readobj_error::success; - } + if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) + return createELFDumper(ELFObj->getELFFile(), Writer, Result); // Big-endian 64-bit - if (const BigELF64Obj *ELFObj = dyn_cast<BigELF64Obj>(Obj)) { - Result.reset(new ELFDumper<Big64ELF>(ELFObj, Writer)); - return readobj_error::success; - } + if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) + return createELFDumper(ELFObj->getELFFile(), Writer, Result); return readobj_error::unsupported_obj_file_format; } } // namespace llvm - static const EnumEntry<unsigned> ElfClass[] = { { "None", ELF::ELFCLASSNONE }, { "32-bit", ELF::ELFCLASS32 }, @@ -300,7 +295,6 @@ static const EnumEntry<unsigned> ElfMachineType[] = { LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO ), - LLVM_READOBJ_ENUM_ENT(ELF, EM_MICROBLAZE ), LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA ), LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX ), LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD ), @@ -311,8 +305,7 @@ static const EnumEntry<unsigned> ElfMachineType[] = { LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ), - LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ), - LLVM_READOBJ_ENUM_ENT(ELF, EM_MBLAZE ) + LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ) }; static const EnumEntry<unsigned> ElfSymbolBindings[] = { @@ -334,7 +327,7 @@ static const EnumEntry<unsigned> ElfSymbolTypes[] = { static const char *getElfSectionType(unsigned Arch, unsigned Type) { switch (Arch) { - case Triple::arm: + case ELF::EM_ARM: switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX); LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); @@ -342,16 +335,12 @@ static const char *getElfSectionType(unsigned Arch, unsigned Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); } - case Triple::hexagon: - switch (Type) { - LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); - } - case Triple::x86_64: - switch (Type) { - LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); - } - case Triple::mips: - case Triple::mipsel: + case ELF::EM_HEXAGON: + switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); } + case ELF::EM_X86_64: + switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } + case ELF::EM_MIPS: + case ELF::EM_MIPS_RS3_LE: switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO); LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); @@ -388,6 +377,7 @@ static const char *getElfSectionType(unsigned Arch, unsigned Type) { static const EnumEntry<unsigned> ElfSectionFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXCLUDE ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS ), @@ -401,26 +391,41 @@ static const EnumEntry<unsigned> ElfSectionFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP ) }; -static const EnumEntry<unsigned> ElfSegmentTypes[] = { - LLVM_READOBJ_ENUM_ENT(ELF, PT_NULL ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_LOAD ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_DYNAMIC), - LLVM_READOBJ_ENUM_ENT(ELF, PT_INTERP ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_NOTE ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_SHLIB ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_PHDR ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_TLS ), - - LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_EH_FRAME), - LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_EH_FRAME), - LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_UNWIND), - - LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_STACK), - LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_RELRO), - - LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_EXIDX), - LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_UNWIND) -}; +static const char *getElfSegmentType(unsigned Arch, unsigned Type) { + // Check potentially overlapped processor-specific + // program header type. + switch (Arch) { + case ELF::EM_ARM: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); + } + case ELF::EM_MIPS: + case ELF::EM_MIPS_RS3_LE: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO); + LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC); + LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS); + } + } + + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC); + LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS ); + + LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME); + LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND); + + LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK); + LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO); + default: return ""; + } +} static const EnumEntry<unsigned> ElfSegmentFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, PF_X), @@ -428,12 +433,9 @@ static const EnumEntry<unsigned> ElfSegmentFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, PF_R) }; - template<class ELFT> void ELFDumper<ELFT>::printFileHeaders() { - error_code EC; - - const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader(); + const typename ELFO::Elf_Ehdr *Header = Obj->getHeader(); { DictScope D(W, "ElfHeader"); @@ -473,24 +475,20 @@ void ELFDumper<ELFT>::printSections() { ListScope SectionsD(W, "Sections"); int SectionIndex = -1; - error_code EC; - for (section_iterator SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; SecI.increment(EC)) { - if (error(EC)) break; - + for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; ++SecI) { ++SectionIndex; - const Elf_Shdr *Section = Obj->getElfSection(SecI); - StringRef Name; - if (error(SecI->getName(Name))) - Name = ""; + const Elf_Shdr *Section = &*SecI; + StringRef Name = errorOrDefault(Obj->getSectionName(Section)); DictScope SectionD(W, "Section"); W.printNumber("Index", SectionIndex); W.printNumber("Name", Name, Section->sh_name); - W.printHex ("Type", getElfSectionType(Obj->getArch(), Section->sh_type), - Section->sh_type); + W.printHex("Type", + getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type), + Section->sh_type); W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags)); W.printHex ("Address", Section->sh_addr); W.printHex ("Offset", Section->sh_offset); @@ -502,35 +500,23 @@ void ELFDumper<ELFT>::printSections() { if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - for (relocation_iterator RelI = SecI->begin_relocations(), - RelE = SecI->end_relocations(); - RelI != RelE; RelI.increment(EC)) { - if (error(EC)) break; - - printRelocation(SecI, RelI); - } + printRelocations(Section); } if (opts::SectionSymbols) { ListScope D(W, "Symbols"); - for (symbol_iterator SymI = Obj->begin_symbols(), - SymE = Obj->end_symbols(); - SymI != SymE; SymI.increment(EC)) { - if (error(EC)) break; - - bool Contained = false; - if (SecI->containsSymbol(*SymI, Contained) || !Contained) - continue; - - printSymbol(SymI); + for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; ++SymI) { + if (Obj->getSection(&*SymI) == Section) + printSymbol(SymI); } } if (opts::SectionData) { - StringRef Data; - if (error(SecI->getContents(Data))) break; - - W.printBinaryBlock("SectionData", Data); + ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section)); + W.printBinaryBlock("SectionData", + StringRef((const char *)Data.data(), Data.size())); } } } @@ -539,72 +525,74 @@ template<class ELFT> void ELFDumper<ELFT>::printRelocations() { ListScope D(W, "Relocations"); - error_code EC; int SectionNumber = -1; - for (section_iterator SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; SecI.increment(EC)) { - if (error(EC)) break; - + for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; ++SecI) { ++SectionNumber; - StringRef Name; - if (error(SecI->getName(Name))) + + if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA) continue; - bool PrintedGroup = false; - for (relocation_iterator RelI = SecI->begin_relocations(), - RelE = SecI->end_relocations(); - RelI != RelE; RelI.increment(EC)) { - if (error(EC)) break; + StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI)); - if (!PrintedGroup) { - W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; - W.indent(); - PrintedGroup = true; - } + W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; + W.indent(); - printRelocation(SecI, RelI); - } + printRelocations(&*SecI); + + W.unindent(); + W.startLine() << "}\n"; + } +} - if (PrintedGroup) { - W.unindent(); - W.startLine() << "}\n"; +template <class ELFT> +void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) { + switch (Sec->sh_type) { + case ELF::SHT_REL: + for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec), + RE = Obj->end_rel(Sec); + RI != RE; ++RI) { + typename ELFO::Elf_Rela Rela; + Rela.r_offset = RI->r_offset; + Rela.r_info = RI->r_info; + Rela.r_addend = 0; + printRelocation(Sec, Rela); + } + break; + case ELF::SHT_RELA: + for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec), + RE = Obj->end_rela(Sec); + RI != RE; ++RI) { + printRelocation(Sec, *RI); } + break; } } -template<class ELFT> -void ELFDumper<ELFT>::printRelocation(section_iterator Sec, - relocation_iterator RelI) { - uint64_t Offset; - uint64_t RelocType; +template <class ELFT> +void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec, + typename ELFO::Elf_Rela Rel) { SmallString<32> RelocName; - int64_t Info; + Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); StringRef SymbolName; - SymbolRef Symbol; - if (Obj->getElfHeader()->e_type == ELF::ET_REL){ - if (error(RelI->getOffset(Offset))) return; - } else { - if (error(RelI->getAddress(Offset))) return; - } - if (error(RelI->getType(RelocType))) return; - if (error(RelI->getTypeName(RelocName))) return; - if (error(RelI->getAdditionalInfo(Info))) return; - if (error(RelI->getSymbol(Symbol))) return; - if (error(Symbol.getName(SymbolName))) return; + std::pair<const Elf_Shdr *, const Elf_Sym *> Sym = + Obj->getRelocationSymbol(Sec, &Rel); + if (Sym.first) + SymbolName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second)); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); - W.printHex("Offset", Offset); - W.printNumber("Type", RelocName, RelocType); + W.printHex("Offset", Rel.r_offset); + W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); - W.printHex("Info", Info); + W.printHex("Addend", Rel.r_addend); } else { raw_ostream& OS = W.startLine(); - OS << W.hex(Offset) + OS << W.hex(Rel.r_offset) << " " << RelocName << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << " " << W.hex(Info) + << " " << W.hex(Rel.r_addend) << "\n"; } } @@ -612,12 +600,9 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec, template<class ELFT> void ELFDumper<ELFT>::printSymbols() { ListScope Group(W, "Symbols"); - - error_code EC; - for (symbol_iterator SymI = Obj->begin_symbols(), SymE = Obj->end_symbols(); - SymI != SymE; SymI.increment(EC)) { - if (error(EC)) break; - + for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; ++SymI) { printSymbol(SymI); } } @@ -626,41 +611,27 @@ template<class ELFT> void ELFDumper<ELFT>::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); - error_code EC; - for (symbol_iterator SymI = Obj->begin_dynamic_symbols(), - SymE = Obj->end_dynamic_symbols(); - SymI != SymE; SymI.increment(EC)) { - if (error(EC)) break; - - printSymbol(SymI, true); + for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(), + SymE = Obj->end_dynamic_symbols(); + SymI != SymE; ++SymI) { + printSymbol(SymI); } } -template<class ELFT> -void ELFDumper<ELFT>::printSymbol(symbol_iterator SymI, bool IsDynamic) { - error_code EC; - - const Elf_Sym *Symbol = Obj->getElfSymbol(SymI); - const Elf_Shdr *Section = Obj->getSection(Symbol); - - StringRef SymbolName; - if (SymI->getName(SymbolName)) - SymbolName = ""; - - StringRef SectionName = ""; - if (Section) - Obj->getSectionName(Section, SectionName); - +template <class ELFT> +void ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) { + StringRef SymbolName = errorOrDefault(Obj->getSymbolName(Symbol)); + const Elf_Shdr *Sec = Obj->getSection(&*Symbol); + StringRef SectionName = Sec ? errorOrDefault(Obj->getSectionName(Sec)) : ""; std::string FullSymbolName(SymbolName); - if (IsDynamic) { - StringRef Version; + if (Symbol.isDynamic()) { bool IsDefault; - if (error(Obj->getSymbolVersion(*SymI, Version, IsDefault))) - return; - if (!Version.empty()) { + ErrorOr<StringRef> Version = Obj->getSymbolVersion(0, &*Symbol, IsDefault); + if (Version) { FullSymbolName += (IsDefault ? "@@" : "@"); - FullSymbolName += Version; - } + FullSymbolName += *Version; + } else + error(Version); } DictScope D(W, "Symbol"); @@ -712,15 +683,25 @@ static const char *getTypeString(uint64_t Type) { LLVM_READOBJ_TYPE_CASE(SYMENT); LLVM_READOBJ_TYPE_CASE(SYMTAB); LLVM_READOBJ_TYPE_CASE(TEXTREL); + LLVM_READOBJ_TYPE_CASE(VERNEED); + LLVM_READOBJ_TYPE_CASE(VERNEEDNUM); + LLVM_READOBJ_TYPE_CASE(VERSYM); + LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION); + LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS); + LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS); + LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO); + LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO); + LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO); + LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM); default: return "unknown"; } } #undef LLVM_READOBJ_TYPE_CASE -template<class ELFT> -static void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type, - uint64_t Value, bool Is64, raw_ostream &OS) { +template <class ELFT> +static void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value, + bool Is64, raw_ostream &OS) { switch (Type) { case DT_PLTREL: if (Value == DT_REL) { @@ -744,9 +725,21 @@ static void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type, case DT_FINI_ARRAY: case DT_PREINIT_ARRAY: case DT_DEBUG: + case DT_VERNEED: + case DT_VERSYM: case DT_NULL: + case DT_MIPS_FLAGS: + case DT_MIPS_BASE_ADDRESS: + case DT_MIPS_GOTSYM: OS << format("0x%" PRIX64, Value); break; + case DT_VERNEEDNUM: + case DT_MIPS_RLD_VERSION: + case DT_MIPS_LOCAL_GOTNO: + case DT_MIPS_SYMTABNO: + case DT_MIPS_UNREFEXTNO: + OS << Value; + break; case DT_PLTRELSZ: case DT_RELASZ: case DT_RELAENT: @@ -760,12 +753,14 @@ static void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type, OS << Value << " (bytes)"; break; case DT_NEEDED: - OS << "SharedLibrary (" - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; + OS << "SharedLibrary (" << O->getDynamicString(Value) << ")"; break; case DT_SONAME: - OS << "LibrarySoname (" - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; + OS << "LibrarySoname (" << O->getDynamicString(Value) << ")"; + break; + case DT_RPATH: + case DT_RUNPATH: + OS << O->getDynamicString(Value); break; } } @@ -777,9 +772,8 @@ void ELFDumper<ELFT>::printUnwindInfo() { template<class ELFT> void ELFDumper<ELFT>::printDynamicTable() { - typedef typename ELFO::Elf_Dyn_iterator EDI; - EDI Start = Obj->begin_dynamic_table(), - End = Obj->end_dynamic_table(true); + typedef typename ELFO::Elf_Dyn_Iter EDI; + EDI Start = Obj->begin_dynamic_table(), End = Obj->end_dynamic_table(true); if (Start == End) return; @@ -788,7 +782,7 @@ void ELFDumper<ELFT>::printDynamicTable() { raw_ostream &OS = W.getOStream(); W.startLine() << "DynamicSection [ (" << Total << " entries)\n"; - bool Is64 = Obj->getBytesInAddress() == 8; + bool Is64 = ELFT::Is64Bits; W.startLine() << " Tag" << (Is64 ? " " : " ") << "Type" @@ -805,38 +799,23 @@ void ELFDumper<ELFT>::printDynamicTable() { W.startLine() << "]\n"; } -static bool compareLibraryName(const LibraryRef &L, const LibraryRef &R) { - StringRef LPath, RPath; - L.getPath(LPath); - R.getPath(RPath); - return LPath < RPath; -} - template<class ELFT> void ELFDumper<ELFT>::printNeededLibraries() { ListScope D(W, "NeededLibraries"); - error_code EC; - - typedef std::vector<LibraryRef> LibsTy; + typedef std::vector<StringRef> LibsTy; LibsTy Libs; - for (library_iterator I = Obj->begin_libraries_needed(), - E = Obj->end_libraries_needed(); - I != E; I.increment(EC)) { - if (EC) - report_fatal_error("Needed libraries iteration failed"); - - Libs.push_back(*I); - } + for (typename ELFO::Elf_Dyn_Iter DynI = Obj->begin_dynamic_table(), + DynE = Obj->end_dynamic_table(); + DynI != DynE; ++DynI) + if (DynI->d_tag == ELF::DT_NEEDED) + Libs.push_back(Obj->getDynamicString(DynI->d_un.d_val)); - std::sort(Libs.begin(), Libs.end(), &compareLibraryName); + std::stable_sort(Libs.begin(), Libs.end()); - for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); - I != E; ++I) { - StringRef Path; - I->getPath(Path); - outs() << " " << Path << "\n"; + for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); I != E; ++I) { + outs() << " " << *I << "\n"; } } @@ -848,7 +827,9 @@ void ELFDumper<ELFT>::printProgramHeaders() { PE = Obj->end_program_headers(); PI != PE; ++PI) { DictScope P(W, "ProgramHeader"); - W.printEnum ("Type", PI->p_type, makeArrayRef(ElfSegmentTypes)); + W.printHex ("Type", + getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type), + PI->p_type); W.printHex ("Offset", PI->p_offset); W.printHex ("VirtualAddress", PI->p_vaddr); W.printHex ("PhysicalAddress", PI->p_paddr); diff --git a/contrib/llvm/tools/llvm-readobj/MachODumper.cpp b/contrib/llvm/tools/llvm-readobj/MachODumper.cpp index 31dc5ce..b97166b 100644 --- a/contrib/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/contrib/llvm/tools/llvm-readobj/MachODumper.cpp @@ -166,28 +166,28 @@ static void getSection(const MachOObjectFile *Obj, DataRefImpl Sec, MachOSection &Section) { if (!Obj->is64Bit()) { - macho::Section Sect = Obj->getSection(Sec); - Section.Address = Sect.Address; - Section.Size = Sect.Size; - Section.Offset = Sect.Offset; - Section.Alignment = Sect.Align; - Section.RelocationTableOffset = Sect.RelocationTableOffset; - Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; - Section.Flags = Sect.Flags; - Section.Reserved1 = Sect.Reserved1; - Section.Reserved2 = Sect.Reserved2; + MachO::section Sect = Obj->getSection(Sec); + Section.Address = Sect.addr; + Section.Size = Sect.size; + Section.Offset = Sect.offset; + Section.Alignment = Sect.align; + Section.RelocationTableOffset = Sect.reloff; + Section.NumRelocationTableEntries = Sect.nreloc; + Section.Flags = Sect.flags; + Section.Reserved1 = Sect.reserved1; + Section.Reserved2 = Sect.reserved2; return; } - macho::Section64 Sect = Obj->getSection64(Sec); - Section.Address = Sect.Address; - Section.Size = Sect.Size; - Section.Offset = Sect.Offset; - Section.Alignment = Sect.Align; - Section.RelocationTableOffset = Sect.RelocationTableOffset; - Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; - Section.Flags = Sect.Flags; - Section.Reserved1 = Sect.Reserved1; - Section.Reserved2 = Sect.Reserved2; + MachO::section_64 Sect = Obj->getSection64(Sec); + Section.Address = Sect.addr; + Section.Size = Sect.size; + Section.Offset = Sect.offset; + Section.Alignment = Sect.align; + Section.RelocationTableOffset = Sect.reloff; + Section.NumRelocationTableEntries = Sect.nreloc; + Section.Flags = Sect.flags; + Section.Reserved1 = Sect.reserved1; + Section.Reserved2 = Sect.reserved2; } @@ -195,20 +195,20 @@ static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { if (!Obj->is64Bit()) { - macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI); - Symbol.StringIndex = Entry.StringIndex; - Symbol.Type = Entry.Type; - Symbol.SectionIndex = Entry.SectionIndex; - Symbol.Flags = Entry.Flags; - Symbol.Value = Entry.Value; + MachO::nlist Entry = Obj->getSymbolTableEntry(DRI); + Symbol.StringIndex = Entry.n_strx; + Symbol.Type = Entry.n_type; + Symbol.SectionIndex = Entry.n_sect; + Symbol.Flags = Entry.n_desc; + Symbol.Value = Entry.n_value; return; } - macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI); - Symbol.StringIndex = Entry.StringIndex; - Symbol.Type = Entry.Type; - Symbol.SectionIndex = Entry.SectionIndex; - Symbol.Flags = Entry.Flags; - Symbol.Value = Entry.Value; + MachO::nlist_64 Entry = Obj->getSymbol64TableEntry(DRI); + Symbol.StringIndex = Entry.n_strx; + Symbol.Type = Entry.n_type; + Symbol.SectionIndex = Entry.n_sect; + Symbol.Flags = Entry.n_desc; + Symbol.Value = Entry.n_value; } void MachODumper::printFileHeaders() { @@ -341,16 +341,15 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj, uint64_t Offset; SmallString<32> RelocName; StringRef SymbolName; - SymbolRef Symbol; if (error(RelI->getOffset(Offset))) return; if (error(RelI->getTypeName(RelocName))) return; - if (error(RelI->getSymbol(Symbol))) return; - if (symbol_iterator(Symbol) != Obj->end_symbols() && - error(Symbol.getName(SymbolName))) + symbol_iterator Symbol = RelI->getSymbol(); + if (Symbol != Obj->end_symbols() && + error(Symbol->getName(SymbolName))) return; DataRefImpl DR = RelI->getRawDataRefImpl(); - macho::RelocationEntry RE = Obj->getRelocation(DR); + MachO::any_relocation_info RE = Obj->getRelocation(DR); bool IsScattered = Obj->isRelocationScattered(RE); if (opts::ExpandRelocs) { @@ -399,8 +398,6 @@ void MachODumper::printDynamicSymbols() { } void MachODumper::printSymbol(symbol_iterator SymI) { - error_code EC; - StringRef SymbolName; if (SymI->getName(SymbolName)) SymbolName = ""; diff --git a/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp b/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp index 2e95b6b..f84a72f 100644 --- a/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -130,12 +130,15 @@ namespace opts { cl::desc("Expand each shown relocation to multiple lines")); } // namespace opts +static int ReturnValue = EXIT_SUCCESS; + namespace llvm { bool error(error_code EC) { if (!EC) return false; + ReturnValue = EXIT_FAILURE; outs() << "\nError reading file: " << EC.message() << ".\n"; outs().flush(); return true; @@ -157,6 +160,7 @@ static void reportError(StringRef Input, error_code EC) { errs() << Input << ": " << EC.message() << "\n"; errs().flush(); + ReturnValue = EXIT_FAILURE; } static void reportError(StringRef Input, StringRef Message) { @@ -164,6 +168,7 @@ static void reportError(StringRef Input, StringRef Message) { Input = "<stdin>"; errs() << Input << ": " << Message << "\n"; + ReturnValue = EXIT_FAILURE; } /// @brief Creates an format-specific object file dumper. @@ -289,5 +294,5 @@ int main(int argc, const char *argv[]) { std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), dumpInput); - return 0; + return ReturnValue; } |