Matteo Frigo wrote:
Avi Kivity <avi@xxxxxxxxxx> writes:
More questions:
- is the bad 'mov gs' instruction reached on AMD? or is it avoided
somehow? What about bare metal?
The instruction is indeed reached on amd, and gs is 0x2b after
the instruction. I don't know about bare metal.
- does the attached program fail when compiled and run in cygwin on an
AMD host?
The program runs as follows:
w2k3-64:/cygdrive/v$ gcc -O gs.c
w2k3-64:/cygdrive/v$ ./a.exe
gs: 2b
gs:0x30: 7efdb000
test
- does setjmp()/longjmp() come from the Windows run-time library, or
from cygwin?
The setjmp()/longjmp() is in the cygwin library /bin/cygwin1.dll .
bash calls longjmp() at the end of the expr built-in, which causes the
problem reported by the original poster.
I should also mention that, as an experiment, I have replaced the mov
gs,ax instruction with a couple of no-ops in cygwin1.dll, and cygwin
runs fine on Intel with this patch.
That was going to be my next question :)
Right now I don't understand how cygwin's longjmp() is supposed to work
at all, given that it clobbers gs.
Can you run the slightly modified gs.c (attached) and rerun on AMD? The
is to see if the runtime somehow restores gs.
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
#include <stdio.h>
int main()
{
unsigned short gs;
unsigned x;
asm ("mov %%gs, %0\n" : "=g"(gs));
asm ("movl %%gs:0x30, %0\n" : "=r"(x));
printf("gs: %x\n", gs);
printf("gs:0x30: %x\n", x);
asm volatile ("mov %0, %%gs\n" : : "g"(gs));
asm volatile ("movl %%gs:0x30, %0\n" : "=r"(x));
printf("gs:0x30: %x\n", x);
return 0;
}