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 PLT mapping symbols


The attached patch makes ld output Arm mapping symbols for the PLT.

I couldn't find a convenient way of adding local symbols to the hash table so 
I've added a hook to add them directly to the output symbol table.

The documentation for elf_backend_output_arch_syms suggests that it may be 
suitable for outputting local symbols. However it turns out the actual 
implementation differs from the behavior described in the comment. This 
callback is actually invoked after all symbols have been output. The only 
user of this hook (elf64-sparc) appears to rely on this behavior. I have 
added a new elf_backend_output_arch_local_syms hook and fixed the 
documentation of the old hook.

The testsuite changes are because the extra mapping symbols make objdump pick 
a different symbol. AFAICS There's neither the before or after answers are 
particularly good so I've adjusted the expected output.

Tested with cross to arm-none-eabi.
Ok?

Paul

2006-05-17  Paul Brook  <paul@codesourcery.com>

bfd/
	* elf-bfd.h (elf_backend_data): Add elf_backend_output_arch_local_syms
	* elf32-arm.c (output_arch_syminfo): Define.
	(elf32_arm_ouput_plt_map_sym, elf32_arm_output_plt_map,
	elf32_arm_output_arch_local_syms): New functions.
	(elf_backend_output_arch_local_syms): Define.
	* elflink.c (bfd_elf_final_link): Call
	elf_backend_output_arch_local_syms.
	* elfxx-target.h (elf_backend_output_arch_local_syms): Provide default
	definition.
	(elfNN_bed): Add elf_backend_output_arch_local_syms.
ld/testsuite/
	* ld-arm/arm-app-abs32.d: Update expected output.
	* ld-arm/arm-app.d: Ditto.
	* ld-arm/arm-lib-plt32.d: Ditto.
	* ld-arm/arm-lib.d: Ditto.
	* ld-arm/mixed-app-v5.d: Ditto.
	* ld-arm/mixed-app.d: Ditto.
	* ld-arm/mixed-lib.d: Ditto.
Index: bfd/elf-bfd.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf-bfd.h,v
retrieving revision 1.205
diff -u -p -r1.205 elf-bfd.h
--- bfd/elf-bfd.h	16 Mar 2006 12:20:15 -0000	1.205
+++ bfd/elf-bfd.h	17 May 2006 14:53:00 -0000
@@ -865,8 +865,16 @@ struct elf_backend_data
 
   /* This function, if defined, is called after all local symbols and
      global symbols converted to locals are emitted into the symtab
-     section.  It allows the backend to emit special global symbols
+     section.  It allows the backend to emit special local symbols
      not handled in the hash table.  */
