Mercurial > illumos > illumos-gate
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>
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.