amd64_set_gsbase()

Mihai Donțu mihai.dontu at gmail.com
Mon Oct 8 15:01:11 PDT 2007


On Monday 08 October 2007, Jung-uk Kim wrote:
> Yes, you are correct.  A short version is "don't do that".  A long 
> version goes like this.  %fs and %gs are not preserved while context 
> switching on amd64.

But this makes emulation software such as Wine a lost hope, doesn't it?
Because Windows apps access the Thread Information Block (TIB) via %gs
(%fs on ia32).

Anyway, my so called "small" program is actually a Win64 emulator and
I need the segment selector to "stay put" across syscalls. It works
like a charm on single threaded apps, but as soon as I spawn a thread,
all hell breaks loose :)

I've managed to come up with something that *kind of* works. It goes
like this:

void my_handler( int s )
{
    if ( s == SIGSEGV ) {
        if ( get_gs() == 0 ) {
            amd64_set_gsbase();
        } else {
            signal( SIGSEGV, SIG_DFL );
        }
    }
}

int my_init( void )
{
    /* alloc TIB memory and initialize */

    amd64_set_gsbase( lpTIB );
    signal( SIGSEGV, my_handler );

    return 0;
}

but after a series of dlopen()-s, my_handler() is called without %gs
being zero and without a valid fault (the handler does not get recalled
after signal( SIGSEGV, SIG_DFL ). I'm still working on this aspect ...

> In fact, you should not use amd64_set_gsbase() 
> directly.  If you *really* have to mess up with base addresses, you 
> have to use sysarch(2) syscall, i.e., sysarch(AMD64_SET_GSBASE, 
> args).

I found this: /usr/src/lib/libc/amd64/sys/amd64_set_gsbase.c:32
"
int
amd64_set_gsbase(void *addr)
{
        return (sysarch(AMD64_SET_GSBASE, &addr));
}
"

and this (man 2 sysarch()): "The sysarch() system call should never be
called directly by user programs.  Instead, they should access its
functions using the architecture-dependent library."

Who am I suppose to believe? :)

> However, it only changes the base address via MSR, i.e., %gs  
> itself has no meaning.

Maybe, but the selector loaded in %gs *does* have meaning.

Anyway, the thing is I _have_ to make this work. I'll keep you posted ;)

-- 
Mihai Donțu


More information about the freebsd-questions mailing list