fix the mergeable string atom, when the target points to a symbol which is at a relative offset from the start of the .rodata section

llvm-svn: 175039
This commit is contained in:
Shankar Easwaran 2013-02-13 06:35:33 +00:00
parent 96d594b14e
commit 4b9cea7317
2 changed files with 15 additions and 6 deletions

View File

@ -461,6 +461,8 @@ public:
return "";
}
virtual uint64_t section() const { return _section->sh_name; }
virtual uint64_t offset() const { return _offset; }
virtual uint64_t ordinal() const { return _ordinal; }

View File

@ -93,18 +93,22 @@ template <class ELFT> class ELFFile : public File {
/// \brief find a mergeAtom given a start offset
struct FindByOffset {
const Elf_Shdr *_shdr;
uint64_t _offset;
FindByOffset(uint64_t offset) : _offset(offset) {}
FindByOffset(const Elf_Shdr *shdr, uint64_t offset)
: _shdr(shdr), _offset(offset) {
}
bool operator()(const ELFMergeAtom<ELFT> *a) {
uint64_t off = a->offset();
return ((_offset >= off) && (_offset <= off + a->size()));
return (_shdr->sh_name == a->section()) &&
((_offset >= off) && (_offset <= off + a->size()));
}
};
/// \brief find a merge atom given a offset
MergeAtomsIter findMergeAtom(uint64_t offset) {
MergeAtomsIter findMergeAtom(const Elf_Shdr *shdr, uint64_t offset) {
return std::find_if(_mergeAtoms.begin(), _mergeAtoms.end(),
FindByOffset(offset));
FindByOffset(shdr, offset));
}
typedef std::unordered_map<MergeSectionKey, DefinedAtom *, MergeSectionEq,
@ -466,9 +470,12 @@ public:
(sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
const MergeSectionKey ms(shdr, ri->addend());
if (_mergedSectionMap.find(ms) == _mergedSectionMap.end()) {
MergeAtomsIter mai = findMergeAtom(ri->addend());
uint64_t addend = ri->addend();
if (Symbol->getType() != llvm::ELF::STT_SECTION)
addend = Symbol->st_value + ri->addend();
MergeAtomsIter mai = findMergeAtom(shdr, addend);
if (mai != _mergeAtoms.end()) {
ri->setOffset(ri->addend() - ((*mai)->offset()));
ri->setOffset(addend - ((*mai)->offset()));
ri->setAddend(0);
ri->setTarget(*mai);
} // check