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 llvm::append_range(ReadSec.Relocations, Relocations.get()); 42 } 43 44 Obj.Sections.push_back(std::move(ReadSec)); 45 } 46 return Error::success(); 47 } 48 49 Error XCOFFReader::readSymbols(Object &Obj) const { 50 std::vector<Symbol> Symbols; 51 Symbols.reserve(XCOFFObj.getNumberOfSymbolTableEntries()); 52 for (SymbolRef Sym : XCOFFObj.symbols()) { 53 Symbol ReadSym; 54 DataRefImpl SymbolDRI = Sym.getRawDataRefImpl(); 55 XCOFFSymbolRef SymbolEntRef = XCOFFObj.toSymbolRef(SymbolDRI); 56 ReadSym.Sym = *SymbolEntRef.getSymbol32(); 57 // Auxiliary entries. 58 if (SymbolEntRef.getNumberOfAuxEntries()) { 59 const char *Start = reinterpret_cast<const char *>( 60 SymbolDRI.p + XCOFF::SymbolTableEntrySize); 61 Expected<StringRef> RawAuxEntriesOrError = XCOFFObj.getRawData( 62 Start, 63 XCOFF::SymbolTableEntrySize * SymbolEntRef.getNumberOfAuxEntries(), 64 StringRef("symbol")); 65 if (!RawAuxEntriesOrError) 66 return RawAuxEntriesOrError.takeError(); 67 ReadSym.AuxSymbolEntries = RawAuxEntriesOrError.get(); 68 } 69 Obj.Symbols.push_back(std::move(ReadSym)); 70 } 71 return Error::success(); 72 } 73 74 Expected<std::unique_ptr<Object>> XCOFFReader::create() const { 75 auto Obj = std::make_unique<Object>(); 76 // Only 32-bit supported now. 77 if (XCOFFObj.is64Bit()) 78 return createStringError(object_error::invalid_file_type, 79 "64-bit XCOFF is not supported yet"); 80 // Read the file header. 81 Obj->FileHeader = *XCOFFObj.fileHeader32(); 82 // Read the optional header. 83 if (XCOFFObj.getOptionalHeaderSize()) 84 Obj->OptionalFileHeader = *XCOFFObj.auxiliaryHeader32(); 85 // Read each section. 86 Obj->Sections.reserve(XCOFFObj.getNumberOfSections()); 87 if (Error E = readSections(*Obj)) 88 return std::move(E); 89 // Read each symbol. 90 Obj->Symbols.reserve(XCOFFObj.getRawNumberOfSymbolTableEntries32()); 91 if (Error E = readSymbols(*Obj)) 92 return std::move(E); 93 // String table. 94 Obj->StringTable = XCOFFObj.getStringTable(); 95 return std::move(Obj); 96 } 97 98 } // end namespace xcoff 99 } // end namespace objcopy 100 } // end namespace llvm 101