]> xenbits.xensource.com Git - people/wipawel/livepatch-build-tools/commitdiff
Mangle local symbols to match Xen's mangling
authorRoss Lagerwall <ross.lagerwall@citrix.com>
Mon, 9 Nov 2015 15:23:33 +0000 (15:23 +0000)
committerRoss Lagerwall <ross.lagerwall@citrix.com>
Wed, 20 Jan 2016 13:48:24 +0000 (13:48 +0000)
create-diff-object.c
prelink.c

index b542ee937f165b3c38753bd85163cac95ff98f5f..e560f0c4358041b186f52d27c3e56b59e58ce1c2 100644 (file)
@@ -1399,6 +1399,46 @@ static void xsplice_build_strings_section_data(struct xsplice_elf *kelf)
        }
 }
 
+static char *mangle_local_symbol(char *filename, char *symname)
+{
+       char *s, *ptr;
+
+       /* filename + # + symbolname */
+       ptr = s = malloc(strlen(filename) + 1 + strlen(symname) + 1);
+       if (!s)
+               ERROR("malloc");
+
+       ptr = stpcpy(ptr, filename);
+       *ptr++ = '#';
+       strcpy(ptr, symname);
+
+       return s;
+}
+
+/*
+ * Rename local symbols to the filename#symbol format used by Xen's "special"
+ * symbol table.
+ */
+static void xsplice_rename_local_symbols(struct xsplice_elf *kelf, char *hint)
+{
+       struct symbol *sym;
+
+       list_for_each_entry(sym, &kelf->symbols, list) {
+               /* ignore NULL symbol */
+               if (!strlen(sym->name))
+                       continue;
+
+               if (sym->type != STT_FUNC && sym->type != STT_OBJECT)
+                       continue;
+
+               if (sym->bind != STB_LOCAL)
+                       continue;
+
+               sym->name = mangle_local_symbol(hint, sym->name);
+               log_debug("Local symbol mangled to: %s\n", sym->name);
+       }
+}
+
 static struct section *create_section_pair(struct xsplice_elf *kelf,
                                           char *name, int entsize, int nr)
 {
@@ -1465,6 +1505,7 @@ static void xsplice_create_patches_sections(struct xsplice_elf *kelf,
        struct rela *rela;
        struct lookup_result result;
        struct xsplice_patch_func *funcs;
+       char *funcname;
 
        /* count patched functions */
        nr = 0;
@@ -1487,11 +1528,13 @@ static void xsplice_create_patches_sections(struct xsplice_elf *kelf,
        list_for_each_entry(sym, &kelf->symbols, list) {
                if (sym->type == STT_FUNC && sym->status == CHANGED) {
                        if (sym->bind == STB_LOCAL) {
+                               funcname = mangle_local_symbol(hint, sym->name);
                                if (lookup_local_symbol(table, sym->name,
                                                        hint, &result))
                                        ERROR("lookup_local_symbol %s (%s)",
                                              sym->name, hint);
                        } else {
+                               funcname = sym->name;
                                if (lookup_global_symbol(table, sym->name,
                                                        &result))
                                        ERROR("lookup_global_symbol %s",
@@ -1532,7 +1575,7 @@ static void xsplice_create_patches_sections(struct xsplice_elf *kelf,
                        ALLOC_LINK(rela, &relasec->relas);
                        rela->sym = strsym;
                        rela->type = R_X86_64_64;
-                       rela->addend = offset_of_string(&kelf->strings, sym->name);
+                       rela->addend = offset_of_string(&kelf->strings, funcname);
                        rela->offset = index * sizeof(*funcs) +
                                       offsetof(struct xsplice_patch_func, name);
 
@@ -1777,6 +1820,9 @@ int main(int argc, char *argv[])
                                        arguments.resolve);
        xsplice_build_strings_section_data(kelf_out);
 
+       log_debug("Rename local symbols\n");
+       xsplice_rename_local_symbols(kelf_out, hint);
+
        /*
         *  At this point, the set of output sections and symbols is
         *  finalized.  Reorder the symbols into linker-compliant
index f922871538c39c4504a62b566449766f25bd680e..a190eca4bc002fa095e5bd86ffe24321ff6567d7 100644 (file)
--- a/prelink.c
+++ b/prelink.c
@@ -63,10 +63,21 @@ void xsplice_resolve_symbols(struct xsplice_elf *kelf,
                        continue;
 
                if (sym->bind == STB_LOCAL) {
-                       if (lookup_local_symbol(table, sym->name,
-                                               curfile, &result))
+                       /*
+                        * Symbols are mangled to match Xen's runtime symbol
+                        * mangling. However, the ELF symbol table in xen-syms
+                        * is normal, so we need to unmangle the local symbols.
+                        */
+
+                       char *s = strchr(sym->name, '#');
+                       if (s)
+                               s++;
+                       else
+                               s = sym->name;
+
+                       if (lookup_local_symbol(table, s, curfile, &result))
                                ERROR("lookup_local_symbol %s (%s)",
-                                     sym->name, curfile);
+                                     s, curfile);
                } else {
                        if (lookup_global_symbol(table, sym->name,
                                                &result))