PR26069, strip/objcopy misaligned address accesses

PR 26069
	PR 18758
	* peicode.h (pe_ILF_make_a_section): Align data for compilers
	other than gcc.
	(pe_ILF_build_a_bfd): Likewise.
This commit is contained in:
Alan Modra 2020-06-03 16:58:55 +09:30
parent 4a32244804
commit 675800364b
2 changed files with 29 additions and 27 deletions

View file

@ -1,3 +1,11 @@
2020-06-03 Alan Modra <amodra@gmail.com>
PR 26069
PR 18758
* peicode.h (pe_ILF_make_a_section): Align data for compilers
other than gcc.
(pe_ILF_build_a_bfd): Likewise.
2020-06-03 Alan Modra <amodra@gmail.com> 2020-06-03 Alan Modra <amodra@gmail.com>
PR 26029 PR 26029

View file

@ -622,6 +622,7 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
{ {
asection_ptr sec; asection_ptr sec;
flagword flags; flagword flags;
intptr_t alignment;
sec = bfd_make_section_old_way (vars->abfd, name); sec = bfd_make_section_old_way (vars->abfd, name);
if (sec == NULL) if (sec == NULL)
@ -652,20 +653,18 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
if (size & 1) if (size & 1)
vars->data --; vars->data --;
# if (GCC_VERSION >= 3000)
/* PR 18758: See note in pe_ILF_buid_a_bfd. We must make sure that we /* PR 18758: See note in pe_ILF_buid_a_bfd. We must make sure that we
preserve host alignment requirements. We test 'size' rather than preserve host alignment requirements. The BFD_ASSERTs in this
vars.data as we cannot perform binary arithmetic on pointers. We assume functions will warn us if we run out of room, but we should
that vars.data was sufficiently aligned upon entry to this function. already have enough padding built in to ILF_DATA_SIZE. */
The BFD_ASSERTs in this functions will warn us if we run out of room, #if GCC_VERSION >= 3000
but we should already have enough padding built in to ILF_DATA_SIZE. */ alignment = __alignof__ (struct coff_section_tdata);
{ #else
unsigned int alignment = __alignof__ (struct coff_section_tdata); alignment = 8;
if (size & (alignment - 1))
vars->data += alignment - (size & (alignment - 1));
}
#endif #endif
vars->data
= (bfd_byte *) (((intptr_t) vars->data + alignment - 1) & -alignment);
/* Create a coff_section_tdata structure for our use. */ /* Create a coff_section_tdata structure for our use. */
sec->used_by_bfd = (struct coff_section_tdata *) vars->data; sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
vars->data += sizeof (struct coff_section_tdata); vars->data += sizeof (struct coff_section_tdata);
@ -779,6 +778,7 @@ pe_ILF_build_a_bfd (bfd * abfd,
asection_ptr id4, id5, id6 = NULL, text = NULL; asection_ptr id4, id5, id6 = NULL, text = NULL;
coff_symbol_type ** imp_sym; coff_symbol_type ** imp_sym;
unsigned int imp_index; unsigned int imp_index;
intptr_t alignment;
/* Decode and verify the types field of the ILF structure. */ /* Decode and verify the types field of the ILF structure. */
import_type = types & 0x3; import_type = types & 0x3;
@ -874,23 +874,17 @@ pe_ILF_build_a_bfd (bfd * abfd,
/* The remaining space in bim->buffer is used /* The remaining space in bim->buffer is used
by the pe_ILF_make_a_section() function. */ by the pe_ILF_make_a_section() function. */
# if (GCC_VERSION >= 3000)
/* PR 18758: Make sure that the data area is sufficiently aligned for /* PR 18758: Make sure that the data area is sufficiently aligned for
pointers on the host. __alignof__ is a gcc extension, hence the test struct coff_section_tdata. __alignof__ is a gcc extension, hence
above. For other compilers we will have to assume that the alignment is the test of GCC_VERSION. For other compilers we assume 8 byte
unimportant, or else extra code can be added here and in alignment. */
pe_ILF_make_a_section. #if GCC_VERSION >= 3000
alignment = __alignof__ (struct coff_section_tdata);
Note - we cannot test 'ptr' directly as it is illegal to perform binary #else
arithmetic on pointers, but we know that the strings section is the only alignment = 8;
one that might end on an unaligned boundary. */
{
unsigned int alignment = __alignof__ (char *);
if (SIZEOF_ILF_STRINGS & (alignment - 1))
ptr += alignment - (SIZEOF_ILF_STRINGS & (alignment - 1));
}
#endif #endif
ptr = (bfd_byte *) (((intptr_t) ptr + alignment - 1) & -alignment);
vars.data = ptr; vars.data = ptr;
vars.abfd = abfd; vars.abfd = abfd;