functionality to handle global atoms in Merge sections
llvm-svn: 175636
This commit is contained in:
parent
6631e94838
commit
25832ede03
|
@ -274,17 +274,6 @@ public:
|
||||||
const Elf_Shdr *section = _objFile->getElfSection(sit);
|
const Elf_Shdr *section = _objFile->getElfSection(sit);
|
||||||
const Elf_Sym *symbol = _objFile->getElfSymbol(it);
|
const Elf_Sym *symbol = _objFile->getElfSymbol(it);
|
||||||
|
|
||||||
// If its a merge section, the atoms have already
|
|
||||||
// been created, lets not create the atoms again
|
|
||||||
if (doStringsMerge) {
|
|
||||||
int64_t sectionFlags = section->sh_flags;
|
|
||||||
sectionFlags &= ~llvm::ELF::SHF_ALLOC;
|
|
||||||
if ((section->sh_entsize < 2) &&
|
|
||||||
(sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef symbolName;
|
StringRef symbolName;
|
||||||
if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
|
if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
|
||||||
return;
|
return;
|
||||||
|
@ -364,6 +353,8 @@ public:
|
||||||
if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
|
if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const Elf_Shdr *section = _objFile->getSection(*si);
|
||||||
|
|
||||||
bool isCommon = (*si)->getType() == llvm::ELF::STT_COMMON ||
|
bool isCommon = (*si)->getType() == llvm::ELF::STT_COMMON ||
|
||||||
(*si)->st_shndx == llvm::ELF::SHN_COMMON;
|
(*si)->st_shndx == llvm::ELF::SHN_COMMON;
|
||||||
|
|
||||||
|
@ -423,6 +414,25 @@ public:
|
||||||
previous_atom->addReference(followOn);
|
previous_atom->addReference(followOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the linker finds that a section has global atoms that are in a
|
||||||
|
// mergeable section, treat them as defined atoms as they shouldnt be
|
||||||
|
// merged away as well as these symbols have to be part of symbol
|
||||||
|
// resolution
|
||||||
|
int64_t sectionFlags = 0;
|
||||||
|
if (section)
|
||||||
|
sectionFlags = section->sh_flags;
|
||||||
|
sectionFlags &= ~llvm::ELF::SHF_ALLOC;
|
||||||
|
if (doStringsMerge && section && (section->sh_entsize < 2) &&
|
||||||
|
(sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
|
||||||
|
if ((*si)->getBinding() == llvm::ELF::STB_GLOBAL) {
|
||||||
|
auto definedMergeAtom = new (_readerStorage) ELFDefinedAtom<ELFT>(
|
||||||
|
*this, symbolName, sectionName, (*si), section, symbolData,
|
||||||
|
_references.size(), _references.size(), _references);
|
||||||
|
_definedAtoms._atoms.push_back(definedMergeAtom);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto newAtom = createDefinedAtomAndAssignRelocations(
|
auto newAtom = createDefinedAtomAndAssignRelocations(
|
||||||
symbolName, sectionName, *si, i.first, symbolData);
|
symbolName, sectionName, *si, i.first, symbolData);
|
||||||
|
|
||||||
|
@ -468,11 +478,14 @@ public:
|
||||||
// refer to the MergeAtom to allow deduping
|
// refer to the MergeAtom to allow deduping
|
||||||
if (doStringsMerge && shdr && (shdr->sh_entsize < 2) &&
|
if (doStringsMerge && shdr && (shdr->sh_entsize < 2) &&
|
||||||
(sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
|
(sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
|
||||||
const MergeSectionKey ms(shdr, ri->addend());
|
const TargetRelocationHandler<ELFT> &relHandler = _elfTargetInfo
|
||||||
|
.template getTargetHandler<ELFT>().getRelocationHandler();
|
||||||
|
int64_t relocAddend = relHandler.relocAddend(*ri);
|
||||||
|
uint64_t addend = ri->addend() + relocAddend;
|
||||||
|
const MergeSectionKey ms(shdr, addend);
|
||||||
if (_mergedSectionMap.find(ms) == _mergedSectionMap.end()) {
|
if (_mergedSectionMap.find(ms) == _mergedSectionMap.end()) {
|
||||||
uint64_t addend = ri->addend();
|
|
||||||
if (Symbol->getType() != llvm::ELF::STT_SECTION)
|
if (Symbol->getType() != llvm::ELF::STT_SECTION)
|
||||||
addend = Symbol->st_value + ri->addend();
|
addend = Symbol->st_value + addend;
|
||||||
MergeAtomsIter mai = findMergeAtom(shdr, addend);
|
MergeAtomsIter mai = findMergeAtom(shdr, addend);
|
||||||
if (mai != _mergeAtoms.end()) {
|
if (mai != _mergeAtoms.end()) {
|
||||||
ri->setOffset(addend - ((*mai)->offset()));
|
ri->setOffset(addend - ((*mai)->offset()));
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
namespace lld {
|
namespace lld {
|
||||||
namespace elf {
|
namespace elf {
|
||||||
template <class ELFT> class ELFDefinedAtom;
|
template <class ELFT> class ELFDefinedAtom;
|
||||||
|
template <class ELFT> class ELFReference;
|
||||||
class ELFWriter;
|
class ELFWriter;
|
||||||
template <class ELFT> class Header;
|
template <class ELFT> class Header;
|
||||||
template <class ELFT> class Section;
|
template <class ELFT> class Section;
|
||||||
|
@ -54,17 +55,20 @@ public:
|
||||||
return DefinedAtom::typeZeroFill;
|
return DefinedAtom::typeZeroFill;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual DefinedAtom::ContentPermissions contentPermissions(
|
virtual DefinedAtom::ContentPermissions
|
||||||
const ELFDefinedAtom<ELFT> *atom) const {
|
contentPermissions(const ELFDefinedAtom<ELFT> *atom) const {
|
||||||
return atom->permissions();
|
return atom->permissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ELFT> class TargetRelocationHandler {
|
template <class ELFT> class TargetRelocationHandler {
|
||||||
public:
|
public:
|
||||||
virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
|
virtual ErrorOr<void>
|
||||||
const AtomLayout &,
|
applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const AtomLayout &,
|
||||||
const Reference &)const = 0;
|
const Reference &)const = 0;
|
||||||
|
|
||||||
|
virtual int64_t relocAddend(const Reference &)const { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief An interface to override functions that are provided by the
|
/// \brief An interface to override functions that are provided by the
|
||||||
|
|
|
@ -52,6 +52,16 @@ void reloc32S(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
|
||||||
}
|
}
|
||||||
} // end anon namespace
|
} // end anon namespace
|
||||||
|
|
||||||
|
int64_t X86_64TargetRelocationHandler::fixupAddend(const Reference &ref) const {
|
||||||
|
switch (ref.kind()) {
|
||||||
|
case R_X86_64_PC32:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
|
ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
|
||||||
ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
|
ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
|
||||||
const Reference &ref) const {
|
const Reference &ref) const {
|
||||||
|
|
|
@ -26,9 +26,11 @@ public:
|
||||||
X86_64TargetRelocationHandler(const X86_64TargetInfo &ti)
|
X86_64TargetRelocationHandler(const X86_64TargetInfo &ti)
|
||||||
: _tlsSize(0), _targetInfo(ti) {}
|
: _tlsSize(0), _targetInfo(ti) {}
|
||||||
|
|
||||||
virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
|
virtual ErrorOr<void>
|
||||||
const AtomLayout &,
|
applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, const AtomLayout &,
|
||||||
const Reference &)const;
|
const Reference &)const;
|
||||||
|
|
||||||
|
virtual int64_t fixupAddend(const Reference &)const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Cached size of the TLS segment.
|
// Cached size of the TLS segment.
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
/* compile the code with -fmerge-all-constants */
|
||||||
|
const char mystr[] = "foobar";
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
||||||
|
# ELF files can have mergeable strings which are global!, treat them as global
|
||||||
|
# defined atoms
|
||||||
|
RUN: lld-core -merge-strings=true -reader ELF %p/Inputs/globalconst.o.x86-64 | FileCheck -check-prefix=globalatoms %s
|
||||||
|
|
||||||
|
globalatoms: - name: mystr
|
||||||
|
globalatoms: scope: global
|
||||||
|
globalatoms: type: constant
|
||||||
|
globalatoms: content: [ 66, 6F, 6F, 62, 61, 72, 00 ]
|
||||||
|
globalatoms: section-choice: custom-required
|
||||||
|
globalatoms: section-name: .rodata.str1.1
|
Loading…
Reference in New Issue