1*f754f88fSGreg Clayton //===-- ObjectFilePECOFF.cpp ------------------------------------*- C++ -*-===// 2*f754f88fSGreg Clayton // 3*f754f88fSGreg Clayton // The LLVM Compiler Infrastructure 4*f754f88fSGreg Clayton // 5*f754f88fSGreg Clayton // This file is distributed under the University of Illinois Open Source 6*f754f88fSGreg Clayton // License. See LICENSE.TXT for details. 7*f754f88fSGreg Clayton // 8*f754f88fSGreg Clayton //===----------------------------------------------------------------------===// 9*f754f88fSGreg Clayton 10*f754f88fSGreg Clayton #include "ObjectFilePECOFF.h" 11*f754f88fSGreg Clayton 12*f754f88fSGreg Clayton #include "llvm/Support/MachO.h" 13*f754f88fSGreg Clayton 14*f754f88fSGreg Clayton #include "lldb/Core/ArchSpec.h" 15*f754f88fSGreg Clayton #include "lldb/Core/DataBuffer.h" 16*f754f88fSGreg Clayton #include "lldb/Host/FileSpec.h" 17*f754f88fSGreg Clayton #include "lldb/Core/FileSpecList.h" 18*f754f88fSGreg Clayton #include "lldb/Core/Module.h" 19*f754f88fSGreg Clayton #include "lldb/Core/PluginManager.h" 20*f754f88fSGreg Clayton #include "lldb/Core/Section.h" 21*f754f88fSGreg Clayton #include "lldb/Core/StreamFile.h" 22*f754f88fSGreg Clayton #include "lldb/Core/StreamString.h" 23*f754f88fSGreg Clayton #include "lldb/Core/Timer.h" 24*f754f88fSGreg Clayton #include "lldb/Core/UUID.h" 25*f754f88fSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 26*f754f88fSGreg Clayton 27*f754f88fSGreg Clayton static uint32_t COFFMachineToMachCPU(uint16_t machine); 28*f754f88fSGreg Clayton 29*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_UNKNOWN 0x0000 30*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_AM33 0x01d3 // Matsushita AM33 31*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_AMD64 0x8664 // x64 32*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM little endian 33*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_EBC 0x0ebc // EFI byte code 34*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386 or later processors and compatible processors 35*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel Itanium processor family 36*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_M32R 0x9041 // Mitsubishi M32R little endian 37*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS16 38*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS with FPU 39*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS16 with FPU 40*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_POWERPC 0x01f0 // Power PC little endian 41*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 // Power PC with floating point support 42*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little endian 43*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_SH3 0x01a2 // Hitachi SH3 44*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 // Hitachi SH3 DSP 45*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_SH4 0x01a6 // Hitachi SH4 46*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_SH5 0x01a8 // Hitachi SH5 47*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_THUMB 0x01c2 // Thumb 48*f754f88fSGreg Clayton #define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2 49*f754f88fSGreg Clayton 50*f754f88fSGreg Clayton 51*f754f88fSGreg Clayton #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ 52*f754f88fSGreg Clayton #define IMAGE_OS2_SIGNATURE 0x454E // NE 53*f754f88fSGreg Clayton #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE 54*f754f88fSGreg Clayton #define IMAGE_NT_SIGNATURE 0x00004550 // PE00 55*f754f88fSGreg Clayton #define OPT_HEADER_MAGIC_PE32 0x010b 56*f754f88fSGreg Clayton #define OPT_HEADER_MAGIC_PE32_PLUS 0x020b 57*f754f88fSGreg Clayton 58*f754f88fSGreg Clayton #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 59*f754f88fSGreg Clayton #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 60*f754f88fSGreg Clayton #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 61*f754f88fSGreg Clayton #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 62*f754f88fSGreg Clayton #define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010 63*f754f88fSGreg Clayton #define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 64*f754f88fSGreg Clayton //#define 0x0040 // Reserved 65*f754f88fSGreg Clayton #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 66*f754f88fSGreg Clayton #define IMAGE_FILE_32BIT_MACHINE 0x0100 67*f754f88fSGreg Clayton #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 68*f754f88fSGreg Clayton #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 69*f754f88fSGreg Clayton #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 70*f754f88fSGreg Clayton #define IMAGE_FILE_SYSTEM 0x1000 71*f754f88fSGreg Clayton #define IMAGE_FILE_DLL 0x2000 72*f754f88fSGreg Clayton #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 73*f754f88fSGreg Clayton #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 74*f754f88fSGreg Clayton 75*f754f88fSGreg Clayton using namespace lldb; 76*f754f88fSGreg Clayton using namespace lldb_private; 77*f754f88fSGreg Clayton 78*f754f88fSGreg Clayton void 79*f754f88fSGreg Clayton ObjectFilePECOFF::Initialize() 80*f754f88fSGreg Clayton { 81*f754f88fSGreg Clayton PluginManager::RegisterPlugin (GetPluginNameStatic(), 82*f754f88fSGreg Clayton GetPluginDescriptionStatic(), 83*f754f88fSGreg Clayton CreateInstance); 84*f754f88fSGreg Clayton } 85*f754f88fSGreg Clayton 86*f754f88fSGreg Clayton void 87*f754f88fSGreg Clayton ObjectFilePECOFF::Terminate() 88*f754f88fSGreg Clayton { 89*f754f88fSGreg Clayton PluginManager::UnregisterPlugin (CreateInstance); 90*f754f88fSGreg Clayton } 91*f754f88fSGreg Clayton 92*f754f88fSGreg Clayton 93*f754f88fSGreg Clayton const char * 94*f754f88fSGreg Clayton ObjectFilePECOFF::GetPluginNameStatic() 95*f754f88fSGreg Clayton { 96*f754f88fSGreg Clayton return "object-file.pe-coff"; 97*f754f88fSGreg Clayton } 98*f754f88fSGreg Clayton 99*f754f88fSGreg Clayton const char * 100*f754f88fSGreg Clayton ObjectFilePECOFF::GetPluginDescriptionStatic() 101*f754f88fSGreg Clayton { 102*f754f88fSGreg Clayton return "Portable Executable and Common Object File Format object file reader (32 and 64 bit)"; 103*f754f88fSGreg Clayton } 104*f754f88fSGreg Clayton 105*f754f88fSGreg Clayton 106*f754f88fSGreg Clayton ObjectFile * 107*f754f88fSGreg Clayton ObjectFilePECOFF::CreateInstance (Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) 108*f754f88fSGreg Clayton { 109*f754f88fSGreg Clayton if (ObjectFilePECOFF::MagicBytesMatch(dataSP)) 110*f754f88fSGreg Clayton { 111*f754f88fSGreg Clayton std::auto_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module, dataSP, file, offset, length)); 112*f754f88fSGreg Clayton if (objfile_ap.get() && objfile_ap->ParseHeader()) 113*f754f88fSGreg Clayton return objfile_ap.release(); 114*f754f88fSGreg Clayton } 115*f754f88fSGreg Clayton return NULL; 116*f754f88fSGreg Clayton } 117*f754f88fSGreg Clayton 118*f754f88fSGreg Clayton bool 119*f754f88fSGreg Clayton ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP) 120*f754f88fSGreg Clayton { 121*f754f88fSGreg Clayton DataExtractor data(dataSP, eByteOrderLittle, 4); 122*f754f88fSGreg Clayton uint32_t offset = 0; 123*f754f88fSGreg Clayton uint16_t magic = data.GetU16 (&offset); 124*f754f88fSGreg Clayton return magic == IMAGE_DOS_SIGNATURE; 125*f754f88fSGreg Clayton } 126*f754f88fSGreg Clayton 127*f754f88fSGreg Clayton 128*f754f88fSGreg Clayton ObjectFilePECOFF::ObjectFilePECOFF (Module* module, 129*f754f88fSGreg Clayton DataBufferSP& dataSP, 130*f754f88fSGreg Clayton const FileSpec* file, 131*f754f88fSGreg Clayton addr_t offset, 132*f754f88fSGreg Clayton addr_t length) : 133*f754f88fSGreg Clayton ObjectFile (module, file, offset, length, dataSP), 134*f754f88fSGreg Clayton m_mutex (Mutex::eMutexTypeRecursive), 135*f754f88fSGreg Clayton m_dos_header (), 136*f754f88fSGreg Clayton m_coff_header (), 137*f754f88fSGreg Clayton m_coff_header_opt (), 138*f754f88fSGreg Clayton m_sect_headers () 139*f754f88fSGreg Clayton { 140*f754f88fSGreg Clayton ::memset (&m_dos_header, 0, sizeof(m_dos_header)); 141*f754f88fSGreg Clayton ::memset (&m_coff_header, 0, sizeof(m_coff_header)); 142*f754f88fSGreg Clayton ::memset (&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); 143*f754f88fSGreg Clayton } 144*f754f88fSGreg Clayton 145*f754f88fSGreg Clayton 146*f754f88fSGreg Clayton ObjectFilePECOFF::~ObjectFilePECOFF() 147*f754f88fSGreg Clayton { 148*f754f88fSGreg Clayton } 149*f754f88fSGreg Clayton 150*f754f88fSGreg Clayton 151*f754f88fSGreg Clayton bool 152*f754f88fSGreg Clayton ObjectFilePECOFF::ParseHeader () 153*f754f88fSGreg Clayton { 154*f754f88fSGreg Clayton Mutex::Locker locker(m_mutex); 155*f754f88fSGreg Clayton m_sect_headers.clear(); 156*f754f88fSGreg Clayton m_data.SetByteOrder (eByteOrderLittle); 157*f754f88fSGreg Clayton uint32_t offset = 0; 158*f754f88fSGreg Clayton 159*f754f88fSGreg Clayton if (ParseDOSHeader()) 160*f754f88fSGreg Clayton { 161*f754f88fSGreg Clayton offset = m_dos_header.e_lfanew; 162*f754f88fSGreg Clayton uint32_t pe_signature = m_data.GetU32 (&offset); 163*f754f88fSGreg Clayton if (pe_signature != IMAGE_NT_SIGNATURE) 164*f754f88fSGreg Clayton return false; 165*f754f88fSGreg Clayton } 166*f754f88fSGreg Clayton if (ParseCOFFHeader(&offset)) 167*f754f88fSGreg Clayton { 168*f754f88fSGreg Clayton if (m_coff_header.hdrsize > 0) 169*f754f88fSGreg Clayton ParseCOFFOptionalHeader(&offset); 170*f754f88fSGreg Clayton ParseSectionHeaders (offset); 171*f754f88fSGreg Clayton return true; 172*f754f88fSGreg Clayton } 173*f754f88fSGreg Clayton return false; 174*f754f88fSGreg Clayton } 175*f754f88fSGreg Clayton 176*f754f88fSGreg Clayton 177*f754f88fSGreg Clayton ByteOrder 178*f754f88fSGreg Clayton ObjectFilePECOFF::GetByteOrder () const 179*f754f88fSGreg Clayton { 180*f754f88fSGreg Clayton return eByteOrderLittle; 181*f754f88fSGreg Clayton } 182*f754f88fSGreg Clayton 183*f754f88fSGreg Clayton bool 184*f754f88fSGreg Clayton ObjectFilePECOFF::IsExecutable() const 185*f754f88fSGreg Clayton { 186*f754f88fSGreg Clayton return (m_coff_header.flags & IMAGE_FILE_DLL) == 0; 187*f754f88fSGreg Clayton } 188*f754f88fSGreg Clayton 189*f754f88fSGreg Clayton size_t 190*f754f88fSGreg Clayton ObjectFilePECOFF::GetAddressByteSize () const 191*f754f88fSGreg Clayton { 192*f754f88fSGreg Clayton if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS) 193*f754f88fSGreg Clayton return 8; 194*f754f88fSGreg Clayton else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) 195*f754f88fSGreg Clayton return 4; 196*f754f88fSGreg Clayton return 4; 197*f754f88fSGreg Clayton } 198*f754f88fSGreg Clayton 199*f754f88fSGreg Clayton //---------------------------------------------------------------------- 200*f754f88fSGreg Clayton // NeedsEndianSwap 201*f754f88fSGreg Clayton // 202*f754f88fSGreg Clayton // Return true if an endian swap needs to occur when extracting data 203*f754f88fSGreg Clayton // from this file. 204*f754f88fSGreg Clayton //---------------------------------------------------------------------- 205*f754f88fSGreg Clayton bool 206*f754f88fSGreg Clayton ObjectFilePECOFF::NeedsEndianSwap() const 207*f754f88fSGreg Clayton { 208*f754f88fSGreg Clayton #if defined(__LITTLE_ENDIAN__) 209*f754f88fSGreg Clayton return false; 210*f754f88fSGreg Clayton #else 211*f754f88fSGreg Clayton return true; 212*f754f88fSGreg Clayton #endif 213*f754f88fSGreg Clayton } 214*f754f88fSGreg Clayton //---------------------------------------------------------------------- 215*f754f88fSGreg Clayton // ParseDOSHeader 216*f754f88fSGreg Clayton //---------------------------------------------------------------------- 217*f754f88fSGreg Clayton bool 218*f754f88fSGreg Clayton ObjectFilePECOFF::ParseDOSHeader () 219*f754f88fSGreg Clayton { 220*f754f88fSGreg Clayton bool success = false; 221*f754f88fSGreg Clayton uint32_t offset = 0; 222*f754f88fSGreg Clayton success = m_data.ValidOffsetForDataOfSize(0, sizeof(m_dos_header)); 223*f754f88fSGreg Clayton 224*f754f88fSGreg Clayton if (success) 225*f754f88fSGreg Clayton { 226*f754f88fSGreg Clayton m_dos_header.e_magic = m_data.GetU16(&offset); // Magic number 227*f754f88fSGreg Clayton success = m_dos_header.e_magic == IMAGE_DOS_SIGNATURE; 228*f754f88fSGreg Clayton 229*f754f88fSGreg Clayton if (success) 230*f754f88fSGreg Clayton { 231*f754f88fSGreg Clayton m_dos_header.e_cblp = m_data.GetU16(&offset); // Bytes on last page of file 232*f754f88fSGreg Clayton m_dos_header.e_cp = m_data.GetU16(&offset); // Pages in file 233*f754f88fSGreg Clayton m_dos_header.e_crlc = m_data.GetU16(&offset); // Relocations 234*f754f88fSGreg Clayton m_dos_header.e_cparhdr = m_data.GetU16(&offset); // Size of header in paragraphs 235*f754f88fSGreg Clayton m_dos_header.e_minalloc = m_data.GetU16(&offset); // Minimum extra paragraphs needed 236*f754f88fSGreg Clayton m_dos_header.e_maxalloc = m_data.GetU16(&offset); // Maximum extra paragraphs needed 237*f754f88fSGreg Clayton m_dos_header.e_ss = m_data.GetU16(&offset); // Initial (relative) SS value 238*f754f88fSGreg Clayton m_dos_header.e_sp = m_data.GetU16(&offset); // Initial SP value 239*f754f88fSGreg Clayton m_dos_header.e_csum = m_data.GetU16(&offset); // Checksum 240*f754f88fSGreg Clayton m_dos_header.e_ip = m_data.GetU16(&offset); // Initial IP value 241*f754f88fSGreg Clayton m_dos_header.e_cs = m_data.GetU16(&offset); // Initial (relative) CS value 242*f754f88fSGreg Clayton m_dos_header.e_lfarlc = m_data.GetU16(&offset); // File address of relocation table 243*f754f88fSGreg Clayton m_dos_header.e_ovno = m_data.GetU16(&offset); // Overlay number 244*f754f88fSGreg Clayton 245*f754f88fSGreg Clayton m_dos_header.e_res[0] = m_data.GetU16(&offset); // Reserved words 246*f754f88fSGreg Clayton m_dos_header.e_res[1] = m_data.GetU16(&offset); // Reserved words 247*f754f88fSGreg Clayton m_dos_header.e_res[2] = m_data.GetU16(&offset); // Reserved words 248*f754f88fSGreg Clayton m_dos_header.e_res[3] = m_data.GetU16(&offset); // Reserved words 249*f754f88fSGreg Clayton 250*f754f88fSGreg Clayton m_dos_header.e_oemid = m_data.GetU16(&offset); // OEM identifier (for e_oeminfo) 251*f754f88fSGreg Clayton m_dos_header.e_oeminfo = m_data.GetU16(&offset); // OEM information; e_oemid specific 252*f754f88fSGreg Clayton m_dos_header.e_res2[0] = m_data.GetU16(&offset); // Reserved words 253*f754f88fSGreg Clayton m_dos_header.e_res2[1] = m_data.GetU16(&offset); // Reserved words 254*f754f88fSGreg Clayton m_dos_header.e_res2[2] = m_data.GetU16(&offset); // Reserved words 255*f754f88fSGreg Clayton m_dos_header.e_res2[3] = m_data.GetU16(&offset); // Reserved words 256*f754f88fSGreg Clayton m_dos_header.e_res2[4] = m_data.GetU16(&offset); // Reserved words 257*f754f88fSGreg Clayton m_dos_header.e_res2[5] = m_data.GetU16(&offset); // Reserved words 258*f754f88fSGreg Clayton m_dos_header.e_res2[6] = m_data.GetU16(&offset); // Reserved words 259*f754f88fSGreg Clayton m_dos_header.e_res2[7] = m_data.GetU16(&offset); // Reserved words 260*f754f88fSGreg Clayton m_dos_header.e_res2[8] = m_data.GetU16(&offset); // Reserved words 261*f754f88fSGreg Clayton m_dos_header.e_res2[9] = m_data.GetU16(&offset); // Reserved words 262*f754f88fSGreg Clayton 263*f754f88fSGreg Clayton m_dos_header.e_lfanew = m_data.GetU32(&offset); // File address of new exe header 264*f754f88fSGreg Clayton } 265*f754f88fSGreg Clayton } 266*f754f88fSGreg Clayton if (!success) 267*f754f88fSGreg Clayton memset(&m_dos_header, 0, sizeof(m_dos_header)); 268*f754f88fSGreg Clayton return success; 269*f754f88fSGreg Clayton } 270*f754f88fSGreg Clayton 271*f754f88fSGreg Clayton 272*f754f88fSGreg Clayton //---------------------------------------------------------------------- 273*f754f88fSGreg Clayton // ParserCOFFHeader 274*f754f88fSGreg Clayton //---------------------------------------------------------------------- 275*f754f88fSGreg Clayton bool 276*f754f88fSGreg Clayton ObjectFilePECOFF::ParseCOFFHeader(uint32_t* offset_ptr) 277*f754f88fSGreg Clayton { 278*f754f88fSGreg Clayton bool success = m_data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(m_coff_header)); 279*f754f88fSGreg Clayton if (success) 280*f754f88fSGreg Clayton { 281*f754f88fSGreg Clayton m_coff_header.machine = m_data.GetU16(offset_ptr); 282*f754f88fSGreg Clayton m_coff_header.nsects = m_data.GetU16(offset_ptr); 283*f754f88fSGreg Clayton m_coff_header.modtime = m_data.GetU32(offset_ptr); 284*f754f88fSGreg Clayton m_coff_header.symoff = m_data.GetU32(offset_ptr); 285*f754f88fSGreg Clayton m_coff_header.nsyms = m_data.GetU32(offset_ptr); 286*f754f88fSGreg Clayton m_coff_header.hdrsize = m_data.GetU16(offset_ptr); 287*f754f88fSGreg Clayton m_coff_header.flags = m_data.GetU16(offset_ptr); 288*f754f88fSGreg Clayton } 289*f754f88fSGreg Clayton if (!success) 290*f754f88fSGreg Clayton memset(&m_coff_header, 0, sizeof(m_coff_header)); 291*f754f88fSGreg Clayton return success; 292*f754f88fSGreg Clayton } 293*f754f88fSGreg Clayton 294*f754f88fSGreg Clayton bool 295*f754f88fSGreg Clayton ObjectFilePECOFF::ParseCOFFOptionalHeader(uint32_t* offset_ptr) 296*f754f88fSGreg Clayton { 297*f754f88fSGreg Clayton bool success = false; 298*f754f88fSGreg Clayton const uint32_t end_offset = *offset_ptr + m_coff_header.hdrsize; 299*f754f88fSGreg Clayton if (*offset_ptr < end_offset) 300*f754f88fSGreg Clayton { 301*f754f88fSGreg Clayton success = true; 302*f754f88fSGreg Clayton m_coff_header_opt.magic = m_data.GetU16(offset_ptr); 303*f754f88fSGreg Clayton m_coff_header_opt.major_linker_version = m_data.GetU8 (offset_ptr); 304*f754f88fSGreg Clayton m_coff_header_opt.minor_linker_version = m_data.GetU8 (offset_ptr); 305*f754f88fSGreg Clayton m_coff_header_opt.code_size = m_data.GetU32(offset_ptr); 306*f754f88fSGreg Clayton m_coff_header_opt.data_size = m_data.GetU32(offset_ptr); 307*f754f88fSGreg Clayton m_coff_header_opt.bss_size = m_data.GetU32(offset_ptr); 308*f754f88fSGreg Clayton m_coff_header_opt.entry = m_data.GetU32(offset_ptr); 309*f754f88fSGreg Clayton m_coff_header_opt.code_offset = m_data.GetU32(offset_ptr); 310*f754f88fSGreg Clayton 311*f754f88fSGreg Clayton const uint32_t addr_byte_size = GetAddressByteSize (); 312*f754f88fSGreg Clayton 313*f754f88fSGreg Clayton if (*offset_ptr < end_offset) 314*f754f88fSGreg Clayton { 315*f754f88fSGreg Clayton if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) 316*f754f88fSGreg Clayton { 317*f754f88fSGreg Clayton // PE32 only 318*f754f88fSGreg Clayton m_coff_header_opt.data_offset = m_data.GetU32(offset_ptr); 319*f754f88fSGreg Clayton } 320*f754f88fSGreg Clayton else 321*f754f88fSGreg Clayton m_coff_header_opt.data_offset = 0; 322*f754f88fSGreg Clayton 323*f754f88fSGreg Clayton if (*offset_ptr < end_offset) 324*f754f88fSGreg Clayton { 325*f754f88fSGreg Clayton m_coff_header_opt.image_base = m_data.GetMaxU64 (offset_ptr, addr_byte_size); 326*f754f88fSGreg Clayton m_coff_header_opt.sect_alignment = m_data.GetU32(offset_ptr); 327*f754f88fSGreg Clayton m_coff_header_opt.file_alignment = m_data.GetU32(offset_ptr); 328*f754f88fSGreg Clayton m_coff_header_opt.major_os_system_version = m_data.GetU16(offset_ptr); 329*f754f88fSGreg Clayton m_coff_header_opt.minor_os_system_version = m_data.GetU16(offset_ptr); 330*f754f88fSGreg Clayton m_coff_header_opt.major_image_version = m_data.GetU16(offset_ptr); 331*f754f88fSGreg Clayton m_coff_header_opt.minor_image_version = m_data.GetU16(offset_ptr); 332*f754f88fSGreg Clayton m_coff_header_opt.major_subsystem_version = m_data.GetU16(offset_ptr); 333*f754f88fSGreg Clayton m_coff_header_opt.minor_subsystem_version = m_data.GetU16(offset_ptr); 334*f754f88fSGreg Clayton m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr); 335*f754f88fSGreg Clayton m_coff_header_opt.image_size = m_data.GetU32(offset_ptr); 336*f754f88fSGreg Clayton m_coff_header_opt.header_size = m_data.GetU32(offset_ptr); 337*f754f88fSGreg Clayton m_coff_header_opt.checksym = m_data.GetU32(offset_ptr); 338*f754f88fSGreg Clayton m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr); 339*f754f88fSGreg Clayton m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr); 340*f754f88fSGreg Clayton m_coff_header_opt.stack_reserve_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); 341*f754f88fSGreg Clayton m_coff_header_opt.stack_commit_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); 342*f754f88fSGreg Clayton m_coff_header_opt.heap_reserve_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); 343*f754f88fSGreg Clayton m_coff_header_opt.heap_commit_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); 344*f754f88fSGreg Clayton m_coff_header_opt.loader_flags = m_data.GetU32(offset_ptr); 345*f754f88fSGreg Clayton uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr); 346*f754f88fSGreg Clayton m_coff_header_opt.data_dirs.clear(); 347*f754f88fSGreg Clayton m_coff_header_opt.data_dirs.resize(num_data_dir_entries); 348*f754f88fSGreg Clayton uint32_t i; 349*f754f88fSGreg Clayton for (i=0; i<num_data_dir_entries; i++) 350*f754f88fSGreg Clayton { 351*f754f88fSGreg Clayton m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr); 352*f754f88fSGreg Clayton m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr); 353*f754f88fSGreg Clayton } 354*f754f88fSGreg Clayton } 355*f754f88fSGreg Clayton } 356*f754f88fSGreg Clayton } 357*f754f88fSGreg Clayton // Make sure we are on track for section data which follows 358*f754f88fSGreg Clayton *offset_ptr = end_offset; 359*f754f88fSGreg Clayton return success; 360*f754f88fSGreg Clayton } 361*f754f88fSGreg Clayton 362*f754f88fSGreg Clayton 363*f754f88fSGreg Clayton //---------------------------------------------------------------------- 364*f754f88fSGreg Clayton // ParseSectionHeaders 365*f754f88fSGreg Clayton //---------------------------------------------------------------------- 366*f754f88fSGreg Clayton bool 367*f754f88fSGreg Clayton ObjectFilePECOFF::ParseSectionHeaders (uint32_t section_header_data_offset) 368*f754f88fSGreg Clayton { 369*f754f88fSGreg Clayton const uint32_t nsects = m_coff_header.nsects; 370*f754f88fSGreg Clayton m_sect_headers.clear(); 371*f754f88fSGreg Clayton 372*f754f88fSGreg Clayton if (nsects > 0) 373*f754f88fSGreg Clayton { 374*f754f88fSGreg Clayton const uint32_t addr_byte_size = GetAddressByteSize (); 375*f754f88fSGreg Clayton const size_t section_header_byte_size = nsects * sizeof(section_header_t); 376*f754f88fSGreg Clayton DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size)); 377*f754f88fSGreg Clayton DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size); 378*f754f88fSGreg Clayton 379*f754f88fSGreg Clayton uint32_t offset = 0; 380*f754f88fSGreg Clayton if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size)) 381*f754f88fSGreg Clayton { 382*f754f88fSGreg Clayton m_sect_headers.resize(nsects); 383*f754f88fSGreg Clayton 384*f754f88fSGreg Clayton for (uint32_t idx = 0; idx<nsects; ++idx) 385*f754f88fSGreg Clayton { 386*f754f88fSGreg Clayton const void *name_data = section_header_data.GetData(&offset, 8); 387*f754f88fSGreg Clayton if (name_data) 388*f754f88fSGreg Clayton { 389*f754f88fSGreg Clayton memcpy(m_sect_headers[idx].name, name_data, 8); 390*f754f88fSGreg Clayton m_sect_headers[idx].vmsize = section_header_data.GetU32(&offset); 391*f754f88fSGreg Clayton m_sect_headers[idx].vmaddr = section_header_data.GetU32(&offset); 392*f754f88fSGreg Clayton m_sect_headers[idx].size = section_header_data.GetU32(&offset); 393*f754f88fSGreg Clayton m_sect_headers[idx].offset = section_header_data.GetU32(&offset); 394*f754f88fSGreg Clayton m_sect_headers[idx].reloff = section_header_data.GetU32(&offset); 395*f754f88fSGreg Clayton m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset); 396*f754f88fSGreg Clayton m_sect_headers[idx].nreloc = section_header_data.GetU16(&offset); 397*f754f88fSGreg Clayton m_sect_headers[idx].nline = section_header_data.GetU16(&offset); 398*f754f88fSGreg Clayton m_sect_headers[idx].flags = section_header_data.GetU32(&offset); 399*f754f88fSGreg Clayton } 400*f754f88fSGreg Clayton } 401*f754f88fSGreg Clayton } 402*f754f88fSGreg Clayton } 403*f754f88fSGreg Clayton 404*f754f88fSGreg Clayton return m_sect_headers.empty() == false; 405*f754f88fSGreg Clayton } 406*f754f88fSGreg Clayton 407*f754f88fSGreg Clayton bool 408*f754f88fSGreg Clayton ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t& sect) 409*f754f88fSGreg Clayton { 410*f754f88fSGreg Clayton if (sect.name[0] == '/') 411*f754f88fSGreg Clayton { 412*f754f88fSGreg Clayton uint32_t stroff = strtoul(§.name[1], NULL, 10); 413*f754f88fSGreg Clayton uint32_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff; 414*f754f88fSGreg Clayton const char *name = m_data.GetCStr (&string_file_offset); 415*f754f88fSGreg Clayton if (name) 416*f754f88fSGreg Clayton { 417*f754f88fSGreg Clayton sect_name = name; 418*f754f88fSGreg Clayton return true; 419*f754f88fSGreg Clayton } 420*f754f88fSGreg Clayton 421*f754f88fSGreg Clayton return false; 422*f754f88fSGreg Clayton } 423*f754f88fSGreg Clayton sect_name = sect.name; 424*f754f88fSGreg Clayton return true; 425*f754f88fSGreg Clayton } 426*f754f88fSGreg Clayton 427*f754f88fSGreg Clayton //---------------------------------------------------------------------- 428*f754f88fSGreg Clayton // GetNListSymtab 429*f754f88fSGreg Clayton //---------------------------------------------------------------------- 430*f754f88fSGreg Clayton Symtab * 431*f754f88fSGreg Clayton ObjectFilePECOFF::GetSymtab() 432*f754f88fSGreg Clayton { 433*f754f88fSGreg Clayton Mutex::Locker symfile_locker(m_mutex); 434*f754f88fSGreg Clayton if (m_symtab_ap.get() == NULL) 435*f754f88fSGreg Clayton { 436*f754f88fSGreg Clayton SectionList *sect_list = GetSectionList(); 437*f754f88fSGreg Clayton m_symtab_ap.reset(new Symtab(this)); 438*f754f88fSGreg Clayton Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); 439*f754f88fSGreg Clayton DataExtractor stab_data; 440*f754f88fSGreg Clayton DataExtractor stabstr_data; 441*f754f88fSGreg Clayton static ConstString g_stab_sect_name(".stab"); 442*f754f88fSGreg Clayton static ConstString g_stabstr_sect_name(".stabstr"); 443*f754f88fSGreg Clayton const Section *stab_section = sect_list->FindSectionByName (g_stab_sect_name).get(); 444*f754f88fSGreg Clayton if (stab_section == NULL) 445*f754f88fSGreg Clayton return m_symtab_ap.get(); 446*f754f88fSGreg Clayton const Section *stabstr_section = sect_list->FindSectionByName (g_stabstr_sect_name).get(); 447*f754f88fSGreg Clayton if (stabstr_section == NULL) 448*f754f88fSGreg Clayton return m_symtab_ap.get(); 449*f754f88fSGreg Clayton uint32_t offset = 0; 450*f754f88fSGreg Clayton if (stab_section->ReadSectionDataFromObjectFile (this, stab_data) && 451*f754f88fSGreg Clayton stabstr_section->ReadSectionDataFromObjectFile (this, stabstr_data)) 452*f754f88fSGreg Clayton { 453*f754f88fSGreg Clayton const uint32_t num_syms = stab_data.GetByteSize() / sizeof (coff_symbol_t); 454*f754f88fSGreg Clayton Symbol *symbols = m_symtab_ap->Resize (num_syms); 455*f754f88fSGreg Clayton for (uint32_t i=0; i<num_syms; ++i) 456*f754f88fSGreg Clayton { 457*f754f88fSGreg Clayton coff_symbol_t symbol; 458*f754f88fSGreg Clayton const void *name_data = stab_data.GetData(&offset, sizeof(symbol.name)); 459*f754f88fSGreg Clayton 460*f754f88fSGreg Clayton if (name_data == NULL) 461*f754f88fSGreg Clayton break; 462*f754f88fSGreg Clayton memcpy (symbol.name, name_data, sizeof(symbol.name)); 463*f754f88fSGreg Clayton symbol.value = stab_data.GetU32 (&offset); 464*f754f88fSGreg Clayton symbol.sect = stab_data.GetU16 (&offset); 465*f754f88fSGreg Clayton symbol.type = stab_data.GetU16 (&offset); 466*f754f88fSGreg Clayton symbol.storage = stab_data.GetU8 (&offset); 467*f754f88fSGreg Clayton symbol.naux = stab_data.GetU8 (&offset); 468*f754f88fSGreg Clayton 469*f754f88fSGreg Clayton symbol.name[sizeof(symbol.name)-1] = '\0'; 470*f754f88fSGreg Clayton Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1).get(), symbol.value); 471*f754f88fSGreg Clayton symbols[i].GetMangled ().SetValue(symbol.name, symbol.name[0]=='_' && symbol.name[1] == 'Z'); 472*f754f88fSGreg Clayton symbols[i].SetValue(symbol_addr); 473*f754f88fSGreg Clayton 474*f754f88fSGreg Clayton if (symbol.naux > 0) 475*f754f88fSGreg Clayton i += symbol.naux; 476*f754f88fSGreg Clayton } 477*f754f88fSGreg Clayton 478*f754f88fSGreg Clayton } 479*f754f88fSGreg Clayton } 480*f754f88fSGreg Clayton return m_symtab_ap.get(); 481*f754f88fSGreg Clayton 482*f754f88fSGreg Clayton } 483*f754f88fSGreg Clayton 484*f754f88fSGreg Clayton SectionList * 485*f754f88fSGreg Clayton ObjectFilePECOFF::GetSectionList() 486*f754f88fSGreg Clayton { 487*f754f88fSGreg Clayton Mutex::Locker symfile_locker(m_mutex); 488*f754f88fSGreg Clayton if (m_sections_ap.get() == NULL) 489*f754f88fSGreg Clayton { 490*f754f88fSGreg Clayton m_sections_ap.reset(new SectionList()); 491*f754f88fSGreg Clayton const uint32_t nsects = m_sect_headers.size(); 492*f754f88fSGreg Clayton Module *module = GetModule(); 493*f754f88fSGreg Clayton for (uint32_t idx = 0; idx<nsects; ++idx) 494*f754f88fSGreg Clayton { 495*f754f88fSGreg Clayton std::string sect_name; 496*f754f88fSGreg Clayton GetSectionName (sect_name, m_sect_headers[idx]); 497*f754f88fSGreg Clayton ConstString const_sect_name (sect_name.c_str()); 498*f754f88fSGreg Clayton 499*f754f88fSGreg Clayton // Use a segment ID of the segment index shifted left by 8 so they 500*f754f88fSGreg Clayton // never conflict with any of the sections. 501*f754f88fSGreg Clayton SectionSP section_sp (new Section (NULL, 502*f754f88fSGreg Clayton module, // Module to which this section belongs 503*f754f88fSGreg Clayton 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 504*f754f88fSGreg Clayton const_sect_name, // Name of this section 505*f754f88fSGreg Clayton eSectionTypeCode, // This section is a container of other sections. 506*f754f88fSGreg Clayton m_sect_headers[idx].vmaddr, // File VM address == addresses as they are found in the object file 507*f754f88fSGreg Clayton m_sect_headers[idx].vmsize, // VM size in bytes of this section 508*f754f88fSGreg Clayton m_sect_headers[idx].offset, // Offset to the data for this section in the file 509*f754f88fSGreg Clayton m_sect_headers[idx].size, // Size in bytes of this section as found in the the file 510*f754f88fSGreg Clayton m_sect_headers[idx].flags)); // Flags for this section 511*f754f88fSGreg Clayton 512*f754f88fSGreg Clayton //section_sp->SetIsEncrypted (segment_is_encrypted); 513*f754f88fSGreg Clayton 514*f754f88fSGreg Clayton m_sections_ap->AddSection(section_sp); 515*f754f88fSGreg Clayton } 516*f754f88fSGreg Clayton } 517*f754f88fSGreg Clayton return m_sections_ap.get(); 518*f754f88fSGreg Clayton } 519*f754f88fSGreg Clayton 520*f754f88fSGreg Clayton bool 521*f754f88fSGreg Clayton ObjectFilePECOFF::GetUUID (UUID* uuid) 522*f754f88fSGreg Clayton { 523*f754f88fSGreg Clayton return false; 524*f754f88fSGreg Clayton } 525*f754f88fSGreg Clayton 526*f754f88fSGreg Clayton uint32_t 527*f754f88fSGreg Clayton ObjectFilePECOFF::GetDependentModules (FileSpecList& files) 528*f754f88fSGreg Clayton { 529*f754f88fSGreg Clayton return 0; 530*f754f88fSGreg Clayton } 531*f754f88fSGreg Clayton 532*f754f88fSGreg Clayton 533*f754f88fSGreg Clayton //---------------------------------------------------------------------- 534*f754f88fSGreg Clayton // Dump 535*f754f88fSGreg Clayton // 536*f754f88fSGreg Clayton // Dump the specifics of the runtime file container (such as any headers 537*f754f88fSGreg Clayton // segments, sections, etc). 538*f754f88fSGreg Clayton //---------------------------------------------------------------------- 539*f754f88fSGreg Clayton void 540*f754f88fSGreg Clayton ObjectFilePECOFF::Dump(Stream *s) 541*f754f88fSGreg Clayton { 542*f754f88fSGreg Clayton Mutex::Locker locker(m_mutex); 543*f754f88fSGreg Clayton s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 544*f754f88fSGreg Clayton s->Indent(); 545*f754f88fSGreg Clayton s->PutCString("ObjectFilePECOFF"); 546*f754f88fSGreg Clayton 547*f754f88fSGreg Clayton ArchSpec header_arch; 548*f754f88fSGreg Clayton GetArchitecture (header_arch); 549*f754f88fSGreg Clayton 550*f754f88fSGreg Clayton *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; 551*f754f88fSGreg Clayton 552*f754f88fSGreg Clayton if (m_sections_ap.get()) 553*f754f88fSGreg Clayton m_sections_ap->Dump(s, NULL, true, UINT32_MAX); 554*f754f88fSGreg Clayton 555*f754f88fSGreg Clayton if (m_symtab_ap.get()) 556*f754f88fSGreg Clayton m_symtab_ap->Dump(s, NULL, eSortOrderNone); 557*f754f88fSGreg Clayton 558*f754f88fSGreg Clayton if (m_dos_header.e_magic) 559*f754f88fSGreg Clayton DumpDOSHeader (s, m_dos_header); 560*f754f88fSGreg Clayton if (m_coff_header.machine) 561*f754f88fSGreg Clayton { 562*f754f88fSGreg Clayton DumpCOFFHeader (s, m_coff_header); 563*f754f88fSGreg Clayton if (m_coff_header.hdrsize) 564*f754f88fSGreg Clayton DumpOptCOFFHeader (s, m_coff_header_opt); 565*f754f88fSGreg Clayton } 566*f754f88fSGreg Clayton s->EOL(); 567*f754f88fSGreg Clayton DumpSectionHeaders(s); 568*f754f88fSGreg Clayton s->EOL(); 569*f754f88fSGreg Clayton } 570*f754f88fSGreg Clayton 571*f754f88fSGreg Clayton //---------------------------------------------------------------------- 572*f754f88fSGreg Clayton // DumpDOSHeader 573*f754f88fSGreg Clayton // 574*f754f88fSGreg Clayton // Dump the MS-DOS header to the specified output stream 575*f754f88fSGreg Clayton //---------------------------------------------------------------------- 576*f754f88fSGreg Clayton void 577*f754f88fSGreg Clayton ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header) 578*f754f88fSGreg Clayton { 579*f754f88fSGreg Clayton s->PutCString ("MSDOS Header\n"); 580*f754f88fSGreg Clayton s->Printf (" e_magic = 0x%4.4x\n", header.e_magic); 581*f754f88fSGreg Clayton s->Printf (" e_cblp = 0x%4.4x\n", header.e_cblp); 582*f754f88fSGreg Clayton s->Printf (" e_cp = 0x%4.4x\n", header.e_cp); 583*f754f88fSGreg Clayton s->Printf (" e_crlc = 0x%4.4x\n", header.e_crlc); 584*f754f88fSGreg Clayton s->Printf (" e_cparhdr = 0x%4.4x\n", header.e_cparhdr); 585*f754f88fSGreg Clayton s->Printf (" e_minalloc = 0x%4.4x\n", header.e_minalloc); 586*f754f88fSGreg Clayton s->Printf (" e_maxalloc = 0x%4.4x\n", header.e_maxalloc); 587*f754f88fSGreg Clayton s->Printf (" e_ss = 0x%4.4x\n", header.e_ss); 588*f754f88fSGreg Clayton s->Printf (" e_sp = 0x%4.4x\n", header.e_sp); 589*f754f88fSGreg Clayton s->Printf (" e_csum = 0x%4.4x\n", header.e_csum); 590*f754f88fSGreg Clayton s->Printf (" e_ip = 0x%4.4x\n", header.e_ip); 591*f754f88fSGreg Clayton s->Printf (" e_cs = 0x%4.4x\n", header.e_cs); 592*f754f88fSGreg Clayton s->Printf (" e_lfarlc = 0x%4.4x\n", header.e_lfarlc); 593*f754f88fSGreg Clayton s->Printf (" e_ovno = 0x%4.4x\n", header.e_ovno); 594*f754f88fSGreg Clayton s->Printf (" e_res[4] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n", 595*f754f88fSGreg Clayton header.e_res[0], 596*f754f88fSGreg Clayton header.e_res[1], 597*f754f88fSGreg Clayton header.e_res[2], 598*f754f88fSGreg Clayton header.e_res[3]); 599*f754f88fSGreg Clayton s->Printf (" e_oemid = 0x%4.4x\n", header.e_oemid); 600*f754f88fSGreg Clayton s->Printf (" e_oeminfo = 0x%4.4x\n", header.e_oeminfo); 601*f754f88fSGreg Clayton 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", 602*f754f88fSGreg Clayton header.e_res2[0], 603*f754f88fSGreg Clayton header.e_res2[1], 604*f754f88fSGreg Clayton header.e_res2[2], 605*f754f88fSGreg Clayton header.e_res2[3], 606*f754f88fSGreg Clayton header.e_res2[4], 607*f754f88fSGreg Clayton header.e_res2[5], 608*f754f88fSGreg Clayton header.e_res2[6], 609*f754f88fSGreg Clayton header.e_res2[7], 610*f754f88fSGreg Clayton header.e_res2[8], 611*f754f88fSGreg Clayton header.e_res2[9]); 612*f754f88fSGreg Clayton s->Printf (" e_lfanew = 0x%8.8x\n", header.e_lfanew); 613*f754f88fSGreg Clayton } 614*f754f88fSGreg Clayton 615*f754f88fSGreg Clayton //---------------------------------------------------------------------- 616*f754f88fSGreg Clayton // DumpCOFFHeader 617*f754f88fSGreg Clayton // 618*f754f88fSGreg Clayton // Dump the COFF header to the specified output stream 619*f754f88fSGreg Clayton //---------------------------------------------------------------------- 620*f754f88fSGreg Clayton void 621*f754f88fSGreg Clayton ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header) 622*f754f88fSGreg Clayton { 623*f754f88fSGreg Clayton s->PutCString ("COFF Header\n"); 624*f754f88fSGreg Clayton s->Printf (" machine = 0x%4.4x\n", header.machine); 625*f754f88fSGreg Clayton s->Printf (" nsects = 0x%4.4x\n", header.nsects); 626*f754f88fSGreg Clayton s->Printf (" modtime = 0x%8.8x\n", header.modtime); 627*f754f88fSGreg Clayton s->Printf (" symoff = 0x%8.8x\n", header.symoff); 628*f754f88fSGreg Clayton s->Printf (" nsyms = 0x%8.8x\n", header.nsyms); 629*f754f88fSGreg Clayton s->Printf (" hdrsize = 0x%4.4x\n", header.hdrsize); 630*f754f88fSGreg Clayton } 631*f754f88fSGreg Clayton 632*f754f88fSGreg Clayton //---------------------------------------------------------------------- 633*f754f88fSGreg Clayton // DumpOptCOFFHeader 634*f754f88fSGreg Clayton // 635*f754f88fSGreg Clayton // Dump the optional COFF header to the specified output stream 636*f754f88fSGreg Clayton //---------------------------------------------------------------------- 637*f754f88fSGreg Clayton void 638*f754f88fSGreg Clayton ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, const coff_opt_header_t& header) 639*f754f88fSGreg Clayton { 640*f754f88fSGreg Clayton s->PutCString ("Optional COFF Header\n"); 641*f754f88fSGreg Clayton s->Printf (" magic = 0x%4.4x\n", header.magic); 642*f754f88fSGreg Clayton s->Printf (" major_linker_version = 0x%2.2x\n", header.major_linker_version); 643*f754f88fSGreg Clayton s->Printf (" minor_linker_version = 0x%2.2x\n", header.minor_linker_version); 644*f754f88fSGreg Clayton s->Printf (" code_size = 0x%8.8x\n", header.code_size); 645*f754f88fSGreg Clayton s->Printf (" data_size = 0x%8.8x\n", header.data_size); 646*f754f88fSGreg Clayton s->Printf (" bss_size = 0x%8.8x\n", header.bss_size); 647*f754f88fSGreg Clayton s->Printf (" entry = 0x%8.8x\n", header.entry); 648*f754f88fSGreg Clayton s->Printf (" code_offset = 0x%8.8x\n", header.code_offset); 649*f754f88fSGreg Clayton s->Printf (" data_offset = 0x%8.8x\n", header.data_offset); 650*f754f88fSGreg Clayton s->Printf (" image_base = 0x%16.16llx\n", header.image_base); 651*f754f88fSGreg Clayton s->Printf (" sect_alignment = 0x%8.8x\n", header.sect_alignment); 652*f754f88fSGreg Clayton s->Printf (" file_alignment = 0x%8.8x\n", header.file_alignment); 653*f754f88fSGreg Clayton s->Printf (" major_os_system_version = 0x%4.4x\n", header.major_os_system_version); 654*f754f88fSGreg Clayton s->Printf (" minor_os_system_version = 0x%4.4x\n", header.minor_os_system_version); 655*f754f88fSGreg Clayton s->Printf (" major_image_version = 0x%4.4x\n", header.major_image_version); 656*f754f88fSGreg Clayton s->Printf (" minor_image_version = 0x%4.4x\n", header.minor_image_version); 657*f754f88fSGreg Clayton s->Printf (" major_subsystem_version = 0x%4.4x\n", header.major_subsystem_version); 658*f754f88fSGreg Clayton s->Printf (" minor_subsystem_version = 0x%4.4x\n", header.minor_subsystem_version); 659*f754f88fSGreg Clayton s->Printf (" reserved1 = 0x%8.8x\n", header.reserved1); 660*f754f88fSGreg Clayton s->Printf (" image_size = 0x%8.8x\n", header.image_size); 661*f754f88fSGreg Clayton s->Printf (" header_size = 0x%8.8x\n", header.header_size); 662*f754f88fSGreg Clayton s->Printf (" checksym = 0x%8.8x\n", header.checksym); 663*f754f88fSGreg Clayton s->Printf (" subsystem = 0x%4.4x\n", header.subsystem); 664*f754f88fSGreg Clayton s->Printf (" dll_flags = 0x%4.4x\n", header.dll_flags); 665*f754f88fSGreg Clayton s->Printf (" stack_reserve_size = 0x%16.16llx\n", header.stack_reserve_size); 666*f754f88fSGreg Clayton s->Printf (" stack_commit_size = 0x%16.16llx\n", header.stack_commit_size); 667*f754f88fSGreg Clayton s->Printf (" heap_reserve_size = 0x%16.16llx\n", header.heap_reserve_size); 668*f754f88fSGreg Clayton s->Printf (" heap_commit_size = 0x%16.16llx\n", header.heap_commit_size); 669*f754f88fSGreg Clayton s->Printf (" loader_flags = 0x%8.8x\n", header.loader_flags); 670*f754f88fSGreg Clayton s->Printf (" num_data_dir_entries = 0x%8.8zx\n", header.data_dirs.size()); 671*f754f88fSGreg Clayton uint32_t i; 672*f754f88fSGreg Clayton for (i=0; i<header.data_dirs.size(); i++) 673*f754f88fSGreg Clayton { 674*f754f88fSGreg Clayton s->Printf (" data_dirs[%u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", 675*f754f88fSGreg Clayton i, 676*f754f88fSGreg Clayton header.data_dirs[i].vmaddr, 677*f754f88fSGreg Clayton header.data_dirs[i].vmsize); 678*f754f88fSGreg Clayton } 679*f754f88fSGreg Clayton } 680*f754f88fSGreg Clayton //---------------------------------------------------------------------- 681*f754f88fSGreg Clayton // DumpSectionHeader 682*f754f88fSGreg Clayton // 683*f754f88fSGreg Clayton // Dump a single ELF section header to the specified output stream 684*f754f88fSGreg Clayton //---------------------------------------------------------------------- 685*f754f88fSGreg Clayton void 686*f754f88fSGreg Clayton ObjectFilePECOFF::DumpSectionHeader(Stream *s, const section_header_t& sh) 687*f754f88fSGreg Clayton { 688*f754f88fSGreg Clayton std::string name; 689*f754f88fSGreg Clayton GetSectionName(name, sh); 690*f754f88fSGreg Clayton 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", 691*f754f88fSGreg Clayton name.c_str(), 692*f754f88fSGreg Clayton sh.vmsize, 693*f754f88fSGreg Clayton sh.vmaddr, 694*f754f88fSGreg Clayton sh.size, 695*f754f88fSGreg Clayton sh.offset, 696*f754f88fSGreg Clayton sh.reloff, 697*f754f88fSGreg Clayton sh.lineoff, 698*f754f88fSGreg Clayton sh.nreloc, 699*f754f88fSGreg Clayton sh.nline, 700*f754f88fSGreg Clayton sh.flags); 701*f754f88fSGreg Clayton } 702*f754f88fSGreg Clayton 703*f754f88fSGreg Clayton 704*f754f88fSGreg Clayton //---------------------------------------------------------------------- 705*f754f88fSGreg Clayton // DumpSectionHeaders 706*f754f88fSGreg Clayton // 707*f754f88fSGreg Clayton // Dump all of the ELF section header to the specified output stream 708*f754f88fSGreg Clayton //---------------------------------------------------------------------- 709*f754f88fSGreg Clayton void 710*f754f88fSGreg Clayton ObjectFilePECOFF::DumpSectionHeaders(Stream *s) 711*f754f88fSGreg Clayton { 712*f754f88fSGreg Clayton 713*f754f88fSGreg Clayton s->PutCString ("Section Headers\n"); 714*f754f88fSGreg Clayton s->PutCString ("IDX name vm size vm addr size offset reloff lineoff nrel nlin flags\n"); 715*f754f88fSGreg Clayton s->PutCString ("==== ---------------- -------- -------- -------- -------- -------- -------- ---- ---- --------\n"); 716*f754f88fSGreg Clayton 717*f754f88fSGreg Clayton uint32_t idx = 0; 718*f754f88fSGreg Clayton SectionHeaderCollIter pos, end = m_sect_headers.end(); 719*f754f88fSGreg Clayton 720*f754f88fSGreg Clayton for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) 721*f754f88fSGreg Clayton { 722*f754f88fSGreg Clayton s->Printf ("[%2u]", idx); 723*f754f88fSGreg Clayton ObjectFilePECOFF::DumpSectionHeader(s, *pos); 724*f754f88fSGreg Clayton } 725*f754f88fSGreg Clayton } 726*f754f88fSGreg Clayton 727*f754f88fSGreg Clayton static bool 728*f754f88fSGreg Clayton COFFMachineToMachCPU (uint16_t machine, ArchSpec &arch) 729*f754f88fSGreg Clayton { 730*f754f88fSGreg Clayton switch (machine) 731*f754f88fSGreg Clayton { 732*f754f88fSGreg Clayton case IMAGE_FILE_MACHINE_AMD64: 733*f754f88fSGreg Clayton case IMAGE_FILE_MACHINE_IA64: 734*f754f88fSGreg Clayton arch.SetArchitecture (eArchTypeMachO, 735*f754f88fSGreg Clayton llvm::MachO::CPUTypeX86_64, 736*f754f88fSGreg Clayton llvm::MachO::CPUSubType_X86_64_ALL); 737*f754f88fSGreg Clayton return true; 738*f754f88fSGreg Clayton 739*f754f88fSGreg Clayton case IMAGE_FILE_MACHINE_I386: 740*f754f88fSGreg Clayton arch.SetArchitecture (eArchTypeMachO, 741*f754f88fSGreg Clayton llvm::MachO::CPUTypeI386, 742*f754f88fSGreg Clayton llvm::MachO::CPUSubType_I386_ALL); 743*f754f88fSGreg Clayton return true; 744*f754f88fSGreg Clayton 745*f754f88fSGreg Clayton case IMAGE_FILE_MACHINE_POWERPC: 746*f754f88fSGreg Clayton case IMAGE_FILE_MACHINE_POWERPCFP: 747*f754f88fSGreg Clayton arch.SetArchitecture (eArchTypeMachO, 748*f754f88fSGreg Clayton llvm::MachO::CPUTypePowerPC, 749*f754f88fSGreg Clayton llvm::MachO::CPUSubType_POWERPC_ALL); 750*f754f88fSGreg Clayton return true; 751*f754f88fSGreg Clayton case IMAGE_FILE_MACHINE_ARM: 752*f754f88fSGreg Clayton case IMAGE_FILE_MACHINE_THUMB: 753*f754f88fSGreg Clayton arch.SetArchitecture (eArchTypeMachO, 754*f754f88fSGreg Clayton llvm::MachO::CPUTypeARM, 755*f754f88fSGreg Clayton llvm::MachO::CPUSubType_ARM_V7); 756*f754f88fSGreg Clayton return true; 757*f754f88fSGreg Clayton } 758*f754f88fSGreg Clayton return false; 759*f754f88fSGreg Clayton } 760*f754f88fSGreg Clayton bool 761*f754f88fSGreg Clayton ObjectFilePECOFF::GetArchitecture (ArchSpec &arch) 762*f754f88fSGreg Clayton { 763*f754f88fSGreg Clayton // For index zero return our cpu type 764*f754f88fSGreg Clayton return COFFMachineToMachCPU (m_coff_header.machine, arch); 765*f754f88fSGreg Clayton } 766*f754f88fSGreg Clayton 767*f754f88fSGreg Clayton ObjectFile::Type 768*f754f88fSGreg Clayton ObjectFilePECOFF::CalculateType() 769*f754f88fSGreg Clayton { 770*f754f88fSGreg Clayton if (m_coff_header.machine != 0) 771*f754f88fSGreg Clayton { 772*f754f88fSGreg Clayton if ((m_coff_header.flags & IMAGE_FILE_DLL) == 0) 773*f754f88fSGreg Clayton return eTypeExecutable; 774*f754f88fSGreg Clayton else 775*f754f88fSGreg Clayton return eTypeSharedLibrary; 776*f754f88fSGreg Clayton } 777*f754f88fSGreg Clayton return eTypeExecutable; 778*f754f88fSGreg Clayton } 779*f754f88fSGreg Clayton 780*f754f88fSGreg Clayton ObjectFile::Strata 781*f754f88fSGreg Clayton ObjectFilePECOFF::CalculateStrata() 782*f754f88fSGreg Clayton { 783*f754f88fSGreg Clayton return eStrataUser; 784*f754f88fSGreg Clayton } 785*f754f88fSGreg Clayton //------------------------------------------------------------------ 786*f754f88fSGreg Clayton // PluginInterface protocol 787*f754f88fSGreg Clayton //------------------------------------------------------------------ 788*f754f88fSGreg Clayton const char * 789*f754f88fSGreg Clayton ObjectFilePECOFF::GetPluginName() 790*f754f88fSGreg Clayton { 791*f754f88fSGreg Clayton return "ObjectFilePECOFF"; 792*f754f88fSGreg Clayton } 793*f754f88fSGreg Clayton 794*f754f88fSGreg Clayton const char * 795*f754f88fSGreg Clayton ObjectFilePECOFF::GetShortPluginName() 796*f754f88fSGreg Clayton { 797*f754f88fSGreg Clayton return GetPluginNameStatic(); 798*f754f88fSGreg Clayton } 799*f754f88fSGreg Clayton 800*f754f88fSGreg Clayton uint32_t 801*f754f88fSGreg Clayton ObjectFilePECOFF::GetPluginVersion() 802*f754f88fSGreg Clayton { 803*f754f88fSGreg Clayton return 1; 804*f754f88fSGreg Clayton } 805*f754f88fSGreg Clayton 806