On 09/10/15 03:56, Konrad Rzeszutek Wilk wrote: > @@ -367,6 +368,35 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) > arg, > if ( copy_to_guest(arg, saved_cmdline, ARRAY_SIZE(saved_cmdline)) ) > return -EFAULT; > return 0; > + > + case XENVER_build_id: > + { > + int rc; > + char *p = NULL; > + unsigned int sz = 0; > + > + if ( guest_handle_is_null(arg) ) > + return -EINVAL;
A NULL guest handle should return size, in the same way that we have size queries with other hypercalls. In the future, build-id will probably extend to sha256 and get//// longer as a result. > + > + if ( len == 0 ) > + return -EINVAL; This check is redundant with the "sz > len" check below. > + > + if ( !guest_handle_okay(arg, len) ) > + return -EINVAL; This check is performed by copy_to_guest() below. > + > + rc = xen_build_id(&p, &sz); > + if ( rc ) > + return rc; > + > + if ( sz > len ) > + return -ENOMEM; ENOBUFS > + > + if ( copy_to_guest(arg, p, sz) ) > + return -EFAULT; > + > + return sz; > + } > + > } > > return -ENOSYS; > diff --git a/xen/common/version.c b/xen/common/version.c > index b152e27..26eeadf 100644 > --- a/xen/common/version.c > +++ b/xen/common/version.c > @@ -1,5 +1,9 @@ > #include <xen/compile.h> > #include <xen/version.h> > +#include <xen/types.h> > +#include <xen/string.h> > +#include <xen/elf.h> > +#include <xen/errno.h> > > const char *xen_compile_date(void) > { > @@ -55,3 +59,36 @@ const char *xen_banner(void) > { > return XEN_BANNER; > } > + > +#ifdef CONFIG_ARM > +int xen_build_id(char **p, unsigned int *len) > +{ > + return -ENODATA; > +} > +#else > +#define NT_GNU_BUILD_ID 3 > + > +extern const Elf_Note __note_gnu_build_id_start; /* Defined in linker > script. */ extern const Elf_Note __note_gnu_build_id_start[], __note_gnu_build_id_end[]; > +extern const char __note_gnu_build_id_end[]; > +int xen_build_id(char **p, unsigned int *len) > +{ > + const Elf_Note *n = &__note_gnu_build_id_start; const Elf_Note *n = __note_gnu_build_id_start; > + > + /* Something is wrong. */ > + if ( __note_gnu_build_id_end <= (char *)&__note_gnu_build_id_start ) Need to check for a full Note header as well. if ( &n[1] > __note_gnu_build_id_end ) > + return -ENODATA; > + > + /* 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); This information could be cached in a couple of static variables, so the sanity checks are only performed once. > + > + return 0; > +} > +#endif > diff --git a/xen/include/public/version.h b/xen/include/public/version.h > index 44f26b0..e575d6b 100644 > --- a/xen/include/public/version.h > +++ b/xen/include/public/version.h > @@ -30,7 +30,8 @@ > > #include "xen.h" > > -/* NB. All ops return zero on success, except XENVER_{version,pagesize} */ > +/* NB. All ops return zero on success, except > + * XENVER_{version,pagesize, build_id} */ > > /* arg == NULL; returns major:minor (16:16). */ > #define XENVER_version 0 > @@ -83,6 +84,12 @@ typedef struct xen_feature_info xen_feature_info_t; > #define XENVER_commandline 9 > typedef char xen_commandline_t[1024]; > > +#define XENVER_build_id 10 > +/* > + * arg1 == pointer to char array, arg2 == size of char array. > + * Return value is the actual size. Return value is the number of bytes written, or -ve error. ~Andrew
_______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel