Add support for ARM's NOREAD section flag.
authorMickael Guene <mickael.guene@st.com>
Tue, 22 Dec 2015 14:12:35 +0000 (14:12 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 22 Dec 2015 14:12:35 +0000 (14:12 +0000)
include/elf
     * arm.h: Add arm SHF_ARM_NOREAD section flag.

bfd  * bfd-in2.h: Regenerate.
     * section.c: Add SEC_ELF_NOREAD.
     * elf32-arm.c (elf32_arm_post_process_headers): Only set
     PF_X attribute if a segment only contains section with
     SHF_ARM_NOREAD flag.
     (elf32_arm_fake_sections): Add SEC_ELF_NOREAD conversion.
     (elf32_arm_section_flags): New function to convert SHF_ARM_NOREAD
     to bfd flag.
     (elf32_arm_lookup_section_flags): New function to allow
     INPUT_SECTION_FLAGS directive with SHF_ARM_NOREAD flag.
     (elf32_arm_special_sections): Add special sections array
     to catch section prefix by '.text.noread' pattern.

ld/testsuite
     * ld-arm/arm-elf.exp: New tests.
     * ld-arm/thumb1-input-section-flag-match.d: New
     * ld-arm/thumb1-input-section-flag-match.s: New
     * ld-arm/thumb1-noread-not-present-mixing-two-section.d: New
     * ld-arm/thumb1-noread-not-present-mixing-two-section.s: New
     * ld-arm/thumb1-noread-present-one-section.d: New
     * ld-arm/thumb1-noread-present-one-section.s: New
     * ld-arm/thumb1-noread-present-two-section.d: New
     * ld-arm/thumb1-noread-present-two-section.s: New

binutils
* readelf.c (get_elf_section_flags): Add support for ARM specific
section flags.

20 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-arm.c
bfd/section.c
binutils/ChangeLog
binutils/readelf.c
include/ChangeLog
include/elf/ChangeLog
include/elf/arm.h
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/arm_noread.ld [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-input-section-flag-match.d [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-input-section-flag-match.s [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-noread-present-one-section.d [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-noread-present-one-section.s [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-noread-present-two-section.d [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-noread-present-two-section.s [new file with mode: 0644]

index f81e90d..03fbb34 100644 (file)
@@ -1,3 +1,18 @@
+2015-12-22 Mickael Guene <mickael.guene@st.com>
+
+       * bfd-in2.h: Regenerate.
+       * section.c: Add SEC_ELF_NOREAD.
+       * elf32-arm.c (elf32_arm_post_process_headers): Only set
+       PF_X attribute if a segment only contains section with
+       SHF_ARM_NOREAD flag.
+       (elf32_arm_fake_sections): Add SEC_ELF_NOREAD conversion.
+       (elf32_arm_section_flags): New function to convert SHF_ARM_NOREAD
+       to bfd flag.
+       (elf32_arm_lookup_section_flags): New function to allow
+       INPUT_SECTION_FLAGS directive with SHF_ARM_NOREAD flag.
+       (elf32_arm_special_sections): Add special sections array
+       to catch section prefix by '.text.noread' pattern.
+
 2015-12-18  H.J. Lu  <hongjiu.lu@intel.com>
 
        * coff-x86_64.c (coff_amd64_reloc): Fix formatting.
index 39eb19a..ca0cafd 100644 (file)
@@ -1432,6 +1432,9 @@ typedef struct bfd_section
      when memory read flag isn't set. */
 #define SEC_COFF_NOREAD 0x40000000
 
+  /* Indicate that section has the no read flag set.  */
+#define SEC_ELF_NOREAD 0x80000000
+
   /*  End of section flags.  */
 
   /* Some internal packed boolean fields.  */
index 49d6469..5d31ef2 100644 (file)
@@ -15417,6 +15417,7 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT
 {
   Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form.  */
   struct elf32_arm_link_hash_table *globals;
+  struct elf_segment_map *m;
 
   i_ehdrp = elf_elfheader (abfd);
 
@@ -15442,6 +15443,26 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT
       else
        i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_SOFT;
     }
+
+  /* Scan segment to set p_flags attribute if it contains only sections with
+     SHF_ARM_NOREAD flag.  */
+  for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+    {
+      unsigned int j;
+
+      if (m->count == 0)
+       continue;
+      for (j = 0; j < m->count; j++)
+       {
+         if (!(elf_section_flags (m->sections[j]) & SHF_ARM_NOREAD))
+           break;
+       }
+      if (j == m->count)
+       {
+         m->p_flags = PF_X;
+         m->p_flags_valid = 1;
+       }
+    }
 }
 
 static enum elf_reloc_type_class
@@ -15493,6 +15514,10 @@ elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
       hdr->sh_type = SHT_ARM_EXIDX;
       hdr->sh_flags |= SHF_LINK_ORDER;
     }
+
+  if (sec->flags & SEC_ELF_NOREAD)
+    hdr->sh_flags |= SHF_ARM_NOREAD;
+
   return TRUE;
 }
 
@@ -17690,6 +17715,33 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
   return n;
 }
 
+static const struct bfd_elf_special_section
+elf32_arm_special_sections[] =
+{
+/* Catch sections with .text.noread prefix and apply allocate, execute and
+   noread section attributes.  */
+  { STRING_COMMA_LEN (".text.noread"),  -2, SHT_PROGBITS,
+    SHF_ALLOC + SHF_EXECINSTR + SHF_ARM_NOREAD },
+  { NULL,                            0, 0, 0,                  0 }
+};
+
+static bfd_boolean
+elf32_arm_section_flags (flagword *flags, const Elf_Internal_Shdr * hdr)
+{
+  if (hdr->sh_flags & SHF_ARM_NOREAD)
+    *flags |= SEC_ELF_NOREAD;
+  return TRUE;
+}
+
+static flagword
+elf32_arm_lookup_section_flags (char *flag_name)
+{
+  if (!strcmp (flag_name, "SHF_ARM_NOREAD"))
+    return SHF_ARM_NOREAD;
+
+  return SEC_NO_FLAGS;
+}
+
 #define ELF_ARCH                       bfd_arch_arm
 #define ELF_TARGET_ID                  ARM_ELF_DATA
 #define ELF_MACHINE_CODE               EM_ARM
@@ -17768,6 +17820,13 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
 #define elf_backend_obj_attrs_order            elf32_arm_obj_attrs_order
 #define elf_backend_obj_attrs_handle_unknown   elf32_arm_obj_attrs_handle_unknown
 
+#undef  elf_backend_special_sections
+#define elf_backend_special_sections           elf32_arm_special_sections
+#undef elf_backend_section_flags
+#define elf_backend_section_flags              elf32_arm_section_flags
+#undef elf_backend_lookup_section_flags_hook
+#define elf_backend_lookup_section_flags_hook   elf32_arm_lookup_section_flags
+
 #include "elf32-target.h"
 
 /* Native Client targets.  */
index 247d98a..1a78c11 100644 (file)
@@ -361,6 +361,9 @@ CODE_FRAGMENT
 .     when memory read flag isn't set. *}
 .#define SEC_COFF_NOREAD 0x40000000
 .
+.  {* Indicate that section has the no read flag set.  *}
+.#define SEC_ELF_NOREAD 0x80000000
+.
 .  {*  End of section flags.  *}
 .
 .  {* Some internal packed boolean fields.  *}
index f588410..fce5f89 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-22  Nick Clifton  <nickc@redhat.com>
+
+       * readelf.c (get_elf_section_flags): Add support for ARM specific
+       section flags.
+
 2015-12-17  Maciej W. Rozycki  <macro@imgtec.com>
 
        * MAINTAINERS: Add myself as MIPS maintainer.
index c21ce3f..a31db52 100644 (file)
@@ -5273,7 +5273,11 @@ get_elf_section_flags (bfd_vma sh_flags)
       /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
       /* SPARC specific.  */
       /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
-      /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") }
+      /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
+      /* ARM specific.  */
+      /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
+      /* 22 */ { STRING_COMMA_LEN ("ARM_NOREAD") },
+      /* 23 */ { STRING_COMMA_LEN ("COMDEF") }
     };
 
   if (do_section_details)
@@ -5343,6 +5347,17 @@ get_elf_section_flags (bfd_vma sh_flags)
                  if (flag == SHF_ORDERED)
                    sindex = 19;
                  break;
+
+               case EM_ARM:
+                 switch (flag)
+                   {
+                   case SHF_ENTRYSECT: sindex = 21; break;
+                   case SHF_ARM_NOREAD: sindex = 22; break;
+                   case SHF_COMDEF: sindex = 23; break;
+                   default: break;
+                   }
+                 break;
+
                default:
                  break;
                }
index 4dcfe10..cd33a61 100644 (file)
@@ -1,7 +1,3 @@
-2015-12-16  Mickael Guene <mickael.guene@st.com>
-
-       * elf/arm.h: Add new arm relocations.
-
 2015-12-01  Alan Modra  <amodra@gmail.com>
 
        * bout.h: Invoke aout N_* macros with pointer to
index 5b98c66..93b0001 100644 (file)
@@ -1,3 +1,11 @@
+2015-12-22 Mickael Guene <mickael.guene@st.com>
+
+       * arm.h: Add arm SHF_ARM_NOREAD section flag.
+
+2015-12-16  Mickael Guene <mickael.guene@st.com>
+
+       * arm.h: Add new arm relocations.
+
 2015-12-14  Yoshinori Sato <ysato@users.sourceforge.jp>
 
        * rx.h (E_FLAG_RX_V2): New RXv2 type.
index 5691118..4f09b6a 100644 (file)
@@ -82,6 +82,7 @@
 
 /* ARM-specific values for sh_flags.  */
 #define SHF_ENTRYSECT      0x10000000   /* Section contains an entry point.  */
+#define SHF_ARM_NOREAD     0x20000000   /* Section contains code that can be place on no read memory area.  */
 #define SHF_COMDEF         0x80000000   /* Section may be multiply defined in the input to a link step.  */
 
 /* ARM-specific program header flags.  */
index ac3d142..d5982b9 100644 (file)
@@ -1,3 +1,15 @@
+2015-12-22 Mickael Guene <mickael.guene@st.com>
+
+       * ld-arm/arm-elf.exp: New tests.
+       * ld-arm/thumb1-input-section-flag-match.d: New
+       * ld-arm/thumb1-input-section-flag-match.s: New
+       * ld-arm/thumb1-noread-not-present-mixing-two-section.d: New
+       * ld-arm/thumb1-noread-not-present-mixing-two-section.s: New
+       * ld-arm/thumb1-noread-present-one-section.d: New
+       * ld-arm/thumb1-noread-present-one-section.s: New
+       * ld-arm/thumb1-noread-present-two-section.d: New
+       * ld-arm/thumb1-noread-present-two-section.s: New
+
 2015-12-16  Mickael Guene <mickael.guene@st.com>
 
        * ld-arm/arm-elf.exp (armelftests_common): Add new relocations
index 23c9e57..a970dba 100644 (file)
@@ -299,6 +299,18 @@ set armelftests_nonacl {
     {"TLS shared library gdesc local" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" "" {tls-lib-loc.s}
      {{objdump -fdw tls-lib-loc.d} {objdump -Rw tls-lib-loc.r}}
      "tls-lib-loc.so"}
+    {"PF_R not present when one noread section" "-static -T arm.ld" "" "" {thumb1-noread-present-one-section.s}
+     {{readelf -l thumb1-noread-present-one-section.d}}
+     "thumb1-noread-present-one-section"}
+    {"PF_R not present when two noread sections" "-static -T arm.ld" "" "" {thumb1-noread-present-two-section.s}
+     {{readelf -l thumb1-noread-present-two-section.d}}
+     "thumb1-noread-present-two-section"}
+    {"PF_R present when mixing noread section with read section" "-static -T arm.ld" "" "" {thumb1-noread-not-present-mixing-two-section.s}
+     {{readelf -l thumb1-noread-not-present-mixing-two-section.d}}
+     "thumb1-noread-not-present-mixing-two-section"}
+    {"Match SHF_ARM_NOREAD with INPUT_SECTION_FLAGS directive" "-static -T arm_noread.ld" "" "" {thumb1-input-section-flag-match.s}
+     {{readelf -l thumb1-input-section-flag-match.d}}
+     "thumb1-noread-not-present-mixing-two-section"}
 }
 
 run_ld_link_tests $armelftests_common
diff --git a/ld/testsuite/ld-arm/arm_noread.ld b/ld/testsuite/ld-arm/arm_noread.ld
new file mode 100644 (file)
index 0000000..3ff17bc
--- /dev/null
@@ -0,0 +1,32 @@
+/* Script for ld testsuite.  */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+MEMORY
+{
+ read_memory   (rx)   : ORIGIN = 0x00008000, LENGTH = 4M
+ noread_memory (!rx)  : ORIGIN = 0x00800000, LENGTH = 4M
+}
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = 0x8000); . = 0x8000;
+  .text.noread      :
+    {
+        INPUT_SECTION_FLAGS (SHF_ARM_NOREAD) *(.text*)
+    } > noread_memory
+  .text           :
+  {
+    *(.before)
+    *(.text)
+    *(.after)
+    *(.ARM.extab*)
+    *(.glue_7)
+    *(.v4_bx)
+  } > read_memory
+  .ARM.exidx : { *(.ARM.exidx*) }
+  . = 0x9000;
+  .got            : { *(.got) *(.got.plt)}
+  . = 0x12340000;
+  .far : { *(.far) }
+  .ARM.attribues 0 : { *(.ARM.atttributes) }
+}
diff --git a/ld/testsuite/ld-arm/thumb1-input-section-flag-match.d b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.d
new file mode 100644 (file)
index 0000000..e25a4f4
--- /dev/null
@@ -0,0 +1,6 @@
+#...
+Program Headers:
+#...
+  LOAD           0x000000 0x00000000 0x00000000 0x08002 0x08002 R E 0x10000
+  LOAD           0x010000 0x00800000 0x00800000 0x00002 0x00002   E 0x10000
+#...
diff --git a/ld/testsuite/ld-arm/thumb1-input-section-flag-match.s b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.s
new file mode 100644 (file)
index 0000000..ac7c89f
--- /dev/null
@@ -0,0 +1,18 @@
+       .text
+       .section .text.noread
+       .arch armv6s-m
+       .syntax unified
+       .global _start
+       .thumb_func
+       .type   _start, %function
+_start:
+       bx lr
+
+       .text
+       .arch armv6s-m
+       .syntax unified
+       .global foo
+       .thumb_func
+       .type   foo, %function
+foo:
+       bx lr
diff --git a/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d
new file mode 100644 (file)
index 0000000..9150576
--- /dev/null
@@ -0,0 +1,5 @@
+#...
+Program Headers:
+#...
+  LOAD           0x000000 0x00000000 0x00000000 0x08004 0x08004 R E 0x10000
+#...
diff --git a/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s
new file mode 100644 (file)
index 0000000..ac7c89f
--- /dev/null
@@ -0,0 +1,18 @@
+       .text
+       .section .text.noread
+       .arch armv6s-m
+       .syntax unified
+       .global _start
+       .thumb_func
+       .type   _start, %function
+_start:
+       bx lr
+
+       .text
+       .arch armv6s-m
+       .syntax unified
+       .global foo
+       .thumb_func
+       .type   foo, %function
+foo:
+       bx lr
diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-one-section.d b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.d
new file mode 100644 (file)
index 0000000..1faf40c
--- /dev/null
@@ -0,0 +1,5 @@
+#...
+Program Headers:
+#...
+  LOAD           0x000000 0x00000000 0x00000000 0x08002 0x08002   E 0x10000
+#...
diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-one-section.s b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.s
new file mode 100644 (file)
index 0000000..4be37d2
--- /dev/null
@@ -0,0 +1,9 @@
+       .text
+       .section .text.noread
+       .arch armv6s-m
+       .syntax unified
+       .global _start
+       .thumb_func
+       .type   _start, %function
+_start:
+       bx lr
diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-two-section.d b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.d
new file mode 100644 (file)
index 0000000..365cab0
--- /dev/null
@@ -0,0 +1,5 @@
+#...
+Program Headers:
+#...
+  LOAD           0x000000 0x00000000 0x00000000 0x08004 0x08004   E 0x10000
+#...
diff --git a/ld/testsuite/ld-arm/thumb1-noread-present-two-section.s b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.s
new file mode 100644 (file)
index 0000000..a97f379
--- /dev/null
@@ -0,0 +1,19 @@
+       .text
+       .section .text.noread.first
+       .arch armv6s-m
+       .syntax unified
+       .global _start
+       .thumb_func
+       .type   _start, %function
+_start:
+       bx lr
+
+       .text
+       .section .text.noread.second
+       .arch armv6s-m
+       .syntax unified
+       .global foo
+       .thumb_func
+       .type   foo, %function
+foo:
+       bx lr