xref: /freebsd-src/contrib/llvm-project/llvm/lib/ObjCopy/XCOFF/XCOFFReader.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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 Andric Error 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 Andric Error 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 Andric Expected<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