From 735bd9bdc62642d67d786ef946da8cae6295fd34 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 9 Nov 2015 15:23:33 +0000 Subject: [PATCH] Mangle local symbols to match Xen's mangling --- create-diff-object.c | 48 +++++++++++++++++++++++++++++++++++++++++++- prelink.c | 17 +++++++++++++--- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/create-diff-object.c b/create-diff-object.c index b542ee9..e560f0c 100644 --- a/create-diff-object.c +++ b/create-diff-object.c @@ -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 diff --git a/prelink.c b/prelink.c index f922871..a190eca 100644 --- 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)) -- 2.39.5