Coverage Report

Created: 2019-02-20 00:17

/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
#include "llvm/Support/ScopedPrinter.h"
41
42
#include <map>
43
44
namespace llvm {
45
namespace object {
46
47
class WindowsResource;
48
49
const size_t WIN_RES_MAGIC_SIZE = 16;
50
const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
51
const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
52
const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
53
const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
54
55
struct WinResHeaderPrefix {
56
  support::ulittle32_t DataSize;
57
  support::ulittle32_t HeaderSize;
58
};
59
60
// Type and Name may each either be an integer ID or a string.  This struct is
61
// only used in the case where they are both IDs.
62
struct WinResIDs {
63
  uint16_t TypeFlag;
64
  support::ulittle16_t TypeID;
65
  uint16_t NameFlag;
66
  support::ulittle16_t NameID;
67
68
  void setType(uint16_t ID) {
69
    TypeFlag = 0xffff;
70
    TypeID = ID;
71
  }
72
73
  void setName(uint16_t ID) {
74
    NameFlag = 0xffff;
75
    NameID = ID;
76
  }
77
};
78
79
struct WinResHeaderSuffix {
80
  support::ulittle32_t DataVersion;
81
  support::ulittle16_t MemoryFlags;
82
  support::ulittle16_t Language;
83
  support::ulittle32_t Version;
84
  support::ulittle32_t Characteristics;
85
};
86
87
class EmptyResError : public GenericBinaryError {
88
public:
89
  EmptyResError(Twine Msg, object_error ECOverride)
90
0
      : GenericBinaryError(Msg, ECOverride) {}
91
};
92
93
class ResourceEntryRef {
94
public:
95
  Error moveNext(bool &End);
96
277
  bool checkTypeString() const { return IsStringType; }
97
23
  ArrayRef<UTF16> getTypeString() const { return Type; }
98
264
  uint16_t getTypeID() const { return TypeID; }
99
277
  bool checkNameString() const { return IsStringName; }
100
153
  ArrayRef<UTF16> getNameString() const { return Name; }
101
186
  uint16_t getNameID() const { return NameID; }
102
  uint16_t getDataVersion() const { return Suffix->DataVersion; }
103
277
  uint16_t getLanguage() const { return Suffix->Language; }
104
  uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
105
277
  uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
106
277
  uint16_t getMinorVersion() const { return Suffix->Version; }
107
277
  uint32_t getCharacteristics() const { return Suffix->Characteristics; }
108
462
  ArrayRef<uint8_t> getData() const { return Data; }
109
110
private:
111
  friend class WindowsResource;
112
113
  ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
114
  Error loadNext();
115
116
  static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
117
                                           const WindowsResource *Owner);
118
119
  BinaryStreamReader Reader;
120
  bool IsStringType;
121
  ArrayRef<UTF16> Type;
122
  uint16_t TypeID;
123
  bool IsStringName;
124
  ArrayRef<UTF16> Name;
125
  uint16_t NameID;
126
  const WinResHeaderSuffix *Suffix = nullptr;
127
  ArrayRef<uint8_t> Data;
128
};
129
130
class WindowsResource : public Binary {
131
public:
132
  Expected<ResourceEntryRef> getHeadEntry();
133
134
  static bool classof(const Binary *V) { return V->isWinRes(); }
135
136
  static Expected<std::unique_ptr<WindowsResource>>
137
  createWindowsResource(MemoryBufferRef Source);
138
139
private:
140
  friend class ResourceEntryRef;
141
142
  WindowsResource(MemoryBufferRef Source);
143
144
  BinaryByteStream BBS;
145
};
146
147
class WindowsResourceParser {
148
public:
149
  class TreeNode;
150
  WindowsResourceParser();
151
  Error parse(WindowsResource *WR);
152
  void printTree(raw_ostream &OS) const;
153
13
  const TreeNode &getTree() const { return Root; }
154
13
  const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
155
13
  const ArrayRef<std::vector<UTF16>> getStringTable() const {
156
13
    return StringTable;
157
13
  }
158
159
  class TreeNode {
160
  public:
161
    template <typename T>
162
    using Children = std::map<T, std::unique_ptr<TreeNode>>;
163
164
    void print(ScopedPrinter &Writer, StringRef Name) const;
165
    uint32_t getTreeSize() const;
166
72
    uint32_t getStringIndex() const { return StringIndex; }
167
184
    uint32_t getDataIndex() const { return DataIndex; }
168
155
    uint16_t getMajorVersion() const { return MajorVersion; }
169
155
    uint16_t getMinorVersion() const { return MinorVersion; }
170
155
    uint32_t getCharacteristics() const { return Characteristics; }
171
234
    bool checkIsDataNode() const { return IsDataNode; }
172
310
    const Children<uint32_t> &getIDChildren() const { return IDChildren; }
173
310
    const Children<std::string> &getStringChildren() const {
174
310
      return StringChildren;
175
310
    }
176
177
  private:
178
    friend class WindowsResourceParser;
179
180
    static uint32_t StringCount;
181
    static uint32_t DataCount;
182
183
    static std::unique_ptr<TreeNode> createStringNode();
184
    static std::unique_ptr<TreeNode> createIDNode();
185
    static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
186
                                                    uint16_t MinorVersion,
187
                                                    uint32_t Characteristics);
188
189
    explicit TreeNode(bool IsStringNode);
190
    TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
191
             uint32_t Characteristics);
192
193
    void addEntry(const ResourceEntryRef &Entry, bool &IsNewTypeString,
194
                  bool &IsNewNameString);
195
    TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString);
196
    TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);
197
    TreeNode &addLanguageNode(const ResourceEntryRef &Entry);
198
    TreeNode &addChild(uint32_t ID, bool IsDataNode = false,
199
                       uint16_t MajorVersion = 0, uint16_t MinorVersion = 0,
200
                       uint32_t Characteristics = 0);
201
    TreeNode &addChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
202
203
    bool IsDataNode = false;
204
    uint32_t StringIndex;
205
    uint32_t DataIndex;
206
    Children<uint32_t> IDChildren;
207
    Children<std::string> StringChildren;
208
    uint16_t MajorVersion = 0;
209
    uint16_t MinorVersion = 0;
210
    uint32_t Characteristics = 0;
211
  };
212
213
private:
214
  TreeNode Root;
215
  std::vector<std::vector<uint8_t>> Data;
216
  std::vector<std::vector<UTF16>> StringTable;
217
};
218
219
Expected<std::unique_ptr<MemoryBuffer>>
220
writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
221
                         const WindowsResourceParser &Parser);
222
223
} // namespace object
224
} // namespace llvm
225
226
#endif