This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: ld 2.11: unaligned memory access for unions
- To: Eberhard Mattes <mattes at azu dot informatik dot uni-stuttgart dot de>
- Subject: Re: ld 2.11: unaligned memory access for unions
- From: Nick Clifton <nickc at cambridge dot redhat dot com>
- Date: 18 Jun 2001 17:36:32 +0100
- Cc: binutils at sources dot redhat dot com
- References: <200106151053.MAA07723@azu.informatik.uni-stuttgart.de>
Hi Eberhard,
Ah OK I understand now. The code is deliberately casting a void *
pointer into a structure pointer, something which strictly speaking it
should not do, since GCC then (reasonably) assumes that the pointer is
aligned as required for the structure type.
> The correct solution is to use a struct for each variant instead of a
> a union of all variants.
True, but that would be a lot more work. I think that the easier
solution would be to use your xmemcpy suggestion, although instead of
using a #define alias, an explicit reference would be better.
Can you try this potentional patch for me and let me know it solves
the problem ?
Cheers
Nick
Index: bfd/peXXigen.c
===================================================================
RCS file: /cvs/src/src/bfd/peXXigen.c,v
retrieving revision 1.2
diff -p -r1.2 peXXigen.c
*** peXXigen.c 2001/03/08 21:04:01 1.2
--- peXXigen.c 2001/06/18 16:34:56
*************** static void add_data_entry
*** 95,101 ****
--- 95,118 ----
PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma));
static boolean pe_print_pdata PARAMS ((bfd *, PTR));
static boolean pe_print_reloc PARAMS ((bfd *, PTR));
+ static void unaligned_memcpy PARAMS ((char *, char *, unsigned));
+ /* This function replaces direct calls to memcpy, and prevents
+ the compiler from assuming that it knows the alignment of the
+ pointers involved. This is needed because we are casting the
+ incoming pointers into pointers to the global internal_syment
+ structure. These casts inherit the (larger) alignment of that
+ structure, but this cannot be guarnteed, since the incoming
+ pointers had smaller alignment requirements. */
+ static void
+ unaligned_memcpy (dest, source, length)
+ char * dest;
+ char * source;
+ unsigned length;
+ {
+ memcpy (dest, source, length);
+ }
+
/**********************************************************************/
void
*************** _bfd_XXi_swap_sym_in (abfd, ext1, in1)
*** 115,121 ****
}
else
{
! memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
}
in->n_value = bfd_h_get_32 (abfd, (bfd_byte *) ext->e_value);
--- 132,138 ----
}
else
{
! unaligned_memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
}
in->n_value = bfd_h_get_32 (abfd, (bfd_byte *) ext->e_value);
*************** _bfd_XXi_swap_sym_out (abfd, inp, extp)
*** 236,242 ****
}
else
{
! memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
}
bfd_h_put_32 (abfd, in->n_value, (bfd_byte *) ext->e_value);
--- 253,259 ----
}
else
{
! unaligned_memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
}
bfd_h_put_32 (abfd, in->n_value, (bfd_byte *) ext->e_value);
*************** _bfd_XXi_swap_aux_in (abfd, ext1, type,
*** 279,285 ****
}
else
{
! memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
}
return;
--- 296,302 ----
}
else
{
! unaligned_memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
}
return;
*************** _bfd_XXi_swap_aux_out (abfd, inp, type,
*** 360,366 ****
}
else
{
! memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
}
return AUXESZ;
--- 377,383 ----
}
else
{
! unaligned_memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
}
return AUXESZ;
*************** _bfd_XXi_swap_scnhdr_out (abfd, in, out)
*** 926,932 ****
bfd_vma ps;
bfd_vma ss;
! memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
PUT_SCNHDR_VADDR (abfd,
((scnhdr_int->s_vaddr
--- 943,950 ----
bfd_vma ps;
bfd_vma ss;
! unaligned_memcpy (scnhdr_ext->s_name, scnhdr_int->s_name,
! sizeof (scnhdr_int->s_name));
PUT_SCNHDR_VADDR (abfd,
((scnhdr_int->s_vaddr