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]

Fix elf32-hppa as HJ did for elf32-i386


elf32-hppa.c has the same problem as elf32-i386.c, not surprisingly
since I inserted both bits of buggy code.  Worse, for hppa I was
foolish enough to put the code on the 2.11 branch.  Apparently, not
as many people as I thought were actually using my latest code on
hppa-linux.  :-(

bfd/ChangeLog
	* elf32-hppa.c (elf32_hppa_size_dynamic_sections): Always
	allocate local .got space.  Use shortcuts from hash table for .got
	and .plt rather than comparing section names.
	(elf32_hppa_check_relocs): Use local_plt_refcounts var rather than
	adjusting index into local_got_refcounts to document what we are
	really doing.
	(elf32_hppa_relocate_section): Similarly for local_plt_offsets.
	Tidy .got and .plt error checking.

-- 
Alan Modra

Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.38
diff -u -p -r1.38 elf32-hppa.c
--- elf32-hppa.c	2001/06/05 04:39:31	1.38
+++ elf32-hppa.c	2001/06/21 05:29:59
@@ -1522,7 +1522,7 @@ elf32_hppa_check_relocs (abfd, info, sec
 		}
 	      else if (need_entry & PLT_PLABEL)
 		{
-		  int indx;
+		  bfd_signed_vma *local_plt_refcounts;
 
 		  if (local_got_refcounts == NULL)
 		    {
@@ -1538,11 +1538,12 @@ elf32_hppa_check_relocs (abfd, info, sec
 		      elf_local_got_refcounts (abfd) = local_got_refcounts;
 		      memset (local_got_refcounts, -1, size);
 		    }
-		  indx = r_symndx + symtab_hdr->sh_info;
-		  if (local_got_refcounts[indx] == -1)
-		    local_got_refcounts[indx] = 1;
+		  local_plt_refcounts = (local_got_refcounts
+					 + symtab_hdr->sh_info);
+		  if (local_plt_refcounts[r_symndx] == -1)
+		    local_plt_refcounts[r_symndx] = 1;
 		  else
-		    local_got_refcounts[indx] += 1;
+		    local_plt_refcounts[r_symndx] += 1;
 		}
 	    }
 	}
