[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]