aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
blob: 44e5ee1b044b629a89859b4b53e55ef95c1e31f1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
//===-- ObjectFilePECOFF.h --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ObjectFilePECOFF_h_
#define liblldb_ObjectFilePECOFF_h_

// C Includes
// C++ Includes
#include <vector>

// Other libraries and framework includes
// Project includes
#include "lldb/Symbol/ObjectFile.h"

class ObjectFilePECOFF : 
    public lldb_private::ObjectFile
{
public:
    typedef enum MachineType
    {
        MachineUnknown = 0x0,
        MachineAm33 = 0x1d3,
        MachineAmd64 = 0x8664,
        MachineArm = 0x1c0,
        MachineArmNt = 0x1c4,
        MachineArm64 = 0xaa64,
        MachineEbc = 0xebc,
        MachineX86 = 0x14c,
        MachineIA64 = 0x200,
        MachineM32R = 0x9041,
        MachineMips16 = 0x266,
        MachineMipsFpu = 0x366,
        MachineMipsFpu16 = 0x466,
        MachinePowerPc = 0x1f0,
        MachinePowerPcfp = 0x1f1,
        MachineR4000 = 0x166,
        MachineSh3 = 0x1a2,
        MachineSh3dsp = 0x1a3,
        MachineSh4 = 0x1a6,
        MachineSh5 = 0x1a8,
        MachineThumb = 0x1c2,
        MachineWcemIpsv2 = 0x169
    } MachineType;
    
    ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
                     lldb::DataBufferSP& data_sp,
                     lldb::offset_t data_offset,
                     const lldb_private::FileSpec* file,
                     lldb::offset_t file_offset,
                     lldb::offset_t length);

    ~ObjectFilePECOFF() override;

    //------------------------------------------------------------------
    // Static Functions
    //------------------------------------------------------------------
    static void
    Initialize();
    
    static void
    Terminate();
    
    static lldb_private::ConstString
    GetPluginNameStatic();
    
    static const char *
    GetPluginDescriptionStatic();
    
    static ObjectFile *
    CreateInstance (const lldb::ModuleSP &module_sp,
                    lldb::DataBufferSP& data_sp,
                    lldb::offset_t data_offset,
                    const lldb_private::FileSpec* file,
                    lldb::offset_t offset,
                    lldb::offset_t length);
    
    static lldb_private::ObjectFile *
    CreateMemoryInstance (const lldb::ModuleSP &module_sp, 
                          lldb::DataBufferSP& data_sp, 
                          const lldb::ProcessSP &process_sp, 
                          lldb::addr_t header_addr);
    
    static size_t
    GetModuleSpecifications (const lldb_private::FileSpec& file,
                             lldb::DataBufferSP& data_sp,
                             lldb::offset_t data_offset,
                             lldb::offset_t file_offset,
                             lldb::offset_t length,
                             lldb_private::ModuleSpecList &specs);

    static bool
    SaveCore (const lldb::ProcessSP &process_sp,
              const lldb_private::FileSpec &outfile,
              lldb_private::Error &error);

    static bool
    MagicBytesMatch (lldb::DataBufferSP& data_sp);

    static lldb::SymbolType
    MapSymbolType(uint16_t coff_symbol_type);

    bool
    ParseHeader() override;
    
    bool
    SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override;

    lldb::ByteOrder
    GetByteOrder() const override;
    
    bool
    IsExecutable() const override;
    
    uint32_t
    GetAddressByteSize() const override;

//    virtual lldb_private::AddressClass
//    GetAddressClass (lldb::addr_t file_addr);

    lldb_private::Symtab *
    GetSymtab() override;
    
    bool
    IsStripped() override;

    void
    CreateSections(lldb_private::SectionList &unified_section_list) override;
    
    void
    Dump(lldb_private::Stream *s) override;
    
    bool
    GetArchitecture(lldb_private::ArchSpec &arch) override;
    
    bool
    GetUUID(lldb_private::UUID* uuid) override;
    
    uint32_t
    GetDependentModules(lldb_private::FileSpecList& files) override;
    
//    virtual lldb_private::Address
//    GetEntryPointAddress ();
    
    ObjectFile::Type
    CalculateType() override;
    
    ObjectFile::Strata
    CalculateStrata() override;
    
    //------------------------------------------------------------------
    // PluginInterface protocol
    //------------------------------------------------------------------
    lldb_private::ConstString
    GetPluginName() override;
    
    uint32_t
    GetPluginVersion() override;

