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
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)
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. */