llvm.org GIT mirror llvm / 24c1125
Revert "Revert "Replace trivial use of external rc.exe by writing our own .res file."" Summary: This reverts commit 51931072a7c9a52540baf76fc30ef391d2529a2f. This revert was originally done because the integrations of the new WindowsResource library into LLD was causing error in chromium, due to bugs in how resource sections were handled. These bugs were fixed, meaning that the features may be reintegrated. Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D34922 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306941 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Beckmann 3 years ago
5 changed file(s) with 58 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
4343 static const char ClGlObjMagic[] = {
4444 '\x38', '\xfe', '\xb3', '\x0c', '\xa5', '\xd9', '\xab', '\x4d',
4545 '\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
46 };
47
48 // The signature bytes that start a .res file.
49 static const char WinResMagic[] = {
50 '\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00',
51 '\xff', '\xff', '\x00', '\x00', '\xff', '\xff', '\x00', '\x00',
4652 };
4753
4854 // Sizes in bytes of various things in the COFF format.
4242 #include
4343
4444 namespace llvm {
45
4645 namespace object {
4746
4847 class WindowsResource;
4948
50 enum class Machine { UNKNOWN, ARM, X64, X86 };
49 const size_t WIN_RES_MAGIC_SIZE = 16;
50 const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
51 const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
52 const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
53 const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
54
55 struct WinResHeaderPrefix {
56 support::ulittle32_t DataSize;
57 support::ulittle32_t HeaderSize;
58 };
59
60 // Type and Name may each either be an integer ID or a string. This struct is
61 // only used in the case where they are both IDs.
62 struct WinResIDs {
63 uint16_t TypeFlag;
64 support::ulittle16_t TypeID;
65 uint16_t NameFlag;
66 support::ulittle16_t NameID;
67
68 void setType(uint16_t ID) {
69 TypeFlag = 0xffff;
70 TypeID = ID;
71 }
72
73 void setName(uint16_t ID) {
74 NameFlag = 0xffff;
75 NameID = ID;
76 }
77 };
78
79 struct WinResHeaderSuffix {
80 support::ulittle32_t DataVersion;
81 support::ulittle16_t MemoryFlags;
82 support::ulittle16_t Language;
83 support::ulittle32_t Version;
84 support::ulittle32_t Characteristics;
85 };
5186
5287 class ResourceEntryRef {
5388 public:
72107
73108 Error loadNext();
74109
75 struct HeaderSuffix {
76 support::ulittle32_t DataVersion;
77 support::ulittle16_t MemoryFlags;
78 support::ulittle16_t Language;
79 support::ulittle32_t Version;
80 support::ulittle32_t Characteristics;
81 };
82
83110 BinaryStreamReader Reader;
84111 bool IsStringType;
85112 ArrayRef Type;
87114 bool IsStringName;
88115 ArrayRef Name;
89116 uint16_t NameID;
90 const HeaderSuffix *Suffix = nullptr;
117 const WinResHeaderSuffix *Suffix = nullptr;
91118 ArrayRef Data;
92119 const WindowsResource *OwningRes = nullptr;
93120 };
5050 return file_magic::coff_import_library;
5151 }
5252 // Windows resource file
53 if (startswith(Magic, "\0\0\0\0\x20\0\0\0\xFF"))
53 if (Magic.size() >= sizeof(COFF::WinResMagic) &&
54 memcmp(Magic.data(), COFF::WinResMagic, sizeof(COFF::WinResMagic)) == 0)
5455 return file_magic::windows_resource;
5556 // 0x0000 = COFF unknown machine type
5657 if (Magic[1] == 0)
3535 // 8-byte because it makes everyone happy.
3636 const uint32_t SECTION_ALIGNMENT = sizeof(uint64_t);
3737
38 static const size_t ResourceMagicSize = 16;
39
40 static const size_t NullEntrySize = 16;
41
4238 uint32_t WindowsResourceParser::TreeNode::StringCount = 0;
4339 uint32_t WindowsResourceParser::TreeNode::DataCount = 0;
4440
4541 WindowsResource::WindowsResource(MemoryBufferRef Source)
4642 : Binary(Binary::ID_WinRes, Source) {
47 size_t LeadingSize = ResourceMagicSize + NullEntrySize;
43 size_t LeadingSize = WIN_RES_MAGIC_SIZE + WIN_RES_NULL_ENTRY_SIZE;
4844 BBS = BinaryByteStream(Data.getBuffer().drop_front(LeadingSize),
4945 support::little);
5046 }
5147
5248 Expected>
5349 WindowsResource::createWindowsResource(MemoryBufferRef Source) {
54 if (Source.getBufferSize() < ResourceMagicSize + NullEntrySize)
50 if (Source.getBufferSize() < WIN_RES_MAGIC_SIZE + WIN_RES_NULL_ENTRY_SIZE)
5551 return make_error(
5652 "File too small to be a resource file",
5753 object_error::invalid_file_type);
104100 }
105101
106102 Error ResourceEntryRef::loadNext() {
107 uint32_t DataSize;
108 RETURN_IF_ERROR(Reader.readInteger(DataSize));
109 uint32_t HeaderSize;
110 RETURN_IF_ERROR(Reader.readInteger(HeaderSize));
111
112 if (HeaderSize < MIN_HEADER_SIZE)
103 const WinResHeaderPrefix *Prefix;
104 RETURN_IF_ERROR(Reader.readObject(Prefix));
105
106 if (Prefix->HeaderSize < MIN_HEADER_SIZE)
113107 return make_error("Header size is too small.",
114108 object_error::parse_failed);
115109
117111
118112 RETURN_IF_ERROR(readStringOrId(Reader, NameID, Name, IsStringName));
119113
120 RETURN_IF_ERROR(Reader.padToAlignment(sizeof(uint32_t)));
114 RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_HEADER_ALIGNMENT));
121115
122116 RETURN_IF_ERROR(Reader.readObject(Suffix));
123117
124 RETURN_IF_ERROR(Reader.readArray(Data, DataSize));
125
126 RETURN_IF_ERROR(Reader.padToAlignment(sizeof(uint32_t)));
118 RETURN_IF_ERROR(Reader.readArray(Data, Prefix->DataSize));
119
120 RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_DATA_ALIGNMENT));
127121
128122 return Error::success();
129123 }
324318 void writeDirectoryTree();
325319 void writeDirectoryStringTable();
326320 void writeFirstSectionRelocations();
327
328321 std::unique_ptr OutputBuffer;
329322 char *BufferStart;
330323 uint64_t CurrentOffset = 0;
468461 SectionOneHeader->PointerToLinenumbers = 0;
469462 SectionOneHeader->NumberOfRelocations = Data.size();
470463 SectionOneHeader->NumberOfLinenumbers = 0;
471 SectionOneHeader->Characteristics = COFF::IMAGE_SCN_ALIGN_1BYTES;
472 SectionOneHeader->Characteristics += COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
473464 SectionOneHeader->Characteristics += COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
474465 SectionOneHeader->Characteristics += COFF::IMAGE_SCN_MEM_READ;
475466 }
7575 "\xfe\xed\xfa\xce........\x00\x00\x00\x0a............";
7676 const char macho_kext_bundle[] =
7777 "\xfe\xed\xfa\xce........\x00\x00\x00\x0b............";
78 const char windows_resource[] = "\x00\x00\x00\x00\x020\x00\x00\x00\xff";
78 const char windows_resource[] =
79 "\x00\x00\x00\x00\x020\x00\x00\x00\xff\xff\x00\x00\xff\xff\x00\x00";
7980 const char macho_dynamically_linked_shared_lib_stub[] =
8081 "\xfe\xed\xfa\xce........\x00\x00\x00\x09............";
8182