about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/bp-checks.h98
-rw-r--r--sysdeps/generic/bp-thunks.h232
-rw-r--r--sysdeps/unix/inet/syscalls.list22
-rw-r--r--sysdeps/unix/make-syscalls.sh141
-rw-r--r--sysdeps/unix/mman/syscalls.list8
-rw-r--r--sysdeps/unix/syscalls.list10
-rw-r--r--sysdeps/unix/sysv/linux/ia64/syscalls.list22
-rw-r--r--sysdeps/unix/sysv/linux/mips/syscalls.list18
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/syscalls.list6
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list10
10 files changed, 307 insertions, 260 deletions
diff --git a/sysdeps/generic/bp-checks.h b/sysdeps/generic/bp-checks.h
new file mode 100644
index 0000000000..a7c54b4955
--- /dev/null
+++ b/sysdeps/generic/bp-checks.h
@@ -0,0 +1,98 @@
+/* Bounded-pointer checking macros for C.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   Contributed by Greg McGary <greg@mcgary.org>
+
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in the GNU MP Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _bp_checks_h_
+# define _bp_checks_h_ 1
+
+# if !__ASSEMBLER__
+
+#  if __BOUNDED_POINTERS__
+
+/* GKM FIXME: when gcc is ready, add real bounds checks */
+#   define BOUNDS_VIOLATED (__builtin_trap (), 0)
+extern int __ubp_memchr (const char *__unbounded, int, unsigned);
+
+/* Verify that pointer's value >= low.  Return pointer value.  */
+#   define CHECK_BOUNDS_LOW(ARG)				\
+  (((__ptrvalue (ARG) < __ptrlow (ARG)) && BOUNDS_VIOLATED),	\
+   __ptrvalue (ARG))
+
+/* Verify that pointer's value < high.  Return pointer value.  */
+#   define CHECK_BOUNDS_HIGH(ARG)				\
+  (((__ptrvalue (ARG) > __ptrhigh (ARG)) && BOUNDS_VIOLATED),	\
+   __ptrvalue (ARG))
+
+/* Check bounds of a pointer seated to a single object.  */
+#   define CHECK_1(ARG) CHECK_N ((ARG), 1)
+
+/* Same as CHECK_1, but tolerate ARG == NULL.  */
+#   define CHECK_1opt(ARG) CHECK_Nopt ((ARG), 1)
+
+/* Check bounds of a pointer seated to an array of N objects.  */
+#   define CHECK_N(ARG, N)				\
+  (((__ptrvalue (ARG) < __ptrlow (ARG)			\
+     || __ptrvalue (ARG) + (N) > __ptrhigh (ARG))	\
+    && BOUNDS_VIOLATED), __ptrvalue (ARG))
+
+/* Same as CHECK_N, but tolerate ARG == NULL.  */
+#   define CHECK_Nopt(ARG, N)				\
+  (((__ptrvalue (ARG)					\
+     && (__ptrvalue (ARG) < __ptrlow (ARG)		\
+	 || __ptrvalue (ARG) + (N) > __ptrhigh (ARG)))	\
+    && BOUNDS_VIOLATED), __ptrvalue (ARG))
+
+/* Check for NUL-terminator within string's bounds.  */
+#   define CHECK_STRING(ARG)					\
+  (((__ptrvalue (ARG) < __ptrlow (ARG)				\
+     || !__ubp_memchr (__ptrvalue (ARG), '\0',			\
+		       (__ptrhigh (ARG) - __ptrvalue (ARG))))	\
+     && BOUNDS_VIOLATED),					\
+   __ptrvalue (ARG))
+
+#  else /* !__BOUNDED_POINTERS__ */
+
+/* Do nothing if not compiling with -fbounded-pointers.  */
+
+#   define BOUNDS_VIOLATED
+#   define CHECK_BOUNDS_LOW(ARG) (ARG)
+#   define CHECK_BOUNDS_HIGH(ARG) (ARG)
+#   define CHECK_1(ARG) (ARG)
+#   define CHECK_1opt(ARG) (ARG)
+#   define CHECK_N(ARG, N) (ARG)
+#   define CHECK_Nopt(ARG, N) (ARG)
+#   define CHECK_STRING(ARG) (ARG)
+
+#  endif /* !__BOUNDED_POINTERS__ */
+
+#  if defined (_IOC_SIZESHIFT) && defined (_IOC_SIZEBITS)
+
+/* Extract the size of the ioctl parameter argument and check its bounds.  */
+#   define CHECK_IOCTL(ARG, CMD) \
+  CHECK_N ((ARG), (((CMD) >> _IOC_SIZESHIFT) & ((1 << _IOC_SIZEBITS) - 1)))
+
+#  else
+#   define CHECK_IOCTL(ARG, CMD) __ptrvalue (ARG)
+#  endif
+
+# endif /* !__ASSEMBLER__ */
+
+#endif /* _bp_checks_h_ */
diff --git a/sysdeps/generic/bp-thunks.h b/sysdeps/generic/bp-thunks.h
index eb0a47b2c1..b036d6ab52 100644
--- a/sysdeps/generic/bp-thunks.h
+++ b/sysdeps/generic/bp-thunks.h
@@ -1,4 +1,4 @@
-/* Bounded-pointer thunk definitions.
+/* Bounded-pointer syscall thunk support.
    Copyright (C) 2000 Free Software Foundation, Inc.
    Contributed by Greg McGary <greg@mcgary.org>
 
@@ -23,203 +23,39 @@
 #ifndef _bpthunks_h_
 #define _bpthunks_h_
 
-#include <libc-symbols.h>
-
-#define BP_ALIAS(STRONG, ALIAS) weak_alias (__BP_##STRONG, __BP_##ALIAS)
-
-#define PV(P) __ptrvalue (P)
-#define SV(S) __ptrvalue (S)
-#define PB(P) __ptrlow (P)
-#define PE(P) __ptrhigh (P)
-#define voidp void *__bounded
-#define charp char *__bounded
-
-/* GKM FIXME: Add code to check bounds.  Right now, they only strip bounds, */
-
-#define BP_THUNK_i_iiip(NAME) __unbounded { \
-  extern int NAME (int, int, int, void *); \
-  int __BP_##NAME (int i0, int i1, int i2, voidp p3) \
-    { return NAME (i0, i1, i2, PV (p3)); } }
-
-#define BP_THUNK_i_iiipi(NAME) __unbounded { \
-  extern int NAME (int, int, int, void *, int); \
-  int __BP_##NAME (int i0, int i1, int i2, voidp p3, int i4) \
-    { return NAME (i0, i1, i2, PV (p3), i4); } }
-
-#define BP_THUNK_i_iiipp(NAME) __unbounded { \
-  extern int NAME (int, int, int, void *, void *); \
-  int __BP_##NAME (int i0, int i1, int i2, voidp p3, voidp p4) \
-    { return NAME (i0, i1, i2, PV (p3), PV (p4)); } }
-
-#define BP_THUNK_i_iip(NAME) __unbounded { \
-  extern int NAME (int, int, void *); \
-  int __BP_##NAME (int i0, int i1, voidp p2) \
-    { return NAME (i0, i1, PV (p2)); } }
-
-#define BP_THUNK_i_iipi(NAME) __unbounded { \
-  extern int NAME (int, int, void *, int); \
-  int __BP_##NAME (int i0, int i1, voidp p2, int i3) \
-    { return NAME (i0, i1, PV (p2), i3); } }
-
-#define BP_THUNK_i_iipp(NAME) __unbounded { \
-  extern int NAME (int, int, void *, void *); \
-  int __BP_##NAME (int i0, int i1, voidp p2, voidp p3) \
-    { return NAME (i0, i1, PV (p2), PV (p3)); } }
-
-#define BP_THUNK_i_ip(NAME) __unbounded { \
-  extern int NAME (int, void *); \
-  int __BP_##NAME (int i0, voidp p1) \
-    { return NAME (i0, PV (p1)); } }
-
-#define BP_THUNK_i_ipi(NAME) __unbounded { \
-  extern int NAME (int, void *, int); \
-  int __BP_##NAME (int i0, voidp p1, int i2) \
-    { return NAME (i0, PV (p1), i2); } }
-
-#define BP_THUNK_i_ipii(NAME) __unbounded { \
-  extern int NAME (int, void *, int, int); \
-  int __BP_##NAME (int i0, voidp p1, int i2, int i3) \
-    { return NAME (i0, PV (p1), i2, i3); } }
-
-#define BP_THUNK_i_ipiii(NAME) __unbounded { \
-  extern int NAME (int, void *, int, int, int); \
-  int __BP_##NAME (int i0, voidp p1, int i2, int i3, int i4) \
-    { return NAME (i0, PV (p1), i2, i3, i4); } }
-
-#define BP_THUNK_i_ipiipi(NAME) __unbounded { \
-  extern int NAME (int, void *, int, int, void *, int); \
-  int __BP_##NAME (int i0, voidp p1, int i2, int i3, voidp p4, int i5) \
-    { return NAME (i0, PV (p1), i2, i3, PV (p4), i5); } }
-
-#define BP_THUNK_i_ipiipp(NAME) __unbounded { \
-  extern int NAME (int, void *, int, int, void *, void *); \
-  int __BP_##NAME (int i0, voidp p1, int i2, int i3, voidp p4, voidp p5) \
-    { return NAME (i0, PV (p1), i2, i3, PV (p4), PV (p5)); } }
-
-#define BP_THUNK_i_ipip(NAME) __unbounded { \
-  extern int NAME (int, void *, int, void *); \
-  int __BP_##NAME (int i0, voidp p1, int i2, voidp p3) \
-    { return NAME (i0, PV (p1), i2, PV (p3)); } }
-
-#define BP_THUNK_i_ipp(NAME) __unbounded { \
-  extern int NAME (int, void *, void *); \
-  int __BP_##NAME (int i0, voidp p1, voidp p2) \
-    { return NAME (i0, PV (p1), PV (p2)); } }
-
-#define BP_THUNK_i_ippi(NAME) __unbounded { \
-  extern int NAME (int, void *, void *, int); \
-  int __BP_##NAME (int i0, voidp p1, voidp p2, int i3) \
-    { return NAME (i0, PV (p1), PV (p2), i3); } }
-
-#define BP_THUNK_i_ipppp(NAME) __unbounded { \
-  extern int NAME (int, void *, void *, void *, void *); \
-  int __BP_##NAME (int i0, voidp p1, voidp p2, voidp p3, voidp p4) \
-    { return NAME (i0, PV (p1), PV (p2), PV (p3), PV (p4)); } }
+/* This header is included by the syscall BP thunks defined in
+   sysd-syscalls, as created by sysdeps/unix/make-syscalls.sh.  It
+   includes all headers that contain prototype declarations for system
+   call functions.  */
 
