[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:
Shankar Easwaran 2015-02-23 22:32:12 +00:00
parent 78a38c9f6d
commit b6c31f3878
3 changed files with 36 additions and 24 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);