This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: secureplt breaks ld on Alpha Linux
- From: Richard Henderson <rth at twiddle dot net>
- To: Mikulas Patocka <mpatocka at redhat dot com>
- Cc: binutils at sourceware dot org, bug-binutils at gnu dot org
- Date: Fri, 29 Aug 2014 16:27:17 -0700
- Subject: Re: secureplt breaks ld on Alpha Linux
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LRH dot 2 dot 02 dot 1408291448090 dot 3870 at file01 dot intranet dot prod dot int dot rdu2 dot redhat dot com>
On 08/29/2014 12:29 PM, Mikulas Patocka wrote:
> I found out that the patch cc75d373fdb9668f367959f99f0b67e056a6c18a
> (Enable secureplt by default for alpha-linux) committed to binutils git
> breaks ld on alpha.
>
> This is a minimalized testcase that shows the breakage:
> http://people.redhat.com/~mpatocka/testcases/alpha-ld-bug/ld-bug.tar.xz
>
> To reproduce the bug, run ./ld-bug.sh to perform the linking, then run the
> resulting binary:
> LD_PRELOAD=./libots.so ./memset
Incidentally, you can't package your ld.so and libc.so and then use the system
ld.so. The ld.so and libc.so used must match. That said, removing the stuff
redundant with my system libraries I can reproduce the crash.
> The bug happens when using the Compaq C Compiler (ccc) on Alpha Linux (it
> can be downloaded from
> ftp://ftp.compaq.com/pub/products/C-CXX/linux/compaq_c/ ). When using
> optimization, Compaq C replaces a call to memset with a call to _OtsZero
> located in libots.so. The above patch breaks ld in such a way that the
> resulting program crashes when performing the dynamic call to _OtsZero.
The code that ccc is generating is incorrect:
1c: 00 40 5b 6b jsr ra,(t12),20 <main+0x20>
1c: LITUSE printf+0x3
1c: HINT printf
20: 00 00 ba 27 ldah gp,0(ra)
20: GPDISP *ABS*+0x8
24: 90 01 3f 22 lda a1,400
28: 00 00 bd 23 lda gp,0(gp)
2c: 00 00 7d a7 ldq t12,0(gp)
2c: ELF_LITERAL _OtsZero
30: 00 00 1d a6 ldq a0,0(gp)
30: ELF_LITERAL a
34: 00 00 1d a4 ldq v0,0(gp)
34: ELF_LITERAL .data
38: 00 00 fe 2f unop
3c: 00 40 5b 6b jsr ra,(t12),40 <main+0x40>
3c: LITUSE _OtsZero+0x3
3c: HINT _OtsZero
40: 00 00 7d a7 ldq t12,0(gp)
40: ELF_LITERAL printf
44: 10 00 00 22 lda a0,16(v0)
44: LITUSE .data+0x1
48: 00 00 fe 2f unop
4c: 00 40 5b 6b jsr ra,(t12),50 <main+0x50>
4c: LITUSE printf+0x3
4c: HINT printf
At 0x40, the compiler has failed to reload gp after the call, like it did after
the first call to printf at 0x20.
The Compaq compiler seems to be assuming non-standard calling conventions in
the call to _OtsZero. If you force LD_BIND_NOW=1 so that all relocation
happens first, the program does run correctly.
There are several ways libots could have been written to annotate the function
for non-standard calling conventions. But Compaq probably went under before
that bug was exposed. Assuming that one can't get the source, it may be
possible to modify the libots.so binary so that it works with modern linkers.
This is not a bug in ld, per se.
r~