mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
Implemented basement to work with unaligned data
This commit is contained in:
@@ -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]])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user