Set ET_EXEC for -pie -Ttext-segment=
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Dec 2013 15:41:27 +0000 (07:41 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Dec 2013 15:41:27 +0000 (07:41 -0800)
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  <hongjiu.lu@intel.com>

* ld-pie/vaddr-0.d: New file.
* ld-pie/vaddr-1.d: Likewise.
* ld-pie/vaddr.s: Likewise.

bfd/ChangeLog
bfd/elf.c
ld/testsuite/ChangeLog
ld/testsuite/ld-pie/vaddr-0.d [new file with mode: 0644]
ld/testsuite/ld-pie/vaddr-1.d [new file with mode: 0644]
ld/testsuite/ld-pie/vaddr.s [new file with mode: 0644]

index b98a08c..4d11e9a 100644 (file)
@@ -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
index 8df38ee..66d9644 100644 (file)
--- 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
index 2f64fce..6100dfe 100644 (file)
@@ -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 (file)
index 0000000..e072222
--- /dev/null
@@ -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 (file)
index 0000000..7b5f992
--- /dev/null
@@ -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 (file)
index 0000000..5fc0ee7
--- /dev/null
@@ -0,0 +1,10 @@
+       .globl main
+       .globl start
+       .globl _start
+       .globl __start
+       .text
+main:
+start:
+_start:
+__start:
+       .byte 0