mirror of https://github.com/dynup/kpatch
create-klp-module: get rid of redundant kpatch_relocation.offset field
kpatch_relocation's 'dest' addend and 'offset' fields are redundant. In fact, the 'offset' field isn't always accurate because it doesn't have a relocation, so its value doesn't adjust when multiple .o files are combined. Just use the 'dest' addend instead. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
parent
f0518ef58a
commit
c6c153431f
|
@ -2517,7 +2517,6 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
krelas[index].addend = rela->addend;
|
krelas[index].addend = rela->addend;
|
||||||
krelas[index].type = rela->type;
|
krelas[index].type = rela->type;
|
||||||
krelas[index].external = external;
|
krelas[index].external = external;
|
||||||
krelas[index].offset = rela->offset;
|
|
||||||
|
|
||||||
/* add rela to fill in krelas[index].dest field */
|
/* add rela to fill in krelas[index].dest field */
|
||||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||||
|
|
|
@ -160,7 +160,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||||
struct symbol *sym, *dest;
|
struct symbol *sym, *dest;
|
||||||
struct rela *rela;
|
struct rela *rela;
|
||||||
char *objname;
|
char *objname;
|
||||||
int nr, index, offset, toc_offset;
|
int nr, index, offset, dest_off;
|
||||||
|
|
||||||
krelas = krelasec->data->d_buf;
|
krelas = krelasec->data->d_buf;
|
||||||
nr = krelasec->data->d_size / sizeof(*krelas);
|
nr = krelasec->data->d_size / sizeof(*krelas);
|
||||||
|
@ -168,48 +168,16 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||||
for (index = 0; index < nr; index++) {
|
for (index = 0; index < nr; index++) {
|
||||||
offset = index * sizeof(*krelas);
|
offset = index * sizeof(*krelas);
|
||||||
|
|
||||||
/* Get the base section to which the rela applies */
|
/* Get the rela dest sym + offset */
|
||||||
rela = find_rela_by_offset(krelasec->rela,
|
rela = find_rela_by_offset(krelasec->rela,
|
||||||
offset + offsetof(struct kpatch_relocation, dest));
|
offset + offsetof(struct kpatch_relocation, dest));
|
||||||
if (!rela)
|
if (!rela)
|
||||||
ERROR("find_rela_by_offset");
|
ERROR("find_rela_by_offset");
|
||||||
|
|
||||||
/*
|
|
||||||
* Patched file:
|
|
||||||
* Relocation section '.rela.toc' at offset 0x46358 contains 60 entries:
|
|
||||||
* Offset Info Type Symbol's Value Symbol's Name + Addend
|
|
||||||
* 0000000000000000 000001ee00000026 R_PPC64_ADDR64 0000000000000000 jiffies + 0
|
|
||||||
* 0000000000000008 0000009400000026 R_PPC64_ADDR64 0000000000000000 __tracepoints + 0
|
|
||||||
* 0000000000000010 000001db00000026 R_PPC64_ADDR64 0000000000000000 __cpu_online_mask + 0
|
|
||||||
* 0000000000000018 0000009c00000026 R_PPC64_ADDR64 0000000000000000 .data..percpu + 0
|
|
||||||
* 0000000000000020 000001ac00000026 R_PPC64_ADDR64 0000000000000000 __per_cpu_offset + 0
|
|
||||||
* 0000000000000028 0000006900000026 R_PPC64_ADDR64 0000000000000000 .rodata.str1.8 + 0
|
|
||||||
* [...]
|
|
||||||
*
|
|
||||||
* Output file:
|
|
||||||
* Relocation section '.rela.toc' at offset 0x1270 contains 58 entries:
|
|
||||||
* Offset Info Type Symbol's Value Symbol's Name + Addend
|
|
||||||
* 0000000000000000 0000000700000026 R_PPC64_ADDR64 0000000000000000 .data + 0
|
|
||||||
* 0000000000000008 0000003c00000026 R_PPC64_ADDR64 0000000000000000 __kpatch_funcs + 0
|
|
||||||
* 0000000000000010 0000005300000026 R_PPC64_ADDR64 0000000000000000 kmalloc_caches + 0
|
|
||||||
* 0000000000000018 0000001100000026 R_PPC64_ADDR64 0000000000000000 .rodata.str1.8 + 0
|
|
||||||
* 0000000000000020 0000001600000026 R_PPC64_ADDR64 0000000000000000 .bss + 0
|
|
||||||
* 0000000000000028 0000004200000026 R_PPC64_ADDR64 0000000000000038 __kpatch_funcs_end + 0
|
|
||||||
* 0000000000000030 0000003400000026 R_PPC64_ADDR64 0000000000000000 __this_module + 0
|
|
||||||
* 0000000000000038 0000004d00000026 R_PPC64_ADDR64 0000000000000000 jiffies + 0
|
|
||||||
* 0000000000000048 0000004500000026 R_PPC64_ADDR64 0000000000000000 __cpu_online_mask + 0
|
|
||||||
* 0000000000000058 0000003900000026 R_PPC64_ADDR64 0000000000000000 __per_cpu_offset + 0
|
|
||||||
* [...]
|
|
||||||
*
|
|
||||||
* On ppc64le, when .o files are linked together, the .toc
|
|
||||||
* entries might get re-arranged. Capture the new .toc rela
|
|
||||||
* offset value, which is used below to set the rela->addend.
|
|
||||||
*/
|
|
||||||
toc_offset = rela->addend;
|
|
||||||
|
|
||||||
dest = rela->sym;
|
dest = rela->sym;
|
||||||
|
dest_off = rela->addend;
|
||||||
|
|
||||||
/* Get the name of the object the rela belongs to */
|
/* Get the name of the object the dest belongs to */
|
||||||
rela = find_rela_by_offset(krelasec->rela,
|
rela = find_rela_by_offset(krelasec->rela,
|
||||||
offset + offsetof(struct kpatch_relocation, objname));
|
offset + offsetof(struct kpatch_relocation, objname));
|
||||||
if (!rela)
|
if (!rela)
|
||||||
|
@ -219,31 +187,31 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||||
if (!objname)
|
if (!objname)
|
||||||
ERROR("strdup");
|
ERROR("strdup");
|
||||||
|
|
||||||
/* Get the corresponding .kpatch.symbol entry */
|
/* Get the .kpatch.symbol entry for the rela src */
|
||||||
rela = find_rela_by_offset(krelasec->rela,
|
rela = find_rela_by_offset(krelasec->rela,
|
||||||
offset + offsetof(struct kpatch_relocation, ksym));
|
offset + offsetof(struct kpatch_relocation, ksym));
|
||||||
if (!rela)
|
if (!rela)
|
||||||
ERROR("find_rela_by_offset");
|
ERROR("find_rela_by_offset");
|
||||||
|
|
||||||
/* Create (or find) a real symbol out of the .kpatch.symbol entry */
|
/* Create (or find) a klp symbol from the rela src entry */
|
||||||
sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend);
|
sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend);
|
||||||
if (!sym)
|
if (!sym)
|
||||||
ERROR("error finding or adding ksym to symtab");
|
ERROR("error finding or adding ksym to symtab");
|
||||||
|
|
||||||
/* Create (or find) the .klp.rela. section for this dest sec and object */
|
/* Create (or find) the .klp.rela. section for the dest sec and object */
|
||||||
klp_relasec = find_or_add_klp_relasec(kelf, dest->sec, objname);
|
klp_relasec = find_or_add_klp_relasec(kelf, dest->sec, objname);
|
||||||
if (!klp_relasec)
|
if (!klp_relasec)
|
||||||
ERROR("error finding or adding klp relasec");
|
ERROR("error finding or adding klp relasec");
|
||||||
|
|
||||||
/* Add the rela to the .klp.rela. section */
|
/* Add the klp rela to the .klp.rela. section */
|
||||||
ALLOC_LINK(rela, &klp_relasec->relas);
|
ALLOC_LINK(rela, &klp_relasec->relas);
|
||||||
|
rela->type = krelas[index].type;
|
||||||
rela->sym = sym;
|
rela->sym = sym;
|
||||||
rela->addend = krelas[index].addend;
|
rela->addend = krelas[index].addend;
|
||||||
rela->type = krelas[index].type;
|
|
||||||
if (!strcmp(dest->sec->name, ".toc"))
|
if (!strcmp(dest->sec->name, ".toc"))
|
||||||
rela->offset = toc_offset;
|
rela->offset = dest_off;
|
||||||
else
|
else
|
||||||
rela->offset = krelas[index].offset + dest->sym.st_value;
|
rela->offset = dest_off + dest->sym.st_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ struct kpatch_relocation {
|
||||||
unsigned long dest;
|
unsigned long dest;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
int addend;
|
int addend;
|
||||||
int offset;
|
|
||||||
int external;
|
int external;
|
||||||
char *objname; /* object to which this rela applies to */
|
char *objname; /* object to which this rela applies to */
|
||||||
struct kpatch_symbol *ksym;
|
struct kpatch_symbol *ksym;
|
||||||
|
|
Loading…
Reference in New Issue