llvm.org GIT mirror llvm / baef3d5
Revert "Hopefully one last commit to fix this patch, addresses string reference" Summary: This reverts commit 56beec1b1cfc6d263e5eddb7efff06117c0724d2. Revert "Quick fix to D32609, it seems .o files are not transferred in all cases." This reverts commit 7652eecd29cfdeeab7f76f687586607a99ff4e36. Revert "Update llvm-readobj -coff-resources to display tree structure." This reverts commit 422b62c4d302cfc92401418c2acd165056081ed7. Reviewers: zturner Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D32958 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302397 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Beckmann 3 years ago
10 changed file(s) with 30 addition(s) and 360 deletion(s). Raw diff Collapse all Expand all
1919 #include "llvm/Object/Binary.h"
2020 #include "llvm/Object/Error.h"
2121 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Support/BinaryByteStream.h"
2322 #include "llvm/Support/COFF.h"
24 #include "llvm/Support/ConvertUTF.h"
2523 #include "llvm/Support/Endian.h"
2624 #include "llvm/Support/ErrorHandling.h"
2725 #include "llvm/Support/ErrorOr.h"
4139 class ExportDirectoryEntryRef;
4240 class ImportDirectoryEntryRef;
4341 class ImportedSymbolRef;
44 class ResourceSectionRef;
4542
4643 using import_directory_iterator = content_iterator;
4744 using delay_import_directory_iterator =
625622 int getOffset() const { return Data & ((1 << 12) - 1); }
626623 };
627624
628 struct coff_resource_dir_entry {
629 union {
630 support::ulittle32_t NameOffset;
631 support::ulittle32_t ID;
632 uint32_t getNameOffset() const {
633 return maskTrailingOnes(31) & NameOffset;
634 }
635 } Identifier;
636 union {
637 support::ulittle32_t DataEntryOffset;
638 support::ulittle32_t SubdirOffset;
639
640 bool isSubDir() const { return SubdirOffset >> 31; }
641 uint32_t value() const {
642 return maskTrailingOnes(31) & SubdirOffset;
643 }
644
645 } Offset;
646 };
647
648625 struct coff_resource_dir_table {
649626 support::ulittle32_t Characteristics;
650627 support::ulittle32_t TimeDateStamp;
10691046 const COFFObjectFile *OwningObject = nullptr;
10701047 };
10711048
1072 class ResourceSectionRef {
1073 public:
1074 ResourceSectionRef() = default;
1075 explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
1076
1077 ErrorOr> getEntryNameString(const coff_resource_dir_entry &Entry);
1078 ErrorOr
1079 getEntrySubDir(const coff_resource_dir_entry &Entry);
1080 ErrorOr getBaseTable();
1081
1082 private:
1083 BinaryByteStream BBS;
1084
1085 ErrorOr getTableAtOffset(uint32_t Offset);
1086 ErrorOr> getDirStringAtOffset(uint32_t Offset);
1087 };
1088
10891049 // Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
10901050 struct FpoData {
10911051 support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
149149 /// Big endian: the MSB precedes the LSB in memory. This is deprecated
150150 /// and should be 0.
151151 IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
152 };
153
154 enum ResourceTypeID {
155 RID_Cursor = 1,
156 RID_Bitmap = 2,
157 RID_Icon = 3,
158 RID_Menu = 4,
159 RID_Dialog = 5,
160 RID_String = 6,
161 RID_FontDir = 7,
162 RID_Font = 8,
163 RID_Accelerator = 9,
164 RID_RCData = 10,
165 RID_MessageTable = 11,
166 RID_Group_Cursor = 12,
167 RID_Group_Icon = 14,
168 RID_Version = 16,
169 RID_DLGInclude = 17,
170 RID_PlugPlay = 19,
171 RID_VXD = 20,
172 RID_AniCursor = 21,
173 RID_AniIcon = 22,
174 RID_HTML = 23,
175 RID_Manifest = 24,
176152 };
177153
178154 struct symbol {
1818 #include "llvm/Object/COFF.h"
1919 #include "llvm/Object/Error.h"
2020 #include "llvm/Object/ObjectFile.h"
21 #include "llvm/Support/BinaryStreamReader.h"
2221 #include "llvm/Support/COFF.h"
2322 #include "llvm/Support/Endian.h"
2423 #include "llvm/Support/Error.h"
159158 Expected COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
160159 COFFSymbolRef Symb = getCOFFSymbol(Ref);
161160 StringRef Result;
162 if (std::error_code EC = getSymbolName(Symb, Result))
161 std::error_code EC = getSymbolName(Symb, Result);
162 if (EC)
163163 return errorCodeToError(EC);
164164 return Result;
165165 }
15901590 Result = Header->PageRVA + Entry[Index].getOffset();
15911591 return std::error_code();
15921592 }
1593
1594 #define RETURN_IF_ERROR(X) \
1595 if (auto EC = errorToErrorCode(X)) \
1596 return EC;
1597
1598 ErrorOr> ResourceSectionRef::getDirStringAtOffset(uint32_t Offset) {
1599 BinaryStreamReader Reader = BinaryStreamReader(BBS);
1600 Reader.setOffset(Offset);
1601 uint16_t Length;
1602 RETURN_IF_ERROR(Reader.readInteger(Length));
1603 ArrayRef RawDirString;
1604 // Strings are stored as 2-byte aligned unicode characters but readFixedString
1605 // assumes byte string, so we double length.
1606 RETURN_IF_ERROR(Reader.readArray(RawDirString, Length));
1607 return RawDirString;
1608 }
1609
1610 ErrorOr>
1611 ResourceSectionRef::getEntryNameString(const coff_resource_dir_entry &Entry) {
1612 return getDirStringAtOffset(Entry.Identifier.getNameOffset());
1613 }
1614
1615 ErrorOr
1616 ResourceSectionRef::getTableAtOffset(uint32_t Offset) {
1617 const coff_resource_dir_table *Table = nullptr;
1618
1619 BinaryStreamReader Reader(BBS);
1620 Reader.setOffset(Offset);
1621 RETURN_IF_ERROR(Reader.readObject(Table));
1622 assert(Table != nullptr);
1623 return *Table;
1624 }
1625
1626 ErrorOr
1627 ResourceSectionRef::getEntrySubDir(const coff_resource_dir_entry &Entry) {
1628 return getTableAtOffset(Entry.Offset.value());
1629 }
1630
1631 ErrorOr ResourceSectionRef::getBaseTable() {
1632 return getTableAtOffset(0);
1633 }
test/tools/llvm-readobj/Inputs/resources/cursor_small.bmp less more
Binary diff not shown
test/tools/llvm-readobj/Inputs/resources/okay_small.bmp less more
Binary diff not shown
test/tools/llvm-readobj/Inputs/resources/test_resource.obj.coff less more
Binary diff not shown
+0
-44
test/tools/llvm-readobj/Inputs/resources/test_resource.rc less more
None #include "windows.h"
1
2 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
3
4 myaccelerators ACCELERATORS
5 {
6 "^C", 999, VIRTKEY, ALT
7 "D", 1100, VIRTKEY, CONTROL, SHIFT
8 "^R", 444, ASCII, NOINVERT
9 }
10
11 cursor BITMAP "cursor_small.bmp"
12 okay BITMAP "okay_small.bmp"
13
14 14432 MENU
15 LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
16 {
17 MENUITEM "yu", 100
18 MENUITEM "shala", 101
19 MENUITEM "kaoya", 102
20 }
21
22 testdialog DIALOG 10, 10, 200, 300
23 STYLE WS_POPUP | WS_BORDER
24 CAPTION "Test"
25 {
26 CTEXT "Continue:", 1, 10, 10, 230, 14
27 PUSHBUTTON "&OK", 2, 66, 134, 161, 13
28 }
29
30 12 ACCELERATORS
31 {
32 "X", 164, VIRTKEY, ALT
33 "H", 5678, VIRTKEY, CONTROL, SHIFT
34 "^R", 444, ASCII, NOINVERT
35 }
36
37 "eat" MENU
38 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
39 {
40 MENUITEM "fish", 100
41 MENUITEM "salad", 101
42 MENUITEM "duck", 102
43 }
test/tools/llvm-readobj/Inputs/resources/test_resource.res less more
Binary diff not shown
None // Check dumping of the .rsrc section(s)
1 // The input was generated with the following commands, using the original Windows
2 // rc.exe and cvtres.exe:
3 // > rc /fo test_resource.res /nologo test_resource.rc
4 // > cvtres /machine:X86 /readonly /nologo /out:test_resource.o test_resource.res
0 RUN: llvm-readobj -coff-resources %p/Inputs/zero-string-table.obj.coff-i386 \
1 RUN: | FileCheck %s -check-prefix RESOURCE
52
6 RUN: llvm-readobj -coff-resources -section-data %p/Inputs/zero-string-table.obj.coff-i386 \
7 RUN: | FileCheck %s -check-prefix ZERO
8 RUN: llvm-readobj -coff-resources %p/Inputs/resources/test_resource.obj.coff \
9 RUN: | FileCheck %s -check-prefix TEST_RES
10
11 ZERO: Resources [
12 ZERO-NEXT: String Name Entries: 0
13 ZERO-NEXT: ID Entries: 1
14 ZERO-NEXT: Type: kRT_STRING (ID 6) [
15 ZERO-NEXT: String Name Entries: 0
16 ZERO-NEXT: ID Entries: 1
17 ZERO-NEXT: Name: (ID 1) [
18 ZERO-NEXT: String Name Entries: 0
19 ZERO-NEXT: ID Entries: 1
20 ZERO-NEXT: Language: (ID 1033) [
21 ZERO-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
22 ZERO-NEXT: Major Version: 0
23 ZERO-NEXT: Minor Version: 0
24 ZERO-NEXT: ]
25 ZERO-NEXT: ]
26 ZERO-NEXT: ]
27
28
29 TEST_RES: Resources [
30 TEST_RES-NEXT: String Name Entries: 0
31 TEST_RES-NEXT: ID Entries: 4
32 TEST_RES-NEXT: Type: kRT_BITMAP (ID 2) [
33 TEST_RES-NEXT: String Name Entries: 2
34 TEST_RES-NEXT: ID Entries: 0
35 TEST_RES-NEXT: Name: CURSOR [
36 TEST_RES-NEXT: String Name Entries: 0
37 TEST_RES-NEXT: ID Entries: 1
38 TEST_RES-NEXT: Language: (ID 1033) [
39 TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
40 TEST_RES-NEXT: Major Version: 0
41 TEST_RES-NEXT: Minor Version: 0
42 TEST_RES-NEXT: ]
43 TEST_RES-NEXT: ]
44 TEST_RES-NEXT: Name: OKAY [
45 TEST_RES-NEXT: String Name Entries: 0
46 TEST_RES-NEXT: ID Entries: 1
47 TEST_RES-NEXT: Language: (ID 1033) [
48 TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
49 TEST_RES-NEXT: Major Version: 0
50 TEST_RES-NEXT: Minor Version: 0
51 TEST_RES-NEXT: ]
52 TEST_RES-NEXT: ]
53 TEST_RES-NEXT: ]
54 TEST_RES-NEXT: Type: kRT_MENU (ID 4) [
55 TEST_RES-NEXT: String Name Entries: 1
56 TEST_RES-NEXT: ID Entries: 1
57 TEST_RES-NEXT: Name: "EAT" [
58 TEST_RES-NEXT: String Name Entries: 0
59 TEST_RES-NEXT: ID Entries: 1
60 TEST_RES-NEXT: Language: (ID 3081) [
61 TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
62 TEST_RES-NEXT: Major Version: 0
63 TEST_RES-NEXT: Minor Version: 0
64 TEST_RES-NEXT: ]
65 TEST_RES-NEXT: ]
66 TEST_RES-NEXT: Name: (ID 14432) [
67 TEST_RES-NEXT: String Name Entries: 0
68 TEST_RES-NEXT: ID Entries: 1
69 TEST_RES-NEXT: Language: (ID 2052) [
70 TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
71 TEST_RES-NEXT: Major Version: 0
72 TEST_RES-NEXT: Minor Version: 0
73 TEST_RES-NEXT: ]
74 TEST_RES-NEXT: ]
75 TEST_RES-NEXT: ]
76 TEST_RES-NEXT: Type: kRT_DIALOG (ID 5) [
77 TEST_RES-NEXT: String Name Entries: 1
78 TEST_RES-NEXT: ID Entries: 0
79 TEST_RES-NEXT: Name: TESTDIALOG [
80 TEST_RES-NEXT: String Name Entries: 0
81 TEST_RES-NEXT: ID Entries: 1
82 TEST_RES-NEXT: Language: (ID 1033) [
83 TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
84 TEST_RES-NEXT: Major Version: 0
85 TEST_RES-NEXT: Minor Version: 0
86 TEST_RES-NEXT: ]
87 TEST_RES-NEXT: ]
88 TEST_RES-NEXT: ]
89 TEST_RES-NEXT: Type: kRT_ACCELERATOR (ID 9) [
90 TEST_RES-NEXT: String Name Entries: 1
91 TEST_RES-NEXT: ID Entries: 1
92 TEST_RES-NEXT: Name: MYACCELERATORS [
93 TEST_RES-NEXT: String Name Entries: 0
94 TEST_RES-NEXT: ID Entries: 1
95 TEST_RES-NEXT: Language: (ID 1033) [
96 TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
97 TEST_RES-NEXT: Major Version: 0
98 TEST_RES-NEXT: Minor Version: 0
99 TEST_RES-NEXT: ]
100 TEST_RES-NEXT: ]
101 TEST_RES-NEXT: Name: (ID 12) [
102 TEST_RES-NEXT: String Name Entries: 0
103 TEST_RES-NEXT: ID Entries: 1
104 TEST_RES-NEXT: Language: (ID 1033) [
105 TEST_RES-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
106 TEST_RES-NEXT: Major Version: 0
107 TEST_RES-NEXT: Minor Version: 0
108 TEST_RES-NEXT: ]
109 TEST_RES-NEXT: ]
110 TEST_RES-NEXT: ]
3 RESOURCE: Resources [
4 RESOURCE-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
5 RESOURCE-NEXT: .rsrc$01 Data (
6 RESOURCE-NEXT: 0000: 00000000 00000000 00000000 00000100 |................|
7 RESOURCE-NEXT: 0010: 06000000 18000080 00000000 00000000 |................|
8 RESOURCE-NEXT: 0020: 00000000 00000100 01000000 30000080 |............0...|
9 RESOURCE-NEXT: 0030: 00000000 00000000 00000000 00000100 |................|
10 RESOURCE-NEXT: 0040: 09040000 48000000 00000000 2A000000 |....H.......*...|
11 RESOURCE-NEXT: 0050: 00000000 00000000 |........|
12 RESOURCE-NEXT: )
13 RESOURCE-NEXT: .rsrc$02 Data (
14 RESOURCE-NEXT: 0000: 00000500 48006500 6C006C00 6F000000 |....H.e.l.l.o...|
15 RESOURCE-NEXT: 0010: 00000000 00000000 00000000 00000000 |................|
16 RESOURCE-NEXT: 0020: 00000000 00000000 00000000 00000000 |................|
17 RESOURCE-NEXT: )
18 RESOURCE-NEXT: ]
4343 #include "llvm/Support/BinaryByteStream.h"
4444 #include "llvm/Support/BinaryStreamReader.h"
4545 #include "llvm/Support/COFF.h"
46 #include "llvm/Support/ConvertUTF.h"
4746 #include "llvm/Support/Casting.h"
4847 #include "llvm/Support/Compiler.h"
4948 #include "llvm/Support/DataExtractor.h"
121120 uint32_t RelocOffset, uint32_t Offset,
122121 StringRef *RelocSym = nullptr);
123122
124 void printResourceDirectoryTable(ResourceSectionRef RSF,
125 const coff_resource_dir_table &Table,
126 StringRef Level);
127
128123 void printBinaryBlockWithRelocs(StringRef Label, const SectionRef &Sec,
129124 StringRef SectionContents, StringRef Block);
130125
144139 void printDelayImportedSymbols(
145140 const DelayImportDirectoryEntryRef &I,
146141 iterator_range Range);
147 ErrorOr
148 getResourceDirectoryTableEntry(const coff_resource_dir_table &Table,
149 uint32_t Index);
150142
151143 typedef DenseMap > RelocMapTy;
152144
541533 LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
542534 };
543535
544 static const EnumEntry ResourceTypeNames[]{
545 {"kRT_CURSOR (ID 1)", COFF::RID_Cursor},
546 {"kRT_BITMAP (ID 2)", COFF::RID_Bitmap},
547 {"kRT_ICON (ID 3)", COFF::RID_Icon},
548 {"kRT_MENU (ID 4)", COFF::RID_Menu},
549 {"kRT_DIALOG (ID 5)", COFF::RID_Dialog},
550 {"kRT_STRING (ID 6)", COFF::RID_String},
551 {"kRT_FONTDIR (ID 7)", COFF::RID_FontDir},
552 {"kRT_FONT (ID 8)", COFF::RID_Font},
553 {"kRT_ACCELERATOR (ID 9)", COFF::RID_Accelerator},
554 {"kRT_RCDATA (ID 10)", COFF::RID_RCData},
555 {"kRT_MESSAGETABLE (ID 11)", COFF::RID_MessageTable},
556 {"kRT_GROUP_CURSOR (ID 12)", COFF::RID_Group_Cursor},
557 {"kRT_GROUP_ICON (ID 14)", COFF::RID_Group_Icon},
558 {"kRT_VERSION (ID 16)", COFF::RID_Version},
559 {"kRT_DLGINCLUDE (ID 17)", COFF::RID_DLGInclude},
560 {"kRT_PLUGPLAY (ID 19)", COFF::RID_PlugPlay},
561 {"kRT_VXD (ID 20)", COFF::RID_VXD},
562 {"kRT_ANICURSOR (ID 21)", COFF::RID_AniCursor},
563 {"kRT_ANIICON (ID 22)", COFF::RID_AniIcon},
564 {"kRT_HTML (ID 23)", COFF::RID_HTML},
565 {"kRT_MANIFEST (ID 24)", COFF::RID_Manifest}};
566
567536 template
568537 static std::error_code getSymbolAuxData(const COFFObjectFile *Obj,
569538 COFFSymbolRef Symbol,
15331502 error(S.getContents(Ref));
15341503
15351504 if ((Name == ".rsrc") || (Name == ".rsrc$01")) {
1536 ResourceSectionRef RSF(Ref);
1537 auto &BaseTable = unwrapOrError(RSF.getBaseTable());
1538 printResourceDirectoryTable(RSF, BaseTable, "Type");
1539 }
1540 if (opts::SectionData)
1541 W.printBinaryBlock(Name.str() + " Data", Ref);
1542 }
1543 }
1544
1545 void COFFDumper::printResourceDirectoryTable(
1546 ResourceSectionRef RSF, const coff_resource_dir_table &Table,
1547 StringRef Level) {
1548 W.printNumber("String Name Entries", Table.NumberOfNameEntries);
1549 W.printNumber("ID Entries", Table.NumberOfIDEntries);
1550
1551 char FormattedTime[20] = {};
1552 time_t TDS = time_t(Table.TimeDateStamp);
1553 strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
1554
1555 // Iterate through level in resource directory tree.
1556 for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries;
1557 i++) {
1558 auto Entry = unwrapOrError(getResourceDirectoryTableEntry(Table, i));
1559 StringRef Name;
1560 SmallString<20> IDStr;
1561 raw_svector_ostream OS(IDStr);
1562 if (i < Table.NumberOfNameEntries) {
1563 ArrayRef RawEntryNameString = unwrapOrError(RSF.getEntryNameString(Entry));
1564 std::string EntryNameString;
1565 if (!llvm::convertUTF16ToUTF8String(RawEntryNameString, EntryNameString))
1566 error(object_error::parse_failed);
1567 OS << ": ";
1568 OS << EntryNameString;
1569 } else {
1570 if (Level == "Type") {
1571 ScopedPrinter Printer(OS);
1572 Printer.printEnum("", Entry.Identifier.ID,
1573 makeArrayRef(ResourceTypeNames));
1574 IDStr = IDStr.slice(0, IDStr.find_first_of(")", 0) + 1);
1575 } else {
1576 OS << ": (ID " << Entry.Identifier.ID << ")";
1577 }
1578 }
1579 Name = StringRef(IDStr);
1580 ListScope ResourceType(W, Level.str() + Name.str());
1581 if (Entry.Offset.isSubDir()) {
1582 StringRef NextLevel;
1583 if (Level == "Name")
1584 NextLevel = "Language";
1585 else
1586 NextLevel = "Name";
1587 auto &NextTable = unwrapOrError(RSF.getEntrySubDir(Entry));
1588 printResourceDirectoryTable(RSF, NextTable, NextLevel);
1589 } else {
1590 W.printHex("Time/Date Stamp", FormattedTime, Table.TimeDateStamp);
1591 W.printNumber("Major Version", Table.MajorVersion);
1592 W.printNumber("Minor Version", Table.MinorVersion);
1593 }
1594 }
1595 }
1596
1597 ErrorOr
1598 COFFDumper::getResourceDirectoryTableEntry(const coff_resource_dir_table &Table,
1599 uint32_t Index) {
1600 if (Index >= Table.NumberOfNameEntries + Table.NumberOfIDEntries)
1601 return object_error::parse_failed;
1602 auto TablePtr = reinterpret_cast(&Table + 1);
1603 return TablePtr[Index];
1505 auto Table =
1506 reinterpret_cast(Ref.data());
1507 char FormattedTime[20];
1508 time_t TDS = time_t(Table->TimeDateStamp);
1509 strftime(FormattedTime, sizeof(FormattedTime), "%Y-%m-%d %H:%M:%S",
1510 gmtime(&TDS));
1511 W.printHex("Time/Date Stamp", FormattedTime, Table->TimeDateStamp);
1512 }
1513 W.printBinaryBlock(Name.str() + " Data", Ref);
1514 }
16041515 }
16051516
16061517 void COFFDumper::printStackMap() const {