PR 5604
	* elf-bfd.h (struct elf_backend_data): Add gc_keep.  Remove param
	names from others.
	(_bfd_elf_gc_keep): Declare.
	* elfxx-target.h (elf_backend_gc_keep): Define.
	(elfNN_bed): Init new field.
	* elflink.c (_bfd_elf_gc_keep): New function.
	(bfd_elf_gc_sections): Call gc_keep.
	* elf64-ppc.c (elf_backend_gc_keep): Define.
	(struct _ppc64_elf_section_data): Move .opd related fields to
	a struct so they don't occupy the same storage.  Adjust accesses
	throughout file.
	(ppc64_elf_gc_keep): New function, split out from..
	(ppc64_elf_gc_mark_hook): ..here.  Don't call _bfd_elf_gc_mark
	to mark .opd section, just set gc_mark.
	(ppc64_elf_edit_opd): Remove no_opd_opt parm.  Don't set opd->adjust
	unless we are changing .opd.  Test non-NULL opd->adjust at all
	accesses throughout file.
	* elf64-ppc.h (ppc64_elf_edit_opd): Update prototype.
ld/
	PR 5604
	* ldlang.c (lang_gc_sections): Move code to set SEC_KEEP on entry
	syms to _bfd_elf_gc_keep.
	* emultempl/ppc64elf.em (ppc_before_allocation): Don't call
	ppc64_elf_edit_opd if no_opd_opt.
This commit is contained in:
Alan Modra 2008-01-15 07:25:49 +00:00
parent 5c07affcae
commit 74f0fb5065
9 changed files with 180 additions and 152 deletions

View File

@ -1,3 +1,25 @@
2008-01-15 Alan Modra <amodra@bigpond.net.au>
PR 5604
* elf-bfd.h (struct elf_backend_data): Add gc_keep. Remove param
names from others.
(_bfd_elf_gc_keep): Declare.
* elfxx-target.h (elf_backend_gc_keep): Define.
(elfNN_bed): Init new field.
* elflink.c (_bfd_elf_gc_keep): New function.
(bfd_elf_gc_sections): Call gc_keep.
* elf64-ppc.c (elf_backend_gc_keep): Define.
(struct _ppc64_elf_section_data): Move .opd related fields to
a struct so they don't occupy the same storage. Adjust accesses
throughout file.
(ppc64_elf_gc_keep): New function, split out from..
(ppc64_elf_gc_mark_hook): ..here. Don't call _bfd_elf_gc_mark
to mark .opd section, just set gc_mark.
(ppc64_elf_edit_opd): Remove no_opd_opt parm. Don't set opd->adjust
unless we are changing .opd. Test non-NULL opd->adjust at all
accesses throughout file.
* elf64-ppc.h (ppc64_elf_edit_opd): Update prototype.
2008-01-15 Alan Modra <amodra@bigpond.net.au>
* bfd-in.h (BFD_HOST_LONG_LONG): Delete.

View File

@ -1,6 +1,6 @@
/* BFD back-end data structures for ELF files.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -915,10 +915,15 @@ struct elf_backend_data
bfd_boolean (*elf_backend_modify_program_headers)
(bfd *, struct bfd_link_info *);
/* This function is called before section garbage collection to
mark entry symbol sections. */
void (*gc_keep)
(struct bfd_link_info *);
/* This function is called during section garbage collection to
mark sections that define global symbols. */
bfd_boolean (*gc_mark_dynamic_ref)
(struct elf_link_hash_entry *h, void *inf);
(struct elf_link_hash_entry *, void *);
/* This function is called during section gc to discover the section a
particular relocation refers to. */
@ -927,14 +932,13 @@ struct elf_backend_data
/* This function, if defined, is called after the first gc marking pass
to allow the backend to mark additional sections. */
bfd_boolean (*gc_mark_extra_sections)
(struct bfd_link_info *info, elf_gc_mark_hook_fn gc_mark_hook);
(struct bfd_link_info *, elf_gc_mark_hook_fn);
/* This function, if defined, is called during the sweep phase of gc
in order that a backend might update any data structures it might
be maintaining. */
bfd_boolean (*gc_sweep_hook)
(bfd *abfd, struct bfd_link_info *info, asection *o,
const Elf_Internal_Rela *relocs);
(bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
/* This function, if defined, is called after the ELF headers have
been created. This allows for things like the OS and ABI versions
@ -2034,6 +2038,9 @@ extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
extern bfd_boolean bfd_elf_final_link
(bfd *, struct bfd_link_info *);
extern void _bfd_elf_gc_keep
(struct bfd_link_info *info);
extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol
(struct elf_link_hash_entry *h, void *inf);

View File

@ -1,5 +1,5 @@
/* PowerPC64-specific support for 64-bit ELF.
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Written by Linus Nordberg, Swox AB <info@swox.com>,
based on elf32-ppc.c by Ian Lance Taylor.
@ -96,6 +96,7 @@ static bfd_vma opd_entry_value
#define elf_backend_as_needed_cleanup ppc64_elf_as_needed_cleanup
#define elf_backend_archive_symbol_lookup ppc64_elf_archive_symbol_lookup
#define elf_backend_check_relocs ppc64_elf_check_relocs
#define elf_backend_gc_keep ppc64_elf_gc_keep
#define elf_backend_gc_mark_dynamic_ref ppc64_elf_gc_mark_dynamic_ref
#define elf_backend_gc_mark_hook ppc64_elf_gc_mark_hook
#define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook
@ -2608,13 +2609,17 @@ struct _ppc64_elf_section_data
{
struct bfd_elf_section_data elf;
/* An array with one entry for each opd function descriptor. */
union
{
/* Points to the function code section for local opd entries. */
asection **opd_func_sec;
/* After editing .opd, adjust references to opd local syms. */
long *opd_adjust;
/* An array with one entry for each opd function descriptor. */
struct _opd_sec_data
{
/* Points to the function code section for local opd entries. */
asection **func_sec;
/* After editing .opd, adjust references to opd local syms. */
long *adjust;
} opd;
/* An array for toc sections, indexed by offset/8.
Specifies the relocation symbol index used at a given toc offset. */
@ -2648,13 +2653,13 @@ ppc64_elf_new_section_hook (bfd *abfd, asection *sec)
return _bfd_elf_new_section_hook (abfd, sec);
}
static void *
static struct _opd_sec_data *
get_opd_info (asection * sec)
{
if (sec != NULL
&& ppc64_elf_section_data (sec) != NULL
&& ppc64_elf_section_data (sec)->sec_type == sec_opd)
return ppc64_elf_section_data (sec)->u.opd_adjust;
return &ppc64_elf_section_data (sec)->u.opd;
return NULL;
}
@ -4438,20 +4443,14 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if we reference an .opd symbol (a function descriptor), we
want to keep the function code symbol's section. This is
easy for global symbols, but for local syms we need to keep
information about the associated function section. Later, if
edit_opd deletes entries, we'll use this array to adjust
local syms in .opd. */
union opd_info {
asection *func_section;
long entry_adjust;
};
information about the associated function section. */
bfd_size_type amt;
amt = sec->size * sizeof (union opd_info) / 8;
amt = sec->size * sizeof (*opd_sym_map) / 8;
opd_sym_map = bfd_zalloc (abfd, amt);
if (opd_sym_map == NULL)
return FALSE;
ppc64_elf_section_data (sec)->u.opd_func_sec = opd_sym_map;
ppc64_elf_section_data (sec)->u.opd.func_sec = opd_sym_map;
BFD_ASSERT (ppc64_elf_section_data (sec)->sec_type == sec_normal);
ppc64_elf_section_data (sec)->sec_type = sec_opd;
}
@ -5069,6 +5068,45 @@ opd_entry_value (asection *opd_sec,
return val;
}
/* Mark all our entry sym sections, both opd and code section. */
static void
ppc64_elf_gc_keep (struct bfd_link_info *info)
{
struct ppc_link_hash_table *htab = ppc_hash_table (info);
struct bfd_sym_chain *sym;
for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
{
struct ppc_link_hash_entry *eh;
asection *sec;
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
&& (eh->oh->elf.root.type == bfd_link_hash_defined
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
{
sec = eh->oh->elf.root.u.def.section;
sec->flags |= SEC_KEEP;
}
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
&& opd_entry_value (eh->elf.root.u.def.section,
eh->elf.root.u.def.value,
&sec, NULL) != (bfd_vma) -1)
sec->flags |= SEC_KEEP;
sec = eh->elf.root.u.def.section;
sec->flags |= SEC_KEEP;
}
}
/* Mark sections containing dynamically referenced symbols. When
building shared libraries, we must assume that any visible symbol is
referenced. */
@ -5122,53 +5160,13 @@ ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
static asection *
ppc64_elf_gc_mark_hook (asection *sec,
struct bfd_link_info *info,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
Elf_Internal_Rela *rel,
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym)
{
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;
for (; sym != NULL; sym = sym->next)
{
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
&& (eh->oh->elf.root.type == bfd_link_hash_defined
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
rsec = eh->oh->elf.root.u.def.section;
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
&& opd_entry_value (eh->elf.root.u.def.section,
eh->elf.root.u.def.value,
&rsec, NULL) != (bfd_vma) -1)
;
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);
}
}
/* Syms return NULL if we're marking .opd, so we avoid marking all
function sections, as all functions are referenced in .opd. */
rsec = NULL;
@ -5206,9 +5204,7 @@ ppc64_elf_gc_mark_hook (asection *sec,
|| eh->oh->elf.root.type == bfd_link_hash_defweak))
{
/* 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);
eh->elf.root.u.def.section->gc_mark = 1;
rsec = eh->oh->elf.root.u.def.section;
}
@ -5216,11 +5212,7 @@ ppc64_elf_gc_mark_hook (asection *sec,
&& opd_entry_value (eh->elf.root.u.def.section,
eh->elf.root.u.def.value,
&rsec, NULL) != (bfd_vma) -1)
{
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);
}
eh->elf.root.u.def.section->gc_mark = 1;
else
rsec = h->root.u.def.section;
break;
@ -5236,16 +5228,15 @@ ppc64_elf_gc_mark_hook (asection *sec,
}
else
{
asection **opd_sym_section;
struct _opd_sec_data *opd;
rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
opd_sym_section = get_opd_info (rsec);
if (opd_sym_section != NULL)
opd = get_opd_info (rsec);
if (opd != NULL && opd->func_sec != NULL)
{
if (!rsec->gc_mark)
_bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
rsec->gc_mark = 1;
rsec = opd_sym_section[(sym->st_value + rel->r_addend) / 8];
rsec = opd->func_sec[(sym->st_value + rel->r_addend) / 8];
}
}
@ -6159,7 +6150,7 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
{
struct ppc_link_hash_entry *eh;
asection *sym_sec;
long *opd_adjust;
struct _opd_sec_data *opd;
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
@ -6176,10 +6167,10 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
return TRUE;
sym_sec = eh->elf.root.u.def.section;
opd_adjust = get_opd_info (sym_sec);
if (opd_adjust != NULL)
opd = get_opd_info (sym_sec);
if (opd != NULL && opd->adjust != NULL)
{
long adjust = opd_adjust[eh->elf.root.u.def.value / 8];
long adjust = opd->adjust[eh->elf.root.u.def.value / 8];
if (adjust == -1)
{
/* This entry has been deleted. */
@ -6345,7 +6336,6 @@ dec_dynrel_count (bfd_vma r_info,
bfd_boolean
ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
bfd_boolean no_opd_opt,
bfd_boolean non_overlapping)
{
bfd *ibfd;
@ -6360,8 +6350,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
Elf_Internal_Sym *local_syms;
struct elf_link_hash_entry **sym_hashes;
bfd_vma offset;
bfd_size_type amt;
long *opd_adjust;
struct _opd_sec_data *opd;
bfd_boolean need_edit, add_aux_fields;
bfd_size_type cnt_16b = 0;
@ -6369,24 +6358,6 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
if (sec == NULL || sec->size == 0)
continue;
amt = sec->size * sizeof (long) / 8;
opd_adjust = get_opd_info (sec);
if (opd_adjust == NULL)
{
/* check_relocs hasn't been called. Must be a ld -r link
or --just-symbols object. */
opd_adjust = bfd_alloc (obfd, amt);
if (opd_adjust == NULL)
return FALSE;
ppc64_elf_section_data (sec)->u.opd_adjust = opd_adjust;
BFD_ASSERT (ppc64_elf_section_data (sec)->sec_type == sec_normal);
ppc64_elf_section_data (sec)->sec_type = sec_opd;
}
memset (opd_adjust, 0, amt);
if (no_opd_opt)
continue;
if (sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
continue;
@ -6530,6 +6501,14 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
bfd_byte *new_contents = NULL;
bfd_boolean skip;
long opd_ent_size;
bfd_size_type amt;
amt = sec->size * sizeof (long) / 8;
opd = &ppc64_elf_section_data (sec)->u.opd;
opd->adjust = bfd_zalloc (obfd, amt);
if (opd->adjust == NULL)
return FALSE;
ppc64_elf_section_data (sec)->sec_type = sec_opd;
/* This seems a waste of time as input .opd sections are all
zeros as generated by gcc, but I suppose there's no reason
@ -6621,7 +6600,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
fdh->elf.root.u.def.value = 0;
fdh->elf.root.u.def.section = sym_sec;
}
opd_adjust[rel->r_offset / 8] = -1;
opd->adjust[rel->r_offset / 8] = -1;
}
else
{
@ -6646,7 +6625,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
for the function descriptor sym which we
don't have at the moment. So keep an
array of adjustments. */
opd_adjust[rel->r_offset / 8]
opd->adjust[rel->r_offset / 8]
= (wptr - new_contents) - (rptr - sec->contents);
if (wptr != rptr)
@ -6675,7 +6654,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
/* We need to adjust any reloc offsets to point to the
new opd entries. While we're at it, we may as well
remove redundant relocs. */
rel->r_offset += opd_adjust[(offset - opd_ent_size) / 8];
rel->r_offset += opd->adjust[(offset - opd_ent_size) / 8];
if (write_rel != rel)
memcpy (write_rel, rel, sizeof (*rel));
++write_rel;
@ -8964,7 +8943,7 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
struct elf_link_hash_entry *h;
Elf_Internal_Sym *sym;
asection *sym_sec;
long *opd_adjust;
struct _opd_sec_data *opd;
bfd_vma sym_value;
bfd_vma dest;
@ -9022,14 +9001,14 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
sym_value += rel->r_addend;
/* If this branch reloc uses an opd sym, find the code section. */
opd_adjust = get_opd_info (sym_sec);
if (opd_adjust != NULL)
opd = get_opd_info (sym_sec);
if (opd != NULL)
{
if (h == NULL)
if (h == NULL && opd->adjust != NULL)
{
long adjust;
adjust = opd_adjust[sym->st_value / 8];
adjust = opd->adjust[sym->st_value / 8];
if (adjust == -1)
/* Assume deleted functions won't ever be called. */
continue;
@ -9384,7 +9363,7 @@ ppc64_elf_size_stubs (bfd *output_bfd,
Elf_Internal_Sym *sym;
char *stub_name;
const asection *id_sec;
long *opd_adjust;
struct _opd_sec_data *opd;
r_type = ELF64_R_TYPE (irela->r_info);
r_indx = ELF64_R_SYM (irela->r_info);
@ -9461,14 +9440,14 @@ ppc64_elf_size_stubs (bfd *output_bfd,
}
code_sec = sym_sec;
opd_adjust = get_opd_info (sym_sec);
if (opd_adjust != NULL)
opd = get_opd_info (sym_sec);
if (opd != NULL)
{
bfd_vma dest;
if (hash == NULL)
if (hash == NULL && opd->adjust != NULL)
{
long adjust = opd_adjust[sym_value / 8];
long adjust = opd->adjust[sym_value / 8];
if (adjust == -1)
continue;
sym_value += adjust;
@ -10032,17 +10011,17 @@ ppc64_elf_relocate_section (bfd *output_bfd,
if (r_symndx < symtab_hdr->sh_info)
{
/* It's a local symbol. */
long *opd_adjust;
struct _opd_sec_data *opd;
sym = local_syms + r_symndx;
sec = local_sections[r_symndx];
sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
sym_type = ELF64_ST_TYPE (sym->st_info);
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
opd_adjust = get_opd_info (sec);
if (opd_adjust != NULL)
opd = get_opd_info (sec);
if (opd != NULL && opd->adjust != NULL)
{
long adjust = opd_adjust[(sym->st_value + rel->r_addend) / 8];
long adjust = opd->adjust[(sym->st_value + rel->r_addend) / 8];
if (adjust == -1)
relocation = 0;
else
@ -11361,21 +11340,22 @@ ppc64_elf_output_symbol_hook (struct bfd_link_info *info,
asection *input_sec,
struct elf_link_hash_entry *h)
{
long *opd_adjust, adjust;
struct _opd_sec_data *opd;
long adjust;
bfd_vma value;
if (h != NULL)
return TRUE;
opd_adjust = get_opd_info (input_sec);
if (opd_adjust == NULL)
opd = get_opd_info (input_sec);
if (opd == NULL || opd->adjust == NULL)
return TRUE;
value = elfsym->st_value - input_sec->output_offset;
if (!info->relocatable)
value -= input_sec->output_section->vma;
adjust = opd_adjust[value / 8];
adjust = opd->adjust[value / 8];
if (adjust == -1)
elfsym->st_value = 0;
else

View File

@ -1,5 +1,6 @@
/* PowerPC64-specific support for 64-bit ELF.
Copyright 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Copyright 2002, 2003, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -21,7 +22,7 @@
void ppc64_elf_init_stub_bfd
(bfd *, struct bfd_link_info *);
bfd_boolean ppc64_elf_edit_opd
(bfd *, struct bfd_link_info *, bfd_boolean, bfd_boolean);
(bfd *, struct bfd_link_info *, bfd_boolean);
asection *ppc64_elf_tls_setup
(bfd *, struct bfd_link_info *);
bfd_boolean ppc64_elf_tls_optimize

View File

@ -1,6 +1,6 @@
/* ELF linking support for BFD.
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007 Free Software Foundation, Inc.
2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -11463,6 +11463,29 @@ bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
return TRUE;
}
/* Keep all sections containing symbols undefined on the command-line,
and the section containing the entry symbol. */
void
_bfd_elf_gc_keep (struct bfd_link_info *info)
{
struct bfd_sym_chain *sym;
for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
{
struct elf_link_hash_entry *h;
h = elf_link_hash_lookup (elf_hash_table (info), sym->name,
FALSE, FALSE, FALSE);
if (h != NULL
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& !bfd_is_abs_section (h->root.u.def.section))
h->root.u.def.section->flags |= SEC_KEEP;
}
}
/* Do mark and sweep of unused sections. */
bfd_boolean
@ -11480,6 +11503,8 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
return TRUE;
}
bed->gc_keep (info);
/* Try to parse each bfd's .eh_frame section. Point elf_eh_frame_section
at the .eh_frame section if we can mark the FDEs individually. */
_bfd_elf_begin_eh_frame_parsing (info);
@ -11536,7 +11561,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
/* Allow the backend to mark additional target specific sections. */
if (bed->gc_mark_extra_sections)
bed->gc_mark_extra_sections(info, gc_mark_hook);
bed->gc_mark_extra_sections (info, gc_mark_hook);
/* ... and mark SEC_EXCLUDE for those that go. */
return elf_gc_sweep (abfd, info);

View File

@ -1,6 +1,6 @@
/* Target definitions for NN-bit ELF
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -132,6 +132,9 @@
#ifndef elf_backend_want_got_sym
#define elf_backend_want_got_sym 1
#endif
#ifndef elf_backend_gc_keep
#define elf_backend_gc_keep _bfd_elf_gc_keep
#endif
#ifndef elf_backend_gc_mark_dynamic_ref
#define elf_backend_gc_mark_dynamic_ref bfd_elf_gc_mark_dynamic_ref_symbol
#endif
@ -656,6 +659,7 @@ static struct elf_backend_data elfNN_bed =
elf_backend_additional_program_headers,
elf_backend_modify_segment_map,
elf_backend_modify_program_headers,
elf_backend_gc_keep,
elf_backend_gc_mark_dynamic_ref,
elf_backend_gc_mark_hook,
elf_backend_gc_mark_extra_sections,

View File

@ -1,3 +1,11 @@
2008-01-15 Alan Modra <amodra@bigpond.net.au>
PR 5604
* ldlang.c (lang_gc_sections): Move code to set SEC_KEEP on entry
syms to _bfd_elf_gc_keep.
* emultempl/ppc64elf.em (ppc_before_allocation): Don't call
ppc64_elf_edit_opd if no_opd_opt.
2008-01-11 Tristan Gingold <gingold@adacore.com>
Eric Botcazou <ebotcazou@adacore.com>

View File

@ -1,5 +1,6 @@
# This shell script emits a C file. -*- C -*-
# Copyright 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
# Copyright 2002, 2003, 2004, 2005, 2007, 2008
# Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
@ -103,8 +104,8 @@ ppc_before_allocation (void)
{
if (stub_file != NULL)
{
if (!ppc64_elf_edit_opd (output_bfd, &link_info, no_opd_opt,
non_overlapping_opd))
if (!no_opd_opt
&& !ppc64_elf_edit_opd (output_bfd, &link_info, non_overlapping_opd))
einfo ("%X%P: can not edit %s %E\n", "opd");
if (ppc64_elf_tls_setup (output_bfd, &link_info) && !no_tls_opt)

View File

@ -1,6 +1,6 @@
/* Linker command language support.
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of the GNU Binutils.
@ -5670,30 +5670,10 @@ lang_gc_sections_1 (lang_statement_union_type *s)
static void
lang_gc_sections (void)
{
struct bfd_link_hash_entry *h;
ldlang_undef_chain_list_type *ulist;
/* Keep all sections so marked in the link script. */
lang_gc_sections_1 (statement_list.head);
/* Keep all sections containing symbols undefined on the command-line,
and the section containing the entry symbol. */
for (ulist = link_info.gc_sym_list; ulist; ulist = ulist->next)
{
h = bfd_link_hash_lookup (link_info.hash, ulist->name,
FALSE, FALSE, FALSE);
if (h != NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
&& ! bfd_is_abs_section (h->u.def.section))
{
h->u.def.section->flags |= SEC_KEEP;
}
}
/* SEC_EXCLUDE is ignored when doing a relocatable link, except in
the special case of debug info. (See bfd/stabs.c)
Twiddle the flag here, to simplify later linker code. */