@@ -2215,6 +2216,7 @@ elf32_hppa_size_dynamic_sections (output
 {
   struct elf32_hppa_link_hash_table *hplink;
   bfd *dynobj;
+  bfd *i;
   asection *s;
   boolean relocs;
   boolean reltext;
@@ -2226,7 +2228,6 @@ elf32_hppa_size_dynamic_sections (output
 
   if (hplink->root.dynamic_sections_created)
     {
-      bfd *i;
 
       /* Set the contents of the .interp section to the interpreter.  */
       if (! info->shared)
@@ -2242,45 +2243,64 @@ elf32_hppa_size_dynamic_sections (output
       elf_link_hash_traverse (&hplink->root,
 			      clobber_millicode_symbols,
 			      info);
+    }
+  else
+    {
+      /* Run through the function symbols, looking for any that are
+	 PIC, and allocate space for the necessary .plt entries so
+	 that %r19 will be set up.  */
+      if (! info->shared)
+	elf_link_hash_traverse (&hplink->root,
+				hppa_handle_PIC_calls,
+				info);
+    }
 
-      /* Set up .got and .plt offsets for local syms.  */
-      for (i = info->input_bfds; i; i = i->link_next)
-	{
-	  bfd_signed_vma *local_got;
-	  bfd_signed_vma *end_local_got;
-	  bfd_signed_vma *local_plt;
-	  bfd_signed_vma *end_local_plt;
-	  bfd_size_type locsymcount;
-	  Elf_Internal_Shdr *symtab_hdr;
-	  asection *srel;
+  /* Set up .got and .plt offsets for local syms.  */
+  for (i = info->input_bfds; i; i = i->link_next)
+    {
+      bfd_signed_vma *local_got;
+      bfd_signed_vma *end_local_got;
+      bfd_signed_vma *local_plt;
+      bfd_signed_vma *end_local_plt;
+      bfd_size_type locsymcount;
+      Elf_Internal_Shdr *symtab_hdr;
+      asection *srel;
 
-	  if (bfd_get_flavour (i) != bfd_target_elf_flavour)
-	    continue;
+      if (bfd_get_flavour (i) != bfd_target_elf_flavour)
+	continue;
 
-	  local_got = elf_local_got_refcounts (i);
-	  if (!local_got)
-	    continue;
+      local_got = elf_local_got_refcounts (i);
+      if (!local_got)
+	continue;
 
-	  symtab_hdr = &elf_tdata (i)->symtab_hdr;
-	  locsymcount = symtab_hdr->sh_info;
-	  end_local_got = local_got + locsymcount;
-	  s = hplink->sgot;
-	  srel = hplink->srelgot;
-	  for (; local_got < end_local_got; ++local_got)
+      symtab_hdr = &elf_tdata (i)->symtab_hdr;
+      locsymcount = symtab_hdr->sh_info;
+      end_local_got = local_got + locsymcount;
+      s = hplink->sgot;
+      srel = hplink->srelgot;
+      for (; local_got < end_local_got; ++local_got)
+	{
+	  if (*local_got > 0)
 	    {
-	      if (*local_got > 0)
-		{
-		  *local_got = s->_raw_size;
-		  s->_raw_size += GOT_ENTRY_SIZE;
-		  if (info->shared)
-		    srel->_raw_size += sizeof (Elf32_External_Rela);
-		}
-	      else
-		*local_got = (bfd_vma) -1;
+	      *local_got = s->_raw_size;
+	      s->_raw_size += GOT_ENTRY_SIZE;
+	      if (info->shared)
+		srel->_raw_size += sizeof (Elf32_External_Rela);
 	    }
+	  else
+	    *local_got = (bfd_vma) -1;
+	}
 
-	  local_plt = end_local_got;
-	  end_local_plt = local_plt + locsymcount;
+      local_plt = end_local_got;
+      end_local_plt = local_plt + locsymcount;
+      if (! hplink->root.dynamic_sections_created)
+	{
+	  /* Won't be used, but be safe.  */
+	  for (; local_plt < end_local_plt; ++local_plt)
+	    *local_plt = (bfd_vma) -1;
+	}
+      else
+	{
 	  s = hplink->splt;
 	  srel = hplink->srelplt;
 	  for (; local_plt < end_local_plt; ++local_plt)
@@ -2297,16 +2317,6 @@ elf32_hppa_size_dynamic_sections (output
 	    }
 	}
     }
-  else
-    {
-      /* Run through the function symbols, looking for any that are
-	 PIC, and allocate space for the necessary .plt entries so
-	 that %r19 will be set up.  */
-      if (! info->shared)
-	elf_link_hash_traverse (&hplink->root,
-				hppa_handle_PIC_calls,
-				info);
-    }
 
   /* Allocate global sym .plt and .got entries.  */
   elf_link_hash_traverse (&hplink->root,
@@ -2332,16 +2342,29 @@ elf32_hppa_size_dynamic_sections (output
   reltext = false;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
-      const char *name;
-
       if ((s->flags & SEC_LINKER_CREATED) == 0)
 	continue;
 
-      /* It's OK to base decisions on the section name, because none
-	 of the dynobj section names depend upon the input files.  */
-      name = bfd_get_section_name (dynobj, s);
+      if (s == hplink->splt)
+	{
+	  if (hplink->need_plt_stub)
+	    {
+	      /* Make space for the plt stub at the end of the .plt
+		 section.  We want this stub right at the end, up
+		 against the .got section.  */
+	      int gotalign = bfd_section_alignment (dynobj, hplink->sgot);
+	      int pltalign = bfd_section_alignment (dynobj, s);
+	      bfd_size_type mask;
 
-      if (strncmp (name, ".rela", 5) == 0)
+	      if (gotalign > pltalign)
+		bfd_set_section_alignment (dynobj, s, gotalign);
+	      mask = ((bfd_size_type) 1 << gotalign) - 1;
+	      s->_raw_size = (s->_raw_size + sizeof (plt_stub) + mask) & ~mask;
+	    }
+	}
+      else if (s == hplink->sgot)
+	;
+      else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
 	{
 	  if (s->_raw_size != 0)
 	    {
@@ -2350,7 +2373,7 @@ elf32_hppa_size_dynamic_sections (output
 
 	      /* Remember whether there are any reloc sections other
 		 than .rela.plt.  */
-	      if (strcmp (name+5, ".plt") != 0)
+	      if (s != hplink->srelplt)
 		relocs = true;
 
 	      /* If this relocation section applies to a read only
@@ -2368,25 +2391,6 @@ elf32_hppa_size_dynamic_sections (output
 	      s->reloc_count = 0;
 	    }
 	}
-      else if (strcmp (name, ".plt") == 0)
-	{
-	  if (hplink->need_plt_stub)
-	    {
-	      /* Make space for the plt stub at the end of the .plt
-		 section.  We want this stub right at the end, up
-		 against the .got section.  */
-	      int gotalign = bfd_section_alignment (dynobj, hplink->sgot);
-	      int pltalign = bfd_section_alignment (dynobj, s);
-	      bfd_size_type mask;
-
-	      if (gotalign > pltalign)
-		bfd_set_section_alignment (dynobj, s, gotalign);
-	      mask = ((bfd_size_type) 1 << gotalign) - 1;
-	      s->_raw_size = (s->_raw_size + sizeof (plt_stub) + mask) & ~mask;
-	    }
-	}
-      else if (strcmp (name, ".got") == 0)
-	;
       else
 	{
 	  /* It's not one of our sections, so don't allocate space.  */
@@ -3587,6 +3591,7 @@ elf32_hppa_relocate_section (output_bfd,
       bfd_reloc_status_type r;
       const char *sym_name;
       boolean plabel;
+      bfd_vma off;
 
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
@@ -3690,13 +3695,9 @@ elf32_hppa_relocate_section (output_bfd,
 	     offset table.  */
 	  if (h != NULL)
 	    {
-	      bfd_vma off;
 	      boolean dyn;
 
 	      off = h->elf.got.offset;
-	      if (off == (bfd_vma) -1)
-		abort ();
-
 	      dyn = hplink->root.dynamic_sections_created;
 	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, &h->elf))
 		{
@@ -3721,18 +3722,15 @@ elf32_hppa_relocate_section (output_bfd,
 		      h->elf.got.offset |= 1;
 		    }
 		}
-
-	      relocation = off;
 	    }
 	  else
 	    {
 	      /* Local symbol case.  */
-	      bfd_vma off;
-
-	      if (local_got_offsets == NULL
-		  || (off = local_got_offsets[r_symndx]) == (bfd_vma) -1)
+	      if (local_got_offsets == NULL)
 		abort ();
 
+	      off = local_got_offsets[r_symndx];
+
 	      /* The offset must always be a multiple of 4.  We use
 		 the least significant bit to record whether we have
 		 already generated the necessary reloc.  */
@@ -3766,13 +3764,15 @@ elf32_hppa_relocate_section (output_bfd,
 
 		  local_got_offsets[r_symndx] |= 1;
 		}
-
-	      relocation = off;
 	    }
 
+	  if (off >= (bfd_vma) -2)
+	    abort ();
+
 	  /* Add the base of the GOT to the relocation value.  */
-	  relocation += (hplink->sgot->output_offset
-			 + hplink->sgot->output_section->vma);
+	  relocation = (off
+			+ hplink->sgot->output_offset
+			+ hplink->sgot->output_section->vma);
 	  break;
 
 	case R_PARISC_SEGREL32:
@@ -3789,8 +3789,6 @@ elf32_hppa_relocate_section (output_bfd,
 	case R_PARISC_PLABEL32:
 	  if (hplink->root.dynamic_sections_created)
 	    {
-	      bfd_vma off;
-
 	      /* If we have a global symbol with a PLT slot, then
 		 redirect this relocation to it.  */
 	      if (h != NULL)
@@ -3817,10 +3815,13 @@ elf32_hppa_relocate_section (output_bfd,
 		}
 	      else
 		{
-		  int indx;
+		  bfd_vma *local_plt_offsets;
+
+		  if (local_got_offsets == NULL)
+		    abort ();
 
-		  indx = r_symndx + symtab_hdr->sh_info;
-		  off = local_got_offsets[indx];
+		  local_plt_offsets = local_got_offsets + symtab_hdr->sh_info;
+		  off = local_plt_offsets[r_symndx];
 
 		  /* As for the local .got entry case, we use the last
 		     bit to record whether we've already initialised
@@ -3855,11 +3856,11 @@ elf32_hppa_relocate_section (output_bfd,
 			  ++srelplt->reloc_count;
 			}
 
-		      local_got_offsets[indx] |= 1;
+		      local_plt_offsets[r_symndx] |= 1;
 		    }
 		}
 
-	      if (off >= (bfd_vma) -2 || (off & 1) != 0)
+	      if (off >= (bfd_vma) -2)
 		abort ();
 
 	      /* PLABELs contain function pointers.  Relocation is to


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