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

Reply via email to