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: [RFC] Providing init_fini_syms earlier?


On Wed, Jul 13, 2005 at 11:18:25PM +0930, Alan Modra wrote:
> On Wed, Jul 13, 2005 at 11:02:11PM +0930, Alan Modra wrote:
> > On Tue, Jul 12, 2005 at 05:47:12PM -0700, H. J. Lu wrote:
> > > The final values have to be absulte.
> > 
> > Why?
> > 
> > > How does it support relaxation
> > > when it will be called more then once?
> > 
> > If they are section relative, then there is no problem with relaxation
> > unless the init or fini sections change size, which I think is
> > unlikely to happen.  There is one disadvantage of section relative syms;
> > They cause their output section to be kept.  Hmm, I suppose we could
> > change that.  We might even be able to do without bfd_mark_used_section
> > entirely now that vma is set correctly for stripped output sections.
> 
> Oh, except you would need to convert the syms to absolute if their
> output section was stripped.  Was that why you were saying they needed
> to be absolute?

This is how I think we should handle these symbols.

bfd/
	* bfd-in.h (_bfd_elf_fix_excluded_sec_syms): Declare.
	(_bfd_elf_provide_section_bound_symbols): Remove param name.
	Formatting.
	* bfd-in2.h: Regenerate.
	* elflink.c (bfd_elf_gc_sections): Don't call generic function.
	(_bfd_elf_provide_symbol): Formatting.
	(_bfd_elf_provide_section_bound_symbols): Remove all hacks, just
	create section relative syms.
	(fix_syms, _bfd_elf_fix_excluded_sec_syms): New functions.
	* elf32-ppc.c (ppc_elf_set_sdata_syms): Use
	_bfd_elf_provide_section_bound_symbols.
	* reloc.c (bfd_mark_used_section): Delete.
	(bfd_generic_gc_sections): Don't call the above.
ld/
	* ldlang.c (strip_excluded_output_sections): Don't call
	bfd_gc_sections.
	* emultempl/elf32.em (gld*_provide_bound_symbols): Move.
	(gld*_provide_init_fini_syms): Move.
	(gld*_before_allocation): Call the above from here..
	(gld*_finish): ..not here.  Call _bfd_elf_fix_excluded_sec_syms.
	* emultempl/hppaelf.em (hppaelf_finish): Likewise.
	* emultempl/ppc64elf.em (ppc_finish): Likewise.

Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.104
diff -c -p -r1.104 bfd-in.h
*** bfd/bfd-in.h	5 Jul 2005 09:44:18 -0000	1.104
--- bfd/bfd-in.h	14 Jul 2005 13:42:27 -0000
*************** extern void _bfd_elf_provide_symbol
*** 704,713 ****
    (struct bfd_link_info *, const char *, bfd_vma, struct bfd_section *);
  
  extern void _bfd_elf_provide_section_bound_symbols
!   (struct bfd_link_info *, struct bfd_section *sec, const char *, const char *);
  
  extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
