@@ -20,6 +20,7 @@
#include <xen/symbols.h>
#include <xen/lib.h>
#include <xen/sched.h>
+#include <xen/xsplice.h>
#include <asm/div64.h>
#include <asm/page.h>
@@ -331,16 +332,17 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
{
unsigned long sym_size, sym_offset;
char namebuf[KSYM_NAME_LEN+1];
+ bool_t payload = 0;
/* Advance parents fmt string, as we have consumed 's' or 'S' */
++*fmt_ptr;
s = symbols_lookup((unsigned long)arg, &sym_size, &sym_offset, namebuf);
-
- /* If the symbol is not found, fall back to printing the address */
+ /* If the symbol is not found, fall back to printing the address. */
if ( !s )
break;
-
+ if ( strncmp(namebuf, s, KSYM_NAME_LEN) )
+ payload = 1;
/* Print symbol name */
str = string(str, end, s, -1, -1, 0);
@@ -354,6 +356,13 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
str = number(str, end, sym_size, 16, -1, -1, SPECIAL);
}
+ if ( payload )
+ {
+ str = string(str, end, " [", -1, -1, 0);
+ str = string(str, end, namebuf, -1, -1, 0);
+ str = string(str, end, "]", -1, -1, 0);
+ }
+
return str;
}
@@ -3,6 +3,7 @@
*
*/
+#include <xen/bug_ex_symbols.h>
#include <xen/cpu.h>
#include <xen/guest_access.h>
#include <xen/keyhandler.h>
@@ -13,6 +14,7 @@
#include <xen/smp.h>
#include <xen/softirq.h>
#include <xen/spinlock.h>
+#include <xen/string.h>
#include <xen/symbols.h>
#include <xen/vmap.h>
#include <xen/wait.h>
@@ -50,6 +52,7 @@ struct payload {
struct list_head applied_list; /* Linked to 'applied_list'. */
struct xsplice_patch_func *funcs; /* The array of functions to patch. */
unsigned int nfuncs; /* Nr of functions to patch. */
+ struct virtual_region bug_ex_region; /*.bug.frame patching and exception table. */
struct xsplice_symbol *symtab; /* All symbols. */
char *strtab; /* Pointer to .strtab. */
unsigned int nsyms; /* Nr of entries in .strtab and symbols. */
@@ -103,6 +106,12 @@ static int verify_payload(const xen_sysctl_xsplice_upload_t *upload)
return 0;
}
+static bool_t ignore_region(unsigned int flag, unsigned long priv)
+{
+ /* See CHECKING_[SYMBOL|BUG_FRAME|EXCEPTION]. */
+ return !(flag & priv);
+}
+
uint64_t xsplice_symbols_lookup_by_name(const char *symname)
{
struct payload *data;
@@ -131,6 +140,51 @@ out:
return value;
}
+static const char *xsplice_symbols_lookup(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset,
+ char *namebuf)
+{
+ struct payload *data;
+ unsigned int i;
+ int best;
+
+ /*
+ * No locking since this list is only ever changed during apply or revert
+ * context.
+ */
+ list_for_each_entry ( data, &applied_list, applied_list )
+ {
+ if ( !((void *)addr >= data->payload_address &&
+ (void *)addr < (data->payload_address + data->core_text_size)) )
+ continue;
+
+ best = -1;
+
+ for ( i = 0; i < data->nsyms; i++ )
+ {
+ if ( data->symtab[i].value <= addr &&
+ ( best == -1 ||
+ data->symtab[best].value < data->symtab[i].value) )
+ best = i;
+ }
+
+ if ( best == -1 )
+ return NULL;
+
+ if ( symbolsize )
+ *symbolsize = data->symtab[best].size;
+ if ( offset )
+ *offset = addr - data->symtab[best].value;
+ if ( namebuf )
+ strlcpy(namebuf, data->name, KSYM_NAME_LEN);
+
+ return data->symtab[best].name;
+ }
+
+ return NULL;
+}
+
static int find_payload(const xen_xsplice_name_t *name, struct payload **f)
{
struct payload *data;
@@ -325,6 +379,7 @@ static int prepare_payload(struct payload *payload,
struct xsplice_elf_sec *sec;
unsigned int i;
struct xsplice_patch_func *f;
+ struct virtual_region *region;
sec = xsplice_elf_sec_by_name(elf, ".xsplice.funcs");
if ( sec )
@@ -377,6 +432,15 @@ static int prepare_payload(struct payload *payload,
XSPLICE, elf->name, f->name, f->old_addr);
}
}
+
+ /* Setup the virtual region with proper data. */
+ region = &payload->bug_ex_region;
+ region->skip = ignore_region;
+ region->symbols_lookup = xsplice_symbols_lookup;
+ region->priv = CHECKING_SYMBOL;
+ region->start = (unsigned long)payload->payload_address;
+ region->end = (unsigned long)(payload->payload_address + payload->core_text_size);
+
return 0;
}
@@ -479,7 +543,6 @@ static int build_symbol_table(struct payload *payload,
payload->symtab = symtab;
payload->strtab = strtab;
payload->nsyms = nsyms;
-
return 0;
}
@@ -707,6 +770,7 @@ static int apply_payload(struct payload *data)
arch_xsplice_patching_leave();
list_add_tail(&data->applied_list, &applied_list);
+ register_virtual_region(&data->bug_ex_region);
return 0;
}
@@ -729,6 +793,7 @@ static int revert_payload(struct payload *data)
arch_xsplice_patching_leave();
list_del_init(&data->applied_list);
+ unregister_virtual_region(&data->bug_ex_region);
return 0;
}