forked from OSchip/llvm-project
[ELF] Refactor -z combreloc
* `RelocationBaseSection::addReloc` increases `numRelativeRelocs`, which duplicates the work done by RelocationSection<ELFT>::writeTo. * --pack-dyn-relocs=android has inappropropriate DT_RELACOUNT. AndroidPackedRelocationSection does not necessarily place relative relocations in the front and DT_RELACOUNT might cause semantics error (though our implementation doesn't and Android bionic doesn't use DT_RELACOUNT anyway.) Move `llvm::partition` to a new function `partitionRels` and compute `numRelativeRelocs` there. Now `RelocationBaseSection::addReloc` is trivial and can be moved to the header to enable inlining. The rest of DynamicReloc and `-z combreloc` handling is moved to the non-template `RelocationBaseSection::computeRels` to decrease code size. My x86-64 lld executable is 44+KiB smaller. While here, rename `sort` to `combreloc`.
This commit is contained in:
parent
460830a9c6
commit
da0e5b885b
|
@ -1589,9 +1589,11 @@ uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
|
|||
|
||||
RelocationBaseSection::RelocationBaseSection(StringRef name, uint32_t type,
|
||||
int32_t dynamicTag,
|
||||
int32_t sizeDynamicTag)
|
||||
int32_t sizeDynamicTag,
|
||||
bool combreloc)
|
||||
: SyntheticSection(SHF_ALLOC, type, config->wordsize, name),
|
||||
dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag) {}
|
||||
dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag),
|
||||
combreloc(combreloc) {}
|
||||
|
||||
void RelocationBaseSection::addSymbolReloc(RelType dynType,
|
||||
InputSectionBase &isec,
|
||||
|
@ -1640,10 +1642,13 @@ void RelocationBaseSection::addReloc(DynamicReloc::Kind kind, RelType dynType,
|
|||
addReloc({dynType, &inputSec, offsetInSec, kind, sym, addend, expr});
|
||||
}
|
||||
|
||||
void RelocationBaseSection::addReloc(const DynamicReloc &reloc) {
|
||||
if (reloc.type == target->relativeRel)
|
||||
++numRelativeRelocs;
|
||||
relocs.push_back(reloc);
|
||||
void RelocationBaseSection::partitionRels() {
|
||||
if (!combreloc)
|
||||
return;
|
||||
const RelType relativeRel = target->relativeRel;
|
||||
numRelativeRelocs =
|
||||
llvm::partition(relocs, [=](auto &r) { return r.type == relativeRel; }) -
|
||||
relocs.begin();
|
||||
}
|
||||
|
||||
void RelocationBaseSection::finalizeContents() {
|
||||
|
@ -1667,20 +1672,6 @@ void RelocationBaseSection::finalizeContents() {
|
|||
}
|
||||
}
|
||||
|
||||
RelrBaseSection::RelrBaseSection()
|
||||
: SyntheticSection(SHF_ALLOC,
|
||||
config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
|
||||
config->wordsize, ".relr.dyn") {}
|
||||
|
||||
template <class ELFT>
|
||||
static void encodeDynamicReloc(typename ELFT::Rela *p,
|
||||
const DynamicReloc &rel) {
|
||||
p->r_offset = rel.r_offset;
|
||||
p->setSymbolAndType(rel.r_sym, rel.type, config->isMips64EL);
|
||||
if (config->isRela)
|
||||
p->r_addend = rel.addend;
|
||||
}
|
||||
|
||||
void DynamicReloc::computeRaw(SymbolTableBaseSection *symtab) {
|
||||
r_offset = getOffset();
|
||||
r_sym = getSymIndex(symtab);
|
||||
|
@ -1688,27 +1679,15 @@ void DynamicReloc::computeRaw(SymbolTableBaseSection *symtab) {
|
|||
kind = AddendOnly; // Catch errors
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
RelocationSection<ELFT>::RelocationSection(StringRef name, bool sort)
|
||||
: RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
|
||||
config->isRela ? DT_RELA : DT_REL,
|
||||
config->isRela ? DT_RELASZ : DT_RELSZ),
|
||||
sort(sort) {
|
||||
this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
|
||||
}
|
||||
|
||||
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
|
||||
void RelocationBaseSection::computeRels() {
|
||||
SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
|
||||
|
||||
parallelForEach(relocs,
|
||||
[symTab](DynamicReloc &rel) { rel.computeRaw(symTab); });
|
||||
// Sort by (!IsRelative,SymIndex,r_offset). DT_REL[A]COUNT requires us to
|
||||
// place R_*_RELATIVE first. SymIndex is to improve locality, while r_offset
|
||||
// is to make results easier to read.
|
||||
if (sort) {
|
||||
const RelType relativeRel = target->relativeRel;
|
||||
auto nonRelative =
|
||||
llvm::partition(relocs, [=](auto &r) { return r.type == relativeRel; });
|
||||
if (combreloc) {
|
||||
auto nonRelative = relocs.begin() + numRelativeRelocs;
|
||||
parallelSort(relocs.begin(), nonRelative,
|
||||
[&](auto &a, auto &b) { return a.r_offset < b.r_offset; });
|
||||
// Non-relative relocations are few, so don't bother with parallelSort.
|
||||
|
@ -1716,20 +1695,41 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
|
|||
return std::tie(a.r_sym, a.r_offset) < std::tie(b.r_sym, b.r_offset);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
RelocationSection<ELFT>::RelocationSection(StringRef name, bool combreloc)
|
||||
: RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
|
||||
config->isRela ? DT_RELA : DT_REL,
|
||||
config->isRela ? DT_RELASZ : DT_RELSZ, combreloc) {
|
||||
this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
|
||||
}
|
||||
|
||||
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
|
||||
computeRels();
|
||||
for (const DynamicReloc &rel : relocs) {
|
||||
encodeDynamicReloc<ELFT>(reinterpret_cast<Elf_Rela *>(buf), rel);
|
||||
auto *p = reinterpret_cast<Elf_Rela *>(buf);
|
||||
p->r_offset = rel.r_offset;
|
||||
p->setSymbolAndType(rel.r_sym, rel.type, config->isMips64EL);
|
||||
if (config->isRela)
|
||||
p->r_addend = rel.addend;
|
||||
buf += config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
|
||||
}
|
||||
}
|
||||
|
||||
RelrBaseSection::RelrBaseSection()
|
||||
: SyntheticSection(SHF_ALLOC,
|
||||
config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
|
||||
config->wordsize, ".relr.dyn") {}
|
||||
|
||||
template <class ELFT>
|
||||
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
|
||||
StringRef name)
|
||||
: RelocationBaseSection(
|
||||
name, config->isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
|
||||
config->isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
|
||||
config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
|
||||
config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ,
|
||||
/*combreloc=*/false) {
|
||||
this->entsize = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -515,11 +515,11 @@ private:
|
|||
class RelocationBaseSection : public SyntheticSection {
|
||||
public:
|
||||
RelocationBaseSection(StringRef name, uint32_t type, int32_t dynamicTag,
|
||||
int32_t sizeDynamicTag);
|
||||
int32_t sizeDynamicTag, bool combreloc);
|
||||
/// Add a dynamic relocation without writing an addend to the output section.
|
||||
/// This overload can be used if the addends are written directly instead of
|
||||
/// using relocations on the input section (e.g. MipsGotSection::writeTo()).
|
||||
void addReloc(const DynamicReloc &reloc);
|
||||
void addReloc(const DynamicReloc &reloc) { relocs.push_back(reloc); }
|
||||
/// Add a dynamic relocation against \p sym with an optional addend.
|
||||
void addSymbolReloc(RelType dynType, InputSectionBase &isec,
|
||||
uint64_t offsetInSec, Symbol &sym, int64_t addend = 0,
|
||||
|
@ -541,6 +541,7 @@ public:
|
|||
bool isNeeded() const override { return !relocs.empty(); }
|
||||
size_t getSize() const override { return relocs.size() * this->entsize; }
|
||||
size_t getRelativeRelocCount() const { return numRelativeRelocs; }
|
||||
void partitionRels();
|
||||
void finalizeContents() override;
|
||||
static bool classof(const SectionBase *d) {
|
||||
return SyntheticSection::classof(d) &&
|
||||
|
@ -551,7 +552,9 @@ public:
|
|||
SmallVector<DynamicReloc, 0> relocs;
|
||||
|
||||
protected:
|
||||
size_t numRelativeRelocs = 0;
|
||||
void computeRels();
|
||||
size_t numRelativeRelocs = 0; // used by -z combreloc
|
||||
bool combreloc;
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -560,11 +563,8 @@ class RelocationSection final : public RelocationBaseSection {
|
|||
using Elf_Rela = typename ELFT::Rela;
|
||||
|
||||
public:
|
||||
RelocationSection(StringRef name, bool sort);
|
||||
RelocationSection(StringRef name, bool combreloc);
|
||||
void writeTo(uint8_t *buf) override;
|
||||
|
||||
private:
|
||||
bool sort;
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
|
|
|
@ -2086,11 +2086,16 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
// Dynamic section must be the last one in this list and dynamic
|
||||
// symbol table section (dynSymTab) must be the first one.
|
||||
for (Partition &part : partitions) {
|
||||
if (part.relaDyn) {
|
||||
// Compute DT_RELACOUNT to be used by part.dynamic.
|
||||
part.relaDyn->partitionRels();
|
||||
finalizeSynthetic(part.relaDyn.get());
|
||||
}
|
||||
|
||||
finalizeSynthetic(part.dynSymTab.get());
|
||||
finalizeSynthetic(part.gnuHashTab.get());
|
||||
finalizeSynthetic(part.hashTab.get());
|
||||
finalizeSynthetic(part.verDef.get());
|
||||
finalizeSynthetic(part.relaDyn.get());
|
||||
finalizeSynthetic(part.relrDyn.get());
|
||||
finalizeSynthetic(part.ehFrameHdr.get());
|
||||
finalizeSynthetic(part.verSym.get());
|
||||
|
|
|
@ -77,15 +77,17 @@
|
|||
/// by the larger groups of relative relocations (i.e. the 8 and 9 followed
|
||||
/// by the 7.)
|
||||
// ANDROID32: Section ({{.+}}) .rel.dyn {
|
||||
// ANDROID32-NEXT: 0x3024C R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30250 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30254 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30258 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x3025C R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30260 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30264 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30268 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x3026C R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30270 R_ARM_RELATIVE -
|
||||
|
||||
// ANDROID32-NEXT: 0x30294 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30298 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x3029C R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x302A0 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x302A4 R_ARM_RELATIVE -
|
||||
|
@ -93,26 +95,25 @@
|
|||
// ANDROID32-NEXT: 0x302AC R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x302B0 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x302B4 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x302B8 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x302BC R_ARM_RELATIVE -
|
||||
|
||||
// ANDROID32-NEXT: 0x30270 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30274 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30278 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x3027C R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30280 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30284 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30288 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x3028C R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x30290 R_ARM_RELATIVE -
|
||||
// ANDROID32-NEXT: 0x302C1 R_ARM_RELATIVE -
|
||||
|
||||
// ANDROID32-NEXT: 0x30274 R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x30298 R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302B9 R_ARM_RELATIVE -
|
||||
|
||||
// ANDROID32-NEXT: 0x3026C R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x30290 R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302BD R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302C1 R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302C5 R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302C9 R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302CD R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302D1 R_ARM_ABS32 bar2
|
||||
// ANDROID32-NEXT: 0x302D5 R_ARM_ABS32 bar2
|
||||
|
||||
// ANDROID32-NEXT: 0x30294 R_ARM_ABS32 zed2 0x0
|
||||
// ANDROID32-NEXT: 0x3028C R_ARM_ABS32 zed2
|
||||
// ANDROID32-NEXT: }
|
||||
|
||||
// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.a32.o %t.a32.so -o %t4.a32
|
||||
|
@ -225,6 +226,7 @@
|
|||
// UNPACKED64-NEXT: 0x30760 R_AARCH64_RELATIVE - 0x9
|
||||
|
||||
// UNPACKED64-NEXT: 0x30769 R_AARCH64_RELATIVE - 0xA
|
||||
|
||||
// UNPACKED64-NEXT: 0x306D0 R_AARCH64_ABS64 bar2 0x1
|
||||
// UNPACKED64-NEXT: 0x30718 R_AARCH64_ABS64 bar2 0x0
|
||||
// UNPACKED64-NEXT: 0x30771 R_AARCH64_ABS64 bar2 0x0
|
||||
|
@ -259,42 +261,42 @@
|
|||
// ANDROID64-HEADERS: 0x0000000060000012 ANDROID_RELASZ [[SIZE]]
|
||||
|
||||
// ANDROID64: Section ({{.+}}) .rela.dyn {
|
||||
// ANDROID64-NEXT: 0x303F0 R_AARCH64_RELATIVE - 0x1
|
||||
// ANDROID64-NEXT: 0x303F8 R_AARCH64_RELATIVE - 0x2
|
||||
// ANDROID64-NEXT: 0x30400 R_AARCH64_RELATIVE - 0x3
|
||||
// ANDROID64-NEXT: 0x30408 R_AARCH64_RELATIVE - 0x4
|
||||
// ANDROID64-NEXT: 0x30410 R_AARCH64_RELATIVE - 0x5
|
||||
// ANDROID64-NEXT: 0x30418 R_AARCH64_RELATIVE - 0x6
|
||||
// ANDROID64-NEXT: 0x30420 R_AARCH64_RELATIVE - 0x7
|
||||
// ANDROID64-NEXT: 0x30428 R_AARCH64_RELATIVE - 0x8
|
||||
// ANDROID64-NEXT: 0x303E0 R_AARCH64_RELATIVE - 0x1
|
||||
// ANDROID64-NEXT: 0x303E8 R_AARCH64_RELATIVE - 0x2
|
||||
// ANDROID64-NEXT: 0x303F0 R_AARCH64_RELATIVE - 0x3
|
||||
// ANDROID64-NEXT: 0x303F8 R_AARCH64_RELATIVE - 0x4
|
||||
// ANDROID64-NEXT: 0x30400 R_AARCH64_RELATIVE - 0x5
|
||||
// ANDROID64-NEXT: 0x30408 R_AARCH64_RELATIVE - 0x6
|
||||
// ANDROID64-NEXT: 0x30410 R_AARCH64_RELATIVE - 0x7
|
||||
// ANDROID64-NEXT: 0x30418 R_AARCH64_RELATIVE - 0x8
|
||||
// ANDROID64-NEXT: 0x30470 R_AARCH64_RELATIVE - 0x1
|
||||
// ANDROID64-NEXT: 0x30478 R_AARCH64_RELATIVE - 0x2
|
||||
// ANDROID64-NEXT: 0x30480 R_AARCH64_RELATIVE - 0x3
|
||||
// ANDROID64-NEXT: 0x30488 R_AARCH64_RELATIVE - 0x4
|
||||
// ANDROID64-NEXT: 0x30490 R_AARCH64_RELATIVE - 0x5
|
||||
// ANDROID64-NEXT: 0x30498 R_AARCH64_RELATIVE - 0x6
|
||||
// ANDROID64-NEXT: 0x304A0 R_AARCH64_RELATIVE - 0x7
|
||||
// ANDROID64-NEXT: 0x304A8 R_AARCH64_RELATIVE - 0x8
|
||||
// ANDROID64-NEXT: 0x304B0 R_AARCH64_RELATIVE - 0x9
|
||||
|
||||
// ANDROID64-NEXT: 0x30480 R_AARCH64_RELATIVE - 0x1
|
||||
// ANDROID64-NEXT: 0x30488 R_AARCH64_RELATIVE - 0x2
|
||||
// ANDROID64-NEXT: 0x30490 R_AARCH64_RELATIVE - 0x3
|
||||
// ANDROID64-NEXT: 0x30498 R_AARCH64_RELATIVE - 0x4
|
||||
// ANDROID64-NEXT: 0x304A0 R_AARCH64_RELATIVE - 0x5
|
||||
// ANDROID64-NEXT: 0x304A8 R_AARCH64_RELATIVE - 0x6
|
||||
// ANDROID64-NEXT: 0x304B0 R_AARCH64_RELATIVE - 0x7
|
||||
// ANDROID64-NEXT: 0x304B8 R_AARCH64_RELATIVE - 0x8
|
||||
// ANDROID64-NEXT: 0x304C0 R_AARCH64_RELATIVE - 0x9
|
||||
// ANDROID64-NEXT: 0x30428 R_AARCH64_RELATIVE - 0x1
|
||||
// ANDROID64-NEXT: 0x30430 R_AARCH64_RELATIVE - 0x2
|
||||
// ANDROID64-NEXT: 0x30438 R_AARCH64_RELATIVE - 0x3
|
||||
// ANDROID64-NEXT: 0x30440 R_AARCH64_RELATIVE - 0x4
|
||||
// ANDROID64-NEXT: 0x30448 R_AARCH64_RELATIVE - 0x5
|
||||
// ANDROID64-NEXT: 0x30450 R_AARCH64_RELATIVE - 0x6
|
||||
// ANDROID64-NEXT: 0x30458 R_AARCH64_RELATIVE - 0x7
|
||||
|
||||
// ANDROID64-NEXT: 0x30438 R_AARCH64_RELATIVE - 0x1
|
||||
// ANDROID64-NEXT: 0x30440 R_AARCH64_RELATIVE - 0x2
|
||||
// ANDROID64-NEXT: 0x30448 R_AARCH64_RELATIVE - 0x3
|
||||
// ANDROID64-NEXT: 0x30450 R_AARCH64_RELATIVE - 0x4
|
||||
// ANDROID64-NEXT: 0x30458 R_AARCH64_RELATIVE - 0x5
|
||||
// ANDROID64-NEXT: 0x30460 R_AARCH64_RELATIVE - 0x6
|
||||
// ANDROID64-NEXT: 0x30468 R_AARCH64_RELATIVE - 0x7
|
||||
// ANDROID64-NEXT: 0x304C9 R_AARCH64_RELATIVE - 0xA
|
||||
// ANDROID64-NEXT: 0x304B9 R_AARCH64_RELATIVE - 0xA
|
||||
|
||||
// ANDROID64-NEXT: 0x30478 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x304D1 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x304D9 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x304F1 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x30430 R_AARCH64_ABS64 bar2 0x1
|
||||
// ANDROID64-NEXT: 0x30470 R_AARCH64_ABS64 zed2 0x0
|
||||
// ANDROID64-NEXT: 0x304E1 R_AARCH64_ABS64 bar2 0x1
|
||||
// ANDROID64-NEXT: 0x304E9 R_AARCH64_ABS64 bar2 0x1
|
||||
// ANDROID64-NEXT: 0x30468 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x304C1 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x304C9 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x304E1 R_AARCH64_ABS64 bar2 0x0
|
||||
// ANDROID64-NEXT: 0x30420 R_AARCH64_ABS64 bar2 0x1
|
||||
// ANDROID64-NEXT: 0x30460 R_AARCH64_ABS64 zed2 0x0
|
||||
// ANDROID64-NEXT: 0x304D1 R_AARCH64_ABS64 bar2 0x1
|
||||
// ANDROID64-NEXT: 0x304D9 R_AARCH64_ABS64 bar2 0x1
|
||||
// ANDROID64-NEXT: }
|
||||
|
||||
// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.a64.o %t.a64.so -o %t4.a64
|
||||
|
|
Loading…
Reference in New Issue