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