18e90adafSMichael J. Spencer //===- COFFObjectFile.cpp - COFF object file implementation -----*- C++ -*-===// 28e90adafSMichael J. Spencer // 38e90adafSMichael J. Spencer // The LLVM Compiler Infrastructure 48e90adafSMichael J. Spencer // 58e90adafSMichael J. Spencer // This file is distributed under the University of Illinois Open Source 68e90adafSMichael J. Spencer // License. See LICENSE.TXT for details. 78e90adafSMichael J. Spencer // 88e90adafSMichael J. Spencer //===----------------------------------------------------------------------===// 98e90adafSMichael J. Spencer // 108e90adafSMichael J. Spencer // This file declares the COFFObjectFile class. 118e90adafSMichael J. Spencer // 128e90adafSMichael J. Spencer //===----------------------------------------------------------------------===// 138e90adafSMichael J. Spencer 148e90adafSMichael J. Spencer #include "llvm/ADT/StringSwitch.h" 158e90adafSMichael J. Spencer #include "llvm/ADT/Triple.h" 168e90adafSMichael J. Spencer #include "llvm/Object/ObjectFile.h" 178e90adafSMichael J. Spencer #include "llvm/Support/COFF.h" 188e90adafSMichael J. Spencer #include "llvm/Support/Endian.h" 198e90adafSMichael J. Spencer 208e90adafSMichael J. Spencer using namespace llvm; 218e90adafSMichael J. Spencer using namespace object; 228e90adafSMichael J. Spencer 238e90adafSMichael J. Spencer namespace { 248e90adafSMichael J. Spencer using support::ulittle8_t; 258e90adafSMichael J. Spencer using support::ulittle16_t; 268e90adafSMichael J. Spencer using support::ulittle32_t; 278e90adafSMichael J. Spencer using support::little16_t; 288e90adafSMichael J. Spencer } 298e90adafSMichael J. Spencer 308e90adafSMichael J. Spencer namespace { 318e90adafSMichael J. Spencer struct coff_file_header { 328e90adafSMichael J. Spencer ulittle16_t Machine; 338e90adafSMichael J. Spencer ulittle16_t NumberOfSections; 348e90adafSMichael J. Spencer ulittle32_t TimeDateStamp; 358e90adafSMichael J. Spencer ulittle32_t PointerToSymbolTable; 368e90adafSMichael J. Spencer ulittle32_t NumberOfSymbols; 378e90adafSMichael J. Spencer ulittle16_t SizeOfOptionalHeader; 388e90adafSMichael J. Spencer ulittle16_t Characteristics; 398e90adafSMichael J. Spencer }; 408e90adafSMichael J. Spencer } 418e90adafSMichael J. Spencer 428e90adafSMichael J. Spencer extern char coff_file_header_layout_static_assert 438e90adafSMichael J. Spencer [sizeof(coff_file_header) == 20 ? 1 : -1]; 448e90adafSMichael J. Spencer 458e90adafSMichael J. Spencer namespace { 468e90adafSMichael J. Spencer struct coff_symbol { 478e90adafSMichael J. Spencer struct StringTableOffset { 488e90adafSMichael J. Spencer ulittle32_t Zeroes; 498e90adafSMichael J. Spencer ulittle32_t Offset; 508e90adafSMichael J. Spencer }; 518e90adafSMichael J. Spencer 528e90adafSMichael J. Spencer union { 538e90adafSMichael J. Spencer char ShortName[8]; 548e90adafSMichael J. Spencer StringTableOffset Offset; 558e90adafSMichael J. Spencer } Name; 568e90adafSMichael J. Spencer 578e90adafSMichael J. Spencer ulittle32_t Value; 588e90adafSMichael J. Spencer little16_t SectionNumber; 598e90adafSMichael J. Spencer 608e90adafSMichael J. Spencer struct { 618e90adafSMichael J. Spencer ulittle8_t BaseType; 628e90adafSMichael J. Spencer ulittle8_t ComplexType; 638e90adafSMichael J. Spencer } Type; 648e90adafSMichael J. Spencer 658e90adafSMichael J. Spencer ulittle8_t StorageClass; 668e90adafSMichael J. Spencer ulittle8_t NumberOfAuxSymbols; 678e90adafSMichael J. Spencer }; 688e90adafSMichael J. Spencer } 698e90adafSMichael J. Spencer 708e90adafSMichael J. Spencer extern char coff_coff_symbol_layout_static_assert 718e90adafSMichael J. Spencer [sizeof(coff_symbol) == 18 ? 1 : -1]; 728e90adafSMichael J. Spencer 738e90adafSMichael J. Spencer namespace { 748e90adafSMichael J. Spencer struct coff_section { 758e90adafSMichael J. Spencer char Name[8]; 768e90adafSMichael J. Spencer ulittle32_t VirtualSize; 778e90adafSMichael J. Spencer ulittle32_t VirtualAddress; 788e90adafSMichael J. Spencer ulittle32_t SizeOfRawData; 798e90adafSMichael J. Spencer ulittle32_t PointerToRawData; 808e90adafSMichael J. Spencer ulittle32_t PointerToRelocations; 818e90adafSMichael J. Spencer ulittle32_t PointerToLinenumbers; 828e90adafSMichael J. Spencer ulittle16_t NumberOfRelocations; 838e90adafSMichael J. Spencer ulittle16_t NumberOfLinenumbers; 848e90adafSMichael J. Spencer ulittle32_t Characteristics; 858e90adafSMichael J. Spencer }; 868e90adafSMichael J. Spencer } 878e90adafSMichael J. Spencer 888e90adafSMichael J. Spencer extern char coff_coff_section_layout_static_assert 898e90adafSMichael J. Spencer [sizeof(coff_section) == 40 ? 1 : -1]; 908e90adafSMichael J. Spencer 918e90adafSMichael J. Spencer namespace { 928e90adafSMichael J. Spencer class COFFObjectFile : public ObjectFile { 938e90adafSMichael J. Spencer private: 94ee066fc4SEric Christopher uint64_t HeaderOff; 958e90adafSMichael J. Spencer const coff_file_header *Header; 968e90adafSMichael J. Spencer const coff_section *SectionTable; 978e90adafSMichael J. Spencer const coff_symbol *SymbolTable; 988e90adafSMichael J. Spencer const char *StringTable; 998e90adafSMichael J. Spencer 1008e90adafSMichael J. Spencer const coff_section *getSection(std::size_t index) const; 1018e90adafSMichael J. Spencer const char *getString(std::size_t offset) const; 1028e90adafSMichael J. Spencer 1038e90adafSMichael J. Spencer protected: 1048e90adafSMichael J. Spencer virtual SymbolRef getSymbolNext(DataRefImpl Symb) const; 1058e90adafSMichael J. Spencer virtual StringRef getSymbolName(DataRefImpl Symb) const; 1068e90adafSMichael J. Spencer virtual uint64_t getSymbolAddress(DataRefImpl Symb) const; 1078e90adafSMichael J. Spencer virtual uint64_t getSymbolSize(DataRefImpl Symb) const; 1088e90adafSMichael J. Spencer virtual char getSymbolNMTypeChar(DataRefImpl Symb) const; 1098e90adafSMichael J. Spencer virtual bool isSymbolInternal(DataRefImpl Symb) const; 1108e90adafSMichael J. Spencer 1118e90adafSMichael J. Spencer virtual SectionRef getSectionNext(DataRefImpl Sec) const; 1128e90adafSMichael J. Spencer virtual StringRef getSectionName(DataRefImpl Sec) const; 1138e90adafSMichael J. Spencer virtual uint64_t getSectionAddress(DataRefImpl Sec) const; 1148e90adafSMichael J. Spencer virtual uint64_t getSectionSize(DataRefImpl Sec) const; 1158e90adafSMichael J. Spencer virtual StringRef getSectionContents(DataRefImpl Sec) const; 1168e90adafSMichael J. Spencer virtual bool isSectionText(DataRefImpl Sec) const; 1178e90adafSMichael J. Spencer 1188e90adafSMichael J. Spencer public: 1198e90adafSMichael J. Spencer COFFObjectFile(MemoryBuffer *Object); 1208e90adafSMichael J. Spencer virtual symbol_iterator begin_symbols() const; 1218e90adafSMichael J. Spencer virtual symbol_iterator end_symbols() const; 1228e90adafSMichael J. Spencer virtual section_iterator begin_sections() const; 1238e90adafSMichael J. Spencer virtual section_iterator end_sections() const; 1248e90adafSMichael J. Spencer 1258e90adafSMichael J. Spencer virtual uint8_t getBytesInAddress() const; 1268e90adafSMichael J. Spencer virtual StringRef getFileFormatName() const; 1278e90adafSMichael J. Spencer virtual unsigned getArch() const; 1288e90adafSMichael J. Spencer }; 1298e90adafSMichael J. Spencer } // end namespace 1308e90adafSMichael J. Spencer 1318e90adafSMichael J. Spencer SymbolRef COFFObjectFile::getSymbolNext(DataRefImpl Symb) const { 1320324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1338e90adafSMichael J. Spencer symb += 1 + symb->NumberOfAuxSymbols; 1340324b672SMichael J. Spencer Symb.p = reinterpret_cast<intptr_t>(symb); 1350324b672SMichael J. Spencer return SymbolRef(Symb, this); 1368e90adafSMichael J. Spencer } 1378e90adafSMichael J. Spencer 1388e90adafSMichael J. Spencer StringRef COFFObjectFile::getSymbolName(DataRefImpl Symb) const { 1390324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1408e90adafSMichael J. Spencer // Check for string table entry. First 4 bytes are 0. 1418e90adafSMichael J. Spencer if (symb->Name.Offset.Zeroes == 0) { 1428e90adafSMichael J. Spencer uint32_t Offset = symb->Name.Offset.Offset; 1438e90adafSMichael J. Spencer return StringRef(getString(Offset)); 1448e90adafSMichael J. Spencer } 1458e90adafSMichael J. Spencer 1468e90adafSMichael J. Spencer if (symb->Name.ShortName[7] == 0) 1478e90adafSMichael J. Spencer // Null terminated, let ::strlen figure out the length. 1488e90adafSMichael J. Spencer return StringRef(symb->Name.ShortName); 1498e90adafSMichael J. Spencer // Not null terminated, use all 8 bytes. 1508e90adafSMichael J. Spencer return StringRef(symb->Name.ShortName, 8); 1518e90adafSMichael J. Spencer } 1528e90adafSMichael J. Spencer 1538e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSymbolAddress(DataRefImpl Symb) const { 1540324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1558e90adafSMichael J. Spencer const coff_section *Section = getSection(symb->SectionNumber); 1568e90adafSMichael J. Spencer char Type = getSymbolNMTypeChar(Symb); 1578e90adafSMichael J. Spencer if (Type == 'U' || Type == 'w') 1588e90adafSMichael J. Spencer return UnknownAddressOrSize; 1598e90adafSMichael J. Spencer if (Section) 1608e90adafSMichael J. Spencer return Section->VirtualAddress + symb->Value; 1618e90adafSMichael J. Spencer return symb->Value; 1628e90adafSMichael J. Spencer } 1638e90adafSMichael J. Spencer 1648e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSymbolSize(DataRefImpl Symb) const { 1658e90adafSMichael J. Spencer // FIXME: Return the correct size. This requires looking at all the symbols 1668e90adafSMichael J. Spencer // in the same section as this symbol, and looking for either the next 1678e90adafSMichael J. Spencer // symbol, or the end of the section. 1680324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1698e90adafSMichael J. Spencer const coff_section *Section = getSection(symb->SectionNumber); 1708e90adafSMichael J. Spencer char Type = getSymbolNMTypeChar(Symb); 1718e90adafSMichael J. Spencer if (Type == 'U' || Type == 'w') 1728e90adafSMichael J. Spencer return UnknownAddressOrSize; 1738e90adafSMichael J. Spencer if (Section) 1748e90adafSMichael J. Spencer return Section->SizeOfRawData - symb->Value; 1758e90adafSMichael J. Spencer return 0; 1768e90adafSMichael J. Spencer } 1778e90adafSMichael J. Spencer 1788e90adafSMichael J. Spencer char COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb) const { 1790324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1808e90adafSMichael J. Spencer char ret = StringSwitch<char>(getSymbolName(Symb)) 1818e90adafSMichael J. Spencer .StartsWith(".debug", 'N') 1828e90adafSMichael J. Spencer .StartsWith(".sxdata", 'N') 1838e90adafSMichael J. Spencer .Default('?'); 1848e90adafSMichael J. Spencer 1858e90adafSMichael J. Spencer if (ret != '?') 1868e90adafSMichael J. Spencer return ret; 1878e90adafSMichael J. Spencer 1888e90adafSMichael J. Spencer uint32_t Characteristics = 0; 189*5f1eb968SNick Lewycky if (const coff_section *Section = getSection(symb->SectionNumber)) { 1908e90adafSMichael J. Spencer Characteristics = Section->Characteristics; 1918e90adafSMichael J. Spencer } 1928e90adafSMichael J. Spencer 1938e90adafSMichael J. Spencer switch (symb->SectionNumber) { 1948e90adafSMichael J. Spencer case COFF::IMAGE_SYM_UNDEFINED: 1958e90adafSMichael J. Spencer // Check storage classes. 1968e90adafSMichael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 1978e90adafSMichael J. Spencer return 'w'; // Don't do ::toupper. 1988e90adafSMichael J. Spencer else 1998e90adafSMichael J. Spencer ret = 'u'; 2008e90adafSMichael J. Spencer break; 2018e90adafSMichael J. Spencer case COFF::IMAGE_SYM_ABSOLUTE: 2028e90adafSMichael J. Spencer ret = 'a'; 2038e90adafSMichael J. Spencer break; 2048e90adafSMichael J. Spencer case COFF::IMAGE_SYM_DEBUG: 2058e90adafSMichael J. Spencer ret = 'n'; 2068e90adafSMichael J. Spencer break; 2078e90adafSMichael J. Spencer default: 2088e90adafSMichael J. Spencer // Check section type. 2098e90adafSMichael J. Spencer if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 2108e90adafSMichael J. Spencer ret = 't'; 2118e90adafSMichael J. Spencer else if ( Characteristics & COFF::IMAGE_SCN_MEM_READ 2128e90adafSMichael J. Spencer && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 2138e90adafSMichael J. Spencer ret = 'r'; 2148e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 2158e90adafSMichael J. Spencer ret = 'd'; 2168e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 2178e90adafSMichael J. Spencer ret = 'b'; 2188e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 2198e90adafSMichael J. Spencer ret = 'i'; 2208e90adafSMichael J. Spencer 2218e90adafSMichael J. Spencer // Check for section symbol. 2228e90adafSMichael J. Spencer else if ( symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC 2238e90adafSMichael J. Spencer && symb->Value == 0) 2248e90adafSMichael J. Spencer ret = 's'; 2258e90adafSMichael J. Spencer } 2268e90adafSMichael J. Spencer 2278e90adafSMichael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 2288e90adafSMichael J. Spencer ret = ::toupper(ret); 2298e90adafSMichael J. Spencer 2308e90adafSMichael J. Spencer return ret; 2318e90adafSMichael J. Spencer } 2328e90adafSMichael J. Spencer 2338e90adafSMichael J. Spencer bool COFFObjectFile::isSymbolInternal(DataRefImpl Symb) const { 2348e90adafSMichael J. Spencer return false; 2358e90adafSMichael J. Spencer } 2368e90adafSMichael J. Spencer 2378e90adafSMichael J. Spencer SectionRef COFFObjectFile::getSectionNext(DataRefImpl Sec) const { 2380324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2398e90adafSMichael J. Spencer sec += 1; 2400324b672SMichael J. Spencer Sec.p = reinterpret_cast<intptr_t>(sec); 2410324b672SMichael J. Spencer return SectionRef(Sec, this); 2428e90adafSMichael J. Spencer } 2438e90adafSMichael J. Spencer 2448e90adafSMichael J. Spencer StringRef COFFObjectFile::getSectionName(DataRefImpl Sec) const { 2450324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2468e90adafSMichael J. Spencer StringRef name; 2478e90adafSMichael J. Spencer if (sec->Name[7] == 0) 2488e90adafSMichael J. Spencer // Null terminated, let ::strlen figure out the length. 2498e90adafSMichael J. Spencer name = sec->Name; 2508e90adafSMichael J. Spencer else 2518e90adafSMichael J. Spencer // Not null terminated, use all 8 bytes. 2528e90adafSMichael J. Spencer name = StringRef(sec->Name, 8); 2538e90adafSMichael J. Spencer 2548e90adafSMichael J. Spencer // Check for string table entry. First byte is '/'. 2558e90adafSMichael J. Spencer if (name[0] == '/') { 2568e90adafSMichael J. Spencer uint32_t Offset; 257ee066fc4SEric Christopher name.substr(1).getAsInteger(10, Offset); 2588e90adafSMichael J. Spencer return StringRef(getString(Offset)); 2598e90adafSMichael J. Spencer } 2608e90adafSMichael J. Spencer 2618e90adafSMichael J. Spencer // It's just a normal name. 2628e90adafSMichael J. Spencer return name; 2638e90adafSMichael J. Spencer } 2648e90adafSMichael J. Spencer 2658e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Sec) const { 2660324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2678e90adafSMichael J. Spencer return sec->VirtualAddress; 2688e90adafSMichael J. Spencer } 2698e90adafSMichael J. Spencer 2708e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSectionSize(DataRefImpl Sec) const { 2710324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2728e90adafSMichael J. Spencer return sec->SizeOfRawData; 2738e90adafSMichael J. Spencer } 2748e90adafSMichael J. Spencer 2758e90adafSMichael J. Spencer StringRef COFFObjectFile::getSectionContents(DataRefImpl Sec) const { 2760324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2778e90adafSMichael J. Spencer return StringRef(reinterpret_cast<const char *>(base + sec->PointerToRawData), 2788e90adafSMichael J. Spencer sec->SizeOfRawData); 2798e90adafSMichael J. Spencer } 2808e90adafSMichael J. Spencer 2818e90adafSMichael J. Spencer bool COFFObjectFile::isSectionText(DataRefImpl Sec) const { 2820324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2838e90adafSMichael J. Spencer return sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 2848e90adafSMichael J. Spencer } 2858e90adafSMichael J. Spencer 2868e90adafSMichael J. Spencer COFFObjectFile::COFFObjectFile(MemoryBuffer *Object) 2878e90adafSMichael J. Spencer : ObjectFile(Object) { 288ee066fc4SEric Christopher 289ee066fc4SEric Christopher HeaderOff = 0; 290ee066fc4SEric Christopher 291ee066fc4SEric Christopher if (base[0] == 0x4d && base[1] == 0x5a) { 292ee066fc4SEric Christopher // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 293ee066fc4SEric Christopher // PE signature to find 'normal' COFF header. 294ee066fc4SEric Christopher HeaderOff += *reinterpret_cast<const ulittle32_t *>(base + 0x3c); 295ee066fc4SEric Christopher HeaderOff += 4; 296ee066fc4SEric Christopher } 297ee066fc4SEric Christopher 298ee066fc4SEric Christopher Header = reinterpret_cast<const coff_file_header *>(base + HeaderOff); 2998e90adafSMichael J. Spencer SectionTable = 3008e90adafSMichael J. Spencer reinterpret_cast<const coff_section *>( base 301ee066fc4SEric Christopher + HeaderOff 3028e90adafSMichael J. Spencer + sizeof(coff_file_header) 3038e90adafSMichael J. Spencer + Header->SizeOfOptionalHeader); 3048e90adafSMichael J. Spencer SymbolTable = 3058e90adafSMichael J. Spencer reinterpret_cast<const coff_symbol *>(base + Header->PointerToSymbolTable); 3068e90adafSMichael J. Spencer 3078e90adafSMichael J. Spencer // Find string table. 3088e90adafSMichael J. Spencer StringTable = reinterpret_cast<const char *>(base) 3098e90adafSMichael J. Spencer + Header->PointerToSymbolTable 3108e90adafSMichael J. Spencer + Header->NumberOfSymbols * 18; 3118e90adafSMichael J. Spencer } 3128e90adafSMichael J. Spencer 3138e90adafSMichael J. Spencer ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { 3140324b672SMichael J. Spencer DataRefImpl ret; 315ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3160324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SymbolTable); 3170324b672SMichael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 3188e90adafSMichael J. Spencer } 3198e90adafSMichael J. Spencer 3208e90adafSMichael J. Spencer ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { 3218e90adafSMichael J. Spencer // The symbol table ends where the string table begins. 3220324b672SMichael J. Spencer DataRefImpl ret; 323ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3240324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(StringTable); 3250324b672SMichael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 3268e90adafSMichael J. Spencer } 3278e90adafSMichael J. Spencer 3288e90adafSMichael J. Spencer ObjectFile::section_iterator COFFObjectFile::begin_sections() const { 3290324b672SMichael J. Spencer DataRefImpl ret; 330ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3310324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable); 3320324b672SMichael J. Spencer return section_iterator(SectionRef(ret, this)); 3338e90adafSMichael J. Spencer } 3348e90adafSMichael J. Spencer 3358e90adafSMichael J. Spencer ObjectFile::section_iterator COFFObjectFile::end_sections() const { 3360324b672SMichael J. Spencer DataRefImpl ret; 337ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3380324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections); 3390324b672SMichael J. Spencer return section_iterator(SectionRef(ret, this)); 3408e90adafSMichael J. Spencer } 3418e90adafSMichael J. Spencer 3428e90adafSMichael J. Spencer uint8_t COFFObjectFile::getBytesInAddress() const { 3430324b672SMichael J. Spencer return getArch() == Triple::x86_64 ? 8 : 4; 3448e90adafSMichael J. Spencer } 3458e90adafSMichael J. Spencer 3468e90adafSMichael J. Spencer StringRef COFFObjectFile::getFileFormatName() const { 3478e90adafSMichael J. Spencer switch(Header->Machine) { 3488e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 3498e90adafSMichael J. Spencer return "COFF-i386"; 3508e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 3518e90adafSMichael J. Spencer return "COFF-x86-64"; 3528e90adafSMichael J. Spencer default: 3538e90adafSMichael J. Spencer return "COFF-<unknown arch>"; 3548e90adafSMichael J. Spencer } 3558e90adafSMichael J. Spencer } 3568e90adafSMichael J. Spencer 3578e90adafSMichael J. Spencer unsigned COFFObjectFile::getArch() const { 3588e90adafSMichael J. Spencer switch(Header->Machine) { 3598e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 3608e90adafSMichael J. Spencer return Triple::x86; 3618e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 3628e90adafSMichael J. Spencer return Triple::x86_64; 3638e90adafSMichael J. Spencer default: 3648e90adafSMichael J. Spencer return Triple::UnknownArch; 3658e90adafSMichael J. Spencer } 3668e90adafSMichael J. Spencer } 3678e90adafSMichael J. Spencer 3688e90adafSMichael J. Spencer const coff_section *COFFObjectFile::getSection(std::size_t index) const { 3698e90adafSMichael J. Spencer if (index > 0 && index <= Header->NumberOfSections) 3708e90adafSMichael J. Spencer return SectionTable + (index - 1); 3718e90adafSMichael J. Spencer return 0; 3728e90adafSMichael J. Spencer } 3738e90adafSMichael J. Spencer 3748e90adafSMichael J. Spencer const char *COFFObjectFile::getString(std::size_t offset) const { 3758e90adafSMichael J. Spencer const ulittle32_t *StringTableSize = 3768e90adafSMichael J. Spencer reinterpret_cast<const ulittle32_t *>(StringTable); 3778e90adafSMichael J. Spencer if (offset < *StringTableSize) 3788e90adafSMichael J. Spencer return StringTable + offset; 3798e90adafSMichael J. Spencer return 0; 3808e90adafSMichael J. Spencer } 3818e90adafSMichael J. Spencer 3828e90adafSMichael J. Spencer namespace llvm { 3838e90adafSMichael J. Spencer 3848e90adafSMichael J. Spencer ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { 3858e90adafSMichael J. Spencer return new COFFObjectFile(Object); 3868e90adafSMichael J. Spencer } 3878e90adafSMichael J. Spencer 3888e90adafSMichael J. Spencer } // end namespace llvm 389