gnunet-svn
[Top][All Lists]
Advanced

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

[libmicrohttpd] 01/03: Implemented basement to work with unaligned data


From: gnunet
Subject: [libmicrohttpd] 01/03: Implemented basement to work with unaligned data
Date: Tue, 18 May 2021 19:27:29 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit 89387e53fe9e5d876fb14f31eac5da7d690290ff
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Tue May 18 19:37:10 2021 +0300

    Implemented basement to work with unaligned data
---
 configure.ac                    | 50 +++++++++++++++++++++++++++
 src/microhttpd/Makefile.am      | 16 ++++-----
 src/microhttpd/mhd_align.h      | 75 +++++++++++++++++++++++++++++++++++++++++
 src/microhttpd/mhd_bithelpers.h | 44 +++++++++++++++++++-----
 4 files changed, 168 insertions(+), 17 deletions(-)

diff --git a/configure.ac b/configure.ac
index cfe3e554..0cf4e43f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -307,6 +307,56 @@ AS_IF([[test "x$inln_prfx" != "xnone"]],
 AC_MSG_RESULT([[$inln_prfx]])
 CFLAGS="$save_CFLAGS"
 
+AC_CHECK_HEADERS([stdalign.h], [], [], [AC_INCLUDES_DEFAULT])
+AC_CACHE_CHECK([[for C11 'alignof()' support]], [[mhd_cv_c_alignof]],
+  [AC_COMPILE_IFELSE(
+     [AC_LANG_PROGRAM(
+        [[
+#ifdef HAVE_STDALIGN_H
+#include <stdalign.h>
+#endif
+        ]], [[
+#if (defined (__GNUC__) && __GNUC__ < 4 && __GNUC_MINOR__ < 9 && ! 
defined(__clang__)) || \
+    (defined (__clang__) && __clang_major__ < 8)
+/* GCC before 4.9 and clang before 8.0 have incorrect implementation of 
'alignof()'
+   which returns preferred alignment instead of minimal required alignment */  
  
+#error Compiler has incorrect implementation of alignof()
+choke me now
+#endif
+          int var1[(alignof(int) >= 2) ? 1 : -1];
+          int var2[alignof(unsigned int) - 1];
+          int var3[(alignof(char) > 0) ? 1 : -1];
+          int var4[(alignof(long) >= 4) ? 1 : -1];
+          
+          /* Mute compiler warnings */
+          var1[0] = var2[0] = var3[0] = 0;
+          var4[0] = 1;
+          if (var1[0] + var2[0] + var3[0] == var4[0])
+            return 1;
+        ]])
+     ], [
+          AC_COMPILE_IFELSE(
+                   [AC_LANG_PROGRAM(
+                       [[
+#ifdef HAVE_STDALIGN_H
+#include <stdalign.h>
+#endif
+                       ]], [[
+                         /* Should fail if 'alignof()' works */
+                         int var1[alignof(nonexisting_type) - 1];
+                         
+                         /* Mute compiler warnings */
+                         var1[0] = 1;
+                         if (var1[0] + 1 == 1)
+                           return 1;
+                       ]])
+                   ], [[mhd_cv_c_alignof='no']], [[mhd_cv_c_alignof='yes']])
+        ], [[mhd_cv_c_alignof='no']])
+  ])
+AS_VAR_IF([mhd_cv_c_alignof], ["yes"],
+  [AC_DEFINE([[HAVE_C_ALIGNOF]], [1], [Define to 1 if your compiler supports 
'alignof()'])])
+
+
 # Check system type
 shutdown_trig_select='no'
 AC_MSG_CHECKING([[for target host OS]])
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index 84fe4f81..abcbeba7 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -59,7 +59,7 @@ libmicrohttpd_la_SOURCES = \
   internal.c internal.h \
   memorypool.c memorypool.h \
   mhd_mono_clock.c mhd_mono_clock.h \
-  mhd_limits.h mhd_byteorder.h \
+  mhd_limits.h \
   sysfdsetsize.c sysfdsetsize.h \
   mhd_str.c mhd_str.h \
   mhd_send.h mhd_send.c \
