Bug 13470 (ppc_wrong_textrels) - ld's powerpc32 relocation/dynsym output changed in many bad ways with 2.22 (e.g. textrel added)
Summary: ld's powerpc32 relocation/dynsym output changed in many bad ways with 2.22 (e...
Status: RESOLVED FIXED
Alias: ppc_wrong_textrels
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.22
: P2 critical
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-12-02 18:50 IST by Bernhard Kaindl
Modified: 2014-05-28 19:42 IST (History)
2 users (show)

See Also:
Host:
Target: powerpc-*-*
Build:
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 18:50:11 IST
Hello Alan

The cleanup which you posted as "powerpc backend tidy", included in binutils-2.22, has quite wide-ranging effects on the powerpc32 backend of ld:

http://www.cygwin.com/ml/binutils/2011-07/msg00005.html

I have found that with this change, all ELF executables using for example program_invocation_name which includes e.g all programs of GNU coreutils-8.14, are affected:

* In their .dynsym section, the Ndx value of
  __progname_full@GLIBC_2.0 and
  program_invocation_name@GLIBC_2.0
  changes from 24 to "UND" and the later's Bind field changes
  from WEAK to GLOBAL.
* Their .rela.dyn sections get R_PPC_ADDR16_HA and
  R_PPC_ADDR16_LO relocations for program_invocation_name
* They have a TEXTREL entry in their dynamic sections
* As the size of .rela.dyn is larger, the ELF file is larger

A minimal program triggering these effects is:

#define _GNU_SOURCE
#include <errno.h>
extern char *program_invocation_name;
main() {
        const char a = *program_invocation_name;
}

From a diff of readelf -a between an ld without and with "powerpc backend tidy"
on powerpc32, compiled using gcc-4.4.6, linked against glibc-2.11.3:

Here the changes to .dynsym in this program:

 Symbol table '.dynsym' contains 6 entries:
    Num:    Value  Size Type    Bind   Vis      Ndx Name
      0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
-     1: 1001077c     4 OBJECT  GLOBAL DEFAULT   24 __progname_full@GLIBC_2.0 (2)
+     1: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __progname_full@GLIBC_2.0 (2)
      2: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
-     3: 100005d8     4 OBJECT  GLOBAL DEFAULT   13 _IO_stdin_used
+     3: 100005e4     4 OBJECT  GLOBAL DEFAULT   13 _IO_stdin_used
      4: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.0 (2)
-     5: 1001077c     4 OBJECT  WEAK   DEFAULT   24 program_invocation_name@GLIBC_2.0 (2)
+     5: 00000000     0 OBJECT  GLOBAL DEFAULT  UND program_invocation_name@GLIBC_2.0 (2)

Here the changes to '.rela.dyn':

-Relocation section '.rela.dyn' at offset 0x28c contains 2 entries:
+Relocation section '.rela.dyn' at offset 0x28c contains 3 entries:
  Offset     Info    Type            Sym.Value  Sym. Name + Addend
-10010708  00000214 R_PPC_GLOB_DAT    00000000   __gmon_start__ + 0
-1001077c  00000113 R_PPC_COPY        1001077c   __progname_full + 0
+10000466  00000506 R_PPC_ADDR16_HA   00000000   program_invocation_nam + 0
+1000046e  00000504 R_PPC_ADDR16_LO   00000000   program_invocation_nam + 0
+1001071c  00000214 R_PPC_GLOB_DAT    00000000   __gmon_start__ + 0

And here the resulting changes to the dynamic section:

-Dynamic section at offset 0x638 contains 20 entries:
+Dynamic section at offset 0x644 contains 21 entries:
   Tag        Type                         Name/Value
  0x00000001 (NEEDED)                     Shared library: [libc.so.6]
- 0x0000000c (INIT)                       0x100002bc
- 0x0000000d (FINI)                       0x100005a8
+ 0x0000000c (INIT)                       0x100002c8
+ 0x0000000d (FINI)                       0x100005b4
  0x00000004 (HASH)                       0x10000164
  0x00000005 (STRTAB)                     0x100001f0
  0x00000006 (SYMTAB)                     0x10000190
  0x0000000a (STRSZ)                      109 (bytes)
  0x0000000b (SYMENT)                     16 (bytes)
  0x00000015 (DEBUG)                      0x0
- 0x00000003 (PLTGOT)                     0x1001071c
+ 0x00000003 (PLTGOT)                     0x10010730
  0x00000002 (PLTRELSZ)                   24 (bytes)
  0x00000014 (PLTREL)                     RELA
- 0x00000017 (JMPREL)                     0x100002a4
+ 0x00000017 (JMPREL)                     0x100002b0
  0x00000007 (RELA)                       0x1000028c
- 0x00000008 (RELASZ)                     48 (bytes)
+ 0x00000008 (RELASZ)                     60 (bytes)
  0x00000009 (RELAENT)                    12 (bytes)
+ 0x00000016 (TEXTREL)                    0x0
  0x6ffffffe (VERNEED)                    0x1000026c
  0x6fffffff (VERNEEDNUM)                 1
  0x6ffffff0 (VERSYM)                     0x1000025e
  0x00000000 (NULL)                       0x0

As the commit changed elf64-ppc.c (ppc64_elf_copy_indirect_symbol) 
likewise, the ppc64 backend of ld may also be affected.

Of course, there may be even more effects, but as this was declared as a
cleanup, it should have had zero effect on the output, which it does not have
and must be fixed.
Comment 1 Mike Frysinger 2011-12-02 19:46:13 IST
we've been getting reports in Gentoo of executables getting TEXTRELs on ppc32 systems with binutils-2.22 as well, and downgrading to binutils-2.21.1 "fixes" things
Comment 2 Andreas Schwab 2011-12-02 20:39:18 IST
ppc64 appears to be unaffected.
Comment 3 cvs-commit@gcc.gnu.org 2011-12-03 00:55:55 IST
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2011-12-03 00:55:51

Modified files:
	bfd            : ChangeLog elf32-ppc.c elf64-ppc.c 

Log message:
	PR ld/13470
	* elf32-ppc.c (ppc_elf_copy_indirect_symbol): Revert substantive
	change in 2011-07-01 commit.  Comment.
	* elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5526&r2=1.5527
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-ppc.c.diff?cvsroot=src&r1=1.305&r2=1.306
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-ppc.c.diff?cvsroot=src&r1=1.371&r2=1.372
Comment 4 cvs-commit@gcc.gnu.org 2011-12-03 00:58:08 IST
CVSROOT:	/cvs/src
Module name:	src
Branch: 	binutils-2_22-branch
Changes by:	amodra@sourceware.org	2011-12-03 00:58:03

Modified files:
	bfd            : ChangeLog elf32-ppc.c elf64-ppc.c 

Log message:
	PR ld/13470
	* elf32-ppc.c (ppc_elf_copy_indirect_symbol): Revert substantive
	change in 2011-07-01 commit.  Comment.
	* elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.

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.26&r2=1.5473.2.27
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-ppc.c.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.302.2.1&r2=1.302.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-ppc.c.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.363.2.4&r2=1.363.2.5
Comment 5 Alan Modra 2011-12-03 01:01:17 IST
The fact that ppc64 didn't see a problem with the testcase is due to code on ppc64 being PIC. A different testcase might expose the same problem on ppc64, to I fixed it there too.
Comment 6 Jackie Rosen 2014-02-16 18:28:34 IST Comment hidden (spam)