Fix the linker so that it will not silently generate ELF binaries with invalid program headers. Fix readelf to report such invalid binaries.
PR ld/20815 bfd * elf.c (elf_modify_segment_map): Allow empty LOAD segments if they contain the program headers. (_bfd_elf_map_sections_to_segments): If the linker created the PHDR segment then always attempt to include it in a LOAD segment. (assign_file_positions_for_non_load_sections): Allow LOAD segments to overlap PHDR segments. (phdr_sorter): New function. Sorts program headers. (assign_file_positions_except_relocs): Sort the program headers before writing them out. Issue an error if the PHDR segment is not covered by a LOAD segment, unless the backend allows it. * elf-bfd.h (struct elf_backend_data): Add elf_backend_allow_non_load_phdr. * elfxx-target.h (elf_backend_allow_non_load_phdr): Provide default definition that returns FALSE. (elfNN_bed): Initialise the elf_backend_allow_non_load_phdr field. * elf64-hppa.c (elf64_hppa_allow_non_load_phdr): New function. Returns TRUE. (elf_backend_allow_non_load_phdr): Define. * elf-m10300.c (_bfd_mn10300_elf_size_dynamic_sections): Do not place the interpreter string into the .interp section if the nointerp flag is set in the link info structure. * elf32-arc.c (elf_arc_size_dynamic_sections): Likewise. * elf32-score7.c (score_elf_final_link_relocate): Allow for the _gp symbol not being part of the output. binutils* readelf.c (process_program_headers): Check PT_LOAD and PT_PHDR segments for validity. ld * ld.texinfo: Note that PT_TLS can be used as a segment type. * testsuite/ld-discard/discard.ld: Add space for program headers. * testsuite/ld-elf/flags1.ld: Likewise. * testsuite/ld-elf/maxpage3.t: Likewise. * testsuite/ld-elf/noload-1.t: Likewise. * testsuite/ld-elf/orphan.ld: Likewise. * testsuite/ld-elf/overlay.t: Likewise. * testsuite/ld-elf/pr14052.t: Likewise. * testsuite/ld-elf/pr19539.t: Likewise. * testsuite/ld-elf/provide-hidden-1.ld: Likewise. * testsuite/ld-elf/provide-hidden-s.ld: Likewise. * testsuite/ld-elf/weak-dyn-1.ld: Likewise. * testsuite/ld-i386/pr19539.t: Likewise. * testsuite/ld-scripts/defined.t: Likewise. * testsuite/ld-scripts/defined6.t: Likewise. * testsuite/ld-scripts/dynamic-sections.t: Likewise. * testsuite/ld-scripts/empty-aligned.t: Likewise. * testsuite/ld-scripts/provide-2.t: Likewise. * testsuite/ld-scripts/provide-4.t: Likewise. * testsuite/ld-vax-elf/plt-local.ld: Likewise. * testsuite/ld-x86-64/pr19539.t: Likewise. * testsuite/ld-elf/ehdr_start-missing.d: Do not initialise the dynamic linker. * testsuite/ld-elf/ehdr_start-weak.d: Likewise. * testsuite/ld-elf/elf.exp (pr14170, pr17068): Likewise. * testsuite/ld-elf/loadaddr1.d: Update expected readelf output. * testsuite/ld-elf/noload-2.d: Likewise. * testsuite/ld-powerpc/vxworks2.sd: Likewise. * testsuite/ld-scripts/phdrs3a.d: Likewise. * testsuite/ld-scripts/size-2.d: Likewise. * testsuite/ld-elf/group.ld: Add program headers. * testsuite/ld-elf/overlay.d: Skip for SPU. * testsuite/ld-elf/flags1.d: Skip for RX. * testsuite/ld-elf/pr19162.d: Skip for HPPA64. * testsuite/ld-elf/pr19539.d: Skip for ALPHA. * testsuite/ld-scripts/empty-orphan.t: Update program headers. * testsuite/ld-scripts/size-2.t: Likewise.
This commit is contained in:
parent
128e85e3ab
commit
1a9ccd70f9
48 changed files with 324 additions and 40 deletions
|
@ -1,3 +1,9 @@
|
|||
2016-11-23 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR ld/20815
|
||||
* readelf.c (process_program_headers): Check PT_LOAD and PT_PHDR
|
||||
segments for validity.
|
||||
|
||||
2016-11-22 Ambrogino Modigliani <ambrogino.modigliani@gmail.com>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
|
|
@ -3797,7 +3797,7 @@ get_segment_type (unsigned long p_type)
|
|||
if (result != NULL)
|
||||
return result;
|
||||
|
||||
sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
|
||||
sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
|
||||
}
|
||||
else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
|
||||
{
|
||||
|
@ -3822,7 +3822,7 @@ get_segment_type (unsigned long p_type)
|
|||
if (result != NULL)
|
||||
return result;
|
||||
|
||||
sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
|
||||
sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
|
||||
}
|
||||
else
|
||||
snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
|
||||
|
@ -4770,6 +4770,7 @@ process_program_headers (FILE * file)
|
|||
{
|
||||
Elf_Internal_Phdr * segment;
|
||||
unsigned int i;
|
||||
Elf_Internal_Phdr * previous_load = NULL;
|
||||
|
||||
if (elf_header.e_phnum == 0)
|
||||
{
|
||||
|
@ -4901,13 +4902,39 @@ process_program_headers (FILE * file)
|
|||
(segment->p_flags & PF_X ? 'E' : ' '));
|
||||
print_vma (segment->p_align, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_segments)
|
||||
putc ('\n', stdout);
|
||||
putc ('\n', stdout);
|
||||
}
|
||||
|
||||
switch (segment->p_type)
|
||||
{
|
||||
case PT_LOAD:
|
||||
if (previous_load
|
||||
&& previous_load->p_vaddr > segment->p_vaddr)
|
||||
error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
|
||||
if (segment->p_memsz < segment->p_filesz)
|
||||
error (_("the segment's file size is larger than its memory size\n"));
|
||||
previous_load = segment;
|
||||
break;
|
||||
|
||||
case PT_PHDR:
|
||||
/* PR 20815 - Verify that the program header is loaded into memory. */
|
||||
if (i > 0 && previous_load != NULL)
|
||||
error (_("the PHDR segment must occur before any LOAD segment\n"));
|
||||
if (elf_header.e_machine != EM_PARISC)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j = 1; j < elf_header.e_phnum; j++)
|
||||
if (program_headers[j].p_vaddr <= segment->p_vaddr
|
||||
&& (program_headers[j].p_vaddr + program_headers[j].p_memsz)
|
||||
>= (segment->p_vaddr + segment->p_filesz))
|
||||
break;
|
||||
if (j == elf_header.e_phnum)
|
||||
error (_("the PHDR segment is not covered by a LOAD segment\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case PT_DYNAMIC:
|
||||
if (dynamic_addr)
|
||||
error (_("more than one dynamic segment\n"));
|
||||
|
@ -6068,7 +6095,9 @@ process_section_headers (FILE * file)
|
|||
if (section->sh_type == SHT_NOBITS)
|
||||
/* NOBITS section headers with non-zero sh_info fields can be
|
||||
created when a binary is stripped of everything but its debug
|
||||
information. The stripped sections have their headers preserved but their types set to SHT_NOBITS. so do not check this type of section. */
|
||||
information. The stripped sections have their headers
|
||||
preserved but their types set to SHT_NOBITS. So do not check
|
||||
this type of section. */
|
||||
;
|
||||
else if (section->sh_flags & SHF_INFO_LINK)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue