}
}
+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)
{
struct rela *rela;
struct lookup_result result;
struct xsplice_patch_func *funcs;
+ char *funcname;
/* count patched functions */
nr = 0;
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",
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);
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
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))