blob: cf815b60eb448d5a0d0236871c5d43718cdca870 [file] [log] [blame]
Greg Claytonf754f882011-09-09 20:33:05 +00001//===-- ObjectFilePECOFF.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#ifndef liblldb_ObjectFilePECOFF_h_
11#define liblldb_ObjectFilePECOFF_h_
12
13#include <vector>
14
Greg Claytonf754f882011-09-09 20:33:05 +000015#include "lldb/Symbol/ObjectFile.h"
Aaron Smith037ed1b2018-12-06 21:36:39 +000016#include "llvm/Object/Binary.h"
Greg Claytonf754f882011-09-09 20:33:05 +000017
Kate Stoneb9c1b512016-09-06 20:57:50 +000018class ObjectFilePECOFF : public lldb_private::ObjectFile {
Greg Claytonf754f882011-09-09 20:33:05 +000019public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000020 typedef enum MachineType {
21 MachineUnknown = 0x0,
22 MachineAm33 = 0x1d3,
23 MachineAmd64 = 0x8664,
24 MachineArm = 0x1c0,
25 MachineArmNt = 0x1c4,
26 MachineArm64 = 0xaa64,
27 MachineEbc = 0xebc,
28 MachineX86 = 0x14c,
29 MachineIA64 = 0x200,
30 MachineM32R = 0x9041,
31 MachineMips16 = 0x266,
32 MachineMipsFpu = 0x366,
33 MachineMipsFpu16 = 0x466,
34 MachinePowerPc = 0x1f0,
35 MachinePowerPcfp = 0x1f1,
36 MachineR4000 = 0x166,
37 MachineSh3 = 0x1a2,
38 MachineSh3dsp = 0x1a3,
39 MachineSh4 = 0x1a6,
40 MachineSh5 = 0x1a8,
41 MachineThumb = 0x1c2,
42 MachineWcemIpsv2 = 0x169
43 } MachineType;
Eugene Zelenko8157a882015-10-23 16:56:07 +000044
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
46 lldb::offset_t data_offset,
47 const lldb_private::FileSpec *file,
48 lldb::offset_t file_offset, lldb::offset_t length);
Eugene Zelenko8157a882015-10-23 16:56:07 +000049
Walter Erquinigo344546b2016-10-17 20:28:19 +000050 ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
51 lldb::DataBufferSP &header_data_sp,
52 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
53
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 ~ObjectFilePECOFF() override;
Greg Claytonf4d6de62013-04-24 22:29:28 +000055
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 //------------------------------------------------------------------
57 // Static Functions
58 //------------------------------------------------------------------
59 static void Initialize();
Adrian McCarthyf7d18932015-11-20 23:09:11 +000060
Kate Stoneb9c1b512016-09-06 20:57:50 +000061 static void Terminate();
Adrian McCarthyc35b91c2016-01-26 00:58:09 +000062
Kate Stoneb9c1b512016-09-06 20:57:50 +000063 static lldb_private::ConstString GetPluginNameStatic();
Adrian McCarthyc35b91c2016-01-26 00:58:09 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 static const char *GetPluginDescriptionStatic();
Virgile Bello2756adf2014-03-08 17:17:20 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 static ObjectFile *
68 CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
69 lldb::offset_t data_offset, const lldb_private::FileSpec *file,
70 lldb::offset_t offset, lldb::offset_t length);
Adrian McCarthyc35b91c2016-01-26 00:58:09 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 static lldb_private::ObjectFile *CreateMemoryInstance(
73 const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
74 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
Greg Clayton3046e662013-07-10 01:23:25 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
77 lldb::DataBufferSP &data_sp,
78 lldb::offset_t data_offset,
79 lldb::offset_t file_offset,
80 lldb::offset_t length,
81 lldb_private::ModuleSpecList &specs);
Eugene Zelenko8157a882015-10-23 16:56:07 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 static bool SaveCore(const lldb::ProcessSP &process_sp,
84 const lldb_private::FileSpec &outfile,
Zachary Turner97206d52017-05-12 04:51:55 +000085 lldb_private::Status &error);
Kate Stoneb9c1b512016-09-06 20:57:50 +000086
87 static bool MagicBytesMatch(lldb::DataBufferSP &data_sp);
88
89 static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
90
91 bool ParseHeader() override;
92
93 bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
94 bool value_is_offset) override;
95
96 lldb::ByteOrder GetByteOrder() const override;
97
98 bool IsExecutable() const override;
99
100 uint32_t GetAddressByteSize() const override;
101
102 // virtual lldb_private::AddressClass
103 // GetAddressClass (lldb::addr_t file_addr);
104
105 lldb_private::Symtab *GetSymtab() override;
106
107 bool IsStripped() override;
108
109 void CreateSections(lldb_private::SectionList &unified_section_list) override;
110
111 void Dump(lldb_private::Stream *s) override;
112
Pavel Labathf760f5a2019-01-03 10:37:19 +0000113 lldb_private::ArchSpec GetArchitecture() override;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114
115 bool GetUUID(lldb_private::UUID *uuid) override;
116
117 uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
118
119 virtual lldb_private::Address GetEntryPointAddress() override;
120
121 ObjectFile::Type CalculateType() override;
122
123 ObjectFile::Strata CalculateStrata() override;
124
125 //------------------------------------------------------------------
126 // PluginInterface protocol
127 //------------------------------------------------------------------
128 lldb_private::ConstString GetPluginName() override;
129
130 uint32_t GetPluginVersion() override;
Eugene Zelenko8157a882015-10-23 16:56:07 +0000131
Zachary Turnerfb3b3bd2016-09-20 20:44:50 +0000132 bool IsWindowsSubsystem();
133
Walter Erquinigo344546b2016-10-17 20:28:19 +0000134 lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
135
Greg Claytonf754f882011-09-09 20:33:05 +0000136protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 bool NeedsEndianSwap() const;
Virgile Belloa4fe3a12013-08-25 13:27:20 +0000138
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 typedef struct dos_header { // DOS .EXE header
140 uint16_t e_magic; // Magic number
141 uint16_t e_cblp; // Bytes on last page of file
142 uint16_t e_cp; // Pages in file
143 uint16_t e_crlc; // Relocations
144 uint16_t e_cparhdr; // Size of header in paragraphs
145 uint16_t e_minalloc; // Minimum extra paragraphs needed
146 uint16_t e_maxalloc; // Maximum extra paragraphs needed
147 uint16_t e_ss; // Initial (relative) SS value
148 uint16_t e_sp; // Initial SP value
149 uint16_t e_csum; // Checksum
150 uint16_t e_ip; // Initial IP value
151 uint16_t e_cs; // Initial (relative) CS value
152 uint16_t e_lfarlc; // File address of relocation table
153 uint16_t e_ovno; // Overlay number
154 uint16_t e_res[4]; // Reserved words
155 uint16_t e_oemid; // OEM identifier (for e_oeminfo)
156 uint16_t e_oeminfo; // OEM information; e_oemid specific
157 uint16_t e_res2[10]; // Reserved words
158 uint32_t e_lfanew; // File address of new exe header
159 } dos_header_t;
Virgile Belloa4fe3a12013-08-25 13:27:20 +0000160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 typedef struct coff_header {
162 uint16_t machine;
163 uint16_t nsects;
164 uint32_t modtime;
165 uint32_t symoff;
166 uint32_t nsyms;
167 uint16_t hdrsize;
168 uint16_t flags;
169 } coff_header_t;
170
171 typedef struct data_directory {
172 uint32_t vmaddr;
173 uint32_t vmsize;
174 } data_directory_t;
175
176 typedef struct coff_opt_header {
177 uint16_t magic;
178 uint8_t major_linker_version;
179 uint8_t minor_linker_version;
180 uint32_t code_size;
181 uint32_t data_size;
182 uint32_t bss_size;
183 uint32_t entry;
184 uint32_t code_offset;
185 uint32_t data_offset;
186
187 uint64_t image_base;
188 uint32_t sect_alignment;
189 uint32_t file_alignment;
190 uint16_t major_os_system_version;
191 uint16_t minor_os_system_version;
192 uint16_t major_image_version;
193 uint16_t minor_image_version;
194 uint16_t major_subsystem_version;
195 uint16_t minor_subsystem_version;
196 uint32_t reserved1;
197 uint32_t image_size;
198 uint32_t header_size;
199 uint32_t checksum;
200 uint16_t subsystem;
201 uint16_t dll_flags;
202 uint64_t stack_reserve_size;
203 uint64_t stack_commit_size;
204 uint64_t heap_reserve_size;
205 uint64_t heap_commit_size;
206 uint32_t loader_flags;
207 // uint32_t num_data_dir_entries;
208 std::vector<data_directory>
209 data_dirs; // will contain num_data_dir_entries entries
210 } coff_opt_header_t;
211
212 typedef enum coff_data_dir_type {
213 coff_data_dir_export_table = 0,
214 coff_data_dir_import_table = 1,
215 } coff_data_dir_type;
216
217 typedef struct section_header {
218 char name[8];
219 uint32_t vmsize; // Virtual Size
220 uint32_t vmaddr; // Virtual Addr
221 uint32_t size; // File size
222 uint32_t offset; // File offset
223 uint32_t reloff; // Offset to relocations
224 uint32_t lineoff; // Offset to line table entries
225 uint16_t nreloc; // Number of relocation entries
226 uint16_t nline; // Number of line table entries
227 uint32_t flags;
228 } section_header_t;
229
230 typedef struct coff_symbol {
231 char name[8];
232 uint32_t value;
233 uint16_t sect;
234 uint16_t type;
235 uint8_t storage;
236 uint8_t naux;
237 } coff_symbol_t;
238
239 typedef struct export_directory_entry {
240 uint32_t characteristics;
241 uint32_t time_date_stamp;
242 uint16_t major_version;
243 uint16_t minor_version;
244 uint32_t name;
245 uint32_t base;
246 uint32_t number_of_functions;
247 uint32_t number_of_names;
248 uint32_t address_of_functions;
249 uint32_t address_of_names;
250 uint32_t address_of_name_ordinals;
251 } export_directory_entry;
252
253 static bool ParseDOSHeader(lldb_private::DataExtractor &data,
254 dos_header_t &dos_header);
255 static bool ParseCOFFHeader(lldb_private::DataExtractor &data,
256 lldb::offset_t *offset_ptr,
257 coff_header_t &coff_header);
258 bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
259 bool ParseSectionHeaders(uint32_t offset);
260
Aaron Smith037ed1b2018-12-06 21:36:39 +0000261 uint32_t ParseDependentModules();
262
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263 static void DumpDOSHeader(lldb_private::Stream *s,
264 const dos_header_t &header);
265 static void DumpCOFFHeader(lldb_private::Stream *s,
266 const coff_header_t &header);
267 static void DumpOptCOFFHeader(lldb_private::Stream *s,
268 const coff_opt_header_t &header);
269 void DumpSectionHeaders(lldb_private::Stream *s);
270 void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh);
Aaron Smith037ed1b2018-12-06 21:36:39 +0000271 void DumpDependentModules(lldb_private::Stream *s);
272
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273 bool GetSectionName(std::string &sect_name, const section_header_t &sect);
274
275 typedef std::vector<section_header_t> SectionHeaderColl;
276 typedef SectionHeaderColl::iterator SectionHeaderCollIter;
277 typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
278
Greg Claytonf754f882011-09-09 20:33:05 +0000279private:
Aaron Smith037ed1b2018-12-06 21:36:39 +0000280 bool CreateBinary();
281
282private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000283 dos_header_t m_dos_header;
284 coff_header_t m_coff_header;
285 coff_opt_header_t m_coff_header_opt;
286 SectionHeaderColl m_sect_headers;
287 lldb::addr_t m_image_base;
288 lldb_private::Address m_entry_point_address;
Aaron Smith037ed1b2018-12-06 21:36:39 +0000289 llvm::Optional<lldb_private::FileSpecList> m_deps_filespec;
290 typedef llvm::object::OwningBinary<llvm::object::Binary> OWNBINType;
291 llvm::Optional<OWNBINType> m_owningbin;
Greg Claytonf754f882011-09-09 20:33:05 +0000292};
293
Eugene Zelenko8157a882015-10-23 16:56:07 +0000294#endif // liblldb_ObjectFilePECOFF_h_