amd64/124134: The kernel doesn't follow the calling convention in
the SVR4/i386 ABI
Pedro F. Giffuni
pfgshield-freebsd at yahoo.com
Fri May 30 14:10:04 UTC 2008
>Synopsis: The kernel doesn't follow the calling convention in the SVR4/i386 ABI
>Arrival-Date: Fri May 30 14:10:03 UTC 2008
>Originator: Pedro F. Giffuni
FreeBSD kakumen.cable.net.co 6.3-RELEASE FreeBSD 6.3-RELEASE #10: Sat Jan 19 01:13:55 COT 2008 root at kakumen.cable.net.co:/usr/src/sys/amd64/compile/SMP amd64
While porting glibc to FreeBSD it was found that FreeBSD doesn't strictly conform to the SVR4 ABI on AMD64:
http://www.x86-64.org/documentation/abi.pdf (see startup calling convention in 3.4.1.)
Further explanation from Petr Salinger:
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
point runs, most registers' values are unspecified, except for a few.
Blindly applied on amd64:
%rdx Contains a function pointer to be registered with `atexit'.
This is how the dynamic linker arranges to have DT_FINI
functions called for shared libraries that have been loaded
before this code runs.
%rsp The stack contains the arguments and environment:
But on amd64 %rsp also have to be 16-byte aligned,
standard C calling convention already passes arguments in registers.
FreeBSD uses %edi as pointer to arguments and environment, %rsp is passed aligned.
On entry from kernel, %rsp=%rdi or %rsp=%rdi-8,
on entry from ld.so, glibc might set up it slightly differently.
On FreeBSD, we use %rsi for passing function pointer to rtld_fini().
On entry from FreeBSD kernel, %rsi is cleared, %rdx is not cleared,
on entry from ld.so, glibc sets both %rsi and %rdx to point to rtld_fini().
Used interface (via %rdi, %rsi) is equal to standard C calling interface for
void _start(void *arg, void *rtld_fini());
It can be workaround in FreeBSD kernel by following both standards simultaneously,
i.e. on entry from kernel after exec() should be %rsp=%rdi and %rdx=%rsi, and %rsp should be properly aligned.
More information about the freebsd-amd64