This is the mail archive of the binutils@sources.redhat.com 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]

elf32-hppa.c fixes.



This patch fixes a segfault caused by scribbling past the end of a
malloc'ed array, and skips non-interesting sections when checking for stub
groups.  _bfd_strip_section_from_output has some curious effects on
output_bfd sections.  a) output_section->index may be larger than
output_bfd->section_count - 1.  b) input_section->output_section->owner
== output_bfd but input_section->output_section isn't on output_bfd->
sections list.

The diff here combines my last two commits - those interested in
seeing the bloopers in the previous commit can go dig it out of CVS.

bfd/ChangeLog
	* elf32-hppa.c (elf32_hppa_check_relocs): Fix weak sym handling in
	currently unused RELATIVE_DYNAMIC_RELOCS code.
	(hppa_discard_copies): Likewise.
	(elf32_hppa_size_stubs): Size `input_list' array correctly.  Correct
	comments.  Don't check non-code output sections for stub grouping.

Alan Modra
-- 
Linuxcare.  Support for the Revolution.

Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.17
diff -u -p -r1.17 elf32-hppa.c
--- elf32-hppa.c	2000/09/18 12:22:41	1.17
+++ elf32-hppa.c	2000/09/21 13:33:44
@@ -1537,8 +1537,7 @@ elf32_hppa_check_relocs (abfd, info, sec
 		  || is_absolute_reloc (r_type)
 		  || (h != NULL
 		      && ((h->elf.elf_link_hash_flags
-			   & ELF_LINK_HASH_DEF_REGULAR) == 0
-			  || h->elf.root.type == bfd_link_hash_defweak)))
+			   & ELF_LINK_HASH_DEF_REGULAR) == 0)))
 #endif
 	      )
 	    {
@@ -2096,7 +2095,7 @@ hppa_discard_copies (h, inf)
      any relocs.  */
   if (eh->elf.dynindx == -1
       || ((eh->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
-	  && eh->elf.root.type != bfd_link_hash_defweak
+	  && !is_absolute_reloc (r_type)
 	  && info->symbolic))
     {
       for (s = eh->reloc_entries; s != NULL; s = s->next)
@@ -2441,7 +2440,7 @@ elf32_hppa_size_stubs (output_bfd, stub_
   hplink->add_stub_section = add_stub_section;
   hplink->layout_sections_again = layout_sections_again;
 
-  /* Count the number of input BFDs and find the top section id.  */
+  /* Count the number of input BFDs and find the top input section id.  */
   for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
        input_bfd != NULL;
        input_bfd = input_bfd->link_next)
@@ -2461,11 +2460,12 @@ elf32_hppa_size_stubs (output_bfd, stub_
   if (hplink->stub_group == NULL)
     return false;
 
-  /* Now make a list of input sections for each output section.
-     We can't use output_bfd->section_count here as some sections may
-     have been removed, and _bfd_strip_section_from_output doesn't
-     renumber the indices.  Sections may also be re-ordered, so the
-     last section index isn't necessarily the biggest.  */
+  /* Make a list of input sections for each output section included in
+     the link.
+
+     We can't use output_bfd->section_count here to find the top output
+     section index as some sections may have been removed, and
+     _bfd_strip_section_from_output doesn't renumber the indices.  */
   for (section = output_bfd->sections, top_index = 0;
        section != NULL;
        section = section->next)
@@ -2473,11 +2473,28 @@ elf32_hppa_size_stubs (output_bfd, stub_
       if (top_index < section->index)
 	top_index = section->index;
     }
+
   input_list
-    = (asection **) bfd_zmalloc (sizeof (asection *) * (top_index + 1));
+    = (asection **) bfd_malloc (sizeof (asection *) * (top_index + 1));
   if (input_list == NULL)
     return false;
 
+  /* For sections we aren't interested in, mark their entries with a
+     value we can check later.  */
+  list = input_list + top_index;
+  do
+    *list = bfd_abs_section_ptr;
+  while (list-- != input_list);
+
+  for (section = output_bfd->sections;
+       section != NULL;
+       section = section->next)
+    {
+      if ((section->flags & SEC_CODE) != 0 && section->index <= top_index)
+	input_list[section->index] = NULL;
+    }
+
+  /* Now actually build the lists.  */
   for (input_bfd = info->input_bfds;
        input_bfd != NULL;
        input_bfd = input_bfd->link_next)
@@ -2487,15 +2504,19 @@ elf32_hppa_size_stubs (output_bfd, stub_
 	   section = section->next)
 	{
 	  if (section->output_section != NULL
-	      && section->output_section->owner == output_bfd)
+	      && section->output_section->owner == output_bfd
+	      && section->output_section->index <= top_index)
 	    {
 	      list = input_list + section->output_section->index;
-	      /* Steal the link_sec pointer for our list.  */
+	      if (*list != bfd_abs_section_ptr)
+		{
+		  /* Steal the link_sec pointer for our list.  */
 #define PREV_SEC(sec) (hplink->stub_group[(sec)->id].link_sec)
-	      /* This happens to make the list in reverse order, which
-		 is what we want.  */
-	      PREV_SEC (section) = *list;
-	      *list = section;
+		  /* This happens to make the list in reverse order,
+		     which is what we want.  */
+		  PREV_SEC (section) = *list;
+		  *list = section;
+		}
 	    }
 	}
     }
@@ -2506,10 +2527,12 @@ elf32_hppa_size_stubs (output_bfd, stub_
      .fini output sections respectively, because glibc splits the
      _init and _fini functions into multiple parts.  Putting a stub in
      the middle of a function is not a good idea.  */
-  list = input_list + output_bfd->section_count;
-  while (list-- != input_list)
+  list = input_list + top_index;
+  do
     {
       asection *tail = *list;
+      if (tail == bfd_abs_section_ptr)
+	continue;
       while (tail != NULL)
 	{
 	  asection *curr;
@@ -2559,7 +2582,9 @@ elf32_hppa_size_stubs (output_bfd, stub_
 	  tail = prev;
 	}
     }
+  while (list-- != input_list);
   free (input_list);
+#undef PREV_SEC
 
   /* We want to read in symbol extension records only once.  To do this
      we need to read in the local symbols in parallel and save them for


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