diff options
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 69 | ||||
-rw-r--r-- | bfd/elf64-ppc.h | 2 | ||||
-rw-r--r-- | bfd/elflink.h | 24 |
4 files changed, 82 insertions, 24 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index de54a92..387f367 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,16 @@ 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. (struct cie, struct eh_cie_fde, struct eh_frame_sec_info): Likewise. (struct eh_frame_array_ent, struct eh_frame_hdr_info): Likewise. diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e92c997..384348e 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -1972,8 +1972,6 @@ static boolean ppc64_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); static void ppc64_elf_hide_symbol 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 PARAMS ((struct elf_link_hash_entry *, PTR)); static boolean readonly_dynrelocs @@ -3539,8 +3537,8 @@ ppc64_elf_hide_symbol (info, h, force_local) } } -static boolean -edit_opd (obfd, info) +boolean +ppc64_elf_edit_opd (obfd, info) bfd *obfd; struct bfd_link_info *info; { @@ -3557,6 +3555,7 @@ edit_opd (obfd, info) Elf_Internal_Sym *local_syms; struct elf_link_hash_entry **sym_hashes; bfd_vma offset; + bfd_size_type amt; long *adjust; boolean need_edit; @@ -3564,9 +3563,16 @@ edit_opd (obfd, info) if (sec == NULL) continue; + amt = sec->_raw_size * sizeof (long) / 24; adjust = (long *) elf_section_data (sec)->tdata; - BFD_ASSERT (adjust != NULL); - memset (adjust, 0, (size_t) sec->_raw_size * sizeof (long) / 24); + if (adjust == NULL) + { + /* 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) continue; @@ -3769,14 +3775,29 @@ edit_opd (obfd, info) { /* Arrange for the function descriptor sym to be dropped. */ - struct elf_link_hash_entry *fdh; + struct ppc_link_hash_entry *fdh; struct ppc_link_hash_entry *fh; fh = (struct ppc_link_hash_entry *) h; - BFD_ASSERT (fh->is_func); - fdh = fh->oh; - fdh->root.u.def.value = 0; - fdh->root.u.def.section = sym_sec; + fdh = (struct ppc_link_hash_entry *) fh->oh; + if (fdh == NULL) + { + 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 @@ -3789,13 +3810,28 @@ edit_opd (obfd, info) to this location in the opd section. We've checked above that opd relocs are ordered. */ - struct elf_link_hash_entry *fdh; + struct ppc_link_hash_entry *fdh; struct ppc_link_hash_entry *fh; fh = (struct ppc_link_hash_entry *) h; - BFD_ASSERT (fh->is_func); - fdh = fh->oh; - fdh->root.u.def.value = wptr - sec->contents; + fdh = (struct ppc_link_hash_entry *) fh->oh; + if (fdh == NULL) + { + 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 { @@ -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 sym dynamic relocs. */ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h index cabc388..21178d5 100644 --- a/bfd/elf64-ppc.h +++ b/bfd/elf64-ppc.h @@ -19,6 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ boolean ppc64_elf_mark_entry_syms PARAMS ((struct bfd_link_info *)); +boolean ppc64_elf_edit_opd + PARAMS ((bfd *, struct bfd_link_info *)); bfd_vma ppc64_elf_toc PARAMS ((bfd *)); int ppc64_elf_setup_section_lists diff --git a/bfd/elflink.h b/bfd/elflink.h index 0f59fec..721b361 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -2208,10 +2208,9 @@ elf_link_add_object_symbols (abfd, info) } } - /* If this is a non-traditional, non-relocateable link, try to - optimize the handling of the .stab/.stabstr sections. */ + /* If this is a non-traditional link, try to optimize the handling + of the .stab/.stabstr sections. */ if (! dynamic - && ! info->relocateable && ! info->traditional_format && info->hash->creator->flavour == bfd_target_elf_flavour && is_elf_hash_table (info) @@ -6982,6 +6981,16 @@ elf_link_input_bfd (finfo, input_bfd) 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; /* 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++) { - unsigned long r_symndx = ELF_R_SYM (rcookie->rel->r_info); + unsigned long r_symndx; if (! rcookie->bad_symtab) if (rcookie->rel->r_offset > offset) @@ -8342,6 +8351,10 @@ elf_reloc_symbol_deleted_p (offset, cookie) if (rcookie->rel->r_offset != offset) continue; + r_symndx = ELF_R_SYM (rcookie->rel->r_info); + if (r_symndx == SHN_UNDEF) + return true; + if (r_symndx >= rcookie->locsymcount || 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; boolean ret = false; - if (info->relocateable - || info->traditional_format + if (info->traditional_format || info->hash->creator->flavour != bfd_target_elf_flavour || ! is_elf_hash_table (info)) return false; |