> This patch adds a new module 'ssfmalloc', a "simple and straight-forward 
> memory
> allocation" facility.

This sets of patches fixes portability issues and does small improvements.


2020-10-25  Bruno Haible  <br...@clisp.org>

        ssfmalloc tests: Small tweaks.
        * tests/test-ssfmalloc.c: Add comments.
        (alloc_pages): Don't require PROT_EXEC bits.
        (block_sizes): Add more small sizes, for better coverage of
        ssfmalloc-bitmap.h.

        ssfmalloc tests: Portability to Minix.
        * modules/ssfmalloc-tests (Files): Add m4/mmap-anon.m4.
        (configure.ac): Invoke gl_FUNC_MMAP_ANON.
        * m4/mmap-anon.m4: Update comment.

        ssfmalloc: Portability to AIX.
        * modules/ssfmalloc (Include): Add ssfmalloc.h.
        (Link): New section.
        * modules/ssfmalloc-tests (Makefile.am): Link test-ssfmalloc with
        $(LIBTHREAD).

        ssfmalloc: Portability to Cygwin.
        * lib/ssfmalloc.h: Add parameter PAGESIZE_MAX.
        (pg_offset_t): Define depending on PAGESIZE_MAX.
        * tests/test-ssfmalloc.c: Undefine PAGESIZE.
        (PAGESIZE_MAX): New macro.

        ssfmalloc: Fix buffer overrun in bitmap search.
        * lib/ssfmalloc-bitmap.h (find_first_packet_set): Don't access the
        word *words_end.

From c433211e54786e26b9c787f3d4a4212536ffaa46 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 25 Oct 2020 18:03:34 +0100
Subject: [PATCH 1/5] ssfmalloc: Fix buffer overrun in bitmap search.

* lib/ssfmalloc-bitmap.h (find_first_packet_set): Don't access the
word *words_end.
---
 ChangeLog              |   6 ++
 lib/ssfmalloc-bitmap.h | 248 ++++++++++++++++++++++++-------------------------
 2 files changed, 130 insertions(+), 124 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8fa32e1..ed0195d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2020-10-25  Bruno Haible  <br...@clisp.org>
+
+	ssfmalloc: Fix buffer overrun in bitmap search.
+	* lib/ssfmalloc-bitmap.h (find_first_packet_set): Don't access the
+	word *words_end.
+
 2020-10-24  Paul Eggert  <egg...@cs.ucla.edu>
 
 	doc: mention ‘restrict’ and C++
