xref: /llvm-project/llvm/lib/ObjCopy/XCOFF/XCOFFReader.cpp (revision 61835d19a848ecd3530d9b86deb6b15f336ae6d6)
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*61835d19Sesmeyi Error 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*61835d19Sesmeyi Error 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*61835d19Sesmeyi Expected<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