]> xenbits.xensource.com Git - livepatch-build-tools.git/commitdiff
create-diff-object: add symbol relations
authorArtem Savkov <asavkov@redhat.com>
Tue, 12 Jun 2018 14:05:30 +0000 (16:05 +0200)
committerRoger Pau Monne <roger.pau@citrix.com>
Tue, 21 Jan 2025 13:12:58 +0000 (14:12 +0100)
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>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
common.h
create-diff-object.c

index 5ff9ef6ca8e98bd5633e410b18421fb806afeb8e..7f3a82ffdb29d2d1d117c1ccb20cc328bdb0529a 100644 (file)
--- a/common.h
+++ b/common.h
@@ -85,6 +85,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;
index c21cc576052a50ef6f1989dfbfa01b755088d0ff..bca2199b0fed0774ec270f4fcbc59c7a42738597 100644 (file)
@@ -327,6 +327,38 @@ static void kpatch_rename_mangled_functions(struct kpatch_elf *base,
        }
 }
 
+/*
+ * 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).
@@ -2333,6 +2365,9 @@ int main(int argc, char *argv[])
        log_debug("Open patched\n");
        kelf_patched = kpatch_elf_open(arguments.args[1]);
 
+       kpatch_detect_child_functions(kelf_base);
+       kpatch_detect_child_functions(kelf_patched);
+
        log_debug("Compare elf headers\n");
        kpatch_compare_elf_headers(kelf_base->elf, kelf_patched->elf);
        log_debug("Check program headers of base\n");