diff --git a/lib/ssfmalloc-bitmap.h b/lib/ssfmalloc-bitmap.h
index abf9949..7410675 100644
--- a/lib/ssfmalloc-bitmap.h
+++ b/lib/ssfmalloc-bitmap.h
@@ -92,217 +92,217 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
       }
     case 2:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t combined = longword & (longword >> 1);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 3:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t combined = longword & (longword >> 1) & (longword >> 2);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 4:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t combined = tmp1 & (tmp1 >> 2);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 5:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (longword >> 4);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 6:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t combined = tmp1 & (tmp1 >> 2) & (tmp1 >> 4);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 7:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t combined =
               tmp1 & (tmp1 >> 2) & (tmp1 >> 4) & (longword >> 6);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 8:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (tmp2 >> 4);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 9:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (longword >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 10:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp1 >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 11:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp1 >> 8) & (longword >> 10);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 12:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (tmp2 >> 4) & (tmp2 >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 13:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined =
               tmp2 & (tmp2 >> 4) & (tmp2 >> 8) & (longword >> 12);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 14:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t combined = tmp2 & (tmp2 >> 4) & (tmp2 >> 8) & (tmp1 >> 12);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 15:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             /* Optimized: Use 5, not 6, '&' operations.  */
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
@@ -310,34 +310,34 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp3 & (tmp3 >> 5) & (tmp3 >> 10);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 16:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp3 >> 8);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 17:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -345,17 +345,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (longword >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 18:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -363,17 +363,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp1 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 19:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -381,17 +381,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp1 >> 16) & (longword >> 18);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 20:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -399,17 +399,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp2 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 21:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -417,17 +417,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp2 >> 16) & (longword >> 20);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 22:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -435,17 +435,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp2 >> 16) & (tmp1 >> 20);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 23:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -454,34 +454,34 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp4 & (tmp2 >> 16) & (tmp1 >> 20) & (longword >> 22);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 24:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
             uint64_t combined = tmp3 & (tmp3 >> 8) & (tmp3 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 25:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -489,17 +489,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (longword >> 24);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 26:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -507,17 +507,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (tmp1 >> 24);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 27:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             /* Optimized: Use 6, not 7, '&' operations.  */
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
@@ -526,17 +526,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp4 >> 9) & (tmp4 >> 18);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 28:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -544,17 +544,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (tmp2 >> 24);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 29:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -562,17 +562,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp3 & (tmp3 >> 8) & (tmp3 >> 16) & (tmp2 >> 24) & (longword >> 28);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 30:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             /* Optimized: Use 6, not 7, '&' operations.  */
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
@@ -581,17 +581,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp4 >> 10) & (tmp4 >> 20);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 31:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -600,17 +600,17 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
               tmp4 & (tmp3 >> 16) & (tmp2 >> 24) & (tmp1 >> 28) & (longword >> 30);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
     case 32:
       {
-        for (; ptr < words_end; ptr++)
+        while (ptr < words_end)
           {
-            uint64_t longword = ptr[0];
+            uint64_t longword = *ptr++;
             if (likely (ptr < words_end))
-              longword |= ((uint64_t) ptr[1]) << 32;
+              longword |= ((uint64_t) *ptr) << 32;
             uint64_t tmp1 = longword & (longword >> 1);
             uint64_t tmp2 = tmp1 & (tmp1 >> 2);
             uint64_t tmp3 = tmp2 & (tmp2 >> 4);
@@ -618,7 +618,7 @@ find_first_packet_set (size_t num_words, const uint32_t *words, size_t c)
             uint64_t combined = tmp4 & (tmp4 >> 16);
             size_t found = ffsll (combined);
             if (found > 0)
-              return 32 * (ptr - words) + (found - 1);
+              return 32 * (ptr - 1 - words) + (found - 1);
           }
         return (size_t)(-1);
       }
-- 
2.7.4

>From 476f69f3bf87887c61f938e6450da874826df867 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 25 Oct 2020 18:08:44 +0100
Subject: [PATCH 2/5] ssfmalloc: Portability to Cygwin.

* lib/ssfmalloc.h: Add parameter PAGESIZE_MAX.
(pg_offset_t): Define depending on PAGESIZE_MAX.
* tests/test-ssfmalloc.c: Undefine PAGESIZE.
(PAGESIZE_MAX): New macro.
---
 ChangeLog              |  6 ++++++
 lib/ssfmalloc.h        |  6 ++++++
 tests/test-ssfmalloc.c | 12 ++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index ed0195d..5f82793 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-10-25  Bruno Haible  <br...@clisp.org>
 
+	ssfmalloc: Portability to Cygwin.
+	* lib/ssfmalloc.h: Add parameter PAGESIZE_MAX.
+	(pg_offset_t): Define depending on PAGESIZE_MAX.
+	* tests/test-ssfmalloc.c: Undefine PAGESIZE.
+	(PAGESIZE_MAX): New macro.
+
 	ssfmalloc: Fix buffer overrun in bitmap search.
 	* lib/ssfmalloc-bitmap.h (find_first_packet_set): Don't access the
 	word *words_end.
diff --git a/lib/ssfmalloc.h b/lib/ssfmalloc.h
index 999126e..43d0851 100644
--- a/lib/ssfmalloc.h
+++ b/lib/ssfmalloc.h
@@ -55,6 +55,8 @@
      PAGESIZE           A variable-like macro of type intptr_t or uintptr_t
                         that evaluates to the memory page size (>= 4096).
 
+     PAGESIZE_MAX       A constant that specifies an upper bound for PAGESIZE.
+
      ALLOC_PAGES        A function-like macro with the signature
                           uintptr_t ALLOC_PAGES (size_t size)
                         where the argument size is > 0 and a multiple of the
@@ -151,7 +153,11 @@ struct any_page_header
 /* ========================= Small and medium blocks ======================== */
 
 /* An integer type, capable of holding the values 0 .. PAGESIZE.  */
+#if PAGESIZE_MAX >= 0x10000
+typedef unsigned int   pg_offset_t;
+#else
 typedef unsigned short pg_offset_t;
+#endif
 
 /* Tree element that corresponds to a page.
    These tree elements are allocated via malloc().  */
