This is the mail archive of the
mailing list for the binutils project.
Re: PR ld/16643: ARM: BFD_ASSERT when only ref to a GC'd symbol is in a stripped section
- From: Alan Modra <amodra at gmail dot com>
- To: Roland McGrath <mcgrathr at google dot com>
- Cc: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Fri, 28 Feb 2014 10:55:16 +1030
- Subject: Re: PR ld/16643: ARM: BFD_ASSERT when only ref to a GC'd symbol is in a stripped section
- Authentication-results: sourceware.org; auth=none
- References: <CAB=4xho=rub8PTp2WO-+YKu9jUhg0Gb735rA5F-_+-XSUxnSUQ at mail dot gmail dot com>
On Thu, Feb 27, 2014 at 03:07:15PM -0800, Roland McGrath wrote:
> I haven't had much luck trying to figure out where the PLT refcount is
> supposed to be maintained in general. Apparently, something about
> --strip-all mode affects how this bookkeeping gets done. Can anyone point
> me to where the actual bug here might be?
This sort of bug is always a mismatch between check_relocs and
gc_sweep_hook. In this case, it looks like the problem is in
elflink.c, where check_relocs is called depending on info->strip and
SEC_DEBUGGING, but gc_sweep_hook is called without those tests.
Of course, the arm backend is slightly insane in counting plt entries
for references from debug sections.. PowerPC for example does this
/* Don't do anything special with non-loaded, non-alloced sections.
In particular, any relocs in such sections should not affect GOT
and PLT reference counting (ie. we don't allow them to create GOT
or PLT entries), there's no possibility or desire to optimize TLS
relocs, and there's not much point in propagating relocs to shared
libs that the dynamic linker won't relocate. */
if ((sec->flags & SEC_ALLOC) == 0)
Here you go, this cures your testcase.
* elflink.c (elf_gc_sweep): Call gc_sweep_hook for exactly
the same conditions we called check_relocs.
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 28ccf53..47e4802 100644
@@ -11992,7 +11992,9 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
info we collected before. */
&& (o->flags & SEC_RELOC) != 0
- && o->reloc_count > 0
+ && o->reloc_count != 0
+ && !((info->strip == strip_all || info->strip == strip_debugger)
+ && (o->flags & SEC_DEBUGGING) != 0)
&& !bfd_is_abs_section (o->output_section))
Australia Development Lab, IBM