-#define BP_THUNK_i_isi(NAME) __unbounded { \
-  extern int NAME (int, char *, int); \
-  int __BP_##NAME (int i0, charp s1, int i2) \
-    { return NAME (i0, SV (s1), i2); } }
-
-#define BP_THUNK_i_isip(NAME) __unbounded { \
-  extern int NAME (int, char *, int, void *); \
-  int __BP_##NAME (int i0, charp s1, int i2, voidp p3) \
-    { return NAME (i0, SV (s1), i2, PV (p3)); } }
-
-#define BP_THUNK_i_p(NAME) __unbounded { \
-  extern int NAME (void *); \
-  int __BP_##NAME (voidp p0) \
-    { return NAME (PV (p0)); } }
-
-#define BP_THUNK_i_pi(NAME) __unbounded { \
-  extern int NAME (void *, int); \
-  int __BP_##NAME (voidp p0, int i1) \
-    { return NAME (PV (p0), i1); } }
-
-#define BP_THUNK_i_pii(NAME) __unbounded { \
-  extern int NAME (void *, int, int); \
-  int __BP_##NAME (voidp p0, int i1, int i2) \
-    { return NAME (PV (p0), i1, i2); } }
-
-#define BP_THUNK_i_piii(NAME) __unbounded { \
-  extern int NAME (void *, int, int, int); \
-  int __BP_##NAME (voidp p0, int i1, int i2, int i3) \
-    { return NAME (PV (p0), i1, i2, i3); } }
-
-#define BP_THUNK_i_pp(NAME) __unbounded { \
-  extern int NAME (void *, void *); \
-  int __BP_##NAME (voidp p0, voidp p1) \
-    { return NAME (PV (p0), PV (p1)); } }
-
-#define BP_THUNK_i_pppi(NAME) __unbounded { \
-  extern int NAME (void *, void *, void *, int); \
-  int __BP_##NAME (voidp p0, voidp p1, voidp p2, int i3) \
-    { return NAME (PV (p0), PV (p1), PV (p2), i3); } }
-
-#define BP_THUNK_i_s(NAME) __unbounded { \
-  extern int NAME (char *); \
-  int __BP_##NAME (charp s0) \
-    { return NAME (SV (s0)); } }
-
-#define BP_THUNK_i_si(NAME) __unbounded { \
-  extern int NAME (char *, int); \
-  int __BP_##NAME (charp s0, int i1) \
-    { return NAME (SV (s0), i1); } }
-
-#define BP_THUNK_i_sii(NAME) __unbounded { \
-  extern int NAME (char *, int, int); \
-  int __BP_##NAME (charp s0, int i1, int i2) \
-    { return NAME (SV (s0), i1, i2); } }
-
-#define BP_THUNK_i_sipip(NAME) __unbounded { \
-  extern int NAME (char *, int, void *, int, void *); \
-  int __BP_##NAME (charp s0, int i1, voidp p2, int i3, voidp p4) \
-    { return NAME (SV (s0), i1, PV (p2), i3, PV (p4)); } }
-
-#define BP_THUNK_i_sp(NAME) __unbounded { \
-  extern int NAME (char *, void *); \
-  int __BP_##NAME (charp s0, voidp p1) \
-    { return NAME (SV (s0), PV (p1)); } }
-
-#define BP_THUNK_i_spi(NAME) __unbounded { \
-  extern int NAME (char *, void *, int); \
-  int __BP_##NAME (charp s0, voidp p1, int i2) \
-    { return NAME (SV (s0), PV (p1), i2); } }
-
-#define BP_THUNK_i_spp(NAME) __unbounded { \
-  extern int NAME (char *, void *, void *); \
-  int __BP_##NAME (charp s0, voidp p1, voidp p2) \
-    { return NAME (SV (s0), PV (p1), PV (p2)); } }
-
-#define BP_THUNK_i_ss(NAME) __unbounded { \
-  extern int NAME (char *, char *); \
-  int __BP_##NAME (charp s0, charp s1) \
-    { return NAME (SV (s0), s1); } }
-
-#define BP_THUNK_i_sssip(NAME) __unbounded { \
-  extern int NAME (char *, char *, char *, int, void *); \
-  int __BP_##NAME (charp s0, charp s1, charp s2, int i3, voidp p4) \
-    { return NAME (SV (s0), SV (s1), SV (s2), i3, PV (p4)); } }
-
-/* sstk */
-#define BP_THUNK_p_i(NAME) __unbounded { \
-  extern void *NAME (int); \
-  voidp __BP_##NAME (int i0) \
-    { charp m; PV (m) = PB (m) = NAME (i0); \
-      PE (m) = PV (m) + i0; return m; } }
-
-/* mremap */
-#define BP_THUNK_p_piii(NAME) __unbounded { \
-  extern void *NAME (void *, int, int, int); \
-  voidp __BP_##NAME (voidp p0, int i1, int i2, int i3) \
-    { charp m; PV (m) = PB (m) = NAME (PV (p0), i1, i2, i3); \
-      PE (m) = PV (m) + i2; return m; } }
-
-/* mmap */
-#define BP_THUNK_p_piiiii(NAME) __unbounded { \
-  extern void *NAME (void *, int, int, int, int, int); \
-  voidp __BP_##NAME (voidp p0, int i1, int i2, int i3, int i4, int i5) \
-    { charp m; PV (m) = PB (m) = NAME (PV (p0), i1, i2, i3, i4, i5); \
-      PE (m) = PV (m) + i1; return m; } }
+#include <libc-symbols.h>
+#include <bp-sym.h>
+#include <bp-checks.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sched.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/klog.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/quota.h>
+#include <sys/resource.h>
+#include <sys/select.h>
+#include <sys/sendfile.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/swap.h>
+#include <sys/sysinfo.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/timex.h>
+#include <sys/utsname.h>
+#include <sys/vm86.h>
+#include <sys/wait.h>
 
 #endif /* _bpthunks_h_ */
