Coverage Report

Created: 2017-10-03 07:32

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