23using namespace object;
26Error COFFReader::readExecutableHeaders(Object &Obj)
const {
28 Obj.Is64 = COFFObj.
is64();
34 if (DH->AddressOfNewExeHeader >
sizeof(*DH))
35 Obj.DosStub = ArrayRef<uint8_t>(
reinterpret_cast<const uint8_t *
>(&DH[1]),
36 DH->AddressOfNewExeHeader -
sizeof(*DH));
44 Obj.BaseOfData = PE32->BaseOfData;
47 for (
size_t I = 0;
I < Obj.PeHeader.NumberOfRvaAndSize;
I++) {
51 Obj.DataDirectories.emplace_back(*Dir);
56Error COFFReader::readSections(Object &Obj)
const {
57 std::vector<Section> Sections;
60 Expected<const coff_section *> SecOrErr = COFFObj.
getSection(
I);
62 return SecOrErr.takeError();
63 const coff_section *Sec = *SecOrErr;
68 ArrayRef<uint8_t> Contents;
71 S.setContentsRef(Contents);
73 for (
const coff_relocation &R : Relocs)
74 S.Relocs.push_back(R);
78 return NameOrErr.takeError();
80 Obj.addSections(Sections);
84Error COFFReader::readSymbols(Object &Obj,
bool IsBigObj)
const {
85 std::vector<Symbol> Symbols;
87 ArrayRef<Section> Sections = Obj.getSections();
89 Expected<COFFSymbolRef> SymOrErr = COFFObj.
getSymbol(
I);
91 return SymOrErr.takeError();
92 COFFSymbolRef SymRef = *SymOrErr;
94 Symbols.push_back(
Symbol());
99 *
reinterpret_cast<const coff_symbol32 *
>(SymRef.getRawPtr()));
102 *
reinterpret_cast<const coff_symbol16 *
>(SymRef.getRawPtr()));
105 return NameOrErr.takeError();
106 Sym.Name = *NameOrErr;
110 assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());
117 if (SymRef.isFileRecord())
118 Sym.AuxFile = StringRef(
reinterpret_cast<const char *
>(AuxData.data()),
122 for (
size_t I = 0;
I < SymRef.getNumberOfAuxSymbols();
I++)
123 Sym.AuxData.push_back(AuxData.slice(
I * SymSize,
sizeof(AuxSymbol)));
126 if (SymRef.getSectionNumber() <=
128 Sym.TargetSectionId = SymRef.getSectionNumber();
129 else if (
static_cast<uint32_t>(SymRef.getSectionNumber() - 1) <
131 Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;
134 "section number out of range");
137 const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
138 const coff_aux_weak_external *WE = SymRef.getWeakExternal();
140 int32_t
Index = SD->getNumber(IsBigObj);
143 "unexpected associative section index");
144 Sym.AssociativeComdatTargetSectionId = Sections[
Index - 1].UniqueId;
149 Sym.WeakTargetSymbolId = WE->TagIndex;
151 I += 1 + SymRef.getNumberOfAuxSymbols();
153 Obj.addSymbols(Symbols);
157Error COFFReader::setSymbolTargets(Object &Obj)
const {
158 std::vector<const Symbol *> RawSymbolTable;
159 for (
const Symbol &
Sym : Obj.getSymbols()) {
160 RawSymbolTable.push_back(&
Sym);
161 for (
size_t I = 0;
I <
Sym.Sym.NumberOfAuxSymbols;
I++)
162 RawSymbolTable.push_back(
nullptr);
164 for (Symbol &
Sym : Obj.getMutableSymbols()) {
167 if (
Sym.WeakTargetSymbolId) {
168 if (*
Sym.WeakTargetSymbolId >= RawSymbolTable.size())
170 "weak external reference out of range");
172 if (Target ==
nullptr)
174 "invalid SymbolTableIndex");
175 Sym.WeakTargetSymbolId =
Target->UniqueId;
178 for (Section &Sec : Obj.getMutableSections()) {
179 for (Relocation &R : Sec.Relocs) {
180 if (
R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
182 "SymbolTableIndex out of range");
183 const Symbol *
Sym = RawSymbolTable[
R.Reloc.SymbolTableIndex];
186 "invalid SymbolTableIndex");
187 R.Target =
Sym->UniqueId;
188 R.TargetName =
Sym->Name;
195 auto Obj = std::make_unique<Object>();
197 bool IsBigObj =
false;
199 Obj->CoffFileHeader = *CFH;
204 "no COFF file header returned");
207 Obj->CoffFileHeader.Machine = CBFH->
Machine;
212 if (
Error E = readExecutableHeaders(*Obj))
214 if (
Error E = readSections(*Obj))
216 if (
Error E = readSymbols(*Obj, IsBigObj))
218 if (
Error E = setSymbolTargets(*Obj))
221 return std::move(Obj);
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Expected< std::unique_ptr< Object > > create() const
const dos_header * getDOSHeader() const
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
const pe32_header * getPE32Header() const
Expected< COFFSymbolRef > getSymbol(uint32_t index) const
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
uint32_t getNumberOfSymbols() const
const coff_file_header * getCOFFHeader() const
const coff_bigobj_file_header * getCOFFBigObjHeader() const
uint32_t getNumberOfSections() const
Expected< const coff_section * > getSection(int32_t index) const
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
const data_directory * getDataDirectory(uint32_t index) const
ArrayRef< uint8_t > getSymbolAuxData(COFFSymbolRef Symbol) const
ArrayRef< coff_relocation > getRelocations(const coff_section *Sec) const
const pe32plus_header * getPE32PlusHeader() const
@ IMAGE_SCN_LNK_NRELOC_OVFL
@ IMAGE_COMDAT_SELECT_ASSOCIATIVE
void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src)
void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src)
coff_symbol< support::ulittle32_t > coff_symbol32
coff_symbol< support::ulittle16_t > coff_symbol16
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.