Bug 13468 (ld_ztext_assertion) - ld -z text: assertion in 2.22 and 2.22.51 when used without -shared
Summary: ld -z text: assertion in 2.22 and 2.22.51 when used without -shared
Status: RESOLVED FIXED
Alias: ld_ztext_assertion
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks: document_ld-z_text
  Show dependency treegraph
 
Reported: 2011-12-02 17:38 UTC by Bernhard Kaindl
Modified: 2011-12-03 10:30 UTC (History)
0 users

See Also:
Host: all
Target: all
Build: all
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bernhard Kaindl 2011-12-02 17:38:54 UTC
Hi Alan,

in the commit titled "PR ld/13254", you implemented ld -z text, but when used without -shared, it leads to an assertion:

$ echo 'foo(){};_start(){foo();}' >foo.c
$ gcc -m32 -c foo.c
$ ./ld/ld-new foo.o -z text -m elf_i386
./ld/ld-new: BFD (GNU Binutils) 2.22 assertion fail ../../bfd/elflink.c:11198
Segmentation fault

This is because of the conditions you use to enable the checking in elflink.c:

 11190        /* Check for DT_TEXTREL (late, in case the backend removes it). */
 11191        if ((info->warn_shared_textrel && info->shared)
 11192            || info->error_textrel) <- This is the added condition
 11193          {
 11194            bfd_byte *dyncon, *dynconend;
 11195
 11196            /* Fix up .dynamic entries.  */
 11197            o = bfd_get_section_by_name (dynobj, ".dynamic");
 11198            BFD_ASSERT (o != NULL);

You can find the change you made at this place the second hunk of this diff:

http://sourceware.org/bugzilla/attachment.cgi?id=5966&action=diff

The thing is that line 11197 is only guaranteed to set o to a non-NULL-val when
info->shared is != 0, but you bypass this check with "|| info->error_textrel)".

info->error_textrel can only be active when info->shared is != 0.

I propose you change these lines as follows:

 11191        if (info->shared &&
 11192            (info->warn_shared_textrel ||
 11192             info->error_textrel))

Also, this makes is immediately clear to every reader that the textrel check
below is only entered when info->shared is set and (in addition) either warn_shared_textrel or error_textrel are set.

I've cross-built a complete minimal system for powerpc and x86 with this fix and
info->error_textrel set to true in the used cross ld by default.
Comment 1 Sourceware Commits 2011-12-03 10:29:06 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2011-12-03 10:29:02

Modified files:
	bfd            : ChangeLog elflink.c 

Log message:
	PR ld/13468
	* elflink.c (bfd_elf_final_link): Don't segfault when checking
	for DT_TEXTREL and .dynamic does not exist.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5527&r2=1.5528
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.430&r2=1.431
Comment 2 Sourceware Commits 2011-12-03 10:29:23 UTC
CVSROOT:	/cvs/src
Module name:	src
Branch: 	binutils-2_22-branch
Changes by:	amodra@sourceware.org	2011-12-03 10:29:18

Modified files:
	bfd            : ChangeLog elflink.c 

Log message:
	PR ld/13468
	* elflink.c (bfd_elf_final_link): Don't segfault when checking
	for DT_TEXTREL and .dynamic does not exist.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.5473.2.27&r2=1.5473.2.28
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.420.2.10&r2=1.420.2.11
Comment 3 Alan Modra 2011-12-03 10:30:08 UTC
Fixed