Skip site navigation (1)Skip section navigation (2)
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>