diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-01-13 20:05:44 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-01-13 20:05:44 +0000 |
commit | c5dc93f680ab42a4a7f64c3d127ff3153228b8c2 (patch) | |
tree | 4dab28bc62d47f916f2fcb055dd32e483762aebc /gnu | |
parent | a7c7e5f20a79073c831c8c09960a5d8179644c58 (diff) |
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@
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h | 3 | ||||
-rw-r--r-- | gnu/usr.bin/binutils-2.17/bfd/elf.c | 30 | ||||
-rw-r--r-- | gnu/usr.bin/binutils-2.17/bfd/elflink.c | 1 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elf-bfd.h | 3 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elf.c | 30 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elflink.c | 1 |
6 files changed, 52 insertions, 16 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) 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) |