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