protected:
	bool NeedsEndianSwap() const;    
    
	typedef struct dos_header  {  // DOS .EXE header
		uint16_t e_magic;         // Magic number
		uint16_t e_cblp;          // Bytes on last page of file
		uint16_t e_cp;            // Pages in file
		uint16_t e_crlc;          // Relocations
		uint16_t e_cparhdr;       // Size of header in paragraphs
		uint16_t e_minalloc;      // Minimum extra paragraphs needed
		uint16_t e_maxalloc;      // Maximum extra paragraphs needed
		uint16_t e_ss;            // Initial (relative) SS value
		uint16_t e_sp;            // Initial SP value
		uint16_t e_csum;          // Checksum
		uint16_t e_ip;            // Initial IP value
		uint16_t e_cs;            // Initial (relative) CS value
		uint16_t e_lfarlc;        // File address of relocation table
		uint16_t e_ovno;          // Overlay number
		uint16_t e_res[4];        // Reserved words
		uint16_t e_oemid;         // OEM identifier (for e_oeminfo)
		uint16_t e_oeminfo;       // OEM information; e_oemid specific
		uint16_t e_res2[10];      // Reserved words
		uint32_t e_lfanew;        // File address of new exe header
    } dos_header_t;
    
	typedef struct coff_header {
		uint16_t machine;
		uint16_t nsects;
		uint32_t modtime;
		uint32_t symoff;
		uint32_t nsyms;
		uint16_t hdrsize;
		uint16_t flags;
	} coff_header_t;
    
	typedef struct data_directory {
		uint32_t vmaddr;
		uint32_t vmsize;
	} data_directory_t;
    
	typedef struct coff_opt_header 
	{
		uint16_t	magic;
		uint8_t		major_linker_version;
		uint8_t		minor_linker_version;
		uint32_t	code_size;
		uint32_t	data_size;
		uint32_t	bss_size;
		uint32_t	entry;
		uint32_t	code_offset;
		uint32_t	data_offset;
        
		uint64_t	image_base;
		uint32_t	sect_alignment;
		uint32_t	file_alignment;
		uint16_t	major_os_system_version;
		uint16_t	minor_os_system_version;
		uint16_t	major_image_version;
		uint16_t	minor_image_version;
		uint16_t	major_subsystem_version;
		uint16_t	minor_subsystem_version;
		uint32_t	reserved1;
		uint32_t	image_size;
		uint32_t	header_size;
		uint32_t	checksum;
		uint16_t	subsystem;
		uint16_t	dll_flags;
		uint64_t	stack_reserve_size;
		uint64_t	stack_commit_size;
		uint64_t	heap_reserve_size;
		uint64_t	heap_commit_size;
		uint32_t	loader_flags;
        //    uint32_t	num_data_dir_entries;
		std::vector<data_directory> data_dirs;	// will contain num_data_dir_entries entries
	} coff_opt_header_t;

    typedef enum coff_data_dir_type
    {
        coff_data_dir_export_table = 0,
        coff_data_dir_import_table = 1,
    } coff_data_dir_type;
    
	typedef struct section_header {
		char		name[8];
		uint32_t	vmsize;	// Virtual Size
		uint32_t	vmaddr;	// Virtual Addr
		uint32_t	size;	// File size
		uint32_t	offset;	// File offset
		uint32_t	reloff;	// Offset to relocations
		uint32_t	lineoff;// Offset to line table entries
		uint16_t	nreloc;	// Number of relocation entries
		uint16_t	nline;	// Number of line table entries
		uint32_t	flags;
	} section_header_t;
    
	typedef struct coff_symbol {
		char		name[8];
		uint32_t	value;
		uint16_t	sect;
		uint16_t	type;
		uint8_t		storage;
		uint8_t		naux;		
	} coff_symbol_t;

    typedef struct export_directory_entry {
        uint32_t   characteristics;
        uint32_t   time_date_stamp;
        uint16_t   major_version;
        uint16_t   minor_version;
        uint32_t   name;
        uint32_t   base;
        uint32_t   number_of_functions;
        uint32_t   number_of_names;
        uint32_t   address_of_functions;
        uint32_t   address_of_names;
        uint32_t   address_of_name_ordinals;
    } export_directory_entry;
    
	static bool ParseDOSHeader (lldb_private::DataExtractor &data, dos_header_t &dos_header);
	static bool ParseCOFFHeader (lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr, coff_header_t &coff_header);
	bool ParseCOFFOptionalHeader (lldb::offset_t *offset_ptr);
	bool ParseSectionHeaders (uint32_t offset);
	
	static	void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t& header);
	static	void DumpCOFFHeader(lldb_private::Stream *s, const coff_header_t& header);
	static	void DumpOptCOFFHeader(lldb_private::Stream *s, const coff_opt_header_t& header);
    void DumpSectionHeaders(lldb_private::Stream *s);
    void DumpSectionHeader(lldb_private::Stream *s, const section_header_t& sh);
    bool GetSectionName(std::string& sect_name, const section_header_t& sect);
    
	typedef std::vector<section_header_t>		SectionHeaderColl;
	typedef SectionHeaderColl::iterator			SectionHeaderCollIter;
	typedef SectionHeaderColl::const_iterator	SectionHeaderCollConstIter;
private:
	dos_header_t		m_dos_header;
	coff_header_t		m_coff_header;
	coff_opt_header_t	m_coff_header_opt;
	SectionHeaderColl	m_sect_headers;
    lldb::addr_t		m_image_base;
};

#endif // liblldb_ObjectFilePECOFF_h_