Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Object/WindowsResource.h
Line
Count
Source (jump to first uncovered line)
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
0
      : GenericBinaryError(Msg, ECOverride) {}
94
};
95
96
class ResourceEntryRef {
97
public:
98
  Error moveNext(bool &End);
99
303
  bool checkTypeString() const { return IsStringType; }
100
29
  ArrayRef<UTF16> getTypeString() const { return Type; }
101
286
  uint16_t getTypeID() const { return TypeID; }
102
303
  bool checkNameString() const { return IsStringName; }
103
169
  ArrayRef<UTF16> getNameString() const { return Name; }
104
203
  uint16_t getNameID() const { return NameID; }
105
  uint16_t getDataVersion() const { return Suffix->DataVersion; }
106
303
  uint16_t getLanguage() const { return Suffix->Language; }
107
  uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
108
298
  uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
109
298
  uint16_t getMinorVersion() const { return Suffix->Version; }
110
298
  uint32_t getCharacteristics() const { return Suffix->Characteristics; }
111
483
  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
20
  const TreeNode &getTree() const { return Root; }
158
20
  const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
159
20
  const ArrayRef<std::vector<UTF16>> getStringTable() const {
160
20
    return StringTable;
161
20
  }
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
79
    uint32_t getStringIndex() const { return StringIndex; }
171
212
    uint32_t getDataIndex() const { return DataIndex; }
172
187
    uint16_t getMajorVersion() const { return MajorVersion; }
173
187
    uint16_t getMinorVersion() const { return MinorVersion; }
174
187
    uint32_t getCharacteristics() const { return Characteristics; }
175
273
    bool checkIsDataNode() const { return IsDataNode; }
176
374
    const Children<uint32_t> &getIDChildren() const { return IDChildren; }
177
374
    const Children<std::string> &getStringChildren() const {
178
374
      return StringChildren;
179
374
    }
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