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]

Re: ppc64 dot symbols


ppc64_elf_gc_mark_hook had hopelessly confused logic.  It's a wonder it
ever worked..  On PowerPC64, an R_PPC64_REL24 or similar reloc really
references two sections; the function code section, and the function
descriptor section.

bfd/ChangeLog
	* elf-bfd.h (_bfd_elf_gc_mark): Declare.
	* elflink.c (elf_link_input_bfd): Formatting.
	(_bfd_elf_gc_mark): Rename from elf_gc_mark and make global.  Adjust
	all callers.
	* elf64-ppc.c (struct ppc_link_hash_entry): Remove is_entry.
	(link_hash_newfunc): Don't set it.
	(ppc64_elf_copy_indirect_symbol): Nor copy it.
	(ppc64_elf_mark_entry_syms): Delete.
	(ppc64_elf_gc_mark_hook): Mark entry syms here.  Also mark opd
	sections.  Use get_opd_info.
	* elf64-ppc.h (ppc64_elf_mark_entry_syms): Delete.
ld/ChangeLog
	* emultempl/ppc64elf.em (ppc_after_open): Delete.
	(LDEMUL_AFTER_OPEN): Don't define.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.151
diff -u -p -r1.151 elf-bfd.h
--- bfd/elf-bfd.h	30 Jul 2004 15:37:04 -0000	1.151
+++ bfd/elf-bfd.h	9 Aug 2004 02:48:37 -0000
@@ -1710,6 +1710,11 @@ extern bfd_boolean bfd_elf_gc_record_vti
 extern bfd_boolean bfd_elf_gc_record_vtentry
   (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma);
 
+extern bfd_boolean _bfd_elf_gc_mark
+  (struct bfd_link_info *, asection *,
+   asection * (*) (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+		   struct elf_link_hash_entry *, Elf_Internal_Sym *));
+
 extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
   (bfd *, struct bfd_link_info *);
 
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.152
diff -u -p -r1.152 elf64-ppc.c
--- bfd/elf64-ppc.c	9 Aug 2004 00:54:28 -0000	1.152
+++ bfd/elf64-ppc.c	9 Aug 2004 02:48:44 -0000
@@ -2776,7 +2776,6 @@ struct ppc_link_hash_entry
   /* Flag function code and descriptor symbols.  */
   unsigned int is_func:1;
   unsigned int is_func_descriptor:1;
-  unsigned int is_entry:1;
 
   /* Whether global opd sym has been adjusted or not.  */
   unsigned int adjust_done:1;
@@ -2986,7 +2985,6 @@ link_hash_newfunc (struct bfd_hash_entry
       eh->oh = NULL;
       eh->is_func = 0;
       eh->is_func_descriptor = 0;
-      eh->is_entry = 0;
       eh->adjust_done = 0;
       eh->tls_mask = 0;
     }
@@ -3372,7 +3370,6 @@ ppc64_elf_copy_indirect_symbol
 
   edir->is_func |= eind->is_func;
   edir->is_func_descriptor |= eind->is_func_descriptor;
-  edir->is_entry |= eind->is_entry;
   edir->tls_mask |= eind->tls_mask;
 
   mask = (ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR
@@ -3464,27 +3461,6 @@ ppc64_elf_copy_indirect_symbol
     BFD_ASSERT (eind->elf.dynindx == -1);
 }
 
-/* Set a flag, used by ppc64_elf_gc_mark_hook, on the entry symbol and
-   symbols undefined on the command-line.  */
-
-bfd_boolean
-ppc64_elf_mark_entry_syms (struct bfd_link_info *info)
-{
-  struct ppc_link_hash_table *htab;
-  struct bfd_sym_chain *sym;
-
-  htab = ppc_hash_table (info);
-  for (sym = info->gc_sym_list; sym; sym = sym->next)
-    {
-      struct elf_link_hash_entry *h;
-
-      h = elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE);
-      if (h != NULL)
-	((struct ppc_link_hash_entry *) h)->is_entry = 1;
-    }
-  return TRUE;
-}
-
 /* Hack symbols defined in .opd sections to be function type.  */
 
 static bfd_boolean
