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