1 //===- XCOFFReader.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "XCOFFReader.h" 10 11 namespace llvm { 12 namespace objcopy { 13 namespace xcoff { 14 15 using namespace object; 16 17 Error XCOFFReader::readSections(Object &Obj) const { 18 ArrayRef<XCOFFSectionHeader32> Sections = XCOFFObj.sections32(); 19 for (const XCOFFSectionHeader32 &Sec : Sections) { 20 Section ReadSec; 21 // Section header. 22 ReadSec.SectionHeader = Sec; 23 DataRefImpl SectionDRI; 24 SectionDRI.p = reinterpret_cast<uintptr_t>(&Sec); 25 26 // Section data. 27 if (Sec.SectionSize) { 28 Expected<ArrayRef<uint8_t>> ContentsRef = 29 XCOFFObj.getSectionContents(SectionDRI); 30 if (!ContentsRef) 31 return ContentsRef.takeError(); 32 ReadSec.Contents = ContentsRef.get(); 33 } 34 35 // Relocations. 36 if (Sec.NumberOfRelocations) { 37 auto Relocations = 38 XCOFFObj.relocations<XCOFFSectionHeader32, XCOFFRelocation32>(Sec); 39 if (!Relocations) 40 return Relocations.takeError(); 41 for (const XCOFFRelocation32 &Rel : Relocations.get()) 42 ReadSec.Relocations.push_back(Rel); 43 } 44 45 Obj.Sections.push_back(std::move(ReadSec)); 46 } 47 return Error::success(); 48 } 49 50 Error XCOFFReader::readSymbols(Object &Obj) const { 51 std::vector<Symbol> Symbols; 52 Symbols.reserve(XCOFFObj.getNumberOfSymbolTableEntries()); 53 for (SymbolRef Sym : XCOFFObj.symbols()) { 54 Symbol ReadSym; 55 DataRefImpl SymbolDRI = Sym.getRawDataRefImpl(); 56 XCOFFSymbolRef SymbolEntRef = XCOFFObj.toSymbolRef(SymbolDRI); 57 ReadSym.Sym = *SymbolEntRef.getSymbol32(); 58 // Auxiliary entries. 59 if (SymbolEntRef.getNumberOfAuxEntries()) { 60 const char *Start = reinterpret_cast<const char *>( 61 SymbolDRI.p + XCOFF::SymbolTableEntrySize); 62 Expected<StringRef> RawAuxEntriesOrError = XCOFFObj.getRawData( 63 Start, 64 XCOFF::SymbolTableEntrySize * SymbolEntRef.getNumberOfAuxEntries(), 65 StringRef("symbol")); 66 if (!RawAuxEntriesOrError) 67 return RawAuxEntriesOrError.takeError(); 68 ReadSym.AuxSymbolEntries = RawAuxEntriesOrError.get(); 69 } 70 Obj.Symbols.push_back(std::move(ReadSym)); 71 } 72 return Error::success(); 73 } 74 75 Expected<std::unique_ptr<Object>> XCOFFReader::create() const { 76 auto Obj = std::make_unique<Object>(); 77 // Only 32-bit supported now. 78 if (XCOFFObj.is64Bit()) 79 return createStringError(object_error::invalid_file_type, 80 "64-bit XCOFF is not supported yet"); 81 // Read the file header. 82 Obj->FileHeader = *XCOFFObj.fileHeader32(); 83 // Read the optional header. 84 if (XCOFFObj.getOptionalHeaderSize()) 85 Obj->OptionalFileHeader = *XCOFFObj.auxiliaryHeader32(); 86 // Read each section. 87 Obj->Sections.reserve(XCOFFObj.getNumberOfSections()); 88 if (Error E = readSections(*Obj)) 89 return std::move(E); 90 // Read each symbol. 91 Obj->Symbols.reserve(XCOFFObj.getRawNumberOfSymbolTableEntries32()); 92 if (Error E = readSymbols(*Obj)) 93 return std::move(E); 94 // String table. 95 Obj->StringTable = XCOFFObj.getStringTable(); 96 return std::move(Obj); 97 } 98 99 } // end namespace xcoff 100 } // end namespace objcopy 101 } // end namespace llvm 102