diff --git a/sysdeps/unix/inet/syscalls.list b/sysdeps/unix/inet/syscalls.list
index 7c4623110a..1a68a81f6c 100644
--- a/sysdeps/unix/inet/syscalls.list
+++ b/sysdeps/unix/inet/syscalls.list
@@ -1,23 +1,23 @@
 # File name	Caller	Syscall name	# args	Strong name	Weak names
 
-accept		-	accept		i:ipp	__libc_accept	accept
+accept		-	accept		i:ibN	__libc_accept	accept
 bind		-	bind		i:ipi	bind
 connect		-	connect		i:ipi	__libc_connect	__connect connect
 gethostid	-	gethostid	i:	gethostid
-gethostname	-	gethostname	i:si	__gethostname	gethostname
-getpeername	-	getpeername	i:ipp	getpeername
-getsockname	-	getsockname	i:ipp	getsockname
-getsockopt	-	getsockopt	i:iiipp	getsockopt
+gethostname	-	gethostname	i:bn	__gethostname	gethostname
+getpeername	-	getpeername	i:ibN	getpeername
+getsockname	-	getsockname	i:ibN	getsockname
+getsockopt	-	getsockopt	i:iiiBN	getsockopt
 listen		-	listen		i:ii	listen
-recv		-	recv		i:ipii	__libc_recv	recv
-recvfrom	-	recvfrom	i:ipiipp	__libc_recvfrom	recvfrom
+recv		-	recv		i:ibni	__libc_recv	recv
+recvfrom	-	recvfrom	i:ibnibN	__libc_recvfrom	recvfrom
 recvmsg		-	recvmsg		i:ipi	__libc_recvmsg	recvmsg
