diff options
| author | Martin Storsjo <martin@martin.st> | 2019-01-22 10:58:09 +0000 |
|---|---|---|
| committer | Martin Storsjo <martin@martin.st> | 2019-01-22 10:58:09 +0000 |
| commit | 9ec18a37187cbe31a0e7d012b7e8193f293a1b67 (patch) | |
| tree | 1b42eaef22e1d8f5ac074fd904ed133549334f87 /llvm/tools/llvm-objcopy | |
| parent | 8010c6beaf638653cb73d8db18c1d9784be5a0de (diff) | |
| download | bcm5719-llvm-9ec18a37187cbe31a0e7d012b7e8193f293a1b67.tar.gz bcm5719-llvm-9ec18a37187cbe31a0e7d012b7e8193f293a1b67.zip | |
[llvm-objcopy] [COFF] Update symbol indices in weak externals
Differential Revision: https://reviews.llvm.org/D57006
llvm-svn: 351800
Diffstat (limited to 'llvm/tools/llvm-objcopy')
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Object.h | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Reader.cpp | 24 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Reader.h | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Writer.cpp | 16 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Writer.h | 2 |
5 files changed, 40 insertions, 6 deletions
diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h index 8e200369f0b..0630f9c5ff8 100644 --- a/llvm/tools/llvm-objcopy/COFF/Object.h +++ b/llvm/tools/llvm-objcopy/COFF/Object.h @@ -11,6 +11,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/BinaryFormat/COFF.h" @@ -47,6 +48,7 @@ struct Symbol { std::vector<uint8_t> AuxData; ssize_t TargetSectionId; ssize_t AssociativeComdatTargetSectionId = 0; + Optional<size_t> WeakTargetSymbolId; size_t UniqueId; size_t RawIndex; bool Referenced; diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp index 20ff32a59dc..2446277cc2b 100644 --- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp @@ -121,12 +121,18 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { // For section definitions, check if it is comdat associative, and if // it is, find the target section unique id. const coff_aux_section_definition *SD = SymRef.getSectionDefinition(); + const coff_aux_weak_external *WE = SymRef.getWeakExternal(); if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) { int32_t Index = SD->getNumber(IsBigObj); if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size()) return createStringError(object_error::parse_failed, "Unexpected associative section index"); Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId; + } else if (WE) { + // This is a raw symbol index for now, but store it in the Symbol + // until we've added them to the Object, which assigns the final + // unique ids. + Sym.WeakTargetSymbolId = WE->TagIndex; } I += 1 + SymRef.getNumberOfAuxSymbols(); } @@ -134,13 +140,27 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const { return Error::success(); } -Error COFFReader::setRelocTargets(Object &Obj) const { +Error COFFReader::setSymbolTargets(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 (Symbol &Sym : Obj.getMutableSymbols()) { + // Convert WeakTargetSymbolId from the original raw symbol index to + // a proper unique id. + if (Sym.WeakTargetSymbolId) { + if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size()) + return createStringError(object_error::parse_failed, + "Weak external reference out of range"); + const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId]; + if (Target == nullptr) + return createStringError(object_error::parse_failed, + "Invalid SymbolTableIndex"); + Sym.WeakTargetSymbolId = Target->UniqueId; + } + } for (Section &Sec : Obj.getMutableSections()) { for (Relocation &R : Sec.Relocs) { if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size()) @@ -184,7 +204,7 @@ 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)) + if (Error E = setSymbolTargets(*Obj)) return std::move(E); return std::move(Obj); diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.h b/llvm/tools/llvm-objcopy/COFF/Reader.h index 4493705e73c..ec15369db0b 100644 --- a/llvm/tools/llvm-objcopy/COFF/Reader.h +++ b/llvm/tools/llvm-objcopy/COFF/Reader.h @@ -28,7 +28,7 @@ class COFFReader { Error readExecutableHeaders(Object &Obj) const; Error readSections(Object &Obj) const; Error readSymbols(Object &Obj, bool IsBigObj) const; - Error setRelocTargets(Object &Obj) const; + Error setSymbolTargets(Object &Obj) const; public: explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {} diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp index 0321f94a896..4f57131d5ab 100644 --- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp @@ -38,7 +38,7 @@ Error COFFWriter::finalizeRelocTargets() { return Error::success(); } -Error COFFWriter::finalizeSectionNumbers() { +Error COFFWriter::finalizeSymbolContents() { for (Symbol &Sym : Obj.getMutableSymbols()) { if (Sym.TargetSectionId <= 0) { // Undefined, or a special kind of symbol. These negative values @@ -75,6 +75,18 @@ Error COFFWriter::finalizeSectionNumbers() { SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16); } } + // Check that we actually have got AuxData to match the weak symbol target + // we want to set. Only >= 1 would be required, but only == 1 makes sense. + if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) { + coff_aux_weak_external *WE = + reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data()); + const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId); + if (Target == nullptr) + return createStringError(object_error::invalid_symbol_index, + "Symbol '%s' is missing its weak target", + Sym.Name.str().c_str()); + WE->TagIndex = Target->RawIndex; + } } return Error::success(); } @@ -137,7 +149,7 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() { Error COFFWriter::finalize(bool IsBigObj) { if (Error E = finalizeRelocTargets()) return E; - if (Error E = finalizeSectionNumbers()) + if (Error E = finalizeSymbolContents()) return E; size_t SizeOfHeaders = 0; diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h index a967a103df9..9b1cfa91d00 100644 --- a/llvm/tools/llvm-objcopy/COFF/Writer.h +++ b/llvm/tools/llvm-objcopy/COFF/Writer.h @@ -31,7 +31,7 @@ class COFFWriter { StringTableBuilder StrTabBuilder; Error finalizeRelocTargets(); - Error finalizeSectionNumbers(); + Error finalizeSymbolContents(); void layoutSections(); size_t finalizeStringTable(); template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable(); |

