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: 948e90adafSMichael J. Spencer const coff_file_header *Header; 958e90adafSMichael J. Spencer const coff_section *SectionTable; 968e90adafSMichael J. Spencer const coff_symbol *SymbolTable; 978e90adafSMichael J. Spencer const char *StringTable; 988e90adafSMichael J. Spencer 998e90adafSMichael J. Spencer const coff_section *getSection(std::size_t index) const; 1008e90adafSMichael J. Spencer const char *getString(std::size_t offset) const; 1018e90adafSMichael J. Spencer 1028e90adafSMichael J. Spencer protected: 1038e90adafSMichael J. Spencer virtual SymbolRef getSymbolNext(DataRefImpl Symb) const; 1048e90adafSMichael J. Spencer virtual StringRef getSymbolName(DataRefImpl Symb) const; 1058e90adafSMichael J. Spencer virtual uint64_t getSymbolAddress(DataRefImpl Symb) const; 1068e90adafSMichael J. Spencer virtual uint64_t getSymbolSize(DataRefImpl Symb) const; 1078e90adafSMichael J. Spencer virtual char getSymbolNMTypeChar(DataRefImpl Symb) const; 1088e90adafSMichael J. Spencer virtual bool isSymbolInternal(DataRefImpl Symb) const; 1098e90adafSMichael J. Spencer 1108e90adafSMichael J. Spencer virtual SectionRef getSectionNext(DataRefImpl Sec) const; 1118e90adafSMichael J. Spencer virtual StringRef getSectionName(DataRefImpl Sec) const; 1128e90adafSMichael J. Spencer virtual uint64_t getSectionAddress(DataRefImpl Sec) const; 1138e90adafSMichael J. Spencer virtual uint64_t getSectionSize(DataRefImpl Sec) const; 1148e90adafSMichael J. Spencer virtual StringRef getSectionContents(DataRefImpl Sec) const; 1158e90adafSMichael J. Spencer virtual bool isSectionText(DataRefImpl Sec) const; 1168e90adafSMichael J. Spencer 1178e90adafSMichael J. Spencer public: 1188e90adafSMichael J. Spencer COFFObjectFile(MemoryBuffer *Object); 1198e90adafSMichael J. Spencer virtual symbol_iterator begin_symbols() const; 1208e90adafSMichael J. Spencer virtual symbol_iterator end_symbols() const; 1218e90adafSMichael J. Spencer virtual section_iterator begin_sections() const; 1228e90adafSMichael J. Spencer virtual section_iterator end_sections() const; 1238e90adafSMichael J. Spencer 1248e90adafSMichael J. Spencer virtual uint8_t getBytesInAddress() const; 1258e90adafSMichael J. Spencer virtual StringRef getFileFormatName() const; 1268e90adafSMichael J. Spencer virtual unsigned getArch() const; 1278e90adafSMichael J. Spencer }; 1288e90adafSMichael J. Spencer } // end namespace 1298e90adafSMichael J. Spencer 1308e90adafSMichael J. Spencer SymbolRef COFFObjectFile::getSymbolNext(DataRefImpl Symb) const { 131*0324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1328e90adafSMichael J. Spencer symb += 1 + symb->NumberOfAuxSymbols; 133*0324b672SMichael J. Spencer Symb.p = reinterpret_cast<intptr_t>(symb); 134*0324b672SMichael J. Spencer return SymbolRef(Symb, this); 1358e90adafSMichael J. Spencer } 1368e90adafSMichael J. Spencer 1378e90adafSMichael J. Spencer StringRef COFFObjectFile::getSymbolName(DataRefImpl Symb) const { 138*0324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1398e90adafSMichael J. Spencer // Check for string table entry. First 4 bytes are 0. 1408e90adafSMichael J. Spencer if (symb->Name.Offset.Zeroes == 0) { 1418e90adafSMichael J. Spencer uint32_t Offset = symb->Name.Offset.Offset; 1428e90adafSMichael J. Spencer return StringRef(getString(Offset)); 1438e90adafSMichael J. Spencer } 1448e90adafSMichael J. Spencer 1458e90adafSMichael J. Spencer if (symb->Name.ShortName[7] == 0) 1468e90adafSMichael J. Spencer // Null terminated, let ::strlen figure out the length. 1478e90adafSMichael J. Spencer return StringRef(symb->Name.ShortName); 1488e90adafSMichael J. Spencer // Not null terminated, use all 8 bytes. 1498e90adafSMichael J. Spencer return StringRef(symb->Name.ShortName, 8); 1508e90adafSMichael J. Spencer } 1518e90adafSMichael J. Spencer 1528e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSymbolAddress(DataRefImpl Symb) const { 153*0324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1548e90adafSMichael J. Spencer const coff_section *Section = getSection(symb->SectionNumber); 1558e90adafSMichael J. Spencer char Type = getSymbolNMTypeChar(Symb); 1568e90adafSMichael J. Spencer if (Type == 'U' || Type == 'w') 1578e90adafSMichael J. Spencer return UnknownAddressOrSize; 1588e90adafSMichael J. Spencer if (Section) 1598e90adafSMichael J. Spencer return Section->VirtualAddress + symb->Value; 1608e90adafSMichael J. Spencer return symb->Value; 1618e90adafSMichael J. Spencer } 1628e90adafSMichael J. Spencer 1638e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSymbolSize(DataRefImpl Symb) const { 1648e90adafSMichael J. Spencer // FIXME: Return the correct size. This requires looking at all the symbols 1658e90adafSMichael J. Spencer // in the same section as this symbol, and looking for either the next 1668e90adafSMichael J. Spencer // symbol, or the end of the section. 167*0324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1688e90adafSMichael J. Spencer const coff_section *Section = getSection(symb->SectionNumber); 1698e90adafSMichael J. Spencer char Type = getSymbolNMTypeChar(Symb); 1708e90adafSMichael J. Spencer if (Type == 'U' || Type == 'w') 1718e90adafSMichael J. Spencer return UnknownAddressOrSize; 1728e90adafSMichael J. Spencer if (Section) 1738e90adafSMichael J. Spencer return Section->SizeOfRawData - symb->Value; 1748e90adafSMichael J. Spencer return 0; 1758e90adafSMichael J. Spencer } 1768e90adafSMichael J. Spencer 1778e90adafSMichael J. Spencer char COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb) const { 178*0324b672SMichael J. Spencer const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); 1798e90adafSMichael J. Spencer char ret = StringSwitch<char>(getSymbolName(Symb)) 1808e90adafSMichael J. Spencer .StartsWith(".debug", 'N') 1818e90adafSMichael J. Spencer .StartsWith(".sxdata", 'N') 1828e90adafSMichael J. Spencer .Default('?'); 1838e90adafSMichael J. Spencer 1848e90adafSMichael J. Spencer if (ret != '?') 1858e90adafSMichael J. Spencer return ret; 1868e90adafSMichael J. Spencer 1878e90adafSMichael J. Spencer uint32_t Characteristics = 0; 1888e90adafSMichael J. Spencer uint32_t PointerToRawData = 0; 1898e90adafSMichael J. Spencer const coff_section *Section = getSection(symb->SectionNumber); 1908e90adafSMichael J. Spencer if (Section) { 1918e90adafSMichael J. Spencer Characteristics = Section->Characteristics; 1928e90adafSMichael J. Spencer PointerToRawData = Section->PointerToRawData; 1938e90adafSMichael J. Spencer } 1948e90adafSMichael J. Spencer 1958e90adafSMichael J. Spencer switch (symb->SectionNumber) { 1968e90adafSMichael J. Spencer case COFF::IMAGE_SYM_UNDEFINED: 1978e90adafSMichael J. Spencer // Check storage classes. 1988e90adafSMichael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) 1998e90adafSMichael J. Spencer return 'w'; // Don't do ::toupper. 2008e90adafSMichael J. Spencer else 2018e90adafSMichael J. Spencer ret = 'u'; 2028e90adafSMichael J. Spencer break; 2038e90adafSMichael J. Spencer case COFF::IMAGE_SYM_ABSOLUTE: 2048e90adafSMichael J. Spencer ret = 'a'; 2058e90adafSMichael J. Spencer break; 2068e90adafSMichael J. Spencer case COFF::IMAGE_SYM_DEBUG: 2078e90adafSMichael J. Spencer ret = 'n'; 2088e90adafSMichael J. Spencer break; 2098e90adafSMichael J. Spencer default: 2108e90adafSMichael J. Spencer // Check section type. 2118e90adafSMichael J. Spencer if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 2128e90adafSMichael J. Spencer ret = 't'; 2138e90adafSMichael J. Spencer else if ( Characteristics & COFF::IMAGE_SCN_MEM_READ 2148e90adafSMichael J. Spencer && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 2158e90adafSMichael J. Spencer ret = 'r'; 2168e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 2178e90adafSMichael J. Spencer ret = 'd'; 2188e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 2198e90adafSMichael J. Spencer ret = 'b'; 2208e90adafSMichael J. Spencer else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 2218e90adafSMichael J. Spencer ret = 'i'; 2228e90adafSMichael J. Spencer 2238e90adafSMichael J. Spencer // Check for section symbol. 2248e90adafSMichael J. Spencer else if ( symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC 2258e90adafSMichael J. Spencer && symb->Value == 0) 2268e90adafSMichael J. Spencer ret = 's'; 2278e90adafSMichael J. Spencer } 2288e90adafSMichael J. Spencer 2298e90adafSMichael J. Spencer if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) 2308e90adafSMichael J. Spencer ret = ::toupper(ret); 2318e90adafSMichael J. Spencer 2328e90adafSMichael J. Spencer return ret; 2338e90adafSMichael J. Spencer } 2348e90adafSMichael J. Spencer 2358e90adafSMichael J. Spencer bool COFFObjectFile::isSymbolInternal(DataRefImpl Symb) const { 2368e90adafSMichael J. Spencer return false; 2378e90adafSMichael J. Spencer } 2388e90adafSMichael J. Spencer 2398e90adafSMichael J. Spencer SectionRef COFFObjectFile::getSectionNext(DataRefImpl Sec) const { 240*0324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2418e90adafSMichael J. Spencer sec += 1; 242*0324b672SMichael J. Spencer Sec.p = reinterpret_cast<intptr_t>(sec); 243*0324b672SMichael J. Spencer return SectionRef(Sec, this); 2448e90adafSMichael J. Spencer } 2458e90adafSMichael J. Spencer 2468e90adafSMichael J. Spencer StringRef COFFObjectFile::getSectionName(DataRefImpl Sec) const { 247*0324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2488e90adafSMichael J. Spencer StringRef name; 2498e90adafSMichael J. Spencer if (sec->Name[7] == 0) 2508e90adafSMichael J. Spencer // Null terminated, let ::strlen figure out the length. 2518e90adafSMichael J. Spencer name = sec->Name; 2528e90adafSMichael J. Spencer else 2538e90adafSMichael J. Spencer // Not null terminated, use all 8 bytes. 2548e90adafSMichael J. Spencer name = StringRef(sec->Name, 8); 2558e90adafSMichael J. Spencer 2568e90adafSMichael J. Spencer // Check for string table entry. First byte is '/'. 2578e90adafSMichael J. Spencer if (name[0] == '/') { 2588e90adafSMichael J. Spencer uint32_t Offset; 2598e90adafSMichael J. Spencer name.getAsInteger(10, Offset); 2608e90adafSMichael J. Spencer return StringRef(getString(Offset)); 2618e90adafSMichael J. Spencer } 2628e90adafSMichael J. Spencer 2638e90adafSMichael J. Spencer // It's just a normal name. 2648e90adafSMichael J. Spencer return name; 2658e90adafSMichael J. Spencer } 2668e90adafSMichael J. Spencer 2678e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSectionAddress(DataRefImpl Sec) const { 268*0324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2698e90adafSMichael J. Spencer return sec->VirtualAddress; 2708e90adafSMichael J. Spencer } 2718e90adafSMichael J. Spencer 2728e90adafSMichael J. Spencer uint64_t COFFObjectFile::getSectionSize(DataRefImpl Sec) const { 273*0324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2748e90adafSMichael J. Spencer return sec->SizeOfRawData; 2758e90adafSMichael J. Spencer } 2768e90adafSMichael J. Spencer 2778e90adafSMichael J. Spencer StringRef COFFObjectFile::getSectionContents(DataRefImpl Sec) const { 278*0324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2798e90adafSMichael J. Spencer return StringRef(reinterpret_cast<const char *>(base + sec->PointerToRawData), 2808e90adafSMichael J. Spencer sec->SizeOfRawData); 2818e90adafSMichael J. Spencer } 2828e90adafSMichael J. Spencer 2838e90adafSMichael J. Spencer bool COFFObjectFile::isSectionText(DataRefImpl Sec) const { 284*0324b672SMichael J. Spencer const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); 2858e90adafSMichael J. Spencer return sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; 2868e90adafSMichael J. Spencer } 2878e90adafSMichael J. Spencer 2888e90adafSMichael J. Spencer COFFObjectFile::COFFObjectFile(MemoryBuffer *Object) 2898e90adafSMichael J. Spencer : ObjectFile(Object) { 2908e90adafSMichael J. Spencer Header = reinterpret_cast<const coff_file_header *>(base); 2918e90adafSMichael J. Spencer SectionTable = 2928e90adafSMichael J. Spencer reinterpret_cast<const coff_section *>( base 2938e90adafSMichael J. Spencer + sizeof(coff_file_header) 2948e90adafSMichael J. Spencer + Header->SizeOfOptionalHeader); 2958e90adafSMichael J. Spencer SymbolTable = 2968e90adafSMichael J. Spencer reinterpret_cast<const coff_symbol *>(base + Header->PointerToSymbolTable); 2978e90adafSMichael J. Spencer 2988e90adafSMichael J. Spencer // Find string table. 2998e90adafSMichael J. Spencer StringTable = reinterpret_cast<const char *>(base) 3008e90adafSMichael J. Spencer + Header->PointerToSymbolTable 3018e90adafSMichael J. Spencer + Header->NumberOfSymbols * 18; 3028e90adafSMichael J. Spencer } 3038e90adafSMichael J. Spencer 3048e90adafSMichael J. Spencer ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { 305*0324b672SMichael J. Spencer DataRefImpl ret; 306*0324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SymbolTable); 307*0324b672SMichael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 3088e90adafSMichael J. Spencer } 3098e90adafSMichael J. Spencer 3108e90adafSMichael J. Spencer ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { 3118e90adafSMichael J. Spencer // The symbol table ends where the string table begins. 312*0324b672SMichael J. Spencer DataRefImpl ret; 313*0324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(StringTable); 314*0324b672SMichael J. Spencer return symbol_iterator(SymbolRef(ret, this)); 3158e90adafSMichael J. Spencer } 3168e90adafSMichael J. Spencer 3178e90adafSMichael J. Spencer ObjectFile::section_iterator COFFObjectFile::begin_sections() const { 318*0324b672SMichael J. Spencer DataRefImpl ret; 319*0324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable); 320*0324b672SMichael J. Spencer return section_iterator(SectionRef(ret, this)); 3218e90adafSMichael J. Spencer } 3228e90adafSMichael J. Spencer 3238e90adafSMichael J. Spencer ObjectFile::section_iterator COFFObjectFile::end_sections() const { 324*0324b672SMichael J. Spencer DataRefImpl ret; 325*0324b672SMichael J. Spencer ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections); 326*0324b672SMichael J. Spencer return section_iterator(SectionRef(ret, this)); 3278e90adafSMichael J. Spencer } 3288e90adafSMichael J. Spencer 3298e90adafSMichael J. Spencer uint8_t COFFObjectFile::getBytesInAddress() const { 330*0324b672SMichael J. Spencer return getArch() == Triple::x86_64 ? 8 : 4; 3318e90adafSMichael J. Spencer } 3328e90adafSMichael J. Spencer 3338e90adafSMichael J. Spencer StringRef COFFObjectFile::getFileFormatName() const { 3348e90adafSMichael J. Spencer switch(Header->Machine) { 3358e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 3368e90adafSMichael J. Spencer return "COFF-i386"; 3378e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 3388e90adafSMichael J. Spencer return "COFF-x86-64"; 3398e90adafSMichael J. Spencer default: 3408e90adafSMichael J. Spencer return "COFF-<unknown arch>"; 3418e90adafSMichael J. Spencer } 3428e90adafSMichael J. Spencer } 3438e90adafSMichael J. Spencer 3448e90adafSMichael J. Spencer unsigned COFFObjectFile::getArch() const { 3458e90adafSMichael J. Spencer switch(Header->Machine) { 3468e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_I386: 3478e90adafSMichael J. Spencer return Triple::x86; 3488e90adafSMichael J. Spencer case COFF::IMAGE_FILE_MACHINE_AMD64: 3498e90adafSMichael J. Spencer return Triple::x86_64; 3508e90adafSMichael J. Spencer default: 3518e90adafSMichael J. Spencer return Triple::UnknownArch; 3528e90adafSMichael J. Spencer } 3538e90adafSMichael J. Spencer } 3548e90adafSMichael J. Spencer 3558e90adafSMichael J. Spencer const coff_section *COFFObjectFile::getSection(std::size_t index) const { 3568e90adafSMichael J. Spencer if (index > 0 && index <= Header->NumberOfSections) 3578e90adafSMichael J. Spencer return SectionTable + (index - 1); 3588e90adafSMichael J. Spencer return 0; 3598e90adafSMichael J. Spencer } 3608e90adafSMichael J. Spencer 3618e90adafSMichael J. Spencer const char *COFFObjectFile::getString(std::size_t offset) const { 3628e90adafSMichael J. Spencer const ulittle32_t *StringTableSize = 3638e90adafSMichael J. Spencer reinterpret_cast<const ulittle32_t *>(StringTable); 3648e90adafSMichael J. Spencer if (offset < *StringTableSize) 3658e90adafSMichael J. Spencer return StringTable + offset; 3668e90adafSMichael J. Spencer return 0; 3678e90adafSMichael J. Spencer } 3688e90adafSMichael J. Spencer 3698e90adafSMichael J. Spencer namespace llvm { 3708e90adafSMichael J. Spencer 3718e90adafSMichael J. Spencer ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { 3728e90adafSMichael J. Spencer return new COFFObjectFile(Object); 3738e90adafSMichael J. Spencer } 3748e90adafSMichael J. Spencer 3758e90adafSMichael J. Spencer } // end namespace llvm 376