@@ -138,7 +138,7 @@ endif
 if ENABLE_DAUTH
 libmicrohttpd_la_SOURCES += \
   digestauth.c \
-  mhd_bithelpers.h \
+  mhd_bithelpers.h mhd_byteorder.h mhd_align.h \
   md5.c md5.h \
   sha256.c sha256.h
 endif
@@ -345,13 +345,13 @@ test_shutdown_poll_ignore_LDADD = \
 endif
 
 test_str_compare_SOURCES = \
-  test_str.c test_helpers.h mhd_str.c
+  test_str.c test_helpers.h mhd_str.c mhd_str.h
 
 test_str_to_value_SOURCES = \
-  test_str.c test_helpers.h mhd_str.c
+  test_str.c test_helpers.h mhd_str.c mhd_str.h
 
 test_str_token_SOURCES = \
-  test_str_token.c mhd_str.c
+  test_str_token.c mhd_str.c mhd_str.h
 
 test_http_reasons_SOURCES = \
   test_http_reasons.c \
@@ -359,15 +359,15 @@ test_http_reasons_SOURCES = \
 
 test_md5_SOURCES = \
   test_md5.c test_helpers.h \
-  md5.c md5.h mhd_bithelpers.h
+  md5.c md5.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
 
 test_sha256_SOURCES = \
   test_sha256.c test_helpers.h \
-  sha256.c sha256.h mhd_bithelpers.h
+  sha256.c sha256.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
 
 test_sha1_SOURCES = \
   test_sha1.c test_helpers.h \
-  sha1.c sha1.h mhd_bithelpers.h
+  sha1.c sha1.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
 
 test_options_SOURCES = \
   test_options.c
diff --git a/src/microhttpd/mhd_align.h b/src/microhttpd/mhd_align.h
new file mode 100644
index 00000000..4464b6cd
--- /dev/null
+++ b/src/microhttpd/mhd_align.h
@@ -0,0 +1,75 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2021 Karlson2k (Evgeny Grin)
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library.
+  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/mhd_align.h
+ * @brief  types alignment macros
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_ALIGN_H
+#define MHD_ALIGN_H 1
+
+#include <stdint.h>
+#include "mhd_options.h"
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_C_ALIGNOF
+
+#ifdef HAVE_STDALIGN_H
+#include <stdalign.h>
+#endif
+
+#define _MHD_ALIGNOF(type) alignof(type)
+
+#endif /* HAVE_C_ALIGNOF */
+
+#ifdef offsetof
+#define _MHD_OFFSETOF(strct, membr) offsetof(strct, membr)
+#else  /* ! offsetof */
+#define _MHD_OFFSETOF(strct, membr) (size_t)(((char*)&(((strct*)0)->membr)) - \
+                                     ((char*)((strct*)0)))
+#endif /* ! offsetof */
+
+/* Provide a limited set of alignment macros */
+/* The set could be extended as needed */
+#ifdef _MHD_ALIGNOF
+#define _MHD_UINT32_ALIGN _MHD_ALIGNOF(uint32_t)
+#define _MHD_UINT64_ALIGN _MHD_ALIGNOF(uint64_t)
+#else  /* ! _MHD_ALIGNOF */
+struct _mhd_dummy_uint32_offset_test
+{
+  char dummy;
+  uint32_t ui32;
+};
+#define _MHD_UINT32_ALIGN \
+  _MHD_OFFSETOF(struct _mhd_dummy_uint32_offset_test, ui32)
+
+struct _mhd_dummy_uint64_offset_test
+{
+  char dummy;
+  uint32_t ui64;
+};
+#define _MHD_UINT32_ALIGN \
+  _MHD_OFFSETOF(struct _mhd_dummy_uint64_offset_test, ui64)
+#endif /* ! _MHD_ALIGNOF */
+
+#endif /* ! MHD_ALIGN_H */
diff --git a/src/microhttpd/mhd_bithelpers.h b/src/microhttpd/mhd_bithelpers.h
index c8c814ac..12e1a569 100644
--- a/src/microhttpd/mhd_bithelpers.h
+++ b/src/microhttpd/mhd_bithelpers.h
@@ -32,8 +32,13 @@
 /* Declarations for VC & Clang/C2 built-ins */
 #include <intrin.h>
 #endif /* _MSC_FULL_VER  */
