Closed Bug 520718 Opened 15 years ago Closed 14 years ago

nanojit: i386 backend accesses the stack below SP

Categories

(Core :: JavaScript Engine, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 590553

People

(Reporter: n.nethercote, Unassigned)

Details

Running lirasm --random I see lots of these: ==28514== Invalid read of size 8 ==28514== at 0x4CD6EB3: ??? ==28514== by 0x805A541: main (lirasm.cpp:1553) ==28514== Address 0xfeb767b8 is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes AIUI Valgrind complains about this because the x86 ABI doesn't guarantee that addresses below SP (in the sense "addresses lower than SP") are accessible. Eg. the kernel could trash them at any time. The code responsible is in asm_u2f(): const int disp = -8; const Register base = SP; Register gr = findRegFor(ins->oprnd1(), GpRegs); NanoAssert(rr == FST0); FILDQ(disp, base); STi(base, disp+4, 0); // high 32 bits = 0 ST(base, disp, gr); // low 32 bits = unsigned value The generated code looks like this: u2f13 = u2f ld5 mov -8(esp),ebx mov -4(esp),0 fildq -8(esp) AFAICT the eight bytes just below ESP are being used as a very short-term scratch space. This also avoids using a register for the base pointer. It seems unlikely to cause any problems in practice but is probably worth avoiding (by allocating memory on the stack with findMemFor()) just to keep things Valgrind-clean.
My ESP-relative addressing patch fixes this as a side effect. I will try to get back to that this week.
(In reply to comment #0) > u2f13 = u2f ld5 > mov -8(esp),ebx > mov -4(esp),0 > fildq -8(esp) > > It seems unlikely to cause any problems in practice Random unreproducible crashes/failures, especially in cases where many signals are delivered, eg, in SIGPROF-based profiling setups.
I still see this, with 'valgrind --smc-check=all lirasm --random 10000'.
The least-worst safe replacement sequence I can think of is pushl $0 pushl %ebx fildq 0(%esp) addl $8,%esp Additional comment re both sequences: this kind of thing looks like it's asking for trouble w.r.t. store-forwarding stalls. Indeed, the "Intel 64 and IA-32 Architectures Optimization Reference Manual" version dated Nov 2007, lists this as Example 3-33 on page 3-54: mov mem, eax mov mem+4, ebx fld mem ; load qword at address "MEM", stalls
fld can take a memory address as argument, right? Why don't we use that form? Just put the constant into memory and load it. That should avoid the stall.
(In reply to comment #5) > Just put the constant into memory and load it. That should avoid the stall. I don't understand. The sequence appears to be intended to take the value in %ebx, convert it unsignedly into a 80-bit float, and park it in %st0. I don't see how to do that without doing a store of %ebx, at least, shortly before the fildq.
(In reply to comment #4) > Additional comment re both sequences: this kind of thing looks > like it's asking for trouble w.r.t. store-forwarding stalls. This code only occurs on non-SSE2 machines so avoiding stalls doesn't seem that important... worth doing if it's easy, but otherwise not.
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.