diff --git a/tests/test-ssfmalloc.c b/tests/test-ssfmalloc.c
index e1dfcec..09427c7 100644
--- a/tests/test-ssfmalloc.c
+++ b/tests/test-ssfmalloc.c
@@ -118,13 +118,25 @@ free_pages (uintptr_t pages, size_t size)
 #endif
 }
 
+/* Cygwin defines PAGESIZE in <limits.h>.  */
+#undef PAGESIZE
+
 /* ======================= Instantiate the front end ======================= */
 
 #define PAGESIZE pagesize
+/* On Cygwin, PAGESIZE is 65536.  On all other platforms, it is either 4096
+   or 8192.  */
+#ifdef __CYGWIN__
+# define PAGESIZE_MAX 65536
+#else
+# define PAGESIZE_MAX 8192
+#endif
+
 #define ALLOC_PAGES alloc_pages
 #define FREE_PAGES free_pages
 #define ALIGNMENT (sizeof (void *)) /* or 8 or 16 or 32 */
 #define PAGE_RESERVED_HEADER_SIZE (3 * UINTPTR_WIDTH / 8) /* = 3 * sizeof (void *) */
+
 #include "ssfmalloc.h"
 
 /* ================================= Tests ================================= */
-- 
2.7.4

>From 92e34aba7c512f4084fa2447087d090be554c0e0 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 25 Oct 2020 18:14:09 +0100
Subject: [PATCH 3/5] ssfmalloc: Portability to AIX.

* modules/ssfmalloc (Include): Add ssfmalloc.h.
(Link): New section.
* modules/ssfmalloc-tests (Makefile.am): Link test-ssfmalloc with
$(LIBTHREAD).
---
 ChangeLog               | 6 ++++++
 modules/ssfmalloc       | 4 ++++
 modules/ssfmalloc-tests | 1 +
 3 files changed, 11 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 5f82793..32b5e0e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-10-25  Bruno Haible  <br...@clisp.org>
 
+	ssfmalloc: Portability to AIX.
+	* modules/ssfmalloc (Include): Add ssfmalloc.h.
+	(Link): New section.
+	* modules/ssfmalloc-tests (Makefile.am): Link test-ssfmalloc with
+	$(LIBTHREAD).
+
 	ssfmalloc: Portability to Cygwin.
 	* lib/ssfmalloc.h: Add parameter PAGESIZE_MAX.
 	(pg_offset_t): Define depending on PAGESIZE_MAX.
diff --git a/modules/ssfmalloc b/modules/ssfmalloc
index d46f652..ace411b 100644
--- a/modules/ssfmalloc
+++ b/modules/ssfmalloc
@@ -19,6 +19,10 @@ configure.ac:
 Makefile.am:
 
 Include:
+"ssfmalloc.h"
+
+Link:
+$(LIBTHREAD)
 
 License:
 LGPLv2+
diff --git a/modules/ssfmalloc-tests b/modules/ssfmalloc-tests
index ea1ed2c..c1994f1 100644
--- a/modules/ssfmalloc-tests
+++ b/modules/ssfmalloc-tests
@@ -9,3 +9,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-ssfmalloc
 check_PROGRAMS += test-ssfmalloc
+test_ssfmalloc_LDADD = $(LDADD) $(LIBTHREAD)
-- 
2.7.4

>From 4b52185214e9bd28026df2e1694191f2f8abe3f1 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 25 Oct 2020 18:16:10 +0100
Subject: [PATCH 4/5] ssfmalloc tests: Portability to Minix.

* modules/ssfmalloc-tests (Files): Add m4/mmap-anon.m4.
(configure.ac): Invoke gl_FUNC_MMAP_ANON.
* m4/mmap-anon.m4: Update comment.
---
 ChangeLog               | 5 +++++
 m4/mmap-anon.m4         | 4 ++--
 modules/ssfmalloc-tests | 2 ++
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 32b5e0e..26ba40c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-10-25  Bruno Haible  <br...@clisp.org>
 
+	ssfmalloc tests: Portability to Minix.
+	* modules/ssfmalloc-tests (Files): Add m4/mmap-anon.m4.
+	(configure.ac): Invoke gl_FUNC_MMAP_ANON.
+	* m4/mmap-anon.m4: Update comment.
+
 	ssfmalloc: Portability to AIX.
 	* modules/ssfmalloc (Include): Add ssfmalloc.h.
 	(Link): New section.
