]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Check for unaligned memory access support at compile time.
authorGuy Harris <[email protected]>
Mon, 16 Oct 2017 08:39:10 +0000 (01:39 -0700)
committerGuy Harris <[email protected]>
Mon, 16 Oct 2017 08:39:10 +0000 (01:39 -0700)
Don't test at configure time; that doesn't work when cross-compiling and
may be a pain to do with CMake.

aclocal.m4
config.h.in
configure
configure.in
extract.h
netdissect.h
util-print.c

index fbfbbea18feacd7c6b03140d36a9d8893093842f..d8679a640d5cdcae36c954b6a51966d33d78274d 100644 (file)
@@ -798,106 +798,6 @@ AC_DEFUN(AC_LBL_CHECK_64BIT_FORMAT,
       ])
   ])
 
-dnl
-dnl Checks to see if unaligned memory accesses fail
-dnl
-dnl usage:
-dnl
-dnl    AC_LBL_UNALIGNED_ACCESS
-dnl
-dnl results:
-dnl
-dnl    LBL_ALIGN (DEFINED)
-dnl
-AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
-    [AC_MSG_CHECKING(if unaligned accesses fail)
-    AC_CACHE_VAL(ac_cv_lbl_unaligned_fail,
-       [case "$host_cpu" in
-
-       #
-       # These are CPU types where:
-       #
-       #       the CPU faults on an unaligned access, but at least some
-       #       OSes that support that CPU catch the fault and simulate
-       #       the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) -
-       #       the simulation is slow, so we don't want to use it;
-       #
-       #       the CPU, I infer (from the old
-       #
-       # XXX: should also check that they don't do weird things (like on arm)
-       #
-       #       comment) doesn't fault on unaligned accesses, but doesn't
-       #       do a normal unaligned fetch, either (e.g., presumably, ARM);
-       #
-       #       for whatever reason, the test program doesn't work
-       #       (this has been claimed to be the case for several of those
-       #       CPUs - I don't know what the problem is; the problem
-       #       was reported as "the test program dumps core" for SuperH,
-       #       but that's what the test program is *supposed* to do -
-       #       it dumps core before it writes anything, so the test
-       #       for an empty output file should find an empty output
-       #       file and conclude that unaligned accesses don't work).
-       #
-       # This run-time test won't work if you're cross-compiling, so
-       # in order to support cross-compiling for a particular CPU,
-       # we have to wire in the list of CPU types anyway, as far as
-       # I know, so perhaps we should just have a set of CPUs on
-       # which we know it doesn't work, a set of CPUs on which we
-       # know it does work, and have the script just fail on other
-       # cpu types and update it when such a failure occurs.
-       #
-       alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1)
-               ac_cv_lbl_unaligned_fail=yes
-               ;;
-
-       *)
-               cat >conftest.c <<EOF
-#              include <sys/types.h>
-#              include <sys/wait.h>
-#              include <stdio.h>
-               unsigned char a[[5]] = { 1, 2, 3, 4, 5 };
-               main() {
-               unsigned int i;
-               pid_t pid;
-               int status;
-               /* avoid "core dumped" message */
-               pid = fork();
-               if (pid <  0)
-                       exit(2);
-               if (pid > 0) {
-                       /* parent */
-                       pid = waitpid(pid, &status, 0);
-                       if (pid < 0)
-                               exit(3);
-                       exit(!WIFEXITED(status));
-               }
-               /* child */
-               i = *(unsigned int *)&a[[1]];
-               printf("%d\n", i);
-               exit(0);
-               }
-EOF
-               ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
-                   conftest.c $LIBS >/dev/null 2>&1
-               if test ! -x conftest ; then
-                       dnl failed to compile for some reason
-                       ac_cv_lbl_unaligned_fail=yes
-               else
-                       ./conftest >conftest.out
-                       if test ! -s conftest.out ; then
-                               ac_cv_lbl_unaligned_fail=yes
-                       else
-                               ac_cv_lbl_unaligned_fail=no
-                       fi
-               fi
-               rm -f -r conftest* core core.conftest
-               ;;
-       esac])
-    AC_MSG_RESULT($ac_cv_lbl_unaligned_fail)
-    if test $ac_cv_lbl_unaligned_fail = yes ; then
-           AC_DEFINE(LBL_ALIGN,1,[if unaligned access fails])
-    fi])
-
 dnl
 dnl If the file .devel exists:
 dnl    Add some warning flags if the compiler supports them
