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]

SPU --auto-overlay and --stack-analyis bugs


This fixes three bugs affecting SPU --auto-overlay, two of which also
affect --stack-analysis.
- a stupid realloc problem which could cause memory corruption, but
  which was rather hard to trigger without the second bug,
- a problem with ELF symbol caching that occurs when --gc-sections
  is used with --auto-overlay or --stack-analysis.
- failure to properly pass the --no-auto-overlay arg when reinvoking
  the linker for --auto-relink.

bfd/
	* elf32-spu.c (get_sym_h): Don't attempt to read global syms.
	(process_stubs): Likewise.
	(discover_functions): Don't used cached symbols.
	(maybe_insert_function): Correct condition under which function
	array is realloc'd.
	(mark_functions_via_relocs): Delete unused variable.
ld/
	* emultempl/spuelf.em (spu_elf_relink): Correct --no-auto-overlay
	arg.

diff -urp src.old/bfd/elf32-spu.c src/bfd/elf32-spu.c
--- src.old/bfd/elf32-spu.c	2008-05-17 12:28:47.000000000 +0930
+++ src/bfd/elf32-spu.c	2008-06-04 16:03:50.000000000 +0930
@@ -410,17 +410,9 @@ get_sym_h (struct elf_link_hash_entry **
 	{
 	  locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
 	  if (locsyms == NULL)
-	    {
-	      size_t symcount = symtab_hdr->sh_info;
-
-	      /* If we are reading symbols into the contents, then
-		 read the global syms too.  This is done to cache
-		 syms for later stack analysis.  */
-	      if ((unsigned char **) locsymsp == &symtab_hdr->contents)
-		symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
-	      locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0,
-					      NULL, NULL, NULL);
-	    }
+	    locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
+					    symtab_hdr->sh_info,
+					    0, NULL, NULL, NULL);
 	  if (locsyms == NULL)
 	    return FALSE;
 	  *locsymsp = locsyms;
@@ -1095,7 +1087,6 @@ process_stubs (struct bfd_link_info *inf
       Elf_Internal_Shdr *symtab_hdr;
       asection *isec;
       Elf_Internal_Sym *local_syms = NULL;
-      void *psyms;
 
       if (ibfd->xvec != &bfd_elf32_spu_vec)
 	continue;
@@ -1105,11 +1096,6 @@ process_stubs (struct bfd_link_info *inf
       if (symtab_hdr->sh_info == 0)
 	continue;
 
-      /* Arrange to read and keep global syms for later stack analysis.  */
-      psyms = &local_syms;
-      if (htab->stack_analysis)
-	psyms = &symtab_hdr->contents;
-
       /* Walk over each section attached to the input bfd.  */
       for (isec = ibfd->sections; isec != NULL; isec = isec->next)
 	{
@@ -1159,7 +1145,7 @@ process_stubs (struct bfd_link_info *inf
 		}
 
 	      /* Determine the reloc target section.  */
-	      if (!get_sym_h (&h, &sym, &sym_sec, psyms, r_indx, ibfd))
+	      if (!get_sym_h (&h, &sym, &sym_sec, &local_syms, r_indx, ibfd))
 		goto error_ret_free_internal;
 
 	      stub_type = needs_ovl_stub (h, sym, sym_sec, isec, irela,
@@ -1823,10 +1809,7 @@ maybe_insert_function (asection *sec,
 	return &sinfo->fun[i];
     }
 
-  if (++i < sinfo->num_fun)
-    memmove (&sinfo->fun[i + 1], &sinfo->fun[i],
-	     (sinfo->num_fun - i) * sizeof (sinfo->fun[i]));
-  else if (i >= sinfo->max_fun)
+  if (sinfo->num_fun >= sinfo->max_fun)
     {
       bfd_size_type amt = sizeof (struct spu_elf_stack_info);
       bfd_size_type old = amt;
@@ -1840,6 +1823,10 @@ maybe_insert_function (asection *sec,
       memset ((char *) sinfo + old, 0, amt - old);
       sec_data->u.i.stack_info = sinfo;
     }
+
+  if (++i < sinfo->num_fun)
+    memmove (&sinfo->fun[i + 1], &sinfo->fun[i],
+	     (sinfo->num_fun - i) * sizeof (sinfo->fun[i]));
   sinfo->fun[i].is_func = is_func;
   sinfo->fun[i].global = global;
   sinfo->fun[i].sec = sec;
@@ -2069,7 +2056,6 @@ mark_functions_via_relocs (asection *sec
 {
   Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
   Elf_Internal_Shdr *symtab_hdr;
-  Elf_Internal_Sym *syms;
   void *psyms;
   static bfd_boolean warned;
 
@@ -2084,7 +2070,6 @@ mark_functions_via_relocs (asection *sec
 
   symtab_hdr = &elf_tdata (sec->owner)->symtab_hdr;
   psyms = &symtab_hdr->contents;
-  syms = *(Elf_Internal_Sym **) psyms;
   irela = internal_relocs;
   irelaend = irela + sec->reloc_count;
   for (; irela < irelaend; irela++)
@@ -2364,15 +2349,18 @@ discover_functions (struct bfd_link_info
 	  continue;
 	}
 
-      syms = (Elf_Internal_Sym *) symtab_hdr->contents;
-      if (syms == NULL)
+      if (symtab_hdr->contents != NULL)
 	{
-	  syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0,
-				       NULL, NULL, NULL);
-	  symtab_hdr->contents = (void *) syms;
-	  if (syms == NULL)
-	    return FALSE;
-	}
+	  /* Don't use cached symbols since the generic ELF linker
+	     code only reads local symbols, and we need globals too.  */ 
+	  free (symtab_hdr->contents);
+	  symtab_hdr->contents = NULL;
+	}
+      syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0,
+				   NULL, NULL, NULL);
+      symtab_hdr->contents = (void *) syms;
+      if (syms == NULL)
+	return FALSE;
 
       /* Select defined function symbols that are going to be output.  */
       psyms = bfd_malloc ((symcount + 1) * sizeof (*psyms));
diff -urp src.old/ld/emultempl/spuelf.em src/ld/emultempl/spuelf.em
--- src.old/ld/emultempl/spuelf.em	2008-04-08 15:49:46.000000000 +0930
+++ src/ld/emultempl/spuelf.em	2008-06-04 13:48:21.000000000 +0930
@@ -295,12 +295,13 @@ spu_elf_open_overlay_script (void)
 static void
 spu_elf_relink (void)
 {
-  char **argv = xmalloc ((my_argc + 5) * sizeof (*argv));
+  char **argv = xmalloc ((my_argc + 4) * sizeof (*argv));
 
   memcpy (argv, my_argv, my_argc * sizeof (*argv));
   argv[my_argc++] = "--no-auto-overlay";
   if (tmp_file_list->name == auto_overlay_file)
-    argv[my_argc++] = auto_overlay_file;
+    argv[my_argc - 1] = concat (argv[my_argc - 1], "=",
+				auto_overlay_file, (const char *) NULL);
   argv[my_argc++] = "-T";
   argv[my_argc++] = auto_overlay_file;
   argv[my_argc] = 0;

-- 
Alan Modra
Australia Development Lab, IBM


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