On Fri, 29 Aug 2014, Richard Henderson wrote:
> 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. > I see. I tested the compiler and it assumes that the function _OtsZero preserves registers v0, t0-t11, a5, s0-s5, fp, gp, f0-f30. It can only modify a0-a4, t12, at. The function _dl_runtime_resolve_old saves these registers, so it works. The function _dl_runtime_resolve_new doesn't save all of them. We can't save the registers in _dl_runtime_resolve_new because _dl_runtime_resolve_new gets its parameter in t11. The only possibility to save them is in the code at the beginning of _PROCEDURE_LINKAGE_TABLE_ - do you think it would be possible to save the registers on the stack here? Or, would it cause unwind problems? > 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~ What exactly these anotations do? Do they turn off lazy binding? Mikulas _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils