mirror of https://github.com/dynup/kpatch
create-diff-object: support ppc64le relative jump labels
RHEL-9 integration tests revealed that the kernel now makes use of R_PPC64_REL64 relocations in the jump table, but need_dynrela() contains code to specifically skip any R_PPC64_REL64 type when determining if a relocation should be turned into dynrela. Kamalesh Babulal explains: I tried digging a little deeper and the upstream Kernel commit b0b3b2c78ec (powerpc: Switch to relative jump labels) in v5.13, introduced the change of generating relocation entries of type R_PPC64_REL64, instead of absolute relocation type R_PPC64_ADDR64: Relocation section '.rela__jump_table' at offset 0x1a87d8 contains 303 entries: Offset Info Type Symbol's Value Symbol's Name + Addend ... 00000000000003c8 000007910000002c R_PPC64_REL64 0000000000000000 __tracepoint_netif_receive_skb + 8 ... Relax the existing check in need_dynrela() for .rela__jump_table R_PPC64_REL64 relocations in case we need dynrelas for them. Fixes: #1212 Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
This commit is contained in:
parent
cc5200fbf8
commit
4f51ee7fa3
|
@ -2993,7 +2993,7 @@ static int function_ptr_rela(const struct rela *rela)
|
|||
rela->type == R_PPC64_TOC16_LO_DS));
|
||||
}
|
||||
|
||||
static bool need_dynrela(struct lookup_table *table, const struct rela *rela)
|
||||
static bool need_dynrela(struct lookup_table *table, struct section *sec, const struct rela *rela)
|
||||
{
|
||||
struct lookup_result symbol;
|
||||
|
||||
|
@ -3002,7 +3002,11 @@ static bool need_dynrela(struct lookup_table *table, const struct rela *rela)
|
|||
* should never be converted to dynrelas.
|
||||
*/
|
||||
if (rela->type == R_PPC64_REL16_HA || rela->type == R_PPC64_REL16_LO ||
|
||||
rela->type == R_PPC64_REL64 || rela->type == R_PPC64_ENTRY)
|
||||
rela->type == R_PPC64_ENTRY)
|
||||
return false;
|
||||
|
||||
/* v5.13+ kernels use relative jump labels */
|
||||
if (rela->type == R_PPC64_REL64 && strcmp(sec->name, ".rela__jump_table"))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
@ -3192,7 +3196,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|||
* internal symbol function pointer check which is done
|
||||
* via .toc indirection in need_dynrela().
|
||||
*/
|
||||
if (need_dynrela(table, rela))
|
||||
if (need_dynrela(table, sec, rela))
|
||||
toc_rela(rela)->need_dynrela = 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue