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: 94*ee066fc4SEric 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; 1898e90adafSMichael J. Spencer uint32_t PointerToRawData = 0; 1908e90adafSMichael J. Spencer const coff_section *Section = getSection(symb->SectionNumber); 1918e90adafSMichael J. Spencer if (Section) { 1928e90adafSMichael J. Spencer Characteristics = Section->Characteristics; 1938e90adafSMichael J. Spencer PointerToRawData = Section->PointerToRawData; 1948e90adafSMichael J. Spencer } 1958e90adafSMichael J. Spencer 1968e90adafSMichael J. Spencer switch (symb->SectionNumber) { 1978e90adafSMichael J. Spencer case COFF::IMAGE_SYM_UNDEFINED: 1988e90adafSMichael J. Spencer // Check storage classes. 1998e90adafSMichael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 2008e90adafSMichael J. Spencer return 'w'; // Don't do ::toupper. 2018e90adafSMichael J. Spencer else 2028e90adafSMichael J. Spencer ret = 'u'; 2038e90adafSMichael J. Spencer break; 2048e90adafSMichael J. Spencer case COFF::IMAGE_SYM_ABSOLUTE: 2058e90adafSMichael J. Spencer ret = 'a'; 2068e90adafSMichael J. Spencer break; 2078e90adafSMichael J. Spencer case COFF::IMAGE_SYM_DEBUG: 2088e90adafSMichael J. Spencer ret = 'n'; 2098e90adafSMichael J. Spencer break; 2108e90adafSMichael J. Spencer default: 2118e90adafSMichael J. Spencer // Check section type. 2128e90adafSMichael J. Spencer if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 2138e90adafSMichael J. Spencer ret = 't'; 2148e90adafSMichael J. Spencer else if ( Characteristics & COFF::IMAGE_SCN_MEM_READ 2158e90adafSMichael J. Spencer && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 2168e90adafSMichael J. Spencer ret = 'r'; 2178e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 2188e90adafSMichael J. Spencer ret = 'd'; 2198e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 2208e90adafSMichael J. Spencer ret = 'b'; 2218e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 2228e90adafSMichael J. Spencer ret = 'i'; 2238e90adafSMichael J. Spencer 2248e90adafSMichael J. Spencer // Check for section symbol. 2258e90adafSMichael J. Spencer else if ( symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC 2268e90adafSMichael J. Spencer && symb->Value == 0) 2278e90adafSMichael J. Spencer ret = 's'; 2288e90adafSMichael J. Spencer } 2298e90adafSMichael J. Spencer 2308e90adafSMichael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 2318e90adafSMichael J. Spencer ret = ::toupper(ret); 2328e90adafSMichael J. Spencer 2338e90adafSMichael J. Spencer return ret; 2348e90adafSMichael J. Spencer } 2358e90adafSMichael J. Spencer 2368e90adafSMichael J. Spencer bool COFFObjectFile::isSymbolInternal(DataRefImpl Symb) const { 2378e90adafSMichael J. Spencer return false; 2388e90adafSMichael J. Spencer } 2398e90adafSMichael J. Spencer 2408e90adafSMichael J. Spencer SectionRef COFFObjectFile::getSectionNext(DataRefImpl Sec) const { 2410324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2428e90adafSMichael J. Spencer sec += 1; 2430324b672SMichael J. Spencer Sec.p = reinterpret_cast<intptr_t>(sec); 2440324b672SMichael J. Spencer return SectionRef(Sec, this); 2458e90adafSMichael J. Spencer } 2468e90adafSMichael J. Spencer 2478e90adafSMichael J. Spencer StringRef COFFObjectFile::getSectionName(DataRefImpl Sec) const { 2480324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2498e90adafSMichael J. Spencer StringRef name; 2508e90adafSMichael J. Spencer if (sec->Name[7] == 0) 2518e90adafSMichael J. Spencer // Null terminated, let ::strlen figure out the length. 2528e90adafSMichael J. Spencer name = sec->Name; 2538e90adafSMichael J. Spencer else 2548e90adafSMichael J. Spencer // Not null terminated, use all 8 bytes. 2558e90adafSMichael J. Spencer name = StringRef(sec->Name, 8); 2568e90adafSMichael J. Spencer 2578e90adafSMichael J. Spencer // Check for string table entry. First byte is '/'. 2588e90adafSMichael J. Spencer if (name[0] == '/') { 2598e90adafSMichael J. Spencer uint32_t Offset; 260*ee066fc4SEric Christopher name.substr(1).getAsInteger(10, Offset); 2618e90adafSMichael J. Spencer return StringRef(getString(Offset)); 2628e90adafSMichael J. Spencer } 2638e90adafSMichael J. Spencer 2648e90adafSMichael J. Spencer // It's just a normal name. 2658e90adafSMichael J. Spencer return name; 2668e90adafSMichael J. Spencer } 2678e90adafSMichael J. Spencer 2688e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Sec) const { 2690324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2708e90adafSMichael J. Spencer return sec->VirtualAddress; 2718e90adafSMichael J. Spencer } 2728e90adafSMichael J. Spencer 2738e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSectionSize(DataRefImpl Sec) const { 2740324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2758e90adafSMichael J. Spencer return sec->SizeOfRawData; 2768e90adafSMichael J. Spencer } 2778e90adafSMichael J. Spencer 2788e90adafSMichael J. Spencer StringRef COFFObjectFile::getSectionContents(DataRefImpl Sec) const { 2790324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2808e90adafSMichael J. Spencer return StringRef(reinterpret_cast<const char *>(base + sec->PointerToRawData), 2818e90adafSMichael J. Spencer sec->SizeOfRawData); 2828e90adafSMichael J. Spencer } 2838e90adafSMichael J. Spencer 2848e90adafSMichael J. Spencer bool COFFObjectFile::isSectionText(DataRefImpl Sec) const { 2850324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2868e90adafSMichael J. Spencer return sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 2878e90adafSMichael J. Spencer } 2888e90adafSMichael J. Spencer 2898e90adafSMichael J. Spencer COFFObjectFile::COFFObjectFile(MemoryBuffer *Object) 2908e90adafSMichael J. Spencer : ObjectFile(Object) { 291*ee066fc4SEric Christopher 292*ee066fc4SEric Christopher HeaderOff = 0; 293*ee066fc4SEric Christopher 294*ee066fc4SEric Christopher if (base[0] == 0x4d && base[1] == 0x5a) { 295*ee066fc4SEric Christopher // PE/COFF, seek through MS-DOS compatibility stub and 4-byte 296*ee066fc4SEric Christopher // PE signature to find 'normal' COFF header. 297*ee066fc4SEric Christopher HeaderOff += *reinterpret_cast<const ulittle32_t *>(base + 0x3c); 298*ee066fc4SEric Christopher HeaderOff += 4; 299*ee066fc4SEric Christopher } 300*ee066fc4SEric Christopher 301*ee066fc4SEric Christopher Header = reinterpret_cast<const coff_file_header *>(base + HeaderOff); 3028e90adafSMichael J. Spencer SectionTable = 3038e90adafSMichael J. Spencer reinterpret_cast<const coff_section *>( base 304*ee066fc4SEric Christopher + HeaderOff 3058e90adafSMichael J. Spencer + sizeof(coff_file_header) 3068e90adafSMichael J. Spencer + Header->SizeOfOptionalHeader); 3078e90adafSMichael J. Spencer SymbolTable = 3088e90adafSMichael J. Spencer reinterpret_cast<const coff_symbol *>(base + Header->PointerToSymbolTable); 3098e90adafSMichael J. Spencer 3108e90adafSMichael J. Spencer // Find string table. 3118e90adafSMichael J. Spencer StringTable = reinterpret_cast<const char *>(base) 3128e90adafSMichael J. Spencer + Header->PointerToSymbolTable 3138e90adafSMichael J. Spencer + Header->NumberOfSymbols * 18; 3148e90adafSMichael J. Spencer } 3158e90adafSMichael J. Spencer 3168e90adafSMichael J. Spencer ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { 3170324b672SMichael J. Spencer DataRefImpl ret; 318*ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3190324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SymbolTable); 3200324b672SMichael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 3218e90adafSMichael J. Spencer } 3228e90adafSMichael J. Spencer 3238e90adafSMichael J. Spencer ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { 3248e90adafSMichael J. Spencer // The symbol table ends where the string table begins. 3250324b672SMichael J. Spencer DataRefImpl ret; 326*ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3270324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(StringTable); 3280324b672SMichael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 3298e90adafSMichael J. Spencer } 3308e90adafSMichael J. Spencer 3318e90adafSMichael J. Spencer ObjectFile::section_iterator COFFObjectFile::begin_sections() const { 3320324b672SMichael J. Spencer DataRefImpl ret; 333*ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3340324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable); 3350324b672SMichael J. Spencer return section_iterator(SectionRef(ret, this)); 3368e90adafSMichael J. Spencer } 3378e90adafSMichael J. Spencer 3388e90adafSMichael J. Spencer ObjectFile::section_iterator COFFObjectFile::end_sections() const { 3390324b672SMichael J. Spencer DataRefImpl ret; 340*ee066fc4SEric Christopher memset(&ret, 0, sizeof(DataRefImpl)); 3410324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections); 3420324b672SMichael J. Spencer return section_iterator(SectionRef(ret, this)); 3438e90adafSMichael J. Spencer } 3448e90adafSMichael J. Spencer 3458e90adafSMichael J. Spencer uint8_t COFFObjectFile::getBytesInAddress() const { 3460324b672SMichael J. Spencer return getArch() == Triple::x86_64 ? 8 : 4; 3478e90adafSMichael J. Spencer } 3488e90adafSMichael J. Spencer 3498e90adafSMichael J. Spencer StringRef COFFObjectFile::getFileFormatName() const { 3508e90adafSMichael J. Spencer switch(Header->Machine) { 3518e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 3528e90adafSMichael J. Spencer return "COFF-i386"; 3538e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 3548e90adafSMichael J. Spencer return "COFF-x86-64"; 3558e90adafSMichael J. Spencer default: 3568e90adafSMichael J. Spencer return "COFF-<unknown arch>"; 3578e90adafSMichael J. Spencer } 3588e90adafSMichael J. Spencer } 3598e90adafSMichael J. Spencer 3608e90adafSMichael J. Spencer unsigned COFFObjectFile::getArch() const { 3618e90adafSMichael J. Spencer switch(Header->Machine) { 3628e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 3638e90adafSMichael J. Spencer return Triple::x86; 3648e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 3658e90adafSMichael J. Spencer return Triple::x86_64; 3668e90adafSMichael J. Spencer default: 3678e90adafSMichael J. Spencer return Triple::UnknownArch; 3688e90adafSMichael J. Spencer } 3698e90adafSMichael J. Spencer } 3708e90adafSMichael J. Spencer 3718e90adafSMichael J. Spencer const coff_section *COFFObjectFile::getSection(std::size_t index) const { 3728e90adafSMichael J. Spencer if (index > 0 && index <= Header->NumberOfSections) 3738e90adafSMichael J. Spencer return SectionTable + (index - 1); 3748e90adafSMichael J. Spencer return 0; 3758e90adafSMichael J. Spencer } 3768e90adafSMichael J. Spencer 3778e90adafSMichael J. Spencer const char *COFFObjectFile::getString(std::size_t offset) const { 3788e90adafSMichael J. Spencer const ulittle32_t *StringTableSize = 3798e90adafSMichael J. Spencer reinterpret_cast<const ulittle32_t *>(StringTable); 3808e90adafSMichael J. Spencer if (offset < *StringTableSize) 3818e90adafSMichael J. Spencer return StringTable + offset; 3828e90adafSMichael J. Spencer return 0; 3838e90adafSMichael J. Spencer } 3848e90adafSMichael J. Spencer 3858e90adafSMichael J. Spencer namespace llvm { 3868e90adafSMichael J. Spencer 3878e90adafSMichael J. Spencer ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { 3888e90adafSMichael J. Spencer return new COFFObjectFile(Object); 3898e90adafSMichael J. Spencer } 3908e90adafSMichael J. Spencer 3918e90adafSMichael J. Spencer } // end namespace llvm 392