+  bfd_boolean (*elf_backend_output_arch_local_syms)
+    (bfd *, struct bfd_link_info *, void *,
+     bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *,
+		      struct elf_link_hash_entry *));
+
+  /* This function, if defined, is called after all symbols are emitted
+     into the symtab section.  It allows the backend to emit special
+     global symbols not handled in the hash table.  */
   bfd_boolean (*elf_backend_output_arch_syms)
     (bfd *, struct bfd_link_info *, void *,
      bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *,
Index: bfd/elf32-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf32-arm.c,v
retrieving revision 1.75
diff -u -p -r1.75 elf32-arm.c
--- bfd/elf32-arm.c	15 May 2006 19:57:34 -0000	1.75
+++ bfd/elf32-arm.c	17 May 2006 15:22:21 -0000
@@ -7908,6 +7908,174 @@ elf32_arm_output_symbol_hook (struct bfd
   return TRUE;
 }
 
+typedef struct
+{
+  PTR finfo;
+  struct bfd_link_info *info;
+  int plt_shndx;
+  bfd_vma plt_offset;
+  bfd_boolean (*func) (PTR, const char *, Elf_Internal_Sym *,
+		       asection *, struct elf_link_hash_entry *);
+} output_arch_syminfo;
+
+enum map_symbol_type
+{
+  ARM_MAP_ARM,
+  ARM_MAP_THUMB,
+  ARM_MAP_DATA
+};
+
+
+/* Output a single PLT mapping symbol.  */
+
+static bfd_boolean
+elf32_arm_ouput_plt_map_sym (output_arch_syminfo *osi,
+			     enum map_symbol_type type,
+			     bfd_vma offset)
+{
+  static const char *names[3] = {"$a", "$t", "$d"};
+  struct elf32_arm_link_hash_table *htab;
+  Elf_Internal_Sym sym;
+
+  htab = elf32_arm_hash_table (osi->info);
+  sym.st_value = osi->plt_offset + offset;
+  sym.st_size = 0;
+  sym.st_other = 0;
+  sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
+  sym.st_shndx = osi->plt_shndx;
+  if (!osi->func (osi->finfo, names[type], &sym, htab->splt, NULL))
+    return FALSE;
+  return TRUE;
+}
+
+
+/* Output mapping symbols for PLT entries associated with H.  */
+
+static bfd_boolean
+elf32_arm_output_plt_map (struct elf_link_hash_entry *h, PTR inf)
+{
+  output_arch_syminfo *osi = (output_arch_syminfo *) inf;
+  struct elf32_arm_link_hash_table *htab;
+  struct elf32_arm_link_hash_entry *eh;
+  bfd_vma addr;
+
+  htab = elf32_arm_hash_table (osi->info);
+
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
+
+  if (h->root.type == bfd_link_hash_warning)
+    /* When warning symbols are created, they **replace** the "real"
+       entry in the hash table, thus we never get to see the real
+       symbol in a hash traversal.  So look at it now.  */
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+  if (h->plt.offset == (bfd_vma) -1)
+    return TRUE;
+
+  eh = (struct elf32_arm_link_hash_entry *) h;
+  addr = h->plt.offset;
+  if (htab->symbian_p)
+    {
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+	return FALSE;
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 4))
+	return FALSE;
+    }
+  else if (htab->vxworks_p)
+    {
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+	return FALSE;
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 8))
+	return FALSE;
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr + 12))
+	return FALSE;
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 20))
+	return FALSE;
+    }
+  else
+    {
+      bfd_boolean thumb_stub;
+
+      thumb_stub = eh->plt_thumb_refcount > 0 && !htab->use_blx;
+      if (thumb_stub)
+	{
+	  if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_THUMB, addr - 4))
+	    return FALSE;
+	}
+#ifdef FOUR_WORD_PLT
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+	return FALSE;
+      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 12))
+	return FALSE;
+#else
+      /* A three-word PLT with no Thumb thunk contains only Arm code, 
+	 so only need to output a mapping symbol for the first PLT entry and
+	 entries with thumb thunks.  */
+      if (thumb_stub || addr == 20)
+	{
+	  if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+	    return FALSE;
+	}
+#endif
+    }
+
+  return TRUE;
+}
+
+
+/* Output mapping symbols for the PLT.  */
+
+static bfd_boolean
+elf32_arm_output_arch_local_syms (bfd *output_bfd,
+    struct bfd_link_info *info,
+    PTR finfo, bfd_boolean (*func) (PTR, const char *,
+				    Elf_Internal_Sym *,
+				    asection *,
+				    struct elf_link_hash_entry *))
+{
+  output_arch_syminfo osi;
+  struct elf32_arm_link_hash_table *htab;
+
+  htab = elf32_arm_hash_table (info);
+  if (!htab->splt || htab->splt->size == 0)
+    return TRUE;
+
+  check_use_blx(htab);
+  osi.finfo = finfo;
+  osi.info = info;
+  osi.func = func;
+  osi.plt_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
+      htab->splt->output_section);
+  osi.plt_offset = htab->splt->output_section->vma;
+
+  /* Output mapping symbols for the plt header.  SymbianOS does not have a
+     plt header.  */
+  if (htab->vxworks_p)
+    {
+      /* VxWorks shared libraries have no PLT header.  */
+      if (!info->shared)
+	{
+	  if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0))
+	    return FALSE;
+	  if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_DATA, 12))
+	    return FALSE;
+	}
+    }
+  else if (!htab->symbian_p)
+    {
+      if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0))
+	return FALSE;
+#ifndef FOUR_WORD_PLT
+      if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_DATA, 16))
+	return FALSE;
+#endif
+    }
+
+  elf_link_hash_traverse (&htab->root, elf32_arm_output_plt_map, (PTR) &osi);
+  return TRUE;
+}
+
 /* Allocate target specific section data.  */
 
 static bfd_boolean