!   (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
  
  /* SunOS shared library support routines for the linker.  */
  
--- 704,717 ----
    (struct bfd_link_info *, const char *, bfd_vma, struct bfd_section *);
  
  extern void _bfd_elf_provide_section_bound_symbols
!   (struct bfd_link_info *, struct bfd_section *, const char *, const char *);
! 
! extern void _bfd_elf_fix_excluded_sec_syms
!   (bfd *, struct bfd_link_info *);
  
  extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
!   (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
!    char **);
  
  /* SunOS shared library support routines for the linker.  */
  
*************** extern struct bfd_link_needed_list *bfd_
*** 716,722 ****
  extern bfd_boolean bfd_sunos_record_link_assignment
    (bfd *, struct bfd_link_info *, const char *);
  extern bfd_boolean bfd_sunos_size_dynamic_sections
!   (bfd *, struct bfd_link_info *, struct bfd_section **, struct bfd_section **, struct bfd_section **);
  
  /* Linux shared library support routines for the linker.  */
  
--- 720,727 ----
  extern bfd_boolean bfd_sunos_record_link_assignment
    (bfd *, struct bfd_link_info *, const char *);
  extern bfd_boolean bfd_sunos_size_dynamic_sections
!   (bfd *, struct bfd_link_info *, struct bfd_section **,
!    struct bfd_section **, struct bfd_section **);
  
  /* Linux shared library support routines for the linker.  */
  
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.172
diff -c -p -r1.172 elf32-ppc.c
*** bfd/elf32-ppc.c	12 Jul 2005 11:39:42 -0000	1.172
--- bfd/elf32-ppc.c	14 Jul 2005 13:42:39 -0000
*************** ppc_elf_set_sdata_syms (bfd *obfd, struc
*** 5307,5319 ****
      }
  
    s = bfd_get_section_by_name (obfd, ".sbss");
!   val = 0;
!   _bfd_elf_provide_symbol (info, "__sbss_start", val, s);
!   _bfd_elf_provide_symbol (info, "___sbss_start", val, s);
!   if (s != NULL)
!     val = s->size;
!   _bfd_elf_provide_symbol (info, "__sbss_end", val, s);
!   _bfd_elf_provide_symbol (info, "___sbss_end", val, s);
    return TRUE;
  }
  
--- 5307,5316 ----
      }
  
    s = bfd_get_section_by_name (obfd, ".sbss");
!   _bfd_elf_provide_section_bound_symbols (info, s,
! 					  "__sbss_start", "__sbss_end");
!   _bfd_elf_provide_section_bound_symbols (info, s,
! 					  "___sbss_start", "___sbss_end");
    return TRUE;
  }
  
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.174
diff -c -p -r1.174 elflink.c
*** bfd/elflink.c	11 Jul 2005 17:40:25 -0000	1.174
--- bfd/elflink.c	14 Jul 2005 13:42:47 -0000
*************** bfd_elf_gc_sections (bfd *abfd, struct b
*** 9119,9127 ****
      (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
       struct elf_link_hash_entry *h, Elf_Internal_Sym *);
  
-   if (!info->gc_sections)
-     return bfd_generic_gc_sections (abfd, info);
- 
    if (!get_elf_backend_data (abfd)->can_gc_sections
        || info->relocatable
        || info->emitrelocations
--- 9119,9124 ----
*************** _bfd_elf_provide_symbol (struct bfd_link
*** 9846,9853 ****
  {
    struct elf_link_hash_entry *h;
  
!   h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE,
! 			    FALSE);
    if (h != NULL && !h->def_regular)
      bfd_elf_set_symbol (h, val, s);
  }
--- 9843,9849 ----
  {
    struct elf_link_hash_entry *h;
  
!   h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
    if (h != NULL && !h->def_regular)
      bfd_elf_set_symbol (h, val, s);
  }
*************** _bfd_elf_provide_section_bound_symbols (
*** 9861,9905 ****
  					const char *start,
  					const char *end)
  {
!   struct elf_link_hash_entry *hs, *he;
!   bfd_vma start_val, end_val;
!   bfd_boolean do_start, do_end;
! 
!   /* Check if we need them or not first.  */
!   hs = elf_link_hash_lookup (elf_hash_table (info), start, FALSE,
! 			     FALSE, FALSE);
!   do_start = hs != NULL && !hs->def_regular;
! 
!   he = elf_link_hash_lookup (elf_hash_table (info), end, FALSE,
! 			     FALSE, FALSE);
!   do_end = he != NULL && !he->def_regular;
  
!   if (!do_start && !do_end)
!     return;
  
!   if (sec != NULL)
!     {
!       start_val = sec->vma;
!       end_val = start_val + sec->size;
!     }
!   else
      {
!       /* We have to choose those values very carefully.  Some targets,
! 	 like alpha, may have relocation overflow with 0. "__bss_start"
! 	 should be defined in all cases.  */
!       struct elf_link_hash_entry *h
! 	= elf_link_hash_lookup (elf_hash_table (info), "__bss_start",
! 				FALSE, FALSE, FALSE);
!       if (h != NULL && h->root.type == bfd_link_hash_defined)
! 	start_val = h->root.u.def.value;
!       else
! 	start_val = 0;
!       end_val = start_val;
      }
  
!   if (do_start)
!     bfd_elf_set_symbol (hs, start_val, NULL);
  
!   if (do_end)
!     bfd_elf_set_symbol (he, end_val, NULL);
  }
--- 9857,9897 ----
  					const char *start,
  					const char *end)
  {
!   bfd_vma val = 0;
!   _bfd_elf_provide_symbol (info, start, val, sec);
!   if (sec != NULL)
!     val = sec->size;
!   _bfd_elf_provide_symbol (info, end, val, sec);
! }
  
! /* Convert symbols in excluded output sections to absolute.  */
  
! static bfd_boolean
! fix_syms (struct bfd_link_hash_entry *h, void *data)
! {
!   bfd *obfd = (bfd *) data;
! 
!   if (h->type == bfd_link_hash_warning)
!     h = h->u.i.link;
! 
!   if (h->type == bfd_link_hash_defined
!       || h->type == bfd_link_hash_defweak)
      {
!       asection *s = h->u.def.section;
!       if (s != NULL
! 	  && s == s->output_section
! 	  && bfd_section_removed_from_list (obfd, s))
! 	{
! 	  h->u.def.value += s->vma;
! 	  h->u.def.section = bfd_abs_section_ptr;
! 	}
      }
  
!   return TRUE;
! }
  
! void
! _bfd_elf_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info)
! {
!   bfd_link_hash_traverse (info->hash, fix_syms, obfd);
  }
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.130
diff -c -p -r1.130 reloc.c
*** bfd/reloc.c	18 Jun 2005 13:23:06 -0000	1.130
--- bfd/reloc.c	14 Jul 2005 13:42:47 -0000
*************** bfd_generic_relax_section (bfd *abfd ATT
*** 4520,4546 ****
    return TRUE;
  }
  