index 487364dcc1c6e22a615a27a8eb8b28b2c30765b9..6d695afaa1b67d93a87216d50f3b59b80dbaa562 100644 (file)
 /* define if your compiler has __attribute__ */
 #undef HAVE___ATTRIBUTE__
 
-/* if unaligned access fails */
-#undef LBL_ALIGN
-
 /* Define to 1 if netinet/ether.h declares `ether_ntohost' */
 #undef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST
 
index e359c868bd162b21256c04f728d04cf01cab6c8c..4203e7317ca5f2e86dc06436b45fe2982069e347 100755 (executable)
--- a/configure
+++ b/configure
@@ -7332,101 +7332,6 @@ $as_echo "$as_me: WARNING: can't find $name" >&2;}
            fi
     fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if unaligned accesses fail" >&5
-$as_echo_n "checking if unaligned accesses fail... " >&6; }
-    if ${ac_cv_lbl_unaligned_fail+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case "$host_cpu" in
-
-       #
-       # These are CPU types where:
-       #
-       #       the CPU faults on an unaligned access, but at least some
-       #       OSes that support that CPU catch the fault and simulate
-       #       the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) -
-       #       the simulation is slow, so we don't want to use it;
-       #
-       #       the CPU, I infer (from the old
-       #
-       # XXX: should also check that they don't do weird things (like on arm)
-       #
-       #       comment) doesn't fault on unaligned accesses, but doesn't
-       #       do a normal unaligned fetch, either (e.g., presumably, ARM);
-       #
-       #       for whatever reason, the test program doesn't work
-       #       (this has been claimed to be the case for several of those
-       #       CPUs - I don't know what the problem is; the problem
-       #       was reported as "the test program dumps core" for SuperH,
-       #       but that's what the test program is *supposed* to do -
-       #       it dumps core before it writes anything, so the test
-       #       for an empty output file should find an empty output
-       #       file and conclude that unaligned accesses don't work).
-       #
-       # This run-time test won't work if you're cross-compiling, so
-       # in order to support cross-compiling for a particular CPU,
-       # we have to wire in the list of CPU types anyway, as far as
-       # I know, so perhaps we should just have a set of CPUs on
-       # which we know it doesn't work, a set of CPUs on which we
-       # know it does work, and have the script just fail on other
-       # cpu types and update it when such a failure occurs.
-       #
-       alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1)
-               ac_cv_lbl_unaligned_fail=yes
-               ;;
-
-       *)
-               cat >conftest.c <<EOF
-#              include <sys/types.h>
-#              include <sys/wait.h>
-#              include <stdio.h>
-               unsigned char a[5] = { 1, 2, 3, 4, 5 };
-               main() {
-               unsigned int i;
-               pid_t pid;
-               int status;
-               /* avoid "core dumped" message */
-               pid = fork();
-               if (pid <  0)
-                       exit(2);
-               if (pid > 0) {
-                       /* parent */
-                       pid = waitpid(pid, &status, 0);
-                       if (pid < 0)
-                               exit(3);
-                       exit(!WIFEXITED(status));
-               }
-               /* child */
-               i = *(unsigned int *)&a[1];
-               printf("%d\n", i);
-               exit(0);
-               }
-EOF
-               ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
-                   conftest.c $LIBS >/dev/null 2>&1
-               if test ! -x conftest ; then
-                                               ac_cv_lbl_unaligned_fail=yes
-               else
-                       ./conftest >conftest.out
-                       if test ! -s conftest.out ; then
-                               ac_cv_lbl_unaligned_fail=yes
-                       else
-                               ac_cv_lbl_unaligned_fail=no
-                       fi
-               fi
-               rm -f -r conftest* core core.conftest
-               ;;
-       esac
-fi
-
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_unaligned_fail" >&5
-$as_echo "$ac_cv_lbl_unaligned_fail" >&6; }
-    if test $ac_cv_lbl_unaligned_fail = yes ; then
-
-$as_echo "#define LBL_ALIGN 1" >>confdefs.h
-
-    fi
-
 # Check for OpenSSL/libressl libcrypto
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use OpenSSL/libressl libcrypto" >&5
 $as_echo_n "checking whether to use OpenSSL/libressl libcrypto... " >&6; }
index 654d973aa2d26c5ff854fbfaae2e80232287f2c4..ef0e8f4fe2aac23bce95c7fbf836f8bb2c08d88a 100644 (file)
@@ -815,8 +815,6 @@ AC_CHECK_TOOL([AR], [ar])
 
 AC_LBL_DEVEL(V_CCOPT)
 
