From d0ecbbac0e905ebf6768deb9dfacd9c7f9a63f2e Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 13 Jan 2015 20:05:01 +0000 Subject: [PATCH] Generate a PT_PHDR entry for static PIE binaries. Modern GDB needs this to do some sanity checking while it determines the load base. ok kurt@ --- gnu/usr.bin/binutils/bfd/elf-bfd.h | 3 +++ gnu/usr.bin/binutils/bfd/elf.c | 30 ++++++++++++++++++++++-------- gnu/usr.bin/binutils/bfd/elflink.c | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/gnu/usr.bin/binutils/bfd/elf-bfd.h b/gnu/usr.bin/binutils/bfd/elf-bfd.h index 110dd696c54..db4d9862a35 100644 --- a/gnu/usr.bin/binutils/bfd/elf-bfd.h +++ b/gnu/usr.bin/binutils/bfd/elf-bfd.h @@ -1235,6 +1235,9 @@ struct elf_obj_tdata /* Used to determine if the e_flags field has been initialized */ bfd_boolean flags_init; + + /* Used to determine if we are creating an executable. */ + bfd_boolean executable; }; #define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data) diff --git a/gnu/usr.bin/binutils/bfd/elf.c b/gnu/usr.bin/binutils/bfd/elf.c index 901fd2ca52d..efef5f9ac74 100644 --- a/gnu/usr.bin/binutils/bfd/elf.c +++ b/gnu/usr.bin/binutils/bfd/elf.c @@ -3234,11 +3234,13 @@ map_sections_to_segments (bfd *abfd) mfirst = NULL; pm = &mfirst; - /* If we have a .interp section, then create a PT_PHDR segment for - the program headers and a PT_INTERP segment for the .interp - section. */ + /* If we have a .interp section, or are creating an executable and + have a .dynamic section, then create a PT_PHDR segment for the + program headers. */ s = bfd_get_section_by_name (abfd, ".interp"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) + if ((s != NULL && (s->flags & SEC_LOAD) != 0) || + (bfd_get_section_by_name (abfd, ".dynamic") && + elf_tdata (abfd)->executable)) { amt = sizeof (struct elf_segment_map); m = bfd_zalloc (abfd, amt); @@ -3253,7 +3255,12 @@ map_sections_to_segments (bfd *abfd) *pm = m; pm = &m->next; + } + /* If we have a .interp section, then create a PT_INTERP segment for + the .interp section. */ + if (s != NULL && (s->flags & SEC_LOAD) != 0) + { amt = sizeof (struct elf_segment_map); m = bfd_zalloc (abfd, amt); if (m == NULL) @@ -4134,13 +4141,20 @@ get_program_header_size (bfd *abfd) segs = 7; s = bfd_get_section_by_name (abfd, ".interp"); + s = bfd_get_section_by_name (abfd, ".interp"); + if ((s != NULL && (s->flags & SEC_LOAD) != 0) || + (bfd_get_section_by_name (abfd, ".dynamic") && + elf_tdata (abfd)->executable)) + { + /* We need a PT_PHDR segment. */ + ++segs; + } + if (s != NULL && (s->flags & SEC_LOAD) != 0) { /* If we have a loadable interpreter section, we need a - PT_INTERP segment. In this case, assume we also need a - PT_PHDR segment, although that may not be true for all - targets. */ - segs += 2; + PT_INTERP segment. */ + ++segs; } if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) diff --git a/gnu/usr.bin/binutils/bfd/elflink.c b/gnu/usr.bin/binutils/bfd/elflink.c index 73a8a4778aa..d6db60849ea 100644 --- a/gnu/usr.bin/binutils/bfd/elflink.c +++ b/gnu/usr.bin/binutils/bfd/elflink.c @@ -4626,6 +4626,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, if (!is_elf_hash_table (info->hash)) return TRUE; + elf_tdata (output_bfd)->executable = info->executable; if (info->execstack) elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; else if (info->noexecstack) -- 2.20.1