Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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_OBJECT_WINDOWSRESOURCE_H
29
#define LLVM_OBJECT_WINDOWSRESOURCE_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
class ResourceSectionRef;
52
struct coff_resource_dir_table;
53
 
54
const size_t WIN_RES_MAGIC_SIZE = 16;
55
const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
56
const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
57
const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
58
const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
59
 
60
struct WinResHeaderPrefix {
61
  support::ulittle32_t DataSize;
62
  support::ulittle32_t HeaderSize;
63
};
64
 
65
// Type and Name may each either be an integer ID or a string.  This struct is
66
// only used in the case where they are both IDs.
67
struct WinResIDs {
68
  uint16_t TypeFlag;
69
  support::ulittle16_t TypeID;
70
  uint16_t NameFlag;
71
  support::ulittle16_t NameID;
72
 
73
  void setType(uint16_t ID) {
74
    TypeFlag = 0xffff;
75
    TypeID = ID;
76
  }
77
 
78
  void setName(uint16_t ID) {
79
    NameFlag = 0xffff;
80
    NameID = ID;
81
  }
82
};
83
 
84
struct WinResHeaderSuffix {
85
  support::ulittle32_t DataVersion;
86
  support::ulittle16_t MemoryFlags;
87
  support::ulittle16_t Language;
88
  support::ulittle32_t Version;
89
  support::ulittle32_t Characteristics;
90
};
91
 
92
class EmptyResError : public GenericBinaryError {
93
public:
94
  EmptyResError(Twine Msg, object_error ECOverride)
95
      : GenericBinaryError(Msg, ECOverride) {}
96
};
97
 
98
class ResourceEntryRef {
99
public:
100
  Error moveNext(bool &End);
101
  bool checkTypeString() const { return IsStringType; }
102
  ArrayRef<UTF16> getTypeString() const { return Type; }
103
  uint16_t getTypeID() const { return TypeID; }
104
  bool checkNameString() const { return IsStringName; }
105
  ArrayRef<UTF16> getNameString() const { return Name; }
106
  uint16_t getNameID() const { return NameID; }
107
  uint16_t getDataVersion() const { return Suffix->DataVersion; }
108
  uint16_t getLanguage() const { return Suffix->Language; }
109
  uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
110
  uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
111
  uint16_t getMinorVersion() const { return Suffix->Version; }
112
  uint32_t getCharacteristics() const { return Suffix->Characteristics; }
113
  ArrayRef<uint8_t> getData() const { return Data; }
114
 
115
private:
116
  friend class WindowsResource;
117
 
118
  ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
119
  Error loadNext();
120
 
121
  static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
122
                                           const WindowsResource *Owner);
123
 
124
  BinaryStreamReader Reader;
125
  const WindowsResource *Owner;
126
  bool IsStringType;
127
  ArrayRef<UTF16> Type;
128
  uint16_t TypeID;
129
  bool IsStringName;
130
  ArrayRef<UTF16> Name;
131
  uint16_t NameID;
132
  const WinResHeaderSuffix *Suffix = nullptr;
133
  ArrayRef<uint8_t> Data;
134
};
135
 
136
class WindowsResource : public Binary {
137
public:
138
  Expected<ResourceEntryRef> getHeadEntry();
139
 
140
  static bool classof(const Binary *V) { return V->isWinRes(); }
141
 
142
  static Expected<std::unique_ptr<WindowsResource>>
143
  createWindowsResource(MemoryBufferRef Source);
144
 
145
private:
146
  friend class ResourceEntryRef;
147
 
148
  WindowsResource(MemoryBufferRef Source);
149
 
150
  BinaryByteStream BBS;
151
};
152
 
