Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit da0e5b8

Browse files
committed
[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`.
1 parent 460830a commit da0e5b8

4 files changed

Lines changed: 101 additions & 94 deletions

File tree

lld/ELF/SyntheticSections.cpp

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,9 +1589,11 @@ uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
15891589

15901590
RelocationBaseSection::RelocationBaseSection(StringRef name, uint32_t type,
15911591
int32_t dynamicTag,
1592-
int32_t sizeDynamicTag)
1592+
int32_t sizeDynamicTag,
1593+
bool combreloc)
15931594
: SyntheticSection(SHF_ALLOC, type, config->wordsize, name),
1594-
dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag) {}
1595+
dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag),
1596+
combreloc(combreloc) {}
15951597

15961598
void RelocationBaseSection::addSymbolReloc(RelType dynType,
15971599
InputSectionBase &isec,
@@ -1640,10 +1642,13 @@ void RelocationBaseSection::addReloc(DynamicReloc::Kind kind, RelType dynType,
16401642
addReloc({dynType, &inputSec, offsetInSec, kind, sym, addend, expr});
16411643
}
16421644

1643-
void RelocationBaseSection::addReloc(const DynamicReloc &reloc) {
1644-
if (reloc.type == target->relativeRel)
1645-
++numRelativeRelocs;
1646-
relocs.push_back(reloc);
1645+
void RelocationBaseSection::partitionRels() {
1646+
if (!combreloc)
1647+
return;
1648+
const RelType relativeRel = target->relativeRel;
1649+
numRelativeRelocs =
1650+
llvm::partition(relocs, [=](auto &r) { return r.type == relativeRel; }) -
1651+
relocs.begin();
16471652
}
16481653

16491654
void RelocationBaseSection::finalizeContents() {
@@ -1667,69 +1672,64 @@ void RelocationBaseSection::finalizeContents() {
16671672
}
16681673
}
16691674

1670-
RelrBaseSection::RelrBaseSection()
1671-
: SyntheticSection(SHF_ALLOC,
1672-
config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
1673-
config->wordsize, ".relr.dyn") {}
1674-
1675-
template <class ELFT>
1676-
static void encodeDynamicReloc(typename ELFT::Rela *p,
1677-
const DynamicReloc &rel) {
1678-
p->r_offset = rel.r_offset;
1679-
p->setSymbolAndType(rel.r_sym, rel.type, config->isMips64EL);
1680-
if (config->isRela)
1681-
p->r_addend = rel.addend;
1682-
}
1683-
16841675
void DynamicReloc::computeRaw(SymbolTableBaseSection *symtab) {
16851676
r_offset = getOffset();
16861677
r_sym = getSymIndex(symtab);
16871678
addend = computeAddend();
16881679
kind = AddendOnly; // Catch errors
16891680
}
16901681

1691-
template <class ELFT>
1692-
RelocationSection<ELFT>::RelocationSection(StringRef name, bool sort)
1693-
: RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
1694-
config->isRela ? DT_RELA : DT_REL,
1695-
config->isRela ? DT_RELASZ : DT_RELSZ),
1696-
sort(sort) {
1697-
this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
1698-
}
1699-
1700-
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
1682+
void RelocationBaseSection::computeRels() {
17011683
SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
1702-
17031684
parallelForEach(relocs,
17041685
[symTab](DynamicReloc &rel) { rel.computeRaw(symTab); });
17051686
// Sort by (!IsRelative,SymIndex,r_offset). DT_REL[A]COUNT requires us to
17061687
// place R_*_RELATIVE first. SymIndex is to improve locality, while r_offset
17071688
// is to make results easier to read.
1708-
if (sort) {
1709-
const RelType relativeRel = target->relativeRel;
1710-
auto nonRelative =
1711-
llvm::partition(relocs, [=](auto &r) { return r.type == relativeRel; });
1689+
if (combreloc) {
1690+
auto nonRelative = relocs.begin() + numRelativeRelocs;
17121691
parallelSort(relocs.begin(), nonRelative,
17131692
[&](auto &a, auto &b) { return a.r_offset < b.r_offset; });
17141693
// Non-relative relocations are few, so don't bother with parallelSort.
17151694
std::sort(nonRelative, relocs.end(), [&](auto &a, auto &b) {
17161695
return std::tie(a.r_sym, a.r_offset) < std::tie(b.r_sym, b.r_offset);
17171696
});
17181697
}
1698+
}
1699+
1700+
template <class ELFT>
1701+
RelocationSection<ELFT>::RelocationSection(StringRef name, bool combreloc)
1702+
: RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
1703+
config->isRela ? DT_RELA : DT_REL,
1704+
config->isRela ? DT_RELASZ : DT_RELSZ, combreloc) {
1705+
this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
1706+
}
17191707

1708+
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
1709+
computeRels();
17201710
for (const DynamicReloc &rel : relocs) {
1721-
encodeDynamicReloc<ELFT>(reinterpret_cast<Elf_Rela *>(buf), rel);
1711+
auto *p = reinterpret_cast<Elf_Rela *>(buf);
1712+
p->r_offset = rel.r_offset;
1713+
p->setSymbolAndType(rel.r_sym, rel.type, config->isMips64EL);
1714+
if (config->isRela)
1715+
p->r_addend = rel.addend;
17221716
buf += config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
17231717
}
17241718
}
17251719

1720+
RelrBaseSection::RelrBaseSection()
1721+
: SyntheticSection(SHF_ALLOC,
1722+
config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
1723+
config->wordsize, ".relr.dyn") {}
1724+
17261725
template <class ELFT>
17271726
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
17281727
StringRef name)
17291728
: RelocationBaseSection(
17301729
name, config->isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
17311730
config->isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
1732-
config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
1731+
config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ,
1732+
/*combreloc=*/false) {
17331733
this->entsize = 1;
17341734
}
17351735

lld/ELF/SyntheticSections.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,11 @@ template <class ELFT> class DynamicSection final : public SyntheticSection {
515515
class RelocationBaseSection : public SyntheticSection {
516516
public:
517517
RelocationBaseSection(StringRef name, uint32_t type, int32_t dynamicTag,
518-
int32_t sizeDynamicTag);
518+
int32_t sizeDynamicTag, bool combreloc);
519519
/// Add a dynamic relocation without writing an addend to the output section.
520520
/// This overload can be used if the addends are written directly instead of
521521
/// using relocations on the input section (e.g. MipsGotSection::writeTo()).
522-
void addReloc(const DynamicReloc &reloc);
522+
void addReloc(const DynamicReloc &reloc) { relocs.push_back(reloc); }
523523
/// Add a dynamic relocation against \p sym with an optional addend.
524524
void addSymbolReloc(RelType dynType, InputSectionBase &isec,
525525
uint64_t offsetInSec, Symbol &sym, int64_t addend = 0,
@@ -541,6 +541,7 @@ class RelocationBaseSection : public SyntheticSection {
541541
bool isNeeded() const override { return !relocs.empty(); }
542542
size_t getSize() const override { return relocs.size() * this->entsize; }
543543
size_t getRelativeRelocCount() const { return numRelativeRelocs; }
544+
void partitionRels();
544545
void finalizeContents() override;
545546
static bool classof(const SectionBase *d) {
546547
return SyntheticSection::classof(d) &&
@@ -551,7 +552,9 @@ class RelocationBaseSection : public SyntheticSection {
551552
SmallVector<DynamicReloc, 0> relocs;
552553

553554
protected:
554-
size_t numRelativeRelocs = 0;
555+
void computeRels();
556+
size_t numRelativeRelocs = 0; // used by -z combreloc
557+
bool combreloc;
555558
};
556559

557560
template <class ELFT>
@@ -560,11 +563,8 @@ class RelocationSection final : public RelocationBaseSection {
560563
using Elf_Rela = typename ELFT::Rela;
561564

562565
public:
563-
RelocationSection(StringRef name, bool sort);
566+
RelocationSection(StringRef name, bool combreloc);
564567
void writeTo(uint8_t *buf) override;
565-
566-
private:
567-
bool sort;
568568
};
569569

570570
template <class ELFT>

lld/ELF/Writer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2086,11 +2086,16 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
20862086
// Dynamic section must be the last one in this list and dynamic
20872087
// symbol table section (dynSymTab) must be the first one.
20882088
for (Partition &part : partitions) {
2089+
if (part.relaDyn) {
2090+
// Compute DT_RELACOUNT to be used by part.dynamic.
2091+
part.relaDyn->partitionRels();
2092+
finalizeSynthetic(part.relaDyn.get());
2093+
}
2094+
20892095
finalizeSynthetic(part.dynSymTab.get());
20902096
finalizeSynthetic(part.gnuHashTab.get());
20912097
finalizeSynthetic(part.hashTab.get());
20922098
finalizeSynthetic(part.verDef.get());
2093-
finalizeSynthetic(part.relaDyn.get());
20942099
finalizeSynthetic(part.relrDyn.get());
20952100
finalizeSynthetic(part.ehFrameHdr.get());
20962101
finalizeSynthetic(part.verSym.get());

lld/test/ELF/pack-dyn-relocs.s

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -77,42 +77,43 @@
7777
/// by the larger groups of relative relocations (i.e. the 8 and 9 followed
7878
/// by the 7.)
7979
// ANDROID32: Section ({{.+}}) .rel.dyn {
80+
// ANDROID32-NEXT: 0x3024C R_ARM_RELATIVE -
81+
// ANDROID32-NEXT: 0x30250 R_ARM_RELATIVE -
8082
// ANDROID32-NEXT: 0x30254 R_ARM_RELATIVE -
8183
// ANDROID32-NEXT: 0x30258 R_ARM_RELATIVE -
8284
// ANDROID32-NEXT: 0x3025C R_ARM_RELATIVE -
8385
// ANDROID32-NEXT: 0x30260 R_ARM_RELATIVE -
8486
// ANDROID32-NEXT: 0x30264 R_ARM_RELATIVE -
8587
// ANDROID32-NEXT: 0x30268 R_ARM_RELATIVE -
86-
// ANDROID32-NEXT: 0x3026C R_ARM_RELATIVE -
87-
// ANDROID32-NEXT: 0x30270 R_ARM_RELATIVE -
8888

89+
// ANDROID32-NEXT: 0x30294 R_ARM_RELATIVE -
90+
// ANDROID32-NEXT: 0x30298 R_ARM_RELATIVE -
8991
// ANDROID32-NEXT: 0x3029C R_ARM_RELATIVE -
9092
// ANDROID32-NEXT: 0x302A0 R_ARM_RELATIVE -
9193
// ANDROID32-NEXT: 0x302A4 R_ARM_RELATIVE -
9294
// ANDROID32-NEXT: 0x302A8 R_ARM_RELATIVE -
9395
// ANDROID32-NEXT: 0x302AC R_ARM_RELATIVE -
9496
// ANDROID32-NEXT: 0x302B0 R_ARM_RELATIVE -
9597
// ANDROID32-NEXT: 0x302B4 R_ARM_RELATIVE -
96-
// ANDROID32-NEXT: 0x302B8 R_ARM_RELATIVE -
97-
// ANDROID32-NEXT: 0x302BC R_ARM_RELATIVE -
98+
99+
// ANDROID32-NEXT: 0x30270 R_ARM_RELATIVE -
100+
// ANDROID32-NEXT: 0x30274 R_ARM_RELATIVE -
98101
// ANDROID32-NEXT: 0x30278 R_ARM_RELATIVE -
99102
// ANDROID32-NEXT: 0x3027C R_ARM_RELATIVE -
100103
// ANDROID32-NEXT: 0x30280 R_ARM_RELATIVE -
101104
// ANDROID32-NEXT: 0x30284 R_ARM_RELATIVE -
102105
// ANDROID32-NEXT: 0x30288 R_ARM_RELATIVE -
103-
// ANDROID32-NEXT: 0x3028C R_ARM_RELATIVE -
104-
// ANDROID32-NEXT: 0x30290 R_ARM_RELATIVE -
105-
// ANDROID32-NEXT: 0x302C1 R_ARM_RELATIVE -
106106

107-
// ANDROID32-NEXT: 0x30274 R_ARM_ABS32 bar2
108-
// ANDROID32-NEXT: 0x30298 R_ARM_ABS32 bar2
107+
// ANDROID32-NEXT: 0x302B9 R_ARM_RELATIVE -
108+
109+
// ANDROID32-NEXT: 0x3026C R_ARM_ABS32 bar2
110+
// ANDROID32-NEXT: 0x30290 R_ARM_ABS32 bar2
111+
// ANDROID32-NEXT: 0x302BD R_ARM_ABS32 bar2
112+
// ANDROID32-NEXT: 0x302C1 R_ARM_ABS32 bar2
109113
// ANDROID32-NEXT: 0x302C5 R_ARM_ABS32 bar2
110114
// ANDROID32-NEXT: 0x302C9 R_ARM_ABS32 bar2
111115
// ANDROID32-NEXT: 0x302CD R_ARM_ABS32 bar2
112-
// ANDROID32-NEXT: 0x302D1 R_ARM_ABS32 bar2
113-
// ANDROID32-NEXT: 0x302D5 R_ARM_ABS32 bar2
114-
115-
// ANDROID32-NEXT: 0x30294 R_ARM_ABS32 zed2 0x0
116+
// ANDROID32-NEXT: 0x3028C R_ARM_ABS32 zed2
116117
// ANDROID32-NEXT: }
117118

118119
// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.a32.o %t.a32.so -o %t4.a32
@@ -225,6 +226,7 @@
225226
// UNPACKED64-NEXT: 0x30760 R_AARCH64_RELATIVE - 0x9
226227

227228
// UNPACKED64-NEXT: 0x30769 R_AARCH64_RELATIVE - 0xA
229+
228230
// UNPACKED64-NEXT: 0x306D0 R_AARCH64_ABS64 bar2 0x1
229231
// UNPACKED64-NEXT: 0x30718 R_AARCH64_ABS64 bar2 0x0
230232
// UNPACKED64-NEXT: 0x30771 R_AARCH64_ABS64 bar2 0x0
@@ -259,42 +261,42 @@
259261
// ANDROID64-HEADERS: 0x0000000060000012 ANDROID_RELASZ [[SIZE]]
260262

261263
// ANDROID64: Section ({{.+}}) .rela.dyn {
262-
// ANDROID64-NEXT: 0x303F0 R_AARCH64_RELATIVE - 0x1
263-
// ANDROID64-NEXT: 0x303F8 R_AARCH64_RELATIVE - 0x2
264-
// ANDROID64-NEXT: 0x30400 R_AARCH64_RELATIVE - 0x3
265-
// ANDROID64-NEXT: 0x30408 R_AARCH64_RELATIVE - 0x4
266-
// ANDROID64-NEXT: 0x30410 R_AARCH64_RELATIVE - 0x5
267-
// ANDROID64-NEXT: 0x30418 R_AARCH64_RELATIVE - 0x6
268-
// ANDROID64-NEXT: 0x30420 R_AARCH64_RELATIVE - 0x7
269-
// ANDROID64-NEXT: 0x30428 R_AARCH64_RELATIVE - 0x8
270-
271-
// ANDROID64-NEXT: 0x30480 R_AARCH64_RELATIVE - 0x1
272-
// ANDROID64-NEXT: 0x30488 R_AARCH64_RELATIVE - 0x2
273-
// ANDROID64-NEXT: 0x30490 R_AARCH64_RELATIVE - 0x3
274-
// ANDROID64-NEXT: 0x30498 R_AARCH64_RELATIVE - 0x4
275-
// ANDROID64-NEXT: 0x304A0 R_AARCH64_RELATIVE - 0x5
276-
// ANDROID64-NEXT: 0x304A8 R_AARCH64_RELATIVE - 0x6
277-
// ANDROID64-NEXT: 0x304B0 R_AARCH64_RELATIVE - 0x7
278-
// ANDROID64-NEXT: 0x304B8 R_AARCH64_RELATIVE - 0x8
279-
// ANDROID64-NEXT: 0x304C0 R_AARCH64_RELATIVE - 0x9
280-
281-
// ANDROID64-NEXT: 0x30438 R_AARCH64_RELATIVE - 0x1
282-
// ANDROID64-NEXT: 0x30440 R_AARCH64_RELATIVE - 0x2
283-
// ANDROID64-NEXT: 0x30448 R_AARCH64_RELATIVE - 0x3
284-
// ANDROID64-NEXT: 0x30450 R_AARCH64_RELATIVE - 0x4
285-
// ANDROID64-NEXT: 0x30458 R_AARCH64_RELATIVE - 0x5
286-
// ANDROID64-NEXT: 0x30460 R_AARCH64_RELATIVE - 0x6
287-
// ANDROID64-NEXT: 0x30468 R_AARCH64_RELATIVE - 0x7
288-
// ANDROID64-NEXT: 0x304C9 R_AARCH64_RELATIVE - 0xA
289-
290-
// ANDROID64-NEXT: 0x30478 R_AARCH64_ABS64 bar2 0x0
291-
// ANDROID64-NEXT: 0x304D1 R_AARCH64_ABS64 bar2 0x0
292-
// ANDROID64-NEXT: 0x304D9 R_AARCH64_ABS64 bar2 0x0
293-
// ANDROID64-NEXT: 0x304F1 R_AARCH64_ABS64 bar2 0x0
294-
// ANDROID64-NEXT: 0x30430 R_AARCH64_ABS64 bar2 0x1
295-
// ANDROID64-NEXT: 0x30470 R_AARCH64_ABS64 zed2 0x0
296-
// ANDROID64-NEXT: 0x304E1 R_AARCH64_ABS64 bar2 0x1
297-
// ANDROID64-NEXT: 0x304E9 R_AARCH64_ABS64 bar2 0x1
264+
// ANDROID64-NEXT: 0x303E0 R_AARCH64_RELATIVE - 0x1
265+
// ANDROID64-NEXT: 0x303E8 R_AARCH64_RELATIVE - 0x2
266+
// ANDROID64-NEXT: 0x303F0 R_AARCH64_RELATIVE - 0x3
267+
// ANDROID64-NEXT: 0x303F8 R_AARCH64_RELATIVE - 0x4
268+
// ANDROID64-NEXT: 0x30400 R_AARCH64_RELATIVE - 0x5
269+
// ANDROID64-NEXT: 0x30408 R_AARCH64_RELATIVE - 0x6
270+
// ANDROID64-NEXT: 0x30410 R_AARCH64_RELATIVE - 0x7
271+
// ANDROID64-NEXT: 0x30418 R_AARCH64_RELATIVE - 0x8
272+
// ANDROID64-NEXT: 0x30470 R_AARCH64_RELATIVE - 0x1
273+
// ANDROID64-NEXT: 0x30478 R_AARCH64_RELATIVE - 0x2
274+
// ANDROID64-NEXT: 0x30480 R_AARCH64_RELATIVE - 0x3
275+
// ANDROID64-NEXT: 0x30488 R_AARCH64_RELATIVE - 0x4
276+
// ANDROID64-NEXT: 0x30490 R_AARCH64_RELATIVE - 0x5
277+
// ANDROID64-NEXT: 0x30498 R_AARCH64_RELATIVE - 0x6
278+
// ANDROID64-NEXT: 0x304A0 R_AARCH64_RELATIVE - 0x7
279+
// ANDROID64-NEXT: 0x304A8 R_AARCH64_RELATIVE - 0x8
280+
// ANDROID64-NEXT: 0x304B0 R_AARCH64_RELATIVE - 0x9
281+
282+
// ANDROID64-NEXT: 0x30428 R_AARCH64_RELATIVE - 0x1
283+
// ANDROID64-NEXT: 0x30430 R_AARCH64_RELATIVE - 0x2
284+
// ANDROID64-NEXT: 0x30438 R_AARCH64_RELATIVE - 0x3
285+
// ANDROID64-NEXT: 0x30440 R_AARCH64_RELATIVE - 0x4
286+
// ANDROID64-NEXT: 0x30448 R_AARCH64_RELATIVE - 0x5
287+
// ANDROID64-NEXT: 0x30450 R_AARCH64_RELATIVE - 0x6
288+
// ANDROID64-NEXT: 0x30458 R_AARCH64_RELATIVE - 0x7
289+
290+
// ANDROID64-NEXT: 0x304B9 R_AARCH64_RELATIVE - 0xA
291+
292+
// ANDROID64-NEXT: 0x30468 R_AARCH64_ABS64 bar2 0x0
293+
// ANDROID64-NEXT: 0x304C1 R_AARCH64_ABS64 bar2 0x0
294+
// ANDROID64-NEXT: 0x304C9 R_AARCH64_ABS64 bar2 0x0
295+
// ANDROID64-NEXT: 0x304E1 R_AARCH64_ABS64 bar2 0x0
296+
// ANDROID64-NEXT: 0x30420 R_AARCH64_ABS64 bar2 0x1
297+
// ANDROID64-NEXT: 0x30460 R_AARCH64_ABS64 zed2 0x0
298+
// ANDROID64-NEXT: 0x304D1 R_AARCH64_ABS64 bar2 0x1
299+
// ANDROID64-NEXT: 0x304D9 R_AARCH64_ABS64 bar2 0x1
298300
// ANDROID64-NEXT: }
299301

300302
// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.a64.o %t.a64.so -o %t4.a64

0 commit comments

Comments
 (0)