-send		-	send		i:ipii	__libc_send	__send send
+send		-	send		i:ibni	__libc_send	__send send
 sendmsg		-	sendmsg		i:ipi	__libc_sendmsg	sendmsg
-sendto		-	sendto		i:ipiipi	__libc_sendto	sendto
+sendto		-	sendto		i:ibnibn	__libc_sendto	sendto
 sethostid	-	sethostid	i:i	sethostid
 sethostname	-	sethostname	i:pi	sethostname
-setsockopt	-	setsockopt	i:iiipi	setsockopt
+setsockopt	-	setsockopt	i:iiibn	setsockopt
 shutdown	-	shutdown	i:ii	shutdown
 socket		-	socket		i:iii	socket
-socketpair	-	socketpair	i:iiip	socketpair
+socketpair	-	socketpair	i:iiif	socketpair
diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
index 9b05da9cc7..0bedf7a432 100644
--- a/sysdeps/unix/make-syscalls.sh
+++ b/sysdeps/unix/make-syscalls.sh
@@ -3,6 +3,37 @@
 # Usage: make-syscalls.sh ../sysdeps/unix/common
 # Expects $sysdirs in environment.
 
+##############################################################################
+
+# Syscall Signature Key Letters for BP Thunks:
+#
+# a: unchecked address (e.g., 1st arg to mmap)
+# b: non-NULL buffer (e.g., 2nd arg to read)
+# B: optionally-NULL buffer (e.g., 4th arg to getsockopt)
+# f: buffer of 2 ints (e.g., 4th arg to socketpair)
+# i: scalar (any signedness & size: int, long, long long, enum, whatever)
+# n: scalar buffer length (e.g., 3rd arg to read)
+# N: pointer to value/return scalar buffer length (e.g., 6th arg to recvfrom)
+# p: pointer to typed object (e.g., any non-void* arg)
+# P: pointer return value (e.g., return value from mmap)
+# s: string (e.g., 1st arg to open)
+# v: vararg scalar (e.g., optional 3rd arg to open)
+# V: vararg pointer (e.g., 3rd arg to fcntl & ioctl)
+
+ptrlet='[abBfNpPs]'
+argdig='[1-9]'
+fixarg='[^vV]'$argdig	# fixed args (declare extern)
+strarg=s$argdig		# string arg (check with CHECK_STRING)
+twoarg=f$argdig		# fd pair arg (check with CHECK_N (..., 2)
+objarg=p$argdig		# object arg (check with CHECK_1)
+ptrarg=$ptrlet$argdig	# pointer arg (toss bounds)
+rtnarg='P'$argdig	# pointer return value (add bounds)
+bufarg='[bB]'$argdig	# buffer arg (check with CHECK_N)
+intarg='[inv]'$argdig	# scalar arg
+borarg='[iv]'$argdig	# boring arg (just pass it through)
+
+##############################################################################
+
 thisdir=$1; shift
 
 echo ''
