changeset 13989:c97356b78587

3544 save-args matcher could be considerably more robust 3545 save-args matcher should accept saves may be out-of-order Reviewed by: Joshua M. Clulow <josh@sysmgr.org> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Albert Lee <trisk@nexenta.com> Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com> Approved by: Gordon Ross <gwr@nexenta.com>
author Richard Lowe <richlowe@richlowe.net>
date Sat, 09 Feb 2013 17:21:16 -0500
parents 81670e8b6dd9
children b04b9a80047a
files exception_lists/packaging usr/src/cmd/mdb/intel/amd64/Makefile.kmdb usr/src/cmd/mdb/intel/amd64/kmdb/Makefile usr/src/cmd/mdb/intel/amd64/mdb/Makefile usr/src/common/saveargs/saveargs.c usr/src/common/saveargs/saveargs.h usr/src/common/saveargs/tests/README usr/src/common/saveargs/tests/functional/Makefile usr/src/common/saveargs/tests/functional/align.c usr/src/common/saveargs/tests/functional/basic.c usr/src/common/saveargs/tests/functional/big-struct-ret-and-spill.c usr/src/common/saveargs/tests/functional/big-struct-ret.c usr/src/common/saveargs/tests/functional/small-struct-ret-and-spill.c usr/src/common/saveargs/tests/functional/small-struct-ret.c usr/src/common/saveargs/tests/functional/stack-spill.c usr/src/common/saveargs/tests/functional/test.sh usr/src/common/saveargs/tests/testmatch/Makefile usr/src/common/saveargs/tests/testmatch/data.s usr/src/common/saveargs/tests/testmatch/testmatch.c usr/src/lib/Makefile usr/src/lib/libdisasm/common/libdisasm.h usr/src/lib/libdisasm/common/mapfile-vers usr/src/lib/libdisasm/i386/dis_i386.c usr/src/lib/libdisasm/sparc/dis_sparc.c usr/src/lib/libproc/Makefile.com usr/src/lib/libproc/amd64/Makefile usr/src/lib/libsaveargs/Makefile usr/src/lib/libsaveargs/Makefile.com usr/src/lib/libsaveargs/Makefile.targ usr/src/lib/libsaveargs/amd64/Makefile usr/src/lib/libsaveargs/amd64/saveargs.c usr/src/lib/libsaveargs/common/linktest_stand.c usr/src/lib/libsaveargs/common/llib-lsaveargs usr/src/lib/libsaveargs/common/mapfile-vers usr/src/lib/libsaveargs/common/saveargs.h usr/src/lib/libsaveargs/tests/README usr/src/lib/libsaveargs/tests/dump/Makefile usr/src/lib/libsaveargs/tests/dump/dump.c usr/src/lib/libsaveargs/tests/functional/Makefile usr/src/lib/libsaveargs/tests/functional/align.c usr/src/lib/libsaveargs/tests/functional/basic.c usr/src/lib/libsaveargs/tests/functional/big-struct-ret-and-spill.c usr/src/lib/libsaveargs/tests/functional/big-struct-ret.c usr/src/lib/libsaveargs/tests/functional/small-struct-ret-and-spill.c usr/src/lib/libsaveargs/tests/functional/small-struct-ret.c usr/src/lib/libsaveargs/tests/functional/stack-spill.c usr/src/lib/libsaveargs/tests/functional/test.sh usr/src/lib/libsaveargs/tests/testmatch/Makefile usr/src/lib/libsaveargs/tests/testmatch/data.s usr/src/lib/libsaveargs/tests/testmatch/testmatch.c usr/src/pkg/manifests/system-library.mf usr/src/tools/findunref/exception_list.open
diffstat 52 files changed, 2044 insertions(+), 1271 deletions(-) [+]
line wrap: on
line diff
--- a/exception_lists/packaging	Fri Mar 15 16:26:41 2013 -0400
+++ b/exception_lists/packaging	Sat Feb 09 17:21:16 2013 -0500
@@ -973,3 +973,11 @@
 # delivered on SPARC and used by the build.
 #
 usr/include/sys/ipmi.h	sparc
+
+#
+# libsaveargs is private
+#
+usr/include/saveargs.h            	i386
+usr/lib/amd64/libsaveargs.so      	i386
+usr/lib/amd64/libstandsaveargs.so	i386
+usr/lib/amd64/llib-lsaveargs.ln   	i386
--- a/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb	Sat Feb 09 17:21:16 2013 -0500
@@ -29,15 +29,6 @@
 
 KMDBSRCS += \
 	kmdb_makecontext.c \
-	mdb_amd64util.c \
-	saveargs.c
-
-%.o: $(SRC)/common/saveargs/%.c
-	$(COMPILE.c) $<
-	$(CTFCONVERT_O)
-
-%.ln: $(SRC)/common/saveargs/%.c
-	$(LINT.c) -c $<
+	mdb_amd64util.c
 
 SACPPFLAGS = -D__$(MACH64) -U__$(MACH)
-CPPFLAGS += -I$(SRC)/common/saveargs
--- a/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -62,6 +62,7 @@
 include ../../../Makefile.kmdb
 
 STANDLIBS += $(ROOT)/usr/lib/amd64/libstanddisasm.so
+STANDLIBS += $(ROOT)/usr/lib/amd64/libstandsaveargs.so
 
 INCDIRS += $(SRC)/uts/i86pc $(SRC)/common/dis/i386
 
--- a/usr/src/cmd/mdb/intel/amd64/mdb/Makefile	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/cmd/mdb/intel/amd64/mdb/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -26,8 +26,7 @@
 SRCS =	kvm_amd64dep.c \
 	kvm_isadep.c \
 	mdb_amd64util.c \
-	proc_amd64dep.c \
-	saveargs.c
+	proc_amd64dep.c
 
 %.o: %.c
 	$(COMPILE.c) $<
@@ -37,25 +36,18 @@
 	$(COMPILE.c) $<
 	$(CTFCONVERT_O)
 
-%.o: $(SRC)/common/saveargs/%.c
-	$(COMPILE.c) $<
-	$(CTFCONVERT_O)
-
 %.ln: %.c
 	$(LINT.c) -c $<
 
 %.ln: ../../mdb/%.c
 	$(LINT.c) -c $<
 
-%.ln: $(SRC)/common/saveargs/%.c
-	$(LINT.c) -c $<
-
 include ../../../../Makefile.cmd
 include ../../../../Makefile.cmd.64
 include ../../Makefile.amd64
 include ../../../Makefile.mdb
 
 CPPFLAGS += -I../../mdb
-CPPFLAGS += -I$(SRC)/common/saveargs
+LDLIBS += -lsaveargs
 
 install: all $(ISAEXEC) $(ROOTPROG64) $(ROOTLINK64)
