* elflink.h (elf_link_add_object_symbols): Optimize stabs for

relocatable link too.
	(elf_link_input_bfd): When emitting relocs, adjust offsets for
	eh_frame and stab sections.  Zap deleted relocs.
	(elf_reloc_symbol_deleted_p): Return true for zero r_symndx.
	(elf_bfd_discard_info): Run for relocatable link too.
	* elf64-ppc.c (ppc64_elf_edit_opd): Rename from edit_opd.  Make global.
	Handle ld -r case.
	(ppc64_elf_size_dynamic_sections): Don't call edit_opd from here.
	* elf64-ppc.h (ppc64_elf_edit_opd): Declare.
This commit is contained in:
Alan Modra
2002-11-12 07:55:43 +00:00
parent 126495ed15
commit d6fe2dc102
4 changed files with 82 additions and 24 deletions

View File

@ -1,5 +1,16 @@
2002-11-12 Alan Modra <amodra@bigpond.net.au> 2002-11-12 Alan Modra <amodra@bigpond.net.au>
* elflink.h (elf_link_add_object_symbols): Optimize stabs for
relocatable link too.
(elf_link_input_bfd): When emitting relocs, adjust offsets for
eh_frame and stab sections. Zap deleted relocs.
(elf_reloc_symbol_deleted_p): Return true for zero r_symndx.
(elf_bfd_discard_info): Run for relocatable link too.
* elf64-ppc.c (ppc64_elf_edit_opd): Rename from edit_opd. Make global.
Handle ld -r case.
(ppc64_elf_size_dynamic_sections): Don't call edit_opd from here.
* elf64-ppc.h (ppc64_elf_edit_opd): Declare.
* elf-bfd.h (struct cie_header): Move from elf_eh-frame.c. * elf-bfd.h (struct cie_header): Move from elf_eh-frame.c.
(struct cie, struct eh_cie_fde, struct eh_frame_sec_info): Likewise. (struct cie, struct eh_cie_fde, struct eh_frame_sec_info): Likewise.
(struct eh_frame_array_ent, struct eh_frame_hdr_info): Likewise. (struct eh_frame_array_ent, struct eh_frame_hdr_info): Likewise.

View File

@ -1972,8 +1972,6 @@ static boolean ppc64_elf_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static void ppc64_elf_hide_symbol static void ppc64_elf_hide_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean)); PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
static boolean edit_opd
PARAMS ((bfd *, struct bfd_link_info *));
static boolean allocate_dynrelocs static boolean allocate_dynrelocs
PARAMS ((struct elf_link_hash_entry *, PTR)); PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean readonly_dynrelocs static boolean readonly_dynrelocs
@ -3539,8 +3537,8 @@ ppc64_elf_hide_symbol (info, h, force_local)
} }
} }
static boolean boolean
edit_opd (obfd, info) ppc64_elf_edit_opd (obfd, info)
bfd *obfd; bfd *obfd;
struct bfd_link_info *info; struct bfd_link_info *info;
{ {
@ -3557,6 +3555,7 @@ edit_opd (obfd, info)
Elf_Internal_Sym *local_syms; Elf_Internal_Sym *local_syms;
struct elf_link_hash_entry **sym_hashes; struct elf_link_hash_entry **sym_hashes;
bfd_vma offset; bfd_vma offset;
bfd_size_type amt;
long *adjust; long *adjust;
boolean need_edit; boolean need_edit;
@ -3564,9 +3563,16 @@ edit_opd (obfd, info)
if (sec == NULL) if (sec == NULL)
continue; continue;
amt = sec->_raw_size * sizeof (long) / 24;
adjust = (long *) elf_section_data (sec)->tdata; adjust = (long *) elf_section_data (sec)->tdata;
BFD_ASSERT (adjust != NULL); if (adjust == NULL)
memset (adjust, 0, (size_t) sec->_raw_size * sizeof (long) / 24); {
/* Must be a ld -r link. ie. check_relocs hasn't been
called. */
adjust = (long *) bfd_zalloc (obfd, amt);
elf_section_data (sec)->tdata = adjust;
}
memset (adjust, 0, (size_t) amt);
if (sec->output_section == bfd_abs_section_ptr) if (sec->output_section == bfd_abs_section_ptr)
continue; continue;
@ -3769,14 +3775,29 @@ edit_opd (obfd, info)
{ {
/* Arrange for the function descriptor sym /* Arrange for the function descriptor sym
to be dropped. */ to be dropped. */
struct elf_link_hash_entry *fdh; struct ppc_link_hash_entry *fdh;
struct ppc_link_hash_entry *fh; struct ppc_link_hash_entry *fh;
fh = (struct ppc_link_hash_entry *) h; fh = (struct ppc_link_hash_entry *) h;
BFD_ASSERT (fh->is_func); fdh = (struct ppc_link_hash_entry *) fh->oh;
fdh = fh->oh; if (fdh == NULL)
fdh->root.u.def.value = 0; {
fdh->root.u.def.section = sym_sec; const char *fd_name;
struct ppc_link_hash_table *htab;
fd_name = h->root.root.string + 1;
htab = ppc_hash_table (info);
fdh = (struct ppc_link_hash_entry *)
elf_link_hash_lookup (&htab->elf, fd_name,
false, false, false);
fdh->is_func_descriptor = 1;
fdh->oh = &fh->elf;
fh->is_func = 1;
fh->oh = &fdh->elf;
}
fdh->elf.root.u.def.value = 0;
fdh->elf.root.u.def.section = sym_sec;
} }
} }
else else
@ -3789,13 +3810,28 @@ edit_opd (obfd, info)
to this location in the opd section. to this location in the opd section.
We've checked above that opd relocs are We've checked above that opd relocs are
ordered. */ ordered. */
struct elf_link_hash_entry *fdh; struct ppc_link_hash_entry *fdh;
struct ppc_link_hash_entry *fh; struct ppc_link_hash_entry *fh;
fh = (struct ppc_link_hash_entry *) h; fh = (struct ppc_link_hash_entry *) h;
BFD_ASSERT (fh->is_func); fdh = (struct ppc_link_hash_entry *) fh->oh;
fdh = fh->oh; if (fdh == NULL)
fdh->root.u.def.value = wptr - sec->contents; {
const char *fd_name;
struct ppc_link_hash_table *htab;
fd_name = h->root.root.string + 1;
htab = ppc_hash_table (info);
fdh = (struct ppc_link_hash_entry *)
elf_link_hash_lookup (&htab->elf, fd_name,
false, false, false);
fdh->is_func_descriptor = 1;
fdh->oh = &fh->elf;
fh->is_func = 1;
fh->oh = &fdh->elf;
}
fdh->elf.root.u.def.value = wptr - sec->contents;
} }
else else
{ {
@ -4145,9 +4181,6 @@ ppc64_elf_size_dynamic_sections (output_bfd, info)
} }
} }
if (!edit_opd (output_bfd, info))
return false;
/* Allocate global sym .plt and .got entries, and space for global /* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */ sym dynamic relocs. */
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);