-AC_LBL_UNALIGNED_ACCESS
-
 # Check for OpenSSL/libressl libcrypto
 AC_MSG_CHECKING(whether to use OpenSSL/libressl libcrypto)
 # Specify location for both includes and libraries.
index 5969c22574b5a83cd9718c13ba7861da8d11e38d..3f880fefda812fd9d71e491a863983088741e073 100644 (file)
--- a/extract.h
+++ b/extract.h
 #define UNALIGNED_OK
 #endif
 
-#ifdef LBL_ALIGN
+#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \
+    (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__)) || \
+    (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \
+    (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \
+    (defined(__s390__) || defined(__s390x__) || defined(__zarch__))
 /*
- * The processor doesn't natively handle unaligned loads.
+ * The processor natively handles unaligned loads, so we can just
+ * cast the pointer and fetch through it.
+ *
+ * XXX - are those all the x86 tests we need?
+ * XXX - do we need to worry about ARMv1 through ARMv5, which didn't
+ * support unaligned loads, and, if so, do we need to worry about all
+ * of them, or just some of them, e.g. ARMv5?
+ * XXX - are those the only 68k tests we need not to generated
+ * unaligned accesses if the target is the 68000 or 68010?
+ * XXX - are there any tests we don't need, because some definitions are for
+ * compilers that also predefine the GCC symbols?
+ * XXX - do we need to test for both 32-bit and 64-bit versions of those
+ * architectures in all cases?
  */
-#if defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
+static inline uint16_t UNALIGNED_OK
+EXTRACT_16BITS(const void *p)
+{
+       return ((uint16_t)ntohs(*(const uint16_t *)(p)));
+}
+
+static inline uint32_t UNALIGNED_OK
+EXTRACT_32BITS(const void *p)
+{
+       return ((uint32_t)ntohl(*(const uint32_t *)(p)));
+}
+
+static inline uint64_t UNALIGNED_OK
+EXTRACT_64BITS(const void *p)
+{
+       return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
+               ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
+
+}
+#elif defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
     (defined(__alpha) || defined(__alpha__) || \
      defined(__mips) || defined(__mips__))
-
 /*
-* This is a GCC-compatible compiler and we have __attribute__, which
- * we assume that mean we have __attribute__((packed)), and this is
- * MIPS or Alpha, which has instructions that can help when doing
- * unaligned loads.
+ * This is MIPS or Alpha, which don't natively handle unaligned loads,
+ * but which have instructions that can help when doing unaligned
+ * loads, and this is a GCC-compatible compiler and we have __attribute__,
+ * which we assume that mean we have __attribute__((packed)), which
+ * we can use to convince the compiler to generate those instructions.
  *
  * Declare packed structures containing a uint16_t and a uint32_t,
  * cast the pointer to point to one of those, and fetch through it;
@@ -146,10 +181,10 @@ EXTRACT_64BITS(const void *p)
        return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 |
                ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0));
 }
-
-#else /* have to do it a byte at a time */
+#else
 /*
- * This isn't a GCC-compatible compiler, we don't have __attribute__,
+ * This architecture doesn't natively support unaligned loads, and either
+ * this isn't a GCC-compatible compiler, we don't have __attribute__,
  * or we do but we don't know of any better way with this instruction
  * set to do unaligned loads, so do unaligned loads of big-endian
  * quantities the hard way - fetch the bytes one at a time and
@@ -172,33 +207,7 @@ EXTRACT_64BITS(const void *p)
                    ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \
                    ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \
                    ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0)))
-#endif /* must special-case unaligned accesses */
-#else /* LBL_ALIGN */
-/*
- * The processor natively handles unaligned loads, so we can just
- * cast the pointer and fetch through it.
- */
-static inline uint16_t UNALIGNED_OK
-EXTRACT_16BITS(const void *p)
-{
-       return ((uint16_t)ntohs(*(const uint16_t *)(p)));
-}
-
-static inline uint32_t UNALIGNED_OK
-EXTRACT_32BITS(const void *p)
-{
-       return ((uint32_t)ntohl(*(const uint32_t *)(p)));
-}
-
-static inline uint64_t UNALIGNED_OK
-EXTRACT_64BITS(const void *p)
-{
-       return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
-               ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
-
-}
-
-#endif /* LBL_ALIGN */
+#endif /* unaligned access checks */
 
 #define EXTRACT_24BITS(p) \
        ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \
index e8d1f3c21e0a4b624891a18df926f888ebd8604b..90bc8050cffc907c7cc20f7ef0cd02436f147f06 100644 (file)
@@ -340,7 +340,30 @@ extern void txtproto_print(netdissect_options *, const u_char *, u_int,
 extern void safeputchar(netdissect_options *, const u_char);
 extern void safeputs(netdissect_options *, const u_char *, const u_int);
 
-#ifdef LBL_ALIGN
+#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \
+    (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__)) || \
+    (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \
+    (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \
+    (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || \
+    defined(__vax__)
+/*
+ * The procesor natively handles unaligned loads, so just use memcpy()
+ * and memcmp(), to enable those optimizations.
+ *
+ * XXX - are those all the x86 tests we need?
+ * XXX - do we need to worry about ARMv1 through ARMv5, which didn't
+ * support unaligned loads, and, if so, do we need to worry about all
+ * of them, or just some of them, e.g. ARMv5?
+ * XXX - are those the only 68k tests we need not to generated
+ * unaligned accesses if the target is the 68000 or 68010?
+ * XXX - are there any tests we don't need, because some definitions are for
+ * compilers that also predefine the GCC symbols?
+ * XXX - do we need to test for both 32-bit and 64-bit versions of those
+ * architectures in all cases?
+ */
+#define UNALIGNED_MEMCPY(p, q, l)      memcpy((p), (q), (l))
+#define UNALIGNED_MEMCMP(p, q, l)      memcmp((p), (q), (l))
+#else
 /*
  * The processor doesn't natively handle unaligned loads,
  * and the compiler might "helpfully" optimize memcpy()
@@ -356,13 +379,6 @@ extern void unaligned_memcpy(void *, const void *, size_t);
 extern int unaligned_memcmp(const void *, const void *, size_t);
 #define UNALIGNED_MEMCPY(p, q, l)      unaligned_memcpy((p), (q), (l))
 #define UNALIGNED_MEMCMP(p, q, l)      unaligned_memcmp((p), (q), (l))
-#else
-/*
- * The procesor natively handles unaligned loads, so just use memcpy()
- * and memcmp(), to enable those optimizations.
- */
-#define UNALIGNED_MEMCPY(p, q, l)      memcpy((p), (q), (l))
-#define UNALIGNED_MEMCMP(p, q, l)      memcmp((p), (q), (l))
 #endif
 
 #define PLURAL_SUFFIX(n) \
index 25ea1386f0b054f27b4fbd4da6cee7976bb34a85..892e07a73c990b296190f59edaf6da067b3459a3 100644 (file)
@@ -946,11 +946,38 @@ safeputchar(netdissect_options *ndo,
        ND_PRINT((ndo, (c < 0x80 && ND_ISPRINT(c)) ? "%c" : "\\0x%02x", c));
 }
 
-#ifdef LBL_ALIGN
+#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \
+    (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__)) || \
+    (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \
+    (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \
+    (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || \
+    defined(__vax__)
 /*
- * Some compilers try to optimize memcpy(), using the alignment constraint
- * on the argument pointer type.  by using this function, we try to avoid the
- * optimization.
+ * The procesor natively handles unaligned loads, so just use memcpy()
+ * and memcmp(), to enable those optimizations.
+ *
+ * XXX - are those all the x86 tests we need?
+ * XXX - do we need to worry about ARMv1 through ARMv5, which didn't
+ * support unaligned loads, and, if so, do we need to worry about all
+ * of them, or just some of them, e.g. ARMv5?
+ * XXX - are those the only 68k tests we need not to generated
+ * unaligned accesses if the target is the 68000 or 68010?
+ * XXX - are there any tests we don't need, because some definitions are for
+ * compilers that also predefine the GCC symbols?
+ * XXX - do we need to test for both 32-bit and 64-bit versions of those
+ * architectures in all cases?
+ */
+#else
+/*
+ * The processor doesn't natively handle unaligned loads,
+ * and the compiler might "helpfully" optimize memcpy()
+ * and memcmp(), when handed pointers that would normally
+ * be properly aligned, into sequences that assume proper
+ * alignment.
+ *
+ * Do copies and compares of possibly-unaligned data by
+ * calling routines that wrap memcpy() and memcmp(), to
+ * prevent that optimization.
  */
 void
 unaligned_memcpy(void *p, const void *q, size_t l)