From 58e7ebacdd97c858834c07c7dce098aeacd500fb Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 12 Dec 2013 07:41:27 -0800 Subject: [PATCH] Set ET_EXEC for -pie -Ttext-segment= bfd/ * elf.c (assign_file_positions_except_relocs): Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=. 2013-12-10 H.J. Lu * ld-pie/vaddr-0.d: New file. * ld-pie/vaddr-1.d: Likewise. * ld-pie/vaddr.s: Likewise. --- bfd/ChangeLog | 5 +++++ bfd/elf.c | 21 +++++++++++++++++++++ ld/testsuite/ChangeLog | 6 ++++++ ld/testsuite/ld-pie/vaddr-0.d | 9 +++++++++ ld/testsuite/ld-pie/vaddr-1.d | 9 +++++++++ ld/testsuite/ld-pie/vaddr.s | 10 ++++++++++ 6 files changed, 60 insertions(+) create mode 100644 ld/testsuite/ld-pie/vaddr-0.d create mode 100644 ld/testsuite/ld-pie/vaddr-1.d create mode 100644 ld/testsuite/ld-pie/vaddr.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b98a08c..4d11e9a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2013-12-12 H.J. Lu + + * elf.c (assign_file_positions_except_relocs): Set e_type in ELF + header to ET_EXEC for -pie -Ttext-segment=. + 2013-12-08 Alan Modra * elflink.c (_bfd_elf_add_default_symbol): Set dynamic_def diff --git a/bfd/elf.c b/bfd/elf.c index 8df38ee..66d9644 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -5152,6 +5152,27 @@ assign_file_positions_except_relocs (bfd *abfd, return FALSE; } + /* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=. */ + if (link_info != NULL + && link_info->executable + && link_info->shared) + { + unsigned int num_segments = elf_elfheader (abfd)->e_phnum; + Elf_Internal_Phdr *segment = elf_tdata (abfd)->phdr; + Elf_Internal_Phdr *end_segment = &segment[num_segments]; + + /* Find the lowest p_vaddr in PT_LOAD segments. */ + bfd_vma p_vaddr = (bfd_vma) -1; + for (; segment < end_segment; segment++) + if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr) + p_vaddr = segment->p_vaddr; + + /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD + segments is non-zero. */ + if (p_vaddr) + i_ehdrp->e_type = ET_EXEC; + } + /* Write out the program headers. */ alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr; if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 2f64fce..6100dfe 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-12-12 H.J. Lu + + * ld-pie/vaddr-0.d: New file. + * ld-pie/vaddr-1.d: Likewise. + * ld-pie/vaddr.s: Likewise. + 2013-12-11 Will Newton * ld-aarch64/ifunc-21.d: Make test more generic to support diff --git a/ld/testsuite/ld-pie/vaddr-0.d b/ld/testsuite/ld-pie/vaddr-0.d new file mode 100644 index 0000000..e072222 --- /dev/null +++ b/ld/testsuite/ld-pie/vaddr-0.d @@ -0,0 +1,9 @@ +#source: vaddr.s +#name: zero p_vaddr +#ld: -pie +#readelf: -h + +ELF Header: +#... + Type: DYN \(Shared object file\) +#pass diff --git a/ld/testsuite/ld-pie/vaddr-1.d b/ld/testsuite/ld-pie/vaddr-1.d new file mode 100644 index 0000000..7b5f992 --- /dev/null +++ b/ld/testsuite/ld-pie/vaddr-1.d @@ -0,0 +1,9 @@ +#source: vaddr.s +#name: non-zero p_vaddr +#ld: -pie -Ttext-segment 0x7000000 -z max-page-size=0x200000 +#readelf: -h + +ELF Header: +#... + Type: EXEC \(Executable file\) +#pass diff --git a/ld/testsuite/ld-pie/vaddr.s b/ld/testsuite/ld-pie/vaddr.s new file mode 100644 index 0000000..5fc0ee7 --- /dev/null +++ b/ld/testsuite/ld-pie/vaddr.s @@ -0,0 +1,10 @@ + .globl main + .globl start + .globl _start + .globl __start + .text +main: +start: +_start: +__start: + .byte 0 -- 2.7.4