153
class WindowsResourceParser {
154
public:
155
  class TreeNode;
156
  WindowsResourceParser(bool MinGW = false);
157
  Error parse(WindowsResource *WR, std::vector<std::string> &Duplicates);
158
  Error parse(ResourceSectionRef &RSR, StringRef Filename,
159
              std::vector<std::string> &Duplicates);
160
  void cleanUpManifests(std::vector<std::string> &Duplicates);
161
  void printTree(raw_ostream &OS) const;
162
  const TreeNode &getTree() const { return Root; }
163
  ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
164
  ArrayRef<std::vector<UTF16>> getStringTable() const { return StringTable; }
165
 
166
  class TreeNode {
167
  public:
168
    template <typename T>
169
    using Children = std::map<T, std::unique_ptr<TreeNode>>;
170
 
171
    void print(ScopedPrinter &Writer, StringRef Name) const;
172
    uint32_t getTreeSize() const;
173
    uint32_t getStringIndex() const { return StringIndex; }
174
    uint32_t getDataIndex() const { return DataIndex; }
175
    uint16_t getMajorVersion() const { return MajorVersion; }
176
    uint16_t getMinorVersion() const { return MinorVersion; }
177
    uint32_t getCharacteristics() const { return Characteristics; }
178
    bool checkIsDataNode() const { return IsDataNode; }
179
    const Children<uint32_t> &getIDChildren() const { return IDChildren; }
180
    const Children<std::string> &getStringChildren() const {
181
      return StringChildren;
182
    }
183
 
184
  private:
185
    friend class WindowsResourceParser;
186
 
187
    // Index is the StringTable vector index for this node's name.
188
    static std::unique_ptr<TreeNode> createStringNode(uint32_t Index);
189
    static std::unique_ptr<TreeNode> createIDNode();
190
    // DataIndex is the Data vector index that the data node points at.
191
    static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
192
                                                    uint16_t MinorVersion,
193
                                                    uint32_t Characteristics,
194
                                                    uint32_t Origin,
195
                                                    uint32_t DataIndex);
196
 
197
    explicit TreeNode(uint32_t StringIndex);
198
    TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
199
             uint32_t Characteristics, uint32_t Origin, uint32_t DataIndex);
200
 
201
    bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
202
                  std::vector<std::vector<uint8_t>> &Data,
203
                  std::vector<std::vector<UTF16>> &StringTable,
204
                  TreeNode *&Result);
205
    TreeNode &addTypeNode(const ResourceEntryRef &Entry,
206
                          std::vector<std::vector<UTF16>> &StringTable);
207
    TreeNode &addNameNode(const ResourceEntryRef &Entry,
208
                          std::vector<std::vector<UTF16>> &StringTable);
209
    bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
210
                         std::vector<std::vector<uint8_t>> &Data,
211
                         TreeNode *&Result);
212
    bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
213
                      uint32_t Characteristics, uint32_t Origin,
214
                      uint32_t DataIndex, TreeNode *&Result);
215
    TreeNode &addIDChild(uint32_t ID);
216
    TreeNode &addNameChild(ArrayRef<UTF16> NameRef,
217
                           std::vector<std::vector<UTF16>> &StringTable);
218
    void shiftDataIndexDown(uint32_t Index);
219
 
220
    bool IsDataNode = false;
221
    uint32_t StringIndex;
222
    uint32_t DataIndex;
223
    Children<uint32_t> IDChildren;
224
    Children<std::string> StringChildren;
225
    uint16_t MajorVersion = 0;
226
    uint16_t MinorVersion = 0;
227
    uint32_t Characteristics = 0;
228
 
229
    // The .res file that defined this TreeNode, for diagnostics.
230
    // Index into InputFilenames.
231
    uint32_t Origin;
232
  };
233
 
234
  struct StringOrID {
235
    bool IsString;
236
    ArrayRef<UTF16> String;
237
    uint32_t ID;
238
 
239
    StringOrID(uint32_t ID) : IsString(false), ID(ID) {}
240
    StringOrID(ArrayRef<UTF16> String) : IsString(true), String(String) {}
241
  };
242
 
243
private:
244
  Error addChildren(TreeNode &Node, ResourceSectionRef &RSR,
245
                    const coff_resource_dir_table &Table, uint32_t Origin,
246
                    std::vector<StringOrID> &Context,
247
                    std::vector<std::string> &Duplicates);
248
  bool shouldIgnoreDuplicate(const ResourceEntryRef &Entry) const;
249
  bool shouldIgnoreDuplicate(const std::vector<StringOrID> &Context) const;
250
 
251
  TreeNode Root;
252
  std::vector<std::vector<uint8_t>> Data;
253
  std::vector<std::vector<UTF16>> StringTable;
254
 
255
  std::vector<std::string> InputFilenames;
256
 
257
  bool MinGW;
258
};
259
 
260
Expected<std::unique_ptr<MemoryBuffer>>
261
writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
262
                         const WindowsResourceParser &Parser,
263
                         uint32_t TimeDateStamp);
264
 
265
void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
266
} // namespace object
267
} // namespace llvm
268
 
269
#endif