Alexander Leidinger

Just another weblog


The FreeBSD-linuxulator explained (for devel­op­ers): basics

The last post about the Lin­ux­u­la­tor where I explained the Lin­ux­u­la­tor from an user point of view got some good amount of atten­tion. Trig­gered by a recent expla­na­tion of the Lin­ux­u­la­tor errno stuff to a fel­low FreeBSD devel­oper I decided so see if more devel­op­ers are inter­ested in some more info too…

The syscall vector

In sys/linux/linux_sysvec.c is all the basic setup to han­dle Linux “sys­tem stuff” in FreeBSD. The “sys­tem stuff” is about trans­lat­ing FreeBSD errnos to Linux errnos, about trans­lat­ing FreeBSD sig­nals to Linux sig­nales, about han­dling Linux traps, and about set­ting up the FreeBSD sys­tem vec­tor (the ker­nel struc­ture which con­tains all the data to iden­tify when a Linux pro­gram is called and to be able to lookup the right ker­nel func­tions for e.g. syscalls and ioctls).

There is not only one syscall vec­tor, there is one for a.out (struct sysentvec linux_sysvec) and one for ELF (struct sysentvec elf_linux_sysvec) bina­ries (at least on i386, for other archi­tec­tures it may not make sense to have the a.out stuff, as they maybe never seen any a.out Linux binary).

The ELF AUX args

When an ELF image is exe­cuted, the Lin­ux­u­la­tor adds some run­time infor­ma­tion (like page­size, uid, guid, …) so that the user­land can query this infor­ma­tion which is not sta­tic at build-time eas­ily. This is han­dled in the elf_linux_fixup func­tion(). If you see some error mes­sages about miss­ing ELF notes from e.g. glibc, this is the place to add this infor­ma­tion to. It would not be bad from time to time to have a look what Linux is pro­vid­ing and miss­ing pieces there. FreeBSD does not has an auto­mated way of doing this, and I am not aware of some­one who reg­u­larly checks this. There is a lit­tle bit more info about ELF notes avail­able in a mes­sage to one of the FreeBSD mail­ing lists, it also has an exam­ple how to read out this data.


Linux and FreeBSD do not share the same point of view how a trap shall be han­dled (SIGBUS or SIGSEGV), the cor­re­spond­ing deci­sion mak­ing is han­dled in translate_traps() and a trans­la­tion table is avail­able as _bsd_to_linux_trapcode.


The val­ues for the sig­nal names are not the same in FreeBSD and Linux. The trans­la­tion tables are called linux_to_bsd_signal and bsd_to_linux_signal. The trans­la­tion is a fea­ture of the syscall vec­tor (= automatic).


The val­ues for the errno names are not the same in FreeBSD and Linux. The trans­la­tion table is called bsd_to_linux_errno. Return­ing an errno in one of the Linux syscalls will trig­ger an auto­matic trans­la­tion from the FreeBSD errno value to the Linux errno value. This means that FreeBSD errnos have to be returned (e.g. FreeBSD ENOSYS=78) and the Linux pro­gram will receive the Linux value (e.g. Linux ENOSYS=38, and as the Linux ker­nel returns neg­a­tive errnos, the linux pro­gram will get –38).

If you see some­where an “-ESOMETHING” in the Lin­ux­u­la­tor code, this is either a bug, or some clever/tricky/dangerous use of the sign-bit to encode some info (e.g. in the futex code there is a func­tion which returns –ENOSYS, but the sign-bit is used as an error indi­ca­tor and the call­ing code is respon­si­ble to trans­late neg­a­tive errnos into pos­i­tive ones).


The Linux syscalls are defined sim­i­lar to the FreeBSD ones. There is a map­ping table (sys/linux/syscalls.master) between syscall num­bers and the cor­re­spond­ing func­tions. This table is used to gen­er­ate code (“make sysent” in sys//linux/) which does what is necessary.

GD Star Rat­ing
GD Star Rat­ing

Tags: , , , , , , , , ,