- /* Mark sections containing global symbols.  This is called through
-    bfd_link_hash_traverse.  */
- 
- static bfd_boolean
- bfd_mark_used_section (struct bfd_link_hash_entry *h,
- 		       void *data ATTRIBUTE_UNUSED)
- {
-   if (h->type == bfd_link_hash_warning)
-     h = h->u.i.link;
- 
-   if (h->type == bfd_link_hash_defined
-       || h->type == bfd_link_hash_defweak)
-     {
-       asection *s = h->u.def.section;
-       if (s != NULL && s->output_section != NULL)
- 	s->output_section->flags |= SEC_KEEP;
-     }
- 
-   return TRUE;
- }
- 
  /*
  INTERNAL_FUNCTION
  	bfd_generic_gc_sections
--- 4520,4525 ----
*************** SYNOPSIS
*** 4551,4568 ****
  
  DESCRIPTION
  	Provides default handling for relaxing for back ends which
! 	don't do section gc -- i.e., does nothing besides the special
! 	case for marking sections having global symbols.
  */
  
  bfd_boolean
  bfd_generic_gc_sections (bfd *abfd ATTRIBUTE_UNUSED,
! 			 struct bfd_link_info *info)
  {
-   /* If called when info->gc_sections is 0, then mark all sections
-      containing global symbols with SEC_KEEP.  */
-   if (!info->gc_sections && !info->relocatable)
-     bfd_link_hash_traverse (info->hash, bfd_mark_used_section, NULL);
    return TRUE;
  }
  
--- 4530,4542 ----
  
  DESCRIPTION
  	Provides default handling for relaxing for back ends which
