This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: editing stabs and eh_frame during ld -r
This final patch enables stabs and eh_frame editing during relocatable
linking. For powerpc64 ELF, also edit the opd section.
bfd/ChangeLog
* 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.
ld/ChangeLog
* emultempl/ppc64elf.em (ppc_before_allocation): New function.
(LDEMUL_BEFORE_ALLOCATION): Define.
(gld${EMULATION_NAME}_finish): Run discard_info for relocatable
linking.
* emultemp/hppaelf.em ((gld${EMULATION_NAME}_finish): Likewise.
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.195
diff -u -p -r1.195 elflink.h
--- bfd/elflink.h 12 Nov 2002 07:35:26 -0000 1.195
+++ bfd/elflink.h 12 Nov 2002 07:45:37 -0000
@@ -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, cook
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, cook
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;
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.70
diff -u -p -r1.70 elf64-ppc.c
--- bfd/elf64-ppc.c 7 Nov 2002 12:45:29 -0000 1.70
+++ bfd/elf64-ppc.c 12 Nov 2002 06:37:25 -0000
@@ -1972,8 +1972,6 @@ static boolean ppc64_elf_adjust_dynamic_
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_lo
}
}
-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
{
@@ -4144,9 +4180,6 @@ ppc64_elf_size_dynamic_sections (output_
*local_got = (bfd_vma) -1;
}
}
-
- if (!edit_opd (output_bfd, info))
- return false;
/* Allocate global sym .plt and .got entries, and space for global
sym dynamic relocs. */
Index: bfd/elf64-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.h,v
retrieving revision 1.4
diff -u -p -r1.4 elf64-ppc.h
--- bfd/elf64-ppc.h 1 Jul 2002 08:06:45 -0000 1.4
+++ bfd/elf64-ppc.h 12 Nov 2002 06:37:25 -0000
@@ -19,6 +19,8 @@ Foundation, Inc., 59 Temple Place - Suit
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
Index: ld/emultempl/hppaelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/hppaelf.em,v
retrieving revision 1.22
diff -c -p -r1.22 hppaelf.em
*** ld/emultempl/hppaelf.em 4 May 2002 02:06:43 -0000 1.22
--- ld/emultempl/hppaelf.em 12 Nov 2002 03:37:19 -0000
*************** build_section_lists (statement)
*** 263,275 ****
static void
gld${EMULATION_NAME}_finish ()
{
- int ret;
-
- /* If generating a relocatable output file, then we don't
- have to examine the relocs. */
- if (link_info.relocateable)
- return;
-
/* bfd_elf32_discard_info just plays with debugging sections,
ie. doesn't affect any code, so we can delay resizing the
sections. It's likely we'll resize everything in the process of
--- 263,268 ----
*************** gld${EMULATION_NAME}_finish ()
*** 277,322 ****
if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
need_laying_out = 1;
! ret = elf32_hppa_setup_section_lists (output_bfd, &link_info);
! if (ret != 0)
{
! if (ret < 0)
! {
! einfo ("%X%P: can not size stub section: %E\n");
! return;
! }
! lang_for_each_statement (build_section_lists);
!
! /* Call into the BFD backend to do the real work. */
! if (! elf32_hppa_size_stubs (output_bfd,
! stub_file->the_bfd,
! &link_info,
! multi_subspace,
! group_size,
! &hppaelf_add_stub_section,
! &hppaelf_layout_sections_again))
{
! einfo ("%X%P: can not size stub section: %E\n");
! return;
}
}
if (need_laying_out)
hppaelf_layout_sections_again ();
! /* Set the global data pointer. */
! if (! elf32_hppa_set_gp (output_bfd, &link_info))
{
! einfo ("%X%P: can not set gp\n");
! return;
! }
! /* Now build the linker stubs. */
! if (stub_file->the_bfd->sections != NULL)
! {
! if (! elf32_hppa_build_stubs (&link_info))
! einfo ("%X%P: can not build stubs: %E\n");
}
}
--- 270,324 ----
if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
need_laying_out = 1;
! /* If generating a relocatable output file, then we don't
! have to examine the relocs. */
! if (! link_info.relocateable)
{
! int ret = elf32_hppa_setup_section_lists (output_bfd, &link_info);
! if (ret != 0)
{
! if (ret < 0)
! {
! einfo ("%X%P: can not size stub section: %E\n");
! return;
! }
!
! lang_for_each_statement (build_section_lists);
!
! /* Call into the BFD backend to do the real work. */
! if (! elf32_hppa_size_stubs (output_bfd,
! stub_file->the_bfd,
! &link_info,
! multi_subspace,
! group_size,
! &hppaelf_add_stub_section,
! &hppaelf_layout_sections_again))
! {
! einfo ("%X%P: can not size stub section: %E\n");
! return;
! }
}
}
if (need_laying_out)
hppaelf_layout_sections_again ();
! if (! link_info.relocateable)
{
! /* Set the global data pointer. */
! if (! elf32_hppa_set_gp (output_bfd, &link_info))
! {
! einfo ("%X%P: can not set gp\n");
! return;
! }
! /* Now build the linker stubs. */
! if (stub_file->the_bfd->sections != NULL)
! {
! if (! elf32_hppa_build_stubs (&link_info))
! einfo ("%X%P: can not build stubs: %E\n");
! }
}
}
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.9
diff -c -p -r1.9 ppc64elf.em
*** ld/emultempl/ppc64elf.em 1 Jul 2002 08:07:31 -0000 1.9
--- ld/emultempl/ppc64elf.em 12 Nov 2002 03:37:19 -0000
*************** static int dotsyms = 1;
*** 43,48 ****
--- 43,49 ----
static void ppc_create_output_section_statements PARAMS ((void));
static void ppc_after_open PARAMS ((void));
+ static void ppc_before_allocation PARAMS ((void));
static asection *ppc_add_stub_section PARAMS ((const char *, asection *));
static void ppc_layout_sections_again PARAMS ((void));
static void gld${EMULATION_NAME}_after_allocation PARAMS ((void));
*************** ppc_after_open ()
*** 84,89 ****
--- 85,102 ----
gld${EMULATION_NAME}_after_open ();
}
+ static void
+ ppc_before_allocation ()
+ {
+ if (!ppc64_elf_edit_opd (output_bfd, &link_info))
+ {
+ einfo ("%X%P: can not edit opd %E\n");
+ return;
+ }
+
+ gld${EMULATION_NAME}_before_allocation ();
+ }
+
struct hook_stub_info
{
lang_statement_list_type add;
*************** build_section_lists (statement)
*** 265,282 ****
static void
gld${EMULATION_NAME}_finish ()
{
- int ret;
-
/* e_entry on PowerPC64 points to the function descriptor for
_start. If _start is missing, default to the first function
descriptor in the .opd section. */
entry_section = ".opd";
- /* If generating a relocatable output file, then we don't have any
- stubs. */
- if (link_info.relocateable)
- return;
-
/* bfd_elf64_discard_info just plays with debugging sections,
ie. doesn't affect any code, so we can delay resizing the
sections. It's likely we'll resize everything in the process of
--- 278,288 ----
*************** gld${EMULATION_NAME}_finish ()
*** 284,310 ****
if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
need_laying_out = 1;
! ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
! if (ret != 0)
{
! if (ret < 0)
{
! einfo ("%X%P: can not size stub section: %E\n");
! return;
! }
! lang_for_each_statement (build_section_lists);
! /* Call into the BFD backend to do the real work. */
! if (!ppc64_elf_size_stubs (output_bfd,
! stub_file->the_bfd,
! &link_info,
! group_size,
! &ppc_add_stub_section,
! &ppc_layout_sections_again))
! {
! einfo ("%X%P: can not size stub section: %E\n");
! return;
}
}
--- 290,321 ----
if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
need_laying_out = 1;
! /* If generating a relocatable output file, then we don't have any
! stubs. */
! if (!link_info.relocateable)
{
! int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
! if (ret != 0)
{
! if (ret < 0)
! {
! einfo ("%X%P: can not size stub section: %E\n");
! return;
! }
! lang_for_each_statement (build_section_lists);
! /* Call into the BFD backend to do the real work. */
! if (!ppc64_elf_size_stubs (output_bfd,
! stub_file->the_bfd,
! &link_info,
! group_size,
! &ppc_add_stub_section,
! &ppc_layout_sections_again))
! {
! einfo ("%X%P: can not size stub section: %E\n");
! return;
! }
}
}
*************** PARSE_AND_LIST_ARGS_CASES='
*** 486,491 ****
--- 497,503 ----
# 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
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
--
Alan Modra
IBM OzLabs - Linux Technology Centre