diff options
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf.c | 21 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-pie/vaddr-0.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-pie/vaddr-1.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-pie/vaddr.s | 10 |
6 files changed, 60 insertions, 0 deletions
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 <hongjiu.lu@intel.com> + + * 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 <amodra@gmail.com> * elflink.c (_bfd_elf_add_default_symbol): Set dynamic_def @@ -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 <hongjiu.lu@intel.com> + + * ld-pie/vaddr-0.d: New file. + * ld-pie/vaddr-1.d: Likewise. + * ld-pie/vaddr.s: Likewise. + 2013-12-11 Will Newton <will.newton@linaro.org> * 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 |