@@ -8238,6 +8406,8 @@ const struct elf_size_info elf32_arm_siz
 #define elf_backend_modify_segment_map		elf32_arm_modify_segment_map
 #define elf_backend_additional_program_headers \
   elf32_arm_additional_program_headers
+#define elf_backend_output_arch_local_syms \
+  elf32_arm_output_arch_local_syms
 
 #define elf_backend_can_refcount    1
 #define elf_backend_can_gc_sections 1
Index: bfd/elflink.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elflink.c,v
retrieving revision 1.213
diff -u -p -r1.213 elflink.c
--- bfd/elflink.c	11 May 2006 15:55:40 -0000	1.213
+++ bfd/elflink.c	16 May 2006 23:32:26 -0000
@@ -8300,6 +8300,19 @@ bfd_elf_final_link (bfd *abfd, struct bf
   if (eoinfo.failed)
     return FALSE;
 
+  /* If backend needs to output some local symbols not present in the hash
+     table, do it now.  */
+  if (bed->elf_backend_output_arch_local_syms)
+    {
+      typedef bfd_boolean (*out_sym_func)
+	(void *, const char *, Elf_Internal_Sym *, asection *,
+	 struct elf_link_hash_entry *);
+
+      if (! ((*bed->elf_backend_output_arch_local_syms)
+	     (abfd, info, &finfo, (out_sym_func) elf_link_output_sym)))
+	return FALSE;
+    }
+
   /* That wrote out all the local symbols.  Finish up the symbol table
      with the global symbols. Even if we want to strip everything we
      can, we still need to deal with those global symbols that got
Index: bfd/elfxx-target.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elfxx-target.h,v
retrieving revision 1.93
diff -u -p -r1.93 elfxx-target.h
--- bfd/elfxx-target.h	25 Apr 2006 17:46:15 -0000	1.93
+++ bfd/elfxx-target.h	17 May 2006 13:47:03 -0000
@@ -413,6 +413,9 @@
 #ifndef elf_backend_print_symbol_all
 #define elf_backend_print_symbol_all		NULL
 #endif
+#ifndef elf_backend_output_arch_local_syms
+#define elf_backend_output_arch_local_syms	NULL
+#endif
 #ifndef elf_backend_output_arch_syms
 #define elf_backend_output_arch_syms		NULL
 #endif
@@ -600,6 +603,7 @@ static const struct elf_backend_data elf
   elf_backend_gc_sweep_hook,
   elf_backend_post_process_headers,
   elf_backend_print_symbol_all,
+  elf_backend_output_arch_local_syms,
   elf_backend_output_arch_syms,
   elf_backend_copy_indirect_symbol,
   elf_backend_hide_symbol,
Index: ld/testsuite/ld-arm/arm-app-abs32.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-app-abs32.d,v
retrieving revision 1.3
diff -u -p -r1.3 arm-app-abs32.d
--- ld/testsuite/ld-arm/arm-app-abs32.d	30 Mar 2005 16:22:07 -0000	1.3
+++ ld/testsuite/ld-arm/arm-app-abs32.d	16 May 2006 19:37:35 -0000
@@ -8,7 +8,7 @@ Disassembly of section .plt:
 
 .* <.plt>:
     .*:	e52de004 	str	lr, \[sp, #-4\]!
-    .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <_start-0x10>
+    .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <\.plt\+0x10>
     .*:	e08fe00e 	add	lr, pc, lr
     .*:	e5bef008 	ldr	pc, \[lr, #8\]!
     .*:	.* 	.*
Index: ld/testsuite/ld-arm/arm-app.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-app.d,v
retrieving revision 1.3
diff -u -p -r1.3 arm-app.d
--- ld/testsuite/ld-arm/arm-app.d	30 Mar 2005 16:22:07 -0000	1.3
+++ ld/testsuite/ld-arm/arm-app.d	16 May 2006 19:37:25 -0000
@@ -8,7 +8,7 @@ Disassembly of section .plt:
 
 .* <.plt>:
  .*:	e52de004 	str	lr, \[sp, #-4\]!
- .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <_start-0x10>
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <\.plt\+0x10>
  .*:	e08fe00e 	add	lr, pc, lr
  .*:	e5bef008 	ldr	pc, \[lr, #8\]!
  .*:	.*
@@ -27,7 +27,7 @@ Disassembly of section .text:
 .* <app_func>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
- .*:	ebfffff4 	bl	.* <_start-0xc>
+ .*:	ebfffff4 	bl	.* <.text-0xc>
  .*:	e89d6800 	ldmia	sp, {fp, sp, lr}
  .*:	e12fff1e 	bx	lr
 
Index: ld/testsuite/ld-arm/arm-lib-plt32.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-lib-plt32.d,v
retrieving revision 1.2
diff -u -p -r1.2 arm-lib-plt32.d
--- ld/testsuite/ld-arm/arm-lib-plt32.d	17 Nov 2004 17:50:27 -0000	1.2
+++ ld/testsuite/ld-arm/arm-lib-plt32.d	16 May 2006 19:37:22 -0000
@@ -8,7 +8,7 @@ Disassembly of section .plt:
 
 .* <.plt>:
  .*:	e52de004 	str	lr, \[sp, #-4\]!
- .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <lib_func1-0x10>
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <\.plt\+0x10>
  .*:	e08fe00e 	add	lr, pc, lr
  .*:	e5bef008 	ldr	pc, \[lr, #8\]!
  .*:	.*
@@ -20,7 +20,7 @@ Disassembly of section .text:
 .* <lib_func1>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
- .*:	ebfffff9 	bl	.* <lib_func1-0xc>
+ .*:	ebfffff9 	bl	.* <.text-0xc>
  .*:	e89d6800 	ldmia	sp, {fp, sp, lr}
  .*:	e12fff1e 	bx	lr
 
Index: ld/testsuite/ld-arm/arm-lib.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/arm-lib.d,v
retrieving revision 1.3
diff -u -p -r1.3 arm-lib.d
--- ld/testsuite/ld-arm/arm-lib.d	17 Nov 2004 17:50:27 -0000	1.3
+++ ld/testsuite/ld-arm/arm-lib.d	16 May 2006 19:37:19 -0000
@@ -8,7 +8,7 @@ Disassembly of section .plt:
 
 .* <.plt>:
  .*:	e52de004 	str	lr, \[sp, #-4\]!
- .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <lib_func1-0x10>
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <\.plt\+0x10>
  .*:	e08fe00e 	add	lr, pc, lr
  .*:	e5bef008 	ldr	pc, \[lr, #8\]!
  .*:	.*
@@ -20,7 +20,7 @@ Disassembly of section .text:
 .* <lib_func1>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
- .*:	ebfffff9 	bl	.* <lib_func1-0xc>
+ .*:	ebfffff9 	bl	.* <.text-0xc>
  .*:	e89d6800 	ldmia	sp, {fp, sp, lr}
  .*:	e12fff1e 	bx	lr
 
Index: ld/testsuite/ld-arm/mixed-app-v5.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/mixed-app-v5.d,v
retrieving revision 1.1
diff -u -p -r1.1 mixed-app-v5.d
--- ld/testsuite/ld-arm/mixed-app-v5.d	12 Dec 2005 17:03:40 -0000	1.1
+++ ld/testsuite/ld-arm/mixed-app-v5.d	16 May 2006 19:37:57 -0000
@@ -8,7 +8,7 @@ Disassembly of section .plt:
 
 .* <.plt>:
  .*:	e52de004 	str	lr, \[sp, #-4\]!
- .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <_start-0x20>
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <\.plt\+0x10>
  .*:	e08fe00e 	add	lr, pc, lr
  .*:	e5bef008 	ldr	pc, \[lr, #8\]!
  .*:	.*
@@ -48,7 +48,7 @@ Disassembly of section .text:
 
 .* <app_tfunc>:
  .*:	b500      	push	{lr}
- .*:	f7ff efc. 	blx	.* <_start-0x..>
+ .*:	f7ff efc. 	blx	.* <.text-0x..>
  .*:	bd00      	pop	{pc}
  .*:	4770      	bx	lr
  .*:	46c0      	nop			\(mov r8, r8\)
Index: ld/testsuite/ld-arm/mixed-app.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/mixed-app.d,v
retrieving revision 1.4
diff -u -p -r1.4 mixed-app.d
--- ld/testsuite/ld-arm/mixed-app.d	15 Aug 2005 15:39:44 -0000	1.4
+++ ld/testsuite/ld-arm/mixed-app.d	16 May 2006 19:39:46 -0000
@@ -8,7 +8,7 @@ Disassembly of section .plt:
 
 .* <.plt>:
  .*:	e52de004 	str	lr, \[sp, #-4\]!
- .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <_start-0x20>
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <\.plt\+0x10>
  .*:	e08fe00e 	add	lr, pc, lr
  .*:	e5bef008 	ldr	pc, \[lr, #8\]!
  .*:	.*
@@ -49,7 +49,7 @@ Disassembly of section .text:
 
 .* <app_tfunc>:
  .*:	b500      	push	{lr}
- .*:	f7ff ffc. 	bl	.* <_start-0x..>
+ .*:	f7ff ffc. 	bl	.* <.text-0x..>
  .*:	bd00      	pop	{pc}
  .*:	4770      	bx	lr
  .*:	46c0      	nop			\(mov r8, r8\)
Index: ld/testsuite/ld-arm/mixed-lib.d
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/testsuite/ld-arm/mixed-lib.d,v
retrieving revision 1.1
diff -u -p -r1.1 mixed-lib.d
--- ld/testsuite/ld-arm/mixed-lib.d	17 Nov 2004 17:50:27 -0000	1.1
+++ ld/testsuite/ld-arm/mixed-lib.d	16 May 2006 19:37:38 -0000
@@ -8,7 +8,7 @@ Disassembly of section .plt:
 
 .* <.plt>:
  .*:	e52de004 	str	lr, \[sp, #-4\]!
- .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <lib_func1-0x1.>
+ .*:	e59fe004 	ldr	lr, \[pc, #4\]	; .* <\.plt\+0x10>
  .*:	e08fe00e 	add	lr, pc, lr
  .*:	e5bef008 	ldr	pc, \[lr, #8\]!
  .*:	.*
@@ -20,7 +20,7 @@ Disassembly of section .text:
 .* <lib_func1>:
  .*:	e1a0c00d 	mov	ip, sp
  .*:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
- .*:	ebfffff. 	bl	.* <lib_func1-0x..>
+ .*:	ebfffff. 	bl	.* <.text-0x..>
  .*:	e89d6800 	ldmia	sp, {fp, sp, lr}
  .*:	e12fff1e 	bx	lr
  .*:	e1a00000 	nop			\(mov r0,r0\)

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