Coverage Report

Created: 2022-01-22 13:19

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
Line
Count
Source
1
//===-- ObjectFilePECOFF.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
#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H
10
#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H
11
12
#include <vector>
13
14
#include "lldb/Symbol/ObjectFile.h"
15
#include "llvm/Object/COFF.h"
16
17
class ObjectFilePECOFF : public lldb_private::ObjectFile {
18
public:
19
  enum MachineType {
20
    MachineUnknown = 0x0,
21
    MachineAm33 = 0x1d3,
22
    MachineAmd64 = 0x8664,
23
    MachineArm = 0x1c0,
24
    MachineArmNt = 0x1c4,
25
    MachineArm64 = 0xaa64,
26
    MachineEbc = 0xebc,
27
    MachineX86 = 0x14c,
28
    MachineIA64 = 0x200,
29
    MachineM32R = 0x9041,
30
    MachineMips16 = 0x266,
31
    MachineMipsFpu = 0x366,
32
    MachineMipsFpu16 = 0x466,
33
    MachinePowerPc = 0x1f0,
34
    MachinePowerPcfp = 0x1f1,
35
    MachineR4000 = 0x166,
36
    MachineSh3 = 0x1a2,
37
    MachineSh3dsp = 0x1a3,
38
    MachineSh4 = 0x1a6,
39
    MachineSh5 = 0x1a8,
40
    MachineThumb = 0x1c2,
41
    MachineWcemIpsv2 = 0x169
42
  };
43
44
  ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
45
                   lldb::offset_t data_offset,
46
                   const lldb_private::FileSpec *file,
47
                   lldb::offset_t file_offset, lldb::offset_t length);
48
49
  ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
50
                   lldb::DataBufferSP &header_data_sp,
51
                   const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
52
53
  ~ObjectFilePECOFF() override;
54
55
  // Static Functions
56
  static void Initialize();
57
58
  static void Terminate();
59
60
3.46k
  static llvm::StringRef GetPluginNameStatic() { return "pe-coff"; }
61
62
  static llvm::StringRef GetPluginDescriptionStatic();
63
64
  static ObjectFile *
65
  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
66
                 lldb::offset_t data_offset, const lldb_private::FileSpec *file,
67
                 lldb::offset_t offset, lldb::offset_t length);
68
69
  static lldb_private::ObjectFile *CreateMemoryInstance(
70
      const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
71
      const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
72
73
  static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
74
                                        lldb::DataBufferSP &data_sp,
75
                                        lldb::offset_t data_offset,
76
                                        lldb::offset_t file_offset,
77
                                        lldb::offset_t length,
78
                                        lldb_private::ModuleSpecList &specs);
79
80
  static bool SaveCore(const lldb::ProcessSP &process_sp,
81
                       const lldb_private::FileSpec &outfile,
82
                       lldb::SaveCoreStyle &core_style,
83
                       lldb_private::Status &error);
84
85
  static bool MagicBytesMatch(lldb::DataBufferSP &data_sp);
86
87
  static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
88
89
  // LLVM RTTI support
90
  static char ID;
91
64
  bool isA(const void *ClassID) const override {
92
64
    return ClassID == &ID || 
ObjectFile::isA(ClassID)63
;
93
64
  }
94
  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
95
96
  bool ParseHeader() override;
97
98
  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
99
                      bool value_is_offset) override;
100
101
  lldb::ByteOrder GetByteOrder() const override;
102
103
  bool IsExecutable() const override;
104
105
  uint32_t GetAddressByteSize() const override;
106
107
  //    virtual lldb_private::AddressClass
108
  //    GetAddressClass (lldb::addr_t file_addr);
109
110
  void ParseSymtab(lldb_private::Symtab &symtab) override;
111
112
  bool IsStripped() override;
113
114
  void CreateSections(lldb_private::SectionList &unified_section_list) override;
115
116
  void Dump(lldb_private::Stream *s) override;
