Subject: Re: amd64 alignment problem - gcc's fault or libpthread's?
To: Frank van der Linden <fvdl@NetBSD.org>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: port-amd64
Date: 02/27/2004 20:08:51
This is a multipart MIME message.

--==_Exmh_107611008716850
Content-Type: text/plain; charset=us-ascii


fvdl@NetBSD.org said:
> If the libpthread regression tests work with this change, go ahead and
> check it in.. 

libpthread is happy, but since it affects makecontext() in general,
I'd like to try a test using it directly.
Now I've found the following: the context returned by getcontext()
is wrong - the ds is set to 0x3f (should be 0x17). setcontext()
complains about that.
The reason is obviously that the old int0x80 syscall path is used
by getmcontext(). If I just add a
movw    $(LSEL(LUDATA_SEL, SEL_UPL)),TF_DS(%rsp)
to the osyscall entry in locore.S, it works much better.
(this also helps for debugging with gdb btw - I can start
a program within gdb now)
Well, this doesn't look like a clean solution -- what is the reason
that getcontext() uses OSYSCALL?
(Is there a need to expose segment registers to the user-visible
mcontext at all? They are pretty meaningless in 64-bit mode.)

I'll append the test program I've used.

best regards
Matthias



--==_Exmh_107611008716850
Content-Type: text/plain ; name="mctest.c"; charset=us-ascii
Content-Description: mctest.c
Content-Disposition: attachment; filename="mctest.c"

#include <stdio.h>
#include <malloc.h>
#include <ucontext.h>
#include <err.h>

char buf[100];

void
thr(int a)
{

	sprintf(buf, "%.*g\n", 12, 1.234);
	printf("called with %d\n", a);
}

void
dumpmc(ucontext_t *p)
{
	mcontext_t *m = &p->uc_mcontext;
	__greg_t *g = m->__gregs;

	printf("fl=%x\n", g[_REG_RFL]);
	printf("es=%x\n", g[_REG_ES]);
	printf("fs=%x\n", g[_REG_FS]);
	printf("gs=%x\n", g[_REG_GS]);
	printf("ds=%x\n", g[_REG_DS]);
#if 0
	g[_REG_DS]=0x17;
#endif
	printf("ss=%x\n", g[_REG_SS]);
	printf("cs=%x\n", g[_REG_CS]);
	printf("ip=%x\n", g[_REG_RIP]);
}

main()
{
	ucontext_t uc;
	char *stack;
	int res;

	getcontext(&uc);
	dumpmc(&uc);
	stack = malloc(10*4096);
	uc.uc_stack.ss_sp = stack;
	uc.uc_stack.ss_size = 10*4096;
	makecontext(&uc, thr, 1, 77);
	dumpmc(&uc);
	res = setcontext(&uc);
	if (res)
		err(1, "setcontext");
}

--==_Exmh_107611008716850--