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