mirror of
https://github.com/dynup/kpatch
synced 2025-02-15 00:47:00 +00:00
create-diff-object: fix ppc64le kpatch_replace_sections_syms() bundling assumption
kpatch_replace_sections_syms() assumes that all bundled symbols start at section offset zero. With ppc64le and GCC 6+, that assumption is no longer accurate. When replacing a rela symbol section with its corresponding symbol, adjust the addend as necessary. Also, with this fix in place, the workaround in create_klp_relasecs_and_syms() can be removed. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
parent
bc2d5aa815
commit
f0518ef58a
@ -1113,6 +1113,13 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
|
|||||||
*/
|
*/
|
||||||
if (rela->sym->sec && rela->sym->sec->sym) {
|
if (rela->sym->sec && rela->sym->sec->sym) {
|
||||||
rela->sym = rela->sym->sec->sym;
|
rela->sym = rela->sym->sec->sym;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ppc64le: a GCC 6+ bundled function is at
|
||||||
|
* offset 8 in its section.
|
||||||
|
*/
|
||||||
|
rela->addend -= rela->sym->sym.st_value;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,25 +238,12 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
|||||||
/* Add the rela to the .klp.rela. section */
|
/* Add the rela to the .klp.rela. section */
|
||||||
ALLOC_LINK(rela, &klp_relasec->relas);
|
ALLOC_LINK(rela, &klp_relasec->relas);
|
||||||
rela->sym = sym;
|
rela->sym = sym;
|
||||||
|
rela->addend = krelas[index].addend;
|
||||||
rela->type = krelas[index].type;
|
rela->type = krelas[index].type;
|
||||||
if (!strcmp(dest->sec->name, ".toc"))
|
if (!strcmp(dest->sec->name, ".toc"))
|
||||||
rela->offset = toc_offset;
|
rela->offset = toc_offset;
|
||||||
else
|
else
|
||||||
rela->offset = krelas[index].offset + dest->sym.st_value;
|
rela->offset = krelas[index].offset + dest->sym.st_value;
|
||||||
|
|
||||||
/*
|
|
||||||
* GCC 6+ adds 0x8 to the offset of every local function entry
|
|
||||||
* in the .toc section, for avoiding the setup of the toc when
|
|
||||||
* the function is called locally. But when the previously
|
|
||||||
* local function becomes global, we don't want to skip the
|
|
||||||
* .toc setup anymore.
|
|
||||||
*/
|
|
||||||
if (!strcmp(dest->sec->name, ".toc") &&
|
|
||||||
rela->sym->type == STT_FUNC && rela->sym->bind == STB_LOCAL) {
|
|
||||||
rela->addend = 0;
|
|
||||||
} else {
|
|
||||||
rela->addend = krelas[index].addend;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user