@@ -4121,17 +4097,59 @@ ppc64_elf_check_relocs (bfd *abfd, struc
 
 static asection *
 ppc64_elf_gc_mark_hook (asection *sec,
-			struct bfd_link_info *info ATTRIBUTE_UNUSED,
+			struct bfd_link_info *info,
 			Elf_Internal_Rela *rel,
 			struct elf_link_hash_entry *h,
 			Elf_Internal_Sym *sym)
 {
-  asection *rsec = NULL;
+  asection *rsec;
+
+  /* First mark all our entry sym sections.  */
+  if (info->gc_sym_list != NULL)
+    {
+      struct ppc_link_hash_table *htab = ppc_hash_table (info);
+      struct bfd_sym_chain *sym = info->gc_sym_list;
+
+      info->gc_sym_list = NULL;
+      do
+	{
+	  struct ppc_link_hash_entry *eh;
+
+	  eh = (struct ppc_link_hash_entry *)
+	    elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE);
+	  if (eh == NULL)
+	    continue;
+	  if (eh->elf.root.type != bfd_link_hash_defined
+	      && eh->elf.root.type != bfd_link_hash_defweak)
+	    continue;
+
+	  if (eh->is_func_descriptor)
+	    rsec = eh->oh->elf.root.u.def.section;
+	  else
+	    continue;
+
+	  if (!rsec->gc_mark)
+	    _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
+
+	  rsec = eh->elf.root.u.def.section;
+	  if (!rsec->gc_mark)
+	    _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
+
+	  sym = sym->next;
+	}
+      while (sym != NULL);
+    }
+
+  /* Syms return NULL if we're marking .opd, so we avoid marking all
+     function sections, as all functions are referenced in .opd.  */
+  rsec = NULL;
+  if (get_opd_info (sec) != NULL)
+    return rsec;
 
   if (h != NULL)
     {
       enum elf_ppc64_reloc_type r_type;
-      struct ppc_link_hash_entry *fdh;
+      struct ppc_link_hash_entry *eh;
 
       r_type = ELF64_R_TYPE (rel->r_info);
       switch (r_type)
@@ -4145,19 +4163,22 @@ ppc64_elf_gc_mark_hook (asection *sec,
 	    {
 	    case bfd_link_hash_defined:
 	    case bfd_link_hash_defweak:
-	      fdh = (struct ppc_link_hash_entry *) h;
+	      eh = (struct ppc_link_hash_entry *) h;
+	      if (eh->oh != NULL && eh->oh->is_func_descriptor)
+		eh = eh->oh;
 
 	      /* Function descriptor syms cause the associated
 		 function code sym section to be marked.  */
-	      if (fdh->is_func_descriptor)
-		rsec = fdh->oh->elf.root.u.def.section;
+	      if (eh->is_func_descriptor)
+		{
+		  /* They also mark their opd section.  */
+		  if (!eh->elf.root.u.def.section->gc_mark)
+		    _bfd_elf_gc_mark (info, eh->elf.root.u.def.section,
+				      ppc64_elf_gc_mark_hook);
 
-	      /* Function entry syms return NULL if they are in .opd
-		 and are not ._start (or others undefined on the ld
-		 command line).  Thus we avoid marking all function
-		 sections, as all functions are referenced in .opd.  */
-	      else if ((fdh->oh != NULL && fdh->oh->is_entry)
-		       || ppc64_elf_section_data (sec)->opd.func_sec == NULL)
+		  rsec = eh->oh->elf.root.u.def.section;
+		}
+	      else
 		rsec = h->root.u.def.section;
 	      break;
 
@@ -4175,11 +4196,14 @@ ppc64_elf_gc_mark_hook (asection *sec,
       asection **opd_sym_section;
 
       rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-      opd_sym_section = ppc64_elf_section_data (rsec)->opd.func_sec;
+      opd_sym_section = get_opd_info (rsec);
       if (opd_sym_section != NULL)
-	rsec = opd_sym_section[sym->st_value / 24];
-      else if (ppc64_elf_section_data (sec)->opd.func_sec != NULL)
-	rsec = NULL;
+	{
+	  if (!rsec->gc_mark)
+	    _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
+
+	  rsec = opd_sym_section[sym->st_value / 24];
+	}
     }
 
   return rsec;
Index: bfd/elf64-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.h,v
retrieving revision 1.14
diff -u -p -r1.14 elf64-ppc.h
--- bfd/elf64-ppc.h	4 Nov 2003 06:16:37 -0000	1.14
+++ bfd/elf64-ppc.h	9 Aug 2004 02:48:44 -0000
@@ -1,5 +1,5 @@
 /* PowerPC64-specific support for 64-bit ELF.
-   Copyright 2002, 2003 Free Software Foundation, Inc.
+   Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -19,8 +19,6 @@ Foundation, Inc., 59 Temple Place - Suit
 
 void ppc64_elf_init_stub_bfd
   (bfd *, struct bfd_link_info *);
-bfd_boolean ppc64_elf_mark_entry_syms
-  (struct bfd_link_info *);
 bfd_boolean ppc64_elf_edit_opd
   (bfd *, struct bfd_link_info *);
 asection *ppc64_elf_tls_setup
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.91
diff -u -p -r1.91 elflink.c
--- bfd/elflink.c	30 Jul 2004 15:37:04 -0000	1.91
+++ bfd/elflink.c	9 Aug 2004 02:48:47 -0000
@@ -6710,10 +6710,9 @@ elf_link_input_bfd (struct elf_final_lin
 			}
 		      else if (complain)
 			{
-			  char *r_sec
-			    = bfd_get_section_ident (o);
-			  char *d_sec
-			    = bfd_get_section_ident (sec);
+			  char *r_sec = bfd_get_section_ident (o);
+			  char *d_sec = bfd_get_section_ident (sec);
+
 			  finfo->info->callbacks->error_handler
 			    (LD_DEFINITION_IN_DISCARDED_SECTION,
 			     _("`%T' referenced in section `%s' of %B: "
@@ -8366,10 +8365,10 @@ typedef asection * (*gc_mark_hook_fn)
   (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
-static bfd_boolean
-elf_gc_mark (struct bfd_link_info *info,
-	     asection *sec,
-	     gc_mark_hook_fn gc_mark_hook)
+bfd_boolean
+_bfd_elf_gc_mark (struct bfd_link_info *info,
+		  asection *sec,
+		  gc_mark_hook_fn gc_mark_hook)
 {
   bfd_boolean ret;
   asection *group_sec;
@@ -8379,7 +8378,7 @@ elf_gc_mark (struct bfd_link_info *info,
   /* Mark all the sections in the group.  */
   group_sec = elf_section_data (sec)->next_in_group;
   if (group_sec && !group_sec->gc_mark)
-    if (!elf_gc_mark (info, group_sec, gc_mark_hook))
+    if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook))
       return FALSE;
 
   /* Look through the section relocs.  */
@@ -8460,7 +8459,7 @@ elf_gc_mark (struct bfd_link_info *info,
 	    {
 	      if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
 		rsec->gc_mark = 1;
-	      else if (!elf_gc_mark (info, rsec, gc_mark_hook))
+	      else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
 		{
 		  ret = FALSE;
 		  goto out2;
@@ -8767,7 +8766,7 @@ bfd_elf_gc_sections (bfd *abfd, struct b
 		 EH frame section.  */  
 	      if (strcmp (o->name, ".eh_frame") == 0)
 		o->gc_mark = 1;
-	      else if (!elf_gc_mark (info, o, gc_mark_hook))
+	      else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
 		return FALSE;
 	    }
 	}
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.28
diff -u -p -r1.28 ppc64elf.em
--- ld/emultempl/ppc64elf.em	25 May 2004 06:33:51 -0000	1.28
+++ ld/emultempl/ppc64elf.em	9 Aug 2004 02:48:47 -0000
@@ -85,18 +85,6 @@ ppc_create_output_section_statements (vo
 }
 
 static void
-ppc_after_open (void)
-{
-  if (!ppc64_elf_mark_entry_syms (&link_info))
-    {
-      einfo ("%X%P: can not mark entry symbols %E\n");
-      return;
-    }
-
-  gld${EMULATION_NAME}_after_open ();
-}
-
-static void
 ppc_before_allocation (void)
 {
   if (stub_file != NULL)
@@ -523,7 +511,6 @@ PARSE_AND_LIST_ARGS_CASES='
 
 # 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

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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