diff mbox

libgo patch committed: Only call varargs from C

Message ID mcrd2lqr0bc.fsf@iant-glaptop.roam.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor Nov. 24, 2013, 2:38 a.m. UTC
Reportedly in the new PPC ELF v2 ABI calls to varargs functions act
differently from calls to normal functions.  The Go compiler can call C
functions directly using //extern comments, but it can't represent a C
varargs function.  Rather than extend the compiler, this patch changes
the library so that C varargs functions are only called from C code, by
introducing a non-varargs C function intermediary that Go can call and
that simply calls the C function.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Comments

Alan Modra Nov. 26, 2013, 8:16 a.m. UTC | #1
On Sat, Nov 23, 2013 at 06:38:31PM -0800, Ian Lance Taylor wrote:
> Reportedly in the new PPC ELF v2 ABI calls to varargs functions act
> differently from calls to normal functions.

Thanks for taking an interest in ELFv2 Ian!  If you mean by "act
differently" that arguments are passed differently, then that is true,
but it was true of the old ABI too.  In ELFv2 the calls are a little
*more* different in that many normal function calls won't need to
allocate a parameter save area, which you need for calls to variable
argument functions.  Note also that both ABIs support calls to
functions with no prototype in scope, including variable argument
functions.
diff mbox

Patch

diff -r dc9e1cbc4013 libgo/Makefile.am
--- a/libgo/Makefile.am	Sat Nov 23 10:55:58 2013 -0800
+++ b/libgo/Makefile.am	Sat Nov 23 18:34:48 2013 -0800
@@ -488,6 +488,7 @@ 
 	runtime/go-unsafe-newarray.c \
 	runtime/go-unsafe-pointer.c \
 	runtime/go-unwind.c \
+	runtime/go-varargs.c \
 	runtime/chan.c \
 	runtime/cpuprof.c \
 	runtime/env_posix.c \
diff -r dc9e1cbc4013 libgo/configure.ac
--- a/libgo/configure.ac	Sat Nov 23 10:55:58 2013 -0800
+++ b/libgo/configure.ac	Sat Nov 23 18:34:48 2013 -0800
@@ -506,7 +506,7 @@ 
 AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
 AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
 
-AC_CHECK_FUNCS(accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat openat pipe2 removexattr renameat setxattr sync_file_range splice tee unlinkat unshare utimensat)
+AC_CHECK_FUNCS(accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat open64 openat pipe2 removexattr renameat setxattr sync_file_range splice tee unlinkat unshare utimensat)
 AC_TYPE_OFF_T
 AC_CHECK_TYPES([loff_t])
 
diff -r dc9e1cbc4013 libgo/go/syscall/exec_unix.go
--- a/libgo/go/syscall/exec_unix.go	Sat Nov 23 10:55:58 2013 -0800
+++ b/libgo/go/syscall/exec_unix.go	Sat Nov 23 18:34:48 2013 -0800
@@ -30,7 +30,7 @@ 
 //chdir(path *byte) _C_int
 
 //sysnb	raw_fcntl(fd int, cmd int, arg int) (val int, err Errno)
-//fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
+//__go_fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
 
 //sysnb	raw_close(fd int) (err Errno)
 //close(fd _C_int) _C_int
diff -r dc9e1cbc4013 libgo/go/syscall/libcall_linux.go
--- a/libgo/go/syscall/libcall_linux.go	Sat Nov 23 10:55:58 2013 -0800
+++ b/libgo/go/syscall/libcall_linux.go	Sat Nov 23 18:34:48 2013 -0800
@@ -9,7 +9,7 @@ 
 import "unsafe"
 
 //sys	Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
-//openat(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int
+//__go_openat(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int
 
 //sys	futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
 //futimesat(dirfd _C_int, path *byte, times *[2]Timeval) _C_int
diff -r dc9e1cbc4013 libgo/go/syscall/libcall_posix.go
--- a/libgo/go/syscall/libcall_posix.go	Sat Nov 23 10:55:58 2013 -0800
+++ b/libgo/go/syscall/libcall_posix.go	Sat Nov 23 18:34:48 2013 -0800
@@ -206,7 +206,7 @@ 
 //fchown(fd _C_int, uid Uid_t, gid Gid_t) _C_int
 
 //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
-//fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
+//__go_fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
 
 //sys	Fdatasync(fd int) (err error)
 //fdatasync(fd _C_int) _C_int
diff -r dc9e1cbc4013 libgo/go/syscall/libcall_posix_largefile.go
--- a/libgo/go/syscall/libcall_posix_largefile.go	Sat Nov 23 10:55:58 2013 -0800
+++ b/libgo/go/syscall/libcall_posix_largefile.go	Sat Nov 23 18:34:48 2013 -0800
@@ -19,7 +19,7 @@ 
 //mmap64(addr *byte, length Size_t, prot _C_int, flags _C_int, fd _C_int, offset Offset_t) *byte
 
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
-//open64(path *byte, mode _C_int, perm Mode_t) _C_int
+//__go_open64(path *byte, mode _C_int, perm Mode_t) _C_int
 
 //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
 //pread64(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t
diff -r dc9e1cbc4013 libgo/go/syscall/libcall_posix_regfile.go
--- a/libgo/go/syscall/libcall_posix_regfile.go	Sat Nov 23 10:55:58 2013 -0800
+++ b/libgo/go/syscall/libcall_posix_regfile.go	Sat Nov 23 18:34:48 2013 -0800
@@ -20,7 +20,7 @@ 
 //mmap(addr *byte, length Size_t, prot _C_int, flags _C_int, fd _C_int, offset Offset_t) *byte
 
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
-//open(path *byte, mode _C_int, perm Mode_t) _C_int
+//__go_open(path *byte, mode _C_int, perm Mode_t) _C_int
 
 //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
 //pread(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t
diff -r dc9e1cbc4013 libgo/runtime/go-varargs.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgo/runtime/go-varargs.c	Sat Nov 23 18:34:48 2013 -0800
@@ -0,0 +1,47 @@ 
+/* go-varargs.c -- functions for calling C varargs functions.
+
+   Copyright 2013 The Go Authors. All rights reserved.
+   Use of this source code is governed by a BSD-style
+   license that can be found in the LICENSE file.  */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+/* The syscall package calls C functions.  The Go compiler can not
+   represent a C varargs functions.  On some systems it's important
+   that the declaration of a function match the call.  This function
+   holds non-varargs C functions that the Go code can call.  */
+
+int
+__go_open (char *path, int mode, mode_t perm)
+{
+  return open (path, mode, perm);
+}
+
+int
+__go_fcntl (int fd, int cmd, int arg)
+{
+  return fcntl (fd, cmd, arg);
+}
+
+#ifdef HAVE_OPEN64
+
+int
+__go_open64 (char *path, int mode, mode_t perm)
+{
+  return open64 (path, mode, perm);
+}
+
+#endif
+
+#ifdef HAVE_OPENAT
+
+int
+__go_openat (int fd, char *path, int flags, mode_t mode)
+{
+  return openat (fd, path, flags, mode);
+}
+
+#endif