diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-05-02 16:24:22 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-05-02 16:24:22 +0000 |
commit | 67b7c93971748e23254c2768545c15631fc111b9 (patch) | |
tree | c27a89b14a09d01bead559753ae2fad04296e032 | |
parent | 62f18c5e354db1cd2584a6267ddbd9ac8bff80e4 (diff) | |
download | netpbm-mirror-67b7c93971748e23254c2768545c15631fc111b9.tar.gz netpbm-mirror-67b7c93971748e23254c2768545c15631fc111b9.tar.xz netpbm-mirror-67b7c93971748e23254c2768545c15631fc111b9.zip |
Fix unaligned memory access on Sparc
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1892 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r-- | common.mk | 3 | ||||
-rw-r--r-- | doc/HISTORY | 3 | ||||
-rw-r--r-- | lib/util/wordaccess.h | 51 | ||||
-rw-r--r-- | lib/util/wordaccess_be_aligned.h | 35 | ||||
-rw-r--r-- | lib/util/wordaccess_be_unaligned.h (renamed from lib/util/wordaccess_gcc3_be.h) | 7 | ||||
-rw-r--r-- | lib/util/wordaccess_generic.h | 6 | ||||
-rw-r--r-- | pm_config.in.h | 10 |
7 files changed, 80 insertions, 35 deletions
diff --git a/common.mk b/common.mk index b445ea19..4077f2ea 100644 --- a/common.mk +++ b/common.mk @@ -144,7 +144,8 @@ IMPORTINC_LIB_UTIL_HEADERS := \ bitarith.h bitreverse.h filename.h intcode.h floatcode.h io.h \ matrix.h mallocvar.h \ nsleep.h nstring.h pm_c_util.h shhopt.h token.h \ - wordaccess.h wordaccess_64_le.h wordaccess_gcc3_be.h wordaccess_generic.h \ + wordaccess.h wordaccess_generic.h wordaccess_64_le.h \ + wordaccess_be_aligned.h wordaccess_be_unaligned.h \ wordintclz.h IMPORTINC_HEADERS := \ diff --git a/doc/HISTORY b/doc/HISTORY index 578a2bd0..721da7ed 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -19,6 +19,9 @@ not yet BJH Release 10.63.00 middle of the AND mask. Always broken (program was new in Netpbm 9.3 (June 2000)). + sparc64 pbmtog3: fix bug that causes crash due to unaligned + memory access. + install: fix Perl warning in installnetpbm. Broken in 10.61. build: fix problem with creating lib/util that already exists. diff --git a/lib/util/wordaccess.h b/lib/util/wordaccess.h index 2eaa2b24..09a896c4 100644 --- a/lib/util/wordaccess.h +++ b/lib/util/wordaccess.h @@ -44,33 +44,32 @@ #include "pm_config.h" -#if (!defined(WORDACCESS_GENERIC) && HAVE_GCC_BITCOUNT ) - - #if BYTE_ORDER == BIG_ENDIAN /* See pm_config.h */ - /* Sun Sparc 64, etc */ - #include "wordaccess_gcc3_be.h" - - #elif (BITS_PER_LONG == 64) - /* AMD Athlon 64, Intel x86_64, Intel Itanium, etc. */ - #include "wordaccess_64_le.h" - - #elif (BITS_PER_LONG == 32) - /* Intel x86_32 (80386, 80486, Pentium), etc. */ - #include "wordaccess_generic.h" - - #else - /* Extremely rare case. - If long is neither 32 nor 64 bits, (say, 128) it comes here. - */ - #define WORDACCESS_GENERIC - #include "wordaccess_generic.h" - - #endif - +#if defined(WORDACCESS_GENERIC) + /* User wants this, regardless of whether machine can do better */ + #include "wordaccess_generic.h" +#elif BYTE_ORDER == BIG_ENDIAN + #if UNALIGNED_OK + #include wordaccess_be_unaligned.h + #else + /* Sparc */ + #include wordaccess_be_aligned.h + #endif +#elif HAVE_GCC_BITCOUNT + #if (BITS_PER_LONG == 64) + /* AMD Athlon 64, Intel x86_64, Intel Itanium, etc. */ + #include "wordaccess_64_le.h" + #elif (BITS_PER_LONG == 32) + /* Intel x86_32 (80386, 80486, Pentium), etc. */ + #include "wordaccess_generic.h" + #else + /* Extremely rare case. + If long is neither 32 nor 64 bits, (say, 128) it comes here. + */ + #include "wordaccess_generic.h" + #endif #else - /* Non GCC, GCC prior to v.3.4 or WORDACCESS_GENERIC defined */ - #include "wordaccess_generic.h" - + /* Non GCC or GCC prior to v.3.4; little-endian */ + #include "wordaccess_generic.h" #endif #endif diff --git a/lib/util/wordaccess_be_aligned.h b/lib/util/wordaccess_be_aligned.h new file mode 100644 index 00000000..0d5809e6 --- /dev/null +++ b/lib/util/wordaccess_be_aligned.h @@ -0,0 +1,35 @@ +/*============================================================================= + This file is the part of wordaccess.h for use under with big-endian + machines that require word accesses to be word-aligned. +*===========================================================================*/ + +typedef unsigned long int wordint; +typedef unsigned char wordintBytes[sizeof(wordint)]; + +static __inline__ wordint +bytesToWordint(wordintBytes bytes) { + uint16_t const hi = *((uint16_t *) (bytes + 0)); + uint16_t const mh = *((uint16_t *) (bytes + 2)); + uint16_t const ml = *((uint16_t *) (bytes + 4)); + uint16_t const lo = *((uint16_t *) (bytes + 6)); + return + (((wordint) hi) << 48) | + (((wordint) mh) << 32) | + (((wordint) ml) << 24) | + (((wordint) lo) << 0); +} + + + +static __inline__ void +wordintToBytes(wordintBytes * const bytesP, + wordint const wordInt) { + uint16_t const hi = ((wordInt >> 48) & 0xFF) + uint16_t const mh = ((wordInt >> 32) & 0xFF); + uint16_t const ml = ((wordInt >> 24) & 0xFF); + uint16_t const lo = ((wordInt >> 0) & 0xFF); + *(uint16_t *)(bytesP + 0) = hi; + *(uint16_t *)(bytesP + 2) = mh; + *(uint16_t *)(bytesP + 4) = ml; + *(uint16_t *)(bytesP + 6) = lo; +} diff --git a/lib/util/wordaccess_gcc3_be.h b/lib/util/wordaccess_be_unaligned.h index 5aa63521..95b68ac7 100644 --- a/lib/util/wordaccess_gcc3_be.h +++ b/lib/util/wordaccess_be_unaligned.h @@ -1,9 +1,6 @@ /*============================================================================= - This file is the part of wordaccess.h for use under these - conditions: - - * GCC (>=3.4), GLIBC - * Big-Endian machines + This file is the part of wordaccess.h for use on a big-endian machine + that does not require word accesses to be word-aligned. *===========================================================================*/ typedef unsigned long int wordint; diff --git a/lib/util/wordaccess_generic.h b/lib/util/wordaccess_generic.h index 94cc8124..6e0a20ef 100644 --- a/lib/util/wordaccess_generic.h +++ b/lib/util/wordaccess_generic.h @@ -1,11 +1,11 @@ /*============================================================================= - This file is the part of wordaccess.h for use under these + This file is the part of wordaccess.h for use under any of these conditions: - * Compilers other than GCC + * Compiler other than GCC * GCC before version 3.4 - * Specified by the user with WORDACCESS_GENERIC + * Requested by the user with WORDACCESS_GENERIC =============================================================================*/ #include "intcode.h" diff --git a/pm_config.in.h b/pm_config.in.h index 3e2f781c..d8e578a3 100644 --- a/pm_config.in.h +++ b/pm_config.in.h @@ -290,6 +290,16 @@ #endif #endif +/* UNALIGNED_OK means it's OK to do unaligned memory access, e.g. + loading an 8-byte word from an address that is not a multiple of 8. + On some systems, such an access causes a trap and a signal. +*/ + +#if defined(__sparc__) +# define UNALIGNED_OK 0 +#else +# define UNALIGNED_OK 1 +#endif /* CONFIGURE: Some systems seem to need more than standard program linkage |