forked from OSchip/llvm-project
[ELF] Create a map from Reference to Symbol.
In LLD's model, symbol is a property of the node (atom) and not a property of edge (reference). Prior to this patch, we stored the symbol in the reference. From post-commit comments, it seemed better to create a map from the reference to the symbol instead and use this mapping wherever desired. Address comments from Ruiu/Simon Atanasyan. llvm-svn: 230273
This commit is contained in:
parent
78a38c9f6d
commit
b6c31f3878
|
@ -38,24 +38,22 @@ template <class ELFT> class ELFReference : public Reference {
|
|||
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
|
||||
|
||||
public:
|
||||
ELFReference(const Elf_Sym *sym, const Elf_Rela *rela, uint64_t off,
|
||||
Reference::KindArch arch, Reference::KindValue relocType,
|
||||
uint32_t idx)
|
||||
: Reference(Reference::KindNamespace::ELF, arch, relocType), _sym(sym),
|
||||
ELFReference(const Elf_Rela *rela, uint64_t off, Reference::KindArch arch,
|
||||
Reference::KindValue relocType, uint32_t idx)
|
||||
: Reference(Reference::KindNamespace::ELF, arch, relocType),
|
||||
_target(nullptr), _targetSymbolIndex(idx), _offsetInAtom(off),
|
||||
_addend(rela->r_addend) {}
|
||||
|
||||
ELFReference(const Elf_Sym *sym, uint64_t off, Reference::KindArch arch,
|
||||
ELFReference(uint64_t off, Reference::KindArch arch,
|
||||
Reference::KindValue relocType, uint32_t idx)
|
||||
: Reference(Reference::KindNamespace::ELF, arch, relocType), _sym(sym),
|
||||
: Reference(Reference::KindNamespace::ELF, arch, relocType),
|
||||
_target(nullptr), _targetSymbolIndex(idx), _offsetInAtom(off),
|
||||
_addend(0) {}
|
||||
|
||||
ELFReference(uint32_t edgeKind)
|
||||
: Reference(Reference::KindNamespace::all, Reference::KindArch::all,
|
||||
edgeKind),
|
||||
_sym(nullptr), _target(nullptr), _targetSymbolIndex(0),
|
||||
_offsetInAtom(0), _addend(0) {}
|
||||
_target(nullptr), _targetSymbolIndex(0), _offsetInAtom(0), _addend(0) {}
|
||||
|
||||
uint64_t offsetInAtom() const override { return _offsetInAtom; }
|
||||
|
||||
|
@ -74,12 +72,7 @@ public:
|
|||
|
||||
void setTarget(const Atom *newAtom) override { _target = newAtom; }
|
||||
|
||||
/// Is used for lookup the symbol or section that refers is in the same group
|
||||
/// or not in a group.
|
||||
const Elf_Sym *symbol() const { return _sym; }
|
||||
|
||||
private:
|
||||
const Elf_Sym *_sym;
|
||||
const Atom *_target;
|
||||
uint64_t _targetSymbolIndex;
|
||||
uint64_t _offsetInAtom;
|
||||
|
|
|
@ -388,6 +388,17 @@ protected:
|
|||
bool redirectReferenceUsingUndefAtom(const Elf_Sym *sourceSymbol,
|
||||
const Elf_Sym *targetSymbol) const;
|
||||
|
||||
void addReferenceToSymbol(const ELFReference<ELFT> *r, const Elf_Sym *sym) {
|
||||
_referenceToSymbol[r] = sym;
|
||||
}
|
||||
|
||||
const Elf_Sym *findSymbolForReference(const ELFReference<ELFT> *r) const {
|
||||
auto elfReferenceToSymbol = _referenceToSymbol.find(r);
|
||||
if (elfReferenceToSymbol != _referenceToSymbol.end())
|
||||
return elfReferenceToSymbol->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
llvm::BumpPtrAllocator _readerStorage;
|
||||
std::unique_ptr<llvm::object::ELFFile<ELFT> > _objFile;
|
||||
atom_collection_vector<DefinedAtom> _definedAtoms;
|
||||
|
@ -405,6 +416,8 @@ protected:
|
|||
std::unordered_map<StringRef, range<Elf_Rel_Iter>> _relocationReferences;
|
||||
std::vector<ELFReference<ELFT> *> _references;
|
||||
llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
|
||||
llvm::DenseMap<const ELFReference<ELFT> *, const Elf_Sym *>
|
||||
_referenceToSymbol;
|
||||
// Group child atoms have a pair corresponding to the signature and the
|
||||
// section header of the section that was used for generating the signature.
|
||||
llvm::DenseMap<const Elf_Sym *, std::pair<StringRef, const Elf_Shdr *>>
|
||||
|
@ -1016,9 +1029,11 @@ void ELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
|
|||
if (rel.r_offset < symValue ||
|
||||
symValue + content.size() <= rel.r_offset)
|
||||
continue;
|
||||
_references.push_back(new (_readerStorage) ELFReference<ELFT>(
|
||||
symbol, &rel, rel.r_offset - symValue, kindArch(),
|
||||
rel.getType(isMips64EL), rel.getSymbol(isMips64EL)));
|
||||
auto elfRelocation = new (_readerStorage)
|
||||
ELFReference<ELFT>(&rel, rel.r_offset - symValue, kindArch(),
|
||||
rel.getType(isMips64EL), rel.getSymbol(isMips64EL));
|
||||
addReferenceToSymbol(elfRelocation, symbol);
|
||||
_references.push_back(elfRelocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1033,11 +1048,13 @@ void ELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
|
|||
if (rel.r_offset < symValue ||
|
||||
symValue + symContent.size() <= rel.r_offset)
|
||||
continue;
|
||||
_references.push_back(new (_readerStorage) ELFReference<ELFT>(
|
||||
symbol, rel.r_offset - symValue, kindArch(), rel.getType(isMips64EL),
|
||||
rel.getSymbol(isMips64EL)));
|
||||
auto elfRelocation = new (_readerStorage)
|
||||
ELFReference<ELFT>(rel.r_offset - symValue, kindArch(),
|
||||
rel.getType(isMips64EL), rel.getSymbol(isMips64EL));
|
||||
int32_t addend = *(symContent.data() + rel.r_offset - symValue);
|
||||
_references.back()->setAddend(addend);
|
||||
elfRelocation->setAddend(addend);
|
||||
addReferenceToSymbol(elfRelocation, symbol);
|
||||
_references.push_back(elfRelocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1079,7 +1096,7 @@ template <class ELFT> void ELFFile<ELFT>::updateReferences() {
|
|||
// If the atom is not in mergeable string section, the target atom is
|
||||
// simply that atom.
|
||||
if (!isMergeableStringSection(shdr)) {
|
||||
ri->setTarget(findAtom(ri->symbol(), symbol));
|
||||
ri->setTarget(findAtom(findSymbolForReference(ri), symbol));
|
||||
continue;
|
||||
}
|
||||
updateReferenceForMergeStringAccess(ri, symbol, shdr);
|
||||
|
|
|
@ -208,9 +208,11 @@ private:
|
|||
symbol->st_value + symContent.size() <= rit->r_offset)
|
||||
continue;
|
||||
|
||||
this->_references.push_back(new (this->_readerStorage) ELFReference<ELFT>(
|
||||
symbol, rit->r_offset - symbol->st_value, this->kindArch(),
|
||||
rit->getType(isMips64EL()), rit->getSymbol(isMips64EL())));
|
||||
auto elfReference = new (this->_readerStorage) ELFReference<ELFT>(
|
||||
rit->r_offset - symbol->st_value, this->kindArch(),
|
||||
rit->getType(isMips64EL()), rit->getSymbol(isMips64EL()));
|
||||
ELFFile<ELFT>::addReferenceToSymbol(elfReference, symbol);
|
||||
this->_references.push_back(elfReference);
|
||||
|
||||
auto addend = getAddend(*rit, secContent);
|
||||
auto pairRelType = getPairRelocation(*rit);
|
||||
|
|
Loading…
Reference in New Issue