mirror of
https://github.com/dynup/kpatch
synced 2025-02-06 12:11:33 +00:00
create-diff-object: create intermediate .kpatch.arch section
In addition to .kpatch.relocations and .kpatch.symbols, have create-diff-object create an .kpatch.arch section. This section can be used to create .klp.arch. sections that are required for klp modules built for versions >= 4.9. Each entry in the .kpatch.arch section represents an arch-specific section (.altinstructions or .parainstructions) and contains a pointer to the arch-specific section itself (see kpatch_arch struct member 'sec') and a pointer to the objname string (see kpatch_arch struct member 'objname'). This is enough information to be able to build .klp.arch. sections in a later phase of kpatch-build.
This commit is contained in:
parent
87643703a7
commit
42902d0fcc
@ -1584,6 +1584,8 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
|
||||
/* include both rela and base sections */
|
||||
sec->include = 1;
|
||||
sec->base->include = 1;
|
||||
/* include secsym so .kpatch.arch relas can point to section symbols */
|
||||
sec->base->secsym->include = 1;
|
||||
|
||||
/*
|
||||
* Update text section data buf and size.
|
||||
@ -1707,6 +1709,56 @@ static void kpatch_mark_ignored_functions_same(struct kpatch_elf *kelf)
|
||||
}
|
||||
}
|
||||
|
||||
static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *objname)
|
||||
{
|
||||
struct special_section *special;
|
||||
struct kpatch_arch *entries;
|
||||
struct symbol *strsym;
|
||||
struct section *sec, *karch_sec;
|
||||
struct rela *rela;
|
||||
int nr, index = 0;
|
||||
|
||||
nr = sizeof(special_sections) / sizeof(special_sections[0]);
|
||||
karch_sec = create_section_pair(kelf, ".kpatch.arch", sizeof(*entries), nr);
|
||||
entries = karch_sec->data->d_buf;
|
||||
|
||||
/* lookup strings symbol */
|
||||
strsym = find_symbol_by_name(&kelf->symbols, ".kpatch.strings");
|
||||
if (!strsym)
|
||||
ERROR("can't find .kpatch.strings symbol");
|
||||
|
||||
for (special = special_sections; special->name; special++) {
|
||||
if (strcmp(special->name, ".parainstructions") &&
|
||||
strcmp(special->name, ".altinstructions"))
|
||||
continue;
|
||||
|
||||
sec = find_section_by_name(&kelf->sections, special->name);
|
||||
if (!sec)
|
||||
continue;
|
||||
|
||||
/* entries[index].sec */
|
||||
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
||||
rela->sym = sec->secsym;
|
||||
rela->type = R_X86_64_64;
|
||||
rela->addend = 0;
|
||||
rela->offset = index * sizeof(*entries) + \
|
||||
offsetof(struct kpatch_arch, sec);
|
||||
|
||||
/* entries[index].objname */
|
||||
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
||||
rela->sym = strsym;
|
||||
rela->type = R_X86_64_64;
|
||||
rela->addend = offset_of_string(&kelf->strings, objname);
|
||||
rela->offset = index * sizeof(*entries) + \
|
||||
offsetof(struct kpatch_arch, objname);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
karch_sec->data->d_size = index * sizeof(struct kpatch_arch);
|
||||
karch_sec->sh.sh_size = karch_sec->data->d_size;
|
||||
}
|
||||
|
||||
static void kpatch_process_special_sections(struct kpatch_elf *kelf)
|
||||
{
|
||||
struct special_section *special;
|
||||
@ -2462,6 +2514,7 @@ int main(int argc, char *argv[])
|
||||
kpatch_create_strings_elements(kelf_out);
|
||||
kpatch_create_patches_sections(kelf_out, lookup, hint, objname);
|
||||
kpatch_create_intermediate_sections(kelf_out, lookup, hint, objname, pmod_name);
|
||||
kpatch_create_kpatch_arch_section(kelf_out, objname);
|
||||
kpatch_create_hooks_objname_rela(kelf_out, objname);
|
||||
kpatch_build_strings_section_data(kelf_out);
|
||||
|
||||
|
@ -40,4 +40,9 @@ struct kpatch_relocation {
|
||||
char *objname; /* object to which this rela applies to */
|
||||
struct kpatch_symbol *ksym;
|
||||
};
|
||||
|
||||
struct kpatch_arch {
|
||||
unsigned long sec;
|
||||
char *objname;
|
||||
};
|
||||
#endif /* _KPATCH_ELF_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user