From 89a097c7e75326389a1ed75a7144e2552b509174 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 10 Dec 2013 11:03:03 -0800 Subject: [PATCH] Use ET_EXEC for -pie -Ttext-segment= --- ChangeLog.pie | 14 ++++++++++++++ bfd/elf.c | 21 +++++++++++++++++++++ ld/testsuite/ld-pie/vaddr-0.d | 9 +++++++++ ld/testsuite/ld-pie/vaddr-1.d | 9 +++++++++ ld/testsuite/ld-pie/vaddr.s | 10 ++++++++++ 5 files changed, 63 insertions(+) create mode 100644 ChangeLog.pie 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/ChangeLog.pie b/ChangeLog.pie new file mode 100644 index 0000000..599c5dd --- /dev/null +++ b/ChangeLog.pie @@ -0,0 +1,14 @@ +bfd/ + +2013-12-10 H.J. Lu + + * elf.c (assign_file_positions_except_relocs): Set e_type in ELF + header to ET_EXEC for -pie -Ttext-segment=. + +ld/testsuite/ + +2013-12-10 H.J. Lu + + * ld-pie/vaddr-0.d: New file. + * ld-pie/vaddr-1.d: Likewise. + * ld-pie/vaddr.s: Likewise. 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/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 -- 1.8.3.1