[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v1 5/5] xsplice: Use ld-embedded build-ids
From: Martin Pohlack <mpohlack@xxxxxxxxx> The mechanism to get this is via the XSPLICE_OP and we add a new subsequent hypercall to retrieve the binary build-id. The hypercall allows an arbirarty size (the buffer is provided to the hypervisor) - however by default the toolstack will allocate it up to 128 bytes. We also add two places for the build-id to be printed: - xsplice keyhandler. We cannot use 'hh' in the hypervisor snprintf handler (as it is not implemented) so instead we use an simpler way to print it. - In the 'xen-xsplice' tool add an extra parameter - build-id to print this as an human readable value. Note that one can also retrieve the value by 'readelf -h xen-syms'. Signed-off-by: Martin Pohlack <mpohlack@xxxxxxxxx> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- tools/libxc/include/xenctrl.h | 1 + tools/libxc/xc_misc.c | 26 +++++++++++++ tools/misc/xen-xsplice.c | 39 ++++++++++++++++++++ xen/arch/x86/Makefile | 4 +- xen/arch/x86/xen.lds.S | 5 +++ xen/common/xsplice.c | 86 +++++++++++++++++++++++++++++++++++++++++++ xen/include/public/sysctl.h | 18 +++++++++ xen/include/xen/version.h | 1 + 8 files changed, 178 insertions(+), 2 deletions(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 2cd982d..946ddc0 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -2860,6 +2860,7 @@ int xc_xsplice_apply(xc_interface *xch, char *id); int xc_xsplice_revert(xc_interface *xch, char *id); int xc_xsplice_unload(xc_interface *xch, char *id); int xc_xsplice_check(xc_interface *xch, char *id); +int xc_xsplice_build_id(xc_interface *xch, char *build_id, unsigned int max); #endif /* XENCTRL_H */ diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index e59f0a1..f67ff16 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -992,6 +992,32 @@ int xc_xsplice_check(xc_interface *xch, char *id) return _xc_xsplice_action(xch, id, XSPLICE_ACTION_CHECK); } +int xc_xsplice_build_id(xc_interface *xch, char *build_id, unsigned int max) +{ + int rc; + DECLARE_SYSCTL; + DECLARE_HYPERCALL_BOUNCE(build_id, max, XC_HYPERCALL_BUFFER_BOUNCE_OUT); + + if ( !build_id || !max ) + return -1; + + if ( xc_hypercall_bounce_pre(xch, build_id) ) + return -1; + + sysctl.cmd = XEN_SYSCTL_xsplice_op; + sysctl.u.xsplice.cmd = XEN_SYSCTL_XSPLICE_INFO; + + sysctl.u.xsplice.u.info.cmd = XEN_SYSCTL_XSPLICE_INFO_BUILD_ID; + sysctl.u.xsplice.u.info.size = max; + + set_xen_guest_handle(sysctl.u.xsplice.u.info.u.info, build_id); + + rc = do_sysctl(xch, &sysctl); + + xc_hypercall_bounce_post(xch, build_id); + + return rc; +} /* * Local variables: * mode: C diff --git a/tools/misc/xen-xsplice.c b/tools/misc/xen-xsplice.c index d8bd222..609d799 100644 --- a/tools/misc/xen-xsplice.c +++ b/tools/misc/xen-xsplice.c @@ -17,6 +17,7 @@ void show_help(void) " <id> An unique name of payload. Up to %d characters.\n" "Commands:\n" " help display this help\n" + " build-id display build-id of hypervisor.\n" " upload <id> <file> upload file <cpuid> with <id> name\n" " list list payloads uploaded.\n" " apply <id> apply <id> patch.\n" @@ -361,12 +362,50 @@ unload: return rc; } + +#define MAX_LEN 1024 +static int build_id_func(int argc, char *argv[]) +{ + char binary_id[MAX_LEN]; + char ascii_id[MAX_LEN]; + int rc; + unsigned int i; + + if ( argc ) + { + show_help(); + return -1; + } + + memset(binary_id, 0, sizeof(binary_id)); + + rc = xc_xsplice_build_id(xch, binary_id, MAX_LEN); + if ( rc < 0 ) + { + printf("Failed to get build_id: %d(%s)\n", errno, strerror(errno)); + return -1; + } + /* Convert to printable format. */ + if ( rc > MAX_LEN ) + rc = MAX_LEN; + + for ( i = 0; i < rc && (i + 1) * 2 < sizeof(binary_id); i++ ) + snprintf(&ascii_id[i * 2], 3, "%02hhx", binary_id[i]); + + ascii_id[i*2]='\0'; + printf("%s", ascii_id); + + return 0; +} +#undef MAX + struct { const char *name; int (*function)(int argc, char *argv[]); } main_options[] = { { "help", help_func }, { "list", list_func }, + { "build-id", build_id_func }, { "upload", upload_func }, { "all", all_func }, }; diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 39a8059..de11910 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -108,11 +108,11 @@ $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0 $(NM) -n $(@D)/.$(@F).0 | $(BASEDIR)/tools/symbols >$(@D)/.$(@F).0.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o - $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ + $(LD) $(LDFLAGS) -T xen.lds -N prelink.o --build-id=sha1 \ $(@D)/.$(@F).0.o -o $(@D)/.$(@F).1 $(NM) -n $(@D)/.$(@F).1 | $(BASEDIR)/tools/symbols >$(@D)/.$(@F).1.S $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o - $(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ + $(LD) $(LDFLAGS) -T xen.lds -N prelink.o --build-id=sha1 \ $(@D)/.$(@F).1.o -o $@ rm -f $(@D)/.$(@F).[0-9]* diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 6553cff..2176782 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -67,6 +67,11 @@ SECTIONS *(.rodata.*) } :text + .note.gnu.build-id : { + __note_gnu_build_id_start = .; + *(.note.gnu.build-id) + } :text + . = ALIGN(SMP_CACHE_BYTES); .data.read_mostly : { /* Exception table */ diff --git a/xen/common/xsplice.c b/xen/common/xsplice.c index d330efe..5728c4b 100644 --- a/xen/common/xsplice.c +++ b/xen/common/xsplice.c @@ -14,6 +14,8 @@ #include <xen/sched.h> #include <xen/lib.h> #include <xen/xsplice.h> +#include <xen/elf.h> +#include <xen/types.h> #include <public/sysctl.h> #include <asm/event.h> @@ -44,6 +46,36 @@ struct payload { struct tasklet tasklet; }; +#ifdef CONFIG_ARM +static int build_id(char **p, unsigned int *len) +{ + return 0; +} +#else +#define NT_GNU_BUILD_ID 3 + +extern char * __note_gnu_build_id_start; /* defined in linker script */ +static int build_id(char **p, unsigned int *len) +{ + Elf_Note *n; + + n = (Elf_Note *)&__note_gnu_build_id_start; + + /* Check if we really have a build-id. */ + if ( NT_GNU_BUILD_ID != n->type ) + return -ENODATA; + + /* Sanity check, name should be "GNU" for ld-generated build-id. */ + if ( strncmp(ELFNOTE_NAME(n), "GNU", n->namesz) != 0 ) + return -ENODATA; + + *len = n->descsz; + *p = ELFNOTE_DESC(n); + + return 0; +} +#endif + static const char *status2str(int64_t status) { #define STATUS(x) [XSPLICE_STATUS_##x] = #x @@ -68,9 +100,31 @@ static const char *status2str(int64_t status) return names[status]; } +#define LEN 128 void xsplice_printall(unsigned char key) { struct payload *data; + char *binary_id = NULL; + unsigned int len = 0; + int rc; + + rc = build_id(&binary_id, &len); + printk("build-id: "); + if ( !rc ) + { + unsigned int i; + + if ( len > LEN ) + len = LEN; + + for ( i = 0; i < len; i++ ) + { + uint8_t c = binary_id[i]; + printk("%02x", c); + } + printk("\n"); + } else if ( rc < 0 ) + printk("rc = %d\n", rc); spin_lock(&payload_list_lock); @@ -81,6 +135,7 @@ void xsplice_printall(unsigned char key) } spin_unlock(&payload_list_lock); } +#undef LEN static int verify_id(xen_xsplice_id_t *id) { @@ -415,6 +470,34 @@ static int xsplice_action(xen_sysctl_xsplice_action_t *action) return rc; } +static int xsplice_info(xen_sysctl_xsplice_info_t *info) +{ + int rc; + unsigned int len = 0; + char *p = NULL; + + if ( info->cmd != XEN_SYSCTL_XSPLICE_INFO_BUILD_ID ) + return -EINVAL; + + if ( info->size == 0 ) + return -EINVAL; + + if ( !guest_handle_okay(info->u.info, info->size) ) + return -EFAULT; + + rc = build_id(&p, &len); + if ( rc ) + return rc; + + if ( len > info->size ) + return -ENOMEM; + + if ( copy_to_guest(info->u.info, p, len) ) + return -EFAULT; + + return len; +} + int xsplice_control(xen_sysctl_xsplice_op_t *xsplice) { int rc; @@ -433,6 +516,9 @@ int xsplice_control(xen_sysctl_xsplice_op_t *xsplice) case XEN_SYSCTL_XSPLICE_ACTION: rc = xsplice_action(&xsplice->u.action); break; + case XEN_SYSCTL_XSPLICE_INFO: + rc = xsplice_info(&xsplice->u.info); + break; default: rc = -ENOSYS; break; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index 08952de..583dce8 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -905,6 +905,23 @@ struct xen_sysctl_xsplice_action { typedef struct xen_sysctl_xsplice_action xen_sysctl_xsplice_action_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_action_t); +/* + * Retrieve information useful for patching tools. + */ +#define XEN_SYSCTL_XSPLICE_INFO 4 +/* The build-id of the hypervisor. */ +#define XEN_SYSCTL_XSPLICE_INFO_BUILD_ID 0 +struct xen_sysctl_xsplice_info { + uint32_t cmd; /* IN: XEN_SYSCTL_XSPLICE_INFO_* */ + uint32_t size; /* IN: Size of info: OUT: Amount of + bytes filed out in info. */ + union { + XEN_GUEST_HANDLE_64(char) info; /* OUT: Requested information. */ + } u; +}; +typedef struct xen_sysctl_xsplice_info xen_sysctl_xsplice_info_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_xsplice_info_t); + struct xen_sysctl_xsplice_op { uint32_t cmd; /* IN: XEN_SYSCTL_XSPLICE_* */ uint32_t _pad; /* IN: Always zero. */ @@ -913,6 +930,7 @@ struct xen_sysctl_xsplice_op { xen_sysctl_xsplice_list_t list; xen_sysctl_xsplice_summary_t get; xen_sysctl_xsplice_action_t action; + xen_sysctl_xsplice_info_t info; } u; }; typedef struct xen_sysctl_xsplice_op xen_sysctl_xsplice_op_t; diff --git a/xen/include/xen/version.h b/xen/include/xen/version.h index 81a3c7d..02f9585 100644 --- a/xen/include/xen/version.h +++ b/xen/include/xen/version.h @@ -12,5 +12,6 @@ unsigned int xen_minor_version(void); const char *xen_extra_version(void); const char *xen_changeset(void); const char *xen_banner(void); +const char *xen_build_id(void); #endif /* __XEN_VERSION_H__ */ -- 2.1.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |