Skip to content

Commit

Permalink
kpatch-elf: Fix rela->string calculation
Browse files Browse the repository at this point in the history
On s390x,
 .L1^B19 -> .rodata.str (bug_table)
 .LC0 -> .rodata.str1.2

  In these cases, return true and rela->string should point to
  rela->sym->sec->data->d_buf + value of the associated symbol.

Previous result:
offset 68, type 26, .LC0 + 2 (string = NETDEV_UP)
offset 78, type 26, .LC17 + 2 (string = NETDEV_UP)
offset 88, type 26, .LC2 + 2 (string = NETDEV_UP)

After fix:
offset 68, type 26, .LC0 + 2 (string = NETDEV_UP)
offset 78, type 26, .LC17 + 2 (string = NETDEV_NOTIFY_PEERS)
offset 88, type 26, .LC2 + 2 (string = NETDEV_REBOOT)

Signed-off-by: Sumanth Korikkar <[email protected]>
  • Loading branch information
sumanthkorikkar committed Sep 20, 2021
1 parent 9d71c8d commit c6f87d6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
4 changes: 4 additions & 0 deletions kpatch-build/create-diff-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,10 @@ static bool rela_equal(struct rela *rela1, struct rela *rela2)
if (!rela_toc1 || !rela_toc2)
return false;

/*
* For LC symbol, comparision is performed using rela->string.
* rela->string is initialized appropriately based on LC symbol or not.
*/
if (rela_toc1->string)
return rela_toc2->string && !strcmp(rela_toc1->string, rela_toc2->string);

Expand Down
23 changes: 22 additions & 1 deletion kpatch-build/kpatch-elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,24 @@ int offset_of_string(struct list_head *list, char *name)
return index;
}

/*
* Check if the symbol name contains LC or L1^B.
*
* On s390x,
* .L1^B19 -> .rodata.str (bug_table)
* .LC0 -> .rodata.str1.2
*
* In these cases, return true and rela->string should point to
* rela->sym->sec->data->d_buf + value of the associated symbol.
*/

static bool lc_string(struct rela *rela) {
if (!strncmp(rela->sym->name, ".LC", 3) || !strncmp(rela->sym->name, ".L1", 3))
return true;
else
return false;
}

void kpatch_create_rela_list(struct kpatch_elf *kelf, struct section *sec)
{
int index = 0, skip = 0;
Expand Down Expand Up @@ -193,7 +211,10 @@ void kpatch_create_rela_list(struct kpatch_elf *kelf, struct section *sec)
ERROR("could not find rela entry symbol\n");
if (rela->sym->sec &&
(rela->sym->sec->sh.sh_flags & SHF_STRINGS)) {
rela->string = rela->sym->sec->data->d_buf + rela->addend;
if (lc_string(rela))
rela->string = rela->sym->sec->data->d_buf + rela->sym->sym.st_value;
else
rela->string = rela->sym->sec->data->d_buf + rela->addend;
if (!rela->string)
ERROR("could not lookup rela string for %s+%ld",
rela->sym->name, rela->addend);
Expand Down

0 comments on commit c6f87d6

Please sign in to comment.