From a9e8d2f03a29f81ecb490980d64431f25296085d Mon Sep 17 00:00:00 2001 From: "josh.macdonald" Date: Mon, 24 Sep 2012 04:10:10 +0000 Subject: Fix UNALIGNED_OK logic, add autoconf rule to detect for non-Windows builds and default to UNALIGNED_OK=1 --- xdelta3/config.h.in | 3 + xdelta3/configure.ac | 1 + xdelta3/m4/ax_check_aligned_access_required.m4 | 84 ++++++++++++++++++++++++++ xdelta3/xdelta3-hash.h | 33 +++------- xdelta3/xdelta3.h | 9 ++- 5 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 xdelta3/m4/ax_check_aligned_access_required.m4 diff --git a/xdelta3/config.h.in b/xdelta3/config.h.in index 220915d..f01f64a 100644 --- a/xdelta3/config.h.in +++ b/xdelta3/config.h.in @@ -1,5 +1,8 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* Define if pointers to integers require aligned access */ +#undef HAVE_ALIGNED_ACCESS_REQUIRED + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H diff --git a/xdelta3/configure.ac b/xdelta3/configure.ac index 869f3c2..394e2ae 100644 --- a/xdelta3/configure.ac +++ b/xdelta3/configure.ac @@ -5,6 +5,7 @@ AC_CONFIG_MACRO_DIR([m4]) #LT_INIT AM_INIT_AUTOMAKE([1.9 no-define foreign tar-ustar]) #AC_DISABLE_STATIC +AX_CHECK_ALIGNED_ACCESS_REQUIRED AC_PROG_CC AC_PROG_CXX AC_CHECK_HEADERS([lzma.h]) diff --git a/xdelta3/m4/ax_check_aligned_access_required.m4 b/xdelta3/m4/ax_check_aligned_access_required.m4 new file mode 100644 index 0000000..b078275 --- /dev/null +++ b/xdelta3/m4/ax_check_aligned_access_required.m4 @@ -0,0 +1,84 @@ +# ==================================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_aligned_access_required.html +# ==================================================================================== +# +# SYNOPSIS +# +# AC_CHECK_ALIGNED_ACCESS_REQUIRED +# +# DESCRIPTION +# +# While the x86 CPUs allow access to memory objects to be unaligned it +# happens that most of the modern designs require objects to be aligned - +# or they will fail with a buserror. That mode is quite known by +# big-endian machines (sparc, etc) however the alpha cpu is little- +# endian. +# +# The following function will test for aligned access to be required and +# set a config.h define HAVE_ALIGNED_ACCESS_REQUIRED (name derived by +# standard usage). Structures loaded from a file (or mmapped to memory) +# should be accessed per-byte in that case to avoid segfault type errors. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program 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 General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 7 + +AC_DEFUN([AX_CHECK_ALIGNED_ACCESS_REQUIRED], +[AC_CACHE_CHECK([if pointers to integers require aligned access], + [ax_cv_have_aligned_access_required], + [AC_TRY_RUN([ +#include +#include + +int main() +{ + char* string = malloc(40); + int i; + for (i=0; i < 40; i++) string[[i]] = i; + { + void* s = string; + int* p = s+1; + int* q = s+2; + + if (*p == *q) { return 1; } + } + return 0; +} + ], + [ax_cv_have_aligned_access_required=yes], + [ax_cv_have_aligned_access_required=no], + [ax_cv_have_aligned_access_required=no]) + ]) +if test "$ax_cv_have_aligned_access_required" = yes ; then + AC_DEFINE([HAVE_ALIGNED_ACCESS_REQUIRED], [1], + [Define if pointers to integers require aligned access]) +fi +]) diff --git a/xdelta3/xdelta3-hash.h b/xdelta3/xdelta3-hash.h index e546d59..08d8136 100644 --- a/xdelta3/xdelta3-hash.h +++ b/xdelta3/xdelta3-hash.h @@ -65,46 +65,29 @@ xd3_large_cksum_update (uint32_t cksum, /* TODO: revisit this topic */ #endif -/* Note: small cksum is hard-coded for 4 bytes */ #if UNALIGNED_OK -static inline uint32_t -xd3_scksum (uint32_t *state, - const uint8_t *base, - const usize_t look) -{ - (*state) = *(uint32_t*)base; - return (*state) * hash_multiplier; -} -static inline uint32_t -xd3_small_cksum_update (uint32_t *state, - const uint8_t *base, - usize_t look) -{ - (*state) = *(uint32_t*)(base+1); - return (*state) * hash_multiplier; -} +#define UNALIGNED_READ32(dest,src) (*(dest)) = (*(uint32_t*)(src)) #else +#define UNALIGNED_READ32(dest,src) memcpy((dest), (src), 4); +#endif + +/* TODO: small cksum is hard-coded for 4 bytes (i.e., "look" is unused) */ static inline uint32_t xd3_scksum (uint32_t *state, const uint8_t *base, const usize_t look) { - (*state) = (base[0] << 24 | - base[1] << 16 | - base[2] << 8 | - base[3]); + UNALIGNED_READ32(state, base); return (*state) * hash_multiplier; } static inline uint32_t xd3_small_cksum_update (uint32_t *state, const uint8_t *base, - const usize_t look) + usize_t look) { - (*state) <<= 8; - (*state) |= base[4]; + UNALIGNED_READ32(state, base+1); return (*state) * hash_multiplier; } -#endif /*********************************************************************** Ctable stuff diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index 6256961..0710f08 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h @@ -171,13 +171,12 @@ typedef uint32_t xoff_t; #define USE_UINT64 (SIZEOF_USIZE_T == 8 || \ SIZEOF_XOFF_T == 8 || REGRESSION_TEST) -/* TODO: probably should do something better here. */ #ifndef UNALIGNED_OK -#if defined(__i386__) || defined(__i486__) || defined(__i586__) || \ - defined(__i686__) || defined(_X86_) || defined(__x86_64__) -#define UNALIGNED_OK 1 -#else +#ifdef HAVE_ALIGNED_ACCESS_REQUIRED #define UNALIGNED_OK 0 +#else +/* This generally includes all Windows builds. */ +#define UNALIGNED_OK 1 #endif #endif -- cgit v1.2.3