diff --git a/m4/mmap-anon.m4 b/m4/mmap-anon.m4
index d5c69df..2995ad5 100644
--- a/m4/mmap-anon.m4
+++ b/m4/mmap-anon.m4
@@ -1,4 +1,4 @@
-# mmap-anon.m4 serial 10
+# mmap-anon.m4 serial 11
 dnl Copyright (C) 2005, 2007, 2009-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -9,7 +9,7 @@ dnl with or without modifications, as long as this notice is preserved.
 # - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS
 #   and MAP_ANON exist and have the same value.
 # - On HP-UX, only MAP_ANONYMOUS exists.
-# - On Mac OS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists.
+# - On Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, only MAP_ANON exists.
 # - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be
 #   used.
 
diff --git a/modules/ssfmalloc-tests b/modules/ssfmalloc-tests
index c1994f1..5e35fe4 100644
--- a/modules/ssfmalloc-tests
+++ b/modules/ssfmalloc-tests
@@ -1,10 +1,12 @@
 Files:
 tests/test-ssfmalloc.c
 tests/macros.h
+m4/mmap-anon.m4
 
 Depends-on:
 
 configure.ac:
+gl_FUNC_MMAP_ANON
 
 Makefile.am:
 TESTS += test-ssfmalloc
-- 
2.7.4

>From 475eac69463f384419a3b5a8bd449a6876123fab Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 25 Oct 2020 18:18:06 +0100
Subject: [PATCH 5/5] ssfmalloc tests: Small tweaks.

* tests/test-ssfmalloc.c: Add comments.
(alloc_pages): Don't require PROT_EXEC bits.
(block_sizes): Add more small sizes, for better coverage of
ssfmalloc-bitmap.h.
---
 ChangeLog              |  6 ++++++
 tests/test-ssfmalloc.c | 25 ++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 26ba40c..bb838bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-10-25  Bruno Haible  <br...@clisp.org>
 
+	ssfmalloc tests: Small tweaks.
+	* tests/test-ssfmalloc.c: Add comments.
+	(alloc_pages): Don't require PROT_EXEC bits.
+	(block_sizes): Add more small sizes, for better coverage of
+	ssfmalloc-bitmap.h.
+
 	ssfmalloc tests: Portability to Minix.
 	* modules/ssfmalloc-tests (Files): Add m4/mmap-anon.m4.
 	(configure.ac): Invoke gl_FUNC_MMAP_ANON.
diff --git a/tests/test-ssfmalloc.c b/tests/test-ssfmalloc.c
index 09427c7..9699e6b 100644
--- a/tests/test-ssfmalloc.c
+++ b/tests/test-ssfmalloc.c
@@ -92,7 +92,7 @@ alloc_pages (size_t size)
   return (uintptr_t) mem;
 #else
   /* Use mmap with the MAP_ANONYMOUS or MAP_ANON flag.  */
-  void *mem = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+  void *mem = mmap (NULL, size, PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS | MAP_VARIABLE, -1, 0);
   if (mem == (void *)(-1))
     return 0;
@@ -143,6 +143,7 @@ free_pages (uintptr_t pages, size_t size)
 
 #include "macros.h"
 
+/* Fills a block of a given size with some contents.  */
 static void
 fill_block (uintptr_t block, size_t size)
 {
@@ -150,6 +151,8 @@ fill_block (uintptr_t block, size_t size)
   memset ((char *) block, code, size);
 }
 
+/* Verifies that the contents of a block is still present
+   (i.e. has not accidentally been overwritten by other operations).  */
 static void
 verify_block (uintptr_t block, size_t size)
 {
@@ -187,12 +190,29 @@ static size_t block_sizes[] =
     64,
     65,
     71,
+    77,
     83,
+    96,
     99,
     110,
+    119,
     127,
     128,
+    130,
+    144,
+    150,
+    157,
+    161,
     169,
+    180,
+    192,
+    199,
+    204,
+    210,
+    224,
+    225,
+    236,
+    241,
     249,
     255,
     256,
@@ -266,6 +286,9 @@ main (int argc, char *argv[])
 
   init_pagesize ();
 
+  /* Randomly allocate and deallocate blocks.
+     Also verify that there are no unexpected modifications to the contents of
+     these blocks.  */
   {
     unsigned int repeat;
     char *blocks[SIZEOF (block_sizes)];
-- 
2.7.4

Reply via email to