This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] ARM: Add support for SHF_ARM_NOREAD section flag


Hi all,

  This is a proposal for a patch that implements the new arm section
flag SHF_ARM_NOREAD. Below is an excerpt of the section extracted
from 'Elf for the ARM architecture' draft version:

4.3.3 Section Attribute Flags
 The defined processor-specific section attribute flags are listed in
Table 4-5, Processor specific section attribute flags. All other
processor-specific values are reserved to future revisions of this
specification.

Table 4-5, Processor specific section attribute flags

Name            | Value            | Comment
------------------------------------------------------------------------
SHF_ARM_NOREAD  | 0x20000000       | The content of this section should
                |                  | not be read by program executor
------------------------------------------------------------------------

 If all the sections contained by a segment have the SHF_ARM_NOREAD
section attribute set, the PF_R attribute should be unset in the program
header for the segment.

This patch implements this feature in bfd.

 Unit tests have be written to check correct implementation.
 No regressions have been observed for arm-linux-gnueabi,
arm-linux-gnueabihf, arm-none-eabi, arm-none-nacl,
armeb-linux-gnueabihf, arm-netbsdelf and arm-vxworks targets
on 64-bit Linux host.

Changelogs:

include/ChangeLog:

2015-12-03 Mickael Guene <mickael.guene@st.com>

     * elf/arm.h: Add arm SHF_ARM_NOREAD section flag.

bfd/ChangeLog:

2015-12-03 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.

ld/testsuite/ChangeLog:

2015-12-03 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
>From c20c997bf2a2c9800f7d42fc616850e3fcce09c6 Mon Sep 17 00:00:00 2001
From: Mickael Guene <mickael.guene@st.com>
Date: Thu, 3 Dec 2015 07:59:09 +0100
Subject: [PATCH]  Add support for SHF_ARM_NOREAD section flag

 Catch section by name with .text.noread* pattern and apply
SHF_ARM_NOREAD section flag attribute to them.
 Only set PF_X attribute for segment if all sections in segment have
SHF_ARM_NOREAD flag.
 Support SHF_ARM_NOREAD string in INPUT_SECTION_FLAGS ld scripts.
---
 bfd/bfd-in2.h                                      |  3 ++
 bfd/elf32-arm.c                                    | 59 ++++++++++++++++++++++
 bfd/section.c                                      |  3 ++
 include/elf/arm.h                                  |  1 +
 ld/testsuite/ld-arm/arm-elf.exp                    | 12 +++++
 ld/testsuite/ld-arm/arm_noread.ld                  | 32 ++++++++++++
 .../ld-arm/thumb1-input-section-flag-match.d       |  6 +++
 .../ld-arm/thumb1-input-section-flag-match.s       | 18 +++++++
 .../thumb1-noread-not-present-mixing-two-section.d |  5 ++
 .../thumb1-noread-not-present-mixing-two-section.s | 18 +++++++
 .../ld-arm/thumb1-noread-present-one-section.d     |  5 ++
 .../ld-arm/thumb1-noread-present-one-section.s     |  9 ++++
 .../ld-arm/thumb1-noread-present-two-section.d     |  5 ++
 .../ld-arm/thumb1-noread-present-two-section.s     | 19 +++++++
 14 files changed, 195 insertions(+)
 create mode 100644 ld/testsuite/ld-arm/arm_noread.ld
 create mode 100644 ld/testsuite/ld-arm/thumb1-input-section-flag-match.d
 create mode 100644 ld/testsuite/ld-arm/thumb1-input-section-flag-match.s
 create mode 100644 ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d
 create mode 100644 ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s
 create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-one-section.d
 create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-one-section.s
 create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-two-section.d
 create mode 100644 ld/testsuite/ld-arm/thumb1-noread-present-two-section.s

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index bca5181..354c778 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1413,6 +1413,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.  */
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 9fd5720..58a4bcd 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -14691,6 +14691,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);
 
@@ -14716,6 +14717,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
@@ -14767,6 +14788,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;
 }
 
@@ -16135,6 +16160,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
@@ -16212,6 +16264,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.  */
diff --git a/bfd/section.c b/bfd/section.c
index b27539a..20dd76f 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -350,6 +350,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.  *}
diff --git a/include/elf/arm.h b/include/elf/arm.h
index 34afdfd..c6289f6 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -83,6 +83,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.  */
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 3c8cc68..595d9dc 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -277,6 +277,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
index 0000000..3ff17bc
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm_noread.ld
@@ -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
index 0000000..e25a4f4
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.d
@@ -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
index 0000000..ac7c89f
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-input-section-flag-match.s
@@ -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
index 0000000..9150576
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.d
@@ -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
index 0000000..ac7c89f
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-noread-not-present-mixing-two-section.s
@@ -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
index 0000000..1faf40c
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.d
@@ -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
index 0000000..4be37d2
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-noread-present-one-section.s
@@ -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
index 0000000..365cab0
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.d
@@ -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
index 0000000..a97f379
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-noread-present-two-section.s
@@ -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
-- 
2.6.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]