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]

Re: linker stub symbols for ELF32 secured ABI


On Sun, Dec 04, 2005 at 03:31:25PM +0200, Yaakov Yaari wrote:
> Hi Alan,
> A while ago I asked you to add linker stub symbols for ELF64.  The form of
> such symbols is <address>.<linker stub type>.<target func name>
> This was implemented in the linker that came with RHEL4.
> >From looking at the code generated by the 20050923 tool chain it seems this
> is not implemented for ELF32 secured ABI.
> Can you fix that?

Sure.  Let me know if the names I chose here are bad for some reason.
If OK, I'll commit this patch.

bfd/
	* elf32-ppc.c (struct ppc_elf_link_hash_table): Add emit_stub_syms.
	(ppc_elf_select_plt_layout): Add emit_stub_syms param, save to htab.
	(add_stub_sym): New function.
	(allocate_dynrelocs): Call add_stub_sym.
	(ppc_elf_size_dynamic_sections): Emit __glink and __glink_PLTresolve
	when emit_stub_syms.
	* elf32-ppc.h (ppc_elf_select_plt_layout): Update prototype.
ld/
	* emultempl/ppc32elf.em (emit_stub_syms): New var.
	(ppc_after_open): Pass it to ppc_elf_select_plt_layout.
	(PARSE_AND_LIST_PROLOGUE <OPTION_STUBSYMS>): Define.
	(PARSE_AND_LIST_LONGOPTS): Add emit-stub-syms.
	(PARSE_AND_LIST_OPTIONS): Describe emit-stub-syms.
	(PARSE_AND_LIST_OPTIONS): Handle it.

Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.183
diff -u -p -r1.183 elf32-ppc.c
--- bfd/elf32-ppc.c	25 Oct 2005 16:19:06 -0000	1.183
+++ bfd/elf32-ppc.c	5 Dec 2005 13:17:49 -0000
@@ -2353,6 +2353,9 @@ struct ppc_elf_link_hash_table
   unsigned int new_plt:1;
   unsigned int old_plt:1;
 
+  /* Set if we should emit symbols for stubs.  */
+  unsigned int emit_stub_syms:1;
+
   /* Small local sym to section mapping cache.  */
   struct sym_sec_cache sym_sec;
 
