Index: llvm/trunk/include/llvm/Object/COFF.h =================================================================== --- llvm/trunk/include/llvm/Object/COFF.h +++ llvm/trunk/include/llvm/Object/COFF.h @@ -20,9 +20,7 @@ #include "llvm/Object/Binary.h" #include "llvm/Object/Error.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/COFF.h" -#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" @@ -42,7 +40,6 @@ class ExportDirectoryEntryRef; class ImportDirectoryEntryRef; class ImportedSymbolRef; -class ResourceSectionRef; using import_directory_iterator = content_iterator; using delay_import_directory_iterator = @@ -626,26 +623,6 @@ int getOffset() const { return Data & ((1 << 12) - 1); } }; -struct coff_resource_dir_entry { - union { - support::ulittle32_t NameOffset; - support::ulittle32_t ID; - uint32_t getNameOffset() const { - return maskTrailingOnes(31) & NameOffset; - } - } Identifier; - union { - support::ulittle32_t DataEntryOffset; - support::ulittle32_t SubdirOffset; - - bool isSubDir() const { return SubdirOffset >> 31; } - uint32_t value() const { - return maskTrailingOnes(31) & SubdirOffset; - } - - } Offset; -}; - struct coff_resource_dir_table { support::ulittle32_t Characteristics; support::ulittle32_t TimeDateStamp; @@ -1070,23 +1047,6 @@ const COFFObjectFile *OwningObject = nullptr; }; -class ResourceSectionRef { -public: - ResourceSectionRef() = default; - explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {} - - ErrorOr> getEntryNameString(const coff_resource_dir_entry &Entry); - ErrorOr - getEntrySubDir(const coff_resource_dir_entry &Entry); - ErrorOr getBaseTable(); - -private: - BinaryByteStream BBS; - - ErrorOr getTableAtOffset(uint32_t Offset); - ErrorOr> getDirStringAtOffset(uint32_t Offset); -}; - // Corresponds to `_FPO_DATA` structure in the PE/COFF spec. struct FpoData { support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code Index: llvm/trunk/include/llvm/Support/COFF.h =================================================================== --- llvm/trunk/include/llvm/Support/COFF.h +++ llvm/trunk/include/llvm/Support/COFF.h @@ -152,30 +152,6 @@ IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 }; - enum ResourceTypeID { - RID_Cursor = 1, - RID_Bitmap = 2, - RID_Icon = 3, - RID_Menu = 4, - RID_Dialog = 5, - RID_String = 6, - RID_FontDir = 7, - RID_Font = 8, - RID_Accelerator = 9, - RID_RCData = 10, - RID_MessageTable = 11, - RID_Group_Cursor = 12, - RID_Group_Icon = 14, - RID_Version = 16, - RID_DLGInclude = 17, - RID_PlugPlay = 19, - RID_VXD = 20, - RID_AniCursor = 21, - RID_AniIcon = 22, - RID_HTML = 23, - RID_Manifest = 24, - }; - struct symbol { char Name[NameSize]; uint32_t Value; Index: llvm/trunk/lib/Object/COFFObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/COFFObjectFile.cpp +++ llvm/trunk/lib/Object/COFFObjectFile.cpp @@ -19,7 +19,6 @@ #include "llvm/Object/COFF.h" #include "llvm/Object/Error.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -160,7 +159,8 @@ Expected COFFObjectFile::getSymbolName(DataRefImpl Ref) const { COFFSymbolRef Symb = getCOFFSymbol(Ref); StringRef Result; - if (std::error_code EC = getSymbolName(Symb, Result)) + std::error_code EC = getSymbolName(Symb, Result); + if (EC) return errorCodeToError(EC); return Result; } @@ -1591,44 +1591,3 @@ Result = Header->PageRVA + Entry[Index].getOffset(); return std::error_code(); } - -#define RETURN_IF_ERROR(X) \ - if (auto EC = errorToErrorCode(X)) \ - return EC; - -ErrorOr> ResourceSectionRef::getDirStringAtOffset(uint32_t Offset) { - BinaryStreamReader Reader = BinaryStreamReader(BBS); - Reader.setOffset(Offset); - uint16_t Length; - RETURN_IF_ERROR(Reader.readInteger(Length)); - ArrayRef RawDirString; - // Strings are stored as 2-byte aligned unicode characters but readFixedString - // assumes byte string, so we double length. - RETURN_IF_ERROR(Reader.readArray(RawDirString, Length)); - return RawDirString; -} - -ErrorOr> -ResourceSectionRef::getEntryNameString(const coff_resource_dir_entry &Entry) { - return getDirStringAtOffset(Entry.Identifier.getNameOffset()); -} - -ErrorOr -ResourceSectionRef::getTableAtOffset(uint32_t Offset) { - const coff_resource_dir_table *Table = nullptr; - - BinaryStreamReader Reader(BBS); - Reader.setOffset(Offset); - RETURN_IF_ERROR(Reader.readObject(Table)); - assert(Table != nullptr); - return *Table; -} - -ErrorOr -ResourceSectionRef::getEntrySubDir(const coff_resource_dir_entry &Entry) { - return getTableAtOffset(Entry.Offset.value()); -} - -ErrorOr ResourceSectionRef::getBaseTable() { - return getTableAtOffset(0); -} Index: llvm/trunk/test/tools/llvm-readobj/Inputs/resources/test_resource.rc =================================================================== --- llvm/trunk/test/tools/llvm-readobj/Inputs/resources/test_resource.rc +++ llvm/trunk/test/tools/llvm-readobj/Inputs/resources/test_resource.rc @@ -1,44 +0,0 @@ -#include "windows.h" - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -myaccelerators ACCELERATORS -{ - "^C", 999, VIRTKEY, ALT - "D", 1100, VIRTKEY, CONTROL, SHIFT - "^R", 444, ASCII, NOINVERT -} - -cursor BITMAP "cursor_small.bmp" -okay BITMAP "okay_small.bmp" - -14432 MENU -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -{ - MENUITEM "yu", 100 - MENUITEM "shala", 101 - MENUITEM "kaoya", 102 -} - -testdialog DIALOG 10, 10, 200, 300 -STYLE WS_POPUP | WS_BORDER -CAPTION "Test" -{ - CTEXT "Continue:", 1, 10, 10, 230, 14 - PUSHBUTTON "&OK", 2, 66, 134, 161, 13 -} - -12 ACCELERATORS -{ - "X", 164, VIRTKEY, ALT - "H", 5678, VIRTKEY, CONTROL, SHIFT - "^R", 444, ASCII, NOINVERT -} - -"eat" MENU -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS -{ - MENUITEM "fish", 100 - MENUITEM "salad", 101 - MENUITEM "duck", 102 -} Index: llvm/trunk/test/tools/llvm-readobj/resources.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/resources.test +++ llvm/trunk/test/tools/llvm-readobj/resources.test @@ -1,111 +1,19 @@ -// Check dumping of the .rsrc section(s) -// The input was generated with the following commands, using the original Windows -// rc.exe and cvtres.exe: -// > rc /fo test_resource.res /nologo test_resource.rc -// > cvtres /machine:X86 /readonly /nologo /out:test_resource.o test_resource.res +RUN: llvm-readobj -coff-resources %p/Inputs/zero-string-table.obj.coff-i386 \ +RUN: | FileCheck %s -check-prefix RESOURCE -RUN: llvm-readobj -coff-resources -section-data %p/Inputs/zero-string-table.obj.coff-i386 \ -RUN: | FileCheck %s -check-prefix ZERO -RUN: llvm-readobj -coff-resources %p/Inputs/resources/test_resource.obj.coff \ -RUN: | FileCheck %s -check-prefix TEST_RES - -ZERO: Resources [ -ZERO-NEXT: String Name Entries: 0 -ZERO-NEXT: ID Entries: 1 -ZERO-NEXT: Type: kRT_STRING (ID 6) [ -ZERO-NEXT: String Name Entries: 0 -ZERO-NEXT: ID Entries: 1 -ZERO-NEXT: Name: (ID 1) [ -ZERO-NEXT: String Name Entries: 0 -ZERO-NEXT: ID Entries: 1 -ZERO-NEXT: Language: (ID 1033) [ -ZERO-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -ZERO-NEXT: Major Version: 0 -ZERO-NEXT: Minor Version: 0 -ZERO-NEXT: ] -ZERO-NEXT: ] -ZERO-NEXT: ] - - -TEST_RES: Resources [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 4 -TEST_RES-NEXT: Type: kRT_BITMAP (ID 2) [ -TEST_RES-NEXT: String Name Entries: 2 -TEST_RES-NEXT: ID Entries: 0 -TEST_RES-NEXT: Name: CURSOR [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Language: (ID 1033) [ -TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT: Major Version: 0 -TEST_RES-NEXT: Minor Version: 0 -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: Name: OKAY [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Language: (ID 1033) [ -TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT: Major Version: 0 -TEST_RES-NEXT: Minor Version: 0 -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: Type: kRT_MENU (ID 4) [ -TEST_RES-NEXT: String Name Entries: 1 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Name: "EAT" [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Language: (ID 3081) [ -TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT: Major Version: 0 -TEST_RES-NEXT: Minor Version: 0 -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: Name: (ID 14432) [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Language: (ID 2052) [ -TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT: Major Version: 0 -TEST_RES-NEXT: Minor Version: 0 -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: Type: kRT_DIALOG (ID 5) [ -TEST_RES-NEXT: String Name Entries: 1 -TEST_RES-NEXT: ID Entries: 0 -TEST_RES-NEXT: Name: TESTDIALOG [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Language: (ID 1033) [ -TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT: Major Version: 0 -TEST_RES-NEXT: Minor Version: 0 -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: Type: kRT_ACCELERATOR (ID 9) [ -TEST_RES-NEXT: String Name Entries: 1 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Name: MYACCELERATORS [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Language: (ID 1033) [ -TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT: Major Version: 0 -TEST_RES-NEXT: Minor Version: 0 -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: Name: (ID 12) [ -TEST_RES-NEXT: String Name Entries: 0 -TEST_RES-NEXT: ID Entries: 1 -TEST_RES-NEXT: Language: (ID 1033) [ -TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT: Major Version: 0 -TEST_RES-NEXT: Minor Version: 0 -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] -TEST_RES-NEXT: ] +RESOURCE: Resources [ +RESOURCE-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +RESOURCE-NEXT: .rsrc$01 Data ( +RESOURCE-NEXT: 0000: 00000000 00000000 00000000 00000100 |................| +RESOURCE-NEXT: 0010: 06000000 18000080 00000000 00000000 |................| +RESOURCE-NEXT: 0020: 00000000 00000100 01000000 30000080 |............0...| +RESOURCE-NEXT: 0030: 00000000 00000000 00000000 00000100 |................| +RESOURCE-NEXT: 0040: 09040000 48000000 00000000 2A000000 |....H.......*...| +RESOURCE-NEXT: 0050: 00000000 00000000 |........| +RESOURCE-NEXT: ) +RESOURCE-NEXT: .rsrc$02 Data ( +RESOURCE-NEXT: 0000: 00000500 48006500 6C006C00 6F000000 |....H.e.l.l.o...| +RESOURCE-NEXT: 0010: 00000000 00000000 00000000 00000000 |................| +RESOURCE-NEXT: 0020: 00000000 00000000 00000000 00000000 |................| +RESOURCE-NEXT: ) +RESOURCE-NEXT: ] Index: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp @@ -44,7 +44,6 @@ #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/COFF.h" -#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataExtractor.h" @@ -122,10 +121,6 @@ uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym = nullptr); - void printResourceDirectoryTable(ResourceSectionRef RSF, - const coff_resource_dir_table &Table, - StringRef Level); - void printBinaryBlockWithRelocs(StringRef Label, const SectionRef &Sec, StringRef SectionContents, StringRef Block); @@ -145,9 +140,6 @@ void printDelayImportedSymbols( const DelayImportDirectoryEntryRef &I, iterator_range Range); - ErrorOr - getResourceDirectoryTableEntry(const coff_resource_dir_table &Table, - uint32_t Index); typedef DenseMap > RelocMapTy; @@ -542,29 +534,6 @@ LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256), }; -static const EnumEntry ResourceTypeNames[]{ - {"kRT_CURSOR (ID 1)", COFF::RID_Cursor}, - {"kRT_BITMAP (ID 2)", COFF::RID_Bitmap}, - {"kRT_ICON (ID 3)", COFF::RID_Icon}, - {"kRT_MENU (ID 4)", COFF::RID_Menu}, - {"kRT_DIALOG (ID 5)", COFF::RID_Dialog}, - {"kRT_STRING (ID 6)", COFF::RID_String}, - {"kRT_FONTDIR (ID 7)", COFF::RID_FontDir}, - {"kRT_FONT (ID 8)", COFF::RID_Font}, - {"kRT_ACCELERATOR (ID 9)", COFF::RID_Accelerator}, - {"kRT_RCDATA (ID 10)", COFF::RID_RCData}, - {"kRT_MESSAGETABLE (ID 11)", COFF::RID_MessageTable}, - {"kRT_GROUP_CURSOR (ID 12)", COFF::RID_Group_Cursor}, - {"kRT_GROUP_ICON (ID 14)", COFF::RID_Group_Icon}, - {"kRT_VERSION (ID 16)", COFF::RID_Version}, - {"kRT_DLGINCLUDE (ID 17)", COFF::RID_DLGInclude}, - {"kRT_PLUGPLAY (ID 19)", COFF::RID_PlugPlay}, - {"kRT_VXD (ID 20)", COFF::RID_VXD}, - {"kRT_ANICURSOR (ID 21)", COFF::RID_AniCursor}, - {"kRT_ANIICON (ID 22)", COFF::RID_AniIcon}, - {"kRT_HTML (ID 23)", COFF::RID_HTML}, - {"kRT_MANIFEST (ID 24)", COFF::RID_Manifest}}; - template static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, COFFSymbolRef Symbol, @@ -1534,76 +1503,18 @@ error(S.getContents(Ref)); if ((Name == ".rsrc") || (Name == ".rsrc$01")) { - ResourceSectionRef RSF(Ref); - auto &BaseTable = unwrapOrError(RSF.getBaseTable()); - printResourceDirectoryTable(RSF, BaseTable, "Type"); + auto Table = + reinterpret_cast(Ref.data()); + char FormattedTime[20]; + time_t TDS = time_t(Table->TimeDateStamp); + strftime(FormattedTime, sizeof(FormattedTime), "%Y-%m-%d %H:%M:%S", + gmtime(&TDS)); + W.printHex("Time/Date Stamp", FormattedTime, Table->TimeDateStamp); } - if (opts::SectionData) - W.printBinaryBlock(Name.str() + " Data", Ref); + W.printBinaryBlock(Name.str() + " Data", Ref); } } -void COFFDumper::printResourceDirectoryTable( - ResourceSectionRef RSF, const coff_resource_dir_table &Table, - StringRef Level) { - W.printNumber("String Name Entries", Table.NumberOfNameEntries); - W.printNumber("ID Entries", Table.NumberOfIDEntries); - - char FormattedTime[20] = {}; - time_t TDS = time_t(Table.TimeDateStamp); - strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS)); - - // Iterate through level in resource directory tree. - for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries; - i++) { - auto Entry = unwrapOrError(getResourceDirectoryTableEntry(Table, i)); - StringRef Name; - SmallString<20> IDStr; - raw_svector_ostream OS(IDStr); - if (i < Table.NumberOfNameEntries) { - ArrayRef RawEntryNameString = unwrapOrError(RSF.getEntryNameString(Entry)); - std::string EntryNameString; - if (!llvm::convertUTF16ToUTF8String(RawEntryNameString, EntryNameString)) - error(object_error::parse_failed); - OS << ": "; - OS << EntryNameString; - } else { - if (Level == "Type") { - ScopedPrinter Printer(OS); - Printer.printEnum("", Entry.Identifier.ID, - makeArrayRef(ResourceTypeNames)); - IDStr = IDStr.slice(0, IDStr.find_first_of(")", 0) + 1); - } else { - OS << ": (ID " << Entry.Identifier.ID << ")"; - } - } - Name = StringRef(IDStr); - ListScope ResourceType(W, Level.str() + Name.str()); - if (Entry.Offset.isSubDir()) { - StringRef NextLevel; - if (Level == "Name") - NextLevel = "Language"; - else - NextLevel = "Name"; - auto &NextTable = unwrapOrError(RSF.getEntrySubDir(Entry)); - printResourceDirectoryTable(RSF, NextTable, NextLevel); - } else { - W.printHex("Time/Date Stamp", FormattedTime, Table.TimeDateStamp); - W.printNumber("Major Version", Table.MajorVersion); - W.printNumber("Minor Version", Table.MinorVersion); - } - } -} - -ErrorOr -COFFDumper::getResourceDirectoryTableEntry(const coff_resource_dir_table &Table, - uint32_t Index) { - if (Index >= Table.NumberOfNameEntries + Table.NumberOfIDEntries) - return object_error::parse_failed; - auto TablePtr = reinterpret_cast(&Table + 1); - return TablePtr[Index]; -} - void COFFDumper::printStackMap() const { object::SectionRef StackMapSection; for (auto Sec : Obj->sections()) {