Some recent changes in dwarf2out.c have caused GCC to generate unaligned data traps on IA64 Linux. In looking a this I tracked it down to md5_read_ctx in libiberty, which is called by md5_finish_ctx, which in turn is called by various routines in dwarf2out.c.
md5_read_ctx has a comment that the buffer must be 32 bit aligned but there is nothing in dwarf2out.c to enforce this alignment to the checksum buffer passed in to md5_finish_ctx. I looked at calls to md5_finish_ctx in fold-const.c to see why these didn't seem to have a problem and noticed that the buffers used were always declared after the md5_ctx structure and I think that 'accidentaly' got everything aligned correctly. If I do the same thing on the three buffer declarations in dwarf2out.c the misaligned messages go away and things work fine. Obviously this isn't a perfect fix, it is relying on how GCC is laying out local variables which isn't gauranteed, but it fixes the problem and I thought I would see if I could get approval for this simple fix or if people think we need a more complete fix. If we need a better fix, what should I do? It doesn't look like we use the alignment attribute in the GCC code anywhere. I could change the type of the checksum buffer from an array of unsigned char to something that has a stronger alignment requirement, but that would probably require a number of casts be added where the checksum variable is used. So, can I get someone to approve this simple, if imperfect, patch? Tested on IA64 Linux. Steve Ellcey s...@cup.hp.com 2011-08-05 Steve Ellcey <s...@cup.hp.com> * dwarf2out.c (generate_type_signature): Change decl order to force alignment. (compute_section_prefix): (optimize_macinfo_range): Ditto. Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 177422) +++ dwarf2out.c (working copy) @@ -6369,8 +6369,8 @@ generate_type_signature (dw_die_ref die, { int mark; const char *name; - unsigned char checksum[16]; struct md5_ctx ctx; + unsigned char checksum[16]; dw_die_ref decl; name = get_AT_string (die, DW_AT_name); @@ -6602,8 +6602,8 @@ compute_section_prefix (dw_die_ref unit_ char *name = XALLOCAVEC (char, strlen (base) + 64); char *p; int i, mark; - unsigned char checksum[16]; struct md5_ctx ctx; + unsigned char checksum[16]; /* Compute the checksum of the DIE, then append part of it as hex digits to the name filename of the unit. */ @@ -20662,8 +20662,8 @@ optimize_macinfo_range (unsigned int idx { macinfo_entry *first, *second, *cur, *inc; char linebuf[sizeof (HOST_WIDE_INT) * 3 + 1]; - unsigned char checksum[16]; struct md5_ctx ctx; + unsigned char checksum[16]; char *grp_name, *tail; const char *base; unsigned int i, count, encoded_filename_len, linebuf_len;