just a quick note of caution when using OpenBSD as a guest OS in qemu...

As of this writing, the qemu release notes list the following known limitation for x86 emulation:

"The x86 segment limits and access rights are not tested at every
memory access (yet). Hopefully, very few OSes seem to rely on that
for normal use."

This has implications for at least the ELF .rodata PROT_EXEC protection feature in OpenBSD (and maybe W^X too). Consider the following example. The fact that it doesn't do anything useful or even make much sense isn't important.

foo.c:
-----
#include 

extern ulong getcallerpc(void *);

int
main()
{
	ulong n;
	n = (12*1024*1024); 

        if(getcallerpc(&n))
                printf("wrong!\n");
}

bar.S:
-----
	.section rodata

	.type	getcallerpc,@function
	.global	getcallerpc
getcallerpc:
	pushl	%ebp
	movl	%esp, %ebp
	movl	4(%ebp), %eax
	popl	%ebp
	ret

Notice that getcallerpc is in .rodata so on a system running OpenBSD natively on x86, we get:

$ cc -g3 -c foo.c bar.S
$ cc -o foo foo.o bar.o
$ gdb ./foo
[...]
Program received signal SIGSEGV, Segmentation fault.
0x1c0005f6 in main () at foo.c:10
10              if(getcallerpc(&n))
(gdb) disass main
[...]
0x1c0005f6 <main+38>:   call   0x3c00000a <getcallerpc>

Which is what you'd expect because we can't call getcallerpc; it's not executable.

Yet the program runs just fine in OpenBSD on qemu emulating x86:

$ ./foo
wrong!
$

which is not what you should be expecting.

I'm not sure what other implications this has, but it should be noted. Maybe it has similar side effects for software DEP in XP as well, but I've never tried XP in qemu nor do I even know if it works.