[libvirt] [PATCH] build: avoid non-portable byte-swapping

Peter Krempa pkrempa at redhat.com
Tue Sep 18 20:54:17 UTC 2012


On 09/18/12 21:55, Eric Blake wrote:
> Commit 0fc89098 used functions only available on glibc, completely
> botched 32-bit environments, and risked SIGBUS due to unaligned
> memory access on platforms that aren't as forgiving as x86_64.
>
> * bootstrap.conf (gnulib_modules): Import ffsl.
> * src/util/bitmap.c (includes): Use <strings.h> for ffsl.
> (virBitmapNewData, virBitmapToData): Avoid 64-bit assumptions and
> non-portable functions.
> ---
>
> I wish I could push this under the build-breaker rule, but it is
> not quite trivial enough.

Indeed. Bit magic never was trivial :).

>
>   bootstrap.conf    |  1 +
>   src/util/bitmap.c | 38 +++++++++++++++++++++++++++-----------
>   2 files changed, 28 insertions(+), 11 deletions(-)
>
> diff --git a/src/util/bitmap.c b/src/util/bitmap.c
> index 51e567a..4bade6c 100644
> --- a/src/util/bitmap.c
> +++ b/src/util/bitmap.c
> @@ -418,15 +419,23 @@ virBitmapPtr virBitmapNewCopy(virBitmapPtr src)
>   virBitmapPtr virBitmapNewData(void *data, int len)
>   {
>       virBitmapPtr bitmap;
> -    int i;
> +    int i, j;
> +    unsigned long *p;
> +    unsigned char *bytes = data;
>
>       bitmap = virBitmapNew(len * CHAR_BIT);
>       if (!bitmap)
>           return NULL;
>
> -    memcpy(bitmap->map, data, len);
> -    for (i = 0; i < bitmap->map_len; i++)
> -        bitmap->map[i] = le64toh(bitmap->map[i]);
> +    /* le64toh is not provided by gnulib, so we do the conversion by hand */
> +    p = bitmap->map;
> +    for (i = j = 0; i < len; i++, j++) {
> +        if (j == sizeof(*p)) {

Incrementing a variable is probably better than calculating modulo.

> +            j = 0;
> +            p++;
> +        }
> +        *p |= bytes[i] << (j * CHAR_BIT);
> +    }
>
>       return bitmap;
>   }

ACK. If there isn't a bug in my "brain simulation unit" then this should 
work as intended.

Peter




More information about the libvir-list mailing list