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