Qemu User Mode for FreeBSD ToDo List
While Qemu user mode is fairly well supported on Linux it lacks a lot of code to support this feature on FreeBSD.
This page tracks the latest work being done to add the missing code to add support for some of the more popular CPU architectures.
Contact
If you are interested in helping please contact SeanBruno or StaceySon.
Code is available in the GitHub: seanbruno/qemu-bsd-user repository.
Missing Features/Known Bugs and Status
Feature/Bug |
Description |
Notes |
Status/Who |
ARM arch |
Missing some ARM dependent bits. |
sigframe and sigreturn trampoline, thread startup in new_thread_start(), maybe some sysarch() stuff, set_mcontext/get_mcontext, etc. |
Done. sson |
MIPS arch |
mips64 is done. Missing some mips32 dependent bits. |
|
Done. sbruno |
SPARC64 arch |
Missing SPARC64 dependent bits. |
demand? Definitely! |
|
PPC/PPC64 arch |
Missing PPC/PPC64 dependent bits. |
Work started, almost runs static binaries (ppc32) |
|
thread cancel |
SIGTHR is used by underlining thread code in QEMU |
May use a different sig number for the emulated SIGTHR |
|
sysctl()/getrlimit() |
Sysctl's KERN_USRSTACK, KERN_PS_STRINGS, and getrlimit(RLIMIT_STACK..) need to return emulator addresses and stack size |
Increasing stack size with setrlimit() is problematic so it is not supported. |
|
Special sysctl(mib[0]=0, mib[1]=3) |
The return returned data for the special sysctl() to convert a name (e.g. "kern.smu.cpus") to its mib/oid is not properly byte swapped for mixed endian host/target. |
Handle the special case for swapping. |
|
Missing sockopt options |
see bsd-user/syscall.c do_getsockopt()/do_setsockopt() |
|
|
ioctl commands |
More ioctl commands need to be added. See bsd-user/freebsd/ioctls.h |
|
|
_umtx_op() |
This code needs to be reviewed and maybe improved. |
UMTX_OP_MUTEX_WAIT doesn't seem correct. |
|
Code cleanup |
FreeBSD dependent code needs to go in bsd-user/FreeBSD. ARCH dependent code needs to go into bsd-user/arm, etc. |
bsd-user/syscall.c and bsd-user/syscall_defs.h need lots of love. |
|
NetBSD/OpenBSD |
Broken by FreeBSD port. Need to be fixed as part of code cleanup. |
|
Done (see above). Needs testing. |
Dynamically linked executables |
Currently I have only been testing with statically linked executables. |
The code is mostly there for dynamically linked executables. |
|
execve() hack |
In the execve() syscall shim check the target executable's ELF header for e_machine=EM_MIPS, e_ident=ELFCLASS64|ELFOSABI_FREEBSD, etc. and automatically insert "qemu-mips64" as the path and the path in front of the argv list. |
fexecve() is a problem. Passing the FD to new qemu-mips64 instance might be a good work-around. |
|
sysctl() for mmap_min_addr |
The guest_base command-line option tried to open "/proc/sys/vm/mmap_min_addr" to determine the minimum virtual address (main.c). This needs to be replaced with the proper sysctl. |
|
|
"sysconf pages: Cannot allocate memory" |
During "Finding dependencies in ports build we get "sysconf pages: Cannot allocate memory". Most likely a sysctl() problem. |
sysconf(_SC_PHYS_PAGES) is failing on arm arch. This is a 32-bit target on a 64-bit host issue. Workaround: Run on 32-bit host. |
|
sysctl() returning struct |
Some sysctl() oid's return structs such as KERN_CLOCKRATE, KERN_VNODE, KERN_PROC, KERN_FILE, KERN_BOOTTIME, etc. |
Maybe do something like ioctl() with sysctl() using thunk. |
|
interrupted read() |
SIGINT during a blocked read() results in a core dump. |
|
|
Perl 5.14 regression test failures |
UPDATE: "Failed 2 tests out of 1970, 99.90% okay." cpan/ExtUtils-MakeMaker/t/fixin fails test 'switch retained'at t/fixin.t line 77. op/magic fails show-shebang: print: not found at line 253. |
Bug fixes: 5a3b8a0f1e, 71c890d48c, 94db009c17, 6a1eccb851, f85dca9064 |
sson@ |
'uname -m' and 'uname -p' |
uname(1) will return the host arch instead of the target arch. Some port configure scripts will use this information. |
It gets it from sysctl: hw.machine & hw.machine_arch |
|
Performance: init_paths() |
For dynamically linked target binaries, init_paths() walks a bunch of directory paths on start up. It might be good to create a cache file or figure a better way or something. |
done (backported from upstream) |
|
Thr (parent) exit seg fault |
Running the attached program results in "<jemalloc>: contrib/jemalloc/include/jemalloc/internal/arena.h:942: Failed assertion: "arena_mapbits_allocated_get(chunk, pageind) != 0" (in target code) and then seg fault in gen_intermediate_code() in qemu-mips64. The tb doesn't seem valid. Looks like thread is still running after main() has exited? |
bug fix for the case of the parent exiting before child thread. |
done. |
The (child) exit seg fault |
When the child thread exits it seg faults in arena_chunk_dirty_insert() (jemalloc). The call path of the child is as follows: pthread_exit() -> _malloc_thread_cleanup() -> jemalloc_tcache_tsd_cleanup_wrapper() -> ... -> arena_chunk_dirty_insert() |
Thread stack pointer needs to be pointing at the top of the stack and not the bottom. |
|
Unsupported ioctl: cmd=0xffffffffc1206949 |
SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq) |
|
|
Missing System Call Shims
Syscall(s) |
Notes |
Status/Who |
ktimer_*() |
Needed? |
|
acl_*()/extattr_*() |
extattr_'s and acl's are needed by tar, etc. |
|
cpuset_*() |
|
|
rctl_*() |
Needed? |
|
sctp_*() |
|
|
kld*()/mod*() |
|
|
quota*() |
|
|
jail*() |
Would be difficult to emulate. |
|
cap_*() |
Would be difficult to emulate. |
|
_mac*() |
Needed? |
|
sendfile() |
|
|
ptrace() |
Would be difficult to emulate. |
|
utrace() |
Needed? |
|
freebsd6_*() |
|
|
setsockopt()/getsockopt() |
Missing some options. see bsd-user/syscall.c do_getsockopt()/do_setsockopt() |
|
ioctl() |
Only tty(4) currently supported. Need more ioctl commands. See bsd-user/freebsd/ioctl.h |
|
rtprio_thread() |
|
|
swapcontext() |
setcontext()/getcontext() are done so this should be easy. |
|
thr_create() |
Not sure if it is used. All the code I have seen uses thr_new() |
|
fexecve() |
|