PR23595, simple objcopy of executable failure for msp430-elf

VMA of the first section in the segment containing the ELF file header
(and possibly section headers too) can't be used to reliably find the
size of the headers plus padding.  What's really needed is sh_offset
of the first section assuming it has contents (vma does have a
relationship to sh_offset, but is only guaranteed in demand paged
executables).

If the first section is SHT_NOBITS and it hasn't been converted to
have file contents by the existence of a following SHT_PROGBITS
section in the same segment, the sh_offset value also isn't reliable.

	PR 23595
	elf.c (copy_elf_program_header): When first segment contains
	only the headers and SHT_NOBITS sections, use segment p_filesz
	to calculate header and padding size.  Use filepos of the first
	section otherwise.
This commit is contained in:
Jozef Lawrynowicz 2018-09-03 11:04:05 +09:30 committed by Alan Modra
parent 0d9a433be4
commit 2542e49e21
2 changed files with 23 additions and 2 deletions

View File

@ -1,3 +1,12 @@
2018-09-03 Jozef Lawrynowicz <jozef.l@mittosystems.com>
Alan Modra <amodra@gmail.com>
PR 23595
elf.c (copy_elf_program_header): When first segment contains
only the headers and SHT_NOBITS sections, use segment p_filesz
to calculate header and padding size. Use filepos of the first
section otherwise.
018-08-31 H.J. Lu <hongjiu.lu@intel.com>
PR ld/23600

View File

@ -7235,6 +7235,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
Elf_Internal_Shdr *this_hdr;
asection *first_section = NULL;
asection *lowest_section;
bfd_boolean no_contents = TRUE;
/* Compute how many sections are in this segment. */
for (section = ibfd->sections, section_count = 0;
@ -7246,6 +7247,8 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
{
if (first_section == NULL)
first_section = section;
if (elf_section_type (section) != SHT_NOBITS)
no_contents = FALSE;
section_count++;
}
}
@ -7342,8 +7345,17 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
}
if (map->includes_filehdr && lowest_section != NULL)
/* We need to keep the space used by the headers fixed. */
map->header_size = lowest_section->vma - segment->p_vaddr;
{
/* Try to keep the space used by the headers plus any
padding fixed. If there are sections with file contents
in this segment then the lowest sh_offset is the best
guess. Otherwise the segment only has file contents for
the headers, and p_filesz is the best guess. */
if (no_contents)
map->header_size = segment->p_filesz;
else
map->header_size = lowest_section->filepos;
}
if (!map->includes_phdrs
&& !map->includes_filehdr