]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
build: avoid non-portable byte-swapping
authorEric Blake <eblake@redhat.com>
Tue, 18 Sep 2012 19:53:15 +0000 (13:53 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 18 Sep 2012 19:53:15 +0000 (13:53 -0600)
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.

bootstrap.conf
src/util/bitmap.c

index 2847c0bfd37303318146ad03a0b4555fd3f4020f..23000ac73c7e80cad3bcd007ec6105b9a589a5ec 100644 (file)
@@ -44,6 +44,7 @@ fcntl
 fcntl-h
 fdatasync
 ffs
+ffsl
 fnmatch
 fsync
 func
index 51e567a8052e37fb4f37a4a08ff898a1930d305b..4bade6cbde56db819297e612d877063db4a6211d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bitmap.h: Simple bitmap operations
  *
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2012 Red Hat, Inc.
  * Copyright (C) 2010 Novell, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -27,6 +27,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
+#include <strings.h>
 #include <stdlib.h>
 #include <sys/types.h>
 
@@ -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)) {
+            j = 0;
+            p++;
+        }
+        *p |= bytes[i] << (j * CHAR_BIT);
+    }
 
     return bitmap;
 }
@@ -446,19 +455,26 @@ int virBitmapToData(virBitmapPtr bitmap, unsigned char **data, int *dataLen)
 {
     int len;
     unsigned long *l;
-    int i;
+    int i, j;
+    unsigned char *bytes;
 
-    len = bitmap->map_len * (VIR_BITMAP_BITS_PER_UNIT / CHAR_BIT);
+    len = (bitmap->max_bit + CHAR_BIT - 1) / CHAR_BIT;
 
     if (VIR_ALLOC_N(*data, len) < 0)
         return -1;
 
-    memcpy(*data, bitmap->map, len);
+    bytes = *data;
     *dataLen = len;
 
-    l = (unsigned long *)*data;
-    for (i = 0; i < bitmap->map_len; i++, l++)
-        *l = htole64(*l);
+    /* htole64 is not provided by gnulib, so we do the conversion by hand */
+    l = bitmap->map;
+    for (i = j = 0; i < len; i++, j++) {
+        if (j == sizeof(*l)) {
+            j = 0;
+            l++;
+        }
+        bytes[i] = *l >> (j * CHAR_BIT);
+    }
 
     return 0;
 }