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

View File

@ -1256,6 +1256,28 @@ static void rela_insn(struct section *sec, struct rela *rela, struct insn *insn)
} }
#endif #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 * Mangle the relas a little. The compiler will sometimes use section symbols
* to reference local objects and functions rather than the object or function * 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; struct rela *rela;
int found = 0; 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 */ /* include load/unload sections */
list_for_each_entry(sec, &kelf->sections, list) { list_for_each_entry(sec, &kelf->sections, list) {
if (!is_callback_section(sec))
continue;
for (callback_section = callback_sections; *callback_section; callback_section++) { sec->include = 1;
found = 1;
if (strcmp(*callback_section, sec->name)) if (is_rela_section(sec)) {
continue; /* include callback dependencies */
rela = list_entry(sec->relas.next, struct rela, list);
sec->include = 1; sym = rela->sym;
found = 1; log_normal("found callback: %s\n",sym->name);
if (is_rela_section(sec)) { kpatch_include_symbol(sym);
/* include callback dependencies */ /* strip the callback symbol */
rela = list_entry(sec->relas.next, sym->include = 0;
struct rela, list); sym->sec->sym = NULL;
sym = rela->sym; /* use section symbol instead */
log_normal("found callback: %s\n",sym->name); rela->sym = sym->sec->secsym;
kpatch_include_symbol(sym); } else {
/* strip the callback symbol */ sec->secsym->include = 1;
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. */ /* Strip temporary global structures used by the callback macros. */
list_for_each_entry(sym, &kelf->symbols, list) { list_for_each_entry(sym, &kelf->symbols, list) {
if (!sym->sec) if (sym->sec && is_callback_section(sym->sec))
continue; sym->include = 0;
for (callback_section = callback_sections; *callback_section; callback_section++) {
if (!strcmp(*callback_section, sym->sec->name)) {
sym->include = 0;
break;
}
}
} }
return found; return found;