mirror of
https://github.com/dynup/kpatch
synced 2025-03-25 04:16:39 +00:00
create-diff-object: Refactor rela_equal() using toc_rela()
Heavy lifting of reading .toc rela entries for rela symbols referring to .toc + offset, can be simplified using toc_rela() in rela_equal() and remove the #ifdery guarding PowerPC code. This patch also trims the commentary related to PowerPC. Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
This commit is contained in:
parent
547f6eda1f
commit
ed14d8d332
@ -252,54 +252,22 @@ static int kpatch_mangled_strcmp(char *s1, char *s2)
|
|||||||
|
|
||||||
static int rela_equal(struct rela *rela1, struct rela *rela2)
|
static int rela_equal(struct rela *rela1, struct rela *rela2)
|
||||||
{
|
{
|
||||||
#ifdef __powerpc__
|
struct rela *rela_toc1, *rela_toc2;
|
||||||
struct section *toc_relasec1, *toc_relasec2;
|
|
||||||
struct rela *r_toc_relasec1, *r_toc_relasec2;
|
|
||||||
unsigned long toc_data1, toc_data2;
|
unsigned long toc_data1, toc_data2;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (rela1->type != rela2->type ||
|
if (rela1->type != rela2->type ||
|
||||||
rela1->offset != rela2->offset)
|
rela1->offset != rela2->offset)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (rela1->string)
|
|
||||||
return rela2->string && !strcmp(rela1->string, rela2->string);
|
|
||||||
|
|
||||||
#ifdef __powerpc__
|
|
||||||
/*
|
/*
|
||||||
* Relocation section '.rela.toc' at offset 0x91f0 contains 122 entries:
|
|
||||||
* Offset Info Type Symbol's Value Symbol's Name + Addend
|
|
||||||
* [...]
|
|
||||||
* 0000000000000090 0000001c00000026 R_PPC64_ADDR64 0000000000000000 .rodata.__dev_remove_pack.str1.8 + 0
|
|
||||||
* 0000000000000098 0000001a00000026 R_PPC64_ADDR64 0000000000000000 .rodata.__dev_getfirstbyhwtype.str1.8 + 0
|
|
||||||
* 00000000000000a0 0000001a00000026 R_PPC64_ADDR64 0000000000000000 .rodata.__dev_getfirstbyhwtype.str1.8 + 10
|
|
||||||
* 00000000000000a8 000000cb00000026 R_PPC64_ADDR64 0000000000000000 dev_base_lock + 0
|
|
||||||
*
|
|
||||||
* Relocation section '.rela.text.netdev_master_upper_dev_get' at offset 0xe38 contains 10 entries:
|
|
||||||
* Offset Info Type Symbol's Value Symbol's Name + Addend
|
|
||||||
* [...]
|
|
||||||
* 00000000000000a0 0000004e00000032 R_PPC64_TOC16_HA 0000000000000000 .toc + 98
|
|
||||||
* 00000000000000a8 0000004e00000040 R_PPC64_TOC16_LO_DS 0000000000000000 .toc + 98
|
|
||||||
* 00000000000000ac 0000004e00000032 R_PPC64_TOC16_HA 0000000000000000 .toc + a0
|
|
||||||
* 00000000000000b0 0000004e00000040 R_PPC64_TOC16_LO_DS 0000000000000000 .toc + a0
|
|
||||||
* 00000000000000b4 000000b90000000a R_PPC64_REL24 0000000000000000 printk + 0
|
|
||||||
* 00000000000000bc 000000a10000000a R_PPC64_REL24 0000000000000000 dump_stack + 0
|
|
||||||
*
|
|
||||||
* With -mcmodel=large on ppc64le, GCC might generate entries in the .toc
|
* With -mcmodel=large on ppc64le, GCC might generate entries in the .toc
|
||||||
* section for relocation symbol references. The .toc offsets may change
|
* section for relocation symbol references. The .toc offsets may change
|
||||||
* between the original and patched .o, so comparing ".toc + offset" isn't
|
* between the original and patched .o, so comparing ".toc + offset" isn't
|
||||||
* right. Compare the .toc-based symbols by reading the corresponding relas
|
* right. Compare the .toc-based symbols by reading the corresponding relas
|
||||||
* from the .toc section.
|
* from the .toc section.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(rela1->sym->name, ".toc") &&
|
rela_toc1 = toc_rela(rela1);
|
||||||
!strcmp(rela2->sym->name, ".toc")) {
|
if (!rela_toc1) {
|
||||||
|
|
||||||
toc_relasec1 = rela1->sym->sec->rela;
|
|
||||||
if (!toc_relasec1)
|
|
||||||
ERROR("cannot find .rela.toc");
|
|
||||||
|
|
||||||
r_toc_relasec1 = find_rela_by_offset(toc_relasec1, rela1->addend);
|
|
||||||
if (!r_toc_relasec1) {
|
|
||||||
/*
|
/*
|
||||||
* .toc section entries are mostly place holder for relocation entries, specified
|
* .toc section entries are mostly place holder for relocation entries, specified
|
||||||
* in .rela.toc section. Sometimes, .toc section may have constants as entries.
|
* in .rela.toc section. Sometimes, .toc section may have constants as entries.
|
||||||
@ -327,54 +295,37 @@ static int rela_equal(struct rela *rela1, struct rela *rela2)
|
|||||||
* Relocation section '.rela.text.select_task_rq_fair' at offset 0x90e98 contains 37 entries:
|
* Relocation section '.rela.text.select_task_rq_fair' at offset 0x90e98 contains 37 entries:
|
||||||
* Offset Info Type Symbol's Value Symbol's Name + Addend
|
* Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||||
* ...
|
* ...
|
||||||
* 0000000000000498 000000c90000000a R_PPC64_REL24 0000000000000000 __update_load_avg_blocked_se.isra.0 + 0
|
|
||||||
* 00000000000004a0 0000008800000032 R_PPC64_TOC16_HA 0000000000000000 .toc + 148
|
* 00000000000004a0 0000008800000032 R_PPC64_TOC16_HA 0000000000000000 .toc + 148
|
||||||
* 00000000000004ac 0000008800000040 R_PPC64_TOC16_LO_DS 0000000000000000 .toc + 148
|
* 00000000000004ac 0000008800000040 R_PPC64_TOC16_LO_DS 0000000000000000 .toc + 148
|
||||||
* 0000000000000514 0000008800000032 R_PPC64_TOC16_HA 0000000000000000 .toc + 150
|
* 0000000000000514 0000008800000032 R_PPC64_TOC16_HA 0000000000000000 .toc + 150
|
||||||
* 000000000000051c 0000008800000040 R_PPC64_TOC16_LO_DS 0000000000000000 .toc + 150
|
* 000000000000051c 0000008800000040 R_PPC64_TOC16_LO_DS 0000000000000000 .toc + 150
|
||||||
* 00000000000005e0 000001870000000a R_PPC64_REL24 0000000000000000 __bitmap_intersects + 0
|
|
||||||
*/
|
*/
|
||||||
memcpy(&toc_data1, rela1->sym->sec->data->d_buf + rela1->addend, sizeof(toc_data1));
|
memcpy(&toc_data1, rela1->sym->sec->data->d_buf + rela1->addend, sizeof(toc_data1));
|
||||||
if (!toc_data1)
|
if (!toc_data1)
|
||||||
ERROR(".toc entry not found %s + %x", rela1->sym->name, rela1->addend);
|
ERROR(".toc entry not found %s + %x", rela1->sym->name, rela1->addend);
|
||||||
}
|
}
|
||||||
|
|
||||||
toc_relasec2 = rela2->sym->sec->rela;
|
rela_toc2 = toc_rela(rela2);
|
||||||
if (!toc_relasec2)
|
if (!rela_toc2) {
|
||||||
ERROR("cannot find .rela.toc");
|
|
||||||
|
|
||||||
r_toc_relasec2 = find_rela_by_offset(toc_relasec2, rela2->addend);
|
|
||||||
if (!r_toc_relasec2) {
|
|
||||||
memcpy(&toc_data2, rela2->sym->sec->data->d_buf + rela2->addend, sizeof(toc_data2));
|
memcpy(&toc_data2, rela2->sym->sec->data->d_buf + rela2->addend, sizeof(toc_data2));
|
||||||
if (!toc_data2)
|
if (!toc_data2)
|
||||||
ERROR(".toc entry not found %s + %x", rela2->sym->name, rela2->addend);
|
ERROR(".toc entry not found %s + %x", rela2->sym->name, rela2->addend);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!r_toc_relasec1 && !r_toc_relasec2)
|
if (!rela_toc1 && !rela_toc2)
|
||||||
return toc_data1 == toc_data2;
|
return toc_data1 == toc_data2;
|
||||||
|
|
||||||
if (r_toc_relasec1->string)
|
if (rela_toc1->string)
|
||||||
return r_toc_relasec2->string &&
|
return rela_toc2->string && !strcmp(rela_toc1->string, rela_toc2->string);
|
||||||
!strcmp(r_toc_relasec1->string, r_toc_relasec2->string);
|
|
||||||
|
|
||||||
if ((r_toc_relasec1->addend != r_toc_relasec2->addend))
|
if (rela_toc1->addend != rela_toc2->addend)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (is_special_static(r_toc_relasec1->sym))
|
if (is_special_static(rela_toc1->sym))
|
||||||
return !kpatch_mangled_strcmp(r_toc_relasec1->sym->name,
|
return !kpatch_mangled_strcmp(rela_toc1->sym->name,
|
||||||
r_toc_relasec2->sym->name);
|
rela_toc2->sym->name);
|
||||||
|
|
||||||
return !strcmp(r_toc_relasec1->sym->name, r_toc_relasec2->sym->name);
|
return !strcmp(rela_toc1->sym->name, rela_toc2->sym->name);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (rela1->addend != rela2->addend)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (is_special_static(rela1->sym))
|
|
||||||
return !kpatch_mangled_strcmp(rela1->sym->name,
|
|
||||||
rela2->sym->name);
|
|
||||||
|
|
||||||
return !strcmp(rela1->sym->name, rela2->sym->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kpatch_compare_correlated_rela_section(struct section *sec)
|
static void kpatch_compare_correlated_rela_section(struct section *sec)
|
||||||
|
Loading…
Reference in New Issue
Block a user