117
118
  lldb_private::ArchSpec GetArchitecture() override;
119
120
  lldb_private::UUID GetUUID() override;
121
122
  uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
123
124
  lldb_private::Address GetEntryPointAddress() override;
125
126
  lldb_private::Address GetBaseAddress() override;
127
128
  ObjectFile::Type CalculateType() override;
129
130
  ObjectFile::Strata CalculateStrata() override;
131
132
  // PluginInterface protocol
133
10
  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
134
135
  bool IsWindowsSubsystem();
136
137
  uint32_t GetRVA(const lldb_private::Address &addr) const;
138
  lldb_private::Address GetAddress(uint32_t rva);
139
  lldb::addr_t GetFileAddress(uint32_t rva) const;
140
141
  lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
142
  lldb_private::DataExtractor ReadImageDataByRVA(uint32_t rva, size_t size);
143
144
  std::unique_ptr<lldb_private::CallFrameInfo> CreateCallFrameInfo() override;
145
146
protected:
147
  bool NeedsEndianSwap() const;
148
149
  typedef struct dos_header { // DOS .EXE header
150
    uint16_t e_magic;         // Magic number
151
    uint16_t e_cblp;          // Bytes on last page of file
152
    uint16_t e_cp;            // Pages in file
153
    uint16_t e_crlc;          // Relocations
154
    uint16_t e_cparhdr;       // Size of header in paragraphs
155
    uint16_t e_minalloc;      // Minimum extra paragraphs needed
156
    uint16_t e_maxalloc;      // Maximum extra paragraphs needed
157
    uint16_t e_ss;            // Initial (relative) SS value
158
    uint16_t e_sp;            // Initial SP value
159
    uint16_t e_csum;          // Checksum
160
    uint16_t e_ip;            // Initial IP value
161
    uint16_t e_cs;            // Initial (relative) CS value
162
    uint16_t e_lfarlc;        // File address of relocation table
163
    uint16_t e_ovno;          // Overlay number
164
    uint16_t e_res[4];        // Reserved words
165
    uint16_t e_oemid;         // OEM identifier (for e_oeminfo)
166
    uint16_t e_oeminfo;       // OEM information; e_oemid specific
167
    uint16_t e_res2[10];      // Reserved words
168
    uint32_t e_lfanew;        // File address of new exe header
169
  } dos_header_t;
170
171
  typedef struct coff_header {
172
    uint16_t machine;
173
    uint16_t nsects;
174
    uint32_t modtime;
175
    uint32_t symoff;
176
    uint32_t nsyms;
177
    uint16_t hdrsize;
178
    uint16_t flags;
179
  } coff_header_t;
180
181
  typedef struct data_directory {
182
    uint32_t vmaddr;
183
    uint32_t vmsize;
184
  } data_directory_t;
185
186
  typedef struct coff_opt_header {
187
    uint16_t magic = 0;
188
    uint8_t major_linker_version = 0;
189
    uint8_t minor_linker_version = 0;
190
    uint32_t code_size = 0;
191
    uint32_t data_size = 0;
192
    uint32_t bss_size = 0;
193
    uint32_t entry = 0;
194
    uint32_t code_offset = 0;
195
    uint32_t data_offset = 0;
196
197
    uint64_t image_base = 0;
198
    uint32_t sect_alignment = 0;
199
    uint32_t file_alignment = 0;
200
    uint16_t major_os_system_version = 0;
201
    uint16_t minor_os_system_version = 0;
202
    uint16_t major_image_version = 0;
203
    uint16_t minor_image_version = 0;
204
    uint16_t major_subsystem_version = 0;
205
    uint16_t minor_subsystem_version = 0;
206
    uint32_t reserved1 = 0;
207
    uint32_t image_size = 0;
208
    uint32_t header_size = 0;
209
    uint32_t checksum = 0;
210
    uint16_t subsystem = 0;
211
    uint16_t dll_flags = 0;
212
    uint64_t stack_reserve_size = 0;
213
    uint64_t stack_commit_size = 0;
214
    uint64_t heap_reserve_size = 0;
215
    uint64_t heap_commit_size = 0;
216
    uint32_t loader_flags = 0;
217
    //    uint32_t  num_data_dir_entries;
218
    std::vector<data_directory>
219
        data_dirs; // will contain num_data_dir_entries entries
220
  } coff_opt_header_t;
