diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h index a483e4e1d01d..3c6198518940 100644 --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/include/llvm/Object/COFF.h @@ -14,9 +14,11 @@ #ifndef LLVM_OBJECT_COFF_H #define LLVM_OBJECT_COFF_H +#include "llvm/ADT/PointerUnion.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/ErrorOr.h" namespace llvm { template class ArrayRef; @@ -62,6 +64,22 @@ struct coff_file_header { bool isImportLibrary() const { return NumberOfSections == 0xffff; } }; +struct coff_bigobj_file_header { + support::ulittle16_t Sig1; + support::ulittle16_t Sig2; + support::ulittle16_t Version; + support::ulittle16_t Machine; + support::ulittle32_t TimeDateStamp; + uint8_t UUID[16]; + support::ulittle32_t unused1; + support::ulittle32_t unused2; + support::ulittle32_t unused3; + support::ulittle32_t unused4; + support::ulittle32_t NumberOfSections; + support::ulittle32_t PointerToSymbolTable; + support::ulittle32_t NumberOfSymbols; +}; + /// The 32-bit PE header that follows the COFF header. struct pe32_header { support::ulittle16_t Magic; @@ -180,67 +198,121 @@ union export_address_table_entry { typedef support::ulittle32_t export_name_pointer_table_entry; typedef support::ulittle16_t export_ordinal_table_entry; -struct coff_symbol { - struct StringTableOffset { - support::ulittle32_t Zeroes; - support::ulittle32_t Offset; - }; +struct StringTableOffset { + support::ulittle32_t Zeroes; + support::ulittle32_t Offset; +}; +template +struct coff_symbol { union { - char ShortName[8]; + char ShortName[COFF::NameSize]; StringTableOffset Offset; } Name; support::ulittle32_t Value; - support::ulittle16_t SectionNumber; + SectionNumberType SectionNumber; support::ulittle16_t Type; support::ulittle8_t StorageClass; support::ulittle8_t NumberOfAuxSymbols; +}; - uint8_t getBaseType() const { return Type & 0x0F; } +typedef coff_symbol coff_symbol16; +typedef coff_symbol coff_symbol32; - uint8_t getComplexType() const { return (Type & 0xF0) >> 4; } +class COFFSymbolRef { +public: + COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS), CS32(nullptr) {} + COFFSymbolRef(const coff_symbol32 *CS) : CS16(nullptr), CS32(CS) {} + COFFSymbolRef() : CS16(nullptr), CS32(nullptr) {} + + const void *getRawPtr() const { + return CS16 ? static_cast(CS16) : CS32; + } + + friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) { + return A.getRawPtr() < B.getRawPtr(); + } + + const char *getShortName() const { + return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName; + } + + const StringTableOffset &getStringTableOffset() const { + return CS16 ? CS16->Name.Offset : CS32->Name.Offset; + } + + uint32_t getValue() const { return CS16 ? CS16->Value : CS32->Value; } + + int32_t getSectionNumber() const { + if (CS16) { + // Reserved sections are returned as negative numbers. + if (CS16->SectionNumber <= COFF::MaxNumberOfSections16) + return CS16->SectionNumber; + return static_cast(CS16->SectionNumber); + } + return static_cast(CS32->SectionNumber); + } + + uint16_t getType() const { return CS16 ? CS16->Type : CS32->Type; } + + uint8_t getStorageClass() const { + return CS16 ? CS16->StorageClass : CS32->StorageClass; + } + + uint8_t getNumberOfAuxSymbols() const { + return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols; + } + + uint8_t getBaseType() const { return getType() & 0x0F; } + + uint8_t getComplexType() const { return (getType() & 0xF0) >> 4; } bool isFunctionDefinition() const { - return StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && + return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION && - !COFF::isReservedSectionNumber(SectionNumber); + !COFF::isReservedSectionNumber(getSectionNumber()); } bool isFunctionLineInfo() const { - return StorageClass == COFF::IMAGE_SYM_CLASS_FUNCTION; + return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION; } bool isWeakExternal() const { - return StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL || - (StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && - SectionNumber == COFF::IMAGE_SYM_UNDEFINED && Value == 0); + return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL || + (getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && + getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED && getValue() == 0); } bool isFileRecord() const { - return StorageClass == COFF::IMAGE_SYM_CLASS_FILE; + return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE; } bool isSectionDefinition() const { // C++/CLI creates external ABS symbols for non-const appdomain globals. // These are also followed by an auxiliary section definition. - bool isAppdomainGlobal = StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && - SectionNumber == COFF::IMAGE_SYM_ABSOLUTE; + bool isAppdomainGlobal = + getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && + getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE; bool isOrdinarySection = - StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Value == 0; + getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC && getValue() == 0; return isAppdomainGlobal || isOrdinarySection; } bool isCLRToken() const { - return StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN; + return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN; } + +private: + const coff_symbol16 *CS16; + const coff_symbol32 *CS32; }; struct coff_section { - char Name[8]; + char Name[COFF::NameSize]; support::ulittle32_t VirtualSize; support::ulittle32_t VirtualAddress; support::ulittle32_t SizeOfRawData; @@ -270,7 +342,6 @@ struct coff_aux_function_definition { support::ulittle32_t TotalSize; support::ulittle32_t PointerToLinenumber; support::ulittle32_t PointerToNextFunction; - char Unused[2]; }; struct coff_aux_bf_and_ef_symbol { @@ -278,17 +349,11 @@ struct coff_aux_bf_and_ef_symbol { support::ulittle16_t Linenumber; char Unused2[6]; support::ulittle32_t PointerToNextFunction; - char Unused3[2]; }; struct coff_aux_weak_external { support::ulittle32_t TagIndex; support::ulittle32_t Characteristics; - char Unused[10]; -}; - -struct coff_aux_file { - char FileName[18]; }; struct coff_aux_section_definition { @@ -298,14 +363,12 @@ struct coff_aux_section_definition { support::ulittle32_t CheckSum; support::ulittle16_t Number; support::ulittle8_t Selection; - char Unused[3]; }; struct coff_aux_clr_token { support::ulittle8_t AuxType; support::ulittle8_t Reserved; support::ulittle32_t SymbolTableIndex; - char Unused[12]; }; struct coff_load_configuration32 { @@ -324,7 +387,7 @@ struct coff_load_configuration32 { support::ulittle32_t ProcessAffinityMask; support::ulittle32_t ProcessHeapFlags; support::ulittle16_t CSDVersion; - uint16_t Reserved; + support::ulittle16_t Reserved; support::ulittle32_t EditList; support::ulittle32_t SecurityCookie; support::ulittle32_t SEHandlerTable; @@ -342,11 +405,13 @@ private: friend class ImportDirectoryEntryRef; friend class ExportDirectoryEntryRef; const coff_file_header *COFFHeader; + const coff_bigobj_file_header *COFFBigObjHeader; const pe32_header *PE32Header; const pe32plus_header *PE32PlusHeader; const data_directory *DataDirectory; const coff_section *SectionTable; - const coff_symbol *SymbolTable; + const coff_symbol16 *SymbolTable16; + const coff_symbol32 *SymbolTable32; const char *StringTable; uint32_t StringTableSize; const import_directory_table_entry *ImportDirectory; @@ -355,7 +420,8 @@ private: std::error_code getString(uint32_t offset, StringRef &Res) const; - const coff_symbol *toSymb(DataRefImpl Symb) const; + template + const coff_symbol_type *toSymb(DataRefImpl Symb) const; const coff_section *toSec(DataRefImpl Sec) const; const coff_relocation *toRel(DataRefImpl Rel) const; @@ -363,6 +429,66 @@ private: std::error_code initImportTablePtr(); std::error_code initExportTablePtr(); +public: + uintptr_t getSymbolTable() const { + if (SymbolTable16) + return reinterpret_cast(SymbolTable16); + if (SymbolTable32) + return reinterpret_cast(SymbolTable32); + return uintptr_t(0); + } + uint16_t getMachine() const { + if (COFFHeader) + return COFFHeader->Machine; + if (COFFBigObjHeader) + return COFFBigObjHeader->Machine; + llvm_unreachable("no COFF header!"); + } + uint16_t getSizeOfOptionalHeader() const { + if (COFFHeader) + return COFFHeader->SizeOfOptionalHeader; + // bigobj doesn't have this field. + if (COFFBigObjHeader) + return 0; + llvm_unreachable("no COFF header!"); + } + uint16_t getCharacteristics() const { + if (COFFHeader) + return COFFHeader->Characteristics; + // bigobj doesn't have characteristics to speak of, + // editbin will silently lie to you if you attempt to set any. + if (COFFBigObjHeader) + return 0; + llvm_unreachable("no COFF header!"); + } + uint32_t getTimeDateStamp() const { + if (COFFHeader) + return COFFHeader->TimeDateStamp; + if (COFFBigObjHeader) + return COFFBigObjHeader->TimeDateStamp; + llvm_unreachable("no COFF header!"); + } + uint32_t getNumberOfSections() const { + if (COFFHeader) + return COFFHeader->NumberOfSections; + if (COFFBigObjHeader) + return COFFBigObjHeader->NumberOfSections; + llvm_unreachable("no COFF header!"); + } + uint32_t getPointerToSymbolTable() const { + if (COFFHeader) + return COFFHeader->PointerToSymbolTable; + if (COFFBigObjHeader) + return COFFBigObjHeader->PointerToSymbolTable; + llvm_unreachable("no COFF header!"); + } + uint32_t getNumberOfSymbols() const { + if (COFFHeader) + return COFFHeader->NumberOfSymbols; + if (COFFBigObjHeader) + return COFFBigObjHeader->NumberOfSymbols; + llvm_unreachable("no COFF header!"); + } protected: void moveSymbolNext(DataRefImpl &Symb) const override; std::error_code getSymbolName(DataRefImpl Symb, @@ -422,7 +548,8 @@ public: section_iterator section_end() const override; const coff_section *getCOFFSection(const SectionRef &Section) const; - const coff_symbol *getCOFFSymbol(const SymbolRef &Symbol) const; + COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const; + COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const; const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const; uint8_t getBytesInAddress() const override; @@ -434,24 +561,47 @@ public: export_directory_iterator export_directory_begin() const; export_directory_iterator export_directory_end() const; - std::error_code getHeader(const coff_file_header *&Res) const; - std::error_code getCOFFHeader(const coff_file_header *&Res) const; std::error_code getPE32Header(const pe32_header *&Res) const; std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const; std::error_code getDataDirectory(uint32_t index, const data_directory *&Res) const; std::error_code getSection(int32_t index, const coff_section *&Res) const; - std::error_code getSymbol(uint32_t index, const coff_symbol *&Res) const; + template + std::error_code getSymbol(uint32_t index, const coff_symbol_type *&Res) const; + ErrorOr getSymbol(uint32_t index) const { + if (SymbolTable16) { + const coff_symbol16 *Symb = nullptr; + if (std::error_code EC = getSymbol(index, Symb)) + return EC; + return COFFSymbolRef(Symb); + } + if (SymbolTable32) { + const coff_symbol32 *Symb = nullptr; + if (std::error_code EC = getSymbol(index, Symb)) + return EC; + return COFFSymbolRef(Symb); + } + llvm_unreachable("no symbol table pointer!"); + } template std::error_code getAuxSymbol(uint32_t index, const T *&Res) const { - const coff_symbol *s; - std::error_code ec = getSymbol(index, s); - Res = reinterpret_cast(s); - return ec; + ErrorOr s = getSymbol(index); + if (std::error_code EC = s.getError()) + return EC; + Res = reinterpret_cast(s->getRawPtr()); + return object_error::success; + } + std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; + + ArrayRef getSymbolAuxData(COFFSymbolRef Symbol) const; + + size_t getSymbolTableEntrySize() const { + if (COFFHeader) + return sizeof(coff_symbol16); + if (COFFBigObjHeader) + return sizeof(coff_symbol32); + llvm_unreachable("null symbol table pointer!"); } - std::error_code getSymbolName(const coff_symbol *symbol, - StringRef &Res) const; - ArrayRef getSymbolAuxData(const coff_symbol *symbol) const; std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const; std::error_code getSectionContents(const coff_section *Sec, diff --git a/llvm/include/llvm/Support/COFF.h b/llvm/include/llvm/Support/COFF.h index e09ef07d81db..f555fbeb4410 100644 --- a/llvm/include/llvm/Support/COFF.h +++ b/llvm/include/llvm/Support/COFF.h @@ -31,11 +31,16 @@ namespace llvm { namespace COFF { // The maximum number of sections that a COFF object can have (inclusive). - const int MaxNumberOfSections = 65299; + const uint16_t MaxNumberOfSections16 = 65299; // The PE signature bytes that follows the DOS stub header. static const char PEMagic[] = { 'P', 'E', '\0', '\0' }; + static const char BigObjMagic[] = { + '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b', + '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8', + }; + // Sizes in bytes of various things in the COFF format. enum { HeaderSize = 20, @@ -55,6 +60,24 @@ namespace COFF { uint16_t Characteristics; }; + struct BigObjHeader { + enum { MinBigObjectVersion = 2 }; + + uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0). + uint16_t Sig2; ///< Must be 0xFFFF. + uint16_t Version; + uint16_t Machine; + uint32_t TimeDateStamp; + uint8_t UUID[16]; + uint32_t unused1; + uint32_t unused2; + uint32_t unused3; + uint32_t unused4; + uint32_t NumberOfSections; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + }; + enum MachineTypes { MT_Invalid = 0xffff, @@ -140,9 +163,9 @@ namespace COFF { SF_WeakExternal = 0x01000000 }; - enum SymbolSectionNumber { - IMAGE_SYM_DEBUG = 0xFFFE, - IMAGE_SYM_ABSOLUTE = 0xFFFF, + enum SymbolSectionNumber : int32_t { + IMAGE_SYM_DEBUG = -2, + IMAGE_SYM_ABSOLUTE = -1, IMAGE_SYM_UNDEFINED = 0 }; @@ -647,8 +670,8 @@ namespace COFF { DEBUG_INDEX_SUBSECTION = 0xF4 }; - inline bool isReservedSectionNumber(int N) { - return N == IMAGE_SYM_UNDEFINED || N > MaxNumberOfSections; + inline bool isReservedSectionNumber(int32_t SectionNumber) { + return SectionNumber <= 0; } } // End namespace COFF. diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 489c92675f69..d382037e31af 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -849,7 +849,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, MakeSectionReal(*Section, Number); } - if (NumberOfSections > static_cast(COFF::MaxNumberOfSections)) + if (NumberOfSections > static_cast(COFF::MaxNumberOfSections16)) report_fatal_error( "PE COFF object files can't have more than 65,299 sections"); diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 94e5b1eb148b..ea134b2499e2 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -88,20 +88,22 @@ static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) { return false; } -const coff_symbol *COFFObjectFile::toSymb(DataRefImpl Ref) const { - const coff_symbol *Addr = reinterpret_cast(Ref.p); +template +const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const { + const coff_symbol_type *Addr = + reinterpret_cast(Ref.p); -# ifndef NDEBUG +#ifndef NDEBUG // Verify that the symbol points to a valid entry in the symbol table. uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base()); - if (Offset < COFFHeader->PointerToSymbolTable - || Offset >= COFFHeader->PointerToSymbolTable - + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) + if (Offset < getPointerToSymbolTable() || + Offset >= getPointerToSymbolTable() + + (getNumberOfSymbols() * sizeof(coff_symbol_type))) report_fatal_error("Symbol was outside of symbol table."); - assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) - == 0 && "Symbol did not point to the beginning of a symbol"); -# endif + assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 && + "Symbol did not point to the beginning of a symbol"); +#endif return Addr; } @@ -111,8 +113,7 @@ const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { # ifndef NDEBUG // Verify that the section points to a valid entry in the section table. - if (Addr < SectionTable - || Addr >= (SectionTable + COFFHeader->NumberOfSections)) + if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections())) report_fatal_error("Section was outside of section table."); uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable); @@ -124,49 +125,58 @@ const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const { } void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const { - const coff_symbol *Symb = toSymb(Ref); - Symb += 1 + Symb->NumberOfAuxSymbols; - Ref.p = reinterpret_cast(Symb); + if (SymbolTable16) { + const coff_symbol16 *Symb = toSymb(Ref); + Symb += 1 + Symb->NumberOfAuxSymbols; + Ref.p = reinterpret_cast(Symb); + } else if (SymbolTable32) { + const coff_symbol32 *Symb = toSymb(Ref); + Symb += 1 + Symb->NumberOfAuxSymbols; + Ref.p = reinterpret_cast(Symb); + } else { + llvm_unreachable("no symbol table pointer!"); + } } std::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref, StringRef &Result) const { - const coff_symbol *Symb = toSymb(Ref); + COFFSymbolRef Symb = getCOFFSymbol(Ref); return getSymbolName(Symb, Result); } std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref, uint64_t &Result) const { - const coff_symbol *Symb = toSymb(Ref); + COFFSymbolRef Symb = getCOFFSymbol(Ref); const coff_section *Section = nullptr; - if (std::error_code EC = getSection(Symb->SectionNumber, Section)) + if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) return EC; - if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) + if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) Result = UnknownAddressOrSize; else if (Section) - Result = Section->VirtualAddress + Symb->Value; + Result = Section->VirtualAddress + Symb.getValue(); else - Result = Symb->Value; + Result = Symb.getValue(); return object_error::success; } std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref, SymbolRef::Type &Result) const { - const coff_symbol *Symb = toSymb(Ref); + COFFSymbolRef Symb = getCOFFSymbol(Ref); Result = SymbolRef::ST_Other; - if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && - Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { + + if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL && + Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) { Result = SymbolRef::ST_Unknown; - } else if (Symb->isFunctionDefinition()) { + } else if (Symb.isFunctionDefinition()) { Result = SymbolRef::ST_Function; } else { - uint32_t Characteristics = 0; - if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) { - const coff_section *Section = nullptr; - if (std::error_code EC = getSection(Symb->SectionNumber, Section)) - return EC; - Characteristics = Section->Characteristics; + uint32_t Characteristics = 0; + if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { + const coff_section *Section = nullptr; + if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) + return EC; + Characteristics = Section->Characteristics; } if (Characteristics & COFF::IMAGE_SCN_MEM_READ && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. @@ -176,13 +186,13 @@ std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref, } uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { - const coff_symbol *Symb = toSymb(Ref); + COFFSymbolRef Symb = getCOFFSymbol(Ref); uint32_t Result = SymbolRef::SF_None; // TODO: Correctly set SF_FormatSpecific, SF_Common - if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { - if (Symb->Value == 0) + if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) { + if (Symb.getValue() == 0) Result |= SymbolRef::SF_Undefined; else Result |= SymbolRef::SF_Common; @@ -190,13 +200,13 @@ uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const { // TODO: This are certainly too restrictive. - if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) + if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL) Result |= SymbolRef::SF_Global; - if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) + if (Symb.getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) Result |= SymbolRef::SF_Weak; - if (Symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE) + if (Symb.getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE) Result |= SymbolRef::SF_Absolute; return Result; @@ -207,15 +217,15 @@ std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, // FIXME: Return the correct size. This requires looking at all the symbols // in the same section as this symbol, and looking for either the next // symbol, or the end of the section. - const coff_symbol *Symb = toSymb(Ref); + COFFSymbolRef Symb = getCOFFSymbol(Ref); const coff_section *Section = nullptr; - if (std::error_code EC = getSection(Symb->SectionNumber, Section)) + if (std::error_code EC = getSection(Symb.getSectionNumber(), Section)) return EC; - if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) + if (Symb.getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED) Result = UnknownAddressOrSize; else if (Section) - Result = Section->SizeOfRawData - Symb->Value; + Result = Section->SizeOfRawData - Symb.getValue(); else Result = 0; return object_error::success; @@ -224,12 +234,12 @@ std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref, std::error_code COFFObjectFile::getSymbolSection(DataRefImpl Ref, section_iterator &Result) const { - const coff_symbol *Symb = toSymb(Ref); - if (COFF::isReservedSectionNumber(Symb->SectionNumber)) { + COFFSymbolRef Symb = getCOFFSymbol(Ref); + if (COFF::isReservedSectionNumber(Symb.getSectionNumber())) { Result = section_end(); } else { const coff_section *Sec = nullptr; - if (std::error_code EC = getSection(Symb->SectionNumber, Sec)) + if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec)) return EC; DataRefImpl Ref; Ref.p = reinterpret_cast(Sec); @@ -336,9 +346,9 @@ std::error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, DataRefImpl SymbRef, bool &Result) const { const coff_section *Sec = toSec(SecRef); - const coff_symbol *Symb = toSymb(SymbRef); + COFFSymbolRef Symb = getCOFFSymbol(SymbRef); const coff_section *SymbSec = nullptr; - if (std::error_code EC = getSection(Symb->SectionNumber, SymbSec)) + if (std::error_code EC = getSection(Symb.getSectionNumber(), SymbSec)) return EC; if (SymbSec == Sec) Result = true; @@ -395,17 +405,24 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { // Initialize the pointer to the symbol table. std::error_code COFFObjectFile::initSymbolTablePtr() { - if (std::error_code EC = getObject( - SymbolTable, Data, base() + COFFHeader->PointerToSymbolTable, - COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) - return EC; + if (COFFHeader) + if (std::error_code EC = + getObject(SymbolTable16, Data, base() + getPointerToSymbolTable(), + getNumberOfSymbols() * getSymbolTableEntrySize())) + return EC; + + if (COFFBigObjHeader) + if (std::error_code EC = + getObject(SymbolTable32, Data, base() + getPointerToSymbolTable(), + getNumberOfSymbols() * getSymbolTableEntrySize())) + return EC; // Find string table. The first four byte of the string table contains the // total size of the string table, including the size field itself. If the // string table is empty, the value of the first four byte would be 4. const uint8_t *StringTableAddr = - base() + COFFHeader->PointerToSymbolTable + - COFFHeader->NumberOfSymbols * sizeof(coff_symbol); + base() + getPointerToSymbolTable() + + getNumberOfSymbols() * getSymbolTableEntrySize(); const ulittle32_t *StringTableSizePtr; if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr)) return EC; @@ -511,9 +528,10 @@ std::error_code COFFObjectFile::initExportTablePtr() { COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr), - PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr), - SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr), - StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0), + COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr), + DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr), + SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0), + ImportDirectory(nullptr), NumberOfImportDirectory(0), ExportDirectory(nullptr) { // Check that we at least have enough room for a header. if (!checkSize(Data, EC, sizeof(coff_file_header))) @@ -534,17 +552,46 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) return; CurPtr = *reinterpret_cast(base() + 0x3c); // Check the PE magic bytes. ("PE\0\0") - if (std::memcmp(base() + CurPtr, "PE\0\0", 4) != 0) { + if (std::memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != + 0) { EC = object_error::parse_failed; return; } - CurPtr += 4; // Skip the PE magic bytes. + CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes. HasPEHeader = true; } if ((EC = getObject(COFFHeader, Data, base() + CurPtr))) return; - CurPtr += sizeof(coff_file_header); + + // It might be a bigobj file, let's check. Note that COFF bigobj and COFF + // import libraries share a common prefix but bigobj is more restrictive. + if (!HasPEHeader && COFFHeader->Machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN && + COFFHeader->NumberOfSections == uint16_t(0xffff) && + checkSize(Data, EC, sizeof(coff_bigobj_file_header))) { + if ((EC = getObject(COFFBigObjHeader, Data, base() + CurPtr))) + return; + + // Verify that we are dealing with bigobj. + if (COFFBigObjHeader->Version >= COFF::BigObjHeader::MinBigObjectVersion && + std::memcmp(COFFBigObjHeader->UUID, COFF::BigObjMagic, + sizeof(COFF::BigObjMagic)) == 0) { + COFFHeader = nullptr; + CurPtr += sizeof(coff_bigobj_file_header); + } else { + // It's not a bigobj. + COFFBigObjHeader = nullptr; + } + } + if (COFFHeader) { + // The prior checkSize call may have failed. This isn't a hard error + // because we were just trying to sniff out bigobj. + EC = object_error::success; + CurPtr += sizeof(coff_file_header); + + if (COFFHeader->isImportLibrary()) + return; + } if (HasPEHeader) { const pe32_header *Header; @@ -571,15 +618,12 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) CurPtr += COFFHeader->SizeOfOptionalHeader; } - if (COFFHeader->isImportLibrary()) - return; - if ((EC = getObject(SectionTable, Data, base() + CurPtr, - COFFHeader->NumberOfSections * sizeof(coff_section)))) + getNumberOfSections() * sizeof(coff_section)))) return; // Initialize the pointer to the symbol table. - if (COFFHeader->PointerToSymbolTable != 0) + if (getPointerToSymbolTable() != 0) if ((EC = initSymbolTablePtr())) return; @@ -596,7 +640,7 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC) basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { DataRefImpl Ret; - Ret.p = reinterpret_cast(SymbolTable); + Ret.p = getSymbolTable(); return basic_symbol_iterator(SymbolRef(Ret, this)); } @@ -638,8 +682,8 @@ section_iterator COFFObjectFile::section_begin() const { section_iterator COFFObjectFile::section_end() const { DataRefImpl Ret; - int NumSections = COFFHeader->isImportLibrary() - ? 0 : COFFHeader->NumberOfSections; + int NumSections = + COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections(); Ret.p = reinterpret_cast(SectionTable + NumSections); return section_iterator(SectionRef(Ret, this)); } @@ -649,7 +693,7 @@ uint8_t COFFObjectFile::getBytesInAddress() const { } StringRef COFFObjectFile::getFileFormatName() const { - switch(COFFHeader->Machine) { + switch(getMachine()) { case COFF::IMAGE_FILE_MACHINE_I386: return "COFF-i386"; case COFF::IMAGE_FILE_MACHINE_AMD64: @@ -662,7 +706,7 @@ StringRef COFFObjectFile::getFileFormatName() const { } unsigned COFFObjectFile::getArch() const { - switch(COFFHeader->Machine) { + switch (getMachine()) { case COFF::IMAGE_FILE_MACHINE_I386: return Triple::x86; case COFF::IMAGE_FILE_MACHINE_AMD64: @@ -674,18 +718,6 @@ unsigned COFFObjectFile::getArch() const { } } -// This method is kept here because lld uses this. As soon as we make -// lld to use getCOFFHeader, this method will be removed. -std::error_code COFFObjectFile::getHeader(const coff_file_header *&Res) const { - return getCOFFHeader(Res); -} - -std::error_code -COFFObjectFile::getCOFFHeader(const coff_file_header *&Res) const { - Res = COFFHeader; - return object_error::success; -} - std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const { Res = PE32Header; return object_error::success; @@ -717,7 +749,7 @@ std::error_code COFFObjectFile::getSection(int32_t Index, // Check for special index values. if (COFF::isReservedSectionNumber(Index)) Result = nullptr; - else if (Index > 0 && Index <= COFFHeader->NumberOfSections) + else if (Index > 0 && static_cast(Index) <= getNumberOfSections()) // We already verified the section table data, so no need to check again. Result = SectionTable + (Index - 1); else @@ -736,65 +768,68 @@ std::error_code COFFObjectFile::getString(uint32_t Offset, return object_error::success; } -std::error_code COFFObjectFile::getSymbol(uint32_t Index, - const coff_symbol *&Result) const { - if (Index < COFFHeader->NumberOfSymbols) - Result = SymbolTable + Index; +template +std::error_code +COFFObjectFile::getSymbol(uint32_t Index, + const coff_symbol_type *&Result) const { + if (Index < getNumberOfSymbols()) + Result = reinterpret_cast(getSymbolTable()) + Index; else return object_error::parse_failed; return object_error::success; } -std::error_code COFFObjectFile::getSymbolName(const coff_symbol *Symbol, +std::error_code COFFObjectFile::getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const { // Check for string table entry. First 4 bytes are 0. - if (Symbol->Name.Offset.Zeroes == 0) { - uint32_t Offset = Symbol->Name.Offset.Offset; + if (Symbol.getStringTableOffset().Zeroes == 0) { + uint32_t Offset = Symbol.getStringTableOffset().Offset; if (std::error_code EC = getString(Offset, Res)) return EC; return object_error::success; } - if (Symbol->Name.ShortName[7] == 0) + if (Symbol.getShortName()[COFF::NameSize - 1] == 0) // Null terminated, let ::strlen figure out the length. - Res = StringRef(Symbol->Name.ShortName); + Res = StringRef(Symbol.getShortName()); else // Not null terminated, use all 8 bytes. - Res = StringRef(Symbol->Name.ShortName, 8); + Res = StringRef(Symbol.getShortName(), COFF::NameSize); return object_error::success; } -ArrayRef COFFObjectFile::getSymbolAuxData( - const coff_symbol *Symbol) const { +ArrayRef +COFFObjectFile::getSymbolAuxData(COFFSymbolRef Symbol) const { const uint8_t *Aux = nullptr; - if (Symbol->NumberOfAuxSymbols > 0) { - // AUX data comes immediately after the symbol in COFF - Aux = reinterpret_cast(Symbol + 1); + size_t SymbolSize = getSymbolTableEntrySize(); + if (Symbol.getNumberOfAuxSymbols() > 0) { + // AUX data comes immediately after the symbol in COFF + Aux = reinterpret_cast(Symbol.getRawPtr()) + SymbolSize; # ifndef NDEBUG // Verify that the Aux symbol points to a valid entry in the symbol table. uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base()); - if (Offset < COFFHeader->PointerToSymbolTable - || Offset >= COFFHeader->PointerToSymbolTable - + (COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) + if (Offset < getPointerToSymbolTable() || + Offset >= + getPointerToSymbolTable() + (getNumberOfSymbols() * SymbolSize)) report_fatal_error("Aux Symbol data was outside of symbol table."); - assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol) - == 0 && "Aux Symbol data did not point to the beginning of a symbol"); + assert((Offset - getPointerToSymbolTable()) % SymbolSize == 0 && + "Aux Symbol data did not point to the beginning of a symbol"); # endif } - return makeArrayRef(Aux, Symbol->NumberOfAuxSymbols * sizeof(coff_symbol)); + return makeArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize); } std::error_code COFFObjectFile::getSectionName(const coff_section *Sec, StringRef &Res) const { StringRef Name; - if (Sec->Name[7] == 0) + if (Sec->Name[COFF::NameSize - 1] == 0) // Null terminated, let ::strlen figure out the length. Name = Sec->Name; else // Not null terminated, use all 8 bytes. - Name = StringRef(Sec->Name, 8); + Name = StringRef(Sec->Name, COFF::NameSize); // Check for string table entry. First byte is '/'. if (Name[0] == '/') { @@ -850,9 +885,14 @@ std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, } symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { - const coff_relocation* R = toRel(Rel); + const coff_relocation *R = toRel(Rel); DataRefImpl Ref; - Ref.p = reinterpret_cast(SymbolTable + R->SymbolTableIndex); + if (SymbolTable16) + Ref.p = reinterpret_cast(SymbolTable16 + R->SymbolTableIndex); + else if (SymbolTable32) + Ref.p = reinterpret_cast(SymbolTable32 + R->SymbolTableIndex); + else + llvm_unreachable("no symbol table pointer!"); return symbol_iterator(SymbolRef(Ref, this)); } @@ -868,9 +908,16 @@ COFFObjectFile::getCOFFSection(const SectionRef &Section) const { return toSec(Section.getRawDataRefImpl()); } -const coff_symbol * -COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { - return toSymb(Symbol.getRawDataRefImpl()); +COFFSymbolRef COFFObjectFile::getCOFFSymbol(const DataRefImpl &Ref) const { + if (SymbolTable16) + return toSymb(Ref); + if (SymbolTable32) + return toSymb(Ref); + llvm_unreachable("no symbol table pointer!"); +} + +COFFSymbolRef COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const { + return getCOFFSymbol(Symbol.getRawDataRefImpl()); } const coff_relocation * @@ -888,7 +935,7 @@ COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const { const coff_relocation *Reloc = toRel(Rel); StringRef Res; - switch (COFFHeader->Machine) { + switch (getMachine()) { case COFF::IMAGE_FILE_MACHINE_AMD64: switch (Reloc->Type) { LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); @@ -963,11 +1010,11 @@ std::error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, SmallVectorImpl &Result) const { const coff_relocation *Reloc = toRel(Rel); - const coff_symbol *Symb = nullptr; - if (std::error_code EC = getSymbol(Reloc->SymbolTableIndex, Symb)) - return EC; DataRefImpl Sym; - Sym.p = reinterpret_cast(Symb); + ErrorOr Symb = getSymbol(Reloc->SymbolTableIndex); + if (std::error_code EC = Symb.getError()) + return EC; + Sym.p = reinterpret_cast(Symb->getRawPtr()); StringRef SymName; if (std::error_code EC = getSymbolName(Sym, SymName)) return EC; diff --git a/llvm/test/MC/ARM/coff-file.s b/llvm/test/MC/ARM/coff-file.s index f0dd29a29256..b4b259d7fe08 100644 --- a/llvm/test/MC/ARM/coff-file.s +++ b/llvm/test/MC/ARM/coff-file.s @@ -21,7 +21,7 @@ // CHECK-SCN: Symbols [ // CHECK-SCN: Symbol { // CHECK-SCN: Name: .file -// CHECK-SCN: Section: (65534) +// CHECK-SCN: Section: (-2) // CHECK-SCN: StorageClass: File // CHECK-SCN: AuxFileRecord { // CHECK-SCN: FileName: null-padded.asm @@ -29,7 +29,7 @@ // CHECK-SCN: } // CHECK-SCN: Symbol { // CHECK-SCN: Name: .file -// CHECK-SCN: Section: (65534) +// CHECK-SCN: Section: (-2) // CHECK-SCN: StorageClass: File // CHECK-SCN: AuxFileRecord { // CHECK-SCN: FileName: eighteen-chars.asm @@ -37,7 +37,7 @@ // CHECK-SCN: } // CHECK-SCN: Symbol { // CHECK-SCN: Name: .file -// CHECK-SCN: Section: (65534) +// CHECK-SCN: Section: (-2) // CHECK-SCN: StorageClass: File // CHECK-SCN: AuxFileRecord { // CHECK-SCN: FileName: multiple-auxiliary-entries.asm diff --git a/llvm/test/MC/COFF/alias.s b/llvm/test/MC/COFF/alias.s index fcaa4204d49b..7dfc4c7f8517 100644 --- a/llvm/test/MC/COFF/alias.s +++ b/llvm/test/MC/COFF/alias.s @@ -92,7 +92,6 @@ weak_aliased_to_external = external2 // CHECK-NEXT: AuxWeakExternal { // CHECK-NEXT: Linked: external2 // CHECK-NEXT: Search: Library (0x2) -// CHECK-NEXT: Unused: (00 00 00 00 00 00 00 00 00 00) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: Symbol { diff --git a/llvm/test/MC/COFF/basic-coff-64.s b/llvm/test/MC/COFF/basic-coff-64.s index 38a9e578a4ca..3f7a26805852 100644 --- a/llvm/test/MC/COFF/basic-coff-64.s +++ b/llvm/test/MC/COFF/basic-coff-64.s @@ -113,7 +113,6 @@ _main: # @main // CHECK: Checksum: 0x0 // CHECK: Number: [[DataNum]] // CHECK: Selection: 0x0 -// CHECK: Unused: (00 00 00) // CHECK: } // CHECK: } // CHECK: Symbol { diff --git a/llvm/test/MC/COFF/basic-coff.s b/llvm/test/MC/COFF/basic-coff.s index 38bfa6d1014c..3a16df45ece9 100644 --- a/llvm/test/MC/COFF/basic-coff.s +++ b/llvm/test/MC/COFF/basic-coff.s @@ -113,7 +113,6 @@ L_.str: # @.str // CHECK: Checksum: 0x0 // CHECK: Number: 2 // CHECK: Selection: 0x0 -// CHECK: Unused: (00 00 00) // CHECK: } // CHECK: } // CHECK: Symbol { diff --git a/llvm/test/MC/COFF/feat00.s b/llvm/test/MC/COFF/feat00.s index bfd47ad4abc0..d08f407cef58 100644 --- a/llvm/test/MC/COFF/feat00.s +++ b/llvm/test/MC/COFF/feat00.s @@ -6,7 +6,7 @@ // CHECK: Symbol { // CHECK: Name: @feat.00 // CHECK: Value: 123 -// CHECK: Section: (65535) +// CHECK: Section: (-1) // CHECK: BaseType: Null (0x0) // CHECK: ComplexType: Null (0x0) // CHECK: StorageClass: External (0x2) diff --git a/llvm/test/MC/COFF/file.s b/llvm/test/MC/COFF/file.s index 132e82b2e25d..1fca5a15e9dd 100644 --- a/llvm/test/MC/COFF/file.s +++ b/llvm/test/MC/COFF/file.s @@ -21,7 +21,7 @@ // CHECK-SCN: Symbols [ // CHECK-SCN: Symbol { // CHECK-SCN: Name: .file -// CHECK-SCN: Section: (65534) +// CHECK-SCN: Section: (-2) // CHECK-SCN: StorageClass: File // CHECK-SCN: AuxFileRecord { // CHECK-SCN: FileName: null-padded.asm @@ -29,7 +29,7 @@ // CHECK-SCN: } // CHECK-SCN: Symbol { // CHECK-SCN: Name: .file -// CHECK-SCN: Section: (65534) +// CHECK-SCN: Section: (-2) // CHECK-SCN: StorageClass: File // CHECK-SCN: AuxFileRecord { // CHECK-SCN: FileName: eighteen-chars.asm @@ -37,7 +37,7 @@ // CHECK-SCN: } // CHECK-SCN: Symbol { // CHECK-SCN: Name: .file -// CHECK-SCN: Section: (65534) +// CHECK-SCN: Section: (-2) // CHECK-SCN: StorageClass: File // CHECK-SCN: AuxFileRecord { // CHECK-SCN: FileName: multiple-auxiliary-entries.asm diff --git a/llvm/test/MC/COFF/symbol-fragment-offset-64.s b/llvm/test/MC/COFF/symbol-fragment-offset-64.s index deac88869b20..cbcc431bf1f9 100644 --- a/llvm/test/MC/COFF/symbol-fragment-offset-64.s +++ b/llvm/test/MC/COFF/symbol-fragment-offset-64.s @@ -117,7 +117,6 @@ _main: # @main // CHECK: Checksum: 0x0 // CHECK: Number: 1 // CHECK: Selection: 0x0 -// CHECK: Unused: (00 00 00) // CHECK: } // CHECK: } // CHECK: Symbol { @@ -135,7 +134,6 @@ _main: # @main // CHECK: Checksum: 0x0 // CHECK: Number: 2 // CHECK: Selection: 0x0 -// CHECK: Unused: (00 00 00) // CHECK: } // CHECK: } // CHECK: Symbol { diff --git a/llvm/test/MC/COFF/symbol-fragment-offset.s b/llvm/test/MC/COFF/symbol-fragment-offset.s index b09c5af1b61e..a5a3f9f07c23 100644 --- a/llvm/test/MC/COFF/symbol-fragment-offset.s +++ b/llvm/test/MC/COFF/symbol-fragment-offset.s @@ -117,7 +117,6 @@ L_.str2: // CHECK: Checksum: 0x0 // CHECK: Number: 1 // CHECK: Selection: 0x0 -// CHECK: Unused: (00 00 00) // CHECK: } // CHECK: } // CHECK: Symbol { @@ -135,7 +134,6 @@ L_.str2: // CHECK: Checksum: 0x0 // CHECK: Number: 2 // CHECK: Selection: 0x0 -// CHECK: Unused: (00 00 00) // CHECK: } // CHECK: } // CHECK: Symbol { diff --git a/llvm/test/MC/COFF/weak.s b/llvm/test/MC/COFF/weak.s index accd3f452eaf..b729cbdf5828 100644 --- a/llvm/test/MC/COFF/weak.s +++ b/llvm/test/MC/COFF/weak.s @@ -45,14 +45,13 @@ LBB0_2: # %return // CHECK-NEXT: AuxWeakExternal { // CHECK-NEXT: Linked: .weak._test_weak.default // CHECK-NEXT: Search: Library -// CHECK-NEXT: Unused: (00 00 00 00 00 00 00 00 00 00) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: Symbol { // CHECK: Name: .weak._test_weak.default // CHECK-NEXT: Value: 0 -// CHECK-NEXT: Section: (65535) +// CHECK-NEXT: Section: (-1) // CHECK-NEXT: BaseType: Null // CHECK-NEXT: ComplexType: Null // CHECK-NEXT: StorageClass: External @@ -70,6 +69,5 @@ LBB0_2: # %return // CHECK-NEXT: AuxWeakExternal { // CHECK-NEXT: Linked: _main // CHECK-NEXT: Search: Library -// CHECK-NEXT: Unused: (00 00 00 00 00 00 00 00 00 00) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/llvm/test/tools/llvm-readobj/Inputs/bigobj.coff-x86-64 b/llvm/test/tools/llvm-readobj/Inputs/bigobj.coff-x86-64 new file mode 100644 index 000000000000..fdfda5e5713a Binary files /dev/null and b/llvm/test/tools/llvm-readobj/Inputs/bigobj.coff-x86-64 differ diff --git a/llvm/test/tools/llvm-readobj/bigobj.test b/llvm/test/tools/llvm-readobj/bigobj.test new file mode 100644 index 000000000000..361a9e44fe6f --- /dev/null +++ b/llvm/test/tools/llvm-readobj/bigobj.test @@ -0,0 +1,139 @@ +RUN: llvm-readobj --file-headers --sections --symbols --relocations %p/Inputs/bigobj.coff-x86-64 | FileCheck %s + +CHECK: File: {{(.*[/\\])?}}bigobj.coff-x86-64 +CHECK-NEXT: Format: COFF-x86-64 +CHECK-NEXT: Arch: x86_64 +CHECK-NEXT: AddressSize: 64bit +CHECK-NEXT: ImageFileHeader { +CHECK-NEXT: Machine: IMAGE_FILE_MACHINE_AMD64 (0x8664) +CHECK-NEXT: SectionCount: 3 +CHECK-NEXT: TimeDateStamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT: PointerToSymbolTable: 0xB0 +CHECK-NEXT: SymbolCount: 8 +CHECK-NEXT: OptionalHeaderSize: 0 +CHECK-NEXT: Characteristics [ (0x0) +CHECK-NEXT: ] +CHECK-NEXT: } +CHECK-NEXT: Sections [ +CHECK-NEXT: Section { +CHECK-NEXT: Number: 1 +CHECK-NEXT: Name: .text (2E 74 65 78 74 00 00 00) +CHECK-NEXT: VirtualSize: 0x0 +CHECK-NEXT: VirtualAddress: 0x0 +CHECK-NEXT: RawDataSize: 0 +CHECK-NEXT: PointerToRawData: 0x0 +CHECK-NEXT: PointerToRelocations: 0x0 +CHECK-NEXT: PointerToLineNumbers: 0x0 +CHECK-NEXT: RelocationCount: 0 +CHECK-NEXT: LineNumberCount: 0 +CHECK-NEXT: Characteristics [ (0x60500020) +CHECK-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000) +CHECK-NEXT: IMAGE_SCN_CNT_CODE (0x20) +CHECK-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000) +CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +CHECK-NEXT: ] +CHECK-NEXT: } +CHECK-NEXT: Section { +CHECK-NEXT: Number: 2 +CHECK-NEXT: Name: .data (2E 64 61 74 61 00 00 00) +CHECK-NEXT: VirtualSize: 0x0 +CHECK-NEXT: VirtualAddress: 0x0 +CHECK-NEXT: RawDataSize: 0 +CHECK-NEXT: PointerToRawData: 0x0 +CHECK-NEXT: PointerToRelocations: 0x0 +CHECK-NEXT: PointerToLineNumbers: 0x0 +CHECK-NEXT: RelocationCount: 0 +CHECK-NEXT: LineNumberCount: 0 +CHECK-NEXT: Characteristics [ (0xC0500040) +CHECK-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000) +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +CHECK-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) +CHECK-NEXT: ] +CHECK-NEXT: } +CHECK-NEXT: Section { +CHECK-NEXT: Number: 3 +CHECK-NEXT: Name: .bss (2E 62 73 73 00 00 00 00) +CHECK-NEXT: VirtualSize: 0x0 +CHECK-NEXT: VirtualAddress: 0x0 +CHECK-NEXT: RawDataSize: 0 +CHECK-NEXT: PointerToRawData: 0x0 +CHECK-NEXT: PointerToRelocations: 0x0 +CHECK-NEXT: PointerToLineNumbers: 0x0 +CHECK-NEXT: RelocationCount: 0 +CHECK-NEXT: LineNumberCount: 0 +CHECK-NEXT: Characteristics [ (0xC0500080) +CHECK-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000) +CHECK-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80) +CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +CHECK-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) +CHECK-NEXT: ] +CHECK-NEXT: } +CHECK-NEXT: ] +CHECK-NEXT: Relocations [ +CHECK-NEXT: ] +CHECK-NEXT: Symbols [ +CHECK-NEXT: Symbol { +CHECK-NEXT: Name: .file +CHECK-NEXT: Value: 0 +CHECK-NEXT: Section: (-2) +CHECK-NEXT: BaseType: Null (0x0) +CHECK-NEXT: ComplexType: Null (0x0) +CHECK-NEXT: StorageClass: File (0x67) +CHECK-NEXT: AuxSymbolCount: 1 +CHECK-NEXT: AuxFileRecord { +CHECK-NEXT: FileName: fake +CHECK-NEXT: } +CHECK-NEXT: } +CHECK-NEXT: Symbol { +CHECK-NEXT: Name: .text +CHECK-NEXT: Value: 0 +CHECK-NEXT: Section: .text (1) +CHECK-NEXT: BaseType: Null (0x0) +CHECK-NEXT: ComplexType: Null (0x0) +CHECK-NEXT: StorageClass: Static (0x3) +CHECK-NEXT: AuxSymbolCount: 1 +CHECK-NEXT: AuxSectionDef { +CHECK-NEXT: Length: 0 +CHECK-NEXT: RelocationCount: 0 +CHECK-NEXT: LineNumberCount: 0 +CHECK-NEXT: Checksum: 0x0 +CHECK-NEXT: Number: 0 +CHECK-NEXT: Selection: 0x0 +CHECK-NEXT: } +CHECK-NEXT: } +CHECK-NEXT: Symbol { +CHECK-NEXT: Name: .data +CHECK-NEXT: Value: 0 +CHECK-NEXT: Section: .data (2) +CHECK-NEXT: BaseType: Null (0x0) +CHECK-NEXT: ComplexType: Null (0x0) +CHECK-NEXT: StorageClass: Static (0x3) +CHECK-NEXT: AuxSymbolCount: 1 +CHECK-NEXT: AuxSectionDef { +CHECK-NEXT: Length: 0 +CHECK-NEXT: RelocationCount: 0 +CHECK-NEXT: LineNumberCount: 0 +CHECK-NEXT: Checksum: 0x0 +CHECK-NEXT: Number: 0 +CHECK-NEXT: Selection: 0x0 +CHECK-NEXT: } +CHECK-NEXT: } +CHECK-NEXT: Symbol { +CHECK-NEXT: Name: .bss +CHECK-NEXT: Value: 0 +CHECK-NEXT: Section: .bss (3) +CHECK-NEXT: BaseType: Null (0x0) +CHECK-NEXT: ComplexType: Null (0x0) +CHECK-NEXT: StorageClass: Static (0x3) +CHECK-NEXT: AuxSymbolCount: 1 +CHECK-NEXT: AuxSectionDef { +CHECK-NEXT: Length: 0 +CHECK-NEXT: RelocationCount: 0 +CHECK-NEXT: LineNumberCount: 0 +CHECK-NEXT: Checksum: 0x0 +CHECK-NEXT: Number: 0 +CHECK-NEXT: Selection: 0x0 +CHECK-NEXT: } +CHECK-NEXT: } +CHECK-NEXT: ] diff --git a/llvm/test/tools/llvm-readobj/coff-file-sections-reading.test b/llvm/test/tools/llvm-readobj/coff-file-sections-reading.test index 5c44c16f0058..846247fd9cfb 100644 --- a/llvm/test/tools/llvm-readobj/coff-file-sections-reading.test +++ b/llvm/test/tools/llvm-readobj/coff-file-sections-reading.test @@ -4,7 +4,7 @@ CHECK: Symbols [ CHECK: Symbol { CHECK: Name: .file CHECK: Value: 0 -CHECK: Section: (65534) +CHECK: Section: (-2) CHECK: BaseType: Null (0x0) CHECK: ComplexType: Null (0x0) CHECK: StorageClass: File (0x67) diff --git a/llvm/test/tools/llvm-readobj/cxx-cli-aux.test b/llvm/test/tools/llvm-readobj/cxx-cli-aux.test index 90e73c033a86..cac9e71c2524 100644 --- a/llvm/test/tools/llvm-readobj/cxx-cli-aux.test +++ b/llvm/test/tools/llvm-readobj/cxx-cli-aux.test @@ -9,7 +9,7 @@ CHECK: Symbols [ CHECK: Symbol { CHECK: Name: ?PerAppDomain@@$$Q3HA CHECK-NEXT: Value: 4 -CHECK-NEXT: Section: (65535) +CHECK-NEXT: Section: (-1) CHECK-NEXT: BaseType: Null (0x0) CHECK-NEXT: ComplexType: Null (0x0) CHECK-NEXT: StorageClass: External (0x2) @@ -21,14 +21,13 @@ CHECK-NEXT: LineNumberCount: 0 CHECK-NEXT: Checksum: 0x0 CHECK-NEXT: Number: 0 CHECK-NEXT: Selection: NoDuplicates (0x1) -CHECK-NEXT: Unused: (00 00 00) CHECK-NEXT: } CHECK-NEXT: } CHECK: Symbol { CHECK: Name: 04000001 CHECK-NEXT: Value: 4 -CHECK-NEXT: Section: (65535) +CHECK-NEXT: Section: (-1) CHECK-NEXT: BaseType: Null (0x0) CHECK-NEXT: ComplexType: Null (0x0) CHECK-NEXT: StorageClass: CLRToken (0x6B) @@ -37,6 +36,5 @@ CHECK-NEXT: AuxCLRToken { CHECK-NEXT: AuxType: 1 CHECK-NEXT: Reserved: 0 CHECK-NEXT: SymbolTableIndex: ?PerAppDomain@@$$Q3HA (19) -CHECK-NEXT: Unused: (00 00 00 00 00 00 00 00 00 00 00 00) CHECK-NEXT: } CHECK-NEXT: } diff --git a/llvm/test/tools/llvm-readobj/sections-ext.test b/llvm/test/tools/llvm-readobj/sections-ext.test index 972d8e6f4ef7..4024878d2bde 100644 --- a/llvm/test/tools/llvm-readobj/sections-ext.test +++ b/llvm/test/tools/llvm-readobj/sections-ext.test @@ -52,7 +52,6 @@ COFF-NEXT: LineNumberCount: 0 COFF-NEXT: Checksum: 0x0 COFF-NEXT: Number: 1 COFF-NEXT: Selection: 0x0 -COFF-NEXT: Unused: (00 00 00) COFF-NEXT: } COFF-NEXT: } COFF-NEXT: Symbol { diff --git a/llvm/test/tools/llvm-readobj/symbols.test b/llvm/test/tools/llvm-readobj/symbols.test index 26830ac46a8a..3876138f9d23 100644 --- a/llvm/test/tools/llvm-readobj/symbols.test +++ b/llvm/test/tools/llvm-readobj/symbols.test @@ -7,7 +7,7 @@ COFF: Symbols [ COFF-NEXT: Symbol { COFF-NEXT: Name: @comp.id COFF-NEXT: Value: 14766605 -COFF-NEXT: Section: (65535) +COFF-NEXT: Section: (-1) COFF-NEXT: BaseType: Null (0x0) COFF-NEXT: ComplexType: Null (0x0) COFF-NEXT: StorageClass: Static (0x3) @@ -16,7 +16,7 @@ COFF-NEXT: } COFF-NEXT: Symbol { COFF-NEXT: Name: @feat.00 COFF-NEXT: Value: 2147484049 -COFF-NEXT: Section: (65535) +COFF-NEXT: Section: (-1) COFF-NEXT: BaseType: Null (0x0) COFF-NEXT: ComplexType: Null (0x0) COFF-NEXT: StorageClass: Static (0x3) @@ -37,7 +37,6 @@ COFF-NEXT: LineNumberCount: 0 COFF-NEXT: Checksum: 0x0 COFF-NEXT: Number: 1 COFF-NEXT: Selection: 0x0 -COFF-NEXT: Unused: (00 00 00) COFF-NEXT: } COFF-NEXT: } diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp index 6c3a9e27b71c..3002119cc518 100644 --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -686,7 +686,7 @@ static char getSymbolNMTypeChar(ELFObjectFile &Obj, } static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { - const coff_symbol *Symb = Obj.getCOFFSymbol(*I); + COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); // OK, this is COFF. symbol_iterator SymI(I); @@ -703,7 +703,7 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { return Ret; uint32_t Characteristics = 0; - if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) { + if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { section_iterator SecI = Obj.section_end(); if (error(SymI->getSection(SecI))) return '?'; @@ -711,7 +711,7 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { Characteristics = Section->Characteristics; } - switch (Symb->SectionNumber) { + switch (Symb.getSectionNumber()) { case COFF::IMAGE_SYM_DEBUG: return 'n'; default: @@ -729,7 +729,7 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { return 'i'; // Check for section symbol. - else if (Symb->isSectionDefinition()) + else if (Symb.isSectionDefinition()) return 's'; } diff --git a/llvm/tools/llvm-objdump/COFFDump.cpp b/llvm/tools/llvm-objdump/COFFDump.cpp index 39d8e8e39f8c..818969114bae 100644 --- a/llvm/tools/llvm-objdump/COFFDump.cpp +++ b/llvm/tools/llvm-objdump/COFFDump.cpp @@ -260,11 +260,8 @@ static void printLoadConfiguration(const COFFObjectFile *Obj) { if (!PE32Header) return; - const coff_file_header *Header; - if (error(Obj->getCOFFHeader(Header))) - return; // Currently only x86 is supported - if (Header->Machine != COFF::IMAGE_FILE_MACHINE_I386) + if (Obj->getMachine() != COFF::IMAGE_FILE_MACHINE_I386) return; const data_directory *DataDir; @@ -518,11 +515,7 @@ static void printRuntimeFunctionRels(const COFFObjectFile *Obj, } void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { - const coff_file_header *Header; - if (error(Obj->getCOFFHeader(Header))) - return; - - if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) { + if (Obj->getMachine() != COFF::IMAGE_FILE_MACHINE_AMD64) { errs() << "Unsupported image machine type " "(currently only AMD64 is supported).\n"; return; diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index c91555dc7b70..7debbe9a961b 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -564,29 +564,25 @@ static void PrintSectionContents(const ObjectFile *Obj) { } static void PrintCOFFSymbolTable(const COFFObjectFile *coff) { - const coff_file_header *header; - if (error(coff->getHeader(header))) - return; - - for (unsigned SI = 0, SE = header->NumberOfSymbols; SI != SE; ++SI) { - const coff_symbol *Symbol; + for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) { + ErrorOr Symbol = coff->getSymbol(SI); StringRef Name; - if (error(coff->getSymbol(SI, Symbol))) + if (error(Symbol.getError())) return; - if (error(coff->getSymbolName(Symbol, Name))) + if (error(coff->getSymbolName(*Symbol, Name))) return; outs() << "[" << format("%2d", SI) << "]" - << "(sec " << format("%2d", int(Symbol->SectionNumber)) << ")" + << "(sec " << format("%2d", int(Symbol->getSectionNumber())) << ")" << "(fl 0x00)" // Flag bits, which COFF doesn't have. - << "(ty " << format("%3x", unsigned(Symbol->Type)) << ")" - << "(scl " << format("%3x", unsigned(Symbol->StorageClass)) << ") " - << "(nx " << unsigned(Symbol->NumberOfAuxSymbols) << ") " - << "0x" << format("%08x", unsigned(Symbol->Value)) << " " + << "(ty " << format("%3x", unsigned(Symbol->getType())) << ")" + << "(scl " << format("%3x", unsigned(Symbol->getStorageClass())) << ") " + << "(nx " << unsigned(Symbol->getNumberOfAuxSymbols()) << ") " + << "0x" << format("%08x", unsigned(Symbol->getValue())) << " " << Name << "\n"; - for (unsigned AI = 0, AE = Symbol->NumberOfAuxSymbols; AI < AE; ++AI, ++SI) { + for (unsigned AI = 0, AE = Symbol->getNumberOfAuxSymbols(); AI < AE; ++AI, ++SI) { if (Symbol->isSectionDefinition()) { const coff_aux_section_definition *asd; if (error(coff->getAuxSymbol(SI + 1, asd))) @@ -602,15 +598,15 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) { , unsigned(asd->Number) , unsigned(asd->Selection)); } else if (Symbol->isFileRecord()) { - const coff_aux_file *AF; - if (error(coff->getAuxSymbol(SI + 1, AF))) + const char *FileName; + if (error(coff->getAuxSymbol(SI + 1, FileName))) return; - StringRef Name(AF->FileName, - Symbol->NumberOfAuxSymbols * COFF::SymbolSize); + StringRef Name(FileName, Symbol->getNumberOfAuxSymbols() * + coff->getSymbolTableEntrySize()); outs() << "AUX " << Name.rtrim(StringRef("\0", 1)) << '\n'; - SI = SI + Symbol->NumberOfAuxSymbols; + SI = SI + Symbol->getNumberOfAuxSymbols(); break; } else { outs() << "AUX Unknown\n"; diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 68a403cc2387..b2cf331761c6 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -313,9 +313,10 @@ WeakExternalCharacteristics[] = { template static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, - const coff_symbol *Symbol, - const T *&Aux) { + COFFSymbolRef Symbol, + uint8_t AuxSymbolIdx, const T *&Aux) { ArrayRef AuxData = Obj->getSymbolAuxData(Symbol); + AuxData = AuxData.slice(AuxSymbolIdx * Obj->getSymbolTableEntrySize()); Aux = reinterpret_cast(AuxData.data()); return readobj_error::success; } @@ -342,25 +343,20 @@ void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName } void COFFDumper::printFileHeaders() { - // Print COFF header - const coff_file_header *COFFHeader = nullptr; - if (error(Obj->getCOFFHeader(COFFHeader))) - return; - - time_t TDS = COFFHeader->TimeDateStamp; + time_t TDS = Obj->getTimeDateStamp(); char FormattedTime[20] = { }; strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS)); { DictScope D(W, "ImageFileHeader"); - W.printEnum ("Machine", COFFHeader->Machine, + W.printEnum ("Machine", Obj->getMachine(), makeArrayRef(ImageFileMachineType)); - 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, + W.printNumber("SectionCount", Obj->getNumberOfSections()); + W.printHex ("TimeDateStamp", FormattedTime, Obj->getTimeDateStamp()); + W.printHex ("PointerToSymbolTable", Obj->getPointerToSymbolTable()); + W.printNumber("SymbolCount", Obj->getNumberOfSymbols()); + W.printNumber("OptionalHeaderSize", Obj->getSizeOfOptionalHeader()); + W.printFlags ("Characteristics", Obj->getCharacteristics(), makeArrayRef(ImageFileCharacteristics)); } @@ -722,9 +718,9 @@ void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); } void COFFDumper::printSymbol(const SymbolRef &Sym) { DictScope D(W, "Symbol"); - const coff_symbol *Symbol = Obj->getCOFFSymbol(Sym); + COFFSymbolRef Symbol = Obj->getCOFFSymbol(Sym); const coff_section *Section; - if (std::error_code EC = Obj->getSection(Symbol->SectionNumber, Section)) { + if (std::error_code EC = Obj->getSection(Symbol.getSectionNumber(), Section)) { W.startLine() << "Invalid section number: " << EC.message() << "\n"; W.flush(); return; @@ -739,19 +735,19 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { Obj->getSectionName(Section, SectionName); W.printString("Name", SymbolName); - W.printNumber("Value", Symbol->Value); - W.printNumber("Section", SectionName, Symbol->SectionNumber); - W.printEnum ("BaseType", Symbol->getBaseType(), makeArrayRef(ImageSymType)); - W.printEnum ("ComplexType", Symbol->getComplexType(), + W.printNumber("Value", Symbol.getValue()); + W.printNumber("Section", SectionName, Symbol.getSectionNumber()); + W.printEnum ("BaseType", Symbol.getBaseType(), makeArrayRef(ImageSymType)); + W.printEnum ("ComplexType", Symbol.getComplexType(), makeArrayRef(ImageSymDType)); - W.printEnum ("StorageClass", Symbol->StorageClass, + W.printEnum ("StorageClass", Symbol.getStorageClass(), makeArrayRef(ImageSymClass)); - W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols); + W.printNumber("AuxSymbolCount", Symbol.getNumberOfAuxSymbols()); - for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) { - if (Symbol->isFunctionDefinition()) { + for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) { + if (Symbol.isFunctionDefinition()) { const coff_aux_function_definition *Aux; - if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) break; DictScope AS(W, "AuxFunctionDef"); @@ -759,18 +755,16 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printNumber("TotalSize", Aux->TotalSize); W.printHex("PointerToLineNumber", Aux->PointerToLinenumber); W.printHex("PointerToNextFunction", Aux->PointerToNextFunction); - W.printBinary("Unused", makeArrayRef(Aux->Unused)); - } else if (Symbol->isWeakExternal()) { + } else if (Symbol.isWeakExternal()) { const coff_aux_weak_external *Aux; - if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) break; - const coff_symbol *Linked; + ErrorOr Linked = Obj->getSymbol(Aux->TagIndex); StringRef LinkedName; - std::error_code EC; - if ((EC = Obj->getSymbol(Aux->TagIndex, Linked)) || - (EC = Obj->getSymbolName(Linked, LinkedName))) { + std::error_code EC = Linked.getError(); + if (EC || (EC = Obj->getSymbolName(*Linked, LinkedName))) { LinkedName = ""; error(EC); } @@ -779,22 +773,21 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printNumber("Linked", LinkedName, Aux->TagIndex); W.printEnum ("Search", Aux->Characteristics, makeArrayRef(WeakExternalCharacteristics)); - W.printBinary("Unused", makeArrayRef(Aux->Unused)); - } else if (Symbol->isFileRecord()) { - const coff_aux_file *Aux; - if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + } else if (Symbol.isFileRecord()) { + const char *FileName; + if (error(getSymbolAuxData(Obj, Symbol, I, FileName))) break; DictScope AS(W, "AuxFileRecord"); - StringRef Name(Aux->FileName, - Symbol->NumberOfAuxSymbols * COFF::SymbolSize); + StringRef Name(FileName, Symbol.getNumberOfAuxSymbols() * + Obj->getSymbolTableEntrySize()); W.printString("FileName", Name.rtrim(StringRef("\0", 1))); break; - } else if (Symbol->isSectionDefinition()) { + } else if (Symbol.isSectionDefinition()) { const coff_aux_section_definition *Aux; - if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) break; DictScope AS(W, "AuxSectionDef"); @@ -804,7 +797,6 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printHex("Checksum", Aux->CheckSum); W.printNumber("Number", Aux->Number); W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect)); - W.printBinary("Unused", makeArrayRef(Aux->Unused)); if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { @@ -819,16 +811,16 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printNumber("AssocSection", AssocName, Aux->Number); } - } else if (Symbol->isCLRToken()) { + } else if (Symbol.isCLRToken()) { const coff_aux_clr_token *Aux; - if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + if (error(getSymbolAuxData(Obj, Symbol, I, Aux))) break; - const coff_symbol *ReferredSym; + ErrorOr ReferredSym = + Obj->getSymbol(Aux->SymbolTableIndex); StringRef ReferredName; - std::error_code EC; - if ((EC = Obj->getSymbol(Aux->SymbolTableIndex, ReferredSym)) || - (EC = Obj->getSymbolName(ReferredSym, ReferredName))) { + std::error_code EC = ReferredSym.getError(); + if (EC || (EC = Obj->getSymbolName(*ReferredSym, ReferredName))) { ReferredName = ""; error(EC); } @@ -837,7 +829,6 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printNumber("AuxType", Aux->AuxType); W.printNumber("Reserved", Aux->Reserved); W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex); - W.printBinary("Unused", makeArrayRef(Aux->Unused)); } else { W.startLine() << "\n"; @@ -846,12 +837,8 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { } void COFFDumper::printUnwindInfo() { - const coff_file_header *Header; - if (error(Obj->getCOFFHeader(Header))) - return; - ListScope D(W, "UnwindInformation"); - switch (Header->Machine) { + switch (Obj->getMachine()) { case COFF::IMAGE_FILE_MACHINE_AMD64: { Win64EH::Dumper Dumper(W); Win64EH::Dumper::SymbolResolver @@ -870,7 +857,7 @@ void COFFDumper::printUnwindInfo() { break; } default: - W.printEnum("unsupported Image Machine", Header->Machine, + W.printEnum("unsupported Image Machine", Obj->getMachine(), makeArrayRef(ImageFileMachineType)); break; } diff --git a/llvm/tools/obj2yaml/coff2yaml.cpp b/llvm/tools/obj2yaml/coff2yaml.cpp index fed4533a982c..dd0db9233f85 100644 --- a/llvm/tools/obj2yaml/coff2yaml.cpp +++ b/llvm/tools/obj2yaml/coff2yaml.cpp @@ -20,7 +20,7 @@ namespace { class COFFDumper { const object::COFFObjectFile &Obj; COFFYAML::Object YAMLObj; - void dumpHeader(const object::coff_file_header *Header); + void dumpHeader(); void dumpSections(unsigned numSections); void dumpSymbols(unsigned numSymbols); @@ -31,22 +31,15 @@ public: } -static void check(std::error_code ec) { - if (ec) - report_fatal_error(ec.message()); -} - COFFDumper::COFFDumper(const object::COFFObjectFile &Obj) : Obj(Obj) { - const object::coff_file_header *Header; - check(Obj.getCOFFHeader(Header)); - dumpHeader(Header); - dumpSections(Header->NumberOfSections); - dumpSymbols(Header->NumberOfSymbols); + dumpHeader(); + dumpSections(Obj.getNumberOfSections()); + dumpSymbols(Obj.getNumberOfSymbols()); } -void COFFDumper::dumpHeader(const object::coff_file_header *Header) { - YAMLObj.Header.Machine = Header->Machine; - YAMLObj.Header.Characteristics = Header->Characteristics; +void COFFDumper::dumpHeader() { + YAMLObj.Header.Machine = Obj.getMachine(); + YAMLObj.Header.Characteristics = Obj.getCharacteristics(); } void COFFDumper::dumpSections(unsigned NumSections) { @@ -136,63 +129,64 @@ dumpCLRTokenDefinition(COFFYAML::Symbol *Sym, void COFFDumper::dumpSymbols(unsigned NumSymbols) { std::vector &Symbols = YAMLObj.Symbols; for (const auto &S : Obj.symbols()) { - const object::coff_symbol *Symbol = Obj.getCOFFSymbol(S); + object::COFFSymbolRef Symbol = Obj.getCOFFSymbol(S); COFFYAML::Symbol Sym; Obj.getSymbolName(Symbol, Sym.Name); - Sym.SimpleType = COFF::SymbolBaseType(Symbol->getBaseType()); - Sym.ComplexType = COFF::SymbolComplexType(Symbol->getComplexType()); - Sym.Header.StorageClass = Symbol->StorageClass; - Sym.Header.Value = Symbol->Value; - Sym.Header.SectionNumber = Symbol->SectionNumber; - Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols; + Sym.SimpleType = COFF::SymbolBaseType(Symbol.getBaseType()); + Sym.ComplexType = COFF::SymbolComplexType(Symbol.getComplexType()); + Sym.Header.StorageClass = Symbol.getStorageClass(); + Sym.Header.Value = Symbol.getValue(); + Sym.Header.SectionNumber = Symbol.getSectionNumber(); + Sym.Header.NumberOfAuxSymbols = Symbol.getNumberOfAuxSymbols(); - if (Symbol->NumberOfAuxSymbols > 0) { + if (Symbol.getNumberOfAuxSymbols() > 0) { ArrayRef AuxData = Obj.getSymbolAuxData(Symbol); - if (Symbol->isFunctionDefinition()) { + if (Symbol.isFunctionDefinition()) { // This symbol represents a function definition. - assert(Symbol->NumberOfAuxSymbols == 1 && + assert(Symbol.getNumberOfAuxSymbols() == 1 && "Expected a single aux symbol to describe this function!"); const object::coff_aux_function_definition *ObjFD = reinterpret_cast( AuxData.data()); dumpFunctionDefinition(&Sym, ObjFD); - } else if (Symbol->isFunctionLineInfo()) { + } else if (Symbol.isFunctionLineInfo()) { // This symbol describes function line number information. - assert(Symbol->NumberOfAuxSymbols == 1 && - "Exepected a single aux symbol to describe this section!"); + assert(Symbol.getNumberOfAuxSymbols() == 1 && + "Expected a single aux symbol to describe this function!"); const object::coff_aux_bf_and_ef_symbol *ObjBES = reinterpret_cast( AuxData.data()); dumpbfAndEfLineInfo(&Sym, ObjBES); - } else if (Symbol->isWeakExternal()) { + } else if (Symbol.isWeakExternal()) { // This symbol represents a weak external definition. - assert(Symbol->NumberOfAuxSymbols == 1 && - "Exepected a single aux symbol to describe this section!"); + assert(Symbol.getNumberOfAuxSymbols() == 1 && + "Expected a single aux symbol to describe this weak symbol!"); const object::coff_aux_weak_external *ObjWE = reinterpret_cast( AuxData.data()); dumpWeakExternal(&Sym, ObjWE); - } else if (Symbol->isFileRecord()) { + } else if (Symbol.isFileRecord()) { // This symbol represents a file record. Sym.File = StringRef(reinterpret_cast(AuxData.data()), - Symbol->NumberOfAuxSymbols * COFF::SymbolSize) + Symbol.getNumberOfAuxSymbols() * + Obj.getSymbolTableEntrySize()) .rtrim(StringRef("\0", /*length=*/1)); - } else if (Symbol->isSectionDefinition()) { + } else if (Symbol.isSectionDefinition()) { // This symbol represents a section definition. - assert(Symbol->NumberOfAuxSymbols == 1 && + assert(Symbol.getNumberOfAuxSymbols() == 1 && "Expected a single aux symbol to describe this section!"); const object::coff_aux_section_definition *ObjSD = reinterpret_cast( AuxData.data()); dumpSectionDefinition(&Sym, ObjSD); - } else if (Symbol->isCLRToken()) { + } else if (Symbol.isCLRToken()) { // This symbol represents a CLR token definition. - assert(Symbol->NumberOfAuxSymbols == 1 && - "Expected a single aux symbol to describe this CLR Token"); + assert(Symbol.getNumberOfAuxSymbols() == 1 && + "Expected a single aux symbol to describe this CLR Token!"); const object::coff_aux_clr_token *ObjCLRToken = reinterpret_cast(