]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Object/WindowsResource.h
MFV r353630: 10809 Performance optimization of AVL tree comparator functions
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Object / WindowsResource.h
1 //===-- WindowsResource.h ---------------------------------------*- 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 declares the .res file class.  .res files are intermediate
10 // products of the typical resource-compilation process on Windows.  This
11 // process is as follows:
12 //
13 // .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
14 //
15 // .rc files are human-readable scripts that list all resources a program uses.
16 //
17 // They are compiled into .res files, which are a list of the resources in
18 // binary form.
19 //
20 // Finally the data stored in the .res is compiled into a COFF file, where it
21 // is organized in a directory tree structure for optimized access by the
22 // program during runtime.
23 //
24 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
25 //
26 //===---------------------------------------------------------------------===//
27
28 #ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
29 #define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
30
31 #include "llvm/ADT/ArrayRef.h"
32 #include "llvm/BinaryFormat/COFF.h"
33 #include "llvm/Object/Binary.h"
34 #include "llvm/Object/Error.h"
35 #include "llvm/Support/BinaryByteStream.h"
36 #include "llvm/Support/BinaryStreamReader.h"
37 #include "llvm/Support/ConvertUTF.h"
38 #include "llvm/Support/Endian.h"
39 #include "llvm/Support/Error.h"
40
41 #include <map>
42
43 namespace llvm {
44
45 class raw_ostream;
46 class ScopedPrinter;
47
48 namespace object {
49
50 class WindowsResource;
51
52 const size_t WIN_RES_MAGIC_SIZE = 16;
53 const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
54 const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
55 const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
56 const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
57
58 struct WinResHeaderPrefix {
59   support::ulittle32_t DataSize;
60   support::ulittle32_t HeaderSize;
61 };
62
63 // Type and Name may each either be an integer ID or a string.  This struct is
64 // only used in the case where they are both IDs.
65 struct WinResIDs {
66   uint16_t TypeFlag;
67   support::ulittle16_t TypeID;
68   uint16_t NameFlag;
69   support::ulittle16_t NameID;
70
71   void setType(uint16_t ID) {
72     TypeFlag = 0xffff;
73     TypeID = ID;
74   }
75
76   void setName(uint16_t ID) {
77     NameFlag = 0xffff;
78     NameID = ID;
79   }
80 };
81
82 struct WinResHeaderSuffix {
83   support::ulittle32_t DataVersion;
84   support::ulittle16_t MemoryFlags;
85   support::ulittle16_t Language;
86   support::ulittle32_t Version;
87   support::ulittle32_t Characteristics;
88 };
89
90 class EmptyResError : public GenericBinaryError {
91 public:
92   EmptyResError(Twine Msg, object_error ECOverride)
93       : GenericBinaryError(Msg, ECOverride) {}
94 };
95
96 class ResourceEntryRef {
97 public:
98   Error moveNext(bool &End);
99   bool checkTypeString() const { return IsStringType; }
100   ArrayRef<UTF16> getTypeString() const { return Type; }
101   uint16_t getTypeID() const { return TypeID; }
102   bool checkNameString() const { return IsStringName; }
103   ArrayRef<UTF16> getNameString() const { return Name; }
104   uint16_t getNameID() const { return NameID; }
105   uint16_t getDataVersion() const { return Suffix->DataVersion; }
106   uint16_t getLanguage() const { return Suffix->Language; }
107   uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
108   uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
109   uint16_t getMinorVersion() const { return Suffix->Version; }
110   uint32_t getCharacteristics() const { return Suffix->Characteristics; }
111   ArrayRef<uint8_t> getData() const { return Data; }
112
113 private:
114   friend class WindowsResource;
115
116   ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
117   Error loadNext();
118
119   static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
120                                            const WindowsResource *Owner);
121
122   BinaryStreamReader Reader;
123   const WindowsResource *Owner;
124   bool IsStringType;
125   ArrayRef<UTF16> Type;
126   uint16_t TypeID;
127   bool IsStringName;
128   ArrayRef<UTF16> Name;
129   uint16_t NameID;
130   const WinResHeaderSuffix *Suffix = nullptr;
131   ArrayRef<uint8_t> Data;
132 };
133
134 class WindowsResource : public Binary {
135 public:
136   Expected<ResourceEntryRef> getHeadEntry();
137
138   static bool classof(const Binary *V) { return V->isWinRes(); }
139
140   static Expected<std::unique_ptr<WindowsResource>>
141   createWindowsResource(MemoryBufferRef Source);
142
143 private:
144   friend class ResourceEntryRef;
145
146   WindowsResource(MemoryBufferRef Source);
147
148   BinaryByteStream BBS;
149 };
150
151 class WindowsResourceParser {
152 public:
153   class TreeNode;
154   WindowsResourceParser();
155   Error parse(WindowsResource *WR, std::vector<std::string> &Duplicates);
156   void printTree(raw_ostream &OS) const;
157   const TreeNode &getTree() const { return Root; }
158   const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
159   const ArrayRef<std::vector<UTF16>> getStringTable() const {
160     return StringTable;
161   }
162
163   class TreeNode {
164   public:
165     template <typename T>
166     using Children = std::map<T, std::unique_ptr<TreeNode>>;
167
168     void print(ScopedPrinter &Writer, StringRef Name) const;
169     uint32_t getTreeSize() const;
170     uint32_t getStringIndex() const { return StringIndex; }
171     uint32_t getDataIndex() const { return DataIndex; }
172     uint16_t getMajorVersion() const { return MajorVersion; }
173     uint16_t getMinorVersion() const { return MinorVersion; }
174     uint32_t getCharacteristics() const { return Characteristics; }
175     bool checkIsDataNode() const { return IsDataNode; }
176     const Children<uint32_t> &getIDChildren() const { return IDChildren; }
177     const Children<std::string> &getStringChildren() const {
178       return StringChildren;
179     }
180
181   private:
182     friend class WindowsResourceParser;
183
184     static uint32_t StringCount;
185     static uint32_t DataCount;
186
187     static std::unique_ptr<TreeNode> createStringNode();
188     static std::unique_ptr<TreeNode> createIDNode();
189     static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
190                                                     uint16_t MinorVersion,
191                                                     uint32_t Characteristics,
192                                                     uint32_t Origin);
193
194     explicit TreeNode(bool IsStringNode);
195     TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
196              uint32_t Characteristics, uint32_t Origin);
197
198     bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
199                   bool &IsNewTypeString, bool &IsNewNameString,
200                   TreeNode *&Result);
201     TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString);
202     TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);
203     bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
204                          TreeNode *&Result);
205     bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
206                       uint32_t Characteristics, uint32_t Origin,
207                       TreeNode *&Result);
208     TreeNode &addIDChild(uint32_t ID);
209     TreeNode &addNameChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
210
211     bool IsDataNode = false;
212     uint32_t StringIndex;
213     uint32_t DataIndex;
214     Children<uint32_t> IDChildren;
215     Children<std::string> StringChildren;
216     uint16_t MajorVersion = 0;
217     uint16_t MinorVersion = 0;
218     uint32_t Characteristics = 0;
219
220     // The .res file that defined this TreeNode, for diagnostics.
221     // Index into InputFilenames.
222     uint32_t Origin;
223   };
224
225 private:
226   TreeNode Root;
227   std::vector<std::vector<uint8_t>> Data;
228   std::vector<std::vector<UTF16>> StringTable;
229
230   std::vector<std::string> InputFilenames;
231 };
232
233 Expected<std::unique_ptr<MemoryBuffer>>
234 writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
235                          const WindowsResourceParser &Parser,
236                          uint32_t TimeDateStamp);
237
238 void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
239 } // namespace object
240 } // namespace llvm
241
242 #endif