This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
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