This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: ld: can not edit toc Invalid operation
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Olaf Hering <olh at suse dot de>, binutils at sources dot redhat dot com
- Date: Sun, 13 Feb 2005 23:05:51 +1030
- Subject: Re: ld: can not edit toc Invalid operation
- References: <20050212225221.GA11623@suse.de> <20050213072708.GG22790@bubble.modra.org> <20050213085821.GB21230@suse.de>
On Sun, Feb 13, 2005 at 09:58:21AM +0100, Olaf Hering wrote:
> On Sun, Feb 13, Alan Modra wrote:
> > > /home/abuild/binhead/bin/ld: can not edit toc Invalid operation
> >
> > This is the real error. The segfault is a consequence of
> > ppc64elf.em:ppc_before_allocation not calling the elf32.em
> > before_allocation function. I guess I should make this a fatal
> > error..
> >
> > Can you find out why ppc64_elf_edit_toc is returning FALSE?
>
> _bfd_elf_link_read_relocs() returns NULL, line 7018
Silly me. It's quite possible to have a toc section that has no
relocs.
* elf64-ppc.c (ppc64_elf_edit_toc): Skip toc if size is zero.
Skip toc reloc adjust if reloc_count is zero.
This tidies up the error situation. I chose to leave most of the errors
non-fatal, which means we need to continue on with normal processing in
these functions rather than just returning.
* emultempl/ppc64elf.em (ppc_create_output_section_statements): Make
an error creating fake bfd fatal.
(ppc_before_allocation): Continue on after errors.
(gld${EMULATION_NAME}_finish): Likewise.
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.191
diff -u -p -r1.191 elf64-ppc.c
--- bfd/elf64-ppc.c 11 Feb 2005 14:18:15 -0000 1.191
+++ bfd/elf64-ppc.c 13 Feb 2005 12:27:46 -0000
@@ -6782,13 +6782,14 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Sym *local_syms;
struct elf_link_hash_entry **sym_hashes;
- Elf_Internal_Rela *relstart, *rel, *wrel;
+ Elf_Internal_Rela *relstart, *rel;
unsigned long *skip, *drop;
unsigned char *used;
unsigned char *keep, last, some_unused;
toc = bfd_get_section_by_name (ibfd, ".toc");
if (toc == NULL
+ || toc->size == 0
|| toc->sec_info_type == ELF_INFO_TYPE_JUST_SYMS
|| elf_discarded_section (toc))
continue;
@@ -7033,25 +7034,32 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_
toc->rawsize = toc->size;
toc->size = src - contents - off;
- /* Read toc relocs. */
- relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL, TRUE);
- if (relstart == NULL)
- goto error_ret;
+ if (toc->reloc_count != 0)
+ {
+ Elf_Internal_Rela *wrel;
+ bfd_size_type sz;
- /* Remove unused toc relocs, and adjust those we keep. */
- wrel = relstart;
- for (rel = relstart; rel < relstart + toc->reloc_count; ++rel)
- if (skip[rel->r_offset >> 3] != (unsigned long) -1)
- {
- wrel->r_offset = rel->r_offset - skip[rel->r_offset >> 3];
- wrel->r_info = rel->r_info;
- wrel->r_addend = rel->r_addend;
- ++wrel;
- }
- toc->reloc_count = wrel - relstart;
- elf_section_data (toc)->rel_hdr.sh_size
- = toc->reloc_count * elf_section_data (toc)->rel_hdr.sh_entsize;
- BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL);
+ /* Read toc relocs. */
+ relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL,
+ TRUE);
+ if (relstart == NULL)
+ goto error_ret;
+
+ /* Remove unused toc relocs, and adjust those we keep. */
+ wrel = relstart;
+ for (rel = relstart; rel < relstart + toc->reloc_count; ++rel)
+ if (skip[rel->r_offset >> 3] != (unsigned long) -1)
+ {
+ wrel->r_offset = rel->r_offset - skip[rel->r_offset >> 3];
+ wrel->r_info = rel->r_info;
+ wrel->r_addend = rel->r_addend;
+ ++wrel;
+ }
+ toc->reloc_count = wrel - relstart;
+ sz = elf_section_data (toc)->rel_hdr.sh_entsize;
+ elf_section_data (toc)->rel_hdr.sh_size = toc->reloc_count * sz;
+ BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL);
+ }
/* Adjust addends for relocs against the toc section sym. */
for (sec = ibfd->sections; sec != NULL; sec = sec->next)
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.37
diff -u -p -r1.37 ppc64elf.em
--- ld/emultempl/ppc64elf.em 10 Feb 2005 09:15:05 -0000 1.37
+++ ld/emultempl/ppc64elf.em 13 Feb 2005 12:27:47 -0000
@@ -88,7 +88,7 @@ ppc_create_output_section_statements (vo
bfd_get_arch (output_bfd),
bfd_get_mach (output_bfd)))
{
- einfo ("%X%P: can not create BFD %E\n");
+ einfo ("%F%P: can not create BFD %E\n");
return;
}
@@ -104,10 +104,7 @@ ppc_before_allocation (void)
{
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");
- return;
- }
+ einfo ("%X%P: can not edit %s %E\n", "opd");
if (ppc64_elf_tls_setup (output_bfd, &link_info) && !no_tls_opt)
{
@@ -117,10 +114,7 @@ ppc_before_allocation (void)
&stat_ptr->head, 0, 0, NULL, TRUE);
if (!ppc64_elf_tls_optimize (output_bfd, &link_info))
- {
- einfo ("%X%P: TLS problem %E\n");
- return;
- }
+ einfo ("%X%P: TLS problem %E\n");
/* We must not cache anything from the preliminary sizing. */
elf_tdata (output_bfd)->program_header_size = 0;
@@ -130,10 +124,7 @@ ppc_before_allocation (void)
if (!no_toc_opt
&& !link_info.relocatable
&& !ppc64_elf_edit_toc (output_bfd, &link_info))
- {
- einfo ("%X%P: can not edit %s %E\n", "toc");
- return;
- }
+ einfo ("%X%P: can not edit %s %E\n", "toc");
}
gld${EMULATION_NAME}_before_allocation ();
@@ -343,14 +334,10 @@ gld${EMULATION_NAME}_finish (void)
{
int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info,
no_multi_toc);
- if (ret != 0)
+ if (ret < 0)
+ einfo ("%X%P: can not size stub section: %E\n");
+ else if (ret > 0)
{
- if (ret < 0)
- {
- einfo ("%X%P: can not size stub section: %E\n");
- return;
- }
-
toc_section = bfd_get_section_by_name (output_bfd, ".got");
if (toc_section != NULL)
lang_for_each_statement (build_toc_list);
@@ -365,10 +352,7 @@ gld${EMULATION_NAME}_finish (void)
group_size,
&ppc_add_stub_section,
&ppc_layout_sections_again))
- {
- einfo ("%X%P: can not size stub section: %E\n");
- return;
- }
+ einfo ("%X%P: can not size stub section: %E\n");
}
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre