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/COFF.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 #define IMAGE_DOS_SIGNATURE             0x5A4D      // MZ
29 #define IMAGE_NT_SIGNATURE              0x00004550  // PE00
30 #define OPT_HEADER_MAGIC_PE32           0x010b
31 #define OPT_HEADER_MAGIC_PE32_PLUS      0x020b
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 void
37 ObjectFilePECOFF::Initialize()
38 {
39     PluginManager::RegisterPlugin (GetPluginNameStatic(),
40                                    GetPluginDescriptionStatic(),
41                                    CreateInstance,
42                                    CreateMemoryInstance,
43                                    GetModuleSpecifications);
44 }
45 
46 void
47 ObjectFilePECOFF::Terminate()
48 {
49     PluginManager::UnregisterPlugin (CreateInstance);
50 }
51 
52 
53 lldb_private::ConstString
54 ObjectFilePECOFF::GetPluginNameStatic()
55 {
56     static ConstString g_name("pe-coff");
57     return g_name;
58 }
59 
60 const char *
61 ObjectFilePECOFF::GetPluginDescriptionStatic()
62 {
63     return "Portable Executable and Common Object File Format object file reader (32 and 64 bit)";
64 }
65 
66 
67 ObjectFile *
68 ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp,
69                                   DataBufferSP& data_sp,
70                                   lldb::offset_t data_offset,
71                                   const lldb_private::FileSpec* file,
72                                   lldb::offset_t file_offset,
73                                   lldb::offset_t length)
74 {
75     if (!data_sp)
76     {
77         data_sp = file->MemoryMapFileContents(file_offset, length);
78         data_offset = 0;
79     }
80 
81     if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
82     {
83         // Update the data to contain the entire file if it doesn't already
84         if (data_sp->GetByteSize() < length)
85             data_sp = file->MemoryMapFileContents(file_offset, length);
86         std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length));
87         if (objfile_ap.get() && objfile_ap->ParseHeader())
88             return objfile_ap.release();
89     }
90     return NULL;
91 }
92 
93 ObjectFile *
94 ObjectFilePECOFF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
95                                         lldb::DataBufferSP& data_sp,
96                                         const lldb::ProcessSP &process_sp,
97                                         lldb::addr_t header_addr)
98 {
99     return NULL;
100 }
101 
102 size_t
103 ObjectFilePECOFF::GetModuleSpecifications (const lldb_private::FileSpec& file,
104                                            lldb::DataBufferSP& data_sp,
105                                            lldb::offset_t data_offset,
106                                            lldb::offset_t file_offset,
107                                            lldb::offset_t length,
108                                            lldb_private::ModuleSpecList &specs)
109 {
110     return 0;
111 }
112 
113 
114 bool
115 ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp)
116 {
117     DataExtractor data(data_sp, eByteOrderLittle, 4);
118     lldb::offset_t offset = 0;
119     uint16_t magic = data.GetU16 (&offset);
120     return magic == IMAGE_DOS_SIGNATURE;
121 }
122 
123 
124 ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
125                                     DataBufferSP& data_sp,
126                                     lldb::offset_t data_offset,
127                                     const FileSpec* file,
128                                     lldb::offset_t file_offset,
129                                     lldb::offset_t length) :
130     ObjectFile (module_sp, file, file_offset, length, data_sp, data_offset),
131     m_dos_header (),
132     m_coff_header (),
133     m_coff_header_opt (),
134     m_sect_headers ()
135 {
136     ::memset (&m_dos_header, 0, sizeof(m_dos_header));
137     ::memset (&m_coff_header, 0, sizeof(m_coff_header));
138     ::memset (&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
139 }
140 
141 
142 ObjectFilePECOFF::~ObjectFilePECOFF()
143 {
144 }
145 
146 
147 bool
148 ObjectFilePECOFF::ParseHeader ()
149 {
150     ModuleSP module_sp(GetModule());
151     if (module_sp)
152     {
153         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
154         m_sect_headers.clear();
155         m_data.SetByteOrder (eByteOrderLittle);
156         lldb::offset_t offset = 0;
157 
158         if (ParseDOSHeader())
159         {
160             offset = m_dos_header.e_lfanew;
161             uint32_t pe_signature = m_data.GetU32 (&offset);
162             if (pe_signature != IMAGE_NT_SIGNATURE)
163                 return false;
164             if (ParseCOFFHeader(&offset))
165             {
166                 if (m_coff_header.hdrsize > 0)
167                     ParseCOFFOptionalHeader(&offset);
168                 ParseSectionHeaders (offset);
169             }
170             return true;
171         }
172     }
173     return false;
174 }
175 
176 
177 ByteOrder
178 ObjectFilePECOFF::GetByteOrder () const
179 {
180     return eByteOrderLittle;
181 }
182 
183 bool
184 ObjectFilePECOFF::IsExecutable() const
185 {
186     return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0;
187 }
188 
189 uint32_t
190 ObjectFilePECOFF::GetAddressByteSize () const
191 {
192     if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
193         return 8;
194     else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
195         return 4;
196     return 4;
197 }
198 
199 //----------------------------------------------------------------------
200 // NeedsEndianSwap
201 //
202 // Return true if an endian swap needs to occur when extracting data
203 // from this file.
204 //----------------------------------------------------------------------
205 bool
206 ObjectFilePECOFF::NeedsEndianSwap() const
207 {
208 #if defined(__LITTLE_ENDIAN__)
209     return false;
210 #else
211     return true;
212 #endif
213 }
214 //----------------------------------------------------------------------
215 // ParseDOSHeader
216 //----------------------------------------------------------------------
217 bool
218 ObjectFilePECOFF::ParseDOSHeader ()
219 {
220     bool success = false;
221     lldb::offset_t offset = 0;
222     success = m_data.ValidOffsetForDataOfSize(0, sizeof(m_dos_header));
223 
224     if (success)
225     {
226         m_dos_header.e_magic = m_data.GetU16(&offset); // Magic number
227         success = m_dos_header.e_magic == IMAGE_DOS_SIGNATURE;
228 
229         if (success)
230         {
231             m_dos_header.e_cblp     = m_data.GetU16(&offset); // Bytes on last page of file
232             m_dos_header.e_cp       = m_data.GetU16(&offset); // Pages in file
233             m_dos_header.e_crlc     = m_data.GetU16(&offset); // Relocations
234             m_dos_header.e_cparhdr  = m_data.GetU16(&offset); // Size of header in paragraphs
235             m_dos_header.e_minalloc = m_data.GetU16(&offset); // Minimum extra paragraphs needed
236             m_dos_header.e_maxalloc = m_data.GetU16(&offset); // Maximum extra paragraphs needed
237             m_dos_header.e_ss       = m_data.GetU16(&offset); // Initial (relative) SS value
238             m_dos_header.e_sp       = m_data.GetU16(&offset); // Initial SP value
239             m_dos_header.e_csum     = m_data.GetU16(&offset); // Checksum
240             m_dos_header.e_ip       = m_data.GetU16(&offset); // Initial IP value
241             m_dos_header.e_cs       = m_data.GetU16(&offset); // Initial (relative) CS value
242             m_dos_header.e_lfarlc   = m_data.GetU16(&offset); // File address of relocation table
243             m_dos_header.e_ovno     = m_data.GetU16(&offset); // Overlay number
244 
245             m_dos_header.e_res[0]   = m_data.GetU16(&offset); // Reserved words
246             m_dos_header.e_res[1]   = m_data.GetU16(&offset); // Reserved words
247             m_dos_header.e_res[2]   = m_data.GetU16(&offset); // Reserved words
248             m_dos_header.e_res[3]   = m_data.GetU16(&offset); // Reserved words
249 
250             m_dos_header.e_oemid    = m_data.GetU16(&offset); // OEM identifier (for e_oeminfo)
251             m_dos_header.e_oeminfo  = m_data.GetU16(&offset); // OEM information; e_oemid specific
252             m_dos_header.e_res2[0]  = m_data.GetU16(&offset); // Reserved words
253             m_dos_header.e_res2[1]  = m_data.GetU16(&offset); // Reserved words
254             m_dos_header.e_res2[2]  = m_data.GetU16(&offset); // Reserved words
255             m_dos_header.e_res2[3]  = m_data.GetU16(&offset); // Reserved words
256             m_dos_header.e_res2[4]  = m_data.GetU16(&offset); // Reserved words
257             m_dos_header.e_res2[5]  = m_data.GetU16(&offset); // Reserved words
258             m_dos_header.e_res2[6]  = m_data.GetU16(&offset); // Reserved words
259             m_dos_header.e_res2[7]  = m_data.GetU16(&offset); // Reserved words
260             m_dos_header.e_res2[8]  = m_data.GetU16(&offset); // Reserved words
261             m_dos_header.e_res2[9]  = m_data.GetU16(&offset); // Reserved words
262 
263             m_dos_header.e_lfanew   = m_data.GetU32(&offset); // File address of new exe header
264         }
265     }
266     if (!success)
267         memset(&m_dos_header, 0, sizeof(m_dos_header));
268     return success;
269 }
270 
271 
272 //----------------------------------------------------------------------
273 // ParserCOFFHeader
274 //----------------------------------------------------------------------
275 bool
276 ObjectFilePECOFF::ParseCOFFHeader(lldb::offset_t *offset_ptr)
277 {
278     bool success = m_data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(m_coff_header));
279     if (success)
280     {
281         m_coff_header.machine   = m_data.GetU16(offset_ptr);
282         m_coff_header.nsects    = m_data.GetU16(offset_ptr);
283         m_coff_header.modtime   = m_data.GetU32(offset_ptr);
284         m_coff_header.symoff    = m_data.GetU32(offset_ptr);
285         m_coff_header.nsyms     = m_data.GetU32(offset_ptr);
286         m_coff_header.hdrsize   = m_data.GetU16(offset_ptr);
287         m_coff_header.flags     = m_data.GetU16(offset_ptr);
288     }
289     if (!success)
290         memset(&m_coff_header, 0, sizeof(m_coff_header));
291     return success;
292 }
293 
294 bool
295 ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr)
296 {
297     bool success = false;
298     const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
299     if (*offset_ptr < end_offset)
300     {
301         success = true;
302         m_coff_header_opt.magic                         = m_data.GetU16(offset_ptr);
303         m_coff_header_opt.major_linker_version          = m_data.GetU8 (offset_ptr);
304         m_coff_header_opt.minor_linker_version          = m_data.GetU8 (offset_ptr);
305         m_coff_header_opt.code_size                     = m_data.GetU32(offset_ptr);
306         m_coff_header_opt.data_size                     = m_data.GetU32(offset_ptr);
307         m_coff_header_opt.bss_size                      = m_data.GetU32(offset_ptr);
308         m_coff_header_opt.entry                         = m_data.GetU32(offset_ptr);
309         m_coff_header_opt.code_offset                   = m_data.GetU32(offset_ptr);
310 
311         const uint32_t addr_byte_size = GetAddressByteSize ();
312 
313         if (*offset_ptr < end_offset)
314         {
315             if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
316             {
317                 // PE32 only
318                 m_coff_header_opt.data_offset               = m_data.GetU32(offset_ptr);
319             }
320             else
321                 m_coff_header_opt.data_offset = 0;
322 
323             if (*offset_ptr < end_offset)
324             {
325                 m_coff_header_opt.image_base                    = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
326                 m_coff_header_opt.sect_alignment                = m_data.GetU32(offset_ptr);
327                 m_coff_header_opt.file_alignment                = m_data.GetU32(offset_ptr);
328                 m_coff_header_opt.major_os_system_version       = m_data.GetU16(offset_ptr);
329                 m_coff_header_opt.minor_os_system_version       = m_data.GetU16(offset_ptr);
330                 m_coff_header_opt.major_image_version           = m_data.GetU16(offset_ptr);
331                 m_coff_header_opt.minor_image_version           = m_data.GetU16(offset_ptr);
332                 m_coff_header_opt.major_subsystem_version       = m_data.GetU16(offset_ptr);
333                 m_coff_header_opt.minor_subsystem_version       = m_data.GetU16(offset_ptr);
334                 m_coff_header_opt.reserved1                     = m_data.GetU32(offset_ptr);
335                 m_coff_header_opt.image_size                    = m_data.GetU32(offset_ptr);
336                 m_coff_header_opt.header_size                   = m_data.GetU32(offset_ptr);
337                 m_coff_header_opt.checksum                      = m_data.GetU32(offset_ptr);
338                 m_coff_header_opt.subsystem                     = m_data.GetU16(offset_ptr);
339                 m_coff_header_opt.dll_flags                     = m_data.GetU16(offset_ptr);
340                 m_coff_header_opt.stack_reserve_size            = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
341                 m_coff_header_opt.stack_commit_size             = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
342                 m_coff_header_opt.heap_reserve_size             = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
343                 m_coff_header_opt.heap_commit_size              = m_data.GetMaxU64 (offset_ptr, addr_byte_size);
344                 m_coff_header_opt.loader_flags                  = m_data.GetU32(offset_ptr);
345                 uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr);
346                 m_coff_header_opt.data_dirs.clear();
347                 m_coff_header_opt.data_dirs.resize(num_data_dir_entries);
348                 uint32_t i;
349                 for (i=0; i<num_data_dir_entries; i++)
350                 {
351                     m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr);
352                     m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr);
353                 }
354             }
355         }
356     }
357     // Make sure we are on track for section data which follows
358     *offset_ptr = end_offset;
359     return success;
360 }
361 
362 
363 //----------------------------------------------------------------------
364 // ParseSectionHeaders
365 //----------------------------------------------------------------------
366 bool
367 ObjectFilePECOFF::ParseSectionHeaders (uint32_t section_header_data_offset)
368 {
369     const uint32_t nsects = m_coff_header.nsects;
370     m_sect_headers.clear();
371 
372     if (nsects > 0)
373     {
374         const uint32_t addr_byte_size = GetAddressByteSize ();
375         const size_t section_header_byte_size = nsects * sizeof(section_header_t);
376         DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size));
377         DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size);
378 
379         lldb::offset_t offset = 0;
380         if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size))
381         {
382             m_sect_headers.resize(nsects);
383 
384             for (uint32_t idx = 0; idx<nsects; ++idx)
385             {
386                 const void *name_data = section_header_data.GetData(&offset, 8);
387                 if (name_data)
388                 {
389                     memcpy(m_sect_headers[idx].name, name_data, 8);
390                     m_sect_headers[idx].vmsize  = section_header_data.GetU32(&offset);
391                     m_sect_headers[idx].vmaddr  = section_header_data.GetU32(&offset);
392                     m_sect_headers[idx].size    = section_header_data.GetU32(&offset);
393                     m_sect_headers[idx].offset  = section_header_data.GetU32(&offset);
394                     m_sect_headers[idx].reloff  = section_header_data.GetU32(&offset);
395                     m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset);
396                     m_sect_headers[idx].nreloc  = section_header_data.GetU16(&offset);
397                     m_sect_headers[idx].nline   = section_header_data.GetU16(&offset);
398                     m_sect_headers[idx].flags   = section_header_data.GetU32(&offset);
399                 }
400             }
401         }
402     }
403 
404     return m_sect_headers.empty() == false;
405 }
406 
407 bool
408 ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t& sect)
409 {
410     if (sect.name[0] == '/')
411     {
412         lldb::offset_t stroff = strtoul(&sect.name[1], NULL, 10);
413         lldb::offset_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
414         const char *name = m_data.GetCStr (&string_file_offset);
415         if (name)
416         {
417             sect_name = name;
418             return true;
419         }
420 
421         return false;
422     }
423     sect_name = sect.name;
424     return true;
425 }
426 
427 //----------------------------------------------------------------------
428 // GetNListSymtab
429 //----------------------------------------------------------------------
430 Symtab *
431 ObjectFilePECOFF::GetSymtab()
432 {
433     ModuleSP module_sp(GetModule());
434     if (module_sp)
435     {
436         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
437         if (m_symtab_ap.get() == NULL)
438         {
439             SectionList *sect_list = GetSectionList();
440             m_symtab_ap.reset(new Symtab(this));
441             Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
442 
443             const uint32_t num_syms = m_coff_header.nsyms;
444 
445             if (num_syms > 0 && m_coff_header.symoff > 0)
446             {
447                 const uint32_t symbol_size = 18;
448                 const uint32_t addr_byte_size = GetAddressByteSize ();
449                 const size_t symbol_data_size = num_syms * symbol_size;
450                 // Include the 4 bytes string table size at the end of the symbols
451                 DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4));
452                 DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size);
453                 lldb::offset_t offset = symbol_data_size;
454                 const uint32_t strtab_size = symtab_data.GetU32 (&offset);
455                 DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size, strtab_size));
456                 DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size);
457 
458                 // First 4 bytes should be zeroed after strtab_size has been read,
459                 // because it is used as offset 0 to encode a NULL string.
460                 uint32_t* strtab_data_start = (uint32_t*)strtab_data_sp->GetBytes();
461                 strtab_data_start[0] = 0;
462 
463                 offset = 0;
464                 std::string symbol_name;
465                 Symbol *symbols = m_symtab_ap->Resize (num_syms);
466                 for (uint32_t i=0; i<num_syms; ++i)
467                 {
468                     coff_symbol_t symbol;
469                     const uint32_t symbol_offset = offset;
470                     const char *symbol_name_cstr = NULL;
471                     // If the first 4 bytes of the symbol string are zero, then we
472                     // it is followed by a 4 byte string table offset. Else these
473                     // 8 bytes contain the symbol name
474                     if (symtab_data.GetU32 (&offset) == 0)
475                     {
476                         // Long string that doesn't fit into the symbol table name,
477                         // so now we must read the 4 byte string table offset
478                         uint32_t strtab_offset = symtab_data.GetU32 (&offset);
479                         symbol_name_cstr = strtab_data.PeekCStr (strtab_offset);
480                         symbol_name.assign (symbol_name_cstr);
481                     }
482                     else
483                     {
484                         // Short string that fits into the symbol table name which is 8 bytes
485                         offset += sizeof(symbol.name) - 4; // Skip remaining
486                         symbol_name_cstr = symtab_data.PeekCStr (symbol_offset);
487                         if (symbol_name_cstr == NULL)
488                             break;
489                         symbol_name.assign (symbol_name_cstr, sizeof(symbol.name));
490                     }
491                     symbol.value    = symtab_data.GetU32 (&offset);
492                     symbol.sect     = symtab_data.GetU16 (&offset);
493                     symbol.type     = symtab_data.GetU16 (&offset);
494                     symbol.storage  = symtab_data.GetU8  (&offset);
495                     symbol.naux     = symtab_data.GetU8  (&offset);
496                     symbols[i].GetMangled ().SetValue (ConstString(symbol_name.c_str()));
497                     if ((int16_t)symbol.sect >= 1)
498                     {
499                         Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value);
500                         symbols[i].GetAddress() = symbol_addr;
501                     }
502 
503                     if (symbol.naux > 0)
504                     {
505                         i += symbol.naux;
506                         offset += symbol_size;
507                     }
508                 }
509 
510             }
511 
512             // Read export header
513             if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size()
514                 && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0)
515             {
516                 export_directory_entry export_table;
517                 uint32_t data_start = m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
518                 Address address(m_coff_header_opt.image_base + data_start, sect_list);
519                 DataBufferSP symtab_data_sp(m_file.ReadFileContents(address.GetSection()->GetFileOffset() + address.GetOffset(), m_coff_header_opt.data_dirs[0].vmsize));
520                 DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), GetAddressByteSize());
521                 lldb::offset_t offset = 0;
522 
523                 // Read export_table header
524                 export_table.characteristics = symtab_data.GetU32(&offset);
525                 export_table.time_date_stamp = symtab_data.GetU32(&offset);
526                 export_table.major_version = symtab_data.GetU16(&offset);
527                 export_table.minor_version = symtab_data.GetU16(&offset);
528                 export_table.name = symtab_data.GetU32(&offset);
529                 export_table.base = symtab_data.GetU32(&offset);
530                 export_table.number_of_functions = symtab_data.GetU32(&offset);
531                 export_table.number_of_names = symtab_data.GetU32(&offset);
532                 export_table.address_of_functions = symtab_data.GetU32(&offset);
533                 export_table.address_of_names = symtab_data.GetU32(&offset);
534                 export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
535 
536                 bool has_ordinal = export_table.address_of_name_ordinals != 0;
537 
538                 lldb::offset_t name_offset = export_table.address_of_names - data_start;
539                 lldb::offset_t name_ordinal_offset = export_table.address_of_name_ordinals - data_start;
540 
541                 Symbol *symbols = m_symtab_ap->Resize(export_table.number_of_names);
542 
543                 std::string symbol_name;
544 
545                 // Read each export table entry
546                 for (size_t i = 0; i < export_table.number_of_names; ++i)
547                 {
548                     uint32_t name_ordinal = has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
549                     uint32_t name_address = symtab_data.GetU32(&name_offset);
550 
551                     const char* symbol_name_cstr = symtab_data.PeekCStr(name_address - data_start);
552                     symbol_name.assign(symbol_name_cstr);
553 
554                     lldb::offset_t function_offset = export_table.address_of_functions - data_start + sizeof(uint32_t) * name_ordinal;
555                     uint32_t function_rva = symtab_data.GetU32(&function_offset);
556 
557                     Address symbol_addr(m_coff_header_opt.image_base + function_rva, sect_list);
558                     symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
559                     symbols[i].GetAddress() = symbol_addr;
560                     symbols[i].SetType(lldb::eSymbolTypeCode);
561                     symbols[i].SetDebug(true);
562                 }
563             }
564         }
565     }
566     return m_symtab_ap.get();
567 
568 }
569 
570 bool
571 ObjectFilePECOFF::IsStripped ()
572 {
573     // TODO: determine this for COFF
574     return false;
575 }
576 
577 
578 
579 void
580 ObjectFilePECOFF::CreateSections (SectionList &unified_section_list)
581 {
582     if (!m_sections_ap.get())
583     {
584         m_sections_ap.reset(new SectionList());
585 
586         ModuleSP module_sp(GetModule());
587         if (module_sp)
588         {
589             lldb_private::Mutex::Locker locker(module_sp->GetMutex());
590             const uint32_t nsects = m_sect_headers.size();
591             ModuleSP module_sp (GetModule());
592             for (uint32_t idx = 0; idx<nsects; ++idx)
593             {
594                 std::string sect_name;
595                 GetSectionName (sect_name, m_sect_headers[idx]);
596                 ConstString const_sect_name (sect_name.c_str());
597                 static ConstString g_code_sect_name (".code");
598                 static ConstString g_CODE_sect_name ("CODE");
599                 static ConstString g_data_sect_name (".data");
600                 static ConstString g_DATA_sect_name ("DATA");
601                 static ConstString g_bss_sect_name (".bss");
602                 static ConstString g_BSS_sect_name ("BSS");
603                 static ConstString g_debug_sect_name (".debug");
604                 static ConstString g_reloc_sect_name (".reloc");
605                 static ConstString g_stab_sect_name (".stab");
606                 static ConstString g_stabstr_sect_name (".stabstr");
607                 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
608                 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
609                 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
610                 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
611                 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
612                 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
613                 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
614                 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
615                 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
616                 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
617                 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
618                 static ConstString g_sect_name_eh_frame (".eh_frame");
619                 SectionType section_type = eSectionTypeOther;
620                 if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE &&
621                     ((const_sect_name == g_code_sect_name) || (const_sect_name == g_CODE_sect_name)))
622                 {
623                     section_type = eSectionTypeCode;
624                 }
625                 else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA &&
626                          ((const_sect_name == g_data_sect_name) || (const_sect_name == g_DATA_sect_name)))
627                 {
628                     section_type = eSectionTypeData;
629                 }
630                 else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA &&
631                          ((const_sect_name == g_bss_sect_name) || (const_sect_name == g_BSS_sect_name)))
632                 {
633                     if (m_sect_headers[idx].size == 0)
634                         section_type = eSectionTypeZeroFill;
635                     else
636                         section_type = eSectionTypeData;
637                 }
638                 else if (const_sect_name == g_debug_sect_name)
639                 {
640                     section_type = eSectionTypeDebug;
641                 }
642                 else if (const_sect_name == g_stabstr_sect_name)
643                 {
644                     section_type = eSectionTypeDataCString;
645                 }
646                 else if (const_sect_name == g_reloc_sect_name)
647                 {
648                     section_type = eSectionTypeOther;
649                 }
650                 else if (const_sect_name == g_sect_name_dwarf_debug_abbrev)    section_type = eSectionTypeDWARFDebugAbbrev;
651                 else if (const_sect_name == g_sect_name_dwarf_debug_aranges)   section_type = eSectionTypeDWARFDebugAranges;
652                 else if (const_sect_name == g_sect_name_dwarf_debug_frame)     section_type = eSectionTypeDWARFDebugFrame;
653                 else if (const_sect_name == g_sect_name_dwarf_debug_info)      section_type = eSectionTypeDWARFDebugInfo;
654                 else if (const_sect_name == g_sect_name_dwarf_debug_line)      section_type = eSectionTypeDWARFDebugLine;
655                 else if (const_sect_name == g_sect_name_dwarf_debug_loc)       section_type = eSectionTypeDWARFDebugLoc;
656                 else if (const_sect_name == g_sect_name_dwarf_debug_macinfo)   section_type = eSectionTypeDWARFDebugMacInfo;
657                 else if (const_sect_name == g_sect_name_dwarf_debug_pubnames)  section_type = eSectionTypeDWARFDebugPubNames;
658                 else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes)  section_type = eSectionTypeDWARFDebugPubTypes;
659                 else if (const_sect_name == g_sect_name_dwarf_debug_ranges)    section_type = eSectionTypeDWARFDebugRanges;
660                 else if (const_sect_name == g_sect_name_dwarf_debug_str)       section_type = eSectionTypeDWARFDebugStr;
661                 else if (const_sect_name == g_sect_name_eh_frame)              section_type = eSectionTypeEHFrame;
662                 else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE)
663                 {
664                     section_type = eSectionTypeCode;
665                 }
666                 else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
667                 {
668                     section_type = eSectionTypeData;
669                 }
670                 else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
671                 {
672                     if (m_sect_headers[idx].size == 0)
673                         section_type = eSectionTypeZeroFill;
674                     else
675                         section_type = eSectionTypeData;
676                 }
677 
678                 // Use a segment ID of the segment index shifted left by 8 so they
679                 // never conflict with any of the sections.
680                 SectionSP section_sp (new Section (module_sp,                    // Module to which this section belongs
681                                                    this,                         // Object file to which this section belongs
682                                                    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
683                                                    const_sect_name,              // Name of this section
684                                                    section_type,                 // This section is a container of other sections.
685                                                    m_coff_header_opt.image_base + m_sect_headers[idx].vmaddr,   // File VM address == addresses as they are found in the object file
686                                                    m_sect_headers[idx].vmsize,   // VM size in bytes of this section
687                                                    m_sect_headers[idx].offset,   // Offset to the data for this section in the file
688                                                    m_sect_headers[idx].size,     // Size in bytes of this section as found in the the file
689                                                    m_sect_headers[idx].flags));  // Flags for this section
690 
691                 //section_sp->SetIsEncrypted (segment_is_encrypted);
692 
693                 unified_section_list.AddSection(section_sp);
694                 m_sections_ap->AddSection (section_sp);
695             }
696         }
697     }
698 }
699 
700 bool
701 ObjectFilePECOFF::GetUUID (UUID* uuid)
702 {
703     return false;
704 }
705 
706 uint32_t
707 ObjectFilePECOFF::GetDependentModules (FileSpecList& files)
708 {
709     return 0;
710 }
711 
712 
713 //----------------------------------------------------------------------
714 // Dump
715 //
716 // Dump the specifics of the runtime file container (such as any headers
717 // segments, sections, etc).
718 //----------------------------------------------------------------------
719 void
720 ObjectFilePECOFF::Dump(Stream *s)
721 {
722     ModuleSP module_sp(GetModule());
723     if (module_sp)
724     {
725         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
726         s->Printf("%p: ", this);
727         s->Indent();
728         s->PutCString("ObjectFilePECOFF");
729 
730         ArchSpec header_arch;
731         GetArchitecture (header_arch);
732 
733         *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
734 
735         SectionList *sections = GetSectionList();
736         if (sections)
737             sections->Dump(s, NULL, true, UINT32_MAX);
738 
739         if (m_symtab_ap.get())
740             m_symtab_ap->Dump(s, NULL, eSortOrderNone);
741 
742         if (m_dos_header.e_magic)
743             DumpDOSHeader (s, m_dos_header);
744         if (m_coff_header.machine)
745         {
746             DumpCOFFHeader (s, m_coff_header);
747             if (m_coff_header.hdrsize)
748                 DumpOptCOFFHeader (s, m_coff_header_opt);
749         }
750         s->EOL();
751         DumpSectionHeaders(s);
752         s->EOL();
753     }
754 }
755 
756 //----------------------------------------------------------------------
757 // DumpDOSHeader
758 //
759 // Dump the MS-DOS header to the specified output stream
760 //----------------------------------------------------------------------
761 void
762 ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header)
763 {
764     s->PutCString ("MSDOS Header\n");
765     s->Printf ("  e_magic    = 0x%4.4x\n", header.e_magic);
766     s->Printf ("  e_cblp     = 0x%4.4x\n", header.e_cblp);
767     s->Printf ("  e_cp       = 0x%4.4x\n", header.e_cp);
768     s->Printf ("  e_crlc     = 0x%4.4x\n", header.e_crlc);
769     s->Printf ("  e_cparhdr  = 0x%4.4x\n", header.e_cparhdr);
770     s->Printf ("  e_minalloc = 0x%4.4x\n", header.e_minalloc);
771     s->Printf ("  e_maxalloc = 0x%4.4x\n", header.e_maxalloc);
772     s->Printf ("  e_ss       = 0x%4.4x\n", header.e_ss);
773     s->Printf ("  e_sp       = 0x%4.4x\n", header.e_sp);
774     s->Printf ("  e_csum     = 0x%4.4x\n", header.e_csum);
775     s->Printf ("  e_ip       = 0x%4.4x\n", header.e_ip);
776     s->Printf ("  e_cs       = 0x%4.4x\n", header.e_cs);
777     s->Printf ("  e_lfarlc   = 0x%4.4x\n", header.e_lfarlc);
778     s->Printf ("  e_ovno     = 0x%4.4x\n", header.e_ovno);
779     s->Printf ("  e_res[4]   = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
780                header.e_res[0],
781                header.e_res[1],
782                header.e_res[2],
783                header.e_res[3]);
784     s->Printf ("  e_oemid    = 0x%4.4x\n", header.e_oemid);
785     s->Printf ("  e_oeminfo  = 0x%4.4x\n", header.e_oeminfo);
786     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",
787                header.e_res2[0],
788                header.e_res2[1],
789                header.e_res2[2],
790                header.e_res2[3],
791                header.e_res2[4],
792                header.e_res2[5],
793                header.e_res2[6],
794                header.e_res2[7],
795                header.e_res2[8],
796                header.e_res2[9]);
797     s->Printf ("  e_lfanew   = 0x%8.8x\n", header.e_lfanew);
798 }
799 
800 //----------------------------------------------------------------------
801 // DumpCOFFHeader
802 //
803 // Dump the COFF header to the specified output stream
804 //----------------------------------------------------------------------
805 void
806 ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header)
807 {
808     s->PutCString ("COFF Header\n");
809     s->Printf ("  machine = 0x%4.4x\n", header.machine);
810     s->Printf ("  nsects  = 0x%4.4x\n", header.nsects);
811     s->Printf ("  modtime = 0x%8.8x\n", header.modtime);
812     s->Printf ("  symoff  = 0x%8.8x\n", header.symoff);
813     s->Printf ("  nsyms   = 0x%8.8x\n", header.nsyms);
814     s->Printf ("  hdrsize = 0x%4.4x\n", header.hdrsize);
815 }
816 
817 //----------------------------------------------------------------------
818 // DumpOptCOFFHeader
819 //
820 // Dump the optional COFF header to the specified output stream
821 //----------------------------------------------------------------------
822 void
823 ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, const coff_opt_header_t& header)
824 {
825     s->PutCString ("Optional COFF Header\n");
826     s->Printf ("  magic                   = 0x%4.4x\n", header.magic);
827     s->Printf ("  major_linker_version    = 0x%2.2x\n", header.major_linker_version);
828     s->Printf ("  minor_linker_version    = 0x%2.2x\n", header.minor_linker_version);
829     s->Printf ("  code_size               = 0x%8.8x\n", header.code_size);
830     s->Printf ("  data_size               = 0x%8.8x\n", header.data_size);
831     s->Printf ("  bss_size                = 0x%8.8x\n", header.bss_size);
832     s->Printf ("  entry                   = 0x%8.8x\n", header.entry);
833     s->Printf ("  code_offset             = 0x%8.8x\n", header.code_offset);
834     s->Printf ("  data_offset             = 0x%8.8x\n", header.data_offset);
835     s->Printf ("  image_base              = 0x%16.16" PRIx64 "\n", header.image_base);
836     s->Printf ("  sect_alignment          = 0x%8.8x\n", header.sect_alignment);
837     s->Printf ("  file_alignment          = 0x%8.8x\n", header.file_alignment);
838     s->Printf ("  major_os_system_version = 0x%4.4x\n", header.major_os_system_version);
839     s->Printf ("  minor_os_system_version = 0x%4.4x\n", header.minor_os_system_version);
840     s->Printf ("  major_image_version     = 0x%4.4x\n", header.major_image_version);
841     s->Printf ("  minor_image_version     = 0x%4.4x\n", header.minor_image_version);
842     s->Printf ("  major_subsystem_version = 0x%4.4x\n", header.major_subsystem_version);
843     s->Printf ("  minor_subsystem_version = 0x%4.4x\n", header.minor_subsystem_version);
844     s->Printf ("  reserved1               = 0x%8.8x\n", header.reserved1);
845     s->Printf ("  image_size              = 0x%8.8x\n", header.image_size);
846     s->Printf ("  header_size             = 0x%8.8x\n", header.header_size);
847     s->Printf ("  checksum                = 0x%8.8x\n", header.checksum);
848     s->Printf ("  subsystem               = 0x%4.4x\n", header.subsystem);
849     s->Printf ("  dll_flags               = 0x%4.4x\n", header.dll_flags);
850     s->Printf ("  stack_reserve_size      = 0x%16.16" PRIx64 "\n", header.stack_reserve_size);
851     s->Printf ("  stack_commit_size       = 0x%16.16" PRIx64 "\n", header.stack_commit_size);
852     s->Printf ("  heap_reserve_size       = 0x%16.16" PRIx64 "\n", header.heap_reserve_size);
853     s->Printf ("  heap_commit_size        = 0x%16.16" PRIx64 "\n", header.heap_commit_size);
854     s->Printf ("  loader_flags            = 0x%8.8x\n", header.loader_flags);
855     s->Printf ("  num_data_dir_entries    = 0x%8.8zx\n", header.data_dirs.size());
856     uint32_t i;
857     for (i=0; i<header.data_dirs.size(); i++)
858     {
859         s->Printf ("  data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n",
860                    i,
861                    header.data_dirs[i].vmaddr,
862                    header.data_dirs[i].vmsize);
863     }
864 }
865 //----------------------------------------------------------------------
866 // DumpSectionHeader
867 //
868 // Dump a single ELF section header to the specified output stream
869 //----------------------------------------------------------------------
870 void
871 ObjectFilePECOFF::DumpSectionHeader(Stream *s, const section_header_t& sh)
872 {
873     std::string name;
874     GetSectionName(name, sh);
875     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",
876                name.c_str(),
877                sh.vmaddr,
878                sh.vmsize,
879                sh.offset,
880                sh.size,
881                sh.reloff,
882                sh.lineoff,
883                sh.nreloc,
884                sh.nline,
885                sh.flags);
886 }
887 
888 
889 //----------------------------------------------------------------------
890 // DumpSectionHeaders
891 //
892 // Dump all of the ELF section header to the specified output stream
893 //----------------------------------------------------------------------
894 void
895 ObjectFilePECOFF::DumpSectionHeaders(Stream *s)
896 {
897 
898     s->PutCString ("Section Headers\n");
899     s->PutCString ("IDX  name             vm addr    vm size    file off   file size  reloc off  line off   nreloc nline  flags\n");
900     s->PutCString ("==== ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ------ ------ ----------\n");
901 
902     uint32_t idx = 0;
903     SectionHeaderCollIter pos, end = m_sect_headers.end();
904 
905     for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx)
906     {
907         s->Printf ("[%2u] ", idx);
908         ObjectFilePECOFF::DumpSectionHeader(s, *pos);
909     }
910 }
911 
912 bool
913 ObjectFilePECOFF::GetArchitecture (ArchSpec &arch)
914 {
915     uint16_t machine = m_coff_header.machine;
916     switch (machine)
917     {
918         case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
919         case llvm::COFF::IMAGE_FILE_MACHINE_I386:
920         case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC:
921         case llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP:
922         case llvm::COFF::IMAGE_FILE_MACHINE_ARM:
923         case llvm::COFF::IMAGE_FILE_MACHINE_ARMV7:
924         case llvm::COFF::IMAGE_FILE_MACHINE_THUMB:
925             arch.SetArchitecture (eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE);
926             return true;
927         default:
928             break;
929     }
930     return false;
931 }
932 
933 ObjectFile::Type
934 ObjectFilePECOFF::CalculateType()
935 {
936     if (m_coff_header.machine != 0)
937     {
938         if ((m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0)
939             return eTypeExecutable;
940         else
941             return eTypeSharedLibrary;
942     }
943     return eTypeExecutable;
944 }
945 
946 ObjectFile::Strata
947 ObjectFilePECOFF::CalculateStrata()
948 {
949     return eStrataUser;
950 }
951 //------------------------------------------------------------------
952 // PluginInterface protocol
953 //------------------------------------------------------------------
954 ConstString
955 ObjectFilePECOFF::GetPluginName()
956 {
957     return GetPluginNameStatic();
958 }
959 
960 uint32_t
961 ObjectFilePECOFF::GetPluginVersion()
962 {
963     return 1;
964 }
965 
966