_SPUEAR_ absolute symbols

Alan Modra amodra@bigpond.net.au
Mon Apr 7 13:08:00 GMT 2008


_SPUEAR_ symbols were originally designed to access SPU function
symbols.  It seems that people would like to use them on other
symbols, such as absolute ones.  This led to segfaults as ld wasn't
prepared to deal with such symbols.

	* elf32-spu.c (allocate_spuear_stubs): Ensure _SPUEAR_ symbol
	is defined in overlay section before creating a stub.
	(build_spuear_stubs): Likewise.
	(spu_elf_size_stubs, spu_elf_build_stubs): Adjust calls.

Index: bfd/elf32-spu.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-spu.c,v
retrieving revision 1.36
diff -u -p -r1.36 elf32-spu.c
--- bfd/elf32-spu.c	1 Apr 2008 23:52:00 -0000	1.36
+++ bfd/elf32-spu.c	7 Apr 2008 12:26:55 -0000
@@ -1008,13 +1008,21 @@ allocate_spuear_stubs (struct elf_link_h
 {
   /* Symbols starting with _SPUEAR_ need a stub because they may be
      invoked by the PPU.  */
+  struct bfd_link_info *info = inf;
+  struct spu_link_hash_table *htab = spu_hash_table (info);
+  asection *sym_sec;
+
   if ((h->root.type == bfd_link_hash_defined
        || h->root.type == bfd_link_hash_defweak)
       && h->def_regular
-      && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
+      && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0
+      && (sym_sec = h->root.u.def.section) != NULL
+      && sym_sec->output_section != NULL
+      && sym_sec->output_section->owner == info->output_bfd
+      && spu_elf_section_data (sym_sec->output_section) != NULL
+      && (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index != 0
+	  || htab->non_overlay_stubs))
     {
-      struct spu_link_hash_table *htab = inf;
-
       count_stub (htab, NULL, NULL, nonovl_stub, h, NULL);
     }
   
@@ -1026,15 +1034,23 @@ build_spuear_stubs (struct elf_link_hash
 {
   /* Symbols starting with _SPUEAR_ need a stub because they may be
      invoked by the PPU.  */
+  struct bfd_link_info *info = inf;
+  struct spu_link_hash_table *htab = spu_hash_table (info);
+  asection *sym_sec;
+
   if ((h->root.type == bfd_link_hash_defined
        || h->root.type == bfd_link_hash_defweak)
       && h->def_regular
-      && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
+      && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0
+      && (sym_sec = h->root.u.def.section) != NULL
+      && sym_sec->output_section != NULL
+      && sym_sec->output_section->owner == info->output_bfd
+      && spu_elf_section_data (sym_sec->output_section) != NULL
+      && (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index != 0
+	  || htab->non_overlay_stubs))
     {
-      struct spu_link_hash_table *htab = inf;
-
       build_stub (htab, NULL, NULL, nonovl_stub, h, NULL,
-		  h->root.u.def.value, h->root.u.def.section);
+		  h->root.u.def.value, sym_sec);
     }
   
   return TRUE;
@@ -1194,7 +1210,7 @@ spu_elf_size_stubs (struct bfd_link_info
   if (!process_stubs (info, FALSE))
     return 0;
 
-  elf_link_hash_traverse (&htab->elf, allocate_spuear_stubs, htab);
+  elf_link_hash_traverse (&htab->elf, allocate_spuear_stubs, info);
   if (htab->stub_err)
     return 0;
 
@@ -1392,7 +1408,7 @@ spu_elf_build_stubs (struct bfd_link_inf
   /* Fill in all the stubs.  */
   process_stubs (info, TRUE);
 
-  elf_link_hash_traverse (&htab->elf, build_spuear_stubs, htab);
+  elf_link_hash_traverse (&htab->elf, build_spuear_stubs, info);
   if (htab->stub_err)
     return FALSE;
 

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list