+#include "mhd_options.h"
 #include "mhd_assert.h"
 #include "mhd_byteorder.h"
+#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN || _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#include "mhd_align.h"
+#endif /* _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN ||
+          _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */
 
 #ifndef __has_builtin
 /* Avoid precompiler errors with non-clang */
@@ -158,15 +163,8 @@
  * put native-endian 64-bit value64 to addr
  * in big-endian mode.
  */
-#if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
-#define _MHD_PUT_64BIT_BE(addr, value64)             \
-  ((*(uint64_t*) (addr)) = (uint64_t) (value64))
-#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
-#define _MHD_PUT_64BIT_BE(addr, value64)             \
-  ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
-#else  /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
-/* Endianness was not detected or non-standard like PDP-endian */
-#define _MHD_PUT_64BIT_BE(addr, value64) do {                            \
+/* Slow version that works with unaligned addr and with any bytes order */
+#define _MHD_PUT_64BIT_BE_SLOW(addr, value64) do {                       \
     ((uint8_t*) (addr))[7] = (uint8_t) ((uint64_t) (value64));           \
     ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 8);    \
     ((uint8_t*) (addr))[5] = (uint8_t) (((uint64_t) (value64)) >> 16);   \
@@ -176,8 +174,32 @@
     ((uint8_t*) (addr))[1] = (uint8_t) (((uint64_t) (value64)) >> 48);   \
     ((uint8_t*) (addr))[0] = (uint8_t) (((uint64_t) (value64)) >> 56);   \
 } while (0)
+#if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_PUT_64BIT_BE(addr, value64)             \
+  ((*(uint64_t*) (addr)) = (uint64_t) (value64))
+#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_PUT_64BIT_BE(addr, value64)             \
+  ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
+#else  /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_PUT_64BIT_BE(addr, value64) _MHD_PUT_64BIT_BE_SLOW(addr, value64)
+/* Indicate that _MHD_PUT_64BIT_BE does not need aligned pointer */
+#define _MHD_PUT_64BIT_BE_UNALIGNED 1
 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
 
+/* Put result safely to unaligned address */
+_MHD_static_inline void
+_MHD_PUT_64BIT_BE_SAFE (void *dst, uint64_t value)
+{
+#ifndef _MHD_PUT_64BIT_BE_UNALIGNED
+  if (0 != ((uintptr_t) dst) % (_MHD_UINT64_ALIGN))
+    _MHD_PUT_64BIT_BE_SLOW (dst, value);
+  else
+#endif /* _MHD_BYTE_ORDER_IS_BIG_OR_LITTLE_ENDIAN */
+  _MHD_PUT_64BIT_BE (dst, value);
+}
+
+
 /* _MHD_PUT_32BIT_BE (addr, value32)
  * put native-endian 32-bit value32 to addr
  * in big-endian mode.
@@ -196,6 +218,8 @@
     ((uint8_t*) (addr))[1] = (uint8_t) (((uint32_t) (value32)) >> 16);   \
     ((uint8_t*) (addr))[0] = (uint8_t) (((uint32_t) (value32)) >> 24);   \
 } while (0)
+/* Indicate that _MHD_PUT_32BIT_BE does not need aligned pointer */
+#define _MHD_PUT_32BIT_BE_UNALIGNED 1
 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
 
 /* _MHD_GET_32BIT_BE (addr)
@@ -215,6 +239,8 @@
     | (((uint32_t) (((const uint8_t*) addr)[1])) << 16)   \
     | (((uint32_t) (((const uint8_t*) addr)[2])) << 8)    \
     | ((uint32_t) (((const uint8_t*) addr)[3])) )
+/* Indicate that _MHD_GET_32BIT_BE does not need aligned pointer */
+#define _MHD_GET_32BIT_BE_UNALIGNED 1
 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
 
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]