@@ -40,11 +71,12 @@ done`
 test -n "$calls" || exit 0
 
 # Emit rules to compile the syscalls remaining in $calls.
-echo "$calls" | while read file srcfile caller syscall args strong weak; do
+echo "$calls" |
+while read file srcfile caller syscall args strong weak; do
 
-# Figure out if $syscall is defined with a number in syscall.h.
-callnum=-
-eval `{ echo "#include <sysdep.h>";
+  # Figure out if $syscall is defined with a number in syscall.h.
+  callnum=-
+  eval `{ echo "#include <sysdep.h>";
 	echo "callnum=SYS_ify ($syscall)"; } |
 	  $asm_CPP - |sed -n -e "/^callnum=.*$syscall/d" \
 			     -e "/^\(callnum=\)[ 	]*\(.*\)/s//\1'\2'/p"`
@@ -66,7 +98,9 @@ eval `{ echo "#include <sysdep.h>";
 
   # Make sure only the first syscall rule is used, if multiple dirs
   # define the same syscall.
- echo "#### CALL=$file NUMBER=$callnum ARGS=$args SOURCE=$srcfile"
+  echo ''
+  echo "#### CALL=$file NUMBER=$callnum ARGS=$args SOURCE=$srcfile"
+
  case x$srcfile"$callnum" in
  x*-) ;; ### Do nothing for undefined callnum
  x-*)
@@ -156,23 +190,102 @@ shared-only-routines += $file
  esac
 
   case x"$callnum",$srcfile,$args in
-  x-,-,*) ;;
-  x*,-,*[sp]* | x*,*.[sS],*[sp]*)
+  x-,-,* | x*,*.[sS],*V*) ;;
+  x*,-,*$ptrlet* | x*,*.[sS],*$ptrlet*)
+
+    # find the name without leading underscores
+    set `echo $strong $weak |tr -s ' \t' '\12' |sed '/^_/d'`
+    callname=$1
+
+    # convert signature string to individual numbered arg names
+    # e.g., i:ipbN -> i0 i1 p2 b3 N4
+    set `echo $args |
+	sed -e 's/^\(.\):\(.*\)/\2 \10/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \11/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \12/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \13/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \14/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \15/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \16/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \17/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \18/' \
+	    -e 's/^\([^ ]\)\(.*\)/\2 \19/'`
+    rtn=$1; shift
+    args=$*
+    arglist=`echo $* |sed 's/ /, /g'`
+
+    # The best way to understand what's going on here is to examine
+    # the output in BUILDDIR/sysd-syscalls.
+
+    # generate makefile envelope & rule head
     echo "ifeq (,\$(filter $file,\$(bp-thunks)))"
-    echo "bp-thunks += $file";
+    echo "bp-thunks += $file"
+    echo "\$(objpfx)\$(bppfx)$file.ob: \$(common-objpfx)s-proto.d"
+
+    # generate macro head & thunk prologue
     echo "\
-\$(objpfx)\$(bppfx)$file.ob: \$(common-objpfx)s-proto.d
-	(echo '#include <bp-thunks.h>'; \\
-	 echo 'BP_THUNK_`echo $args |tr : _` ($strong)'; \\"
+	(echo '#define $callname($arglist) r0, $rtn; \\'; \\
+	 echo '`echo $args | \
+		    sed -e 's/\('$fixarg'\)/extern \1, \1v;/g' \
+			-e 's/\(v'$argdig'\)/extern int \1v;/g'` \\'; \\
+	 echo '__typeof (r0) BP_SYM ($strong) (`echo $args | \
+		    sed -e 's/ /, /g' \
+			-e 's/\('$ptrarg'\)/__typeof (\1v) *__bounded \1a/g' \
+			-e 's/\('$intarg'\)/__typeof (\1v) \1a/g'`) { \\'; \\
+	 echo '  extern __typeof (r0) ($callname) (`echo $args | \
+		    sed -e 's/ /, /g' \
+			-e 's/\('$ptrarg'\)/__typeof (\1v) *__unbounded/g' \
+			-e 's/\('$intarg'\)/__typeof (\1v)/g'`); \\'; \\"
+
+    # generate thunk bounds checks
+    for arg; do
+      next=$2; shift
+      case $arg in
+      B$argdig) echo "	 echo '  __ptrvalue (${arg}a) && \\'; \\" ;;
+      esac
+      case $arg in
+      n$argdig) len=$arg ;; ### save for possible use with return value.
+      $strarg) echo "	 echo '  CHECK_STRING (${arg}a); \\'; \\" ;;
+      $objarg) echo "	 echo '  CHECK_1 (${arg}a); \\'; \\" ;;
+      $twoarg) echo "	 echo '  CHECK_N (${arg}a, 2); \\'; \\" ;;
+      $bufarg)
+	case $next in
+	n$argdig) echo "	 echo '  CHECK_N (${arg}a, ${next}a); \\'; \\" ;;
+	N$argdig) echo "	 echo '  CHECK_N (${arg}a, *CHECK_1 (${next}a)); \\'; \\" ;;
+	*) echo "### BP Thunk Error: Expected length after buffer ###" ;;
+	esac ;;
+      esac
+    done
 
+    # generate thunk epilogue
+    funcall="($callname) (`echo $args | \
+		    sed -e 's/ /, /g' \
+			-e 's/\('$ptrarg'\)/__ptrvalue (\1a)/g' \
+			-e 's/\('$intarg'\)/\1a/g'`)"
+    case $rtn in
+    P*) echo "	 echo '{ __typeof ($rtn) *__bounded rtn; \\'; \\
+	 echo '  __ptrlow (rtn) = __ptrvalue (rtn) = $funcall; \\'; \\
+	 echo '  __ptrhigh (rtn) = __ptrlow (rtn) + ${len}a; return rtn; } \\'; \\" ;;
+    *) echo "	 echo '  return $funcall; \\'; \\" ;;
+    esac
+    echo "	 echo '} \\'; \\"
+
+    # generate thunk aliases
     for name in $weak; do
       case $name in
 	*@*) ;;
-	*) echo "	 echo 'BP_ALIAS ($strong, $name)'; \\" ;;
+	*) echo "	 echo 'weak_alias (BP_SYM ($strong), BP_SYM ($name)) \\'; \\" ;;
       esac
     done
-
-    echo '	) | $(COMPILE.c) -x c -o $@ -'
+    # wrap up
+    echo "\
+	 echo ''; \\
+	 echo '#include <bp-thunks.h>'; \\
+	) | \$(COMPILE.c) -x c -o \$@ -"
+### Use this for debugging intermediate output:
+### echo '	) >$(@:.ob=.c)
+###	$(subst -c,-E,$(COMPILE.c)) -o $(@:.ob=.ib) $(@:.ob=.c)
+###	$(COMPILE.c) -x cpp-output -o $@ $(@:.ob=.ib)'
     echo endif
     ;;
   esac
diff --git a/sysdeps/unix/mman/syscalls.list b/sysdeps/unix/mman/syscalls.list
index 67aa948915..d610fe5eee 100644
--- a/sysdeps/unix/mman/syscalls.list
+++ b/sysdeps/unix/mman/syscalls.list
@@ -5,7 +5,7 @@
 # File name	Caller	Syscall name	# args	Strong name	Weak names
 
 madvise		-	madvise		i:pii	madvise
-mmap		-	mmap		p:piiiii	__mmap		mmap
-mprotect	-	mprotect	i:pii	__mprotect	mprotect
-msync		-	msync		i:pii	__libc_msync	msync
-munmap		-	munmap		i:pi	__munmap	munmap
+mmap		-	mmap		P:aniiii __mmap		mmap
+mprotect	-	mprotect	i:aii	__mprotect	mprotect
+msync		-	msync		i:aii	__libc_msync	msync
+munmap		-	munmap		i:ai	__munmap	munmap
diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
index 530402ab78..ee99b3b573 100644
--- a/sysdeps/unix/syscalls.list
+++ b/sysdeps/unix/syscalls.list
@@ -10,7 +10,7 @@ close		-	close		i:i	__libc_close	__close close
 dup		-	dup		i:i	__dup		dup
 dup2		-	dup2		i:ii	__dup2		dup2
 fchdir		-	fchdir		i:i	__fchdir	fchdir
-fcntl		-	fcntl		i:iip	__libc_fcntl	__fcntl fcntl
+fcntl		-	fcntl		i:iiV	__libc_fcntl	__fcntl fcntl
 fstatfs		-	fstatfs		i:ip	__fstatfs	fstatfs
 fsync		-	fsync		i:i	__libc_fsync	fsync
 getdomain	-	getdomainname	i:si	getdomainname
@@ -21,15 +21,15 @@ getpid		-	getpid		i:	__getpid	getpid
 getpriority	-	getpriority	i:ii	getpriority
 getrlimit	-	getrlimit	i:ip	__getrlimit	getrlimit
 getuid		-	getuid		i:	__getuid	getuid
-ioctl		-	ioctl		i:iip	__ioctl		ioctl
+ioctl		-	ioctl		i:iiV	__ioctl		ioctl
 kill		-	kill		i:ii	__kill		kill
 link		-	link		i:ss	__link		link
 lseek		-	lseek		i:iii	__libc_lseek	__lseek lseek
 mkdir		-	mkdir		i:si	__mkdir		mkdir
-open		-	open		i:sii	__libc_open	__open open
+open		-	open		i:siv	__libc_open	__open open
 profil		-	profil		i:piii	profil
 ptrace		-	ptrace		i:iiii	ptrace
-read		-	read		i:ipi	__libc_read	__read read
+read		-	read		i:ibn	__libc_read	__read read
 readlink	-	readlink	i:spi	__readlink	readlink
 readv		-	readv		i:ipi	__readv		readv
 reboot		-	reboot		i:i	reboot
@@ -61,5 +61,5 @@ umask		-	umask		i:i	__umask		umask
 uname		-	uname		i:p	uname
 unlink		-	unlink		i:s	__unlink	unlink
 utimes		-	utimes		i:sp	__utimes	utimes
-write		-	write		i:ipi	__libc_write	__write write
+write		-	write		i:ibn	__libc_write	__write write
 writev		-	writev		i:ipi	__writev	writev
diff --git a/sysdeps/unix/sysv/linux/ia64/syscalls.list b/sysdeps/unix/sysv/linux/ia64/syscalls.list
index 7b484051be..a7a465a03c 100644
--- a/sysdeps/unix/sysv/linux/ia64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/ia64/syscalls.list
@@ -8,15 +8,15 @@ pread		-	pread		4	__syscall_pread	__syscall_pread64 __pread pread __pread64 prea
 pwrite		-	pwrite		4	__syscall_pwrite	__syscall_pwrite64 __pwrite pwrite __pwrite64 pwrite64
 fstatfs		-	fstatfs		i:ip	__fstatfs	fstatfs fstatfs64 __fstatfs64
 statfs		-	statfs		i:sp	__statfs	statfs statfs64
-mmap		-	mmap		6	__mmap		mmap __mmap64 mmap64
+mmap		-	mmap		P:aniiii __mmap		mmap __mmap64 mmap64
 getpeername	-	getpeername	i:ipp	__getpeername	getpeername
 getpriority	-	getpriority	i:ii	__getpriority	getpriority
 
 # semaphore and shm system calls
 msgctl		-	msgctl		i:iip	__msgctl	msgctl
 msgget		-	msgget		i:ii	__msgget	msgget
-msgrcv		-	msgrcv		i:ipiii	__msgrcv	msgrcv
-msgsnd		-	msgsnd		i:ipii	__msgsnd	msgsnd
+msgrcv		-	msgrcv		i:ibnii	__msgrcv	msgrcv
+msgsnd		-	msgsnd		i:ibni	__msgsnd	msgsnd
 shmat		-	shmat		i:ipi	__shmat		shmat
 shmctl		-	shmctl		i:iip	__shmctl	shmctl
 shmdt		-	shmdt		i:s	__shmdt		shmdt
@@ -31,18 +31,18 @@ bind		-	bind		i:ipi	__bind		bind
 connect		-	connect		i:ipi	__libc_connect	__connect connect
 getpeername	-	getpeername	i:ipp	__getpeername	getpeername
 getsockname	-	getsockname	i:ipp	__getsockname	getsockname
-getsockopt	-	getsockopt	i:iiipp	__getsockopt	getsockopt
+getsockopt	-	getsockopt	i:iiiBN	__getsockopt	getsockopt
 listen		-	listen		i:ii	__listen	listen
-recv		-	recv		i:ipii	__libc_recv	__recv recv
-recvfrom	-	recvfrom	i:ipiipp	__libc_recvfrom	__recvfrom recvfrom
+recv		-	recv		i:ibni	__libc_recv	__recv recv
+recvfrom	-	recvfrom	i:ibnibN	__libc_recvfrom	__recvfrom recvfrom
 recvmsg		-	recvmsg		i:ipi	__libc_recvmsg	recvmsg
-send		-	send		i:ipii	__libc_send	__send send
+send		-	send		i:ibni	__libc_send	__send send
 sendmsg		-	sendmsg		i:ipi	__libc_sendmsg	sendmsg
-sendto		-	sendto		i:ipiipi	__libc_sendto	__sendto sendto
-setsockopt	-	setsockopt	i:iiipi	__setsockopt	setsockopt
+sendto		-	sendto		i:ibnibn	__libc_sendto	__sendto sendto
+setsockopt	-	setsockopt	i:iiibn	__setsockopt	setsockopt
 shutdown	-	shutdown	i:ii	__shutdown	shutdown
 socket		-	socket		i:iii	__socket	socket
-socketpair	-	socketpair	i:iiip	__socketpair	socketpair
+socketpair	-	socketpair	i:iiif	__socketpair	socketpair
 
 # DIG-compliant access to PCI configuration space:
 pciconfig_read	EXTRA	pciconfig_read	5	pciconfig_read
@@ -57,7 +57,7 @@ getresgid	-	getresgid	i:ppp	getresgid
 rt_sigaction	EXTRA	rt_sigaction	i:ippi	__syscall_rt_sigaction		rt_sigaction
 rt_sigpending	EXTRA	rt_sigpending	i:pi	__syscall_rt_sigpending		rt_sigpending
 rt_sigprocmask	EXTRA	rt_sigprocmask	i:ippi	__syscall_rt_sigprocmask	rt_sigprocmask
-rt_sigqueueinfo	EXTRA	rt_sigqueueinfo	i:iip	__syscall_rt_sigqueueinfo	rt_sigqueueinfo	
+rt_sigqueueinfo	EXTRA	rt_sigqueueinfo	i:iip	__syscall_rt_sigqueueinfo	rt_sigqueueinfo
 rt_sigsuspend	EXTRA	rt_sigsuspend	i:pi	__syscall_rt_sigsuspend		rt_sigsuspend
 rt_sigtimedwait	EXTRA	rt_sigtimedwait	i:pppi	__syscall_rt_sigtimedwait	rt_sigtimedwait
 
diff --git a/sysdeps/unix/sysv/linux/mips/syscalls.list b/sysdeps/unix/sysv/linux/mips/syscalls.list
index 575d4c4bf1..117e7dd0fa 100644
--- a/sysdeps/unix/sysv/linux/mips/syscalls.list
+++ b/sysdeps/unix/sysv/linux/mips/syscalls.list
@@ -21,18 +21,18 @@ bind		-	bind		i:ipi	__bind		bind
 connect		-	connect		i:ipi	__libc_connect	__connect connect
 getpeername	-	getpeername	i:ipp	__getpeername	getpeername
 getsockname	-	getsockname	i:ipp	__getsockname	getsockname
-getsockopt	-	getsockopt	i:iiipp	__getsockopt	getsockopt
+getsockopt	-	getsockopt	i:iiiBN	__getsockopt	getsockopt
 listen		-	listen		i:ii	__listen	listen
-recv		-	recv		i:ipii	__libc_recv	__recv recv
-recvfrom	-	recvfrom	i:ipiipp __libc_recvfrom __recvfrom recvfrom
+recv		-	recv		i:ibni	__libc_recv	__recv recv
+recvfrom	-	recvfrom	i:ibnibN __libc_recvfrom __recvfrom recvfrom
 recvmsg		-	recvmsg		i:ipi	__libc_recvmsg	__recvmsg recvmsg
-send		-	send		i:ipii	__libc_send	__send send
+send		-	send		i:ibni	__libc_send	__send send
 sendmsg		-	sendmsg		i:ipi	__libc_sendmsg	__sendmsg sendmsg
-sendto		-	sendto		i:ipiipi __libc_sendto	__sendto sendto
-setsockopt	-	setsockopt	i:iiipi	__setsockopt	setsockopt
+sendto		-	sendto		i:ibnibn __libc_sendto	__sendto sendto
+setsockopt	-	setsockopt	i:iiibn	__setsockopt	setsockopt
 shutdown	-	shutdown	i:ii	__shutdown	shutdown
 socket		-	socket		i:iii	__socket	socket
-socketpair	-	socketpair	i:iiip	__socketpair	socketpair
+socketpair	-	socketpair	i:iiif	__socketpair	socketpair
 
 #
 # These are defined locally because the caller is also defined in this dir.
@@ -61,10 +61,10 @@ getresuid	-	getresuid	i:ppp	getresuid
 s_ipc		msgget	ipc		i:iiiip	__syscall_ipc
 s_lstat64	lxstat64 lstat64	i:sp	__syscall_lstat64
 s_poll		poll	poll		i:pii	__syscall_poll
-s_pread64	pread64	pread		i:ipiiii __syscall_pread
+s_pread64	pread64	pread		i:ibniii __syscall_pread
 s_putpmsg	putpmsg	putpmsg		i:ippii	__syscall_putpmsg
 s_ptrace	ptrace	ptrace		i:iipp	__syscall_ptrace
-s_pwrite64	pwrite64 pwrite		i:ipiiii __syscall_pwrite
+s_pwrite64	pwrite64 pwrite		i:ibniii __syscall_pwrite
 s_reboot	reboot	reboot		i:iii	__syscall_reboot
 s_setrlimit	setrlimit setrlimit	i:ip	__syscall_setrlimit
 s_sigpending	sigpending sigpending	i:p	__syscall_sigpending
diff --git a/sysdeps/unix/sysv/linux/powerpc/syscalls.list b/sysdeps/unix/sysv/linux/powerpc/syscalls.list
index 1b329fa55d..7fc6fa2b33 100644
--- a/sysdeps/unix/sysv/linux/powerpc/syscalls.list
+++ b/sysdeps/unix/sysv/linux/powerpc/syscalls.list
@@ -22,12 +22,12 @@ getresgid	-	getresgid	i:ppp	getresgid
 getresuid	-	getresuid	i:ppp	getresuid
 s_getrlimit	getrlimit getrlimit	i:ip	__syscall_getrlimit
 s_lstat64	lxstat64 lstat64	i:sp	__syscall_lstat64
-s_mmap2		mmap64	mmap2		p:piiiii __syscall_mmap2
+s_mmap2		mmap64	mmap2		P:aniiii __syscall_mmap2
 s_poll		poll	poll		i:pii	__syscall_poll
-s_pread64	pread64	pread		i:ipiii	__syscall_pread
+s_pread64	pread64	pread		i:ibnii	__syscall_pread
 s_ptrace	ptrace	ptrace		i:iipp	__syscall_ptrace
 s_putpmsg	putpmsg	putpmsg		i:ippii	__syscall_putpmsg
-s_pwrite64	pwrite64 pwrite		i:ipiii	__syscall_pwrite
+s_pwrite64	pwrite64 pwrite		i:ibnii	__syscall_pwrite
 s_reboot	reboot	reboot		i:iii	__syscall_reboot
 s_setrlimit	setrlimit setrlimit	i:ip	__syscall_setrlimit
 s_sigaction	sigaction sigaction	i:ipp	__syscall_sigaction
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 9b72a61c54..8d7e7703f9 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -23,18 +23,18 @@ klogctl		EXTRA	syslog		i:isi	klogctl
 lchown		-	lchown		i:sii	__lchown	lchown
 madvise		-	madvise		i:pii	posix_madvise	madvise
 mincore		-	mincore		i:iip	mincore
-mlock		EXTRA	mlock		i:pi	__mlock	mlock
+mlock		EXTRA	mlock		i:bn	__mlock	mlock
 mlockall	EXTRA	mlockall	i:i	__mlockall	mlockall
-mmap		-	mmap		p:piiiii	__mmap		mmap
+mmap		-	mmap		P:aniiii	__mmap		mmap
 mount		EXTRA	mount		i:sssip	__mount	mount
-mremap		EXTRA	mremap		p:piii	__mremap	mremap
-munlock		EXTRA	munlock		i:pi	__munlock	munlock
+mremap		EXTRA	mremap		P:aini	__mremap	mremap
+munlock		EXTRA	munlock		i:ai	__munlock	munlock
 munlockall	EXTRA	munlockall	i:	__munlockall	munlockall
 nanosleep	-	nanosleep	i:pp	__libc_nanosleep	__nanosleep nanosleep
 nfsservctl	EXTRA	nfsservctl	i:ipp	nfsservctl
 pause		-	pause		i:	__libc_pause	pause
 personality	init-first personality	i:i	__personality	personality
-pipe		-	pipe		i:p	__pipe		pipe
+pipe		-	pipe		i:f	__pipe		pipe
 prctl		EXTRA	prctl		i:iiiii	prctl
 query_module	EXTRA	query_module	i:sipip	query_module
 quotactl	EXTRA	quotactl	i:isip	quotactl