editing stabs and eh_frame during ld -r

Alan Modra amodra@bigpond.net.au
Mon Nov 11 23:52:00 GMT 2002


This final patch enables stabs and eh_frame editing during relocatable
linking.  For powerpc64 ELF, also edit the opd section.

bfd/ChangeLog
	* elflink.h (elf_link_add_object_symbols): Optimize stabs for
	relocatable link too.
	(elf_link_input_bfd): When emitting relocs, adjust offsets for
	eh_frame and stab sections.  Zap deleted relocs.
	(elf_reloc_symbol_deleted_p): Return true for zero r_symndx.
	(elf_bfd_discard_info): Run for relocatable link too.

	* elf64-ppc.c (ppc64_elf_edit_opd): Rename from edit_opd.  Make global.
	Handle ld -r case.
	(ppc64_elf_size_dynamic_sections): Don't call edit_opd from here.
	* elf64-ppc.h (ppc64_elf_edit_opd): Declare.

ld/ChangeLog
	* emultempl/ppc64elf.em (ppc_before_allocation): New function.
	(LDEMUL_BEFORE_ALLOCATION): Define.
	(gld${EMULATION_NAME}_finish): Run discard_info for relocatable
	linking.
	* emultemp/hppaelf.em ((gld${EMULATION_NAME}_finish): Likewise.

Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.195
diff -u -p -r1.195 elflink.h
--- bfd/elflink.h	12 Nov 2002 07:35:26 -0000	1.195
+++ bfd/elflink.h	12 Nov 2002 07:45:37 -0000
@@ -2208,10 +2208,9 @@ elf_link_add_object_symbols (abfd, info)
 	}
     }
 
-  /* If this is a non-traditional, non-relocateable link, try to
-     optimize the handling of the .stab/.stabstr sections.  */
+  /* If this is a non-traditional link, try to optimize the handling
+     of the .stab/.stabstr sections.  */
   if (! dynamic
-      && ! info->relocateable
       && ! info->traditional_format
       && info->hash->creator->flavour == bfd_target_elf_flavour
       && is_elf_hash_table (info)
@@ -6982,6 +6981,16 @@ elf_link_input_bfd (finfo, input_bfd)
 		      next_erel = 0;
 		    }
 
+		  irela->r_offset = _bfd_elf_section_offset (output_bfd,
+							     finfo->info, o,
+							     irela->r_offset);
+		  if (irela->r_offset >= (bfd_vma) -2)
+		    {
+		      /* This is a reloc for a deleted entry or somesuch.  */
+		      memset (irela, 0, sizeof (*irela));
+		      continue;
+		    }
+
 		  irela->r_offset += o->output_offset;
 
 		  /* Relocs in an executable have to be virtual addresses.  */
