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