101 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "XCOFFReader.h"10 11namespace llvm {12namespace objcopy {13namespace xcoff {14 15using namespace object;16 17Error 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 49Error 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 74Expected<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 xcoff99} // end namespace objcopy100} // end namespace llvm101