! 	don't do section gc -- i.e., does nothing.
  */
  
  bfd_boolean
  bfd_generic_gc_sections (bfd *abfd ATTRIBUTE_UNUSED,
! 			 struct bfd_link_info *info ATTRIBUTE_UNUSED)
  {
    return TRUE;
  }
  
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.190
diff -c -p -r1.190 ldlang.c
*** ld/ldlang.c	8 Jul 2005 06:20:15 -0000	1.190
--- ld/ldlang.c	14 Jul 2005 13:43:15 -0000
*************** void
*** 3049,3055 ****
  strip_excluded_output_sections (void)
  {
    lang_output_section_statement_type *os;
-   unsigned int gc_sections;
  
    /* Run lang_size_sections (if not already done) to ensure that all
       symbols defined in the linker script are put in the bfd hash
--- 3049,3054 ----
*************** strip_excluded_output_sections (void)
*** 3062,3074 ****
        lang_reset_memory_regions ();
      }
  
-   /* Now call into bfd_gc_sections to mark all sections defining global
-      symbols with SEC_KEEP.  */
-   gc_sections = link_info.gc_sections;
-   link_info.gc_sections = 0;
-   bfd_gc_sections (output_bfd, &link_info);
-   link_info.gc_sections = gc_sections;
- 
    for (os = &lang_output_section_statement.head->output_section_statement;
         os != NULL;
         os = os->next)
--- 3061,3066 ----
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.150
diff -c -p -r1.150 elf32.em
*** ld/emultempl/elf32.em	8 Jul 2005 06:20:15 -0000	1.150
--- ld/emultempl/elf32.em	14 Jul 2005 13:43:16 -0000
*************** static void gld${EMULATION_NAME}_before_
*** 61,67 ****
  static bfd_boolean gld${EMULATION_NAME}_place_orphan
    (lang_input_statement_type *file, asection *s);
  static void gld${EMULATION_NAME}_layout_sections_again (void);
- static void gld${EMULATION_NAME}_provide_init_fini_syms (void);
  static void gld${EMULATION_NAME}_finish (void) ATTRIBUTE_UNUSED;
  
  EOF
--- 61,66 ----
*************** if test x"$LDEMUL_BEFORE_ALLOCATION" != 
*** 1040,1045 ****
--- 1039,1085 ----
    fi
  cat >>e${EMULATION_NAME}.c <<EOF
  
+ static void
+ gld${EMULATION_NAME}_provide_bound_symbols (const char *sec,
+ 					    const char *start,
+ 					    const char *end)
+ {
+   asection *s = bfd_get_section_by_name (output_bfd, sec);
+   _bfd_elf_provide_section_bound_symbols (&link_info, s, start, end);
+ }
+ 
+ /* If not building a shared library, provide
+ 
+    __preinit_array_start
+    __preinit_array_end
+    __init_array_start
+    __init_array_end
+    __fini_array_start
+    __fini_array_end
+ 
+    They are set here rather than via PROVIDE in the linker
+    script, because using PROVIDE inside an output section
+    statement results in unnecessary output sections.  Using
+    PROVIDE outside an output section statement runs the risk of
+    section alignment affecting where the section starts.  */
+ 
+ static void
+ gld${EMULATION_NAME}_provide_init_fini_syms (void)
+ {
+   if (!link_info.relocatable && link_info.executable)
+     {
+       gld${EMULATION_NAME}_provide_bound_symbols (".preinit_array",
+ 						  "__preinit_array_start",
+ 						  "__preinit_array_end");
+       gld${EMULATION_NAME}_provide_bound_symbols (".init_array",
+ 						  "__init_array_start",
+ 						  "__init_array_end");
+       gld${EMULATION_NAME}_provide_bound_symbols (".fini_array",
+ 						  "__fini_array_start",
+ 						  "__fini_array_end");
+     }
+ }
+ 
  /* This is called after the sections have been attached to output
     sections, but before any sizes or addresses have been set.  */
  
*************** gld${EMULATION_NAME}_before_allocation (
*** 1057,1062 ****
--- 1097,1104 ----
       referred to by dynamic objects.  */
    lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
  
+   gld${EMULATION_NAME}_provide_init_fini_syms ();
+ 
    /* Let the ELF backend work out the sizes of any sections required
       by dynamic linking.  */
    rpath = command_line.rpath;
*************** if test x"$LDEMUL_FINISH" != xgld"$EMULA
*** 1448,1496 ****
  cat >>e${EMULATION_NAME}.c <<EOF
  
  static void
- gld${EMULATION_NAME}_provide_bound_symbols (const char *sec,
- 					    const char *start,
- 					    const char *end)
- {
-   asection *s = bfd_get_section_by_name (output_bfd, sec);
-   if (s && bfd_section_removed_from_list (output_bfd, s))
-     s = NULL;
-   _bfd_elf_provide_section_bound_symbols (&link_info, s, start, end);
- }
- 
- /* If not building a shared library, provide
- 
-    __preinit_array_start
-    __preinit_array_end
-    __init_array_start
-    __init_array_end
-    __fini_array_start
-    __fini_array_end
- 
-    They are set here rather than via PROVIDE in the linker
-    script, because using PROVIDE inside an output section
-    statement results in unnecessary output sections.  Using
-    PROVIDE outside an output section statement runs the risk of
-    section alignment affecting where the section starts.  */
- 
- static void
- gld${EMULATION_NAME}_provide_init_fini_syms (void)
- {
-   if (!link_info.relocatable && link_info.executable)
-     {
-       gld${EMULATION_NAME}_provide_bound_symbols (".preinit_array",
- 						  "__preinit_array_start",
- 						  "__preinit_array_end");
-       gld${EMULATION_NAME}_provide_bound_symbols (".init_array",
- 						  "__init_array_start",
- 						  "__init_array_end");
-       gld${EMULATION_NAME}_provide_bound_symbols (".fini_array",
- 						  "__fini_array_start",
- 						  "__fini_array_end");
-     }
- }
- 
- static void
  gld${EMULATION_NAME}_layout_sections_again (void)
  {
    lang_reset_memory_regions ();
--- 1490,1495 ----
*************** gld${EMULATION_NAME}_finish (void)
*** 1511,1517 ****
    if (bfd_elf_discard_info (output_bfd, &link_info))
      gld${EMULATION_NAME}_layout_sections_again ();
  
!   gld${EMULATION_NAME}_provide_init_fini_syms ();
  }
  EOF
  fi
--- 1510,1516 ----
    if (bfd_elf_discard_info (output_bfd, &link_info))
      gld${EMULATION_NAME}_layout_sections_again ();
  
!   _bfd_elf_fix_excluded_sec_syms (output_bfd, &link_info);
  }
  EOF
  fi
Index: ld/emultempl/hppaelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/hppaelf.em,v
retrieving revision 1.42
diff -c -p -r1.42 hppaelf.em
*** ld/emultempl/hppaelf.em	8 Jul 2005 06:20:16 -0000	1.42
--- ld/emultempl/hppaelf.em	14 Jul 2005 13:43:16 -0000
*************** hppaelf_finish (void)
*** 305,311 ****
  	}
      }
  
!   gld${EMULATION_NAME}_provide_init_fini_syms ();
  }
  
  
--- 305,311 ----
  	}
      }
  
!   _bfd_elf_fix_excluded_sec_syms (output_bfd, &link_info);
  }
  
  
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.46
diff -c -p -r1.46 ppc64elf.em
*** ld/emultempl/ppc64elf.em	8 Jul 2005 06:20:16 -0000	1.46
--- ld/emultempl/ppc64elf.em	14 Jul 2005 13:43:17 -0000
*************** ppc_finish (void)
*** 379,385 ****
      }
  
    ppc64_elf_restore_symbols (&link_info);
!   gld${EMULATION_NAME}_provide_init_fini_syms ();
  }
  
  
--- 379,385 ----
      }
  
    ppc64_elf_restore_symbols (&link_info);
!   _bfd_elf_fix_excluded_sec_syms (output_bfd, &link_info);
  }
  
  

-- 
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]