123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- //===- XCOFFReader.cpp ----------------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "XCOFFReader.h"
- namespace llvm {
- namespace objcopy {
- namespace xcoff {
- using namespace object;
- Error XCOFFReader::readSections(Object &Obj) const {
- ArrayRef<XCOFFSectionHeader32> Sections = XCOFFObj.sections32();
- for (const XCOFFSectionHeader32 &Sec : Sections) {
- Section ReadSec;
- // Section header.
- ReadSec.SectionHeader = Sec;
- DataRefImpl SectionDRI;
- SectionDRI.p = reinterpret_cast<uintptr_t>(&Sec);
- // Section data.
- if (Sec.SectionSize) {
- Expected<ArrayRef<uint8_t>> ContentsRef =
- XCOFFObj.getSectionContents(SectionDRI);
- if (!ContentsRef)
- return ContentsRef.takeError();
- ReadSec.Contents = ContentsRef.get();
- }
- // Relocations.
- if (Sec.NumberOfRelocations) {
- auto Relocations =
- XCOFFObj.relocations<XCOFFSectionHeader32, XCOFFRelocation32>(Sec);
- if (!Relocations)
- return Relocations.takeError();
- for (const XCOFFRelocation32 &Rel : Relocations.get())
- ReadSec.Relocations.push_back(Rel);
- }
- Obj.Sections.push_back(std::move(ReadSec));
- }
- return Error::success();
- }
- Error XCOFFReader::readSymbols(Object &Obj) const {
- std::vector<Symbol> Symbols;
- Symbols.reserve(XCOFFObj.getNumberOfSymbolTableEntries());
- for (SymbolRef Sym : XCOFFObj.symbols()) {
- Symbol ReadSym;
- DataRefImpl SymbolDRI = Sym.getRawDataRefImpl();
- XCOFFSymbolRef SymbolEntRef = XCOFFObj.toSymbolRef(SymbolDRI);
- ReadSym.Sym = *SymbolEntRef.getSymbol32();
- // Auxiliary entries.
- if (SymbolEntRef.getNumberOfAuxEntries()) {
- const char *Start = reinterpret_cast<const char *>(
- SymbolDRI.p + XCOFF::SymbolTableEntrySize);
- Expected<StringRef> RawAuxEntriesOrError = XCOFFObj.getRawData(
- Start,
- XCOFF::SymbolTableEntrySize * SymbolEntRef.getNumberOfAuxEntries(),
- StringRef("symbol"));
- if (!RawAuxEntriesOrError)
- return RawAuxEntriesOrError.takeError();
- ReadSym.AuxSymbolEntries = RawAuxEntriesOrError.get();
- }
- Obj.Symbols.push_back(std::move(ReadSym));
- }
- return Error::success();
- }
- Expected<std::unique_ptr<Object>> XCOFFReader::create() const {
- auto Obj = std::make_unique<Object>();
- // Only 32-bit supported now.
- if (XCOFFObj.is64Bit())
- return createStringError(object_error::invalid_file_type,
- "64-bit XCOFF is not supported yet");
- // Read the file header.
- Obj->FileHeader = *XCOFFObj.fileHeader32();
- // Read the optional header.
- if (XCOFFObj.getOptionalHeaderSize())
- Obj->OptionalFileHeader = *XCOFFObj.auxiliaryHeader32();
- // Read each section.
- Obj->Sections.reserve(XCOFFObj.getNumberOfSections());
- if (Error E = readSections(*Obj))
- return std::move(E);
- // Read each symbol.
- Obj->Symbols.reserve(XCOFFObj.getRawNumberOfSymbolTableEntries32());
- if (Error E = readSymbols(*Obj))
- return std::move(E);
- // String table.
- Obj->StringTable = XCOFFObj.getStringTable();
- return std::move(Obj);
- }
- } // end namespace xcoff
- } // end namespace objcopy
- } // end namespace llvm
|