ppc64 dot symbols
Alan Modra
amodra@bigpond.net.au
Mon Aug 9 03:12:00 GMT 2004
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
More information about the Binutils
mailing list