lld: fix addends with partial linking
[ELF] Update addends in non-allocatable sections for REL targets when creating a relocatable output. LLVM PR: 37735 LLVM Differential Revision: https://reviews.llvm.org/D48929 PR: 225128 Obtained from: LLVM r336799 by Igor Kudrin
This commit is contained in:
parent
daa1e39110
commit
33683c3d3c
@ -686,6 +686,23 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
|
||||
}
|
||||
}
|
||||
|
||||
// This is used when '-r' is given.
|
||||
// For REL targets, InputSection::copyRelocations() may store artificial
|
||||
// relocations aimed to update addends. They are handled in relocateAlloc()
|
||||
// for allocatable sections, and this function does the same for
|
||||
// non-allocatable sections, such as sections with debug information.
|
||||
static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) {
|
||||
const unsigned Bits = Config->Is64 ? 64 : 32;
|
||||
|
||||
for (const Relocation &Rel : Sec->Relocations) {
|
||||
// InputSection::copyRelocations() adds only R_ABS relocations.
|
||||
assert(Rel.Expr == R_ABS);
|
||||
uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff;
|
||||
uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits);
|
||||
Target->relocateOne(BufLoc, Rel.Type, TargetVA);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
|
||||
if (Flags & SHF_ALLOC) {
|
||||
@ -694,7 +711,9 @@ void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
|
||||
}
|
||||
|
||||
auto *Sec = cast<InputSection>(this);
|
||||
if (Sec->AreRelocsRela)
|
||||
if (Config->Relocatable)
|
||||
relocateNonAllocForRelocatable(Sec, Buf);
|
||||
else if (Sec->AreRelocsRela)
|
||||
Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>());
|
||||
else
|
||||
Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>());
|
||||
|
Loading…
Reference in New Issue
Block a user