diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy/COFF/Reader.cpp')
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Reader.cpp | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp index 5d805961d6f..76b3f73debe 100644 --- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp @@ -73,7 +73,7 @@ Error COFFReader::readSections(Object &Obj) const { return errorCodeToError(EC); ArrayRef<coff_relocation> Relocs = COFFObj.getRelocations(Sec); for (const coff_relocation &R : Relocs) - S.Relocs.push_back(R); + S.Relocs.push_back(Relocation{R}); if (auto EC = COFFObj.getSectionName(Sec, S.Name)) return errorCodeToError(EC); if (Sec->hasExtendedRelocations()) @@ -84,14 +84,16 @@ Error COFFReader::readSections(Object &Obj) const { } Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { + std::vector<Symbol> Symbols; + Symbols.reserve(COFFObj.getRawNumberOfSymbols()); for (uint32_t I = 0, E = COFFObj.getRawNumberOfSymbols(); I < E;) { Expected<COFFSymbolRef> SymOrErr = COFFObj.getSymbol(I); if (!SymOrErr) return SymOrErr.takeError(); COFFSymbolRef SymRef = *SymOrErr; - Obj.Symbols.push_back(Symbol()); - Symbol &Sym = Obj.Symbols.back(); + Symbols.push_back(Symbol()); + Symbol &Sym = Symbols.back(); // Copy symbols from the original form into an intermediate coff_symbol32. if (IsBigObj) copySymbol(Sym.Sym, @@ -106,6 +108,30 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0); I += 1 + SymRef.getNumberOfAuxSymbols(); } + Obj.addSymbols(Symbols); + return Error::success(); +} + +Error COFFReader::setRelocTargets(Object &Obj) const { + std::vector<const Symbol *> RawSymbolTable; + for (const Symbol &Sym : Obj.getSymbols()) { + RawSymbolTable.push_back(&Sym); + for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++) + RawSymbolTable.push_back(nullptr); + } + for (Section &Sec : Obj.Sections) { + for (Relocation &R : Sec.Relocs) { + if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size()) + return make_error<StringError>("SymbolTableIndex out of range", + object_error::parse_failed); + const Symbol *Sym = RawSymbolTable[R.Reloc.SymbolTableIndex]; + if (Sym == nullptr) + return make_error<StringError>("Invalid SymbolTableIndex", + object_error::parse_failed); + R.Target = Sym->UniqueId; + R.TargetName = Sym->Name; + } + } return Error::success(); } @@ -136,6 +162,8 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const { return std::move(E); if (Error E = readSymbols(*Obj, IsBigObj)) return std::move(E); + if (Error E = setRelocTargets(*Obj)) + return std::move(E); return std::move(Obj); } |