221
222
  enum coff_data_dir_type {
223
    coff_data_dir_export_table = 0,
224
    coff_data_dir_import_table = 1,
225
    coff_data_dir_exception_table = 3
226
  };
227
228
  typedef struct section_header {
229
    char name[8];
230
    uint32_t vmsize;  // Virtual Size
231
    uint32_t vmaddr;  // Virtual Addr
232
    uint32_t size;    // File size
233
    uint32_t offset;  // File offset
234
    uint32_t reloff;  // Offset to relocations
235
    uint32_t lineoff; // Offset to line table entries
236
    uint16_t nreloc;  // Number of relocation entries
237
    uint16_t nline;   // Number of line table entries
238
    uint32_t flags;
239
  } section_header_t;
240
241
  typedef struct coff_symbol {
242
    char name[8];
243
    uint32_t value;
244
    uint16_t sect;
245
    uint16_t type;
246
    uint8_t storage;
247
    uint8_t naux;
248
  } coff_symbol_t;
249
250
  typedef struct export_directory_entry {
251
    uint32_t characteristics;
252
    uint32_t time_date_stamp;
253
    uint16_t major_version;
254
    uint16_t minor_version;
255
    uint32_t name;
256
    uint32_t base;
257
    uint32_t number_of_functions;
258
    uint32_t number_of_names;
259
    uint32_t address_of_functions;
260
    uint32_t address_of_names;
261
    uint32_t address_of_name_ordinals;
262
  } export_directory_entry;
263
264
  static bool ParseDOSHeader(lldb_private::DataExtractor &data,
265
                             dos_header_t &dos_header);
266
  static bool ParseCOFFHeader(lldb_private::DataExtractor &data,
267
                              lldb::offset_t *offset_ptr,
268
                              coff_header_t &coff_header);
269
  bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
270
  bool ParseSectionHeaders(uint32_t offset);
271
272
  uint32_t ParseDependentModules();
273
274
  static void DumpDOSHeader(lldb_private::Stream *s,
275
                            const dos_header_t &header);
276
  static void DumpCOFFHeader(lldb_private::Stream *s,
277
                             const coff_header_t &header);
278
  static void DumpOptCOFFHeader(lldb_private::Stream *s,
279
                                const coff_opt_header_t &header);
280
  void DumpSectionHeaders(lldb_private::Stream *s);
281
  void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh);
282
  void DumpDependentModules(lldb_private::Stream *s);
283
284
  llvm::StringRef GetSectionName(const section_header_t &sect);
285
  static lldb::SectionType GetSectionType(llvm::StringRef sect_name,
286
                                          const section_header_t &sect);
287
288
  typedef std::vector<section_header_t> SectionHeaderColl;
289
  typedef SectionHeaderColl::iterator SectionHeaderCollIter;
290
  typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
291
292
private:
293
  bool CreateBinary();
294
295
  dos_header_t m_dos_header;
296
  coff_header_t m_coff_header;
297
  coff_opt_header_t m_coff_header_opt;
298
  SectionHeaderColl m_sect_headers;
299
  lldb::addr_t m_image_base;
300
  lldb_private::Address m_entry_point_address;
301
  llvm::Optional<lldb_private::FileSpecList> m_deps_filespec;
302
  std::unique_ptr<llvm::object::COFFObjectFile> m_binary;
303
  lldb_private::UUID m_uuid;
304
};
305
306
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_PECOFF_OBJECTFILEPECOFF_H