1 //===-- ObjectFilePECOFF.cpp ------------------------------------*- 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 #include "ObjectFilePECOFF.h"
11 
12 #include "llvm/Support/MachO.h"
13 
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/DataBuffer.h"
16 #include "lldb/Host/FileSpec.h"
17 #include "lldb/Core/FileSpecList.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ModuleSpec.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/Section.h"
22 #include "lldb/Core/StreamFile.h"
23 #include "lldb/Core/StreamString.h"
24 #include "lldb/Core/Timer.h"
25 #include "lldb/Core/UUID.h"
26 #include "lldb/Symbol/ObjectFile.h"
27 
28 static uint32_t COFFMachineToMachCPU(uint16_t machine);
29 
30 #define IMAGE_FILE_MACHINE_UNKNOWN      0x0000
31 #define IMAGE_FILE_MACHINE_AM33         0x01d3  // Matsushita AM33
32 #define IMAGE_FILE_MACHINE_AMD64        0x8664  // x64
33 #define IMAGE_FILE_MACHINE_ARM          0x01c0  // ARM little endian
34 #define IMAGE_FILE_MACHINE_EBC          0x0ebc  // EFI byte code
35 #define IMAGE_FILE_MACHINE_I386         0x014c  // Intel 386 or later processors and compatible processors
36 #define IMAGE_FILE_MACHINE_IA64         0x0200  // Intel Itanium processor family
37 #define IMAGE_FILE_MACHINE_M32R         0x9041  // Mitsubishi M32R little endian
38 #define IMAGE_FILE_MACHINE_MIPS16       0x0266  // MIPS16
39 #define IMAGE_FILE_MACHINE_MIPSFPU      0x0366  // MIPS with FPU
40 #define IMAGE_FILE_MACHINE_MIPSFPU16    0x0466  // MIPS16 with FPU
41 #define IMAGE_FILE_MACHINE_POWERPC      0x01f0  // Power PC little endian
42 #define IMAGE_FILE_MACHINE_POWERPCFP    0x01f1  // Power PC with floating point support
43 #define IMAGE_FILE_MACHINE_R4000        0x0166  // MIPS little endian
44 #define IMAGE_FILE_MACHINE_SH3          0x01a2  // Hitachi SH3
45 #define IMAGE_FILE_MACHINE_SH3DSP       0x01a3  // Hitachi SH3 DSP
46 #define IMAGE_FILE_MACHINE_SH4          0x01a6  // Hitachi SH4
47 #define IMAGE_FILE_MACHINE_SH5          0x01a8  // Hitachi SH5
48 #define IMAGE_FILE_MACHINE_THUMB        0x01c2  // Thumb
49 #define IMAGE_FILE_MACHINE_WCEMIPSV2    0x0169  // MIPS little-endian WCE v2
50 
51 
52 #define IMAGE_DOS_SIGNATURE             0x5A4D      // MZ
53 #define IMAGE_OS2_SIGNATURE             0x454E      // NE
54 #define IMAGE_OS2_SIGNATURE_LE          0x454C      // LE
55 #define IMAGE_NT_SIGNATURE              0x00004550  // PE00
56 #define OPT_HEADER_MAGIC_PE32           0x010b
57 #define OPT_HEADER_MAGIC_PE32_PLUS      0x020b
58 
59 #define IMAGE_FILE_RELOCS_STRIPPED          0x0001
60 #define IMAGE_FILE_EXECUTABLE_IMAGE         0x0002
61 #define IMAGE_FILE_LINE_NUMS_STRIPPED       0x0004
62 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED      0x0008
63 #define IMAGE_FILE_AGGRESSIVE_WS_TRIM       0x0010
64 #define IMAGE_FILE_LARGE_ADDRESS_AWARE      0x0020
65 //#define                                   0x0040  // Reserved
66 #define IMAGE_FILE_BYTES_REVERSED_LO        0x0080
67 #define IMAGE_FILE_32BIT_MACHINE            0x0100
68 #define IMAGE_FILE_DEBUG_STRIPPED           0x0200
69 #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP  0x0400
70 #define IMAGE_FILE_NET_RUN_FROM_SWAP        0x0800
71 #define IMAGE_FILE_SYSTEM                   0x1000
72 #define IMAGE_FILE_DLL                      0x2000
73 #define IMAGE_FILE_UP_SYSTEM_ONLY           0x4000
74 #define IMAGE_FILE_BYTES_REVERSED_HI        0x8000
75 
76 
77 // Section Flags
78 // The section flags in the Characteristics field of the section header indicate
79 // characteristics of the section.
80 #define IMAGE_SCN_TYPE_NO_PAD               0x00000008 // The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
81 #define IMAGE_SCN_CNT_CODE                  0x00000020 // The section contains executable code.
82 #define IMAGE_SCN_CNT_INITIALIZED_DATA      0x00000040 // The section contains initialized data.
83 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA    0x00000080 // The section contains uninitialized data.
84 #define IMAGE_SCN_LNK_OTHER                 0x00000100 // Reserved for future use.
85 #define IMAGE_SCN_LNK_INFO                  0x00000200 // The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
86 #define IMAGE_SCN_LNK_REMOVE                0x00000800 // The section will not become part of the image. This is valid only for object files.
87 #define IMAGE_SCN_LNK_COMDAT                0x00001000 // The section contains COMDAT data. For more information, see section 5.5.6, “COMDAT Sections (Object Only).” This is valid only for object files.
88 #define IMAGE_SCN_GPREL                     0x00008000 // The section contains data referenced through the global pointer (GP).
89 #define IMAGE_SCN_MEM_PURGEABLE             0x00020000
90 #define IMAGE_SCN_MEM_16BIT                 0x00020000 // For ARM machine types, the section contains Thumb code.  Reserved for future use with other machine types.
91 #define IMAGE_SCN_MEM_LOCKED                0x00040000
92 #define IMAGE_SCN_MEM_PRELOAD               0x00080000
93 #define IMAGE_SCN_ALIGN_1BYTES              0x00100000 // Align data on a 1-byte boundary. Valid only for object files.
94 #define IMAGE_SCN_ALIGN_2BYTES              0x00200000 // Align data on a 2-byte boundary. Valid only for object files.
95 #define IMAGE_SCN_ALIGN_4BYTES              0x00300000 // Align data on a 4-byte boundary. Valid only for object files.
96 #define IMAGE_SCN_ALIGN_8BYTES              0x00400000 // Align data on an 8-byte boundary. Valid only for object files.
97 #define IMAGE_SCN_ALIGN_16BYTES             0x00500000 // Align data on a 16-byte boundary. Valid only for object files.
98 #define IMAGE_SCN_ALIGN_32BYTES             0x00600000 // Align data on a 32-byte boundary. Valid only for object files.
99 #define IMAGE_SCN_ALIGN_64BYTES             0x00700000 // Align data on a 64-byte boundary. Valid only for object files.
100 #define IMAGE_SCN_ALIGN_128BYTES            0x00800000 // Align data on a 128-byte boundary. Valid only for object files.
101 #define IMAGE_SCN_ALIGN_256BYTES            0x00900000 // Align data on a 256-byte boundary. Valid only for object files.
102 #define IMAGE_SCN_ALIGN_512BYTES            0x00A00000 // Align data on a 512-byte boundary. Valid only for object files.
103 #define IMAGE_SCN_ALIGN_1024BYTES           0x00B00000 // Align data on a 1024-byte boundary. Valid only for object files.
104 #define IMAGE_SCN_ALIGN_2048BYTES           0x00C00000 // Align data on a 2048-byte boundary. Valid only for object files.
105 #define IMAGE_SCN_ALIGN_4096BYTES           0x00D00000 // Align data on a 4096-byte boundary. Valid only for object files.
106 #define IMAGE_SCN_ALIGN_8192BYTES           0x00E00000 // Align data on an 8192-byte boundary. Valid only for object files.
107 #define IMAGE_SCN_LNK_NRELOC_OVFL           0x01000000 // The section contains extended relocations.
108 #define IMAGE_SCN_MEM_DISCARDABLE           0x02000000 // The section can be discarded as needed.
109 #define IMAGE_SCN_MEM_NOT_CACHED            0x04000000 // The section cannot be cached.
110 #define IMAGE_SCN_MEM_NOT_PAGED             0x08000000 // The section is not pageable.
111 #define IMAGE_SCN_MEM_SHARED                0x10000000 // The section can be shared in memory.
112 #define IMAGE_SCN_MEM_EXECUTE               0x20000000 // The section can be executed as code.
113 #define IMAGE_SCN_MEM_READ                  0x40000000 // The section can be read.
114 #define IMAGE_SCN_MEM_WRITE                 0x80000000 // The section can be written to.
115 
116 using namespace lldb;
117 using namespace lldb_private;
118 
119 void
120 ObjectFilePECOFF::Initialize()
121 {
122     PluginManager::RegisterPlugin (GetPluginNameStatic(),
123                                    GetPluginDescriptionStatic(),
124                                    CreateInstance,
125                                    CreateMemoryInstance,
126                                    GetModuleSpecifications);
127 }
128 
129 void
130 ObjectFilePECOFF::Terminate()
131 {
132     PluginManager::UnregisterPlugin (CreateInstance);
133 }
134 
135 
136 const char *
137 ObjectFilePECOFF::GetPluginNameStatic()
138 {
139     return "object-file.pe-coff";
140 }
141 
142 const char *
143 ObjectFilePECOFF::GetPluginDescriptionStatic()
144 {
145     return "Portable Executable and Common Object File Format object file reader (32 and 64 bit)";
146 }
147 
148 
149 ObjectFile *
150 ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp,
151                                   DataBufferSP& data_sp,
152                                   lldb::offset_t data_offset,
153                                   const lldb_private::FileSpec* file,
154                                   lldb::offset_t file_offset,
155                                   lldb::offset_t length)
156 {
157     if (!data_sp)
158     {
159         data_sp = file->MemoryMapFileContents(file_offset, length);
160         data_offset = 0;
161     }
162 
163     if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
164     {
165         // Update the data to contain the entire file if it doesn't already
166         if (data_sp->GetByteSize() < length)
167             data_sp = file->MemoryMapFileContents(file_offset, length);
168         std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length));
169         if (objfile_ap.get() && objfile_ap->ParseHeader())
170             return objfile_ap.release();
171     }
172     return NULL;
173 }
174 
175 ObjectFile *
176 ObjectFilePECOFF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
177                                         lldb::DataBufferSP& data_sp,
178                                         const lldb::ProcessSP &process_sp,
179                                         lldb::addr_t header_addr)
180 {
181     return NULL;
182 }
183 
184 size_t
185 ObjectFilePECOFF::GetModuleSpecifications (const lldb_private::FileSpec& file,
186                                            lldb::DataBufferSP& data_sp,
187                                            lldb::offset_t data_offset,
188                                            lldb::offset_t file_offset,
189                                            lldb::offset_t length,
190                                            lldb_private::ModuleSpecList &specs)
191 {
192     return 0;
193 }
194 
195 
196 bool
197 ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp)
198 {
199     DataExtractor data(data_sp, eByteOrderLittle, 4);
200     lldb::offset_t offset = 0;
201     uint16_t magic = data.GetU16 (&offset);
202     return magic == IMAGE_DOS_SIGNATURE;
203 }
204 
205 
206 ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
207                                     DataBufferSP& data_sp,
208                                     lldb::offset_t data_offset,
209                                     const FileSpec* file,
210                                     lldb::offset_t file_offset,
211                                     lldb::offset_t length) :
212     ObjectFile (module_sp, file, file_offset, length, data_sp, data_offset),
213     m_dos_header (),
214     m_coff_header (),
215     m_coff_header_opt (),
216     m_sect_headers ()
217 {
218     ::memset (&m_dos_header, 0, sizeof(m_dos_header));
219     ::memset (&m_coff_header, 0, sizeof(m_coff_header));
220     ::memset (&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
221 }
222 
223 
224 ObjectFilePECOFF::~ObjectFilePECOFF()
225 {
226 }
227 
228 
229 bool
230 ObjectFilePECOFF::ParseHeader ()
231 {
232     ModuleSP module_sp(GetModule());
233     if (module_sp)
234     {
235         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
236         m_sect_headers.clear();
237         m_data.SetByteOrder (eByteOrderLittle);
238         lldb::offset_t offset = 0;
239 
240         if (ParseDOSHeader())
241         {
242             offset = m_dos_header.e_lfanew;
243             uint32_t pe_signature = m_data.GetU32 (&offset);
244             if (pe_signature != IMAGE_NT_SIGNATURE)
245                 return false;
246             if (ParseCOFFHeader(&offset))
247             {
248                 if (m_coff_header.hdrsize > 0)
249                     ParseCOFFOptionalHeader(&offset);
250                 ParseSectionHeaders (offset);
251             }
252             return true;
253         }
254     }
255     return false;
256 }
257 
258 
259 ByteOrder
260 ObjectFilePECOFF::GetByteOrder () const
261 {
262     return eByteOrderLittle;
263 }
264 
265 bool
266 ObjectFilePECOFF::IsExecutable() const
267 {
268     return (m_coff_header.flags & IMAGE_FILE_DLL) == 0;
269 }
270 
271 uint32_t
272 ObjectFilePECOFF::GetAddressByteSize () const
273 {
274     if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
275         return 8;
276     else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
277         return 4;
278     return 4;
279 }
280 
281 //----------------------------------------------------------------------
282 // NeedsEndianSwap
283 //
284 // Return true if an endian swap needs to occur when extracting data
285 // from this file.
286 //----------------------------------------------------------------------
287 bool
288 ObjectFilePECOFF::NeedsEndianSwap() const
289 {
290 #if defined(__LITTLE_ENDIAN__)
291     return false;
292 #else
293     return true;
294 #endif
295 }
296 //----------------------------------------------------------------------
297 // ParseDOSHeader
298 //----------------------------------------------------------------------
299 bool
300 ObjectFilePECOFF::ParseDOSHeader ()
301 {
302     bool success = false;
303     lldb::offset_t offset = 0;
304     success = m_data.ValidOffsetForDataOfSize(0, sizeof(m_dos_header));
305 
306     if (success)
307     {
308         m_dos_header.e_magic = m_data.GetU16(&offset); // Magic number
309         success = m_dos_header.e_magic == IMAGE_DOS_SIGNATURE;
310 
311         if (success)
312         {
313             m_dos_header.e_cblp     = m_data.GetU16(&offset); // Bytes on last page of file
314             m_dos_header.e_cp       = m_data.GetU16(&offset); // Pages in file
315             m_dos_header.e_crlc     = m_data.GetU16(&offset); // Relocations
316             m_dos_header.e_cparhdr  = m_data.GetU16(&offset); // Size of header in paragraphs
317             m_dos_header.e_minalloc = m_data.GetU16(&offset); // Minimum extra paragraphs needed
318             m_dos_header.e_maxalloc = m_data.GetU16(&offset); // Maximum extra paragraphs needed
319             m_dos_header.e_ss       = m_data.GetU16(&offset); // Initial (relative) SS value
320             m_dos_header.e_sp       = m_data.GetU16(&offset); // Initial SP value
321             m_dos_header.e_csum     = m_data.GetU16(&offset); // Checksum
322             m_dos_header.e_ip       = m_data.GetU16(&offset); // Initial IP value
323             m_dos_header.e_cs       = m_data.GetU16(&offset); // Initial (relative) CS value
324             m_dos_header.e_lfarlc   = m_data.GetU16(&offset); // File address of relocation table
325             m_dos_header.e_ovno     = m_data.GetU16(&offset); // Overlay number
326 
327             m_dos_header.e_res[0]   = m_data.GetU16(&offset); // Reserved words
328             m_dos_header.e_res[1]   = m_data.GetU16(&offset); // Reserved words
329             m_dos_header.e_res[2]   = m_data.GetU16(&offset); // Reserved words
330             m_dos_header.e_res[3]   = m_data.GetU16(&offset); // Reserved words
331 
332             m_dos_header.e_oemid    = m_data.GetU16(&offset); // OEM identifier (for e_oeminfo)
333             m_dos_header.e_oeminfo  = m_data.GetU16(&offset); // OEM information; e_oemid specific
334             m_dos_header.e_res2[0]  = m_data.GetU16(&offset); // Reserved words
335             m_dos_header.e_res2[1]  = m_data.GetU16(&offset); // Reserved words
336             m_dos_header.e_res2[2]  = m_data.GetU16(&offset); // Reserved words
337             m_dos_header.e_res2[3]  = m_data.GetU16(&offset); // Reserved words
338             m_dos_header.e_res2[4]  = m_data.GetU16(&offset); // Reserved words
339             m_dos_header.e_res2[5]  = m_data.GetU16(&offset); // Reserved words
340             m_dos_header.e_res2[6]  = m_data.GetU16(&offset); // Reserved words
341             m_dos_header.e_res2[7]  = m_data.GetU16(&offset); // Reserved words
342             m_dos_header.e_res2[8]  = m_data.GetU16(&offset); // Reserved words
343             m_dos_header.e_res2[9]  = m_data.GetU16(&offset); // Reserved words
344 
345             m_dos_header.e_lfanew   = m_data.GetU32(&offset); // File address of new exe header
346         }
347     }
348     if (!success)
349         memset(&m_dos_header, 0, sizeof(m_dos_header));
350     return success;
351 }
352 
353 
354 //----------------------------------------------------------------------
355 // ParserCOFFHeader
356 //----------------------------------------------------------------------
357 bool
358 ObjectFilePECOFF::ParseCOFFHeader(lldb::offset_t *offset_ptr)
359 {
360     bool success = m_data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(m_coff_header));
361     if (success)
362     {
363         m_coff_header.machine   = m_data.GetU16(offset_ptr);
364         m_coff_header.nsects    = m_data.GetU16(offset_ptr);
365         m_coff_header.modtime   = m_data.GetU32(offset_ptr);
366         m_coff_header.symoff    = m_data.GetU32(offset_ptr);
367         m_coff_header.nsyms     = m_data.GetU32(offset_ptr);
368         m_coff_header.hdrsize   = m_data.GetU16(offset_ptr);
369         m_coff_header.flags     = m_data.GetU16(offset_ptr);
370     }
371     if (!success)
372         memset(&m_coff_header, 0, sizeof(m_coff_header));
373     return success;
374 }
375 
376 bool
377 ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr)
378 {
379     bool success = false;
380     const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
381     if (*offset_ptr < end_offset)
382     {
383         success = true;
384         m_coff_header_opt.magic                         = m_data.GetU16(offset_ptr);
385         m_coff_header_opt.major_linker_version          = m_data.GetU8 (offset_ptr);
386         m_coff_header_opt.minor_linker_version          = m_data.GetU8 (offset_ptr);
387         m_coff_header_opt.code_size                     = m_data.GetU32(offset_ptr);
388         m_coff_header_opt.data_size                     = m_data.GetU32(offset_ptr);
389         m_coff_header_opt.bss_size                      = m_data.GetU32(offset_ptr);
390         m_coff_header_opt.entry                         = m_data.GetU32(offset_ptr);
391         m_coff_header_opt.code_offset                   = m_data.GetU32(offset_ptr);
392 
393         const uint32_t addr_byte_size = GetAddressByteSize ();
394 
395         if (*offset_ptr < end_offset)
396         {
397             if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
398             {
399                 // PE32 only
400                 m_coff_header_opt.data_offset               = m_data.GetU32(offset_ptr);
401             }
402             else
403                 m_coff_header_opt.data_offset = 0;
404 
405             if (*offset_ptr < end_offset)
406             {
407                 m_coff_header_opt.image_base                    = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
408                 m_coff_header_opt.sect_alignment                = m_data.GetU32(offset_ptr);
409                 m_coff_header_opt.file_alignment                = m_data.GetU32(offset_ptr);
410                 m_coff_header_opt.major_os_system_version       = m_data.GetU16(offset_ptr);
411                 m_coff_header_opt.minor_os_system_version       = m_data.GetU16(offset_ptr);
412                 m_coff_header_opt.major_image_version           = m_data.GetU16(offset_ptr);
413                 m_coff_header_opt.minor_image_version           = m_data.GetU16(offset_ptr);
414                 m_coff_header_opt.major_subsystem_version       = m_data.GetU16(offset_ptr);
415                 m_coff_header_opt.minor_subsystem_version       = m_data.GetU16(offset_ptr);
416                 m_coff_header_opt.reserved1                     = m_data.GetU32(offset_ptr);
417                 m_coff_header_opt.image_size                    = m_data.GetU32(offset_ptr);
418                 m_coff_header_opt.header_size                   = m_data.GetU32(offset_ptr);
419                 m_coff_header_opt.checksum                      = m_data.GetU32(offset_ptr);
420                 m_coff_header_opt.subsystem                     = m_data.GetU16(offset_ptr);
421                 m_coff_header_opt.dll_flags                     = m_data.GetU16(offset_ptr);
422                 m_coff_header_opt.stack_reserve_size            = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
423                 m_coff_header_opt.stack_commit_size             = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
424                 m_coff_header_opt.heap_reserve_size             = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
425                 m_coff_header_opt.heap_commit_size              = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
426                 m_coff_header_opt.loader_flags                  = m_data.GetU32(offset_ptr);
427                 uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr);
428                 m_coff_header_opt.data_dirs.clear();
429                 m_coff_header_opt.data_dirs.resize(num_data_dir_entries);
430                 uint32_t i;
431                 for (i=0; i<num_data_dir_entries; i++)
432                 {
433                     m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr);
434                     m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr);
435                 }
436             }
437         }
438     }
439     // Make sure we are on track for section data which follows
440     *offset_ptr = end_offset;
441     return success;
442 }
443 
444 
445 //----------------------------------------------------------------------
446 // ParseSectionHeaders
447 //----------------------------------------------------------------------
448 bool
449 ObjectFilePECOFF::ParseSectionHeaders (uint32_t section_header_data_offset)
450 {
451     const uint32_t nsects = m_coff_header.nsects;
452     m_sect_headers.clear();
453 
454     if (nsects > 0)
455     {
456         const uint32_t addr_byte_size = GetAddressByteSize ();
457         const size_t section_header_byte_size = nsects * sizeof(section_header_t);
458         DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size));
459         DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size);
460 
461         lldb::offset_t offset = 0;
462         if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size))
463         {
464             m_sect_headers.resize(nsects);
465 
466             for (uint32_t idx = 0; idx<nsects; ++idx)
467             {
468                 const void *name_data = section_header_data.GetData(&offset, 8);
469                 if (name_data)
470                 {
471                     memcpy(m_sect_headers[idx].name, name_data, 8);
472                     m_sect_headers[idx].vmsize  = section_header_data.GetU32(&offset);
473                     m_sect_headers[idx].vmaddr  = section_header_data.GetU32(&offset);
474                     m_sect_headers[idx].size    = section_header_data.GetU32(&offset);
475                     m_sect_headers[idx].offset  = section_header_data.GetU32(&offset);
476                     m_sect_headers[idx].reloff  = section_header_data.GetU32(&offset);
477                     m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset);
478                     m_sect_headers[idx].nreloc  = section_header_data.GetU16(&offset);
479                     m_sect_headers[idx].nline   = section_header_data.GetU16(&offset);
480                     m_sect_headers[idx].flags   = section_header_data.GetU32(&offset);
481                 }
482             }
483         }
484     }
485 
486     return m_sect_headers.empty() == false;
487 }
488 
489 bool
490 ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t& sect)
491 {
492     if (sect.name[0] == '/')
493     {
494         lldb::offset_t stroff = strtoul(&sect.name[1], NULL, 10);
495         lldb::offset_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
496         const char *name = m_data.GetCStr (&string_file_offset);
497         if (name)
498         {
499             sect_name = name;
500             return true;
501         }
502 
503         return false;
504     }
505     sect_name = sect.name;
506     return true;
507 }
508 
509 //----------------------------------------------------------------------
510 // GetNListSymtab
511 //----------------------------------------------------------------------
512 Symtab *
513 ObjectFilePECOFF::GetSymtab()
514 {
515     ModuleSP module_sp(GetModule());
516     if (module_sp)
517     {
518         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
519         if (m_symtab_ap.get() == NULL)
520         {
521             SectionList *sect_list = GetSectionList();
522             m_symtab_ap.reset(new Symtab(this));
523             Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
524 
525             const uint32_t num_syms = m_coff_header.nsyms;
526 
527             if (num_syms > 0 && m_coff_header.symoff > 0)
528             {
529                 const uint32_t symbol_size = sizeof(section_header_t);
530                 const uint32_t addr_byte_size = GetAddressByteSize ();
531                 const size_t symbol_data_size = num_syms * symbol_size;
532                 // Include the 4 bytes string table size at the end of the symbols
533                 DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4));
534                 DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size);
535                 lldb::offset_t offset = symbol_data_size;
536                 const uint32_t strtab_size = symtab_data.GetU32 (&offset);
537                 DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size + 4, strtab_size));
538                 DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size);
539 
540                 offset = 0;
541                 std::string symbol_name;
542                 Symbol *symbols = m_symtab_ap->Resize (num_syms);
543                 for (uint32_t i=0; i<num_syms; ++i)
544                 {
545                     coff_symbol_t symbol;
546                     const uint32_t symbol_offset = offset;
547                     const char *symbol_name_cstr = NULL;
548                     // If the first 4 bytes of the symbol string are zero, then we
549                     // it is followed by a 4 byte string table offset. Else these
550                     // 8 bytes contain the symbol name
551                     if (symtab_data.GetU32 (&offset) == 0)
552                     {
553                         // Long string that doesn't fit into the symbol table name,
554                         // so now we must read the 4 byte string table offset
555                         uint32_t strtab_offset = symtab_data.GetU32 (&offset);
556                         symbol_name_cstr = strtab_data.PeekCStr (strtab_offset);
557                         symbol_name.assign (symbol_name_cstr);
558                     }
559                     else
560                     {
561                         // Short string that fits into the symbol table name which is 8 bytes
562                         offset += sizeof(symbol.name) - 4; // Skip remaining
563                         symbol_name_cstr = symtab_data.PeekCStr (symbol_offset);
564                         if (symbol_name_cstr == NULL)
565                             break;
566                         symbol_name.assign (symbol_name_cstr, sizeof(symbol.name));
567                     }
568                     symbol.value    = symtab_data.GetU32 (&offset);
569                     symbol.sect     = symtab_data.GetU16 (&offset);
570                     symbol.type     = symtab_data.GetU16 (&offset);
571                     symbol.storage  = symtab_data.GetU8  (&offset);
572                     symbol.naux     = symtab_data.GetU8  (&offset);
573                     Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value);
574                     symbols[i].GetMangled ().SetValue (ConstString(symbol_name.c_str()));
575                     symbols[i].GetAddress() = symbol_addr;
576 
577                     if (symbol.naux > 0)
578                         i += symbol.naux;
579                 }
580 
581             }
582         }
583     }
584     return m_symtab_ap.get();
585 
586 }
587 
588 SectionList *
589 ObjectFilePECOFF::GetSectionList()
590 {
591     ModuleSP module_sp(GetModule());
592     if (module_sp)
593     {
594         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
595         if (m_sections_ap.get() == NULL)
596         {
597             m_sections_ap.reset(new SectionList());
598             const uint32_t nsects = m_sect_headers.size();
599             ModuleSP module_sp (GetModule());
600             for (uint32_t idx = 0; idx<nsects; ++idx)
601             {
602                 std::string sect_name;
603                 GetSectionName (sect_name, m_sect_headers[idx]);
604                 ConstString const_sect_name (sect_name.c_str());
605                 static ConstString g_code_sect_name (".code");
606                 static ConstString g_CODE_sect_name ("CODE");
607                 static ConstString g_data_sect_name (".data");
608                 static ConstString g_DATA_sect_name ("DATA");
609                 static ConstString g_bss_sect_name (".bss");
610                 static ConstString g_BSS_sect_name ("BSS");
611                 static ConstString g_debug_sect_name (".debug");
612                 static ConstString g_reloc_sect_name (".reloc");
613                 static ConstString g_stab_sect_name (".stab");
614                 static ConstString g_stabstr_sect_name (".stabstr");
615                 SectionType section_type = eSectionTypeOther;
616                 if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE &&
617                     ((const_sect_name == g_code_sect_name) || (const_sect_name == g_CODE_sect_name)))
618                 {
619                     section_type = eSectionTypeCode;
620                 }
621                 else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA &&
622                          ((const_sect_name == g_data_sect_name) || (const_sect_name == g_DATA_sect_name)))
623                 {
624                     section_type = eSectionTypeData;
625                 }
626                 else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA &&
627                          ((const_sect_name == g_bss_sect_name) || (const_sect_name == g_BSS_sect_name)))
628                 {
629                     if (m_sect_headers[idx].size == 0)
630                         section_type = eSectionTypeZeroFill;
631                     else
632                         section_type = eSectionTypeData;
633                 }
634                 else if (const_sect_name == g_debug_sect_name)
635                 {
636                     section_type = eSectionTypeDebug;
637                 }
638                 else if (const_sect_name == g_stabstr_sect_name)
639                 {
640                     section_type = eSectionTypeDataCString;
641                 }
642                 else if (const_sect_name == g_reloc_sect_name)
643                 {
644                     section_type = eSectionTypeOther;
645                 }
646                 else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE)
647                 {
648                     section_type = eSectionTypeCode;
649                 }
650                 else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA)
651                 {
652                     section_type = eSectionTypeData;
653                 }
654                 else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
655                 {
656                     if (m_sect_headers[idx].size == 0)
657                         section_type = eSectionTypeZeroFill;
658                     else
659                         section_type = eSectionTypeData;
660                 }
661 
662                 // Use a segment ID of the segment index shifted left by 8 so they
663                 // never conflict with any of the sections.
664                 SectionSP section_sp (new Section (module_sp,                    // Module to which this section belongs
665                                                    idx + 1,                      // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
666                                                    const_sect_name,              // Name of this section
667                                                    section_type,                    // This section is a container of other sections.
668                                                    m_sect_headers[idx].vmaddr,   // File VM address == addresses as they are found in the object file
669                                                    m_sect_headers[idx].vmsize,   // VM size in bytes of this section
670                                                    m_sect_headers[idx].offset,   // Offset to the data for this section in the file
671                                                    m_sect_headers[idx].size,     // Size in bytes of this section as found in the the file
672                                                    m_sect_headers[idx].flags));  // Flags for this section
673 
674                 //section_sp->SetIsEncrypted (segment_is_encrypted);
675 
676                 m_sections_ap->AddSection(section_sp);
677             }
678 
679             m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
680         }
681     }
682     return m_sections_ap.get();
683 }
684 
685 bool
686 ObjectFilePECOFF::GetUUID (UUID* uuid)
687 {
688     return false;
689 }
690 
691 uint32_t
692 ObjectFilePECOFF::GetDependentModules (FileSpecList& files)
693 {
694     return 0;
695 }
696 
697 
698 //----------------------------------------------------------------------
699 // Dump
700 //
701 // Dump the specifics of the runtime file container (such as any headers
702 // segments, sections, etc).
703 //----------------------------------------------------------------------
704 void
705 ObjectFilePECOFF::Dump(Stream *s)
706 {
707     ModuleSP module_sp(GetModule());
708     if (module_sp)
709     {
710         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
711         s->Printf("%p: ", this);
712         s->Indent();
713         s->PutCString("ObjectFilePECOFF");
714 
715         ArchSpec header_arch;
716         GetArchitecture (header_arch);
717 
718         *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
719 
720         if (m_sections_ap.get())
721             m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
722 
723         if (m_symtab_ap.get())
724             m_symtab_ap->Dump(s, NULL, eSortOrderNone);
725 
726         if (m_dos_header.e_magic)
727             DumpDOSHeader (s, m_dos_header);
728         if (m_coff_header.machine)
729         {
730             DumpCOFFHeader (s, m_coff_header);
731             if (m_coff_header.hdrsize)
732                 DumpOptCOFFHeader (s, m_coff_header_opt);
733         }
734         s->EOL();
735         DumpSectionHeaders(s);
736         s->EOL();
737     }
738 }
739 
740 //----------------------------------------------------------------------
741 // DumpDOSHeader
742 //
743 // Dump the MS-DOS header to the specified output stream
744 //----------------------------------------------------------------------
745 void
746 ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header)
747 {
748     s->PutCString ("MSDOS Header\n");
749     s->Printf ("  e_magic    = 0x%4.4x\n", header.e_magic);
750     s->Printf ("  e_cblp     = 0x%4.4x\n", header.e_cblp);
751     s->Printf ("  e_cp       = 0x%4.4x\n", header.e_cp);
752     s->Printf ("  e_crlc     = 0x%4.4x\n", header.e_crlc);
753     s->Printf ("  e_cparhdr  = 0x%4.4x\n", header.e_cparhdr);
754     s->Printf ("  e_minalloc = 0x%4.4x\n", header.e_minalloc);
755     s->Printf ("  e_maxalloc = 0x%4.4x\n", header.e_maxalloc);
756     s->Printf ("  e_ss       = 0x%4.4x\n", header.e_ss);
757     s->Printf ("  e_sp       = 0x%4.4x\n", header.e_sp);
758     s->Printf ("  e_csum     = 0x%4.4x\n", header.e_csum);
759     s->Printf ("  e_ip       = 0x%4.4x\n", header.e_ip);
760     s->Printf ("  e_cs       = 0x%4.4x\n", header.e_cs);
761     s->Printf ("  e_lfarlc   = 0x%4.4x\n", header.e_lfarlc);
762     s->Printf ("  e_ovno     = 0x%4.4x\n", header.e_ovno);
763     s->Printf ("  e_res[4]   = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
764                header.e_res[0],
765                header.e_res[1],
766                header.e_res[2],
767                header.e_res[3]);
768     s->Printf ("  e_oemid    = 0x%4.4x\n", header.e_oemid);
769     s->Printf ("  e_oeminfo  = 0x%4.4x\n", header.e_oeminfo);
770     s->Printf ("  e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
771                header.e_res2[0],
772                header.e_res2[1],
773                header.e_res2[2],
774                header.e_res2[3],
775                header.e_res2[4],
776                header.e_res2[5],
777                header.e_res2[6],
778                header.e_res2[7],
779                header.e_res2[8],
780                header.e_res2[9]);
781     s->Printf ("  e_lfanew   = 0x%8.8x\n", header.e_lfanew);
782 }
783 
784 //----------------------------------------------------------------------
785 // DumpCOFFHeader
786 //
787 // Dump the COFF header to the specified output stream
788 //----------------------------------------------------------------------
789 void
790 ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header)
791 {
792     s->PutCString ("COFF Header\n");
793     s->Printf ("  machine = 0x%4.4x\n", header.machine);
794     s->Printf ("  nsects  = 0x%4.4x\n", header.nsects);
795     s->Printf ("  modtime = 0x%8.8x\n", header.modtime);
796     s->Printf ("  symoff  = 0x%8.8x\n", header.symoff);
797     s->Printf ("  nsyms   = 0x%8.8x\n", header.nsyms);
798     s->Printf ("  hdrsize = 0x%4.4x\n", header.hdrsize);
799 }
800 
801 //----------------------------------------------------------------------
802 // DumpOptCOFFHeader
803 //
804 // Dump the optional COFF header to the specified output stream
805 //----------------------------------------------------------------------
806 void
807 ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, const coff_opt_header_t& header)
808 {
809     s->PutCString ("Optional COFF Header\n");
810     s->Printf ("  magic                   = 0x%4.4x\n", header.magic);
811     s->Printf ("  major_linker_version    = 0x%2.2x\n", header.major_linker_version);
812     s->Printf ("  minor_linker_version    = 0x%2.2x\n", header.minor_linker_version);
813     s->Printf ("  code_size               = 0x%8.8x\n", header.code_size);
814     s->Printf ("  data_size               = 0x%8.8x\n", header.data_size);
815     s->Printf ("  bss_size                = 0x%8.8x\n", header.bss_size);
816     s->Printf ("  entry                   = 0x%8.8x\n", header.entry);
817     s->Printf ("  code_offset             = 0x%8.8x\n", header.code_offset);
818     s->Printf ("  data_offset             = 0x%8.8x\n", header.data_offset);
819     s->Printf ("  image_base              = 0x%16.16" PRIx64 "\n", header.image_base);
820     s->Printf ("  sect_alignment          = 0x%8.8x\n", header.sect_alignment);
821     s->Printf ("  file_alignment          = 0x%8.8x\n", header.file_alignment);
822     s->Printf ("  major_os_system_version = 0x%4.4x\n", header.major_os_system_version);
823     s->Printf ("  minor_os_system_version = 0x%4.4x\n", header.minor_os_system_version);
824     s->Printf ("  major_image_version     = 0x%4.4x\n", header.major_image_version);
825     s->Printf ("  minor_image_version     = 0x%4.4x\n", header.minor_image_version);
826     s->Printf ("  major_subsystem_version = 0x%4.4x\n", header.major_subsystem_version);
827     s->Printf ("  minor_subsystem_version = 0x%4.4x\n", header.minor_subsystem_version);
828     s->Printf ("  reserved1               = 0x%8.8x\n", header.reserved1);
829     s->Printf ("  image_size              = 0x%8.8x\n", header.image_size);
830     s->Printf ("  header_size             = 0x%8.8x\n", header.header_size);
831     s->Printf ("  checksum                = 0x%8.8x\n", header.checksum);
832     s->Printf ("  subsystem               = 0x%4.4x\n", header.subsystem);
833     s->Printf ("  dll_flags               = 0x%4.4x\n", header.dll_flags);
834     s->Printf ("  stack_reserve_size      = 0x%16.16" PRIx64 "\n", header.stack_reserve_size);
835     s->Printf ("  stack_commit_size       = 0x%16.16" PRIx64 "\n", header.stack_commit_size);
836     s->Printf ("  heap_reserve_size       = 0x%16.16" PRIx64 "\n", header.heap_reserve_size);
837     s->Printf ("  heap_commit_size        = 0x%16.16" PRIx64 "\n", header.heap_commit_size);
838     s->Printf ("  loader_flags            = 0x%8.8x\n", header.loader_flags);
839     s->Printf ("  num_data_dir_entries    = 0x%8.8zx\n", header.data_dirs.size());
840     uint32_t i;
841     for (i=0; i<header.data_dirs.size(); i++)
842     {
843         s->Printf ("  data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n",
844                    i,
845                    header.data_dirs[i].vmaddr,
846                    header.data_dirs[i].vmsize);
847     }
848 }
849 //----------------------------------------------------------------------
850 // DumpSectionHeader
851 //
852 // Dump a single ELF section header to the specified output stream
853 //----------------------------------------------------------------------
854 void
855 ObjectFilePECOFF::DumpSectionHeader(Stream *s, const section_header_t& sh)
856 {
857     std::string name;
858     GetSectionName(name, sh);
859     s->Printf ("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x 0x%4.4x 0x%8.8x\n",
860                name.c_str(),
861                sh.vmaddr,
862                sh.vmsize,
863                sh.offset,
864                sh.size,
865                sh.reloff,
866                sh.lineoff,
867                sh.nreloc,
868                sh.nline,
869                sh.flags);
870 }
871 
872 
873 //----------------------------------------------------------------------
874 // DumpSectionHeaders
875 //
876 // Dump all of the ELF section header to the specified output stream
877 //----------------------------------------------------------------------
878 void
879 ObjectFilePECOFF::DumpSectionHeaders(Stream *s)
880 {
881 
882     s->PutCString ("Section Headers\n");
883     s->PutCString ("IDX  name             vm addr    vm size    file off   file size  reloc off  line off   nreloc nline  flags\n");
884     s->PutCString ("==== ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ------ ------ ----------\n");
885 
886     uint32_t idx = 0;
887     SectionHeaderCollIter pos, end = m_sect_headers.end();
888 
889     for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx)
890     {
891         s->Printf ("[%2u] ", idx);
892         ObjectFilePECOFF::DumpSectionHeader(s, *pos);
893     }
894 }
895 
896 static bool
897 COFFMachineToMachCPU (uint16_t machine, ArchSpec &arch)
898 {
899     switch (machine)
900     {
901         case IMAGE_FILE_MACHINE_AMD64:
902         case IMAGE_FILE_MACHINE_IA64:
903             arch.SetArchitecture (eArchTypeMachO,
904                                   llvm::MachO::CPUTypeX86_64,
905                                   llvm::MachO::CPUSubType_X86_64_ALL);
906             return true;
907 
908         case IMAGE_FILE_MACHINE_I386:
909             arch.SetArchitecture (eArchTypeMachO,
910                                   llvm::MachO::CPUTypeI386,
911                                   llvm::MachO::CPUSubType_I386_ALL);
912             return true;
913 
914         case IMAGE_FILE_MACHINE_POWERPC:
915         case IMAGE_FILE_MACHINE_POWERPCFP:
916             arch.SetArchitecture (eArchTypeMachO,
917                                   llvm::MachO::CPUTypePowerPC,
918                                   llvm::MachO::CPUSubType_POWERPC_ALL);
919             return true;
920         case IMAGE_FILE_MACHINE_ARM:
921         case IMAGE_FILE_MACHINE_THUMB:
922             arch.SetArchitecture (eArchTypeMachO,
923                                   llvm::MachO::CPUTypeARM,
924                                   llvm::MachO::CPUSubType_ARM_V7);
925             return true;
926     }
927     return false;
928 }
929 bool
930 ObjectFilePECOFF::GetArchitecture (ArchSpec &arch)
931 {
932     // For index zero return our cpu type
933     return COFFMachineToMachCPU (m_coff_header.machine, arch);
934 }
935 
936 ObjectFile::Type
937 ObjectFilePECOFF::CalculateType()
938 {
939     if (m_coff_header.machine != 0)
940     {
941         if ((m_coff_header.flags & IMAGE_FILE_DLL) == 0)
942             return eTypeExecutable;
943         else
944             return eTypeSharedLibrary;
945     }
946     return eTypeExecutable;
947 }
948 
949 ObjectFile::Strata
950 ObjectFilePECOFF::CalculateStrata()
951 {
952     return eStrataUser;
953 }
954 //------------------------------------------------------------------
955 // PluginInterface protocol
956 //------------------------------------------------------------------
957 const char *
958 ObjectFilePECOFF::GetPluginName()
959 {
960     return "ObjectFilePECOFF";
961 }
962 
963 const char *
964 ObjectFilePECOFF::GetShortPluginName()
965 {
966     return GetPluginNameStatic();
967 }
968 
969 uint32_t
970 ObjectFilePECOFF::GetPluginVersion()
971 {
972     return 1;
973 }
974 
975