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]
Other format: [Raw text]

Fix ld segfaults under hppa64-hp-hpux11


The enclosed patch fixes the two problems noted by Ross Alexander in this
message <http://sources.redhat.com/ml/binutils/2002-06/msg00029.html>.

PROBLEM 1 - BUILDING SHARED LIBRARIES WITH UNDEFINED FUNCTION REFERENCES

This was the more complicated of the two.  The problem was we were trying
to create an opd for "f1" when linking libtest2.sl when we shouldn't.
f1 is not defined in libtest2.sl (it is defined in libtest1.sl) so we
shouldn't try to create an opd entry for it when we link libtest2.sl.
Thus, I changed allocate_global_data_opd to not request an opd entry
when a symbol has no output section.  This fixed the segfault but a
simple application linked against libtest2.sl segfaulted when a call
with (*r1) was performed.  A check to see if we want an opd entry
needed to be added to elf64_hppa_finalize_dynreloc to fix this problem.

PROBLEM 2 - BUILDING EXECUTABLE WITH UNDEFINED FUNCTION REFERENCE

We probably shouldn't be creating a dlt entry for an undefined function
reference.  However, since an error condition has already occurred, 
I simply added a check to see if the section pointer for the symbol
was not NULL to prevent the segfault.

I have tested the patch on Ross's two examples.  I have also tested
the patch with a rebuild of binutils and gcc on hppa64-hp-hpux11.00.

Please install if OK.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2002-06-12  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* elf64-hppa.c (allocate_global_data_opd): We don't need an opd entry
	for a symbol that has no output section.
	(allocate_dynrel_entries): Correct comment.
	(elf64_hppa_finalize_dynreloc): Likewise.  Don't create an opd entry
	unless we want one.
	(elf64_hppa_finalize_opd): Prevent segfault if dyn_h is NULL.
	(elf64_hppa_finalize_dlt): Likewise.  Prevent segfault for symbols
	with no section.  Remove unnecessary parentheses.

Index: elf64-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-hppa.c,v
retrieving revision 1.21
diff -u -3 -p -r1.21 elf64-hppa.c
--- elf64-hppa.c	6 Jun 2002 00:29:21 -0000	1.21
+++ elf64-hppa.c	12 Jun 2002 16:00:01 -0000
@@ -1159,7 +1159,8 @@ allocate_global_data_opd (dyn_h, data)
 
       /* We never need an opd entry for a symbol which is not
 	 defined by this output file.  */
-      if (h && h->root.type == bfd_link_hash_undefined)
+      if (h && (h->root.type == bfd_link_hash_undefined
+		|| h->root.u.def.section->output_section == NULL))
 	dyn_h->want_opd = 0;
 
       /* If we are creating a shared library, took the address of a local
@@ -1168,9 +1169,8 @@ allocate_global_data_opd (dyn_h, data)
       else if (x->info->shared
 	       || h == NULL
 	       || h->dynindx == -1
-	       || ((h->root.type == bfd_link_hash_defined
-		    || h->root.type == bfd_link_hash_defweak)
-		   && h->root.u.def.section->output_section != NULL))
+	       || (h->root.type == bfd_link_hash_defined
+		   || h->root.type == bfd_link_hash_defweak))
 	{
 	  /* If we are creating a shared library, then we will have to
 	     create a runtime relocation for the symbol to properly
@@ -1535,9 +1535,8 @@ allocate_dynrel_entries (dyn_h, data)
       switch (rent->type)
 	{
 	case R_PARISC_FPTR64:
-	  /* Allocate one iff we are not building a shared library and
-	     !want_opd, which by this point will be true only if we're
-	     actually allocating one statically in the main executable.  */
+	  /* Allocate one iff we are building a shared library and don't
+	     want an opd entry.  */
 	  if (!x->info->shared && dyn_h->want_opd)
 	    continue;
 	  break;
@@ -2115,7 +2114,7 @@ elf64_hppa_finalize_opd (dyn_h, data)
 {
   struct bfd_link_info *info = (struct bfd_link_info *)data;
   struct elf64_hppa_link_hash_table *hppa_info;
-  struct elf_link_hash_entry *h = dyn_h->h;
+  struct elf_link_hash_entry *h = dyn_h ? dyn_h->h : NULL;
   asection *sopd;
   asection *sopdrel;
 
@@ -2123,7 +2122,7 @@ elf64_hppa_finalize_opd (dyn_h, data)
   sopd = hppa_info->opd_sec;
   sopdrel = hppa_info->opd_rel_sec;
 
-  if (h && dyn_h && dyn_h->want_opd)
+  if (h && dyn_h->want_opd)
     {
       bfd_vma value;
 
@@ -2236,7 +2235,7 @@ elf64_hppa_finalize_dlt (dyn_h, data)
   struct bfd_link_info *info = (struct bfd_link_info *)data;
   struct elf64_hppa_link_hash_table *hppa_info;
   asection *sdlt, *sdltrel;
-  struct elf_link_hash_entry *h = dyn_h->h;
+  struct elf_link_hash_entry *h = dyn_h ? dyn_h->h : NULL;
 
   hppa_info = elf64_hppa_hash_table (info);
 
@@ -2247,7 +2246,7 @@ elf64_hppa_finalize_dlt (dyn_h, data)
      address, so there is no need to create a relocation.  Just install
      the proper value into the DLT, note this shortcut can not be
      skipped when building a shared library.  */
-  if (! info->shared && h && dyn_h && dyn_h->want_dlt)
+  if (! info->shared && h && dyn_h->want_dlt)
     {
       bfd_vma value;
 
@@ -2263,16 +2262,17 @@ elf64_hppa_finalize_dlt (dyn_h, data)
 		   + hppa_info->opd_sec->output_offset
 		   + hppa_info->opd_sec->output_section->vma);
 	}
-      else
+      else if (h->root.u.def.section)
 	{
-	  value = (h->root.u.def.value
-		   + h->root.u.def.section->output_offset);
-
+	  value = h->root.u.def.value + h->root.u.def.section->output_offset;
 	  if (h->root.u.def.section->output_section)
 	    value += h->root.u.def.section->output_section->vma;
 	  else
 	    value += h->root.u.def.section->vma;
 	}
+      else
+	/* We have an undefined function reference.  */
+	value = 0;
 
       /* We do not need to include the output offset of the DLT section
 	 here because we are modifying the in-memory contents.  */
@@ -2360,9 +2360,8 @@ elf64_hppa_finalize_dynreloc (dyn_h, dat
 	  switch (rent->type)
 	    {
 	      case R_PARISC_FPTR64:
-	      /* Allocate one iff we are not building a shared library and
-		 !want_opd, which by this point will be true only if we're
-		 actually allocating one statically in the main executable.  */
+	      /* Allocate one iff we are building a shared library and don't
+		 want an opd entry.  */
 	      if (!info->shared && dyn_h->want_opd)
 		continue;
 	      break;
@@ -2395,7 +2394,7 @@ elf64_hppa_finalize_dynreloc (dyn_h, dat
 	     We use a section symbol recorded by check_relocs as the
 	     base symbol for the relocation.  The addend is the difference
 	     between the section symbol and the address of the .opd entry.  */
-	  if (info->shared && rent->type == R_PARISC_FPTR64)
+	  if (info->shared && rent->type == R_PARISC_FPTR64 && dyn_h->want_opd)
 	    {
 	      bfd_vma value, value2;
 


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