From b17ce193d0001dff4c15abae924a5d5a6e8dac22 Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 13 Jan 2015 20:05:43 +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-2.17/bfd/elf-bfd.h | 3 +++ gnu/usr.bin/binutils-2.17/bfd/elf.c | 30 ++++++++++++++++++------- gnu/usr.bin/binutils-2.17/bfd/elflink.c | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h b/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h index 3fba1c228f0..e6971087236 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h +++ b/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h @@ -1368,6 +1368,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-2.17/bfd/elf.c b/gnu/usr.bin/binutils-2.17/bfd/elf.c index aaf92014173..9232cac828e 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elf.c +++ b/gnu/usr.bin/binutils-2.17/bfd/elf.c @@ -3644,11 +3644,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); @@ -3663,7 +3665,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) @@ -4658,13 +4665,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-2.17/bfd/elflink.c b/gnu/usr.bin/binutils-2.17/bfd/elflink.c index ee159727815..6bb64fbc5a5 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elflink.c +++ b/gnu/usr.bin/binutils-2.17/bfd/elflink.c @@ -4986,6 +4986,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, return TRUE; elf_tdata (output_bfd)->relro = info->relro; + 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