Patch for PR other/13906 (md5.c does unaligned memory accesses)
Steve Ellcey
sje@cup.hp.com
Fri Jul 1 18:01:00 GMT 2005
PR 13906 is a report that a user cannot bootstrap on HPPA with a full
array of --enable-checking options because the resulting compiler aborts
in md5_process_block.
I looked at md5.h and md5.c in glibc version 2.3.3 and picked up the
following changes to fix the problem. I did a build on HPPA with
--enable-checking="misc,tree,rtl,rtlflag,gc,gcac,fold" to verify that
this fixes the reported problem and did a full regression test (without
--enable-checking specified) on IA64 HP-UX and Linux.
The odd looking _STRING_ARCH_unaligned macro in md5.c is straight from
glibc.
OK for checkin?
Steve Ellcey
sje@cup.hp.com
include/ChangeLog
2005-07-01 Steve Ellcey <sje@cup.hp.com>
PR other/13906
* ansidecl.h (ATTRIBUTE_ALIGNED_ALIGNOF): New.
* md5.h (md5_uintptr): New.
(md5_ctx): Align buffer field.
libiberty/ChangeLog
2005-07-01 Steve Ellcey <sje@cup.hp.com>
PR other/13906
* md5.c (md5_process_bytes): Check alignment.
*** gcc.orig/gcc/include/ansidecl.h Fri Jul 1 10:42:24 2005
--- gcc/gcc/include/ansidecl.h Fri Jul 1 10:41:21 2005
*************** So instead we use the macro below and te
*** 352,357 ****
--- 352,366 ----
# endif /* GNUC >= 3.5 */
#endif /* ATTRIBUTE_SENTINEL */
+
+ #ifndef ATTRIBUTE_ALIGNED_ALIGNOF
+ # if (GCC_VERSION >= 3000)
+ # define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
+ # else
+ # define ATTRIBUTE_ALIGNED_ALIGNOF(m)
+ # endif /* GNUC >= 3.3 */
+ #endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
+
/* We use __extension__ in some places to suppress -pedantic warnings
about GCC extensions. This feature didn't work properly before
gcc 2.8. */
*** gcc.orig/gcc/include/md5.h Fri Jul 1 10:42:15 2005
--- gcc/gcc/include/md5.h Fri Jul 1 10:41:28 2005
***************
*** 37,42 ****
--- 37,43 ----
#ifdef _LIBC
# include <sys/types.h>
typedef u_int32_t md5_uint32;
+ typedef uintptr_t md5_uintptr;
#else
# define INT_MAX_32_BITS 2147483647
*************** typedef u_int32_t md5_uint32;
*** 64,69 ****
--- 65,73 ----
# endif
# endif
# endif
+ /* We have to make a guess about the integer type equivalent in size
+ to pointers which should always be correct. */
+ typedef unsigned long int md5_uintptr;
#endif
/* Structure to save state of computation between the single steps. */
*************** struct md5_ctx
*** 76,82 ****
md5_uint32 total[2];
md5_uint32 buflen;
! char buffer[128];
};
/*
--- 80,86 ----
md5_uint32 total[2];
md5_uint32 buflen;
! char buffer[128] ATTRIBUTE_ALIGNED_ALIGNOF(md5_uint32);
};
/*
*** gcc.orig/gcc/libiberty/md5.c Fri Jul 1 10:42:00 2005
--- gcc/gcc/libiberty/md5.c Fri Jul 1 10:41:41 2005
*************** md5_process_bytes (const void *buffer, s
*** 223,228 ****
--- 223,245 ----
/* Process available complete blocks. */
if (len > 64)
{
+ #if !_STRING_ARCH_unaligned
+ /* To check alignment gcc has an appropriate operator. Other
+ compilers don't. */
+ # if __GNUC__ >= 2
+ # define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
+ # else
+ # define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
+ # endif
+ if (UNALIGNED_P (buffer))
+ while (len > 64)
+ {
+ md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+ buffer = (const char *) buffer + 64;
+ len -= 64;
+ }
+ else
+ #endif
md5_process_block (buffer, len & ~63, ctx);
buffer = (const void *) ((const char *) buffer + (len & ~63));
len &= 63;
More information about the Gcc-patches
mailing list