Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
WindowsResource.cpp
Go to the documentation of this file.
1//===-- WindowsResource.cpp -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the .res file class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Object/WindowsResource.h"
14#include "llvm/Object/COFF.h"
15#include "llvm/Object/WindowsMachineFlag.h"
16#include "llvm/Support/FormatVariadic.h"
17#include "llvm/Support/MathExtras.h"
18#include "llvm/Support/ScopedPrinter.h"
19#include <ctime>
20#include <queue>
21
22using namespacellvm;
23using namespaceobject;
24
25namespacellvm {
26namespaceobject {
27
28#define RETURN_IF_ERROR(X) \
29 if (auto EC = X) \
30 return EC;
31
32#define UNWRAP_REF_OR_RETURN(Name, Expr) \
33 auto Name##OrErr = Expr; \
34 if (!Name##OrErr) \
35 return Name##OrErr.takeError(); \
36 const auto &Name = *Name##OrErr;
37
38#define UNWRAP_OR_RETURN(Name, Expr) \
39 auto Name##OrErr = Expr; \
40 if (!Name##OrErr) \
41 return Name##OrErr.takeError(); \
42 auto Name = *Name##OrErr;
43
44constuint32_tMIN_HEADER_SIZE = 7 *sizeof(uint32_t) + 2 *sizeof(uint16_t);
45
46// COFF files seem to be inconsistent with alignment between sections, just use
47// 8-byte because it makes everyone happy.
48constuint32_tSECTION_ALIGNMENT =sizeof(uint64_t);
49
50WindowsResource::WindowsResource(MemoryBufferRef Source)
51 :Binary(Binary::ID_WinRes, Source) {
52size_t LeadingSize =WIN_RES_MAGIC_SIZE +WIN_RES_NULL_ENTRY_SIZE;
53 BBS =BinaryByteStream(Data.getBuffer().drop_front(LeadingSize),
54llvm::endianness::little);
55}
56
57// static
58Expected<std::unique_ptr<WindowsResource>>
59WindowsResource::createWindowsResource(MemoryBufferRef Source) {
60if (Source.getBufferSize() <WIN_RES_MAGIC_SIZE +WIN_RES_NULL_ENTRY_SIZE)
61return make_error<GenericBinaryError>(
62 Source.getBufferIdentifier() +": too small to be a resource file",
63 object_error::invalid_file_type);
64 std::unique_ptr<WindowsResource> Ret(newWindowsResource(Source));
65return std::move(Ret);
66}
67
68Expected<ResourceEntryRef>WindowsResource::getHeadEntry() {
69if (BBS.getLength() <sizeof(WinResHeaderPrefix) +sizeof(WinResHeaderSuffix))
70return make_error<EmptyResError>(getFileName() +" contains no entries",
71 object_error::unexpected_eof);
72return ResourceEntryRef::create(BinaryStreamRef(BBS),this);
73}
74
75ResourceEntryRef::ResourceEntryRef(BinaryStreamRefRef,
76constWindowsResource *Owner)
77 : Reader(Ref), Owner(Owner) {}
78
79Expected<ResourceEntryRef>
80ResourceEntryRef::create(BinaryStreamRef BSR,constWindowsResource *Owner) {
81autoRef =ResourceEntryRef(BSR, Owner);
82if (auto E =Ref.loadNext())
83return E;
84returnRef;
85}
86
87ErrorResourceEntryRef::moveNext(bool &End) {
88// Reached end of all the entries.
89if (Reader.bytesRemaining() == 0) {
90End =true;
91returnError::success();
92 }
93RETURN_IF_ERROR(loadNext());
94
95returnError::success();
96}
97
98staticErrorreadStringOrId(BinaryStreamReader &Reader,uint16_t &ID,
99ArrayRef<UTF16> &Str,bool &IsString) {
100uint16_t IDFlag;
101RETURN_IF_ERROR(Reader.readInteger(IDFlag));
102 IsString = IDFlag != 0xffff;
103
104if (IsString) {
105 Reader.setOffset(
106 Reader.getOffset() -
107sizeof(uint16_t));// Re-read the bytes which we used to check the flag.
108RETURN_IF_ERROR(Reader.readWideString(Str));
109 }else
110RETURN_IF_ERROR(Reader.readInteger(ID));
111
112returnError::success();
113}
114
115Error ResourceEntryRef::loadNext() {
116constWinResHeaderPrefix *Prefix;
117RETURN_IF_ERROR(Reader.readObject(Prefix));
118
119if (Prefix->HeaderSize <MIN_HEADER_SIZE)
120return make_error<GenericBinaryError>(Owner->getFileName() +
121": header size too small",
122object_error::parse_failed);
123
124RETURN_IF_ERROR(readStringOrId(Reader,TypeID,Type, IsStringType));
125
126RETURN_IF_ERROR(readStringOrId(Reader, NameID, Name, IsStringName));
127
128RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_HEADER_ALIGNMENT));
129
130RETURN_IF_ERROR(Reader.readObject(Suffix));
131
132RETURN_IF_ERROR(Reader.readArray(Data, Prefix->DataSize));
133
134RETURN_IF_ERROR(Reader.padToAlignment(WIN_RES_DATA_ALIGNMENT));
135
136returnError::success();
137}
138
139WindowsResourceParser::WindowsResourceParser(bool MinGW)
140 : Root(false), MinGW(MinGW) {}
141
142voidprintResourceTypeName(uint16_tTypeID,raw_ostream &OS) {
143switch (TypeID) {
144case 1:OS <<"CURSOR (ID 1)";break;
145case 2:OS <<"BITMAP (ID 2)";break;
146case 3:OS <<"ICON (ID 3)";break;
147case 4:OS <<"MENU (ID 4)";break;
148case 5:OS <<"DIALOG (ID 5)";break;
149case 6:OS <<"STRINGTABLE (ID 6)";break;
150case 7:OS <<"FONTDIR (ID 7)";break;
151case 8:OS <<"FONT (ID 8)";break;
152case 9:OS <<"ACCELERATOR (ID 9)";break;
153case 10:OS <<"RCDATA (ID 10)";break;
154case 11:OS <<"MESSAGETABLE (ID 11)";break;
155case 12:OS <<"GROUP_CURSOR (ID 12)";break;
156case 14:OS <<"GROUP_ICON (ID 14)";break;
157case 16:OS <<"VERSIONINFO (ID 16)";break;
158case 17:OS <<"DLGINCLUDE (ID 17)";break;
159case 19:OS <<"PLUGPLAY (ID 19)";break;
160case 20:OS <<"VXD (ID 20)";break;
161case 21:OS <<"ANICURSOR (ID 21)";break;
162case 22:OS <<"ANIICON (ID 22)";break;
163case 23:OS <<"HTML (ID 23)";break;
164case 24:OS <<"MANIFEST (ID 24)";break;
165default:OS <<"ID " <<TypeID;break;
166 }
167}
168
169staticboolconvertUTF16LEToUTF8String(ArrayRef<UTF16> Src, std::string &Out) {
170if (!sys::IsBigEndianHost)
171returnconvertUTF16ToUTF8String(Src, Out);
172
173 std::vector<UTF16> EndianCorrectedSrc;
174 EndianCorrectedSrc.resize(Src.size() + 1);
175llvm::copy(Src, EndianCorrectedSrc.begin() + 1);
176 EndianCorrectedSrc[0] =UNI_UTF16_BYTE_ORDER_MARK_SWAPPED;
177returnconvertUTF16ToUTF8String(ArrayRef(EndianCorrectedSrc), Out);
178}
179
180static std::stringmakeDuplicateResourceError(
181constResourceEntryRef &Entry,StringRef File1,StringRef File2) {
182 std::string Ret;
183raw_string_ostreamOS(Ret);
184
185OS <<"duplicate resource:";
186
187OS <<" type ";
188if (Entry.checkTypeString()) {
189 std::stringUTF8;
190if (!convertUTF16LEToUTF8String(Entry.getTypeString(),UTF8))
191UTF8 ="(failed conversion from UTF16)";
192OS <<'\"' <<UTF8 <<'\"';
193 }else
194printResourceTypeName(Entry.getTypeID(),OS);
195
196OS <<"/name ";
197if (Entry.checkNameString()) {
198 std::stringUTF8;
199if (!convertUTF16LEToUTF8String(Entry.getNameString(),UTF8))
200UTF8 ="(failed conversion from UTF16)";
201OS <<'\"' <<UTF8 <<'\"';
202 }else {
203OS <<"ID " << Entry.getNameID();
204 }
205
206OS <<"/language " << Entry.getLanguage() <<", in " << File1 <<" and in "
207 << File2;
208
209returnOS.str();
210}
211
212staticvoidprintStringOrID(constWindowsResourceParser::StringOrID &S,
213raw_string_ostream &OS,bool IsType,bool IsID) {
214if (S.IsString) {
215 std::stringUTF8;
216if (!convertUTF16LEToUTF8String(S.String,UTF8))
217UTF8 ="(failed conversion from UTF16)";
218OS <<'\"' <<UTF8 <<'\"';
219 }elseif (IsType)
220printResourceTypeName(S.ID,OS);
221elseif (IsID)
222OS <<"ID " << S.ID;
223else
224OS << S.ID;
225}
226
227static std::stringmakeDuplicateResourceError(
228const std::vector<WindowsResourceParser::StringOrID> &Context,
229StringRef File1,StringRef File2) {
230 std::string Ret;
231raw_string_ostreamOS(Ret);
232
233OS <<"duplicate resource:";
234
235if (Context.size() >= 1) {
236OS <<" type ";
237printStringOrID(Context[0],OS,/* IsType */true,/* IsID */true);
238 }
239
240if (Context.size() >= 2) {
241OS <<"/name ";
242printStringOrID(Context[1],OS,/* IsType */false,/* IsID */true);
243 }
244
245if (Context.size() >= 3) {
246OS <<"/language ";
247printStringOrID(Context[2],OS,/* IsType */false,/* IsID */false);
248 }
249OS <<", in " << File1 <<" and in " << File2;
250
251returnOS.str();
252}
253
254// MinGW specific. Remove default manifests (with language zero) if there are
255// other manifests present, and report an error if there are more than one
256// manifest with a non-zero language code.
257// GCC has the concept of a default manifest resource object, which gets
258// linked in implicitly if present. This default manifest has got language
259// id zero, and should be dropped silently if there's another manifest present.
260// If the user resources surprisignly had a manifest with language id zero,
261// we should also ignore the duplicate default manifest.
262voidWindowsResourceParser::cleanUpManifests(
263 std::vector<std::string> &Duplicates) {
264auto TypeIt = Root.IDChildren.find(/* RT_MANIFEST */ 24);
265if (TypeIt == Root.IDChildren.end())
266return;
267
268TreeNode *TypeNode = TypeIt->second.get();
269auto NameIt =
270 TypeNode->IDChildren.find(/* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 1);
271if (NameIt == TypeNode->IDChildren.end())
272return;
273
274TreeNode *NameNode = NameIt->second.get();
275if (NameNode->IDChildren.size() <= 1)
276return;// None or one manifest present, all good.
277
278// If we have more than one manifest, drop the language zero one if present,
279// and check again.
280auto LangZeroIt = NameNode->IDChildren.find(0);
281if (LangZeroIt != NameNode->IDChildren.end() &&
282 LangZeroIt->second->IsDataNode) {
283uint32_t RemovedIndex = LangZeroIt->second->DataIndex;
284 NameNode->IDChildren.erase(LangZeroIt);
285 Data.erase(Data.begin() + RemovedIndex);
286 Root.shiftDataIndexDown(RemovedIndex);
287
288// If we're now down to one manifest, all is good.
289if (NameNode->IDChildren.size() <= 1)
290return;
291 }
292
293// More than one non-language-zero manifest
294auto FirstIt = NameNode->IDChildren.begin();
295uint32_t FirstLang = FirstIt->first;
296TreeNode *FirstNode = FirstIt->second.get();
297auto LastIt = NameNode->IDChildren.rbegin();
298uint32_t LastLang = LastIt->first;
299TreeNode *LastNode = LastIt->second.get();
300 Duplicates.push_back(
301 ("duplicate non-default manifests with languages " +Twine(FirstLang) +
302" in " + InputFilenames[FirstNode->Origin] +" and " +Twine(LastLang) +
303" in " + InputFilenames[LastNode->Origin])
304 .str());
305}
306
307// Ignore duplicates of manifests with language zero (the default manifest),
308// in case the user has provided a manifest with that language id. See
309// the function comment above for context. Only returns true if MinGW is set
310// to true.
311bool WindowsResourceParser::shouldIgnoreDuplicate(
312constResourceEntryRef &Entry) const{
313return MinGW && !Entry.checkTypeString() &&
314 Entry.getTypeID() ==/* RT_MANIFEST */ 24 &&
315 !Entry.checkNameString() &&
316 Entry.getNameID() ==/* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 1 &&
317 Entry.getLanguage() == 0;
318}
319
320bool WindowsResourceParser::shouldIgnoreDuplicate(
321const std::vector<StringOrID> &Context) const{
322return MinGW && Context.size() == 3 && !Context[0].IsString &&
323 Context[0].ID ==/* RT_MANIFEST */ 24 && !Context[1].IsString &&
324 Context[1].ID ==/* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 1 &&
325 !Context[2].IsString && Context[2].ID == 0;
326}
327
328ErrorWindowsResourceParser::parse(WindowsResource *WR,
329 std::vector<std::string> &Duplicates) {
330auto EntryOrErr = WR->getHeadEntry();
331if (!EntryOrErr) {
332auto E = EntryOrErr.takeError();
333if (E.isA<EmptyResError>()) {
334// Check if the .res file contains no entries. In this case we don't have
335// to throw an error but can rather just return without parsing anything.
336// This applies for files which have a valid PE header magic and the
337// mandatory empty null resource entry. Files which do not fit this
338// criteria would have already been filtered out by
339// WindowsResource::createWindowsResource().
340consumeError(std::move(E));
341returnError::success();
342 }
343return E;
344 }
345
346ResourceEntryRef Entry = EntryOrErr.get();
347uint32_t Origin = InputFilenames.size();
348 InputFilenames.push_back(std::string(WR->getFileName()));
349boolEnd =false;
350while (!End) {
351
352TreeNode *Node;
353bool IsNewNode = Root.addEntry(Entry, Origin, Data,StringTable, Node);
354if (!IsNewNode) {
355if (!shouldIgnoreDuplicate(Entry))
356 Duplicates.push_back(makeDuplicateResourceError(
357 Entry, InputFilenames[Node->Origin], WR->getFileName()));
358 }
359
360RETURN_IF_ERROR(Entry.moveNext(End));
361 }
362
363returnError::success();
364}
365
366ErrorWindowsResourceParser::parse(ResourceSectionRef &RSR,StringRef Filename,
367 std::vector<std::string> &Duplicates) {
368UNWRAP_REF_OR_RETURN(BaseTable, RSR.getBaseTable());
369uint32_t Origin = InputFilenames.size();
370 InputFilenames.push_back(std::string(Filename));
371 std::vector<StringOrID> Context;
372return addChildren(Root, RSR, BaseTable, Origin, Context, Duplicates);
373}
374
375voidWindowsResourceParser::printTree(raw_ostream &OS) const{
376ScopedPrinter Writer(OS);
377 Root.print(Writer,"Resource Tree");
378}
379
380bool WindowsResourceParser::TreeNode::addEntry(
381constResourceEntryRef &Entry,uint32_t Origin,
382 std::vector<std::vector<uint8_t>> &Data,
383 std::vector<std::vector<UTF16>> &StringTable, TreeNode *&Result) {
384 TreeNode &TypeNode = addTypeNode(Entry,StringTable);
385 TreeNode &NameNode = TypeNode.addNameNode(Entry,StringTable);
386return NameNode.addLanguageNode(Entry, Origin, Data, Result);
387}
388
389Error WindowsResourceParser::addChildren(TreeNode &Node,
390ResourceSectionRef &RSR,
391constcoff_resource_dir_table &Table,
392uint32_t Origin,
393 std::vector<StringOrID> &Context,
394 std::vector<std::string> &Duplicates) {
395
396for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries;
397 i++) {
398UNWRAP_REF_OR_RETURN(Entry, RSR.getTableEntry(Table, i));
399 TreeNode *Child;
400
401if (Entry.Offset.isSubDir()) {
402
403// Create a new subdirectory and recurse
404if (i < Table.NumberOfNameEntries) {
405UNWRAP_OR_RETURN(NameString, RSR.getEntryNameString(Entry));
406 Child = &Node.addNameChild(NameString,StringTable);
407 Context.push_back(StringOrID(NameString));
408 }else {
409 Child = &Node.addIDChild(Entry.Identifier.ID);
410 Context.push_back(StringOrID(Entry.Identifier.ID));
411 }
412
413UNWRAP_REF_OR_RETURN(NextTable, RSR.getEntrySubDir(Entry));
414Error E =
415 addChildren(*Child, RSR, NextTable, Origin, Context, Duplicates);
416if (E)
417return E;
418 Context.pop_back();
419
420 }else {
421
422// Data leaves are supposed to have a numeric ID as identifier (language).
423if (Table.NumberOfNameEntries > 0)
424returncreateStringError(object_error::parse_failed,
425"unexpected string key for data object");
426
427// Try adding a data leaf
428UNWRAP_REF_OR_RETURN(DataEntry, RSR.getEntryData(Entry));
429 TreeNode *Child;
430 Context.push_back(StringOrID(Entry.Identifier.ID));
431boolAdded =Node.addDataChild(Entry.Identifier.ID, Table.MajorVersion,
432 Table.MinorVersion, Table.Characteristics,
433 Origin, Data.size(), Child);
434if (Added) {
435UNWRAP_OR_RETURN(Contents, RSR.getContents(DataEntry));
436 Data.push_back(ArrayRef<uint8_t>(
437reinterpret_cast<constuint8_t *>(Contents.data()),
438 Contents.size()));
439 }else {
440if (!shouldIgnoreDuplicate(Context))
441 Duplicates.push_back(makeDuplicateResourceError(
442 Context, InputFilenames[Child->Origin], InputFilenames.back()));
443 }
444 Context.pop_back();
445
446 }
447 }
448returnError::success();
449}
450
451WindowsResourceParser::TreeNode::TreeNode(uint32_t StringIndex)
452 : StringIndex(StringIndex) {}
453
454WindowsResourceParser::TreeNode::TreeNode(uint16_t MajorVersion,
455uint16_t MinorVersion,
456uint32_tCharacteristics,
457uint32_t Origin,uint32_t DataIndex)
458 : IsDataNode(true), DataIndex(DataIndex), MajorVersion(MajorVersion),
459 MinorVersion(MinorVersion),Characteristics(Characteristics),
460 Origin(Origin) {}
461
462std::unique_ptr<WindowsResourceParser::TreeNode>
463WindowsResourceParser::TreeNode::createStringNode(uint32_t Index) {
464return std::unique_ptr<TreeNode>(new TreeNode(Index));
465}
466
467std::unique_ptr<WindowsResourceParser::TreeNode>
468WindowsResourceParser::TreeNode::createIDNode() {
469return std::unique_ptr<TreeNode>(new TreeNode(0));
470}
471
472std::unique_ptr<WindowsResourceParser::TreeNode>
473WindowsResourceParser::TreeNode::createDataNode(uint16_t MajorVersion,
474uint16_t MinorVersion,
475uint32_tCharacteristics,
476uint32_t Origin,
477uint32_t DataIndex) {
478return std::unique_ptr<TreeNode>(new TreeNode(
479 MajorVersion, MinorVersion,Characteristics, Origin, DataIndex));
480}
481
482WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addTypeNode(
483constResourceEntryRef &Entry,
484 std::vector<std::vector<UTF16>> &StringTable) {
485if (Entry.checkTypeString())
486return addNameChild(Entry.getTypeString(),StringTable);
487else
488return addIDChild(Entry.getTypeID());
489}
490
491WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addNameNode(
492constResourceEntryRef &Entry,
493 std::vector<std::vector<UTF16>> &StringTable) {
494if (Entry.checkNameString())
495return addNameChild(Entry.getNameString(),StringTable);
496else
497return addIDChild(Entry.getNameID());
498}
499
500bool WindowsResourceParser::TreeNode::addLanguageNode(
501constResourceEntryRef &Entry,uint32_t Origin,
502 std::vector<std::vector<uint8_t>> &Data, TreeNode *&Result) {
503boolAdded = addDataChild(Entry.getLanguage(),Entry.getMajorVersion(),
504Entry.getMinorVersion(),Entry.getCharacteristics(),
505 Origin, Data.size(), Result);
506if (Added)
507 Data.push_back(Entry.getData());
508returnAdded;
509}
510
511bool WindowsResourceParser::TreeNode::addDataChild(
512uint32_tID,uint16_t MajorVersion,uint16_t MinorVersion,
513uint32_tCharacteristics,uint32_t Origin,uint32_t DataIndex,
514 TreeNode *&Result) {
515auto NewChild = createDataNode(MajorVersion, MinorVersion,Characteristics,
516 Origin, DataIndex);
517auto ElementInserted = IDChildren.emplace(ID, std::move(NewChild));
518Result = ElementInserted.first->second.get();
519return ElementInserted.second;
520}
521
522WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addIDChild(
523uint32_tID) {
524auto Child = IDChildren.find(ID);
525if (Child == IDChildren.end()) {
526auto NewChild = createIDNode();
527WindowsResourceParser::TreeNode &Node = *NewChild;
528 IDChildren.emplace(ID, std::move(NewChild));
529returnNode;
530 }else
531return *(Child->second);
532}
533
534WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addNameChild(
535ArrayRef<UTF16> NameRef, std::vector<std::vector<UTF16>> &StringTable) {
536 std::string NameString;
537convertUTF16LEToUTF8String(NameRef, NameString);
538
539auto Child = StringChildren.find(NameString);
540if (Child == StringChildren.end()) {
541auto NewChild = createStringNode(StringTable.size());
542StringTable.push_back(NameRef);
543WindowsResourceParser::TreeNode &Node = *NewChild;
544 StringChildren.emplace(NameString, std::move(NewChild));
545returnNode;
546 }else
547return *(Child->second);
548}
549
550voidWindowsResourceParser::TreeNode::print(ScopedPrinter &Writer,
551StringRefName) const{
552ListScope NodeScope(Writer,Name);
553for (autoconst &Child : StringChildren) {
554 Child.second->print(Writer, Child.first);
555 }
556for (autoconst &Child : IDChildren) {
557 Child.second->print(Writer,to_string(Child.first));
558 }
559}
560
561// This function returns the size of the entire resource tree, including
562// directory tables, directory entries, and data entries. It does not include
563// the directory strings or the relocations of the .rsrc section.
564uint32_tWindowsResourceParser::TreeNode::getTreeSize() const{
565uint32_tSize = (IDChildren.size() + StringChildren.size()) *
566sizeof(coff_resource_dir_entry);
567
568// Reached a node pointing to a data entry.
569if (IsDataNode) {
570Size +=sizeof(coff_resource_data_entry);
571returnSize;
572 }
573
574// If the node does not point to data, it must have a directory table pointing
575// to other nodes.
576Size +=sizeof(coff_resource_dir_table);
577
578for (autoconst &Child : StringChildren) {
579Size += Child.second->getTreeSize();
580 }
581for (autoconst &Child : IDChildren) {
582Size += Child.second->getTreeSize();
583 }
584returnSize;
585}
586
587// Shift DataIndex of all data children with an Index greater or equal to the
588// given one, to fill a gap from removing an entry from the Data vector.
589void WindowsResourceParser::TreeNode::shiftDataIndexDown(uint32_t Index) {
590if (IsDataNode && DataIndex >= Index) {
591 DataIndex--;
592 }else {
593for (auto &Child : IDChildren)
594 Child.second->shiftDataIndexDown(Index);
595for (auto &Child : StringChildren)
596 Child.second->shiftDataIndexDown(Index);
597 }
598}
599
600classWindowsResourceCOFFWriter {
601public:
602WindowsResourceCOFFWriter(COFF::MachineTypes MachineType,
603constWindowsResourceParser &Parser,Error &E);
604 std::unique_ptr<MemoryBuffer>write(uint32_t TimeDateStamp);
605
606private:
607void performFileLayout();
608void performSectionOneLayout();
609void performSectionTwoLayout();
610void writeCOFFHeader(uint32_t TimeDateStamp);
611void writeFirstSectionHeader();
612void writeSecondSectionHeader();
613void writeFirstSection();
614void writeSecondSection();
615voidwriteSymbolTable();
616voidwriteStringTable();
617void writeDirectoryTree();
618void writeDirectoryStringTable();
619void writeFirstSectionRelocations();
620 std::unique_ptr<WritableMemoryBuffer> OutputBuffer;
621char *BufferStart;
622uint64_t CurrentOffset = 0;
623COFF::MachineTypes MachineType;
624constWindowsResourceParser::TreeNode &Resources;
625constArrayRef<std::vector<uint8_t>> Data;
626uint64_t FileSize;
627uint32_t SymbolTableOffset;
628uint32_t SectionOneSize;
629uint32_t SectionOneOffset;
630uint32_t SectionOneRelocations;
631uint32_t SectionTwoSize;
632uint32_t SectionTwoOffset;
633constArrayRef<std::vector<UTF16>>StringTable;
634 std::vector<uint32_t> StringTableOffsets;
635 std::vector<uint32_t> DataOffsets;
636 std::vector<uint32_t> RelocationAddresses;
637};
638
639WindowsResourceCOFFWriter::WindowsResourceCOFFWriter(
640COFF::MachineTypes MachineType,constWindowsResourceParser &Parser,
641Error &E)
642 : MachineType(MachineType), Resources(Parser.getTree()),
643 Data(Parser.getData()),StringTable(Parser.getStringTable()) {
644 performFileLayout();
645
646 OutputBuffer =WritableMemoryBuffer::getNewMemBuffer(
647 FileSize,"internal .obj file created from .res files");
648}
649
650void WindowsResourceCOFFWriter::performFileLayout() {
651// Add size of COFF header.
652 FileSize =COFF::Header16Size;
653
654// one .rsrc section header for directory tree, another for resource data.
655 FileSize += 2 *COFF::SectionSize;
656
657 performSectionOneLayout();
658 performSectionTwoLayout();
659
660// We have reached the address of the symbol table.
661 SymbolTableOffset = FileSize;
662
663 FileSize +=COFF::Symbol16Size;// size of the @feat.00 symbol.
664 FileSize += 4 *COFF::Symbol16Size;// symbol + aux for each section.
665 FileSize += Data.size() *COFF::Symbol16Size;// 1 symbol per resource.
666 FileSize += 4;// four null bytes for the string table.
667}
668
669void WindowsResourceCOFFWriter::performSectionOneLayout() {
670 SectionOneOffset = FileSize;
671
672 SectionOneSize = Resources.getTreeSize();
673uint32_t CurrentStringOffset = SectionOneSize;
674uint32_t TotalStringTableSize = 0;
675for (autoconst &String :StringTable) {
676 StringTableOffsets.push_back(CurrentStringOffset);
677uint32_t StringSize =String.size() *sizeof(UTF16) +sizeof(uint16_t);
678 CurrentStringOffset += StringSize;
679 TotalStringTableSize += StringSize;
680 }
681 SectionOneSize +=alignTo(TotalStringTableSize,sizeof(uint32_t));
682
683// account for the relocations of section one.
684 SectionOneRelocations = FileSize + SectionOneSize;
685 FileSize += SectionOneSize;
686 FileSize +=
687 Data.size() *COFF::RelocationSize;// one relocation for each resource.
688 FileSize =alignTo(FileSize,SECTION_ALIGNMENT);
689}
690
691void WindowsResourceCOFFWriter::performSectionTwoLayout() {
692// add size of .rsrc$2 section, which contains all resource data on 8-byte
693// alignment.
694 SectionTwoOffset = FileSize;
695 SectionTwoSize = 0;
696for (autoconst &Entry : Data) {
697 DataOffsets.push_back(SectionTwoSize);
698 SectionTwoSize +=alignTo(Entry.size(),sizeof(uint64_t));
699 }
700 FileSize += SectionTwoSize;
701 FileSize =alignTo(FileSize,SECTION_ALIGNMENT);
702}
703
704std::unique_ptr<MemoryBuffer>
705WindowsResourceCOFFWriter::write(uint32_t TimeDateStamp) {
706 BufferStart = OutputBuffer->getBufferStart();
707
708 writeCOFFHeader(TimeDateStamp);
709 writeFirstSectionHeader();
710 writeSecondSectionHeader();
711 writeFirstSection();
712 writeSecondSection();
713 writeSymbolTable();
714 writeStringTable();
715
716return std::move(OutputBuffer);
717}
718
719// According to COFF specification, if the Src has a size equal to Dest,
720// it's okay to *not* copy the trailing zero.
721staticvoidcoffnamecpy(char (&Dest)[COFF::NameSize],StringRef Src) {
722assert(Src.size() <=COFF::NameSize &&
723"Src is larger than COFF::NameSize");
724assert((Src.size() ==COFF::NameSize || Dest[Src.size()] =='\0') &&
725"Dest not zeroed upon initialization");
726 memcpy(Dest, Src.data(), Src.size());
727}
728
729void WindowsResourceCOFFWriter::writeCOFFHeader(uint32_t TimeDateStamp) {
730// Write the COFF header.
731auto *Header =reinterpret_cast<coff_file_header *>(BufferStart);
732 Header->Machine = MachineType;
733 Header->NumberOfSections = 2;
734 Header->TimeDateStamp = TimeDateStamp;
735 Header->PointerToSymbolTable = SymbolTableOffset;
736// One symbol for every resource plus 2 for each section and 1 for @feat.00
737 Header->NumberOfSymbols = Data.size() + 5;
738 Header->SizeOfOptionalHeader = 0;
739// cvtres.exe sets 32BIT_MACHINE even for 64-bit machine types. Match it.
740 Header->Characteristics =COFF::IMAGE_FILE_32BIT_MACHINE;
741}
742
743void WindowsResourceCOFFWriter::writeFirstSectionHeader() {
744// Write the first section header.
745 CurrentOffset +=sizeof(coff_file_header);
746auto *SectionOneHeader =
747reinterpret_cast<coff_section *>(BufferStart + CurrentOffset);
748coffnamecpy(SectionOneHeader->Name,".rsrc$01");
749 SectionOneHeader->VirtualSize = 0;
750 SectionOneHeader->VirtualAddress = 0;
751 SectionOneHeader->SizeOfRawData = SectionOneSize;
752 SectionOneHeader->PointerToRawData = SectionOneOffset;
753 SectionOneHeader->PointerToRelocations = SectionOneRelocations;
754 SectionOneHeader->PointerToLinenumbers = 0;
755 SectionOneHeader->NumberOfRelocations = Data.size();
756 SectionOneHeader->NumberOfLinenumbers = 0;
757 SectionOneHeader->Characteristics +=COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
758 SectionOneHeader->Characteristics +=COFF::IMAGE_SCN_MEM_READ;
759}
760
761void WindowsResourceCOFFWriter::writeSecondSectionHeader() {
762// Write the second section header.
763 CurrentOffset +=sizeof(coff_section);
764auto *SectionTwoHeader =
765reinterpret_cast<coff_section *>(BufferStart + CurrentOffset);
766coffnamecpy(SectionTwoHeader->Name,".rsrc$02");
767 SectionTwoHeader->VirtualSize = 0;
768 SectionTwoHeader->VirtualAddress = 0;
769 SectionTwoHeader->SizeOfRawData = SectionTwoSize;
770 SectionTwoHeader->PointerToRawData = SectionTwoOffset;
771 SectionTwoHeader->PointerToRelocations = 0;
772 SectionTwoHeader->PointerToLinenumbers = 0;
773 SectionTwoHeader->NumberOfRelocations = 0;
774 SectionTwoHeader->NumberOfLinenumbers = 0;
775 SectionTwoHeader->Characteristics =COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
776 SectionTwoHeader->Characteristics +=COFF::IMAGE_SCN_MEM_READ;
777}
778
779void WindowsResourceCOFFWriter::writeFirstSection() {
780// Write section one.
781 CurrentOffset +=sizeof(coff_section);
782
783 writeDirectoryTree();
784 writeDirectoryStringTable();
785 writeFirstSectionRelocations();
786
787 CurrentOffset =alignTo(CurrentOffset,SECTION_ALIGNMENT);
788}
789
790void WindowsResourceCOFFWriter::writeSecondSection() {
791// Now write the .rsrc$02 section.
792for (autoconst &RawDataEntry : Data) {
793llvm::copy(RawDataEntry, BufferStart + CurrentOffset);
794 CurrentOffset +=alignTo(RawDataEntry.size(),sizeof(uint64_t));
795 }
796
797 CurrentOffset =alignTo(CurrentOffset,SECTION_ALIGNMENT);
798}
799
800void WindowsResourceCOFFWriter::writeSymbolTable() {
801// Now write the symbol table.
802// First, the feat symbol.
803auto *Symbol =reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
804coffnamecpy(Symbol->Name.ShortName,"@feat.00");
805Symbol->Value = 0x11;
806Symbol->SectionNumber = 0xffff;
807Symbol->Type =COFF::IMAGE_SYM_DTYPE_NULL;
808Symbol->StorageClass =COFF::IMAGE_SYM_CLASS_STATIC;
809Symbol->NumberOfAuxSymbols = 0;
810 CurrentOffset +=sizeof(coff_symbol16);
811
812// Now write the .rsrc1 symbol + aux.
813Symbol =reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
814coffnamecpy(Symbol->Name.ShortName,".rsrc$01");
815Symbol->Value = 0;
816Symbol->SectionNumber = 1;
817Symbol->Type =COFF::IMAGE_SYM_DTYPE_NULL;
818Symbol->StorageClass =COFF::IMAGE_SYM_CLASS_STATIC;
819Symbol->NumberOfAuxSymbols = 1;
820 CurrentOffset +=sizeof(coff_symbol16);
821auto *Aux =reinterpret_cast<coff_aux_section_definition *>(BufferStart +
822 CurrentOffset);
823 Aux->Length = SectionOneSize;
824 Aux->NumberOfRelocations = Data.size();
825 Aux->NumberOfLinenumbers = 0;
826 Aux->CheckSum = 0;
827 Aux->NumberLowPart = 0;
828 Aux->Selection = 0;
829 CurrentOffset +=sizeof(coff_aux_section_definition);
830
831// Now write the .rsrc2 symbol + aux.
832Symbol =reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
833coffnamecpy(Symbol->Name.ShortName,".rsrc$02");
834Symbol->Value = 0;
835Symbol->SectionNumber = 2;
836Symbol->Type =COFF::IMAGE_SYM_DTYPE_NULL;
837Symbol->StorageClass =COFF::IMAGE_SYM_CLASS_STATIC;
838Symbol->NumberOfAuxSymbols = 1;
839 CurrentOffset +=sizeof(coff_symbol16);
840 Aux =reinterpret_cast<coff_aux_section_definition *>(BufferStart +
841 CurrentOffset);
842 Aux->Length = SectionTwoSize;
843 Aux->NumberOfRelocations = 0;
844 Aux->NumberOfLinenumbers = 0;
845 Aux->CheckSum = 0;
846 Aux->NumberLowPart = 0;
847 Aux->Selection = 0;
848 CurrentOffset +=sizeof(coff_aux_section_definition);
849
850// Now write a symbol for each relocation.
851for (unsigned i = 0; i < Data.size(); i++) {
852auto RelocationName =formatv("$R{0:X-6}", i & 0xffffff).sstr<COFF::NameSize>();
853Symbol =reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset);
854coffnamecpy(Symbol->Name.ShortName, RelocationName);
855Symbol->Value = DataOffsets[i];
856Symbol->SectionNumber = 2;
857Symbol->Type =COFF::IMAGE_SYM_DTYPE_NULL;
858Symbol->StorageClass =COFF::IMAGE_SYM_CLASS_STATIC;
859Symbol->NumberOfAuxSymbols = 0;
860 CurrentOffset +=sizeof(coff_symbol16);
861 }
862}
863
864void WindowsResourceCOFFWriter::writeStringTable() {
865// Just 4 null bytes for the string table.
866auto COFFStringTable =reinterpret_cast<void *>(BufferStart + CurrentOffset);
867 memset(COFFStringTable, 0, 4);
868}
869
870void WindowsResourceCOFFWriter::writeDirectoryTree() {
871// Traverse parsed resource tree breadth-first and write the corresponding
872// COFF objects.
873 std::queue<const WindowsResourceParser::TreeNode *>Queue;
874Queue.push(&Resources);
875uint32_t NextLevelOffset =
876sizeof(coff_resource_dir_table) + (Resources.getStringChildren().size() +
877 Resources.getIDChildren().size()) *
878sizeof(coff_resource_dir_entry);
879 std::vector<const WindowsResourceParser::TreeNode *> DataEntriesTreeOrder;
880uint32_t CurrentRelativeOffset = 0;
881
882while (!Queue.empty()) {
883auto CurrentNode =Queue.front();
884Queue.pop();
885auto *Table =reinterpret_cast<coff_resource_dir_table *>(BufferStart +
886 CurrentOffset);
887 Table->Characteristics = CurrentNode->getCharacteristics();
888 Table->TimeDateStamp = 0;
889 Table->MajorVersion = CurrentNode->getMajorVersion();
890 Table->MinorVersion = CurrentNode->getMinorVersion();
891auto &IDChildren = CurrentNode->getIDChildren();
892auto &StringChildren = CurrentNode->getStringChildren();
893 Table->NumberOfNameEntries = StringChildren.size();
894 Table->NumberOfIDEntries = IDChildren.size();
895 CurrentOffset +=sizeof(coff_resource_dir_table);
896 CurrentRelativeOffset +=sizeof(coff_resource_dir_table);
897
898// Write the directory entries immediately following each directory table.
899for (autoconst &Child : StringChildren) {
900auto *Entry =reinterpret_cast<coff_resource_dir_entry *>(BufferStart +
901 CurrentOffset);
902Entry->Identifier.setNameOffset(
903 StringTableOffsets[Child.second->getStringIndex()]);
904if (Child.second->checkIsDataNode()) {
905Entry->Offset.DataEntryOffset = NextLevelOffset;
906 NextLevelOffset +=sizeof(coff_resource_data_entry);
907 DataEntriesTreeOrder.push_back(Child.second.get());
908 }else {
909Entry->Offset.SubdirOffset = NextLevelOffset + (1 << 31);
910 NextLevelOffset +=sizeof(coff_resource_dir_table) +
911 (Child.second->getStringChildren().size() +
912 Child.second->getIDChildren().size()) *
913sizeof(coff_resource_dir_entry);
914Queue.push(Child.second.get());
915 }
916 CurrentOffset +=sizeof(coff_resource_dir_entry);
917 CurrentRelativeOffset +=sizeof(coff_resource_dir_entry);
918 }
919for (autoconst &Child : IDChildren) {
920auto *Entry =reinterpret_cast<coff_resource_dir_entry *>(BufferStart +
921 CurrentOffset);
922Entry->Identifier.ID = Child.first;
923if (Child.second->checkIsDataNode()) {
924Entry->Offset.DataEntryOffset = NextLevelOffset;
925 NextLevelOffset +=sizeof(coff_resource_data_entry);
926 DataEntriesTreeOrder.push_back(Child.second.get());
927 }else {
928Entry->Offset.SubdirOffset = NextLevelOffset + (1 << 31);
929 NextLevelOffset +=sizeof(coff_resource_dir_table) +
930 (Child.second->getStringChildren().size() +
931 Child.second->getIDChildren().size()) *
932sizeof(coff_resource_dir_entry);
933Queue.push(Child.second.get());
934 }
935 CurrentOffset +=sizeof(coff_resource_dir_entry);
936 CurrentRelativeOffset +=sizeof(coff_resource_dir_entry);
937 }
938 }
939
940 RelocationAddresses.resize(Data.size());
941// Now write all the resource data entries.
942for (constauto *DataNodes : DataEntriesTreeOrder) {
943auto *Entry =reinterpret_cast<coff_resource_data_entry *>(BufferStart +
944 CurrentOffset);
945 RelocationAddresses[DataNodes->getDataIndex()] = CurrentRelativeOffset;
946Entry->DataRVA = 0;// Set to zero because it is a relocation.
947Entry->DataSize = Data[DataNodes->getDataIndex()].size();
948Entry->Codepage = 0;
949Entry->Reserved = 0;
950 CurrentOffset +=sizeof(coff_resource_data_entry);
951 CurrentRelativeOffset +=sizeof(coff_resource_data_entry);
952 }
953}
954
955void WindowsResourceCOFFWriter::writeDirectoryStringTable() {
956// Now write the directory string table for .rsrc$01
957uint32_t TotalStringTableSize = 0;
958for (auto &String :StringTable) {
959uint16_tLength =String.size();
960support::endian::write16le(BufferStart + CurrentOffset,Length);
961 CurrentOffset +=sizeof(uint16_t);
962auto *Start =reinterpret_cast<UTF16 *>(BufferStart + CurrentOffset);
963llvm::copy(String, Start);
964 CurrentOffset +=Length *sizeof(UTF16);
965 TotalStringTableSize +=Length *sizeof(UTF16) +sizeof(uint16_t);
966 }
967 CurrentOffset +=
968alignTo(TotalStringTableSize,sizeof(uint32_t)) - TotalStringTableSize;
969}
970
971void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {
972
973// Now write the relocations for .rsrc$01
974// Five symbols already in table before we start, @feat.00 and 2 for each
975// .rsrc section.
976uint32_t NextSymbolIndex = 5;
977for (unsigned i = 0; i < Data.size(); i++) {
978auto *Reloc =
979reinterpret_cast<coff_relocation *>(BufferStart + CurrentOffset);
980 Reloc->VirtualAddress = RelocationAddresses[i];
981 Reloc->SymbolTableIndex = NextSymbolIndex++;
982switch (getMachineArchType(MachineType)) {
983caseTriple::thumb:
984 Reloc->Type =COFF::IMAGE_REL_ARM_ADDR32NB;
985break;
986caseTriple::x86_64:
987 Reloc->Type =COFF::IMAGE_REL_AMD64_ADDR32NB;
988break;
989caseTriple::x86:
990 Reloc->Type =COFF::IMAGE_REL_I386_DIR32NB;
991break;
992caseTriple::aarch64:
993 Reloc->Type =COFF::IMAGE_REL_ARM64_ADDR32NB;
994break;
995default:
996llvm_unreachable("unknown machine type");
997 }
998 CurrentOffset +=sizeof(coff_relocation);
999 }
1000}
1001
1002Expected<std::unique_ptr<MemoryBuffer>>
1003writeWindowsResourceCOFF(COFF::MachineTypes MachineType,
1004constWindowsResourceParser &Parser,
1005uint32_t TimeDateStamp) {
1006Error E =Error::success();
1007WindowsResourceCOFFWriter Writer(MachineType,Parser, E);
1008if (E)
1009return E;
1010return Writer.write(TimeDateStamp);
1011}
1012
1013}// namespace object
1014}// namespace llvm
writeSymbolTable
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, StringRef StringTable, uint64_t MembersOffset, unsigned NumSyms, uint64_t PrevMemberOffset=0, uint64_t NextMemberOffset=0, bool Is64Bit=false)
Definition:ArchiveWriter.cpp:595
true
basic Basic Alias true
Definition:BasicAliasAnalysis.cpp:1981
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
RETURN_IF_ERROR
#define RETURN_IF_ERROR(Expr)
Definition:COFFObjectFile.cpp:2203
Characteristics
COFFYAML::WeakExternalCharacteristics Characteristics
Definition:COFFYAML.cpp:350
getFileName
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
Definition:CodeViewYAMLDebugSections.cpp:553
UNI_UTF16_BYTE_ORDER_MARK_SWAPPED
#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED
Definition:ConvertUTF.h:143
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
End
bool End
Definition:ELF_riscv.cpp:480
FormatVariadic.h
MathExtras.h
COFF.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
ScopedPrinter.h
WindowsMachineFlag.h
UNWRAP_OR_RETURN
#define UNWRAP_OR_RETURN(Name, Expr)
Definition:WindowsResource.cpp:38
UNWRAP_REF_OR_RETURN
#define UNWRAP_REF_OR_RETURN(Name, Expr)
Definition:WindowsResource.cpp:32
WindowsResource.h
Node
Definition:ItaniumDemangle.h:163
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::BinaryByteStream
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Definition:BinaryByteStream.h:30
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition:BinaryStreamReader.h:29
llvm::BinaryStreamReader::readObject
Error readObject(const T *&Dest)
Get a pointer to an object of type T from the underlying stream, as if by memcpy, and store the resul...
Definition:BinaryStreamReader.h:160
llvm::BinaryStreamReader::readWideString
Error readWideString(ArrayRef< UTF16 > &Dest)
Similar to readCString, however read a null-terminated UTF16 string instead.
Definition:BinaryStreamReader.cpp:101
llvm::BinaryStreamReader::readInteger
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream's offset.
Definition:BinaryStreamReader.h:67
llvm::BinaryStreamReader::bytesRemaining
uint64_t bytesRemaining() const
Definition:BinaryStreamReader.h:248
llvm::BinaryStreamReader::getOffset
uint64_t getOffset() const
Definition:BinaryStreamReader.h:246
llvm::BinaryStreamReader::padToAlignment
Error padToAlignment(uint32_t Align)
Definition:BinaryStreamReader.cpp:154
llvm::BinaryStreamReader::setOffset
void setOffset(uint64_t Off)
Definition:BinaryStreamReader.h:245
llvm::BinaryStreamReader::readArray
Error readArray(ArrayRef< T > &Array, uint32_t NumElements)
Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...
Definition:BinaryStreamReader.h:178
llvm::BinaryStreamRef
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
Definition:BinaryStreamRef.h:154
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::MemoryBufferRef
Definition:MemoryBufferRef.h:22
llvm::ScopedPrinter
Definition:ScopedPrinter.h:100
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringTable
A table of densely packed, null-terminated strings indexed by offset.
Definition:StringTable.h:33
llvm::StringTable::size
constexpr size_t size() const
Returns the byte size of the table.
Definition:StringTable.h:97
llvm::Triple::x86
@ x86
Definition:Triple.h:85
llvm::Triple::x86_64
@ x86_64
Definition:Triple.h:86
llvm::Triple::thumb
@ thumb
Definition:Triple.h:83
llvm::Triple::aarch64
@ aarch64
Definition:Triple.h:51
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::TypeID
TypeID
Definitions of all of the base types for the Type system.
Definition:Type.h:54
llvm::WritableMemoryBuffer::getNewMemBuffer
static std::unique_ptr< WritableMemoryBuffer > getNewMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
Definition:MemoryBuffer.cpp:349
llvm::object::Binary
Definition:Binary.h:32
llvm::object::Binary::getFileName
StringRef getFileName() const
Definition:Binary.cpp:41
llvm::object::EmptyResError
Definition:WindowsResource.h:92
llvm::object::Parser
Definition:COFFModuleDefinition.cpp:139
llvm::object::ResourceEntryRef
Definition:WindowsResource.h:98
llvm::object::ResourceEntryRef::moveNext
Error moveNext(bool &End)
Definition:WindowsResource.cpp:87
llvm::object::ResourceSectionRef
Definition:COFF.h:1407
llvm::object::ResourceSectionRef::getBaseTable
Expected< const coff_resource_dir_table & > getBaseTable()
Definition:COFFObjectFile.cpp:2271
llvm::object::ResourceSectionRef::getEntrySubDir
Expected< const coff_resource_dir_table & > getEntrySubDir(const coff_resource_dir_entry &Entry)
Definition:COFFObjectFile.cpp:2260
llvm::object::ResourceSectionRef::getEntryData
Expected< const coff_resource_data_entry & > getEntryData(const coff_resource_dir_entry &Entry)
Definition:COFFObjectFile.cpp:2266
llvm::object::ResourceSectionRef::getEntryNameString
Expected< ArrayRef< UTF16 > > getEntryNameString(const coff_resource_dir_entry &Entry)
Definition:COFFObjectFile.cpp:2222
llvm::object::ResourceSectionRef::getContents
Expected< StringRef > getContents(const coff_resource_data_entry &Entry)
Definition:COFFObjectFile.cpp:2318
llvm::object::ResourceSectionRef::getTableEntry
Expected< const coff_resource_dir_entry & > getTableEntry(const coff_resource_dir_table &Table, uint32_t Index)
Definition:COFFObjectFile.cpp:2276
llvm::object::WindowsResourceCOFFWriter
Definition:WindowsResource.cpp:600
llvm::object::WindowsResourceCOFFWriter::WindowsResourceCOFFWriter
WindowsResourceCOFFWriter(COFF::MachineTypes MachineType, const WindowsResourceParser &Parser, Error &E)
Definition:WindowsResource.cpp:639
llvm::object::WindowsResourceCOFFWriter::write
std::unique_ptr< MemoryBuffer > write(uint32_t TimeDateStamp)
Definition:WindowsResource.cpp:705
llvm::object::WindowsResourceParser::TreeNode
Definition:WindowsResource.h:166
llvm::object::WindowsResourceParser::TreeNode::getStringChildren
const Children< std::string > & getStringChildren() const
Definition:WindowsResource.h:180
llvm::object::WindowsResourceParser::TreeNode::getTreeSize
uint32_t getTreeSize() const
Definition:WindowsResource.cpp:564
llvm::object::WindowsResourceParser::TreeNode::getIDChildren
const Children< uint32_t > & getIDChildren() const
Definition:WindowsResource.h:179
llvm::object::WindowsResourceParser::TreeNode::print
void print(ScopedPrinter &Writer, StringRef Name) const
Definition:WindowsResource.cpp:550
llvm::object::WindowsResourceParser
Definition:WindowsResource.h:153
llvm::object::WindowsResourceParser::cleanUpManifests
void cleanUpManifests(std::vector< std::string > &Duplicates)
Definition:WindowsResource.cpp:262
llvm::object::WindowsResourceParser::getTree
const TreeNode & getTree() const
Definition:WindowsResource.h:162
llvm::object::WindowsResourceParser::printTree
void printTree(raw_ostream &OS) const
Definition:WindowsResource.cpp:375
llvm::object::WindowsResourceParser::getData
ArrayRef< std::vector< uint8_t > > getData() const
Definition:WindowsResource.h:163
llvm::object::WindowsResourceParser::WindowsResourceParser
WindowsResourceParser(bool MinGW=false)
Definition:WindowsResource.cpp:139
llvm::object::WindowsResourceParser::getStringTable
ArrayRef< std::vector< UTF16 > > getStringTable() const
Definition:WindowsResource.h:164
llvm::object::WindowsResourceParser::parse
Error parse(WindowsResource *WR, std::vector< std::string > &Duplicates)
Definition:WindowsResource.cpp:328
llvm::object::WindowsResource
Definition:WindowsResource.h:136
llvm::object::WindowsResource::getHeadEntry
Expected< ResourceEntryRef > getHeadEntry()
Definition:WindowsResource.cpp:68
llvm::object::WindowsResource::createWindowsResource
static Expected< std::unique_ptr< WindowsResource > > createWindowsResource(MemoryBufferRef Source)
Definition:WindowsResource.cpp:59
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition:raw_ostream.h:52
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition:raw_ostream.h:661
uint16_t
uint32_t
uint64_t
uint8_t
unsigned
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
false
Definition:StackSlotColoring.cpp:193
llvm::AMDGPU::HSAMD::ValueKind::Queue
@ Queue
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition:ARMBuildAttributes.h:83
llvm::COFF::MachineTypes
MachineTypes
Definition:COFF.h:92
llvm::COFF::IMAGE_SCN_MEM_READ
@ IMAGE_SCN_MEM_READ
Definition:COFF.h:335
llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition:COFF.h:303
llvm::COFF::IMAGE_REL_ARM64_ADDR32NB
@ IMAGE_REL_ARM64_ADDR32NB
Definition:COFF.h:402
llvm::COFF::NameSize
@ NameSize
Definition:COFF.h:57
llvm::COFF::Header16Size
@ Header16Size
Definition:COFF.h:55
llvm::COFF::Symbol16Size
@ Symbol16Size
Definition:COFF.h:58
llvm::COFF::SectionSize
@ SectionSize
Definition:COFF.h:60
llvm::COFF::RelocationSize
@ RelocationSize
Definition:COFF.h:61
llvm::COFF::IMAGE_REL_AMD64_ADDR32NB
@ IMAGE_REL_AMD64_ADDR32NB
Definition:COFF.h:363
llvm::COFF::IMAGE_SYM_CLASS_STATIC
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition:COFF.h:224
llvm::COFF::IMAGE_REL_ARM_ADDR32NB
@ IMAGE_REL_ARM_ADDR32NB
Definition:COFF.h:382
llvm::COFF::IMAGE_REL_I386_DIR32NB
@ IMAGE_REL_I386_DIR32NB
Definition:COFF.h:350
llvm::COFF::Entry
@ Entry
Definition:COFF.h:844
llvm::COFF::IMAGE_FILE_32BIT_MACHINE
@ IMAGE_FILE_32BIT_MACHINE
Machine is based on a 32bit word architecture.
Definition:COFF.h:159
llvm::COFF::IMAGE_SYM_DTYPE_NULL
@ IMAGE_SYM_DTYPE_NULL
No complex type; simple scalar variable.
Definition:COFF.h:273
llvm::logicalview::LVComparePass::Added
@ Added
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::object::MIN_HEADER_SIZE
const uint32_t MIN_HEADER_SIZE
Definition:WindowsResource.cpp:44
llvm::object::printStringOrID
static void printStringOrID(const WindowsResourceParser::StringOrID &S, raw_string_ostream &OS, bool IsType, bool IsID)
Definition:WindowsResource.cpp:212
llvm::object::writeWindowsResourceCOFF
Expected< std::unique_ptr< MemoryBuffer > > writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType, const WindowsResourceParser &Parser, uint32_t TimeDateStamp)
Definition:WindowsResource.cpp:1003
llvm::object::WIN_RES_NULL_ENTRY_SIZE
const size_t WIN_RES_NULL_ENTRY_SIZE
Definition:WindowsResource.h:55
llvm::object::WIN_RES_DATA_ALIGNMENT
const uint32_t WIN_RES_DATA_ALIGNMENT
Definition:WindowsResource.h:57
llvm::object::printResourceTypeName
void printResourceTypeName(uint16_t TypeID, raw_ostream &OS)
Definition:WindowsResource.cpp:142
llvm::object::WIN_RES_HEADER_ALIGNMENT
const uint32_t WIN_RES_HEADER_ALIGNMENT
Definition:WindowsResource.h:56
llvm::object::makeDuplicateResourceError
static std::string makeDuplicateResourceError(const ResourceEntryRef &Entry, StringRef File1, StringRef File2)
Definition:WindowsResource.cpp:180
llvm::object::object_error::parse_failed
@ parse_failed
llvm::object::coffnamecpy
static void coffnamecpy(char(&Dest)[COFF::NameSize], StringRef Src)
Definition:WindowsResource.cpp:721
llvm::object::WIN_RES_MAGIC_SIZE
const size_t WIN_RES_MAGIC_SIZE
Definition:WindowsResource.h:54
llvm::object::readStringOrId
static Error readStringOrId(BinaryStreamReader &Reader, uint16_t &ID, ArrayRef< UTF16 > &Str, bool &IsString)
Definition:WindowsResource.cpp:98
llvm::object::convertUTF16LEToUTF8String
static bool convertUTF16LEToUTF8String(ArrayRef< UTF16 > Src, std::string &Out)
Definition:WindowsResource.cpp:169
llvm::object::coff_symbol16
coff_symbol< support::ulittle16_t > coff_symbol16
Definition:COFF.h:269
llvm::object::writeStringTable
static void writeStringTable(std::vector< uint8_t > &B, ArrayRef< const std::string_view > Strings)
Definition:COFFImportFile.cpp:147
llvm::object::SECTION_ALIGNMENT
const uint32_t SECTION_ALIGNMENT
Definition:WindowsResource.cpp:48
llvm::support::endian::write16le
void write16le(void *P, uint16_t V)
Definition:Endian.h:465
llvm::sys::IsBigEndianHost
constexpr bool IsBigEndianHost
Definition:SwapByteOrder.h:26
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Length
@ Length
Definition:DWP.cpp:480
llvm::to_string
std::string to_string(const T &Value)
Definition:ScopedPrinter.h:85
llvm::UTF16
unsigned short UTF16
Definition:ConvertUTF.h:129
llvm::getMachineArchType
Triple::ArchType getMachineArchType(T machine)
Definition:WindowsMachineFlag.h:34
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition:Error.h:1291
llvm::formatv
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
Definition:FormatVariadic.h:252
llvm::write
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Definition:DWP.cpp:625
llvm::convertUTF16ToUTF8String
bool convertUTF16ToUTF8String(ArrayRef< char > SrcBytes, std::string &Out)
Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
Definition:ConvertUTFWrapper.cpp:83
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::copy
OutputIt copy(R &&Range, OutputIt Out)
Definition:STLExtras.h:1841
llvm::HighlightColor::String
@ String
llvm::UTF8
unsigned char UTF8
Definition:ConvertUTF.h:130
llvm::endianness::little
@ little
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition:Error.h:1069
llvm::ListScope
Definition:ScopedPrinter.h:868
llvm::object::WinResHeaderPrefix
Definition:WindowsResource.h:60
llvm::object::WinResHeaderSuffix
Definition:WindowsResource.h:84
llvm::object::WindowsResourceParser::StringOrID
Definition:WindowsResource.h:234
llvm::object::WindowsResourceParser::StringOrID::ID
uint32_t ID
Definition:WindowsResource.h:237
llvm::object::WindowsResourceParser::StringOrID::String
ArrayRef< UTF16 > String
Definition:WindowsResource.h:236
llvm::object::WindowsResourceParser::StringOrID::IsString
bool IsString
Definition:WindowsResource.h:235
llvm::object::coff_aux_section_definition
Definition:COFF.h:519
llvm::object::coff_aux_section_definition::Length
support::ulittle32_t Length
Definition:COFF.h:520
llvm::object::coff_file_header
Definition:COFF.h:79
llvm::object::coff_relocation
Definition:COFF.h:482
llvm::object::coff_relocation::VirtualAddress
support::ulittle32_t VirtualAddress
Definition:COFF.h:483
llvm::object::coff_resource_data_entry
Definition:COFF.h:826
llvm::object::coff_resource_dir_entry
Definition:COFF.h:803
llvm::object::coff_resource_dir_table
Definition:COFF.h:833
llvm::object::coff_resource_dir_table::NumberOfNameEntries
support::ulittle16_t NumberOfNameEntries
Definition:COFF.h:838
llvm::object::coff_resource_dir_table::Characteristics
support::ulittle32_t Characteristics
Definition:COFF.h:834
llvm::object::coff_resource_dir_table::NumberOfIDEntries
support::ulittle16_t NumberOfIDEntries
Definition:COFF.h:839
llvm::object::coff_resource_dir_table::TimeDateStamp
support::ulittle32_t TimeDateStamp
Definition:COFF.h:835
llvm::object::coff_resource_dir_table::MinorVersion
support::ulittle16_t MinorVersion
Definition:COFF.h:837
llvm::object::coff_resource_dir_table::MajorVersion
support::ulittle16_t MajorVersion
Definition:COFF.h:836
llvm::object::coff_section
Definition:COFF.h:448
llvm::object::coff_symbol
Definition:COFF.h:254

Generated on Fri Jul 18 2025 11:46:03 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp