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