summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-01-13 20:05:44 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-01-13 20:05:44 +0000
commitc5dc93f680ab42a4a7f64c3d127ff3153228b8c2 (patch)
tree4dab28bc62d47f916f2fcb055dd32e483762aebc /gnu
parenta7c7e5f20a79073c831c8c09960a5d8179644c58 (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.h3
-rw-r--r--gnu/usr.bin/binutils-2.17/bfd/elf.c30
-rw-r--r--gnu/usr.bin/binutils-2.17/bfd/elflink.c1
-rw-r--r--gnu/usr.bin/binutils/bfd/elf-bfd.h3
-rw-r--r--gnu/usr.bin/binutils/bfd/elf.c30
-rw-r--r--gnu/usr.bin/binutils/bfd/elflink.c1
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)