1 //===- XCOFFReader.cpp ----------------------------------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "XCOFFReader.h"
15 using namespace object
;
17 Error
XCOFFReader::readSections(Object
&Obj
) const {
18 ArrayRef
<XCOFFSectionHeader32
> Sections
= XCOFFObj
.sections32();
19 for (const XCOFFSectionHeader32
&Sec
: Sections
) {
22 ReadSec
.SectionHeader
= Sec
;
23 DataRefImpl SectionDRI
;
24 SectionDRI
.p
= reinterpret_cast<uintptr_t>(&Sec
);
27 if (Sec
.SectionSize
) {
28 Expected
<ArrayRef
<uint8_t>> ContentsRef
=
29 XCOFFObj
.getSectionContents(SectionDRI
);
31 return ContentsRef
.takeError();
32 ReadSec
.Contents
= ContentsRef
.get();
36 if (Sec
.NumberOfRelocations
) {
38 XCOFFObj
.relocations
<XCOFFSectionHeader32
, XCOFFRelocation32
>(Sec
);
40 return Relocations
.takeError();
41 for (const XCOFFRelocation32
&Rel
: Relocations
.get())
42 ReadSec
.Relocations
.push_back(Rel
);
45 Obj
.Sections
.push_back(std::move(ReadSec
));
47 return Error::success();
50 Error
XCOFFReader::readSymbols(Object
&Obj
) const {
51 std::vector
<Symbol
> Symbols
;
52 Symbols
.reserve(XCOFFObj
.getNumberOfSymbolTableEntries());
53 for (SymbolRef Sym
: XCOFFObj
.symbols()) {
55 DataRefImpl SymbolDRI
= Sym
.getRawDataRefImpl();
56 XCOFFSymbolRef SymbolEntRef
= XCOFFObj
.toSymbolRef(SymbolDRI
);
57 ReadSym
.Sym
= *SymbolEntRef
.getSymbol32();
59 if (SymbolEntRef
.getNumberOfAuxEntries()) {
60 const char *Start
= reinterpret_cast<const char *>(
61 SymbolDRI
.p
+ XCOFF::SymbolTableEntrySize
);
62 Expected
<StringRef
> RawAuxEntriesOrError
= XCOFFObj
.getRawData(
64 XCOFF::SymbolTableEntrySize
* SymbolEntRef
.getNumberOfAuxEntries(),
66 if (!RawAuxEntriesOrError
)
67 return RawAuxEntriesOrError
.takeError();
68 ReadSym
.AuxSymbolEntries
= RawAuxEntriesOrError
.get();
70 Obj
.Symbols
.push_back(std::move(ReadSym
));
72 return Error::success();
75 Expected
<std::unique_ptr
<Object
>> XCOFFReader::create() const {
76 auto Obj
= std::make_unique
<Object
>();
77 // Only 32-bit supported now.
78 if (XCOFFObj
.is64Bit())
79 return createStringError(object_error::invalid_file_type
,
80 "64-bit XCOFF is not supported yet");
81 // Read the file header.
82 Obj
->FileHeader
= *XCOFFObj
.fileHeader32();
83 // Read the optional header.
84 if (XCOFFObj
.getOptionalHeaderSize())
85 Obj
->OptionalFileHeader
= *XCOFFObj
.auxiliaryHeader32();
87 Obj
->Sections
.reserve(XCOFFObj
.getNumberOfSections());
88 if (Error E
= readSections(*Obj
))
91 Obj
->Symbols
.reserve(XCOFFObj
.getRawNumberOfSymbolTableEntries32());
92 if (Error E
= readSymbols(*Obj
))
95 Obj
->StringTable
= XCOFFObj
.getStringTable();
96 return std::move(Obj
);
99 } // end namespace xcoff
100 } // end namespace objcopy
101 } // end namespace llvm