mirror of
https://github.com/dynup/kpatch
synced 2025-01-06 13:09:26 +00:00
Merge pull request #616 from rosslagerwall/extable-addend
create-diff-object: Update fixup offsets in .rela__ex_table
This commit is contained in:
commit
dc3ef4d6da
@ -1490,6 +1490,31 @@ int should_keep_rela_group(struct section *sec, int start, int size)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When updating .fixup, the corresponding addends in .ex_table need to be
|
||||||
|
* updated too. Stash the result in rela.r_addend so that the calculation in
|
||||||
|
* fixup_group_size() is not affected.
|
||||||
|
*/
|
||||||
|
void kpatch_update_ex_table_addend(struct kpatch_elf *kelf,
|
||||||
|
struct special_section *special,
|
||||||
|
int src_offset, int dest_offset,
|
||||||
|
int group_size)
|
||||||
|
{
|
||||||
|
struct rela *rela;
|
||||||
|
struct section *sec;
|
||||||
|
|
||||||
|
sec = find_section_by_name(&kelf->sections, ".rela__ex_table");
|
||||||
|
if (!sec)
|
||||||
|
ERROR("missing .rela__ex_table section");
|
||||||
|
|
||||||
|
list_for_each_entry(rela, &sec->relas, list) {
|
||||||
|
if (!strcmp(rela->sym->name, ".fixup") &&
|
||||||
|
rela->addend >= src_offset &&
|
||||||
|
rela->addend < src_offset + group_size)
|
||||||
|
rela->rela.r_addend = rela->addend - (src_offset - dest_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
|
void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
|
||||||
struct special_section *special,
|
struct special_section *special,
|
||||||
struct section *sec)
|
struct section *sec)
|
||||||
@ -1506,6 +1531,14 @@ void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
|
|||||||
if (!dest)
|
if (!dest)
|
||||||
ERROR("malloc");
|
ERROR("malloc");
|
||||||
|
|
||||||
|
/* Restore the stashed r_addend from kpatch_update_ex_table_addend. */
|
||||||
|
if (!strcmp(special->name, "__ex_table")) {
|
||||||
|
list_for_each_entry(rela, &sec->relas, list) {
|
||||||
|
if (!strcmp(rela->sym->name, ".fixup"))
|
||||||
|
rela->addend = rela->rela.r_addend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
group_size = 0;
|
group_size = 0;
|
||||||
src_offset = 0;
|
src_offset = 0;
|
||||||
dest_offset = 0;
|
dest_offset = 0;
|
||||||
@ -1533,6 +1566,13 @@ void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
|
|||||||
rela->rela.r_offset = rela->offset;
|
rela->rela.r_offset = rela->offset;
|
||||||
|
|
||||||
rela->sym->include = 1;
|
rela->sym->include = 1;
|
||||||
|
|
||||||
|
|
||||||
|
if (!strcmp(special->name, ".fixup"))
|
||||||
|
kpatch_update_ex_table_addend(kelf, special,
|
||||||
|
src_offset,
|
||||||
|
dest_offset,
|
||||||
|
group_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user