View File

@ -19,6 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
boolean ppc64_elf_mark_entry_syms boolean ppc64_elf_mark_entry_syms
PARAMS ((struct bfd_link_info *)); PARAMS ((struct bfd_link_info *));
boolean ppc64_elf_edit_opd
PARAMS ((bfd *, struct bfd_link_info *));
bfd_vma ppc64_elf_toc bfd_vma ppc64_elf_toc
PARAMS ((bfd *)); PARAMS ((bfd *));
int ppc64_elf_setup_section_lists int ppc64_elf_setup_section_lists

View File

@ -2208,10 +2208,9 @@ elf_link_add_object_symbols (abfd, info)
} }
} }
/* If this is a non-traditional, non-relocateable link, try to /* If this is a non-traditional link, try to optimize the handling
optimize the handling of the .stab/.stabstr sections. */ of the .stab/.stabstr sections. */
if (! dynamic if (! dynamic
&& ! info->relocateable
&& ! info->traditional_format && ! info->traditional_format
&& info->hash->creator->flavour == bfd_target_elf_flavour && info->hash->creator->flavour == bfd_target_elf_flavour
&& is_elf_hash_table (info) && is_elf_hash_table (info)
@ -6982,6 +6981,16 @@ elf_link_input_bfd (finfo, input_bfd)
next_erel = 0; next_erel = 0;
} }
irela->r_offset = _bfd_elf_section_offset (output_bfd,
finfo->info, o,
irela->r_offset);
if (irela->r_offset >= (bfd_vma) -2)
{
/* This is a reloc for a deleted entry or somesuch. */
memset (irela, 0, sizeof (*irela));
continue;
}
irela->r_offset += o->output_offset; irela->r_offset += o->output_offset;
/* Relocs in an executable have to be virtual addresses. */ /* Relocs in an executable have to be virtual addresses. */
@ -8334,7 +8343,7 @@ elf_reloc_symbol_deleted_p (offset, cookie)
for (; rcookie->rel < rcookie->relend; rcookie->rel++) for (; rcookie->rel < rcookie->relend; rcookie->rel++)
{ {
unsigned long r_symndx = ELF_R_SYM (rcookie->rel->r_info); unsigned long r_symndx;
if (! rcookie->bad_symtab) if (! rcookie->bad_symtab)
if (rcookie->rel->r_offset > offset) if (rcookie->rel->r_offset > offset)
@ -8342,6 +8351,10 @@ elf_reloc_symbol_deleted_p (offset, cookie)
if (rcookie->rel->r_offset != offset) if (rcookie->rel->r_offset != offset)
continue; continue;
r_symndx = ELF_R_SYM (rcookie->rel->r_info);
if (r_symndx == SHN_UNDEF)
return true;
if (r_symndx >= rcookie->locsymcount if (r_symndx >= rcookie->locsymcount
|| ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL) || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
{ {
@ -8400,8 +8413,7 @@ elf_bfd_discard_info (output_bfd, info)
unsigned int count; unsigned int count;
boolean ret = false; boolean ret = false;
if (info->relocateable if (info->traditional_format
|| info->traditional_format
|| info->hash->creator->flavour != bfd_target_elf_flavour || info->hash->creator->flavour != bfd_target_elf_flavour
|| ! is_elf_hash_table (info)) || ! is_elf_hash_table (info))
return false; return false;