This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: ld 2.11: unaligned memory access for unions


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]