create-diff-object: add is_callback_section() helper

This simplifies the code a bit.  Also this helper will be needed for
subsequent patches.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
Josh Poimboeuf 2019-08-15 14:05:28 -05:00
parent 5665d06853
commit 14cc8a013d
1 changed files with 41 additions and 43 deletions

View File

@ -1256,6 +1256,28 @@ static void rela_insn(struct section *sec, struct rela *rela, struct insn *insn)
}
#endif
static bool is_callback_section(struct section *sec) {
static char *callback_sections[] = {
".kpatch.callbacks.pre_patch",
".kpatch.callbacks.post_patch",
".kpatch.callbacks.pre_unpatch",
".kpatch.callbacks.post_unpatch",
".rela.kpatch.callbacks.pre_patch",
".rela.kpatch.callbacks.post_patch",
".rela.kpatch.callbacks.pre_unpatch",
".rela.kpatch.callbacks.post_unpatch",
NULL,
};
char **callback_sec;
for (callback_sec = callback_sections; *callback_sec; callback_sec++)
if (!strcmp(sec->name, *callback_sec))
return true;
return false;
}
/*
* Mangle the relas a little. The compiler will sometimes use section symbols
* to reference local objects and functions rather than the object or function
@ -1550,57 +1572,33 @@ static int kpatch_include_callback_elements(struct kpatch_elf *kelf)
struct rela *rela;
int found = 0;
static char *callback_sections[] = {
".kpatch.callbacks.pre_patch",
".kpatch.callbacks.post_patch",
".kpatch.callbacks.pre_unpatch",
".kpatch.callbacks.post_unpatch",
".rela.kpatch.callbacks.pre_patch",
".rela.kpatch.callbacks.post_patch",
".rela.kpatch.callbacks.pre_unpatch",
".rela.kpatch.callbacks.post_unpatch",
NULL,
};
char **callback_section;
/* include load/unload sections */
list_for_each_entry(sec, &kelf->sections, list) {
if (!is_callback_section(sec))
continue;
for (callback_section = callback_sections; *callback_section; callback_section++) {
if (strcmp(*callback_section, sec->name))
continue;
sec->include = 1;
found = 1;
if (is_rela_section(sec)) {
/* include callback dependencies */
rela = list_entry(sec->relas.next,
struct rela, list);
sym = rela->sym;
log_normal("found callback: %s\n",sym->name);
kpatch_include_symbol(sym);
/* strip the callback symbol */
sym->include = 0;
sym->sec->sym = NULL;
/* use section symbol instead */
rela->sym = sym->sec->secsym;
} else {
sec->secsym->include = 1;
}
sec->include = 1;
found = 1;
if (is_rela_section(sec)) {
/* include callback dependencies */
rela = list_entry(sec->relas.next, struct rela, list);
sym = rela->sym;
log_normal("found callback: %s\n",sym->name);
kpatch_include_symbol(sym);
/* strip the callback symbol */
sym->include = 0;
sym->sec->sym = NULL;
/* use section symbol instead */
rela->sym = sym->sec->secsym;
} else {
sec->secsym->include = 1;
}
}
/* Strip temporary global structures used by the callback macros. */
list_for_each_entry(sym, &kelf->symbols, list) {
if (!sym->sec)
continue;
for (callback_section = callback_sections; *callback_section; callback_section++) {
if (!strcmp(*callback_section, sym->sec->name)) {
sym->include = 0;
break;
}
}
if (sym->sec && is_callback_section(sym->sec))
sym->include = 0;
}
return found;