[ELF] Always separate relative relocations regardless of -z combreloc (#187964)
Remove the combreloc guard from addReloc and mergeRels so that relative relocations are always routed to relativeRelocs, even with -z nocombreloc or --pack-dyn-relocs=android. Update AndroidPackedRelocationSection::updateAllocSize to iterate both relativeRelocs and relocs.
This commit is contained in:
parent
076226f378
commit
dc4df5da88
@ -1519,9 +1519,11 @@ void RelocationBaseSection::mergeRels() {
|
||||
|
||||
void RelocationBaseSection::finalizeContents() {
|
||||
mergeRels();
|
||||
// Cache the count for DT_RELACOUNT. This must not change after
|
||||
// DynamicSection::finalizeContents sizes the .dynamic section.
|
||||
numRelativeRelocs = relativeRelocs.size();
|
||||
// Cache the count for DT_RELACOUNT. DynamicSection<ELFT>::computeContents
|
||||
// uses ctx.arg.zCombreloc (not the per-section combreloc) to decide whether
|
||||
// to emit DT_RELACOUNT, so this must match.
|
||||
if (combreloc)
|
||||
numRelativeRelocs = relativeRelocs.size();
|
||||
SymbolTableBaseSection *symTab = getPartition(ctx).dynSymTab.get();
|
||||
|
||||
// When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
|
||||
@ -1685,23 +1687,22 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
|
||||
// The format header includes the number of relocations and the initial
|
||||
// offset (we set this to zero because the first relocation group will
|
||||
// perform the initial adjustment).
|
||||
add(relocs.size());
|
||||
add(relativeRelocs.size() + relocs.size());
|
||||
add(0);
|
||||
|
||||
std::vector<Elf_Rela> relatives, nonRelatives;
|
||||
|
||||
for (const DynamicReloc &rel : relocs) {
|
||||
SymbolTableBaseSection *symTab = getPartition(ctx).dynSymTab.get();
|
||||
auto makeRela = [&](const DynamicReloc &rel) {
|
||||
Elf_Rela r;
|
||||
r.r_offset = rel.getOffset();
|
||||
r.setSymbolAndType(rel.getSymIndex(getPartition(ctx).dynSymTab.get()),
|
||||
rel.type, false);
|
||||
r.setSymbolAndType(rel.getSymIndex(symTab), rel.type, false);
|
||||
r.r_addend = ctx.arg.isRela ? rel.computeAddend(ctx) : 0;
|
||||
|
||||
if (r.getType(ctx.arg.isMips64EL) == ctx.target->relativeRel)
|
||||
relatives.push_back(r);
|
||||
else
|
||||
nonRelatives.push_back(r);
|
||||
}
|
||||
return r;
|
||||
};
|
||||
std::vector<Elf_Rela> relatives, nonRelatives;
|
||||
for (const DynamicReloc &rel : relativeRelocs)
|
||||
relatives.push_back(makeRela(rel));
|
||||
for (const DynamicReloc &rel : relocs)
|
||||
nonRelatives.push_back(makeRela(rel));
|
||||
|
||||
llvm::sort(relatives, [](const Elf_Rel &a, const Elf_Rel &b) {
|
||||
return a.r_offset < b.r_offset;
|
||||
|
||||
@ -495,7 +495,7 @@ public:
|
||||
/// This overload can be used if the addends are written directly instead of
|
||||
/// using relocations on the input section (e.g. MipsGotSection::writeTo()).
|
||||
template <bool shard = false> void addReloc(const DynamicReloc &reloc) {
|
||||
if (combreloc && reloc.type == relativeRel)
|
||||
if (reloc.type == relativeRel)
|
||||
relativeRelocs.push_back(reloc);
|
||||
else
|
||||
relocs.push_back(reloc);
|
||||
|
||||
@ -31,12 +31,12 @@
|
||||
# NOCOMB-NOT: RELACOUNT
|
||||
# NOCOMB: Relocations [
|
||||
# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn {
|
||||
# NOCOMB-NEXT: 0x3418 R_X86_64_RELATIVE - 0x3420
|
||||
# NOCOMB-NEXT: 0x33F8 R_X86_64_64 aaa 0x0
|
||||
# NOCOMB-NEXT: 0x3400 R_X86_64_64 ccc 0x0
|
||||
# NOCOMB-NEXT: 0x3408 R_X86_64_64 bbb 0x0
|
||||
# NOCOMB-NEXT: 0x3410 R_X86_64_64 aaa 0x0
|
||||
# NOCOMB-NEXT: 0x23F0 R_X86_64_GLOB_DAT aaa 0x0
|
||||
# NOCOMB-NEXT: 0x3418 R_X86_64_RELATIVE - 0x3420
|
||||
# NOCOMB-NEXT: }
|
||||
|
||||
.globl aaa, bbb, ccc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user