Date: Fri, 26 Jan 2007 18:21:09 -0500 From: Jung-uk Kim <jkim@FreeBSD.org> To: freebsd-amd64@FreeBSD.org Cc: freebsd-emulation@FreeBSD.org Subject: load_fs() and load_gs() Message-ID: <200701261821.12274.jkim@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
I have been chasing TLS problem for Linuxulator/amd64. The whole thing actually boils down to the following simulation: ---------------- #include <stdio.h> #include <sys/types.h> #include <machine/cpufunc.h> #include <machine/sysarch.h> static __thread u_int tls = 0xdeadbeef; int main(void) { #if defined(__amd64__) u_int fs; uint64_t fsbase; fs = rfs(); if (sysarch(AMD64_GET_FSBASE, &fsbase)) return (-1); printf("fsbase = 0x%lx, %%fs: 0x%08x, tls = 0x%x\n", fsbase, fs, tls); /* * glibc does the following two calls. * Note: Actually we don't do anything here * but writing them back. */ if (sysarch(AMD64_SET_FSBASE, &fsbase)) return (-1); load_fs(fs); if (sysarch(AMD64_GET_FSBASE, &fsbase)) return (-1); printf("fsbase = 0x%lx, %%fs: 0x%08x, tls = 0x%x\n", fsbase, rfs(), tls); #elif defined(__i386__) u_int gs; uint32_t gsbase; gs = rgs(); if (sysarch(I386_GET_GSBASE, &gsbase)) return (-1); printf("gsbase = 0x%lx, %%gs: 0x%08x, tls = 0x%x\n", gsbase, gs, tls); /* * glibc does the following two calls. * Note: Actually we don't do anything here * but writing them back. */ if (sysarch(I386_SET_GSBASE, &gsbase)) return (-1); load_gs(gs); if (sysarch(I386_GET_GSBASE, &gsbase)) return (-1); printf("gsbase = 0x%lx, %%gs: 0x%08x, tls = 0x%x\n", gsbase, rgs(), tls); #endif return (0); } ---------------- If you run it on amd64 (both amd64 and i386 binaries), it segfaults at: mov %fs:0x0,%rax (amd64) or mov %gs:0x0,%eax (i386) which is basically reading tls. Why does it segfaults when we just read and write them back? Can anyone enlighten me? Thanks, Jung-uk Kim
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701261821.12274.jkim>