Date: Fri, 30 May 2008 14:07:04 GMT From: "Pedro F. Giffuni" <pfgshield-freebsd@yahoo.com> To: freebsd-gnats-submit@FreeBSD.org Subject: amd64/124134: The kernel doesn't follow the calling convention in the SVR4/i386 ABI Message-ID: <200805301407.m4UE74Wl091320@www.freebsd.org> Resent-Message-ID: <200805301410.m4UEA3MB056772@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 124134 >Category: amd64 >Synopsis: The kernel doesn't follow the calling convention in the SVR4/i386 ABI >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-amd64 >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri May 30 14:10:03 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Pedro F. Giffuni >Release: 6.3-Release >Organization: >Environment: FreeBSD kakumen.cable.net.co 6.3-RELEASE FreeBSD 6.3-RELEASE #10: Sat Jan 19 01:13:55 COT 2008 root@kakumen.cable.net.co:/usr/src/sys/amd64/compile/SMP amd64 >Description: 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: 0(%rsp) argc 8(%rsp) argv[0] ... (8*argc)(%rsp) NULL (8*(argc+1))(%rsp) envp[0] ... NULL 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()); */ >How-To-Repeat: http://lists.debian.org/debian-bsd/2006/02/msg00223.html >Fix: 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. >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200805301407.m4UE74Wl091320>