create-diff-object: add symbol relations

Add a function that would detect parent/child symbol relations. So far
it only supports .cold.* symbols as children.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
This commit is contained in:
Artem Savkov 2018-06-12 16:05:30 +02:00
parent 2f3db2abe9
commit bd2589530c
2 changed files with 37 additions and 0 deletions

View File

@ -183,6 +183,38 @@ static void kpatch_bundle_symbols(struct kpatch_elf *kelf)
}
}
/*
* During optimization gcc may move unlikely execution branches into *.cold
* subfunctions. kpatch_detect_child_functions detects such subfunctions and
* crossreferences them with their parent functions through parent/child
* pointers.
*/
static void kpatch_detect_child_functions(struct kpatch_elf *kelf)
{
struct symbol *sym;
list_for_each_entry(sym, &kelf->symbols, list) {
char *coldstr;
coldstr = strstr(sym->name, ".cold.");
if (coldstr != NULL) {
char *pname;
pname = strndup(sym->name, coldstr - sym->name);
if (!pname)
ERROR("strndup");
sym->parent = find_symbol_by_name(&kelf->symbols, pname);
free(pname);
if (!sym->parent)
ERROR("failed to find parent function for %s", sym->name);
sym->parent->child = sym;
}
}
}
/*
* This function detects whether the given symbol is a "special" static local
* variable (for lack of a better term).
@ -3163,6 +3195,9 @@ int main(int argc, char *argv[])
kpatch_bundle_symbols(kelf_base);
kpatch_bundle_symbols(kelf_patched);
kpatch_detect_child_functions(kelf_base);
kpatch_detect_child_functions(kelf_patched);
kpatch_compare_elf_headers(kelf_base->elf, kelf_patched->elf);
kpatch_check_program_headers(kelf_base->elf);
kpatch_check_program_headers(kelf_patched->elf);

View File

@ -70,6 +70,8 @@ struct section {
struct symbol {
struct list_head list;
struct symbol *twin;
struct symbol *parent;
struct symbol *child;
struct section *sec;
GElf_Sym sym;
char *name;