brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · e6018eb Raw
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