--- a/usr/src/common/saveargs/saveargs.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * The Sun Studio and GCC (patched for opensolaris/illumos) compilers
- * implement a argument saving scheme on amd64 via the -Wu,save-args or
- * options.  When the option is specified, INTEGER type function arguments
- * passed via registers will be saved on the stack immediately after %rbp, and
- * will not be modified through out the life of the routine.
- *
- *				+--------+
- *		%rbp	-->     |  %rbp  |
- *				+--------+
- *		-0x8(%rbp)	|  %rdi  |
- *				+--------+
- *		-0x10(%rbp)	|  %rsi  |
- *				+--------+
- *		-0x18(%rbp)	|  %rdx  |
- *				+--------+
- *		-0x20(%rbp)	|  %rcx  |
- *				+--------+
- *		-0x28(%rbp)	|  %r8   |
- *				+--------+
- *		-0x30(%rbp)	|  %r9   |
- *				+--------+
- *
- *
- * For example, for the following function,
- *
- * void
- * foo(int a1, int a2, int a3, int a4, int a5, int a6, int a7)
- * {
- * ...
- * }
- *
- * Disassembled code will look something like the following:
- *
- *     pushq	%rbp
- *     movq	%rsp, %rbp
- *     subq	$imm8, %rsp			**
- *     movq	%rdi, -0x8(%rbp)
- *     movq	%rsi, -0x10(%rbp)
- *     movq	%rdx, -0x18(%rbp)
- *     movq	%rcx, -0x20(%rbp)
- *     movq	%r8, -0x28(%rbp)
- *     movq	%r9, -0x30(%rbp)
- *     ...
- * or
- *     pushq	%rbp
- *     movq	%rsp, %rbp
- *     subq	$imm8, %rsp			**
- *     movq	%r9, -0x30(%rbp)
- *     movq	%r8, -0x28(%rbp)
- *     movq	%rcx, -0x20(%rbp)
- *     movq	%rdx, -0x18(%rbp)
- *     movq	%rsi, -0x10(%rbp)
- *     movq	%rdi, -0x8(%rbp)
- *     ...
- * or
- *     pushq	%rbp
- *     movq	%rsp, %rbp
- *     pushq	%rdi
- *     pushq	%rsi
- *     pushq	%rdx
- *     pushq	%rcx
- *     pushq	%r8
- *     pushq	%r9
- *
- * **: The space being reserved is in addition to what the current
- *     function prolog already reserves.
- *
- * We loop through the first SAVEARGS_INSN_SEQ_LEN bytes of the function
- * looking for each argument saving instruction we would expect to see.  We
- * loop byte-by-byte, rather than doing anything smart about insn lengths,
- * only deviating from this when we know we have our insn, and can skip the
- * rest of it.
- *
- * If there are odd number of arguments to a function, additional space is
- * reserved on the stack to maintain 16-byte alignment.  For example,
- *
- *     argc == 0: no argument saving.
- *     argc == 3: save 3, but space for 4 is reserved
- *     argc == 7: save 6.
- */
-
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-#include <saveargs.h>
-
-/*
- * Size of the instruction sequence arrays.  It should correspond to
- * the maximum number of arguments passed via registers.
- */
-#define	INSTR_ARRAY_SIZE	6
-
-#define	INSTR1(ins, off) (ins[(off)])
-#define	INSTR2(ins, off) (ins[(off)] + (ins[(off) + 1] << 8))
-#define	INSTR3(ins, off)	\
-	(ins[(off)] + (ins[(off) + 1] << 8) + (ins[(off + 2)] << 16))
-#define	INSTR4(ins, off)	\
-	(ins[(off)] + (ins[(off) + 1] << 8) + (ins[(off + 2)] << 16) + \
-	(ins[(off) + 3] << 24))
-
-/*
- * Sun Studio 10 patch implementation saves %rdi first;
- * GCC 3.4.3 Sun branch implementation saves them in reverse order.
- */
-static const uint32_t save_instr[INSTR_ARRAY_SIZE] = {
-	0xf87d8948,	/* movq %rdi, -0x8(%rbp) */
-	0xf0758948,	/* movq %rsi, -0x10(%rbp) */
-	0xe8558948,	/* movq %rdx, -0x18(%rbp) */
-	0xe04d8948,	/* movq %rcx, -0x20(%rbp) */
-	0xd845894c,	/* movq %r8, -0x28(%rbp) */
-	0xd04d894c	/* movq %r9, -0x30(%rbp) */
-};
-
-static const uint16_t save_instr_push[] = {
-	0x57,	/* pushq %rdi */
-	0x56,	/* pushq %rsi */
-	0x52,	/* pushq %rdx */
-	0x51,	/* pushq %rcx */
-	0x5041,	/* pushq %r8 */
-	0x5141	/* pushq %r9 */
-};
-
-/*
- * If the return type of a function is a structure greater than 16 bytes in
- * size, %rdi will contain the address to which it should be stored, and
- * arguments will begin at %rsi.  Studio will push all of the normal argument
- * registers anyway, GCC will start pushing at %rsi, so we need a separate
- * pattern.
- */
-static const uint32_t save_instr_sr[INSTR_ARRAY_SIZE-1] = {
-	0xf8758948,	/* movq %rsi,-0x8(%rbp) */
-	0xf0558948,	/* movq %rdx,-0x10(%rbp) */
-	0xe84d8948,	/* movq %rcx,-0x18(%rbp) */
-	0xe045894c,	/* movq %r8,-0x20(%rbp) */
-	0xd84d894c	/* movq %r9,-0x28(%rbp) */
-};
-
-static const uint8_t save_fp_pushes[] = {
-    0x55,	/* pushq %rbp */
-    0xcc	/* int $0x3 */
-};
-#define	NUM_FP_PUSHES (sizeof (save_fp_pushes) / sizeof (save_fp_pushes[0]))
-
-static const uint32_t save_fp_movs[] = {
-	0x00e58948,	/* movq %rsp,%rbp, encoding 1 */
-	0x00ec8b48,	/* movq %rsp,%rbp, encoding 2 */
-};
-#define	NUM_FP_MOVS (sizeof (save_fp_movs) / sizeof (save_fp_movs[0]))
-
-static int
-has_saved_fp(uint8_t *ins, int size)
-{
-	int i, j;
-	uint32_t n;
-	int found_push = 0;
-
-	for (i = 0; i < size; i++) {
-		if (found_push == 0) {
-			n = INSTR1(ins, i);
-			for (j = 0; j <= NUM_FP_PUSHES; j++)
-				if (save_fp_pushes[j] == n) {
-					found_push = 1;
-					break;
-				}
-		} else {
-			n = INSTR3(ins, i);
-			for (j = 0; j <= NUM_FP_MOVS; j++)
-				if (save_fp_movs[j] == n)
-					return (1);
-		}
-	}
-
-	return (0);
-}
-
-int
-saveargs_has_args(uint8_t *ins, size_t size, uint_t argc, int start_index)
-{
-	int		i, j;
-	uint32_t	n;
-
-	argc = MIN((start_index + argc), INSTR_ARRAY_SIZE);
-
-	if (!has_saved_fp(ins, size))
-		return (SAVEARGS_NO_ARGS);
-
-	/*
-	 * Compare against Sun Studio implementation
-	 */
-	for (i = 4, j = 0; i <= size - 4; i++) {
-		n = INSTR4(ins, i);
-
-		if (n == save_instr[j]) {
-			i += 3;
-			if (++j >= argc)
-				return (start_index ? SAVEARGS_STRUCT_ARGS :
-				    SAVEARGS_TRAD_ARGS);
-		}
-	}
-
-	/*
-	 * Compare against GCC implementation
-	 */
-	for (i = 4, j = argc - 1; i <= size - 4; i++) {
-		n = INSTR4(ins, i);
-
-		if (n == save_instr[j]) {
-			i += 3;
-			if (--j < start_index)
-				return (SAVEARGS_TRAD_ARGS);
-		}
-	}
-
-	/*
-	 * Compare against GCC push-based implementation
-	 */
-	for (i = 4, j = start_index; i <= size - 2; i += 1) {
-		n = (i >= (8 - start_index)) ? INSTR2(ins, i) : INSTR1(ins, i);
-
-		if (n == save_instr_push[j]) {
-			if (i >= (8 - start_index))
-				i += 1;
-			if (++j >= argc)
-				return (SAVEARGS_TRAD_ARGS);
-		}
-	}
-
-	/* Look for a GCC-style returned structure */
-	if (start_index != 0) {
-		for (i = 4, j = argc - 2; i <= size - 4; i++) {
-			n = INSTR4(ins, i);
-
-			if (n == save_instr_sr[j]) {
-				i += 3;
-				if (--j >= (argc - 1))
-					return (SAVEARGS_TRAD_ARGS);
-			}
-		}
-	}
-
-	return (SAVEARGS_NO_ARGS);
-}
--- a/usr/src/common/saveargs/saveargs.h	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef	_SAVEARGS_H
-#define	_SAVEARGS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-
-/*
- * The longest instruction sequence in bytes before all 6 arguments are
- * saved on the stack.  This value depends on compiler implementation,
- * therefore it should be examined periodically to guarantee accuracy.
- */
-#define	SAVEARGS_INSN_SEQ_LEN	256
-
-#define	SAVEARGS_NO_ARGS	0	/* no saved arguments */
-#define	SAVEARGS_TRAD_ARGS	1	/* traditionally located arguments */
-#define	SAVEARGS_STRUCT_ARGS	2	/* struct return addr pushed as arg0 */
-
-int saveargs_has_args(uint8_t *, size_t, uint_t, int);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	/* _SAVEARGS_H */
--- a/usr/src/common/saveargs/tests/README	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-testmatch:
-
-   A stub program that tests the saveargs matcher against a variety of
-   function prologues (assembled from data.s)
-
-functional:
-
-   Actually test the full chunk of the (libproc) side of the code, running
-   pstack on the range of test apps.
--- a/usr/src/common/saveargs/tests/functional/Makefile	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#
-# This file and its contents are supplied under the terms of the
-# Common Development and Distribution License ("CDDL"), version 1.0.
-# You may only use this file in accordance with the terms of version
-# 1.0 of the CDDL.
-#
-# A full copy of the text of the CDDL should have accompanied this
-# source.  A copy of the CDDL is also available via the Internet at
-# http://www.illumos.org/license/CDDL.
-#
-
-#
-# Copyright 2012, Richard Lowe.
-#
-
-include $(SRC)/Makefile.master
-include $(SRC)/Makefile.master.64
-
-.KEEP_STATE:
-
-PROGS = align \
-	basic \
-	big-struct-ret \
-	big-struct-ret-and-spill \
-	small-struct-ret \
-	small-struct-ret-and-spill \
-	stack-spill
-
-CFLAGS += $(CTF_FLAGS)
-CFLAGS64 += $(CTF_FLAGS)
-
-%: %.c
-	$(LINK.c) -o $@ $< -lc
-	$(CTFCONVERT) -L VERSION $@
-
-all: $(PROGS)
-
-install: all
-
-clean:
-	$(RM) $(PROGS)
-
-clobber: clean
-
-FRC:
--- a/usr/src/common/saveargs/tests/functional/align.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-
-int
-test(long a, long b, long c, long d, long e)
-{
-	printf("%ld %ld %ld %ld %ld\n", a, b, c, d, e);
-	for (;;)
-		sleep(60);
-}
-
-int
-main(int argc, char **argv)
-{
-	test(1, 2, 3, 4, 5);
-	return (0);
-}
--- a/usr/src/common/saveargs/tests/functional/basic.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-
-int
-test(long a, long b, long c, long d)
-{
-	printf("%ld %ld %ld %ld\n", a, b, c, d);
-	for (;;)
-		sleep(60);
-}
-
-int
-main(int argc, char **argv)
-{
-	test(1, 2, 3, 4);
-	return (0);
-}
--- a/usr/src/common/saveargs/tests/functional/big-struct-ret-and-spill.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-
-struct foo {
-	long a;
-	long b;
-	long c;
-};
-
-struct foo
-test(long a, long b, long c, long d, long e, long f, long g, long h)
-{
-	printf("%ld %ld %ld %ld %ld %ld %ld %ld\n", a, b, c, d, e, f, g, h);
-	for (;;)
-		sleep(60);
-}
-
-int
-main(int argc, char **argv)
-{
-	test(1, 2, 3, 4, 5, 6, 7, 8);
-	return (0);
-}
--- a/usr/src/common/saveargs/tests/functional/big-struct-ret.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-
-struct foo {
-	long a;
-	long b;
-	long c;
-};
-
-struct foo
-test(long a, long b, long c, long d)
-{
-	printf("%ld %ld %ld %ld\n", a, b, c, d);
-	for (;;)
-		sleep(60);
-}
-
-int
-main(int argc, char **argv)
-{
-	test(1, 2, 3, 4);
-	return (0);
-}
--- a/usr/src/common/saveargs/tests/functional/small-struct-ret-and-spill.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-
-struct foo {
-	long a;
-	long b;
-};
-
-struct foo
-test(long a, long b, long c, long d, long e, long f, long g, long h)
-{
-	printf("%ld %ld %ld %ld %ld %ld %ld %ld\n", a, b, c, d, e, f, g, h);
-	for (;;)
-		sleep(60);
-}
-
-int
-main(int argc, char **argv)
-{
-	test(1, 2, 3, 4, 5, 6, 7, 8);
-	return (0);
-}
--- a/usr/src/common/saveargs/tests/functional/small-struct-ret.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-
-struct foo {
-	long a;
-	long b;
-};
-
-struct foo
-test(long a, long b, long c, long d)
-{
-	printf("%ld %ld %ld %ld\n", a, b, c, d);
-	for (;;)
-		sleep(60);
-}
-
-int
-main(int argc, char **argv)
-{
-	test(1, 2, 3, 4);
-	return (0);
-}
--- a/usr/src/common/saveargs/tests/functional/stack-spill.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-
-int
-test(long a, long b, long c, long d, long e, long f, long g, long h)
-{
-	printf("%ld %ld %ld %ld %ld %ld %ld %ld\n", a, b, c, d, e, f, g, h);
-	for (;;)
-		sleep(60);
-}
-
-int
-main(int argc, char **argv)
-{
-	test(1, 2, 3, 4, 5, 6, 7, 8);
-	return (0);
-}
--- a/usr/src/common/saveargs/tests/functional/test.sh	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#! /usr/bin/ksh
-#
-# This file and its contents are supplied under the terms of the
-# Common Development and Distribution License ("CDDL"), version 1.0.
-# You may only use this file in accordance with the terms of version
-# 1.0 of the CDDL.
-#
-# A full copy of the text of the CDDL should have accompanied this
-# source.  A copy of the CDDL is also available via the Internet at
-# http://www.illumos.org/license/CDDL.
-#
-
-#
-# Copyright 2012, Richard Lowe.
-#
-
-function tester {
-    prog=${1}
-    pattern=${2}
-
-    ./$prog >/dev/null &
-    pid=$!
-    if (/usr/bin/amd64/pstack $pid | /usr/xpg4/bin/grep -q "${pattern}"); then
-        echo "pass: ${prog}"
-    else
-        echo "FAIL: ${prog}"
-    fi
-    kill $pid
-}
-
-tester align "test (1, 2, 3, 4, 5)"
-tester basic "test (1, 2, 3, 4)"
-tester big-struct-ret "test (1, 2, 3, 4)"
-tester big-struct-ret-and-spill "test (1, 2, 3, 4, 5, 6, 7, 8)"
-tester small-struct-ret "test (1, 2, 3, 4)"
-tester small-struct-ret-and-spill "test (1, 2, 3, 4, 5, 6, 7, 8)"
-tester stack-spill "test (1, 2, 3, 4, 5, 6, 7, 8)"
--- a/usr/src/common/saveargs/tests/testmatch/Makefile	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#
-# This file and its contents are supplied under the terms of the
-# Common Development and Distribution License ("CDDL"), version 1.0.
-# You may only use this file in accordance with the terms of version
-# 1.0 of the CDDL.
-#
-# A full copy of the text of the CDDL should have accompanied this
-# source.  A copy of the CDDL is also available via the Internet at
-# http://www.illumos.org/license/CDDL.
-#
-
-#
-# Copyright 2012, Richard Lowe.
-#
-
-include $(SRC)/Makefile.master
-include $(SRC)/Makefile.master.64
-
-.KEEP_STATE:
-
-OBJECTS = testmatch.o saveargs.o data.o
-PROG = testmatch
-
-CPPFLAGS += -I$(SRC)/common/saveargs
-ASFLAGS += -P
-AS_CPPFLAGS += -D_ASM
-
-%.o: $(SRC)/common/saveargs/%.c
-	$(COMPILE.c) -o $@ $<
-
-$(PROG): $(OBJECTS)
-	$(LINK.c) -o $@ $(OBJECTS) -lc
-
-clean:
-	$(RM) $(OBJECTS) $(PROG)
-
-clobber: clean
-
-all: $(PROG)
-
-install: all
--- a/usr/src/common/saveargs/tests/testmatch/data.s	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#define	FUNC(x) \
-	.text; \
-	.align	16; \
-	.globl	x; \
-	.type	x, @function; \
-x:
-
-#define	SET_SIZE(x, x_size) \
-	.size	x, [.-x]; \
-        .globl x_size; \
-        .type  x_size, @object; \
-x_size:
-
-/*
- * Extracted versions of the functional tests
- *
- * Named of the form <compiler>-<prologue style>-<nature of test>
- * basic			-- A regular function
- * align			-- odd number of arguments needing save-area
- * 				   alignment
- * big-struct-ret		-- returns a > 16byte structure by value
- * big-struct-ret-and-spill	-- returns a > 16byte structure by value and
- * 				   spills args to the stack
- * small-struct-ret		-- returns a < 16byte structure by value
- * small-struct-ret-and-spill	-- returns a < 16byte structure by value and
- * 				   spills args to the stack
- * stack-spill			-- spills arguments to the stack
- */
-FUNC(gcc_mov_align)
-pushq	%rbp
-movq	%rsp, %rbp
-movq	%rbx, -0x38(%rbp)
-movq	%r8, -0x28(%rbp)
-movq	%rcx, -0x20(%rbp)
-movq	%rdx, -0x18(%rbp)
-movq	%rsi, -0x10(%rbp)
-movq	%rdi, -0x8(%rbp)
-subq	$0x70, %rsp
-SET_SIZE(gcc_mov_align, gcc_mov_align_end)
-
-FUNC(gcc_mov_basic)
-pushq	%rbp
-movq	%rsp, %rbp
-movq	%rbx,-0x28(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-subq    $0x50,%rsp
-SET_SIZE(gcc_mov_basic, gcc_mov_basic_end)
-
-FUNC(gcc_mov_big_struct_ret)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rbx,-0x28(%rbp)
-movq    %r8,-0x20(%rbp)
-movq    %rcx,-0x18(%rbp)
-movq    %rdx,-0x10(%rbp)
-movq    %rsi,-0x8(%rbp)
-subq    $0x50,%rsp
-SET_SIZE(gcc_mov_big_struct_ret, gcc_mov_big_struct_ret_end)
-
-FUNC(gcc_mov_big_struct_ret_and_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rbx,-0x38(%rbp)
-movq    %r9,-0x28(%rbp)
-movq    %r8,-0x20(%rbp)
-movq    %rcx,-0x18(%rbp)
-movq    %rdx,-0x10(%rbp)
-movq    %rsi,-0x8(%rbp)
-subq    $0x90,%rsp
-SET_SIZE(gcc_mov_big_struct_ret_and_spill, gcc_mov_big_struct_ret_and_spill_end)
-
-FUNC(gcc_mov_small_struct_ret)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rbx,-0x28(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-subq    $0x50,%rsp
-SET_SIZE(gcc_mov_small_struct_ret, gcc_mov_small_struct_ret_end)
-
-FUNC(gcc_mov_small_struct_ret_and_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rbx,-0x38(%rbp)
-movq    %r9,-0x30(%rbp)
-movq    %r8,-0x28(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-subq    $0x90,%rsp
-SET_SIZE(gcc_mov_small_struct_ret_and_spill, gcc_mov_small_struct_ret_and_spill_end)
-
-FUNC(gcc_mov_stack_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rbx,-0x38(%rbp)
-movq    %r9,-0x30(%rbp)
-movq    %r8,-0x28(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-subq    $0x90,%rsp
-SET_SIZE(gcc_mov_stack_spill, gcc_mov_stack_spill_end)
-
-FUNC(gcc_push_align)
-pushq   %rbp
-movq    %rsp,%rbp
-pushq   %rdi
-pushq   %rsi
-pushq   %rdx
-pushq   %rcx
-pushq   %r8
-subq    $0x8,%rsp
-subq    $0x30,%rsp
-SET_SIZE(gcc_push_align, gcc_push_align_end)
-
-FUNC(gcc_push_basic)
-pushq   %rbp
-movq    %rsp,%rbp
-pushq   %rdi
-pushq   %rsi
-pushq   %rdx
-pushq   %rcx
-subq    $0x20,%rsp
-SET_SIZE(gcc_push_basic, gcc_push_basic_end)
-
-FUNC(gcc_push_big_struct_ret)
-pushq   %rbp
-movq    %rsp,%rbp
-pushq   %rsi
-pushq   %rdx
-pushq   %rcx
-pushq   %r8
-subq    $0x30,%rsp
-SET_SIZE(gcc_push_big_struct_ret, gcc_push_big_struct_ret_end)
-
-FUNC(gcc_push_big_struct_ret_and_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-pushq   %rsi
-pushq   %rdx
-pushq   %rcx
-pushq   %r8
-pushq   %r9
-subq    $0x8,%rsp
-subq    $0x50,%rsp
-SET_SIZE(gcc_push_big_struct_ret_and_spill, gcc_push_big_struct_ret_and_spill_end)
-
-FUNC(gcc_push_small_struct_ret)
-pushq   %rbp
-movq    %rsp,%rbp
-pushq   %rdi
-pushq   %rsi
-pushq   %rdx
-pushq   %rcx
-subq    $0x20,%rsp
-SET_SIZE(gcc_push_small_struct_ret, gcc_push_small_struct_ret_end)
-
-FUNC(gcc_push_small_struct_ret_and_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-pushq   %rdi
-pushq   %rsi
-pushq   %rdx
-pushq   %rcx
-pushq   %r8
-pushq   %r9
-subq    $0x50,%rsp
-SET_SIZE(gcc_push_small_struct_ret_and_spill, gcc_push_small_struct_ret_and_spill_end)
-
-FUNC(gcc_push_stack_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-pushq   %rdi
-pushq   %rsi
-pushq   %rdx
-pushq   %rcx
-pushq   %r8
-pushq   %r9
-subq    $0x50,%rsp
-SET_SIZE(gcc_push_stack_spill, gcc_push_stack_spill_end)
-
-FUNC(ss_mov_align)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x30,%rsp
-movq    %rdi,-0x8(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %r8,-0x28(%rbp)
-SET_SIZE(ss_mov_align, ss_mov_align_end)
-
-FUNC(ss_mov_basic)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x20,%rsp
-movq    %rdi,-0x8(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rcx,-0x20(%rbp)
-SET_SIZE(ss_mov_basic, ss_mov_basic_end)
-
-FUNC(ss_mov_big_struct_ret)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x30,%rsp
-movq    %rdi,-0x8(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %r8,-0x28(%rbp)
-SET_SIZE(ss_mov_big_struct_ret, ss_mov_big_struct_ret_end)
-
-FUNC(ss_mov_big_struct_ret_and_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x50,%rsp
-movq    %rdi,-0x8(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %r8,-0x28(%rbp)
-movq    %r9,-0x30(%rbp)
-SET_SIZE(ss_mov_big_struct_ret_and_spill, ss_mov_big_struct_ret_and_spill_end)
-
-FUNC(ss_mov_small_struct_ret)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x20,%rsp
-movq    %rdi,-0x8(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rcx,-0x20(%rbp)
-SET_SIZE(ss_mov_small_struct_ret, ss_mov_small_struct_ret_end)
-
-FUNC(ss_mov_small_struct_ret_and_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x50,%rsp
-movq    %rdi,-0x8(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %r8,-0x28(%rbp)
-movq    %r9,-0x30(%rbp)
-SET_SIZE(ss_mov_small_struct_ret_and_spill, ss_mov_small_struct_ret_and_spill_end)
-
-FUNC(ss_mov_stack_spill)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x50,%rsp
-movq    %rdi,-0x8(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %r8,-0x28(%rbp)
-movq    %r9,-0x30(%rbp)
-SET_SIZE(ss_mov_stack_spill, ss_mov_stack_spill_end)
-
-/* DTrace instrumentation */
-FUNC(dtrace_instrumented)
-int	$0x3
-movq	%rsp, %rbp
-movq	%rbx,-0x28(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-subq    $0x50,%rsp
-SET_SIZE(dtrace_instrumented, dtrace_instrumented_end)
-
-/*
- * System functions with special characteristics, be they non-initial FP save,
- * gaps between FP save and argument saving, or gaps between saved arguments.
- */
-FUNC(kmem_alloc)
-leaq    -0x1(%rdi),%rax
-pushq   %rbp
-movq    %rax,%rdx
-movq    %rsp,%rbp
-subq    $0x30,%rsp
-shrq    $0x3,%rdx
-movq    %r12,-0x28(%rbp)
-movq    %rbx,-0x30(%rbp)
-cmpq    $0x1ff,%rdx
-movq    %r13,-0x20(%rbp)
-movq    %r14,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-movq    %rdi,%r12
-SET_SIZE(kmem_alloc, kmem_alloc_end)
-
-FUNC(uts_kill)
-pushq   %rbp
-movq    %rsp,%rbp
-subq    $0x50,%rsp
-movq    %rbx,-0x28(%rbp)
-leaq    -0x50(%rbp),%rbx
-movq    %r12,-0x20(%rbp)
-movq    %r13,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movl    %edi,%r12d
-movq    %rdi,-0x8(%rbp)
-SET_SIZE(uts_kill, uts_kill_end)
-
-FUNC(av1394_ic_bitreverse)
-movq    %rdi,%rdx
-movq    $0x5555555555555555,%rax
-movq    $0x3333333333333333,%rcx
-shrq    $0x1,%rdx
-pushq   %rbp
-andq    %rax,%rdx
-andq    %rdi,%rax
-addq    %rax,%rax
-movq    %rsp,%rbp
-subq    $0x10,%rsp
-orq     %rdx,%rax
-movq    %rdi,-0x8(%rbp)
-SET_SIZE(av1394_ic_bitreverse, av1394_ic_bitreverse_end)
-
-/* Problematic functions which should not match */
-
-FUNC(no_fp) /* No frame pointer */
-movq	%rdi, %rsi
-movq	%rsi, %rdi
-movq	%rbx,-0x28(%rbp)
-movq    %rcx,-0x20(%rbp)
-movq    %rdx,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-subq    $0x50,%rsp
-SET_SIZE(no_fp, no_fp_end)
-
-/* Small structure return, but with an SSE type (thus forcing it to the stack) */
-FUNC(small_struct_ret_w_float)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rdi,-0x8(%rbp)
-subq    $0x30,%rsp
-SET_SIZE(small_struct_ret_w_float, small_struct_ret_w_float_end)
-
-/* Big structure return, but with an SSE type */
-FUNC(big_struct_ret_w_float)
-pushq  %rbp
-movq   %rsp,%rbp
-movq   %rsi,-0x8(%rbp)
-subq   $0x50,%rsp
-movq   %rsi,-0x48(%rbp)
-movq   -0x48(%rbp),%rax
-movq   %rax,%rsi
-movl   $0x400f60,%edi
-movl   $0x0,%eax
-movl   $0x1770,%edi
-movl   $0x0,%eax
-leave
-ret
-SET_SIZE(big_struct_ret_w_float, big_struct_ret_w_float_end)
-
-FUNC(big_struct_arg_by_value)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rdi,-0x8(%rbp)
-subq    $0x40,%rsp
-SET_SIZE(big_struct_arg_by_value, big_struct_arg_by_value_end)
-
-FUNC(small_struct_arg_by_value)
-pushq   %rbp
-movq    %rsp,%rbp
-movq    %rdx,-0x18(%rbp)
-movq    %rsi,-0x10(%rbp)
-movq    %rdi,-0x8(%rbp)
-subq    $0x50,%rsp
-SET_SIZE(small_struct_arg_by_value, small_struct_arg_by_value_end)
--- a/usr/src/common/saveargs/tests/testmatch/testmatch.c	Fri Mar 15 16:26:41 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2012, Richard Lowe.
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <saveargs.h>
-
-#define	DEF_TEST(name)		\
-    extern uint8_t name[];	\
-    extern int name##_end
-
-#define	SIZE_OF(name) ((caddr_t)&name##_end - (caddr_t)&name)
-
-#define	TEST_GOOD(name, argc)					\
-    if (saveargs_has_args(name, SIZE_OF(name), argc, 0) != 0)	\
-	printf("Pass: %s\n", #name);				\
-    else							\
-	printf("FAIL: %s\n", #name);
-
-#define	TEST_GOOD_STRUCT(name, argc)				\
-    if (saveargs_has_args(name, SIZE_OF(name), argc, 1) != 0)	\
-	printf("Pass: %s\n", #name);				\
-    else							\
-	printf("FAIL: %s\n", #name);
-
-#define	TEST_BAD(name, argc)					\
-    if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == 0)	\
-	printf("Pass: %s\n", #name);				\
-    else							\
-	printf("FAIL: %s\n", #name);
-
-#define	TEST_BAD_STRUCT(name, argc)				\
-    if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 0)	\
-	printf("Pass: %s\n", #name);				\
-    else							\
-	printf("FAIL: %s\n", #name);
-
-DEF_TEST(gcc_mov_align);
-DEF_TEST(gcc_mov_basic);
-DEF_TEST(gcc_mov_big_struct_ret);
-DEF_TEST(gcc_mov_big_struct_ret_and_spill);
-DEF_TEST(gcc_mov_small_struct_ret);
-DEF_TEST(gcc_mov_small_struct_ret_and_spill);
-DEF_TEST(gcc_mov_stack_spill);
-
-DEF_TEST(gcc_push_align);
-DEF_TEST(gcc_push_basic);
-DEF_TEST(gcc_push_big_struct_ret);
-DEF_TEST(gcc_push_big_struct_ret_and_spill);
-DEF_TEST(gcc_push_small_struct_ret);
-DEF_TEST(gcc_push_small_struct_ret_and_spill);
-DEF_TEST(gcc_push_stack_spill);
-
-DEF_TEST(ss_mov_align);
-DEF_TEST(ss_mov_basic);
-DEF_TEST(ss_mov_big_struct_ret);
-DEF_TEST(ss_mov_big_struct_ret_and_spill);
-DEF_TEST(ss_mov_small_struct_ret);
-DEF_TEST(ss_mov_small_struct_ret_and_spill);
-DEF_TEST(ss_mov_stack_spill);
-
-DEF_TEST(dtrace_instrumented);
-DEF_TEST(kmem_alloc);
-DEF_TEST(uts_kill);
-DEF_TEST(av1394_ic_bitreverse);
-
-DEF_TEST(small_struct_ret_w_float);
-DEF_TEST(big_struct_ret_w_float);
-
-/*
- * Functions which should not match
- *
- * no_fp			-- valid save-args sequence with no saved FP
- * big_struct_arg_by_value	-- function with big struct passed by value
- * small_struct_arg_by_value	-- function with small struct passed by value
- */
-DEF_TEST(no_fp);
-DEF_TEST(big_struct_arg_by_value);
-DEF_TEST(small_struct_arg_by_value);
-
-int
-main(int argc, char **argv)
-{
-	TEST_GOOD(kmem_alloc, 2);
-	TEST_GOOD(uts_kill, 2);
-	TEST_GOOD(av1394_ic_bitreverse, 1);
-	TEST_GOOD(dtrace_instrumented, 4);
-	TEST_GOOD_STRUCT(big_struct_ret_w_float, 1);
-	TEST_BAD(no_fp, 5);
-
-	TEST_GOOD(gcc_mov_align, 5);
-	TEST_GOOD(gcc_push_align, 5);
-	TEST_GOOD(ss_mov_align, 5);
-
-	TEST_GOOD(gcc_mov_basic, 4);
-	TEST_GOOD(gcc_push_basic, 4);
-	TEST_GOOD(ss_mov_basic, 4);
-
-	TEST_GOOD_STRUCT(gcc_mov_big_struct_ret, 4);
-	TEST_GOOD_STRUCT(gcc_push_big_struct_ret, 4);
-	TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
-
-	TEST_GOOD_STRUCT(gcc_mov_big_struct_ret_and_spill, 8);
-	TEST_GOOD_STRUCT(gcc_push_big_struct_ret_and_spill, 8);
-	TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
-
-	TEST_GOOD(gcc_mov_small_struct_ret, 4);
-	TEST_GOOD(gcc_push_small_struct_ret, 4);
-	TEST_GOOD(ss_mov_small_struct_ret, 4);
-
-	TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
-	TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
-	TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
-
-	TEST_GOOD(gcc_mov_stack_spill, 8);
-	TEST_GOOD(gcc_push_stack_spill, 8);
-	TEST_GOOD(ss_mov_stack_spill, 8);
-
-	TEST_BAD(big_struct_arg_by_value, 2);
-	TEST_BAD(small_struct_arg_by_value, 2);
-
-	TEST_BAD(small_struct_ret_w_float, 1);
-
-	return (0);
-}
--- a/usr/src/lib/Makefile	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/lib/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -271,7 +271,8 @@
 i386_SUBDIRS=		\
 	libntfs		\
 	libparted	\
-	libfdisk
+	libfdisk	\
+	libsaveargs
 
 sparc_SUBDIRS= .WAIT	\
 	efcode		\
@@ -511,7 +512,8 @@
 
 i386_HDRSUBDIRS=	\
 	libparted	\
-	libfdisk
+	libfdisk	\
+	libsaveargs
 
 sparc_HDRSUBDIRS=	\
 	libds		\
@@ -623,7 +625,7 @@
 libpp:		libast
 libzonecfg:	libc libsocket libnsl libuuid libnvpair libsysevent libsec \
 		libbrand libpool libscf
-libproc:	../cmd/sgs/librtld_db ../cmd/sgs/libelf libctf
+libproc:	../cmd/sgs/librtld_db ../cmd/sgs/libelf libctf libsaveargs
 libproject:	libpool libproc libsecdb
 libtermcap:	libcurses
 libtsnet:	libnsl libtsol libsecdb
@@ -635,6 +637,7 @@
 libscf:		libuutil libmd libgen libsmbios libnsl
 libinetsvc:	libscf
 librestart:	libuutil libscf
+libsaveargs:	libdisasm
 ../cmd/sgs/libdl:	../cmd/sgs/libconv
 ../cmd/sgs/libelf:	../cmd/sgs/libconv
 pkcs11:		libcryptoutil
--- a/usr/src/lib/libdisasm/common/libdisasm.h	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/lib/libdisasm/common/libdisasm.h	Sat Feb 09 17:21:16 2013 -0500
@@ -27,8 +27,6 @@
 #ifndef	_LIBDISASM_H
 #define	_LIBDISASM_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 
 #ifdef	__cplusplus
@@ -67,6 +65,7 @@
 extern void dis_flags_set(dis_handle_t *, int f);
 extern void dis_flags_clear(dis_handle_t *, int f);
 extern int dis_max_instrlen(dis_handle_t *);
+extern int dis_instrlen(dis_handle_t *, uint64_t);
 
 /* libdisasm errors */
 #define	E_DIS_NOMEM		1	/* Out of memory */
--- a/usr/src/lib/libdisasm/common/mapfile-vers	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/lib/libdisasm/common/mapfile-vers	Sat Feb 09 17:21:16 2013 -0500
@@ -44,6 +44,7 @@
 	dis_errno;
 	dis_handle_create;
 	dis_handle_destroy;
+	dis_instrlen;
 	dis_max_instrlen;
 	dis_previnstr;
 	dis_set_data;
--- a/usr/src/lib/libdisasm/i386/dis_i386.c	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/lib/libdisasm/i386/dis_i386.c	Sat Feb 09 17:21:16 2013 -0500
@@ -24,8 +24,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <libdisasm.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -245,3 +243,12 @@
 	dis_free(hist, sizeof (uint64_t) * n);
 	return (res);
 }
+
+int
+dis_instrlen(dis_handle_t *dhp, uint64_t pc)
+{
+	if (dis_disassemble(dhp, pc, NULL, 0) != 0)
+		return (-1);
+
+	return (dhp->dh_addr - pc);
+}
--- a/usr/src/lib/libdisasm/sparc/dis_sparc.c	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/lib/libdisasm/sparc/dis_sparc.c	Sat Feb 09 17:21:16 2013 -0500
@@ -29,9 +29,6 @@
  * Use is subject to license terms.
  */
 
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * The sparc disassembler is mostly straightforward, each instruction is
  * represented by an inst_t structure.  The inst_t definitions are organized
@@ -229,6 +226,13 @@
 	return (pc - n*4);
 }
 
+/* ARGSUSED */
+int
+dis_instrlen(dis_handle_t *dhp, uint64_t pc)
+{
+	return (4);
+}
+
 int
 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
 {
--- a/usr/src/lib/libproc/Makefile.com	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/lib/libproc/Makefile.com	Sat Feb 09 17:21:16 2013 -0500
@@ -74,13 +74,6 @@
 ISAOBJS =	\
 	Pisadep.o
 
-amd64_SAVEOBJS = \
-	saveargs.o
-
-amd64_CPPFLAGS = -I$(SRC)/common/saveargs
-
-SAVEOBJS = $($(MACH64)_SAVEOBJS)
-
 OBJECTS = $(CMNOBJS) $(ISAOBJS) $(SAVEOBJS)
 
 # include library definitions
--- a/usr/src/lib/libproc/amd64/Makefile	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/lib/libproc/amd64/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -22,8 +22,6 @@
 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 # This is a 64-bit build, and as such needs 64-bit ELF support
 CMNOBJS64 =	Psymtab_machelf64.o
@@ -32,5 +30,6 @@
 include ../../Makefile.lib.64
 
 CPPFLAGS += -D_SYSCALL32
+LDLIBS += -lsaveargs
 
 install: all $(ROOTLIBS64) $(ROOTLINKS64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,65 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.lib
+
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all :=		TARGET= all
+clean :=	TARGET= clean
+clobber :=	TARGET= clobber
+delete :=	TARGET= delete
+install :=	TARGET= install
+lint :=		TARGET= lint
+_msg :=		TARGET= _msg
+package :=	TARGET= package
+
+LIBRARY= 	libsaveargs.a
+
+# definitions for install_h target
+HDRS=		saveargs.h
+ROOTHDRDIR=	$(ROOT)/usr/include
+ROOTHDRS=	$(HDRS:%=$(ROOTHDRDIR)/%)
+CHECKHDRS=	$(HDRS:%.h=common/%.check)
+
+$(ROOTHDRS) :=  FILEMODE= 644
+
+# install rule for install_h target
+$(ROOTHDRDIR)/%: common/%
+	$(INS.file)
+
+.KEEP_STATE:
+
+all clean clobber delete install lint package: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+$(SUBDIRS):	FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/Makefile.com	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,99 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# The build process for libsaveargs is sightly different from that used by other
+# libraries, because libsaveargs must be built in two flavors - as a standalone
+# for use by kmdb and as a normal library.  We use $(CURTYPE) to indicate the
+# current flavor being built.
+#
+
+LIBRARY=	libsaveargs.a
+STANDLIBRARY=	libstandsaveargs.so
+VERS=		.1
+
+# By default, we build the shared library.  Construction of the standalone
+# is specifically requested by architecture-specific Makefiles.
+TYPES=		library
+CURTYPE=	library
+
+COMDIR=		$(SRC)/lib/libsaveargs/common
+
+OBJECTS_common_amd64	= saveargs.o
+SRCS_common_amd64	= $(OBJECTS_common_amd64:%.o=../amd64/%.c)
+
+OBJECTS= $(OBJECTS_common_$(MACH)) $(OBJECTS_common_$(MACH64)) $(OBJECTS_common_common)
+
+include $(SRC)/lib/Makefile.lib
+
+SRCS=	$(SRCS_common_$(MACH)) $(SRCS_common_$(MACH64)) $(SRC_common_common)
+
+#
+# Used to verify that the standalone doesn't have any unexpected external
+# dependencies.
+#
+LINKTEST_OBJ = objs/linktest_stand.o
+
+CLOBBERFILES_standalone = $(LINKTEST_OBJ)
+CLOBBERFILES += $(CLOBBERFILES_$(CURTYPE))
+
+LIBS_standalone	= $(STANDLIBRARY)
+LIBS_library = $(DYNLIB) $(LINTLIB)
+LIBS = $(LIBS_$(CURTYPE))
+
+MAPFILES =	$(COMDIR)/mapfile-vers
+
+LDLIBS +=	-lc -ldisasm
+
+LDFLAGS_standalone = $(ZNOVERSION) $(BREDUCE) -dy -r
+LDFLAGS = $(LDFLAGS_$(CURTYPE))
+
+ASFLAGS_standalone = -DDIS_STANDALONE
+ASFLAGS_library =
+ASFLAGS += -P $(ASFLAGS_$(CURTYPE)) -D_ASM
+
+$(LINTLIB) := SRCS = $(COMDIR)/$(LINTSRC)
+
+# We want the thread-specific errno in the library, but we don't want it in
+# the standalone.  $(DTS_ERRNO) is designed to add -D_TS_ERRNO to $(CPPFLAGS),
+# in order to enable this feature.  Conveniently, -D_REENTRANT does the same
+# thing.  As such, we null out $(DTS_ERRNO) to ensure that the standalone
+# doesn't get it.
+DTS_ERRNO=
+
+CPPFLAGS_standalone = -DDIS_STANDALONE
+CPPFLAGS_library = -D_REENTRANT
+CPPFLAGS +=	-I$(COMDIR) $(CPPFLAGS_$(CURTYPE))
+
+CFLAGS_standalone = $(STAND_FLAGS_32)
+CFLAGS_common =
+CFLAGS += $(CFLAGS_$(CURTYPE)) $(CFLAGS_common)
+
+CFLAGS64_standalone = $(STAND_FLAGS_64)
+CFLAGS64 += $(CCVERBOSE) $(CFLAGS64_$(CURTYPE)) $(CFLAGS64_common)
+
+DYNFLAGS +=     $(ZINTERPOSE)
+
+.KEEP_STATE:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/Makefile.targ	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,80 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# We build each flavor in a separate make invocation to improve clarity(!) in
+# Makefile.com.  The subordinate makes have $(CURTYPE) set to indicate the
+# flavor they're supposed to build.  This causes the correct set of source
+# files and compiler and linker flags to be selected.
+#
+
+install: $(TYPES:%=install.%)
+
+all: $(TYPES:%=all.%)
+
+$(TYPES:%=all.%):
+	@CURTYPE=$(@:all.%=%) $(MAKE) $@.targ
+
+$(TYPES:%=install.%):
+	@CURTYPE=$(@:install.%=%) $(MAKE) $@.targ
+
+install.library.targ: all.library $(INSTALL_DEPS_library)
+install.standalone.targ: all.standalone $(INSTALL_DEPS_standalone)
+
+all.library.targ: $(LIBS)
+all.standalone.targ: $(STANDLIBRARY)
+
+lint: $(TYPES:%=lint.%)
+
+$(TYPES:%=lint.%):
+	@CURTYPE=$(@:lint.%=%) $(MAKE) lintcheck
+
+$(STANDLIBRARY): $(OBJS) $(LINKTEST_OBJ)
+	$(LD) $(BREDUCE) $(ZDEFS) $(LDFLAGS) -o $@.linktest $(OBJS) $(LINKTEST_OBJ)
+	rm $@.linktest
+	$(LD) $(LDFLAGS) -o $@ $(OBJS)
+
+clobber: $(TYPES:%=clobber.%)
+
+$(TYPES:%=clobber.%):
+	@CURTYPE=$(@:clobber.%=%) $(MAKE) clobber.targ
+
+clobber.targ: clean
+	-$(RM) $(CLOBBERTARGFILES)
+
+# include library targets
+include $(SRC)/lib/Makefile.targ
+
+$(PICS): pics
+$(OBJS): objs
+
+objs/%.o pics/%.o: $(COMDIR)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
+
+# install rule for lint library target
+$(ROOTLINTDIR)/%: $(COMDIR)/%
+	$(INS.file)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/amd64/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+TYPES=library standalone
+
+INSTALL_DEPS_library = $(ROOTLINKS64) $(ROOTLINT64) $(ROOTLIBS64)
+INSTALL_DEPS_standalone = $(ROOTLIBS64)
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/amd64/saveargs.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,374 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+/*
+ * The Sun Studio and GCC (patched for opensolaris/illumos) compilers
+ * implement a argument saving scheme on amd64 via the -Wu,save-args or
+ * options.  When the option is specified, INTEGER type function arguments
+ * passed via registers will be saved on the stack immediately after %rbp, and
+ * will not be modified through out the life of the routine.
+ *
+ *				+--------+
+ *		%rbp	-->     |  %rbp  |
+ *				+--------+
+ *		-0x8(%rbp)	|  %rdi  |
+ *				+--------+
+ *		-0x10(%rbp)	|  %rsi  |
+ *				+--------+
+ *		-0x18(%rbp)	|  %rdx  |
+ *				+--------+
+ *		-0x20(%rbp)	|  %rcx  |
+ *				+--------+
+ *		-0x28(%rbp)	|  %r8   |
+ *				+--------+
+ *		-0x30(%rbp)	|  %r9   |
+ *				+--------+
+ *
+ *
+ * For example, for the following function,
+ *
+ * void
+ * foo(int a1, int a2, int a3, int a4, int a5, int a6, int a7)
+ * {
+ * ...
+ * }
+ *
+ * Disassembled code will look something like the following:
+ *
+ *     pushq	%rbp
+ *     movq	%rsp, %rbp
+ *     subq	$imm8, %rsp			**
+ *     movq	%rdi, -0x8(%rbp)
+ *     movq	%rsi, -0x10(%rbp)
+ *     movq	%rdx, -0x18(%rbp)
+ *     movq	%rcx, -0x20(%rbp)
+ *     movq	%r8, -0x28(%rbp)
+ *     movq	%r9, -0x30(%rbp)
+ *     ...
+ * or
+ *     pushq	%rbp
+ *     movq	%rsp, %rbp
+ *     subq	$imm8, %rsp			**
+ *     movq	%r9, -0x30(%rbp)
+ *     movq	%r8, -0x28(%rbp)
+ *     movq	%rcx, -0x20(%rbp)
+ *     movq	%rdx, -0x18(%rbp)
+ *     movq	%rsi, -0x10(%rbp)
+ *     movq	%rdi, -0x8(%rbp)
+ *     ...
+ * or
+ *     pushq	%rbp
+ *     movq	%rsp, %rbp
+ *     pushq	%rdi
+ *     pushq	%rsi
+ *     pushq	%rdx
+ *     pushq	%rcx
+ *     pushq	%r8
+ *     pushq	%r9
+ *
+ * **: The space being reserved is in addition to what the current
+ *     function prolog already reserves.
+ *
+ * We loop through the first SAVEARGS_INSN_SEQ_LEN bytes of the function
+ * looking for each argument saving instruction we would expect to see.
+ *
+ * If there are odd number of arguments to a function, additional space is
+ * reserved on the stack to maintain 16-byte alignment.  For example,
+ *
+ *     argc == 0: no argument saving.
+ *     argc == 3: save 3, but space for 4 is reserved
+ *     argc == 7: save 6.
+ */
+
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <libdisasm.h>
+#include <string.h>
+
+#include <saveargs.h>
+
+/*
+ * Size of the instruction sequence arrays.  It should correspond to
+ * the maximum number of arguments passed via registers.
+ */
+#define	INSTR_ARRAY_SIZE	6
+
+#define	INSTR1(ins, off) (ins[(off)])
+#define	INSTR2(ins, off) (ins[(off)] + (ins[(off) + 1] << 8))
+#define	INSTR3(ins, off)	\
+	(ins[(off)] + (ins[(off) + 1] << 8) + (ins[(off + 2)] << 16))
+#define	INSTR4(ins, off)	\
+	(ins[(off)] + (ins[(off) + 1] << 8) + (ins[(off + 2)] << 16) + \
+	(ins[(off) + 3] << 24))
+
+/*
+ * Sun Studio 10 patch implementation saves %rdi first;
+ * GCC 3.4.3 Sun branch implementation saves them in reverse order.
+ */
+static const uint32_t save_instr[INSTR_ARRAY_SIZE] = {
+	0xf87d8948,	/* movq %rdi, -0x8(%rbp) */
+	0xf0758948,	/* movq %rsi, -0x10(%rbp) */
+	0xe8558948,	/* movq %rdx, -0x18(%rbp) */
+	0xe04d8948,	/* movq %rcx, -0x20(%rbp) */
+	0xd845894c,	/* movq %r8, -0x28(%rbp) */
+	0xd04d894c	/* movq %r9, -0x30(%rbp) */
+};
+
+static const uint16_t save_instr_push[] = {
+	0x57,	/* pushq %rdi */
+	0x56,	/* pushq %rsi */
+	0x52,	/* pushq %rdx */
+	0x51,	/* pushq %rcx */
+	0x5041,	/* pushq %r8 */
+	0x5141	/* pushq %r9 */
+};
+
+/*
+ * If the return type of a function is a structure greater than 16 bytes in
+ * size, %rdi will contain the address to which it should be stored, and
+ * arguments will begin at %rsi.  Studio will push all of the normal argument
+ * registers anyway, GCC will start pushing at %rsi, so we need a separate
+ * pattern.
+ */
+static const uint32_t save_instr_sr[INSTR_ARRAY_SIZE-1] = {
+	0xf8758948,	/* movq %rsi,-0x8(%rbp) */
+	0xf0558948,	/* movq %rdx,-0x10(%rbp) */
+	0xe84d8948,	/* movq %rcx,-0x18(%rbp) */
+	0xe045894c,	/* movq %r8,-0x20(%rbp) */
+	0xd84d894c	/* movq %r9,-0x28(%rbp) */
+};
+
+static const uint8_t save_fp_pushes[] = {
+	0x55,	/* pushq %rbp */
+	0xcc	/* int $0x3 */
+};
+#define	NUM_FP_PUSHES (sizeof (save_fp_pushes) / sizeof (save_fp_pushes[0]))
+
+static const uint32_t save_fp_movs[] = {
+	0x00e58948,	/* movq %rsp,%rbp, encoding 1 */
+	0x00ec8b48,	/* movq %rsp,%rbp, encoding 2 */
+};
+#define	NUM_FP_MOVS (sizeof (save_fp_movs) / sizeof (save_fp_movs[0]))
+
+typedef struct {
+	uint8_t *data;
+	size_t size;
+} text_t;
+
+static int
+do_read(void *data, uint64_t addr, void *buf, size_t len)
+{
+	text_t	*t = data;
+
+	if (addr >= t->size)
+		return (-1);
+
+	len = MIN(len, t->size - addr);
+
+	(void) memcpy(buf, (char *)t->data + addr, len);
+
+	return (len);
+}
+
+/* ARGSUSED */
+int
+do_lookup(void *data, uint64_t addr, char *buf, size_t buflen, uint64_t *start,
+    size_t *symlen)
+{
+	/* We don't actually need lookup info */
+	return (-1);
+}
+
+static int
+instr_size(dis_handle_t *dhp, uint8_t *ins, unsigned int i, size_t size)
+{
+	text_t	t;
+
+	t.data = ins;
+	t.size = size;
+
+	dis_set_data(dhp, &t);
+	return (dis_instrlen(dhp, i));
+}
+
+static boolean_t
+has_saved_fp(dis_handle_t *dhp, uint8_t *ins, int size)
+{
+	int 		i, j;
+	uint32_t	n;
+	boolean_t	found_push = B_FALSE;
+	ssize_t		sz = 0;
+
+	for (i = 0; i < size; i += sz) {
+		if ((sz = instr_size(dhp, ins, i, size)) < 1)
+			return (B_FALSE);
+
+		if (found_push == B_FALSE) {
+			if (sz != 1)
+				continue;
+
+			n = INSTR1(ins, i);
+			for (j = 0; j <= NUM_FP_PUSHES; j++)
+				if (save_fp_pushes[j] == n) {
+					found_push = B_TRUE;
+					break;
+				}
+		} else {
+			if (sz != 3)
+				continue;
+			n = INSTR3(ins, i);
+			for (j = 0; j <= NUM_FP_MOVS; j++)
+				if (save_fp_movs[j] == n)
+					return (B_TRUE);
+		}
+	}
+
+	return (B_FALSE);
+}
+
+int
+saveargs_has_args(uint8_t *ins, size_t size, uint_t argc, int start_index)
+{
+	int		i, j;
+	uint32_t	n;
+	uint8_t		found = 0;
+	ssize_t		sz = 0;
+	dis_handle_t	*dhp = NULL;
+	int		ret = SAVEARGS_NO_ARGS;
+
+	argc = MIN((start_index + argc), INSTR_ARRAY_SIZE);
+
+	if ((dhp = dis_handle_create(DIS_X86_SIZE64, NULL, do_lookup,
+	    do_read)) == NULL)
+		return (SAVEARGS_NO_ARGS);
+
+	if (!has_saved_fp(dhp, ins, size)) {
+		dis_handle_destroy(dhp);
+		return (SAVEARGS_NO_ARGS);
+	}
+
+	/*
+	 * For each possible style of argument saving, walk the insn stream as
+	 * we've been given it, and set bit N in 'found' if we find the
+	 * instruction saving the Nth argument.
+	 */
+
+	/*
+	 * Compare against regular implementation
+	 */
+	found = 0;
+	for (i = 0; i < size; i += sz) {
+		sz = instr_size(dhp, ins, i, size);
+
+		if (sz < 1)
+			break;
+		else if (sz != 4)
+			continue;
+
+		n = INSTR4(ins, i);
+
+		for (j = 0; j < argc; j++) {
+			if (n == save_instr[j]) {
+				found |= (1 << j);
+
+				if (found == ((1 << argc) - 1)) {
+					ret = start_index ?
+					    SAVEARGS_STRUCT_ARGS :
+					    SAVEARGS_TRAD_ARGS;
+					goto done;
+				}
+
+				break;
+			}
+		}
+	}
+
+	/*
+	 * Compare against GCC push-based implementation
+	 */
+	found = 0;
+	for (i = 0; i < size; i += sz) {
+		if ((sz = instr_size(dhp, ins, i, size)) < 1)
+			break;
+
+		for (j = start_index; j < argc; j++) {
+			if (sz == 2) /* Two byte */
+				n = INSTR2(ins, i);
+			else if (sz == 1)
+				n = INSTR1(ins, i);
+			else
+				continue;
+
+			if (n == save_instr_push[j]) {
+				found |= (1 << (j - start_index));
+
+				if (found ==
+				    ((1 << (argc - start_index)) - 1)) {
+					ret = SAVEARGS_TRAD_ARGS;
+					goto done;
+				}
+
+				break;
+			}
+		}
+	}
+
+	/*
+	 * Look for a GCC-style returned structure.
+	 */
+	found = 0;
+	if (start_index != 0) {
+		for (i = 0; i < size; i += sz) {
+			sz = instr_size(dhp, ins, i, size);
+
+			if (sz < 1)
+				break;
+			else if (sz != 4)
+				continue;
+
+			n = INSTR4(ins, i);
+
+			/* argc is inclusive of start_index, allow for that */
+			for (j = 0; j < (argc - start_index); j++) {
+				if (n == save_instr_sr[j]) {
+					found |= (1 << j);
+
+					if (found ==
+					    ((1 << (argc - start_index)) - 1)) {
+						ret = SAVEARGS_TRAD_ARGS;
+						goto done;
+					}
+
+					break;
+				}
+			}
+		}
+	}
+
+done:
+	dis_handle_destroy(dhp);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/common/linktest_stand.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,18 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/* Copyright 2013, Richard Lowe */
+
+void memcpy(void) {}
+void dis_set_data(void) {}
+void dis_instrlen(void) {}
+void dis_handle_create(void) {}
+void dis_handle_destroy(void) {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/common/llib-lsaveargs	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,17 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/* Copyright 2013, Richard Lowe. */
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <saveargs.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/common/mapfile-vers	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,35 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+# Copyright 2013, Richard Lowe.
+
+#
+# MAPFILE HEADER START
+#
+# WARNING:  STOP NOW.  DO NOT MODIFY THIS FILE.
+# Object versioning must comply with the rules detailed in
+#
+#	usr/src/lib/README.mapfiles
+#
+# You should not be making modifications here until you've read the most current
+# copy of that file. If you need help, contact a gatekeeper for guidance.
+#
+# MAPFILE HEADER END
+#
+
+$mapfile_version 2
+
+SYMBOL_VERSION ILLUMOSprivate {
+	global:
+		saveargs_has_args;
+	local:
+		*;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/common/saveargs.h	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SAVEARGS_H
+#define	_SAVEARGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+/*
+ * The longest instruction sequence in bytes before all 6 arguments are
+ * saved on the stack.  This value depends on compiler implementation,
+ * therefore it should be examined periodically to guarantee accuracy.
+ */
+#define	SAVEARGS_INSN_SEQ_LEN	256
+
+#define	SAVEARGS_NO_ARGS	0	/* no saved arguments */
+#define	SAVEARGS_TRAD_ARGS	1	/* traditionally located arguments */
+#define	SAVEARGS_STRUCT_ARGS	2	/* struct return addr pushed as arg0 */
+
+int saveargs_has_args(uint8_t *, size_t, uint_t, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _SAVEARGS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/README	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,14 @@
+testmatch:
+
+   A stub program that tests the saveargs matcher against a variety of
+   function prologues (assembled from data.s)
+
+functional:
+
+   Actually test the full chunk of the (libproc) side of the code, running
+   pstack on the range of test apps.
+
+dump:
+
+    Display each function in a given object we believe to have saved
+    arguments.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/dump/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,39 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2012, Richard Lowe.
+#
+
+include $(SRC)/Makefile.master
+include $(SRC)/Makefile.master.64
+
+.KEEP_STATE:
+
+OBJECTS = dump.o
+PROG = dump
+
+CFLAGS += -m64
+
+LDLIBS64 += -lctf -lelf -lsaveargs
+
+C99MODE = $(C99_ENABLE)
+
+$(PROG): $(OBJECTS)
+	$(LINK.c) -o $@ $(OBJECTS) $(LDLIBS64)
+clean:
+	$(RM) $(OBJECTS) $(PROG)
+
+clobber: clean
+
+all: $(PROG)
+
+install: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/dump/dump.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,167 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2011, Robert Mustacchi, Inc. All rights reserved.
+ * Copyright 2013, Richard Lowe.
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libctf.h>
+#include <saveargs.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+
+extern const char *__progname;
+
+typedef struct symtab_sym {
+	GElf_Sym ss_sym;
+	char *ss_name;
+	ctf_funcinfo_t ss_finfo;
+	uint8_t *ss_data;
+	size_t ss_size;
+} symtab_sym_t;
+
+static void
+walk_symtab(Elf *elf, char *fname, ctf_file_t *fp,
+    void (*callback)(ctf_file_t *, symtab_sym_t *))
+{
+	Elf_Scn *stab = NULL;
+	Elf_Scn *text = NULL;
+	Elf_Data *stabdata = NULL;
+	Elf_Data *textdata = NULL;
+	GElf_Ehdr ehdr;
+	GElf_Shdr stabshdr;
+	GElf_Shdr textshdr;
+	int foundtext = 0, foundstab = 0;
+	symtab_sym_t ss;
+
+	if ((gelf_getehdr(elf, &ehdr)) == NULL)
+		errx(1, "could not read ELF header from %s\n",
+		    fname);
+
+	while ((stab = elf_nextscn(elf, stab)) != NULL) {
+		(void) gelf_getshdr(stab, &stabshdr);
+
+		if (stabshdr.sh_type == SHT_SYMTAB) {
+			foundstab = 1;
+			break;
+		}
+	}
+
+	while ((text = elf_nextscn(elf, text)) != NULL) {
+		(void) gelf_getshdr(text, &textshdr);
+
+		if (strcmp(".text", elf_strptr(elf,
+		    ehdr.e_shstrndx, (size_t)textshdr.sh_name)) == 0) {
+			foundtext = 1;
+			break;
+		}
+	}
+
+	if (!foundstab || !foundtext)
+		return;
+
+	stabdata = elf_getdata(stab, NULL);
+	textdata = elf_rawdata(text,  NULL);
+	for (unsigned symdx = 0;
+	    symdx < (stabshdr.sh_size / stabshdr.sh_entsize);
+	    symdx++) {
+		(void) gelf_getsym(stabdata, symdx, &ss.ss_sym);
+
+		if ((GELF_ST_TYPE(ss.ss_sym.st_info) != STT_FUNC) ||
+		    (ss.ss_sym.st_shndx == SHN_UNDEF))
+			continue;
+
+		ss.ss_name = elf_strptr(elf, stabshdr.sh_link,
+		    ss.ss_sym.st_name);
+		ss.ss_data = ((uint8_t *)(textdata->d_buf)) +
+		    (ss.ss_sym.st_value - textshdr.sh_addr);
+
+		if (ctf_func_info(fp, symdx, &ss.ss_finfo) == CTF_ERR) {
+			fprintf(stderr, "failed to get funcinfo for: %s\n",
+			    ss.ss_name);
+			continue;
+		}
+
+		(void) callback(fp, &ss);
+	}
+}
+
+void
+check_sym(ctf_file_t *ctfp, symtab_sym_t *ss)
+{
+	int rettype = ctf_type_kind(ctfp, ss->ss_finfo.ctc_return);
+	int start_index = 0;
+
+	if (ss->ss_finfo.ctc_argc == 0) /* No arguments, no point */
+		return;
+
+	if (((rettype == CTF_K_STRUCT) || (rettype == CTF_K_UNION)) &&
+	    ctf_type_size(ctfp, ss->ss_finfo.ctc_return) > 16)
+		start_index = 1;
+
+	if (saveargs_has_args(ss->ss_data, ss->ss_sym.st_size,
+	    ss->ss_finfo.ctc_argc, start_index) != SAVEARGS_NO_ARGS)
+		printf("%s has %d saved args\n", ss->ss_name,
+		    ss->ss_finfo.ctc_argc);
+}
+
+int
+main(int argc, char **argv)
+{
+	Elf		*elf;
+	ctf_file_t	*ctfp;
+	int errp, fd;
+
+	if (ctf_version(CTF_VERSION) == -1)
+		errx(1, "mismatched libctf versions\n");
+
+	if (elf_version(EV_CURRENT) == EV_NONE)
+		errx(1, "mismatched libelf versions\n");
+
+	if (argc != 2)
+		errx(2, "usage: %s <file>\n", __progname);
+
+	if ((ctfp = ctf_open(argv[1], &errp)) == NULL)
+		errx(1, "failed to ctf_open file: %s: %s\n", argv[1],
+		    ctf_errmsg(errp));
+
+	if ((fd = open(argv[1], O_RDONLY)) == -1)
+		errx(1, "could not open %s\n", argv[1]);
+
+	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
+		errx(1, "could not interpret ELF from %s\n",
+		    argv[1]);
+
+	walk_symtab(elf, argv[1], ctfp, check_sym);
+
+	(void) elf_end(elf);
+	(void) close(fd);
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,45 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2012, Richard Lowe.
+#
+
+include $(SRC)/Makefile.master
+include $(SRC)/Makefile.master.64
+
+.KEEP_STATE:
+
+PROGS = align \
+	basic \
+	big-struct-ret \
+	big-struct-ret-and-spill \
+	small-struct-ret \
+	small-struct-ret-and-spill \
+	stack-spill
+
+CFLAGS += $(CTF_FLAGS)
+CFLAGS64 += $(CTF_FLAGS)
+
+%: %.c
+	$(LINK.c) -o $@ $< -lc
+	$(CTFCONVERT) -L VERSION $@
+
+all: $(PROGS)
+
+install: all
+
+clean:
+	$(RM) $(PROGS)
+
+clobber: clean
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/align.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,32 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int
+test(long a, long b, long c, long d, long e)
+{
+	printf("%ld %ld %ld %ld %ld\n", a, b, c, d, e);
+	for (;;)
+		sleep(60);
+}
+
+int
+main(int argc, char **argv)
+{
+	test(1, 2, 3, 4, 5);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/basic.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,32 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int
+test(long a, long b, long c, long d)
+{
+	printf("%ld %ld %ld %ld\n", a, b, c, d);
+	for (;;)
+		sleep(60);
+}
+
+int
+main(int argc, char **argv)
+{
+	test(1, 2, 3, 4);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/big-struct-ret-and-spill.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,38 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+struct foo {
+	long a;
+	long b;
+	long c;
+};
+
+struct foo
+test(long a, long b, long c, long d, long e, long f, long g, long h)
+{
+	printf("%ld %ld %ld %ld %ld %ld %ld %ld\n", a, b, c, d, e, f, g, h);
+	for (;;)
+		sleep(60);
+}
+
+int
+main(int argc, char **argv)
+{
+	test(1, 2, 3, 4, 5, 6, 7, 8);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/big-struct-ret.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,38 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+struct foo {
+	long a;
+	long b;
+	long c;
+};
+
+struct foo
+test(long a, long b, long c, long d)
+{
+	printf("%ld %ld %ld %ld\n", a, b, c, d);
+	for (;;)
+		sleep(60);
+}
+
+int
+main(int argc, char **argv)
+{
+	test(1, 2, 3, 4);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/small-struct-ret-and-spill.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,37 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+struct foo {
+	long a;
+	long b;
+};
+
+struct foo
+test(long a, long b, long c, long d, long e, long f, long g, long h)
+{
+	printf("%ld %ld %ld %ld %ld %ld %ld %ld\n", a, b, c, d, e, f, g, h);
+	for (;;)
+		sleep(60);
+}
+
+int
+main(int argc, char **argv)
+{
+	test(1, 2, 3, 4, 5, 6, 7, 8);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/small-struct-ret.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,37 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+struct foo {
+	long a;
+	long b;
+};
+
+struct foo
+test(long a, long b, long c, long d)
+{
+	printf("%ld %ld %ld %ld\n", a, b, c, d);
+	for (;;)
+		sleep(60);
+}
+
+int
+main(int argc, char **argv)
+{
+	test(1, 2, 3, 4);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/stack-spill.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,32 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int
+test(long a, long b, long c, long d, long e, long f, long g, long h)
+{
+	printf("%ld %ld %ld %ld %ld %ld %ld %ld\n", a, b, c, d, e, f, g, h);
+	for (;;)
+		sleep(60);
+}
+
+int
+main(int argc, char **argv)
+{
+	test(1, 2, 3, 4, 5, 6, 7, 8);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/functional/test.sh	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,37 @@
+#! /usr/bin/ksh
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2012, Richard Lowe.
+#
+
+function tester {
+    prog=${1}
+    pattern=${2}
+
+    ./$prog >/dev/null &
+    pid=$!
+    if (/usr/bin/amd64/pstack $pid | /usr/xpg4/bin/grep -q "${pattern}"); then
+        echo "pass: ${prog}"
+    else
+        echo "FAIL: ${prog}"
+    fi
+    kill $pid
+}
+
+tester align "test (1, 2, 3, 4, 5)"
+tester basic "test (1, 2, 3, 4)"
+tester big-struct-ret "test (1, 2, 3, 4)"
+tester big-struct-ret-and-spill "test (1, 2, 3, 4, 5, 6, 7, 8)"
+tester small-struct-ret "test (1, 2, 3, 4)"
+tester small-struct-ret-and-spill "test (1, 2, 3, 4, 5, 6, 7, 8)"
+tester stack-spill "test (1, 2, 3, 4, 5, 6, 7, 8)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/testmatch/Makefile	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,40 @@
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2012, Richard Lowe.
+#
+
+include $(SRC)/Makefile.master
+include $(SRC)/Makefile.master.64
+
+.KEEP_STATE:
+
+OBJECTS = testmatch.o data.o
+PROG = testmatch
+
+LDLIBS64 += -lsaveargs
+
+ASFLAGS += -P
+AS_CPPFLAGS += -D_ASM
+
+$(PROG): $(OBJECTS)
+	$(LINK.c) -o $@ $(OBJECTS) $(LDLIBS64)
+
+clean:
+	$(RM) $(OBJECTS) $(PROG)
+
+clobber: clean
+
+all: $(PROG)
+
+install: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/testmatch/data.s	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,468 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#define	FUNC(x) \
+	.text; \
+	.align	16; \
+	.globl	x; \
+	.type	x, @function; \
+x:
+
+#define	SET_SIZE(x, x_size) \
+	.size	x, [.-x]; \
+        .globl x_size; \
+        .type  x_size, @object; \
+x_size:
+
+/*
+ * Extracted versions of the functional tests
+ *
+ * Named of the form <compiler>-<prologue style>-<nature of test>
+ * basic			-- A regular function
+ * align			-- odd number of arguments needing save-area
+ * 				   alignment
+ * big-struct-ret		-- returns a > 16byte structure by value
+ * big-struct-ret-and-spill	-- returns a > 16byte structure by value and
+ * 				   spills args to the stack
+ * small-struct-ret		-- returns a < 16byte structure by value
+ * small-struct-ret-and-spill	-- returns a < 16byte structure by value and
+ * 				   spills args to the stack
+ * stack-spill			-- spills arguments to the stack
+ */
+FUNC(gcc_mov_align)
+pushq	%rbp
+movq	%rsp, %rbp
+movq	%rbx, -0x38(%rbp)
+movq	%r8, -0x28(%rbp)
+movq	%rcx, -0x20(%rbp)
+movq	%rdx, -0x18(%rbp)
+movq	%rsi, -0x10(%rbp)
+movq	%rdi, -0x8(%rbp)
+subq	$0x70, %rsp
+SET_SIZE(gcc_mov_align, gcc_mov_align_end)
+
+FUNC(gcc_mov_basic)
+pushq	%rbp
+movq	%rsp, %rbp
+movq	%rbx,-0x28(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(gcc_mov_basic, gcc_mov_basic_end)
+
+FUNC(gcc_mov_noorder)
+pushq	%rbp
+movq	%rsp, %rbp
+movq    %rcx,-0x20(%rbp)
+movq	%rbx,-0x28(%rbp)
+movq    %rdi,-0x8(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(gcc_mov_noorder, gcc_mov_noorder_end)
+        
+FUNC(gcc_mov_big_struct_ret)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rbx,-0x28(%rbp)
+movq    %r8,-0x20(%rbp)
+movq    %rcx,-0x18(%rbp)
+movq    %rdx,-0x10(%rbp)
+movq    %rsi,-0x8(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(gcc_mov_big_struct_ret, gcc_mov_big_struct_ret_end)
+
+FUNC(gcc_mov_struct_noorder)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rcx,-0x18(%rbp)
+movq    %r8,-0x20(%rbp)
+movq    %rsi,-0x8(%rbp)
+movq    %rdx,-0x10(%rbp)
+movq    %rbx,-0x28(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(gcc_mov_struct_noorder, gcc_mov_struct_noorder_end)
+
+FUNC(gcc_mov_big_struct_ret_and_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rbx,-0x38(%rbp)
+movq    %r9,-0x28(%rbp)
+movq    %r8,-0x20(%rbp)
+movq    %rcx,-0x18(%rbp)
+movq    %rdx,-0x10(%rbp)
+movq    %rsi,-0x8(%rbp)
+subq    $0x90,%rsp
+SET_SIZE(gcc_mov_big_struct_ret_and_spill, gcc_mov_big_struct_ret_and_spill_end)
+
+FUNC(gcc_mov_small_struct_ret)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rbx,-0x28(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(gcc_mov_small_struct_ret, gcc_mov_small_struct_ret_end)
+
+FUNC(gcc_mov_small_struct_ret_and_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rbx,-0x38(%rbp)
+movq    %r9,-0x30(%rbp)
+movq    %r8,-0x28(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+subq    $0x90,%rsp
+SET_SIZE(gcc_mov_small_struct_ret_and_spill, gcc_mov_small_struct_ret_and_spill_end)
+
+FUNC(gcc_mov_stack_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rbx,-0x38(%rbp)
+movq    %r9,-0x30(%rbp)
+movq    %r8,-0x28(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+subq    $0x90,%rsp
+SET_SIZE(gcc_mov_stack_spill, gcc_mov_stack_spill_end)
+
+FUNC(gcc_push_align)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rdi
+pushq   %rsi
+pushq   %rdx
+pushq   %rcx
+pushq   %r8
+subq    $0x8,%rsp
+subq    $0x30,%rsp
+SET_SIZE(gcc_push_align, gcc_push_align_end)
+
+FUNC(gcc_push_basic)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rdi
+pushq   %rsi
+pushq   %rdx
+pushq   %rcx
+subq    $0x20,%rsp
+SET_SIZE(gcc_push_basic, gcc_push_basic_end)
+
+FUNC(gcc_push_noorder)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rsi
+pushq   %rdi
+pushq   %rcx
+pushq   %rdx
+subq    $0x20,%rsp
+SET_SIZE(gcc_push_noorder, gcc_push_noorder_end)
+
+FUNC(gcc_push_big_struct_ret)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rsi
+pushq   %rdx
+pushq   %rcx
+pushq   %r8
+subq    $0x30,%rsp
+SET_SIZE(gcc_push_big_struct_ret, gcc_push_big_struct_ret_end)
+
+FUNC(gcc_push_struct_noorder)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rdx
+pushq   %rsi
+pushq   %r8
+pushq   %rcx
+subq    $0x30,%rsp
+SET_SIZE(gcc_push_struct_noorder, gcc_push_struct_noorder_end)
+        
+FUNC(gcc_push_big_struct_ret_and_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rsi
+pushq   %rdx
+pushq   %rcx
+pushq   %r8
+pushq   %r9
+subq    $0x8,%rsp
+subq    $0x50,%rsp
+SET_SIZE(gcc_push_big_struct_ret_and_spill, gcc_push_big_struct_ret_and_spill_end)
+
+FUNC(gcc_push_small_struct_ret)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rdi
+pushq   %rsi
+pushq   %rdx
+pushq   %rcx
+subq    $0x20,%rsp
+SET_SIZE(gcc_push_small_struct_ret, gcc_push_small_struct_ret_end)
+
+FUNC(gcc_push_small_struct_ret_and_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rdi
+pushq   %rsi
+pushq   %rdx
+pushq   %rcx
+pushq   %r8
+pushq   %r9
+subq    $0x50,%rsp
+SET_SIZE(gcc_push_small_struct_ret_and_spill, gcc_push_small_struct_ret_and_spill_end)
+
+FUNC(gcc_push_stack_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+pushq   %rdi
+pushq   %rsi
+pushq   %rdx
+pushq   %rcx
+pushq   %r8
+pushq   %r9
+subq    $0x50,%rsp
+SET_SIZE(gcc_push_stack_spill, gcc_push_stack_spill_end)
+
+FUNC(ss_mov_align)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x30,%rsp
+movq    %rdi,-0x8(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %r8,-0x28(%rbp)
+SET_SIZE(ss_mov_align, ss_mov_align_end)
+
+FUNC(ss_mov_basic)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x20,%rsp
+movq    %rdi,-0x8(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rcx,-0x20(%rbp)
+SET_SIZE(ss_mov_basic, ss_mov_basic_end)
+
+FUNC(ss_mov_big_struct_ret)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x30,%rsp
+movq    %rdi,-0x8(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %r8,-0x28(%rbp)
+SET_SIZE(ss_mov_big_struct_ret, ss_mov_big_struct_ret_end)
+
+FUNC(ss_mov_big_struct_ret_and_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x50,%rsp
+movq    %rdi,-0x8(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %r8,-0x28(%rbp)
+movq    %r9,-0x30(%rbp)
+SET_SIZE(ss_mov_big_struct_ret_and_spill, ss_mov_big_struct_ret_and_spill_end)
+
+FUNC(ss_mov_small_struct_ret)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x20,%rsp
+movq    %rdi,-0x8(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rcx,-0x20(%rbp)
+SET_SIZE(ss_mov_small_struct_ret, ss_mov_small_struct_ret_end)
+
+FUNC(ss_mov_small_struct_ret_and_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x50,%rsp
+movq    %rdi,-0x8(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %r8,-0x28(%rbp)
+movq    %r9,-0x30(%rbp)
+SET_SIZE(ss_mov_small_struct_ret_and_spill, ss_mov_small_struct_ret_and_spill_end)
+
+FUNC(ss_mov_stack_spill)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x50,%rsp
+movq    %rdi,-0x8(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %r8,-0x28(%rbp)
+movq    %r9,-0x30(%rbp)
+SET_SIZE(ss_mov_stack_spill, ss_mov_stack_spill_end)
+
+/* DTrace instrumentation */
+FUNC(dtrace_instrumented)
+int	$0x3
+movq	%rsp, %rbp
+movq	%rbx,-0x28(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(dtrace_instrumented, dtrace_instrumented_end)
+
+/*
+ * System functions with special characteristics, be they non-initial FP save,
+ * gaps between FP save and argument saving, or gaps between saved arguments.
+ */
+FUNC(kmem_alloc)
+leaq    -0x1(%rdi),%rax
+pushq   %rbp
+movq    %rax,%rdx
+movq    %rsp,%rbp
+subq    $0x30,%rsp
+shrq    $0x3,%rdx
+movq    %r12,-0x28(%rbp)
+movq    %rbx,-0x30(%rbp)
+cmpq    $0x1ff,%rdx
+movq    %r13,-0x20(%rbp)
+movq    %r14,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+movq    %rdi,%r12
+SET_SIZE(kmem_alloc, kmem_alloc_end)
+
+FUNC(uts_kill)
+pushq   %rbp
+movq    %rsp,%rbp
+subq    $0x50,%rsp
+movq    %rbx,-0x28(%rbp)
+leaq    -0x50(%rbp),%rbx
+movq    %r12,-0x20(%rbp)
+movq    %r13,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movl    %edi,%r12d
+movq    %rdi,-0x8(%rbp)
+SET_SIZE(uts_kill, uts_kill_end)
+
+FUNC(av1394_ic_bitreverse)
+movq    %rdi,%rdx
+movq    $0x5555555555555555,%rax
+movq    $0x3333333333333333,%rcx
+shrq    $0x1,%rdx
+pushq   %rbp
+andq    %rax,%rdx
+andq    %rdi,%rax
+addq    %rax,%rax
+movq    %rsp,%rbp
+subq    $0x10,%rsp
+orq     %rdx,%rax
+movq    %rdi,-0x8(%rbp)
+SET_SIZE(av1394_ic_bitreverse, av1394_ic_bitreverse_end)
+
+/* Problematic functions which should not match */
+
+FUNC(no_fp) /* No frame pointer */
+movq	%rdi, %rsi
+movq	%rsi, %rdi
+movq	%rbx,-0x28(%rbp)
+movq    %rcx,-0x20(%rbp)
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(no_fp, no_fp_end)
+
+/* Small structure return, but with an SSE type (thus forcing it to the stack) */
+FUNC(small_struct_ret_w_float)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rdi,-0x8(%rbp)
+subq    $0x30,%rsp
+SET_SIZE(small_struct_ret_w_float, small_struct_ret_w_float_end)
+
+/* Big structure return, but with an SSE type */
+FUNC(big_struct_ret_w_float)
+pushq  %rbp
+movq   %rsp,%rbp
+movq   %rsi,-0x8(%rbp)
+subq   $0x50,%rsp
+movq   %rsi,-0x48(%rbp)
+movq   -0x48(%rbp),%rax
+movq   %rax,%rsi
+movl   $0x400f60,%edi
+movl   $0x0,%eax
+movl   $0x1770,%edi
+movl   $0x0,%eax
+leave
+ret
+SET_SIZE(big_struct_ret_w_float, big_struct_ret_w_float_end)
+
+FUNC(big_struct_arg_by_value)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rdi,-0x8(%rbp)
+subq    $0x40,%rsp
+SET_SIZE(big_struct_arg_by_value, big_struct_arg_by_value_end)
+
+FUNC(small_struct_arg_by_value)
+pushq   %rbp
+movq    %rsp,%rbp
+movq    %rdx,-0x18(%rbp)
+movq    %rsi,-0x10(%rbp)
+movq    %rdi,-0x8(%rbp)
+subq    $0x50,%rsp
+SET_SIZE(small_struct_arg_by_value, small_struct_arg_by_value_end)
+
+FUNC(interleaved_argument_saves)
+pushq	%rbp
+movq	%rdi,%rax
+shlq	$0x21,%rax
+movq	%rsp,%rbp
+shrq	$0x29,%rax
+subq	$0x30,%rsp
+movq	%rdi,-0x8(%rbp)
+movq	%rbx,-0x28(%rbp)
+movzbl	%dil,%edi
+movq	%rcx,-0x20(%rbp)
+movq	%rdx,-0x18(%rbp)
+movq	%rsi,-0x10(%rbp)
+movq	0x0(,%rax,8),%rax
+SET_SIZE(interleaved_argument_saves, interleaved_argument_saves_end)
+
+FUNC(jmp_table)
+pushq	%rbp
+movq	%rsp,%rbp
+.word	0x9afe
+.word	0xffff
+.word	0xffff
+.word	0xa8ff
+.word	0xffff
+.word	0xffff
+.word	0x7cff
+.word	0xffff
+.word	0xffff
+SET_SIZE(jmp_table, jmp_table_end)        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsaveargs/tests/testmatch/testmatch.c	Sat Feb 09 17:21:16 2013 -0500
@@ -0,0 +1,175 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <saveargs.h>
+
+#define	DEF_TEST(name)		\
+    extern uint8_t name[];	\
+    extern int name##_end
+
+#define	SIZE_OF(name) ((caddr_t)&name##_end - (caddr_t)&name)
+
+#define	TEST_GOOD(name, argc)					\
+	if (saveargs_has_args(name, SIZE_OF(name), argc, 0) ==	\
+	    SAVEARGS_TRAD_ARGS)					\
+		printf("Pass: %s\n", #name);			\
+	else							\
+		printf("FAIL: %s\n", #name);
+
+#define	TEST_GOOD_STRUCT(name, argc)				\
+	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) ==	\
+	    SAVEARGS_STRUCT_ARGS)				\
+		printf("Pass: %s\n", #name);			\
+	else							\
+		printf("FAIL: %s\n", #name);
+
+/*
+ * GCC deals with structures differently, so TRAD args is actually correct for
+ * this
+ */
+#define	TEST_GOOD_GSTRUCT(name, argc)				\
+	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) ==	\
+	    SAVEARGS_TRAD_ARGS)					\
+		printf("Pass: %s\n", #name);			\
+	else							\
+		printf("FAIL: %s\n", #name);
+
+#define	TEST_BAD(name, argc)					\
+	if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == 	\
+		SAVEARGS_NO_ARGS)				\
+		printf("Pass: %s\n", #name);			\
+	else							\
+		printf("FAIL: %s\n", #name);
+
+#define	TEST_BAD_STRUCT(name, argc)				\
+	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 	\
+		SAVEARGS_NO_ARGS)				\
+		printf("Pass: %s\n", #name);			\
+	else							\
+		printf("FAIL: %s\n", #name);
+
+#define	TEST_BAD_GSTRUCT(name, argc)				\
+	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 	\
+		SAVEARGS_NO_ARGS)				\
+		printf("Pass: %s\n", #name);			\
+	else							\
+		printf("FAIL: %s\n", #name);
+
+DEF_TEST(gcc_mov_align);
+DEF_TEST(gcc_mov_basic);
+DEF_TEST(gcc_mov_noorder);
+DEF_TEST(gcc_mov_struct_noorder);
+DEF_TEST(gcc_mov_big_struct_ret);
+DEF_TEST(gcc_mov_big_struct_ret_and_spill);
+DEF_TEST(gcc_mov_small_struct_ret);
+DEF_TEST(gcc_mov_small_struct_ret_and_spill);
+DEF_TEST(gcc_mov_stack_spill);
+
+DEF_TEST(gcc_push_align);
+DEF_TEST(gcc_push_basic);
+DEF_TEST(gcc_push_noorder);
+DEF_TEST(gcc_push_struct_noorder);
+DEF_TEST(gcc_push_big_struct_ret);
+DEF_TEST(gcc_push_big_struct_ret_and_spill);
+DEF_TEST(gcc_push_small_struct_ret);
+DEF_TEST(gcc_push_small_struct_ret_and_spill);
+DEF_TEST(gcc_push_stack_spill);
+
+DEF_TEST(ss_mov_align);
+DEF_TEST(ss_mov_basic);
+DEF_TEST(ss_mov_big_struct_ret);
+DEF_TEST(ss_mov_big_struct_ret_and_spill);
+DEF_TEST(ss_mov_small_struct_ret);
+DEF_TEST(ss_mov_small_struct_ret_and_spill);
+DEF_TEST(ss_mov_stack_spill);
+
+DEF_TEST(dtrace_instrumented);
+DEF_TEST(kmem_alloc);
+DEF_TEST(uts_kill);
+DEF_TEST(av1394_ic_bitreverse);
+
+DEF_TEST(small_struct_ret_w_float);
+DEF_TEST(big_struct_ret_w_float);
+
+DEF_TEST(interleaved_argument_saves);
+DEF_TEST(jmp_table);
+
+/*
+ * Functions which should not match
+ *
+ * no_fp			-- valid save-args sequence with no saved FP
+ * big_struct_arg_by_value	-- function with big struct passed by value
+ * small_struct_arg_by_value	-- function with small struct passed by value
+ */
+DEF_TEST(no_fp);
+DEF_TEST(big_struct_arg_by_value);
+DEF_TEST(small_struct_arg_by_value);
+
+int
+main(int argc, char **argv)
+{
+	TEST_GOOD(kmem_alloc, 2);
+	TEST_GOOD(uts_kill, 2);
+	TEST_GOOD(av1394_ic_bitreverse, 1);
+	TEST_GOOD(dtrace_instrumented, 4);
+	TEST_GOOD_GSTRUCT(big_struct_ret_w_float, 1);
+	TEST_BAD(no_fp, 5);
+
+	TEST_GOOD(gcc_mov_align, 5);
+	TEST_GOOD(gcc_push_align, 5);
+	TEST_GOOD(ss_mov_align, 5);
+
+	TEST_GOOD(gcc_mov_basic, 4);
+	TEST_GOOD(gcc_push_basic, 4);
+	TEST_GOOD(ss_mov_basic, 4);
+
+	TEST_GOOD(gcc_mov_noorder, 4);
+	TEST_GOOD(gcc_push_noorder, 4);
+
+	TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret, 4);
+	TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret, 4);
+	TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
+
+	TEST_GOOD_GSTRUCT(gcc_mov_struct_noorder, 4);
+	TEST_GOOD_GSTRUCT(gcc_push_struct_noorder, 4);
+
+	TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret_and_spill, 8);
+	TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret_and_spill, 8);
+	TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
+
+	TEST_GOOD(gcc_mov_small_struct_ret, 4);
+	TEST_GOOD(gcc_push_small_struct_ret, 4);
+	TEST_GOOD(ss_mov_small_struct_ret, 4);
+
+	TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
+	TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
+	TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
+
+	TEST_GOOD(gcc_mov_stack_spill, 8);
+	TEST_GOOD(gcc_push_stack_spill, 8);
+	TEST_GOOD(ss_mov_stack_spill, 8);
+
+	TEST_BAD(big_struct_arg_by_value, 2);
+	TEST_BAD(small_struct_arg_by_value, 2);
+
+	TEST_BAD(small_struct_ret_w_float, 1);
+
+	TEST_GOOD(interleaved_argument_saves, 4);
+	TEST_BAD(jmp_table, 1);
+
+	return (0);
+}
--- a/usr/src/pkg/manifests/system-library.mf	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/pkg/manifests/system-library.mf	Sat Feb 09 17:21:16 2013 -0500
@@ -351,6 +351,7 @@
 file path=usr/lib/$(ARCH64)/libproject.so.1
 file path=usr/lib/$(ARCH64)/libraidcfg.so.1
 file path=usr/lib/$(ARCH64)/libreparse.so.1
+$(i386_ONLY)file path=usr/lib/$(ARCH64)/libsaveargs.so.1
 file path=usr/lib/$(ARCH64)/libsched.so.1
 file path=usr/lib/$(ARCH64)/libsctp.so.1
 file path=usr/lib/$(ARCH64)/libshell.so.1
--- a/usr/src/tools/findunref/exception_list.open	Fri Mar 15 16:26:41 2013 -0400
+++ b/usr/src/tools/findunref/exception_list.open	Sat Feb 09 17:21:16 2013 -0500
@@ -132,7 +132,7 @@
 ./usr/src/lib/crypt_modules/sha256/test.c
 ./usr/src/lib/efcode/fcode_test
 ./usr/src/lib/libkvm/common/test.c
-./usr/src/common/saveargs/tests/
+./usr/src/lib/libsaveargs/tests/
 
 #
 # Ignore debugging code.