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]

[RFC PATCH, binutils, ARM 3/9] Allow stubs without associated input section in ARM backend


Hi,

[Posting patch series as RFC]

This patch is part of a patch series to add support for ARMv8-M security extension[1] to GNU ld. This specific patch allows stubs to not be associated by an input section, as required for creating Secure Gateway veneers. This is achieved by letting the bfd ARM backend specify the output section for a veneer input section.


[1] Software requirements for ARMv8-M security extension are described in document ARM-ECM-0359818 [2]
[2] Available on http://infocenter.arm.com in Developer guides and articles > Software development > ARMÂv8-M Security Extensions: Requirements on Development Tools

ChangeLog entries are as follow:


*** bfd/ChangeLog ***

2015-12-16  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * bfd-in.h (elf32_arm_size_stubs): Add an output section parameter.
        * bfd-in2.h: Regenerated.
        * elf32-arm.c (struct elf32_arm_link_hash_table): Add an output section
        parameter to add_stub_section callback.
        (elf32_arm_create_or_find_stub_sec): Get output section from link_sec
        and pass it down to add_stub_section.
        (elf32_arm_add_stub): Set section to stub_sec if NULL before using it
        for error message.
        (elf32_arm_size_stubs): Add output section parameter to
        add_stub_section function pointer parameter.


*** ld/ChangeLog ***

2015-12-16  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * emultempl/armelf.em (elf32_arm_add_stub_section): Add output_section
        parameter and rename input_section parameter to after_input_section.
        Append input stub section to the output section if after_input_section
        is NULL.


diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 1721ce7003d4a76953793b002583997e438e3cb0..7abc05878789788bc9d5a9329dc92d80a0346935 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -934,7 +934,8 @@ extern void elf32_arm_next_input_section
   (struct bfd_link_info *, struct bfd_section *);
 extern bfd_boolean elf32_arm_size_stubs
   (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
-   struct bfd_section * (*) (const char *, struct bfd_section *, unsigned int),
+   struct bfd_section * (*) (const char *, struct bfd_section *,
+			     struct bfd_section *, unsigned int),
    void (*) (void));
 extern bfd_boolean elf32_arm_build_stubs
   (struct bfd_link_info *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 606d11b73c783ae54728e7f9f2fd90c00f7617b7..87ee56b80b2a1a0ae785ff4cb2495e2c7fd23a47 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -941,7 +941,8 @@ extern void elf32_arm_next_input_section
   (struct bfd_link_info *, struct bfd_section *);
 extern bfd_boolean elf32_arm_size_stubs
   (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
-   struct bfd_section * (*) (const char *, struct bfd_section *, unsigned int),
+   struct bfd_section * (*) (const char *, struct bfd_section *,
+			     struct bfd_section *, unsigned int),
    void (*) (void));
 extern bfd_boolean elf32_arm_build_stubs
   (struct bfd_link_info *);
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e6afb99512524ac26c0e3842e8dbe293c58bacad..8450733016a496ec34533e8aad4900be16dc5849 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3103,7 +3103,8 @@ struct elf32_arm_link_hash_table
   bfd *stub_bfd;
 
   /* Linker call-backs.  */
-  asection * (*add_stub_section) (const char *, asection *, unsigned int);
+  asection * (*add_stub_section) (const char *, asection *, asection *,
+				  unsigned int);
   void (*layout_sections_again) (void);
 
   /* Array to keep track of which stub sections have been created, and
@@ -4068,6 +4069,7 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
 {
   asection *link_sec;
   asection *stub_sec;
+  asection *out_sec;
 
   link_sec = htab->stub_group[section->id].link_sec;
   BFD_ASSERT (link_sec != NULL);
@@ -4090,7 +4092,8 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
 
 	  memcpy (s_name, link_sec->name, namelen);
 	  memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
-	  stub_sec = (*htab->add_stub_section) (s_name, link_sec,
+	  out_sec = link_sec->output_section;
+	  stub_sec = (*htab->add_stub_section) (s_name, out_sec, link_sec,
 						htab->nacl_p ? 4 : 3);
 	  if (stub_sec == NULL)
 	    return NULL;
@@ -4126,6 +4129,8 @@ elf32_arm_add_stub (const char *stub_name,
 				     TRUE, FALSE);
   if (stub_entry == NULL)
     {
+      if (section == NULL)
+	section = stub_sec;
       (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
 			     section->owner,
 			     stub_name);
@@ -5140,6 +5145,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 		      struct bfd_link_info *info,
 		      bfd_signed_vma group_size,
 		      asection * (*add_stub_section) (const char *, asection *,
+						      asection *,
 						      unsigned int),
 		      void (*layout_sections_again) (void))
 {
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 2931a49f3fb0fee2a035d0788ead7726eab83d10..a3b52e685fcd2d415737f3ee9ed461978a2419f6 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -203,12 +203,12 @@ hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
 
 static asection *
 elf32_arm_add_stub_section (const char * stub_sec_name,
-			    asection *   input_section,
+			    asection *   output_section,
+			    asection *   after_input_section,
 			    unsigned int alignment_power)
 {
   asection *stub_sec;
   flagword flags;
-  asection *output_section;
   lang_output_section_statement_type *os;
   struct hook_stub_info info;
 
@@ -221,18 +221,34 @@ elf32_arm_add_stub_section (const char * stub_sec_name,
 
   bfd_set_section_alignment (stub_file->the_bfd, stub_sec, alignment_power);
 
-  output_section = input_section->output_section;
   os = lang_output_section_get (output_section);
 
-  info.input_section = input_section;
+  info.input_section = after_input_section;
   lang_list_init (&info.add);
   lang_add_section (&info.add, stub_sec, NULL, os);
 
   if (info.add.head == NULL)
     goto err_ret;
 
-  if (hook_in_stub (&info, &os->children.head))
-    return stub_sec;
+  if (after_input_section == NULL)
+    {
+      lang_statement_union_type **lp = &os->children.head;
+      lang_statement_union_type *l, *lprev = NULL;
+
+      for (; (l = *lp) != NULL; lp = &l->header.next, lprev = l);
+
+      if (lprev)
+	lprev->header.next = info.add.head;
+      else
+	os->children.head = info.add.head;
+
+      return stub_sec;
+    }
+  else
+    {
+      if (hook_in_stub (&info, &os->children.head))
+	return stub_sec;
+    }
 
  err_ret:
   einfo ("%X%P: can not make stub section: %E\n");


The patch doesn't show any regression when running the binutils-gdb testsuite for the arm-none-eabi target.

Any comments?

Best regards,

Thomas


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