@@ -8334,7 +8343,7 @@ elf_reloc_symbol_deleted_p (offset, cook
 
   for (; rcookie->rel < rcookie->relend; rcookie->rel++)
     {
-      unsigned long r_symndx = ELF_R_SYM (rcookie->rel->r_info);
+      unsigned long r_symndx;
 
       if (! rcookie->bad_symtab)
 	if (rcookie->rel->r_offset > offset)
@@ -8342,6 +8351,10 @@ elf_reloc_symbol_deleted_p (offset, cook
       if (rcookie->rel->r_offset != offset)
 	continue;
 
+      r_symndx = ELF_R_SYM (rcookie->rel->r_info);
+      if (r_symndx == SHN_UNDEF)
+	return true;
+
       if (r_symndx >= rcookie->locsymcount
 	  || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
 	{
@@ -8400,8 +8413,7 @@ elf_bfd_discard_info (output_bfd, info)
   unsigned int count;
   boolean ret = false;
 
-  if (info->relocateable
-      || info->traditional_format
+  if (info->traditional_format
       || info->hash->creator->flavour != bfd_target_elf_flavour
       || ! is_elf_hash_table (info))
     return false;
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.70
diff -u -p -r1.70 elf64-ppc.c
--- bfd/elf64-ppc.c	7 Nov 2002 12:45:29 -0000	1.70
+++ bfd/elf64-ppc.c	12 Nov 2002 06:37:25 -0000
@@ -1972,8 +1972,6 @@ static boolean ppc64_elf_adjust_dynamic_
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
 static void ppc64_elf_hide_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
-static boolean edit_opd
-  PARAMS ((bfd *, struct bfd_link_info *));
 static boolean allocate_dynrelocs
   PARAMS ((struct elf_link_hash_entry *, PTR));
 static boolean readonly_dynrelocs
@@ -3539,8 +3537,8 @@ ppc64_elf_hide_symbol (info, h, force_lo
     }
 }
 
-static boolean
-edit_opd (obfd, info)
+boolean
+ppc64_elf_edit_opd (obfd, info)
      bfd *obfd;
      struct bfd_link_info *info;
 {
@@ -3557,6 +3555,7 @@ edit_opd (obfd, info)
       Elf_Internal_Sym *local_syms;
       struct elf_link_hash_entry **sym_hashes;
       bfd_vma offset;
+      bfd_size_type amt;
       long *adjust;
       boolean need_edit;
 
@@ -3564,9 +3563,16 @@ edit_opd (obfd, info)
       if (sec == NULL)
 	continue;
 
+      amt = sec->_raw_size * sizeof (long) / 24;
       adjust = (long *) elf_section_data (sec)->tdata;
-      BFD_ASSERT (adjust != NULL);
-      memset (adjust, 0, (size_t) sec->_raw_size * sizeof (long) / 24);
+      if (adjust == NULL)
+	{
+	  /* Must be a ld -r link.  ie. check_relocs hasn't been
+	     called.  */
+	  adjust = (long *) bfd_zalloc (obfd, amt);
+	  elf_section_data (sec)->tdata = adjust;
+	}
+      memset (adjust, 0, (size_t) amt);
 
       if (sec->output_section == bfd_abs_section_ptr)
 	continue;
@@ -3769,14 +3775,29 @@ edit_opd (obfd, info)
 			{
 			  /* Arrange for the function descriptor sym
 			     to be dropped.  */
-			  struct elf_link_hash_entry *fdh;
+			  struct ppc_link_hash_entry *fdh;
 			  struct ppc_link_hash_entry *fh;
 
 			  fh = (struct ppc_link_hash_entry *) h;
-			  BFD_ASSERT (fh->is_func);
-			  fdh = fh->oh;
-			  fdh->root.u.def.value = 0;
-			  fdh->root.u.def.section = sym_sec;
+			  fdh = (struct ppc_link_hash_entry *) fh->oh;
+			  if (fdh == NULL)
+			    {
+			      const char *fd_name;
+			      struct ppc_link_hash_table *htab;
+
+			      fd_name = h->root.root.string + 1;
+			      htab = ppc_hash_table (info);
+			      fdh = (struct ppc_link_hash_entry *)
+				elf_link_hash_lookup (&htab->elf, fd_name,
+						      false, false, false);
+			      fdh->is_func_descriptor = 1;
+			      fdh->oh = &fh->elf;
+			      fh->is_func = 1;
+			      fh->oh = &fdh->elf;
+			    }
+
+			  fdh->elf.root.u.def.value = 0;
+			  fdh->elf.root.u.def.section = sym_sec;
 			}
 		    }
 		  else
@@ -3789,13 +3810,28 @@ edit_opd (obfd, info)
 			     to this location in the opd section.
 			     We've checked above that opd relocs are
 			     ordered.  */
-			  struct elf_link_hash_entry *fdh;
+			  struct ppc_link_hash_entry *fdh;
 			  struct ppc_link_hash_entry *fh;
 
 			  fh = (struct ppc_link_hash_entry *) h;
-			  BFD_ASSERT (fh->is_func);
-			  fdh = fh->oh;
-			  fdh->root.u.def.value = wptr - sec->contents;
+			  fdh = (struct ppc_link_hash_entry *) fh->oh;
+			  if (fdh == NULL)
+			    {
+			      const char *fd_name;
+			      struct ppc_link_hash_table *htab;
+
+			      fd_name = h->root.root.string + 1;
+			      htab = ppc_hash_table (info);
+			      fdh = (struct ppc_link_hash_entry *)
+				elf_link_hash_lookup (&htab->elf, fd_name,
+						      false, false, false);
+			      fdh->is_func_descriptor = 1;
+			      fdh->oh = &fh->elf;
+			      fh->is_func = 1;
+			      fh->oh = &fdh->elf;
+			    }
+
+			  fdh->elf.root.u.def.value = wptr - sec->contents;
 			}
 		      else
 			{
@@ -4144,9 +4180,6 @@ ppc64_elf_size_dynamic_sections (output_
 	    *local_got = (bfd_vma) -1;
 	}
     }
-
-  if (!edit_opd (output_bfd, info))
-    return false;
 
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
Index: bfd/elf64-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.h,v
retrieving revision 1.4
diff -u -p -r1.4 elf64-ppc.h
--- bfd/elf64-ppc.h	1 Jul 2002 08:06:45 -0000	1.4
+++ bfd/elf64-ppc.h	12 Nov 2002 06:37:25 -0000
@@ -19,6 +19,8 @@ Foundation, Inc., 59 Temple Place - Suit
 
 boolean ppc64_elf_mark_entry_syms
   PARAMS ((struct bfd_link_info *));
+boolean ppc64_elf_edit_opd
+  PARAMS ((bfd *, struct bfd_link_info *));
 bfd_vma ppc64_elf_toc
   PARAMS ((bfd *));
 int ppc64_elf_setup_section_lists
Index: ld/emultempl/hppaelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/hppaelf.em,v
retrieving revision 1.22
diff -c -p -r1.22 hppaelf.em
*** ld/emultempl/hppaelf.em	4 May 2002 02:06:43 -0000	1.22
--- ld/emultempl/hppaelf.em	12 Nov 2002 03:37:19 -0000
*************** build_section_lists (statement)
*** 263,275 ****
  static void
  gld${EMULATION_NAME}_finish ()
  {
-   int ret;
- 
-   /* If generating a relocatable output file, then we don't
-      have to examine the relocs.  */
-   if (link_info.relocateable)
-     return;
- 
    /* bfd_elf32_discard_info just plays with debugging sections,
       ie. doesn't affect any code, so we can delay resizing the
       sections.  It's likely we'll resize everything in the process of
--- 263,268 ----
*************** gld${EMULATION_NAME}_finish ()
*** 277,322 ****
    if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
      need_laying_out = 1;
  
!   ret = elf32_hppa_setup_section_lists (output_bfd, &link_info);
!   if (ret != 0)
      {
!       if (ret < 0)
! 	{
! 	  einfo ("%X%P: can not size stub section: %E\n");
! 	  return;
! 	}
  
!       lang_for_each_statement (build_section_lists);
! 
!       /* Call into the BFD backend to do the real work.  */
!       if (! elf32_hppa_size_stubs (output_bfd,
! 				   stub_file->the_bfd,
! 				   &link_info,
! 				   multi_subspace,
! 				   group_size,
! 				   &hppaelf_add_stub_section,
! 				   &hppaelf_layout_sections_again))
  	{
! 	  einfo ("%X%P: can not size stub section: %E\n");
! 	  return;
  	}
      }
  
    if (need_laying_out)
      hppaelf_layout_sections_again ();
  
!   /* Set the global data pointer.  */
!   if (! elf32_hppa_set_gp (output_bfd, &link_info))
      {
!       einfo ("%X%P: can not set gp\n");
!       return;
!     }
  
!   /* Now build the linker stubs.  */
!   if (stub_file->the_bfd->sections != NULL)
!     {
!       if (! elf32_hppa_build_stubs (&link_info))
! 	einfo ("%X%P: can not build stubs: %E\n");
      }
  }
  
--- 270,324 ----
    if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
      need_laying_out = 1;
  
!   /* If generating a relocatable output file, then we don't
!      have to examine the relocs.  */
!   if (! link_info.relocateable)
      {
!       int ret = elf32_hppa_setup_section_lists (output_bfd, &link_info);
  
!       if (ret != 0)
  	{
! 	  if (ret < 0)
! 	    {
! 	      einfo ("%X%P: can not size stub section: %E\n");
! 	      return;
! 	    }
! 
! 	  lang_for_each_statement (build_section_lists);
! 
! 	  /* Call into the BFD backend to do the real work.  */
! 	  if (! elf32_hppa_size_stubs (output_bfd,
! 				       stub_file->the_bfd,
! 				       &link_info,
! 				       multi_subspace,
! 				       group_size,
! 				       &hppaelf_add_stub_section,
! 				       &hppaelf_layout_sections_again))
! 	    {
! 	      einfo ("%X%P: can not size stub section: %E\n");
! 	      return;
! 	    }
  	}
      }
  
    if (need_laying_out)
      hppaelf_layout_sections_again ();
  
!   if (! link_info.relocateable)
      {
!       /* Set the global data pointer.  */
!       if (! elf32_hppa_set_gp (output_bfd, &link_info))
! 	{
! 	  einfo ("%X%P: can not set gp\n");
! 	  return;
! 	}
  
!       /* Now build the linker stubs.  */
!       if (stub_file->the_bfd->sections != NULL)
! 	{
! 	  if (! elf32_hppa_build_stubs (&link_info))
! 	    einfo ("%X%P: can not build stubs: %E\n");
! 	}
      }
  }
  
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.9
diff -c -p -r1.9 ppc64elf.em
*** ld/emultempl/ppc64elf.em	1 Jul 2002 08:07:31 -0000	1.9
--- ld/emultempl/ppc64elf.em	12 Nov 2002 03:37:19 -0000
*************** static int dotsyms = 1;
*** 43,48 ****
--- 43,49 ----
  
  static void ppc_create_output_section_statements PARAMS ((void));
  static void ppc_after_open PARAMS ((void));
+ static void ppc_before_allocation PARAMS ((void));
  static asection *ppc_add_stub_section PARAMS ((const char *, asection *));
  static void ppc_layout_sections_again PARAMS ((void));
  static void gld${EMULATION_NAME}_after_allocation PARAMS ((void));
*************** ppc_after_open ()
*** 84,89 ****
--- 85,102 ----
    gld${EMULATION_NAME}_after_open ();
  }
  
+ static void
+ ppc_before_allocation ()
+ {
+   if (!ppc64_elf_edit_opd (output_bfd, &link_info))
+     {
+       einfo ("%X%P: can not edit opd %E\n");
+       return;
+     }
+ 
+   gld${EMULATION_NAME}_before_allocation ();
+ }
+ 
  struct hook_stub_info
  {
    lang_statement_list_type add;
*************** build_section_lists (statement)
*** 265,282 ****
  static void
  gld${EMULATION_NAME}_finish ()
  {
-   int ret;
- 
    /* e_entry on PowerPC64 points to the function descriptor for
       _start.  If _start is missing, default to the first function
       descriptor in the .opd section.  */
    entry_section = ".opd";
  
-   /* If generating a relocatable output file, then we don't have any
-      stubs.  */
-   if (link_info.relocateable)
-     return;
- 
    /* bfd_elf64_discard_info just plays with debugging sections,
       ie. doesn't affect any code, so we can delay resizing the
       sections.  It's likely we'll resize everything in the process of
--- 278,288 ----
*************** gld${EMULATION_NAME}_finish ()
*** 284,310 ****
    if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
      need_laying_out = 1;
  
!   ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
!   if (ret != 0)
      {
!       if (ret < 0)
  	{
! 	  einfo ("%X%P: can not size stub section: %E\n");
! 	  return;
! 	}
  
!       lang_for_each_statement (build_section_lists);
  
!       /* Call into the BFD backend to do the real work.  */
!       if (!ppc64_elf_size_stubs (output_bfd,
! 				 stub_file->the_bfd,
! 				 &link_info,
! 				 group_size,
! 				 &ppc_add_stub_section,
! 				 &ppc_layout_sections_again))
! 	{
! 	  einfo ("%X%P: can not size stub section: %E\n");
! 	  return;
  	}
      }
  
--- 290,321 ----
    if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
      need_laying_out = 1;
  
!   /* If generating a relocatable output file, then we don't have any
!      stubs.  */
!   if (!link_info.relocateable)
      {
!       int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
!       if (ret != 0)
  	{
! 	  if (ret < 0)
! 	    {
! 	      einfo ("%X%P: can not size stub section: %E\n");
! 	      return;
! 	    }
  
! 	  lang_for_each_statement (build_section_lists);
  
! 	  /* Call into the BFD backend to do the real work.  */
! 	  if (!ppc64_elf_size_stubs (output_bfd,
! 				     stub_file->the_bfd,
! 				     &link_info,
! 				     group_size,
! 				     &ppc_add_stub_section,
! 				     &ppc_layout_sections_again))
! 	    {
! 	      einfo ("%X%P: can not size stub section: %E\n");
! 	      return;
! 	    }
  	}
      }
  
*************** PARSE_AND_LIST_ARGS_CASES='
*** 486,491 ****
--- 497,503 ----
  # Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
  #
  LDEMUL_AFTER_OPEN=ppc_after_open
+ LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
  LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
  LDEMUL_FINISH=gld${EMULATION_NAME}_finish
  LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list