@@ -3593,7 +3596,8 @@ ppc_elf_merge_private_bfd_data (bfd *ibf
 int
 ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
 			   struct bfd_link_info *info,
-			   int force_old_plt)
+			   int force_old_plt,
+			   int emit_stub_syms)
 {
   struct ppc_elf_link_hash_table *htab;
   flagword flags;
@@ -3602,6 +3606,8 @@ ppc_elf_select_plt_layout (bfd *output_b
   if (force_old_plt || !htab->new_plt)
     htab->old_plt = 1;
 
+  htab->emit_stub_syms = emit_stub_syms;
+
   if (htab->is_vxworks)
     {
       /* The VxWorks PLT is a loaded section with contents.  */
@@ -4207,6 +4213,51 @@ ppc_elf_adjust_dynamic_symbol (struct bf
   return TRUE;
 }
 
+/* Generate a symbol to mark plt call stubs, of the form
+   xxxxxxxx_plt_call_<callee> where xxxxxxxx is a hex number, usually 0,
+   specifying the addend on the plt relocation, or for -fPIC,
+   xxxxxxxx.got2_plt_call_<callee>.  */
+
+static bfd_boolean
+add_stub_sym (struct plt_entry *ent,
+	      struct elf_link_hash_entry *h,
+	      struct ppc_elf_link_hash_table *htab)
+{
+  struct elf_link_hash_entry *sh;
+  size_t len1, len2, len3;
+  char *name;
+
+  len1 = strlen (h->root.root.string);
+  len2 = sizeof ("plt_call_") - 1;
+  len3 = 0;
+  if (ent->sec)
+    len3 = strlen (ent->sec->name);
+  name = bfd_malloc (len1 + len2 + len3 + 10);
+  if (name == NULL)
+    return FALSE;
+  sprintf (name, "%08x", (unsigned) ent->addend & 0xffffffff);
+  if (ent->sec)
+    memcpy (name + 8, ent->sec->name, len3);
+  name[len3 + 8] = '_';
+  memcpy (name + len3 + 9, "plt_call_", len2);
+  memcpy (name + len3 + 9 + len2, h->root.root.string, len1 + 1);
+  sh = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+  if (sh == NULL)
+    return FALSE;
+  if (sh->root.type == bfd_link_hash_new)
+    {
+      sh->root.type = bfd_link_hash_defined;
+      sh->root.u.def.section = htab->glink;
+      sh->root.u.def.value = ent->glink_offset;
+      sh->ref_regular = 1;
+      sh->def_regular = 1;
+      sh->ref_regular_nonweak = 1;
+      sh->forced_local = 1;
+      sh->non_elf = 0;
+    }
+  return TRUE;
+}
+
 /* Allocate NEED contiguous space in .got, and return the offset.
    Handles allocation of the got header when crossing 32k.  */
 
@@ -4308,6 +4359,10 @@ allocate_dynrelocs (struct elf_link_hash
 			h->root.u.def.value = glink_offset;
 		      }
 		    ent->glink_offset = glink_offset;
+
+		    if (htab->emit_stub_syms
+			&& !add_stub_sym (ent, h, htab))
+		      return FALSE;
 		  }
 		else
 		  {
@@ -4747,6 +4802,41 @@ ppc_elf_size_dynamic_sections (bfd *outp
       /* Pad out to align the start of PLTresolve.  */
       htab->glink->size += -htab->glink->size & 15;
       htab->glink->size += GLINK_PLTRESOLVE;
+
+      if (htab->emit_stub_syms)
+	{
+	  struct elf_link_hash_entry *sh;
+	  sh = elf_link_hash_lookup (&htab->elf, "__glink",
+				     TRUE, FALSE, FALSE);
+	  if (sh == NULL)
+	    return FALSE;
+	  if (sh->root.type == bfd_link_hash_new)
+	    {
+	      sh->root.type = bfd_link_hash_defined;
+	      sh->root.u.def.section = htab->glink;
+	      sh->root.u.def.value = htab->glink_pltresolve;
+	      sh->ref_regular = 1;
+	      sh->def_regular = 1;
+	      sh->ref_regular_nonweak = 1;
+	      sh->forced_local = 1;
+	      sh->non_elf = 0;
+	    }
+	  sh = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
+				     TRUE, FALSE, FALSE);
+	  if (sh == NULL)
+	    return FALSE;
+	  if (sh->root.type == bfd_link_hash_new)
+	    {
+	      sh->root.type = bfd_link_hash_defined;
+	      sh->root.u.def.section = htab->glink;
+	      sh->root.u.def.value = htab->glink->size - GLINK_PLTRESOLVE;
+	      sh->ref_regular = 1;
+	      sh->def_regular = 1;
+	      sh->ref_regular_nonweak = 1;
+	      sh->forced_local = 1;
+	      sh->non_elf = 0;
+	    }
+	}
     }
 
   /* We've now determined the sizes of the various dynamic sections.
Index: bfd/elf32-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.h,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-ppc.h
--- bfd/elf32-ppc.h	16 Jul 2005 03:30:23 -0000	1.8
+++ bfd/elf32-ppc.h	5 Dec 2005 13:17:49 -0000
@@ -17,7 +17,7 @@ You should have received a copy of the G
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *, int);
+int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *, int, int);
 asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *);
 bfd_boolean ppc_elf_tls_optimize (bfd *, struct bfd_link_info *);
 void ppc_elf_set_sdata_syms (bfd *, struct bfd_link_info *);
Index: ld/emultempl/ppc32elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc32elf.em,v
retrieving revision 1.10
diff -u -p -r1.10 ppc32elf.em
--- ld/emultempl/ppc32elf.em	4 Aug 2005 06:22:13 -0000	1.10
+++ ld/emultempl/ppc32elf.em	5 Dec 2005 13:17:49 -0000
@@ -41,6 +41,9 @@ is_ppc_elf32_vec(const bfd_target * vec)
 /* Whether to run tls optimization.  */
 static int notlsopt = 0;
 
+/* Whether to emit symbols for stubs.  */
+static int emit_stub_syms = 0;
+
 /* Chooses the correct place for .plt and .got.  */
 static int old_plt = 0;
 static int old_got = 0;
@@ -58,7 +61,9 @@ ppc_after_open (void)
       lang_output_section_statement_type *plt_os[2];
       lang_output_section_statement_type *got_os[2];
 
-      new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt);
+      emit_stub_syms |= link_info.emitrelocations;
+      new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt,
+					   emit_stub_syms);
       if (new_plt < 0)
 	einfo ("%X%P: select_plt_layout problem %E\n");
 
@@ -126,9 +131,11 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_NO_TLS_OPT		301
 #define OPTION_OLD_PLT			302
 #define OPTION_OLD_GOT			303
+#define OPTION_STUBSYMS			304
 '
 
 PARSE_AND_LIST_LONGOPTS='
+  { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
   { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
   { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
   { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },
@@ -136,6 +143,7 @@ PARSE_AND_LIST_LONGOPTS='
 
 PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("\
+  --emit-stub-syms      Label linker stubs with a symbol.\n\
   --no-tls-optimize     Don'\''t try to optimize TLS accesses.\n\
   --bss-plt             Force old-style BSS PLT.\n\
   --sdata-got           Force GOT location just before .sdata.\n"
@@ -143,6 +151,10 @@ PARSE_AND_LIST_OPTIONS='
 '
 
 PARSE_AND_LIST_ARGS_CASES='
+    case OPTION_STUBSYMS:
+      emit_stub_syms = 1;
+      break;
+
     case OPTION_NO_TLS_OPT:
       notlsopt = 1;
       break;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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