Fwd: [libiberty] problem with unaligned pointers when using md5_process_bytes

piervit@pvittet.com piervit@pvittet.com
Thu Sep 15 12:03:00 GMT 2011


Hello,

I request your help on the following problem:
Recently, I used the libiberty md5_process_bytes function (for some 
MELT code) and got a problem with it:

I don't know why but on some systems (debian i686) I got some 
unaligned pointers (only when using MELT, I could not reproduce 
elsewhere, so that might come from me or from MELT). Normally, even 
with unaligned pointers, this should works as the function 
md5_process_bytes handles this case:

#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
	len --;
     if (UNALIGNED_P (buffer))
       while (len > 64)
         {
			memcpy (ctx->buffer, buffer, 64);
           md5_process_block (ctx->buffer, 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;
   }

However the handling looks quite strange to me, if UNALIGNED_P 
(buffer) (as this is the case for me) is true, we normally travel the 
while, but then, we execute a new time the line "buffer = (const void 
*) ((const char *) buffer + (len & ~63));", which appear to shift the 
buffer a new time (for more detail, you can have a look at my given gdb 
trace).

I was able to fully compile GCC MELT branch by only adding a pair of 
braces as you can see on the given diff file. I guess this is a bug in 
libiberty (even if I can't understand why my pointer is not aligned).

So can you confirm (or no) that there is a bug in this function (I can 
post to gcc-patches if you think it is a bug), and give me informations 
about how to explain the fact that I get unaligned pointers.

Thanks a lot for your help!

Pierre Vittet
-------------- next part --------------
dpierre@Octave gcc %gdb --args ./cc1 @warmelt-firstmelt-stage1.args                                                                                                                                                                     [0]
GNU gdb (GDB) 7.2-debian
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dpierre/programmation/melt/gcc_melt_build/gcc/cc1...done.
Breakpoint 1 at 0x8df215d: file /home/dpierre/programmation/melt/gcc_melt_source/gcc/diagnostic.c, line 893.
Breakpoint 2 at 0x8df206b: file /home/dpierre/programmation/melt/gcc_melt_source/gcc/diagnostic.c, line 837.
Breakpoint 3 at 0x80cc9f0
Breakpoint 4 at 0x80cce20
(gdb) break md5_process_bytes 
Breakpoint 5 at 0x8e3461c: file /home/dpierre/programmation/melt/gcc_melt_source/libiberty/md5.c, line 206.
(gdb) run
Breakpoint 5, md5_process_bytes (buffer=0xbfffe3f6, len=1024, ctx=0xbfffe358) at /home/dpierre/programmation/melt/gcc_melt_source/libiberty/md5.c:206
206	  if (ctx->buflen != 0)
(gdb) n
228	  if (len > 64)
(gdb) n
238	      if (UNALIGNED_P (buffer))
(gdb) l
233	# if __GNUC__ >= 2
234	#  define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
235	# else
236	#  define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
237	# endif
238	      if (UNALIGNED_P (buffer))
239	        while (len > 64)
240	          {
241		    memcpy (ctx->buffer, buffer, 64);
242	            md5_process_block (ctx->buffer, 64, ctx);
(gdb) n
239	        while (len > 64)
(gdb) l
234	#  define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
235	# else
236	#  define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
237	# endif
238	      if (UNALIGNED_P (buffer))
239	        while (len > 64)
240	          {
241		    memcpy (ctx->buffer, buffer, 64);
242	            md5_process_block (ctx->buffer, 64, ctx);
243	            buffer = (const char *) buffer + 64;
(gdb) 
244	            len -= 64;
245	          }
246	      else
247	#endif
248	      md5_process_block (buffer, len & ~63, ctx);
249	      buffer = (const void *) ((const char *) buffer + (len & ~63));
250	      len &= 63;
251	    }
252	
253	  /* Move remaining bytes in internal buffer.  */
(gdb) break 248
Breakpoint 6 at 0x8e347b6: file /home/dpierre/programmation/melt/gcc_melt_source/libiberty/md5.c, line 248.
(gdb) break 249
Breakpoint 7 at 0x8e347d4: file /home/dpierre/programmation/melt/gcc_melt_source/libiberty/md5.c, line 249.
(gdb) c
Continuing.

Breakpoint 7, md5_process_bytes (buffer=0xbfffe7b6, len=64, ctx=0xbfffe358) at /home/dpierre/programmation/melt/gcc_melt_source/libiberty/md5.c:249
249	      buffer = (const void *) ((const char *) buffer + (len & ~63));
(gdb) c
Continuing.

Breakpoint 7, md5_process_bytes (buffer=0xbfffe7b6, len=64, ctx=0xbfffe358) at /home/dpierre/programmation/melt/gcc_melt_source/libiberty/md5.c:249
249	      buffer = (const void *) ((const char *) buffer + (len & ~63));
(gdb) print (len & ~63)
$1 = 64
(gdb) print buffer
$2 = (const void *) 0xbfffe7b6
(gdb) print (char *) buffer
$3 = 0xbfffe7b6 "r FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Pub"
(gdb) n
250	      len &= 63;
(gdb) print (char *) buffer
$4 = 0xbfffe7f6 ""
(gdb) print len
$5 = 64
#We see that buffer has been shift while we don't want this (it is empty while len != 0)
-------------- next part --------------
Index: libiberty/md5.c
===================================================================
--- libiberty/md5.c	(révision 178851)
+++ libiberty/md5.c	(copie de travail)
@@ -245,9 +245,11 @@ md5_process_bytes (const void *buffer, size_t len,
           }
       else
 #endif
+      {
       md5_process_block (buffer, len & ~63, ctx);
       buffer = (const void *) ((const char *) buffer + (len & ~63));
       len &= 63;
+      }
     }
 
   /* Move remaining bytes in internal buffer.  */


More information about the Gcc-help mailing list