diff options
Diffstat (limited to 'usr/src')
85 files changed, 2193 insertions, 237 deletions
diff --git a/usr/src/cmd/dtrace/Makefile.com b/usr/src/cmd/dtrace/Makefile.com index 2f69e31be5..81aad72bbf 100644 --- a/usr/src/cmd/dtrace/Makefile.com +++ b/usr/src/cmd/dtrace/Makefile.com @@ -29,6 +29,7 @@ OBJS = dtrace.o SRCS = $(OBJS:%.o=../%.c) include ../../Makefile.cmd +include ../../Makefile.ctf CFLAGS += $(CCVERBOSE) CFLAGS64 += $(CCVERBOSE) @@ -53,5 +54,6 @@ lint: lint_SRCS %.o: ../%.c $(COMPILE.c) $< + $(POST_PROCESS_O) include ../../Makefile.targ diff --git a/usr/src/cmd/dtrace/dtrace.c b/usr/src/cmd/dtrace/dtrace.c index e74e3df690..f005629fc9 100644 --- a/usr/src/cmd/dtrace/dtrace.c +++ b/usr/src/cmd/dtrace/dtrace.c @@ -25,6 +25,7 @@ */ /* * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -488,6 +489,7 @@ static void print_probe_info(const dtrace_probeinfo_t *p) { char buf[BUFSIZ]; + char *user; int i; oprintf("\n\tProbe Description Attributes\n"); @@ -511,10 +513,14 @@ print_probe_info(const dtrace_probeinfo_t *p) oprintf("\n\tArgument Types\n"); for (i = 0; i < p->dtp_argc; i++) { + if (p->dtp_argv[i].dtt_flags & DTT_FL_USER) + user = "userland "; + else + user = ""; if (ctf_type_name(p->dtp_argv[i].dtt_ctfp, p->dtp_argv[i].dtt_type, buf, sizeof (buf)) == NULL) (void) strlcpy(buf, "(unknown)", sizeof (buf)); - oprintf("\t\targs[%d]: %s\n", i, buf); + oprintf("\t\targs[%d]: %s%s\n", i, user, buf); } if (p->dtp_argc == 0) diff --git a/usr/src/cmd/dtrace/test/tst/common/Makefile b/usr/src/cmd/dtrace/test/tst/common/Makefile index 147e66b7ad..49d810a720 100644 --- a/usr/src/cmd/dtrace/test/tst/common/Makefile +++ b/usr/src/cmd/dtrace/test/tst/common/Makefile @@ -26,7 +26,12 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# Copyright (c) 2013, Joyent, Inc. All rights reserved. +# + +# +# WARNING: Do not include Makefile.ctf here. That will cause tests to +# break. # include $(SRC)/Makefile.master @@ -85,6 +90,38 @@ json/tst.usdt.exe: json/tst.usdt.o json/usdt.o $(LINK.c) -o json/tst.usdt.exe json/tst.usdt.o json/usdt.o $(LDLIBS) $(POST_PROCESS) ; $(STRIP_STABS) +# +# Tests that use the next three programs rely on the binaries having +# valid CTF data. +# +uctf/tst.aouttype.exe: uctf/tst.aouttype.c + $(COMPILE.c) $(CTF_FLAGS) -o uctf/tst.aouttype.o uctf/tst.aouttype.c + $(CTFCONVERT) -i -L VERSION uctf/tst.aouttype.o + $(LINK.c) -o uctf/tst.aouttype.exe uctf/tst.aouttype.o $(LDLIBS) + $(CTFMERGE) -L VERSION -o $@ uctf/tst.aouttype.o + $(POST_PROCESS) ; $(STRIP_STABS) + +uctf/tst.chasestrings.exe: uctf/tst.chasestrings.c + $(COMPILE.c) $(CTF_FLAGS) -o uctf/tst.chasestrings.o uctf/tst.chasestrings.c + $(CTFCONVERT) -i -L VERSION uctf/tst.chasestrings.o + $(LINK.c) -o uctf/tst.chasestrings.exe uctf/tst.chasestrings.o $(LDLIBS) + $(CTFMERGE) -L VERSION -o $@ uctf/tst.chasestrings.o + $(POST_PROCESS) ; $(STRIP_STABS) + +uctf/tst.printtype.exe: uctf/tst.printtype.c + $(COMPILE.c) $(CTF_FLAGS) -o uctf/tst.printtype.o uctf/tst.printtype.c + $(CTFCONVERT) -i -L VERSION uctf/tst.printtype.o + $(LINK.c) -o uctf/tst.printtype.exe uctf/tst.printtype.o $(LDLIBS) + $(CTFMERGE) -L VERSION -o $@ uctf/tst.printtype.o + $(POST_PROCESS) ; $(STRIP_STABS) + +# +# This program should never have any ctf data in it. +# +uctf/tst.libtype.exe: + $(LINK.c) -o uctf/tst.libtype.exe uctf/tst.libtype.c $(LDLIBS) + $(POST_PROCESS) ; $(STRIP_STABS) + usdt/tst.args.exe: usdt/tst.args.o usdt/args.o $(LINK.c) -o usdt/tst.args.exe usdt/tst.args.o usdt/args.o $(LDLIBS) $(POST_PROCESS) ; $(STRIP_STABS) diff --git a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh index 692a715303..b16ea53c81 100644 --- a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh @@ -45,10 +45,10 @@ cat > Makefile <<EOF all: main main: main.o - gcc -o main main.o + gcc -m32 -o main main.o main.o: main.c - gcc -c main.c + gcc -m32 -c main.c EOF cat > main.c <<EOF diff --git a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh index 03b6003fed..d447c2225f 100644 --- a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh @@ -45,16 +45,16 @@ cat > Makefile <<EOF all: main altlib.so main: main.o - gcc -o main main.o + gcc -m32 -o main main.o main.o: main.c - gcc -c main.c + gcc -m32 -c main.c altlib.so: altlib.o - gcc -shared -o altlib.so altlib.o -lc + gcc -m32 -shared -o altlib.so altlib.o -lc altlib.o: altlib.c - gcc -c altlib.c + gcc -m32 -fPIC -c altlib.c EOF cat > altlib.c <<EOF diff --git a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh index 4a74cb050a..dcd4d4111a 100644 --- a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh @@ -46,10 +46,10 @@ cat > Makefile <<EOF all: main main: main.o prov.o - gcc -o main main.o prov.o + gcc -m32 -o main main.o prov.o main.o: main.c prov.h - gcc -c main.c + gcc -m32 -c main.c prov.h: prov.d $dtrace -h -s prov.d diff --git a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh index 8d326ad7c1..7030be7394 100644 --- a/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh @@ -46,10 +46,10 @@ cat > Makefile <<EOF all: main altlib.so main: main.o provmain.o - gcc -o main main.o provmain.o + gcc -m32 -o main main.o provmain.o main.o: main.c prov.h - gcc -c main.c + gcc -m32 -c main.c prov.h: prov.d $dtrace -h -s prov.d @@ -58,10 +58,10 @@ provmain.o: prov.d main.o $dtrace -G -32 -o provmain.o -s prov.d main.o altlib.so: altlib.o provalt.o - gcc -shared -o altlib.so altlib.o provalt.o -lc + gcc -m32 -shared -o altlib.so altlib.o provalt.o -lc altlib.o: altlib.c prov.h - gcc -c altlib.c + gcc -m32 -c altlib.c provalt.o: prov.d altlib.o $dtrace -G -32 -o provalt.o -s prov.d altlib.o diff --git a/usr/src/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh b/usr/src/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh index 4c5df0a1ef..b0eff5fc2b 100644 --- a/usr/src/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh @@ -50,7 +50,7 @@ main(int argc, char *argv[]) } EOF -gcc -o test test.c +gcc -m32 -o test test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d new file mode 100644 index 0000000000..4865d81ee1 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid.d @@ -0,0 +1,21 @@ +/* + * 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 (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option quiet + +BEGIN +{ + trace((pidfoo`int)0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d new file mode 100644 index 0000000000..bafed12172 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid2.d @@ -0,0 +1,21 @@ +/* + * 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 (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option quiet + +BEGIN +{ + trace((pid8foo`int)0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d new file mode 100644 index 0000000000..fb9443a828 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidpid3.d @@ -0,0 +1,21 @@ +/* + * 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 (c) 2013 Joyent, Inc. All rights reserved. + */ + +#pragma D option quiet + +BEGIN +{ + trace((pid0`int)0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh new file mode 100644 index 0000000000..978cde3cf0 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidtype.ksh @@ -0,0 +1,34 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# While it's hard to be completely certain that a type of the name we want +# doesn't exist, we're going to try to pick a name which is rather unique. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="season_8_mountain_of_madness_t" +pid=$$ + +rc=`$dtrace -n "BEGIN{ trace(pid$pid`$t)0); }"` + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh new file mode 100644 index 0000000000..e64ed526ed --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/err.invalidtype2.ksh @@ -0,0 +1,35 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# While it's hard to be completely certain that a type of the name we want +# doesn't exist, we're going to try to pick a name which is rather +# unique. This time we're also going to use the pid$target alias. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="season_8_mountain_of_madness_t" +pid=$$ + +rc=`$dtrace -n "BEGIN{ trace(pid`$t)0); }"` -p $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh new file mode 100644 index 0000000000..d987c8da7a --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/err.user64mode.ksh @@ -0,0 +1,90 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# This test is purposefully using a 64-bit DTrace and thus 64-bit types +# when compared with a 32-bit process. This test uses the userland +# keyword and so the implicit copyin should access illegal memory and +# thus exit. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="zelda_info_t" +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -64 -qs /dev/stdin <<EOF +typedef struct info { + char *zi_gamename; + int zi_ndungeons; + char *zi_villain; + int zi_haszelda; +} info_t; + +pid$pid::has_princess:entry +/next == 0/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + exit(0); +} + +ERROR +{ + exit(1); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c new file mode 100644 index 0000000000..a4d25f8ca8 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.aouttype.c @@ -0,0 +1,46 @@ +/* + * 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 (c) Joyent, Inc. All rights reserved. + */ + +/* + * This test tries to make sure that we have CTF data for a type that only this + * binary would reasonably have. In this case, the + * season_7_lisa_the_vegetarian_t. + */ +#include <unistd.h> + +typedef struct season_7_lisa_the_vegetarian { + int fr_salad; +} season_7_lisa_the_vegetarian_t; + +int +sleeper(season_7_lisa_the_vegetarian_t *lp) +{ + for (;;) { + sleep(lp->fr_salad); + } + /*NOTREACHED*/ + return (0); +} + +int +main(void) +{ + season_7_lisa_the_vegetarian_t l; + l.fr_salad = 100; + + sleeper(&l); + + return (0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh new file mode 100644 index 0000000000..151a93676d --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.aouttype.ksh @@ -0,0 +1,44 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Lookup a type that is inside a.out. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="season_7_lisa_the_vegetrian_t *" +exe="tst.aouttype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +rc=`$dtrace -n "BEGIN{ trace((pid$pid\`$t)0); exit(0); }"` + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c new file mode 100644 index 0000000000..595a7cb6c5 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.c @@ -0,0 +1,79 @@ +/* + * 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 (c) Joyent, Inc. All rights reserved. + */ + +/* + * This test takes data from the current binary which is basically running in a + * loop between two functions and our goal is to have two unique types that they + * contain which we can print. + */ + +#include <unistd.h> + +typedef struct zelda_info { + char *zi_gamename; + int zi_ndungeons; + char *zi_villain; + int zi_haszelda; +} zelda_info_t; + +static int +has_princess(zelda_info_t *z) +{ + return (z->zi_haszelda); +} + +static int +has_dungeons(zelda_info_t *z) +{ + return (z->zi_ndungeons != 0); +} + +static const char * +has_villain(zelda_info_t *z) +{ + return (z->zi_villain); +} + +int +main(void) +{ + zelda_info_t oot; + zelda_info_t la; + zelda_info_t lttp; + + oot.zi_gamename = "Ocarina of Time"; + oot.zi_ndungeons = 10; + oot.zi_villain = "Ganondorf"; + oot.zi_haszelda = 1; + + la.zi_gamename = "Link's Awakening"; + la.zi_ndungeons = 9; + la.zi_villain = "Nightmare"; + la.zi_haszelda = 0; + + lttp.zi_gamename = "A Link to the Past"; + lttp.zi_ndungeons = 12; + lttp.zi_villain = "Ganon"; + lttp.zi_haszelda = 1; + + for (;;) { + (void) has_princess(&oot); + (void) has_dungeons(&la); + (void) has_villain(<tp); + sleep(1); + } + + return (0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh new file mode 100644 index 0000000000..25028460db --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh @@ -0,0 +1,76 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# This test is checking that we can read members and that pointers inside +# members point to valid data that is intelligible, eg. strings. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="zelda_info_t" +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::has_princess:entry +/next == 0/ +{ + this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))); + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons, + copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))); + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons, + copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + this->t = (pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t))); + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + copyinstr((uintptr_t)this->t->zi_gamename), this->t->zi_ndungeons, + copyinstr((uintptr_t)this->t->zi_villain), this->t->zi_haszelda); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out new file mode 100644 index 0000000000..219e406e61 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.chasestrings.ksh.out @@ -0,0 +1,4 @@ +game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1 +game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0 +game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1 + diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.libtype.c b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.libtype.c new file mode 100644 index 0000000000..916a5b51b9 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.libtype.c @@ -0,0 +1,29 @@ +/* + * 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 (c) Joyent, Inc. All rights reserved. + */ + +/* + * We're linked against libc which has types, though we do not. + */ +#include <unistd.h> + +int +main(void) +{ + for (;;) { + sleep(1000); + } + /*NOTREACHED*/ + return (0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh new file mode 100644 index 0000000000..af7c6c8fe1 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.libtype.ksh @@ -0,0 +1,45 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Here we want to make sure that the program in question does not have ctf data +# in its a.out; however, we can get types out of a linked libc. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="int" +exe="tst.libtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -eq 0 ]]; then + echo "CTF exists in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +rc=`$dtrace -n "BEGIN{ trace((pid$pid\`$t)0); exit(0); }"` + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh new file mode 100644 index 0000000000..f767def53d --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.linkmap.ksh @@ -0,0 +1,44 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# We should be able to see both strstr from libc and from ld on an +# alternate linkmap. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 + +$dtrace -q -p $$ -s /dev/stdin <<EOF +pid\$target:LM1\`ld.so.1:strstr:entry, +pid\$target:libc.so.1:strstr:entry +{ + exit (0); +} + +BEGIN +{ + exit (0); +} +EOF +rc=$? + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh new file mode 100644 index 0000000000..febb015918 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.pidprint.ksh @@ -0,0 +1,69 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we expect. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::ff_getgameid:entry +/next == 0/ +{ + print(*args[0]); + printf("\n"); + next = 1; +} + +pid$pid::ff_getpartysize:entry +/next == 1/ +{ + print(*args[0]); + printf("\n"); + next = 2; +} + +pid$pid::ff_getsummons:entry +/next == 2/ +{ + print(*args[0]); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh new file mode 100644 index 0000000000..7398dc41d9 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.pidprinttarg.ksh @@ -0,0 +1,70 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we +# expect. This time, use $target to make sure that path works correctly. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -p $pid -qs /dev/stdin <<EOF +pid\$target::ff_getgameid:entry +/next == 0/ +{ + print(*args[0]); + printf("\n"); + next = 1; +} + +pid\$target::ff_getpartysize:entry +/next == 1/ +{ + print(*args[0]); + printf("\n"); + next = 2; +} + +pid\$target::ff_getsummons:entry +/next == 2/ +{ + print(*args[0]); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.c b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.c new file mode 100644 index 0000000000..6c27593e97 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.c @@ -0,0 +1,72 @@ +/* + * 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 (c) Joyent, Inc. All rights reserved. + */ + +/* + * The point of this is to use print() on various functions to make sure that we + * can print basic structures. Note that we purposefully are making sure that + * there are no pointers here. + */ +#include <unistd.h> + +typedef struct final_fantasy_info { + int ff_gameid; + int ff_partysize; + int ff_hassummons; +} final_fantasy_info_t; + +static int +ff_getgameid(final_fantasy_info_t *f) +{ + return (0); +} + +static int +ff_getpartysize(final_fantasy_info_t *f) +{ + return (0); +} + +static int +ff_getsummons(final_fantasy_info_t *f) +{ + return (0); +} + +int +main(void) +{ + final_fantasy_info_t ffiii, ffx, ffi; + + ffi.ff_gameid = 1; + ffi.ff_partysize = 4; + ffi.ff_hassummons = 0; + + ffiii.ff_gameid = 6; + ffiii.ff_partysize = 4; + ffiii.ff_hassummons = 1; + + ffx.ff_gameid = 10; + ffx.ff_partysize = 3; + ffx.ff_hassummons = 1; + + for (;;) { + ff_getgameid(&ffi); + ff_getpartysize(&ffx); + ff_getsummons(&ffiii); + sleep(1); + } + /*NOTREACHED*/ + return (0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh new file mode 100644 index 0000000000..dfc1535829 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh @@ -0,0 +1,69 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we expect. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::ff_getgameid:entry +/next == 0/ +{ + print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)))); + printf("\n"); + next = 1; +} + +pid$pid::ff_getpartysize:entry +/next == 1/ +{ + print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)))); + printf("\n"); + next = 2; +} + +pid$pid::ff_getsummons:entry +/next == 2/ +{ + print(*(pid$pid\`$t *)(copyin(arg0, sizeof (pid$pid\`$t)))); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out new file mode 100644 index 0000000000..1770ba2354 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtype.ksh.out @@ -0,0 +1,16 @@ +final_fantasy_info_t { + int ff_gameid = 0x1 + int ff_partysize = 0x4 + int ff_hassummons = 0 +} +final_fantasy_info_t { + int ff_gameid = 0xa + int ff_partysize = 0x3 + int ff_hassummons = 0x1 +} +final_fantasy_info_t { + int ff_gameid = 0x6 + int ff_partysize = 0x4 + int ff_hassummons = 0x1 +} + diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh new file mode 100644 index 0000000000..025d4a8c02 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.printtypetarg.ksh @@ -0,0 +1,70 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Use print() on userland CTF types and verify we get the data we +# expect. Use the pid` alias for $target. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="final_fantasy_info_t" +exe="tst.printtype.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -p $pid -qs /dev/stdin <<EOF +pid\$target::ff_getgameid:entry +/next == 0/ +{ + print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t)))); + printf("\n"); + next = 1; +} + +pid\$target::ff_getpartysize:entry +/next == 1/ +{ + print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t)))); + printf("\n"); + next = 2; +} + +pid\$target::ff_getsummons:entry +/next == 2/ +{ + print(*(pid\`$t *)(copyin(arg0, sizeof (pid\`$t)))); + printf("\n"); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh new file mode 100644 index 0000000000..58811ff6fb --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh @@ -0,0 +1,83 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# Simple test that if we manually use the userland keyword that it +# works. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +t="zelda_info_t" +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -32 -qs /dev/stdin <<EOF +typedef struct info { + char *zi_gamename; + int zi_ndungeons; + char *zi_villain; + int zi_haszelda; +} info_t; + +pid$pid::has_princess:entry +/next == 0/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + this->t = (userland info_t *)arg0; + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(this->t->zi_gamename), this->t->zi_ndungeons, + stringof(this->t->zi_villain), this->t->zi_haszelda); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out new file mode 100644 index 0000000000..219e406e61 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userlandkey.ksh.out @@ -0,0 +1,4 @@ +game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1 +game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0 +game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1 + diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh new file mode 100644 index 0000000000..79d79de8ae --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh @@ -0,0 +1,72 @@ +#! /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 (c) 2013 Joyent, Inc. All rights reserved. +# + +# +# This test is checking that we can read members and that pointers inside +# members point to valid data that is intelligible, eg. strings. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +exe="tst.chasestrings.exe" + +elfdump "./$exe" | grep -q '.SUNW_ctf' +if [[ $? -ne 0 ]]; then + echo "CTF does not exist in $exe, that's a bug" >&2 + exit 1 +fi + +./$exe & +pid=$! + +$dtrace -qs /dev/stdin <<EOF +pid$pid::has_princess:entry +/next == 0/ +{ + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(args[0]->zi_gamename), args[0]->zi_ndungeons, + stringof(args[0]->zi_villain), args[0]->zi_haszelda); + next = 1; +} + +pid$pid::has_dungeons:entry +/next == 1/ +{ + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(args[0]->zi_gamename), args[0]->zi_ndungeons, + stringof(args[0]->zi_villain), args[0]->zi_haszelda); + next = 2; +} + +pid$pid::has_villain:entry +/next == 2/ +{ + printf("game: %s, dungeon: %d, villain: %s, zelda: %d\n", + stringof(args[0]->zi_gamename), args[0]->zi_ndungeons, + stringof(args[0]->zi_villain), args[0]->zi_haszelda); + exit(0); +} +EOF +rc=$? + +kill -9 $pid + +exit $rc diff --git a/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out new file mode 100644 index 0000000000..219e406e61 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/uctf/tst.userstrings.ksh.out @@ -0,0 +1,4 @@ +game: Ocarina of Time, dungeon: 10, villain: Ganondorf, zelda: 1 +game: Link's Awakening, dungeon: 9, villain: Nightmare, zelda: 0 +game: A Link to the Past, dungeon: 12, villain: Ganon, zelda: 1 + diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh index c9bcb03e63..3480d34862 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh @@ -60,10 +60,10 @@ cat > Makefile <<EOF all: main main: main.o prov.o - gcc -o main main.o prov.o + gcc -m32 -o main main.o prov.o main.o: main.c prov.h - gcc -c main.c + gcc -m32 -c main.c prov.h: prov.d $dtrace -h -s prov.d diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh index ade3a54d48..da1b2b3e28 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh @@ -45,17 +45,17 @@ cat > Makefile <<EOF all: main livelib.so deadlib.so main: main.o prov.o - gcc -o main main.o + gcc -m32 -o main main.o main.o: main.c - gcc -c main.c + gcc -m32 -c main.c livelib.so: livelib.o prov.o - gcc -shared -o livelib.so livelib.o prov.o -lc + gcc -m32 -shared -o livelib.so livelib.o prov.o -lc livelib.o: livelib.c prov.h - gcc -c livelib.c + gcc -m32 -fPIC -c livelib.c prov.o: livelib.o prov.d $dtrace -G -s prov.d livelib.o @@ -65,10 +65,10 @@ prov.h: prov.d deadlib.so: deadlib.o - gcc -shared -o deadlib.so deadlib.o -lc + gcc -m32 -shared -o deadlib.so deadlib.o -lc deadlib.o: deadlib.c - gcc -c deadlib.c + gcc -m32 -fPIC -c deadlib.c clean: rm -f main.o livelib.o prov.o prov.h deadlib.o diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh index 692c8d9b5c..328db12cc1 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh @@ -40,17 +40,17 @@ cat > Makefile <<EOF all: main livelib.so deadlib.so main: main.o prov.o - gcc -o main main.o + gcc -m32 -o main main.o main.o: main.c - gcc -c main.c + gcc -m32 -c main.c livelib.so: livelib.o prov.o - gcc -shared -o livelib.so livelib.o prov.o -lc + gcc -m32 -shared -o livelib.so livelib.o prov.o -lc livelib.o: livelib.c prov.h - gcc -c livelib.c + gcc -m32 -fPIC -c livelib.c prov.o: livelib.o prov.d $dtrace -G -s prov.d livelib.o @@ -60,10 +60,10 @@ prov.h: prov.d deadlib.so: deadlib.o - gcc -shared -o deadlib.so deadlib.o -lc + gcc -m32 -shared -o deadlib.so deadlib.o -lc deadlib.o: deadlib.c - gcc -c deadlib.c + gcc -m32 -fPIC -c deadlib.c clean: rm -f main.o livelib.o prov.o prov.h deadlib.o diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh index e950eb4af2..73400cda99 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh @@ -45,17 +45,17 @@ cat > Makefile <<EOF all: main livelib.so deadlib.so main: main.o prov.o - gcc -o main main.o + gcc -m32 -o main main.o main.o: main.c - gcc -c main.c + gcc -m32 -c main.c livelib.so: livelib.o prov.o - gcc -shared -o livelib.so livelib.o prov.o -lc + gcc -m32 -shared -o livelib.so livelib.o prov.o -lc livelib.o: livelib.c prov.h - gcc -c livelib.c + gcc -m32 -fPIC -c livelib.c prov.o: livelib.o prov.d $dtrace -G -s prov.d livelib.o @@ -65,10 +65,10 @@ prov.h: prov.d deadlib.so: deadlib.o - gcc -shared -o deadlib.so deadlib.o -lc + gcc -m32 -shared -o deadlib.so deadlib.o -lc deadlib.o: deadlib.c - gcc -c deadlib.c + gcc -m32 -fPIC -c deadlib.c clean: rm -f main.o livelib.o prov.o prov.h deadlib.o diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh index 3d50443370..307b8a02a0 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh @@ -71,7 +71,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -81,7 +81,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh index 47ea79f376..abf037f92f 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh @@ -60,7 +60,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -70,7 +70,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh index 9b71ac2637..451bf76171 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh @@ -76,7 +76,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -86,7 +86,8 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o + +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh index 79e8266192..630f4c9342 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh @@ -69,7 +69,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -79,7 +79,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh index 1264e3ffb6..9449313483 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh @@ -70,7 +70,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -80,7 +80,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.header.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.header.ksh index f4679bc3f8..9fc5838db2 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.header.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.header.ksh @@ -64,7 +64,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -74,7 +74,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh index bbe1a4acc9..2f659a20d1 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh @@ -61,7 +61,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -71,7 +71,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh index 35d97afc48..f740ae0b16 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh @@ -63,7 +63,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -73,7 +73,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh index 852f5a0b3c..515d5d50c7 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh @@ -64,7 +64,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -74,7 +74,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh index 7def9ed2ab..eb0eb42144 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.multiprov.ksh @@ -64,7 +64,7 @@ provider $oogle { }; EOF - cc -c $oogle.c + gcc -m32 -c $oogle.c if [ $? -ne 0 ]; then print -u2 "failed to compile $oogle.c" @@ -87,7 +87,7 @@ echo "}" >> test.c echo 'END{printa("%-10s %@d\\n", @)}' >> test.d -cc -o test test.c $objs +gcc -m32 -o test test.c $objs if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh index a43970f560..5c21f7cab9 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noprobes.ksh @@ -46,7 +46,7 @@ provider doogle { }; EOF -cc -c test.c +gcc -m32 -c test.c $dtrace -G -32 -s doogle.d test.o -o doogle.d.o if [ $? -eq 0 ]; then diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh index 338dcdf03e..abbb830e72 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh @@ -51,7 +51,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -61,7 +61,8 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o + +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh index a2e5edee38..27bc3e5287 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh @@ -51,7 +51,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -61,7 +61,8 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o + +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh index a1e939c883..512595d012 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh @@ -61,7 +61,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -71,7 +71,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh index f18c585ef6..529f52ff6a 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh @@ -51,7 +51,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -61,7 +61,8 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o + +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh index 2f0ee33f1e..76d9391179 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh @@ -51,7 +51,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -61,7 +61,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static.ksh index 85b0e553c4..b646cf067e 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static.ksh @@ -62,7 +62,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -72,7 +72,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh index 07b765702c..162074501c 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh @@ -66,7 +66,7 @@ provider test_prov { }; EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -82,7 +82,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create final DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.user.ksh b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.user.ksh index f52c1c351e..0b28060600 100644 --- a/usr/src/cmd/dtrace/test/tst/common/usdt/tst.user.ksh +++ b/usr/src/cmd/dtrace/test/tst/common/usdt/tst.user.ksh @@ -61,7 +61,7 @@ main(int argc, char **argv) } EOF -gcc -c test.c +gcc -m32 -c test.c if [ $? -ne 0 ]; then print -u2 "failed to compile test.c" exit 1 @@ -71,7 +71,7 @@ if [ $? -ne 0 ]; then print -u2 "failed to create DOF" exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh b/usr/src/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh index a06f44e42b..722eea6088 100644 --- a/usr/src/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh +++ b/usr/src/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh @@ -87,7 +87,7 @@ if [ $? -ne 0 ]; then exit 1 fi -gcc -o test test.o prov.o +gcc -m32 -o test test.o prov.o if [ $? -ne 0 ]; then print -u2 "failed to link final executable" exit 1 diff --git a/usr/src/common/ctf/ctf_open.c b/usr/src/common/ctf/ctf_open.c index 2148389fff..001cf5c591 100644 --- a/usr/src/common/ctf/ctf_open.c +++ b/usr/src/common/ctf/ctf_open.c @@ -25,7 +25,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <ctf_impl.h> @@ -788,6 +788,92 @@ bad: } /* + * Dupliate a ctf_file_t and its underlying section information into a new + * container. This works by copying the three ctf_sect_t's of the original + * container if they exist and passing those into ctf_bufopen. To copy those, we + * mmap anonymous memory with ctf_data_alloc and bcopy the data across. It's not + * the cheapest thing, but it's what we've got. + */ +ctf_file_t * +ctf_dup(ctf_file_t *ofp) +{ + ctf_file_t *fp; + ctf_sect_t ctfsect, symsect, strsect; + ctf_sect_t *ctp, *symp, *strp; + void *cbuf, *symbuf, *strbuf; + int err; + + cbuf = symbuf = strbuf = NULL; + /* + * The ctfsect isn't allowed to not exist, but the symbol and string + * section might not. We only need to copy the data of the section, not + * the name, as ctf_bufopen will take care of that. + */ + bcopy(&ofp->ctf_data, &ctfsect, sizeof (ctf_sect_t)); + cbuf = ctf_data_alloc(ctfsect.cts_size); + if (cbuf == NULL) { + (void) ctf_set_errno(ofp, ECTF_MMAP); + return (NULL); + } + + bcopy(ctfsect.cts_data, cbuf, ctfsect.cts_size); + ctf_data_protect(cbuf, ctfsect.cts_size); + ctfsect.cts_data = cbuf; + ctfsect.cts_offset = 0; + ctp = &ctfsect; + + if (ofp->ctf_symtab.cts_data != NULL) { + bcopy(&ofp->ctf_symtab, &symsect, sizeof (ctf_sect_t)); + symbuf = ctf_data_alloc(symsect.cts_size); + if (symbuf == NULL) { + (void) ctf_set_errno(ofp, ECTF_MMAP); + goto err; + } + bcopy(symsect.cts_data, symbuf, symsect.cts_size); + ctf_data_protect(symbuf, symsect.cts_size); + symsect.cts_data = symbuf; + symsect.cts_offset = 0; + symp = &symsect; + } else { + symp = NULL; + } + + if (ofp->ctf_strtab.cts_data != NULL) { + bcopy(&ofp->ctf_strtab, &strsect, sizeof (ctf_sect_t)); + strbuf = ctf_data_alloc(strsect.cts_size); + if (strbuf == NULL) { + (void) ctf_set_errno(ofp, ECTF_MMAP); + goto err; + } + bcopy(strsect.cts_data, strbuf, strsect.cts_size); + ctf_data_protect(strbuf, strsect.cts_size); + strsect.cts_data = strbuf; + strsect.cts_offset = 0; + strp = &strsect; + } else { + strp = NULL; + } + + fp = ctf_bufopen(ctp, symp, strp, &err); + if (fp == NULL) { + (void) ctf_set_errno(ofp, err); + goto err; + } + + fp->ctf_flags |= LCTF_MMAP; + + return (fp); + +err: + ctf_data_free(cbuf, ctfsect.cts_size); + if (symbuf != NULL) + ctf_data_free(symbuf, symsect.cts_size); + if (strbuf != NULL) + ctf_data_free(strbuf, strsect.cts_size); + return (NULL); +} + +/* * Close the specified CTF container and free associated data structures. Note * that ctf_close() is a reference counted operation: if the specified file is * the parent of other active containers, its reference count will be greater diff --git a/usr/src/common/ctf/ctf_types.c b/usr/src/common/ctf/ctf_types.c index 290c518ae7..ab1b9ff14b 100644 --- a/usr/src/common/ctf/ctf_types.c +++ b/usr/src/common/ctf/ctf_types.c @@ -25,8 +25,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <ctf_impl.h> ssize_t @@ -199,8 +197,9 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_t type) * Lookup the given type ID and print a string name for it into buf. Return * the actual number of bytes (not including \0) needed to format the name. */ -ssize_t -ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) +static ssize_t +ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, + const char *qname) { ctf_decl_t cd; ctf_decl_node_t *cdp; @@ -255,6 +254,8 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) case CTF_K_INTEGER: case CTF_K_FLOAT: case CTF_K_TYPEDEF: + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_POINTER: @@ -268,13 +269,22 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) break; case CTF_K_STRUCT: case CTF_K_FORWARD: - ctf_decl_sprintf(&cd, "struct %s", name); + ctf_decl_sprintf(&cd, "struct "); + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); + ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_UNION: - ctf_decl_sprintf(&cd, "union %s", name); + ctf_decl_sprintf(&cd, "union "); + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); + ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_ENUM: - ctf_decl_sprintf(&cd, "enum %s", name); + ctf_decl_sprintf(&cd, "enum "); + if (qname != NULL) + ctf_decl_sprintf(&cd, "%s`", qname); + ctf_decl_sprintf(&cd, "%s", name); break; case CTF_K_VOLATILE: ctf_decl_sprintf(&cd, "volatile"); @@ -301,6 +311,12 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) return (cd.cd_len); } +ssize_t +ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) +{ + return (ctf_type_qlname(fp, type, buf, len, NULL)); +} + /* * Lookup the given type ID and print a string name for it into buf. If buf * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. @@ -308,10 +324,19 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) char * ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) { - ssize_t rv = ctf_type_lname(fp, type, buf, len); + ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL); + return (rv >= 0 && rv < len ? buf : NULL); +} + +char * +ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, + const char *qname) +{ + ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname); return (rv >= 0 && rv < len ? buf : NULL); } + /* * Resolve the type down to a base type node, and then return the size * of the type storage in bytes. diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index 0873de319e..5573e8db25 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -23,6 +23,10 @@ # # +# Copyright (c) 2013, Joyent, Inc. All rights reserved. +# + +# # MAPFILE HEADER START # # WARNING: STOP NOW. DO NOT MODIFY THIS FILE. @@ -62,6 +66,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_create; ctf_delete_type; ctf_discard; + ctf_dup; ctf_enum_value; ctf_label_info; ctf_label_iter; @@ -104,6 +109,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { ctf_type_kind; ctf_type_lname; ctf_type_name; + ctf_type_qname; ctf_type_reference; ctf_type_resolve; ctf_type_size; diff --git a/usr/src/lib/libdtrace/common/dt_as.c b/usr/src/lib/libdtrace/common/dt_as.c index 457b8fd721..f937261c35 100644 --- a/usr/src/lib/libdtrace/common/dt_as.c +++ b/usr/src/lib/libdtrace/common/dt_as.c @@ -23,8 +23,10 @@ * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #include <sys/types.h> #include <strings.h> @@ -125,7 +127,7 @@ dt_copyvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) dvp->dtdv_flags |= DIFV_F_MOD; bzero(&dn, sizeof (dn)); - dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type); + dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type, B_FALSE); dt_node_diftype(pcb->pcb_hdl, &dn, &dvp->dtdv_type); idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW); diff --git a/usr/src/lib/libdtrace/common/dt_cc.c b/usr/src/lib/libdtrace/common/dt_cc.c index f4b0509b4a..5d38704ffe 100644 --- a/usr/src/lib/libdtrace/common/dt_cc.c +++ b/usr/src/lib/libdtrace/common/dt_cc.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent Inc. All rights reserved. + * Copyright (c) 2013, Joyent Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -662,6 +662,8 @@ dt_action_printflike(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp, static void dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp) { + int ctflib; + dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp); boolean_t istrace = (dnp->dn_ident->di_id == DT_ACT_TRACE); const char *act = istrace ? "trace" : "print"; @@ -693,7 +695,10 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp) * like arrays and function pointers that can't be resolved by * ctf_type_lookup(). This is later processed by dtrace_dof_create() * and turned into a reference into the string table so that we can - * get the type information when we process the data after the fact. + * get the type information when we process the data after the fact. In + * the case where we are referring to userland CTF data, we also need to + * to identify which ctf container in question we care about and encode + * that within the name. */ if (dnp->dn_ident->di_id == DT_ACT_PRINT) { dt_node_t *dret; @@ -703,12 +708,25 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp) dret = yypcb->pcb_dret; dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp); - n = snprintf(NULL, 0, "%s`%d", dmp->dm_name, dret->dn_type) + 1; + if (dmp->dm_pid != 0) { + ctflib = dt_module_getlibid(dtp, dmp, dret->dn_ctfp); + assert(ctflib >= 0); + n = snprintf(NULL, 0, "%s`%d`%d", dmp->dm_name, + ctflib, dret->dn_type) + 1; + } else { + n = snprintf(NULL, 0, "%s`%d", dmp->dm_name, + dret->dn_type) + 1; + } sdp->dtsd_strdata = dt_alloc(dtp, n); if (sdp->dtsd_strdata == NULL) longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); - (void) snprintf(sdp->dtsd_strdata, n, "%s`%d", dmp->dm_name, - dret->dn_type); + if (dmp->dm_pid != 0) { + (void) snprintf(sdp->dtsd_strdata, n, "%s`%d`%d", + dmp->dm_name, ctflib, dret->dn_type); + } else { + (void) snprintf(sdp->dtsd_strdata, n, "%s`%d", + dmp->dm_name, dret->dn_type); + } } ap->dtad_difo = dt_as(yypcb); diff --git a/usr/src/lib/libdtrace/common/dt_decl.c b/usr/src/lib/libdtrace/common/dt_decl.c index 563c0057da..4e99ff4c9f 100644 --- a/usr/src/lib/libdtrace/common/dt_decl.c +++ b/usr/src/lib/libdtrace/common/dt_decl.c @@ -21,7 +21,8 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. */ #include <strings.h> @@ -775,7 +776,7 @@ dt_decl_enumerator(char *s, dt_node_t *dnp) yyintdecimal = 0; dnp = dt_node_int(value); - dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type); + dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type, B_FALSE); if ((inp = malloc(sizeof (dt_idnode_t))) == NULL) longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); @@ -817,6 +818,8 @@ dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip) char *name; int rv; + tip->dtt_flags = 0; + /* * Based on our current #include depth and decl stack depth, determine * which dynamic CTF module and scope to use when adding any new types. @@ -824,6 +827,9 @@ dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip) dmp = yypcb->pcb_idepth ? dtp->dt_cdefs : dtp->dt_ddefs; flag = yypcb->pcb_dstack.ds_next ? CTF_ADD_NONROOT : CTF_ADD_ROOT; + if (ddp->dd_attr & DT_DA_USER) + tip->dtt_flags = DTT_FL_USER; + /* * If we have already cached a CTF type for this decl, then we just * return the type information for the cached type. diff --git a/usr/src/lib/libdtrace/common/dt_decl.h b/usr/src/lib/libdtrace/common/dt_decl.h index 2933155c78..d322875782 100644 --- a/usr/src/lib/libdtrace/common/dt_decl.h +++ b/usr/src/lib/libdtrace/common/dt_decl.h @@ -23,12 +23,14 @@ * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #ifndef _DT_DECL_H #define _DT_DECL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <libctf.h> #include <dtrace.h> @@ -59,6 +61,7 @@ typedef struct dt_decl { #define DT_DA_RESTRICT 0x0040 /* qualify type as restrict */ #define DT_DA_VOLATILE 0x0080 /* qualify type as volatile */ #define DT_DA_PAREN 0x0100 /* parenthesis tag */ +#define DT_DA_USER 0x0200 /* user-land type specifier */ typedef enum dt_dclass { DT_DC_DEFAULT, /* no storage class specified */ diff --git a/usr/src/lib/libdtrace/common/dt_dis.c b/usr/src/lib/libdtrace/common/dt_dis.c index fff4235a6b..c0af36420e 100644 --- a/usr/src/lib/libdtrace/common/dt_dis.c +++ b/usr/src/lib/libdtrace/common/dt_dis.c @@ -26,7 +26,8 @@ */ /* - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. */ #include <strings.h> @@ -312,9 +313,10 @@ dt_dis_typestr(const dtrace_diftype_t *t, char *buf, size_t len) (void) snprintf(ckind, sizeof (ckind), "0x%x", t->dtdt_ckind); } - if (t->dtdt_flags & DIF_TF_BYREF) { - (void) snprintf(buf, len, "%s (%s) by ref (size %lu)", - kind, ckind, (ulong_t)t->dtdt_size); + if (t->dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF)) { + (void) snprintf(buf, len, "%s (%s) by %sref (size %lu)", + kind, ckind, (t->dtdt_flags & DIF_TF_BYUREF) ? "user " : "", + (ulong_t)t->dtdt_size); } else { (void) snprintf(buf, len, "%s (%s) (size %lu)", kind, ckind, (ulong_t)t->dtdt_size); diff --git a/usr/src/lib/libdtrace/common/dt_error.c b/usr/src/lib/libdtrace/common/dt_error.c index f7ad28ebae..d822e2d420 100644 --- a/usr/src/lib/libdtrace/common/dt_error.c +++ b/usr/src/lib/libdtrace/common/dt_error.c @@ -110,7 +110,8 @@ static const struct { { EDT_BADAGGVAR, "Invalid aggregation variable identifier" }, { EDT_OVERSION, "Client requested deprecated version of library" }, { EDT_ENABLING_ERR, "Failed to enable probe" }, - { EDT_NOPROBES, "No probe sites found for declared provider" } + { EDT_NOPROBES, "No probe sites found for declared provider" }, + { EDT_CANTLOAD, "Failed to load module" }, }; static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]); diff --git a/usr/src/lib/libdtrace/common/dt_grammar.y b/usr/src/lib/libdtrace/common/dt_grammar.y index 0c12623bc4..07790f4ebc 100644 --- a/usr/src/lib/libdtrace/common/dt_grammar.y +++ b/usr/src/lib/libdtrace/common/dt_grammar.y @@ -23,8 +23,10 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <dt_impl.h> @@ -102,6 +104,7 @@ %token DT_KEY_TYPEDEF %token DT_KEY_UNION %token DT_KEY_UNSIGNED +%token DT_KEY_USERLAND %token DT_KEY_VOID %token DT_KEY_VOLATILE %token DT_KEY_WHILE @@ -633,6 +636,7 @@ type_specifier: DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); } | DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); } | DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); } | DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); } + | DT_KEY_USERLAND { $$ = dt_decl_attr(DT_DA_USER); } | DT_KEY_STRING { $$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string")); } diff --git a/usr/src/lib/libdtrace/common/dt_ident.c b/usr/src/lib/libdtrace/common/dt_ident.c index 3dfa058b16..33f94eb9fd 100644 --- a/usr/src/lib/libdtrace/common/dt_ident.c +++ b/usr/src/lib/libdtrace/common/dt_ident.c @@ -21,6 +21,8 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. */ #include <sys/sysmacros.h> @@ -95,7 +97,7 @@ dt_idcook_sign(dt_node_t *dnp, dt_ident_t *idp, } } - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } /* @@ -154,7 +156,7 @@ dt_idcook_assc(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) if (argc != 0) isp->dis_args[argc - 1].dn_list = NULL; - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } else { dt_idcook_sign(dnp, idp, argc, args, @@ -294,7 +296,7 @@ dt_idcook_func(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) } dt_node_type_assign(&isp->dis_args[i], - dtt.dtt_ctfp, dtt.dtt_type); + dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); } } @@ -381,7 +383,9 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap) dt_node_type_assign(dnp, prp->pr_argv[ap->dn_value].dtt_ctfp, - prp->pr_argv[ap->dn_value].dtt_type); + prp->pr_argv[ap->dn_value].dtt_type, + prp->pr_argv[ap->dn_value].dtt_flags & DTT_FL_USER ? + B_TRUE : B_FALSE); } else if ((dxp = dt_xlator_lookup(dtp, nnp, xnp, DT_XLATE_FUZZY)) != NULL || ( @@ -409,7 +413,8 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap) dnp->dn_ident->di_ctfp = xidp->di_ctfp; dnp->dn_ident->di_type = xidp->di_type; - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), + B_FALSE); } else { xyerror(D_ARGS_XLATOR, "translator for %s[%lld] from %s to %s " @@ -455,7 +460,7 @@ dt_idcook_regs(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap) idp->di_ctfp = dtt.dtt_ctfp; idp->di_type = dtt.dtt_type; - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } /*ARGSUSED*/ @@ -477,7 +482,7 @@ dt_idcook_type(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) idp->di_type = dtt.dtt_type; } - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } /*ARGSUSED*/ @@ -485,7 +490,7 @@ static void dt_idcook_thaw(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args) { if (idp->di_ctfp != NULL && idp->di_type != CTF_ERR) - dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type); + dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE); } static void diff --git a/usr/src/lib/libdtrace/common/dt_impl.h b/usr/src/lib/libdtrace/common/dt_impl.h index fc275e6805..e1e2c09822 100644 --- a/usr/src/lib/libdtrace/common/dt_impl.h +++ b/usr/src/lib/libdtrace/common/dt_impl.h @@ -133,6 +133,10 @@ typedef struct dt_module { GElf_Addr dm_bss_va; /* virtual address of BSS */ GElf_Xword dm_bss_size; /* size in bytes of BSS */ dt_idhash_t *dm_extern; /* external symbol definitions */ + pid_t dm_pid; /* pid for this module */ + uint_t dm_nctflibs; /* number of ctf children libraries */ + ctf_file_t **dm_libctfp; /* process library ctf pointers */ + char **dm_libctfn; /* names of process ctf containers */ } dt_module_t; #define DT_DM_LOADED 0x1 /* module symbol and type data is loaded */ @@ -513,7 +517,8 @@ enum { EDT_BADAGGVAR, /* invalid aggregation variable identifier */ EDT_OVERSION, /* client is requesting deprecated version */ EDT_ENABLING_ERR, /* failed to enable probe */ - EDT_NOPROBES /* no probes sites for declared provider */ + EDT_NOPROBES, /* no probes sites for declared provider */ + EDT_CANTLOAD /* failed to load a module */ }; /* diff --git a/usr/src/lib/libdtrace/common/dt_lex.l b/usr/src/lib/libdtrace/common/dt_lex.l index 5b2ad34d2e..5e990e2049 100644 --- a/usr/src/lib/libdtrace/common/dt_lex.l +++ b/usr/src/lib/libdtrace/common/dt_lex.l @@ -23,6 +23,10 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <string.h> #include <stdlib.h> @@ -60,13 +64,17 @@ static void unput(int); %} %e 1500 /* maximum nodes */ -%p 3700 /* maximum positions */ +%p 4900 /* maximum positions */ %n 600 /* maximum states */ +%a 3000 /* maximum transitions */ %s S0 S1 S2 S3 S4 RGX_AGG "@"[a-zA-Z_][0-9a-zA-Z_]* RGX_PSPEC [-$:a-zA-Z_.?*\\\[\]!][-$:0-9a-zA-Z_.`?*\\\[\]!]* +RGX_ALTIDENT [a-zA-Z_][0-9a-zA-Z_]* +RGX_LMID LM[0-9a-fA-F]+` +RGX_MOD_IDENT [a-zA-Z_`][0-9a-z.A-Z_`]*` RGX_IDENT [a-zA-Z_`][0-9a-zA-Z_`]* RGX_INT ([0-9]+|0[xX][0-9A-Fa-f]+)[uU]?[lL]?[lL]? RGX_FP ([0-9]+("."?)[0-9]*|"."[0-9]+)((e|E)("+"|-)?[0-9]+)?[fFlL]? @@ -136,6 +144,7 @@ if (yypcb->pcb_token != 0) { <S0>typedef return (DT_KEY_TYPEDEF); <S0>union return (DT_KEY_UNION); <S0>unsigned return (DT_KEY_UNSIGNED); +<S0>userland return (DT_KEY_USERLAND); <S0>void return (DT_KEY_VOID); <S0>volatile return (DT_KEY_VOLATILE); <S0>while return (DT_KEY_WHILE); @@ -314,7 +323,9 @@ if (yypcb->pcb_token != 0) { return (DT_TOK_INT); } -<S0>{RGX_IDENT} { +<S0>{RGX_IDENT} | +<S0>{RGX_MOD_IDENT}{RGX_IDENT} | +<S0>{RGX_MOD_IDENT} { return (id_or_type(yytext)); } diff --git a/usr/src/lib/libdtrace/common/dt_module.c b/usr/src/lib/libdtrace/common/dt_module.c index 1490f775c3..0288f329da 100644 --- a/usr/src/lib/libdtrace/common/dt_module.c +++ b/usr/src/lib/libdtrace/common/dt_module.c @@ -22,6 +22,9 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <sys/types.h> #include <sys/modctl.h> @@ -418,6 +421,9 @@ static const dt_modops_t dt_modops_64 = { dt_module_t * dt_module_create(dtrace_hdl_t *dtp, const char *name) { + long pid; + char *eptr; + dt_ident_t *idp; uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets; dt_module_t *dmp; @@ -441,6 +447,32 @@ dt_module_create(dtrace_hdl_t *dtp, const char *name) else dmp->dm_ops = &dt_modops_32; + /* + * Modules for userland processes are special. They always refer to a + * specific process and have a copy of their CTF data from a specific + * instant in time. Any dt_module_t that begins with 'pid' is a module + * for a specific process, much like how any probe description that + * begins with 'pid' is special. pid123 refers to process 123. A module + * that is just 'pid' refers specifically to pid$target. This is + * generally done as D does not currently allow for macros to be + * evaluated when working with types. + */ + if (strncmp(dmp->dm_name, "pid", 3) == 0) { + errno = 0; + if (dmp->dm_name[3] == '\0') { + idp = dt_idhash_lookup(dtp->dt_macros, "target"); + if (idp != NULL && idp->di_id != 0) + dmp->dm_pid = idp->di_id; + } else { + pid = strtol(dmp->dm_name + 3, &eptr, 10); + if (errno == 0 && *eptr == '\0') + dmp->dm_pid = (pid_t)pid; + else + dt_dprintf("encountered malformed pid " + "module: %s\n", dmp->dm_name); + } + } + return (dmp); } @@ -504,12 +536,169 @@ dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp) return (0); } +typedef struct dt_module_cb_arg { + struct ps_prochandle *dpa_proc; + dtrace_hdl_t *dpa_dtp; + dt_module_t *dpa_dmp; + uint_t dpa_count; +} dt_module_cb_arg_t; + +/* ARGSUSED */ +static int +dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj) +{ + ctf_file_t *fp; + dt_module_cb_arg_t *dcp = arg; + + /* Try to grab a ctf container if it exists */ + fp = Pname_to_ctf(dcp->dpa_proc, obj); + if (fp != NULL) + dcp->dpa_count++; + return (0); +} + +/* ARGSUSED */ +static int +dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj) +{ + ctf_file_t *fp; + char buf[MAXPATHLEN], *p; + dt_module_cb_arg_t *dcp = arg; + int count = dcp->dpa_count; + Lmid_t lmid; + + fp = Pname_to_ctf(dcp->dpa_proc, obj); + if (fp == NULL) + return (0); + fp = ctf_dup(fp); + if (fp == NULL) + return (0); + dcp->dpa_dmp->dm_libctfp[count] = fp; + /* + * While it'd be nice to simply use objname here, because of our prior + * actions we'll always get a resolved object name to its on disk file. + * Like the pid provider, we need to tell a bit of a lie here. The type + * that the user thinks of is in terms of the libraries they requested, + * eg. libc.so.1, they don't care about the fact that it's + * libc_hwcap.so.1. + */ + (void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf)); + if ((p = strrchr(buf, '/')) == NULL) + p = buf; + else + p++; + + /* + * If for some reason we can't find a link map id for this module, which + * would be really quite weird. We instead just say the link map id is + * zero. + */ + if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0) + lmid = 0; + + if (lmid == 0) + dcp->dpa_dmp->dm_libctfn[count] = strdup(p); + else + (void) asprintf(&dcp->dpa_dmp->dm_libctfn[count], + "LM%lx`%s", lmid, p); + if (dcp->dpa_dmp->dm_libctfn[count] == NULL) + return (1); + ctf_setspecific(fp, dcp->dpa_dmp); + dcp->dpa_count++; + return (0); +} + +/* + * We've been asked to load data that belongs to another process. As such we're + * going to pgrab it at this instant, load everything that we might ever care + * about, and then drive on. The reason for this is that the process that we're + * interested in might be changing. As long as we have grabbed it, then this + * can't be a problem for us. + * + * For now, we're actually going to punt on most things and just try to get CTF + * data, nothing else. Basically this is only useful as a source of type + * information, we can't go and do the stacktrace lookups, etc. + */ +static int +dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp) +{ + struct ps_prochandle *p; + dt_module_cb_arg_t arg; + + /* + * Note that on success we do not release this hold. We must hold this + * for our life time. + */ + p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE); + if (p == NULL) { + dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + dt_proc_lock(dtp, p); + + arg.dpa_proc = p; + arg.dpa_dtp = dtp; + arg.dpa_dmp = dmp; + arg.dpa_count = 0; + if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) { + dt_dprintf("failed to iterate objects\n"); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + + if (arg.dpa_count == 0) { + dt_dprintf("no ctf data present\n"); + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + + dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count); + if (dmp->dm_libctfp == NULL) { + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_NOMEM)); + } + bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count); + + dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count); + if (dmp->dm_libctfn == NULL) { + free(dmp->dm_libctfp); + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_NOMEM)); + } + bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count); + + dmp->dm_nctflibs = arg.dpa_count; + + arg.dpa_count = 0; + if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) { + dt_proc_unlock(dtp, p); + dt_module_unload(dtp, dmp); + dt_proc_release(dtp, p); + return (dt_set_errno(dtp, EDT_CANTLOAD)); + } + assert(arg.dpa_count == dmp->dm_nctflibs); + dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count, + (int)dmp->dm_pid); + + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); + dmp->dm_flags |= DT_DM_LOADED; + + return (0); +} + int dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp) { if (dmp->dm_flags & DT_DM_LOADED) return (0); /* module is already loaded */ + if (dmp->dm_pid != 0) + return (dt_module_load_proc(dtp, dmp)); + dmp->dm_ctdata.cts_name = ".SUNW_ctf"; dmp->dm_ctdata.cts_type = SHT_PROGBITS; dmp->dm_ctdata.cts_flags = 0; @@ -595,6 +784,14 @@ dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp) return (0); } +int +dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp) +{ + if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0) + return (1); + return (dt_module_getctf(dtp, dmp) != NULL); +} + ctf_file_t * dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp) { @@ -668,9 +865,22 @@ err: void dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp) { + int i; + ctf_close(dmp->dm_ctfp); dmp->dm_ctfp = NULL; + if (dmp->dm_libctfp != NULL) { + for (i = 0; i < dmp->dm_nctflibs; i++) { + ctf_close(dmp->dm_libctfp[i]); + free(dmp->dm_libctfn[i]); + } + free(dmp->dm_libctfp); + free(dmp->dm_libctfn); + dmp->dm_libctfp = NULL; + dmp->dm_nctflibs = 0; + } + bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t)); bzero(&dmp->dm_symtab, sizeof (ctf_sect_t)); bzero(&dmp->dm_strtab, sizeof (ctf_sect_t)); @@ -711,6 +921,8 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp) (void) elf_end(dmp->dm_elf); dmp->dm_elf = NULL; + dmp->dm_pid = 0; + dmp->dm_flags &= ~DT_DM_LOADED; } @@ -799,6 +1011,34 @@ dt_module_modelname(dt_module_t *dmp) return ("32-bit"); } +/* ARGSUSED */ +int +dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp) +{ + int i; + + for (i = 0; i < dmp->dm_nctflibs; i++) { + if (dmp->dm_libctfp[i] == fp) + return (i); + } + + return (-1); +} + +/* ARGSUSED */ +ctf_file_t * +dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name) +{ + int i; + + for (i = 0; i < dmp->dm_nctflibs; i++) { + if (strcmp(dmp->dm_libctfn[i], name) == 0) + return (dmp->dm_libctfp[i]); + } + + return (NULL); +} + /* * Update our module cache by adding an entry for the specified module 'name'. * We create the dt_module_t and populate it using /system/object/<name>/. @@ -1140,8 +1380,10 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, dt_module_t *dmp; int found = 0; ctf_id_t id; - uint_t n; + uint_t n, i; int justone; + ctf_file_t *fp; + char *buf, *p, *q; uint_t mask = 0; /* mask of dt_module flags to match */ uint_t bits = 0; /* flag bits that must be present */ @@ -1156,7 +1398,6 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, return (-1); /* dt_errno is set for us */ n = 1; justone = 1; - } else { if (object == DTRACE_OBJ_KMODS) mask = bits = DT_DM_KERNEL; @@ -1180,7 +1421,7 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, * module. If our search was scoped to only one module then * return immediately leaving dt_errno unmodified. */ - if (dt_module_getctf(dtp, dmp) == NULL) { + if (dt_module_hasctf(dtp, dmp) == 0) { if (justone) return (-1); continue; @@ -1192,13 +1433,38 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name, * 'tip' and keep going in the hope that we will locate the * underlying structure definition. Otherwise just return. */ - if ((id = ctf_lookup_by_name(dmp->dm_ctfp, name)) != CTF_ERR) { + if (dmp->dm_pid == 0) { + id = ctf_lookup_by_name(dmp->dm_ctfp, name); + fp = dmp->dm_ctfp; + } else { + if ((p = strchr(name, '`')) != NULL) { + buf = strdup(name); + if (buf == NULL) + return (dt_set_errno(dtp, EDT_NOMEM)); + p = strchr(buf, '`'); + if ((q = strchr(p + 1, '`')) != NULL) + p = q; + *p = '\0'; + fp = dt_module_getctflib(dtp, dmp, buf); + if (fp == NULL || (id = ctf_lookup_by_name(fp, + p + 1)) == CTF_ERR) + id = CTF_ERR; + free(buf); + } else { + for (i = 0; i < dmp->dm_nctflibs; i++) { + fp = dmp->dm_libctfp[i]; + id = ctf_lookup_by_name(fp, name); + if (id != CTF_ERR) + break; + } + } + } + if (id != CTF_ERR) { tip->dtt_object = dmp->dm_name; - tip->dtt_ctfp = dmp->dm_ctfp; + tip->dtt_ctfp = fp; tip->dtt_type = id; - - if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve( - dmp->dm_ctfp, id)) != CTF_K_FORWARD) + if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) != + CTF_K_FORWARD) return (0); found++; @@ -1220,6 +1486,7 @@ dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp, tip->dtt_object = NULL; tip->dtt_ctfp = NULL; tip->dtt_type = CTF_ERR; + tip->dtt_flags = 0; if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL) return (dt_set_errno(dtp, EDT_NOMOD)); diff --git a/usr/src/lib/libdtrace/common/dt_module.h b/usr/src/lib/libdtrace/common/dt_module.h index 8334a2bb81..d103e028e4 100644 --- a/usr/src/lib/libdtrace/common/dt_module.h +++ b/usr/src/lib/libdtrace/common/dt_module.h @@ -23,12 +23,13 @@ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #ifndef _DT_MODULE_H #define _DT_MODULE_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <dt_impl.h> #ifdef __cplusplus @@ -43,11 +44,16 @@ extern void dt_module_destroy(dtrace_hdl_t *, dt_module_t *); extern dt_module_t *dt_module_lookup_by_name(dtrace_hdl_t *, const char *); extern dt_module_t *dt_module_lookup_by_ctf(dtrace_hdl_t *, ctf_file_t *); +extern int dt_module_hasctf(dtrace_hdl_t *, dt_module_t *); extern ctf_file_t *dt_module_getctf(dtrace_hdl_t *, dt_module_t *); extern dt_ident_t *dt_module_extern(dtrace_hdl_t *, dt_module_t *, const char *, const dtrace_typeinfo_t *); extern const char *dt_module_modelname(dt_module_t *); +extern int dt_module_getlibid(dtrace_hdl_t *, dt_module_t *, + const ctf_file_t *); +extern ctf_file_t *dt_module_getctflib(dtrace_hdl_t *, dt_module_t *, + const char *); #ifdef __cplusplus } diff --git a/usr/src/lib/libdtrace/common/dt_open.c b/usr/src/lib/libdtrace/common/dt_open.c index f9c235df44..0f20f21697 100644 --- a/usr/src/lib/libdtrace/common/dt_open.c +++ b/usr/src/lib/libdtrace/common/dt_open.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -113,8 +113,9 @@ #define DT_VERS_1_9_1 DT_VERSION_NUMBER(1, 9, 1) #define DT_VERS_1_10 DT_VERSION_NUMBER(1, 10, 0) #define DT_VERS_1_11 DT_VERSION_NUMBER(1, 11, 0) -#define DT_VERS_LATEST DT_VERS_1_11 -#define DT_VERS_STRING "Sun D 1.11" +#define DT_VERS_1_12 DT_VERSION_NUMBER(1, 12, 0) +#define DT_VERS_LATEST DT_VERS_1_12 +#define DT_VERS_STRING "Sun D 1.12" const dt_version_t _dtrace_versions[] = { DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */ @@ -138,6 +139,7 @@ const dt_version_t _dtrace_versions[] = { DT_VERS_1_9_1, /* D API 1.9.1 */ DT_VERS_1_10, /* D API 1.10 */ DT_VERS_1_11, /* D API 1.11 */ + DT_VERS_1_12, /* D API 1.12 */ 0 }; diff --git a/usr/src/lib/libdtrace/common/dt_parser.c b/usr/src/lib/libdtrace/common/dt_parser.c index 6f837c4bed..753009f857 100644 --- a/usr/src/lib/libdtrace/common/dt_parser.c +++ b/usr/src/lib/libdtrace/common/dt_parser.c @@ -21,8 +21,8 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ /* @@ -192,7 +192,7 @@ dt_type_lookup(const char *s, dtrace_typeinfo_t *tip) { static const char delimiters[] = " \t\n\r\v\f*`"; dtrace_hdl_t *dtp = yypcb->pcb_hdl; - const char *p, *q, *end, *obj; + const char *p, *q, *r, *end, *obj; for (p = s, end = s + strlen(s); *p != '\0'; p = q) { while (isspace(*p)) @@ -220,8 +220,23 @@ dt_type_lookup(const char *s, dtrace_typeinfo_t *tip) bcopy(s, type, (size_t)(p - s)); bcopy(q + 1, type + (size_t)(p - s), strlen(q + 1) + 1); - if (strchr(q + 1, '`') != NULL) - return (dt_set_errno(dtp, EDT_BADSCOPE)); + /* + * There may be at most three delimeters. The second + * delimeter is usually used to distinguish the type + * within a given module, however, there could be a link + * map id on the scene in which case that delimeter + * would be the third. We determine presence of the lmid + * if it rouglhly meets the from LM[0-9] + */ + if ((r = strchr(q + 1, '`')) != NULL && + ((r = strchr(r + 1, '`')) != NULL)) { + if (strchr(r + 1, '`') != NULL) + return (dt_set_errno(dtp, + EDT_BADSCOPE)); + if (q[1] != 'L' || q[2] != 'M') + return (dt_set_errno(dtp, + EDT_BADSCOPE)); + } return (dtrace_lookup_by_type(dtp, object, type, tip)); } @@ -251,6 +266,7 @@ dt_type_pointer(dtrace_typeinfo_t *tip) ctf_file_t *ctfp = tip->dtt_ctfp; ctf_id_t type = tip->dtt_type; ctf_id_t base = ctf_type_resolve(ctfp, type); + uint_t bflags = tip->dtt_flags; dt_module_t *dmp; ctf_id_t ptr; @@ -282,6 +298,7 @@ dt_type_pointer(dtrace_typeinfo_t *tip) tip->dtt_object = dmp->dm_name; tip->dtt_ctfp = dmp->dm_ctfp; tip->dtt_type = ptr; + tip->dtt_flags = bflags; return (0); } @@ -385,7 +402,7 @@ void dt_node_promote(dt_node_t *lp, dt_node_t *rp, dt_node_t *dnp) { dt_type_promote(lp, rp, &dnp->dn_ctfp, &dnp->dn_type); - dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type); + dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type, B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); } @@ -654,7 +671,8 @@ dt_node_attr_assign(dt_node_t *dnp, dtrace_attribute_t attr) } void -dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type) +dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type, + boolean_t user) { ctf_id_t base = ctf_type_resolve(fp, type); uint_t kind = ctf_type_kind(fp, base); @@ -686,6 +704,9 @@ dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type) type == DT_DYN_TYPE(yypcb->pcb_hdl)) dnp->dn_flags |= DT_NF_REF; + if (user) + dnp->dn_flags |= DT_NF_USERLAND; + dnp->dn_flags |= DT_NF_COOKED; dnp->dn_ctfp = fp; dnp->dn_type = type; @@ -723,6 +744,7 @@ size_t dt_node_type_size(const dt_node_t *dnp) { ctf_id_t base; + dtrace_hdl_t *dtp = yypcb->pcb_hdl; if (dnp->dn_kind == DT_NODE_STRING) return (strlen(dnp->dn_string) + 1); @@ -735,6 +757,20 @@ dt_node_type_size(const dt_node_t *dnp) if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_FORWARD) return (0); + /* + * Here we have a 32-bit user pointer that is being used with a 64-bit + * kernel. When we're using it and its tagged as a userland reference -- + * then we need to keep it as a 32-bit pointer. However, if we are + * referring to it as a kernel address, eg. being used after a copyin() + * then we need to make sure that we actually return the kernel's size + * of a pointer, 8 bytes. + */ + if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_POINTER && + ctf_getmodel(dnp->dn_ctfp) == CTF_MODEL_ILP32 && + !(dnp->dn_flags & DT_NF_USERLAND) && + dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) + return (8); + return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type)); } @@ -1221,7 +1257,7 @@ dt_node_int(uintmax_t value) if (value <= dtp->dt_ints[i].did_limit) { dt_node_type_assign(dnp, dtp->dt_ints[i].did_ctfp, - dtp->dt_ints[i].did_type); + dtp->dt_ints[i].did_type, B_FALSE); /* * If a prefix character is present in macro text, add @@ -1256,7 +1292,7 @@ dt_node_string(char *string) dnp = dt_node_alloc(DT_NODE_STRING); dnp->dn_op = DT_TOK_STRING; dnp->dn_string = string; - dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp)); + dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp), B_FALSE); return (dnp); } @@ -1332,7 +1368,8 @@ dt_node_type(dt_decl_t *ddp) dnp = dt_node_alloc(DT_NODE_TYPE); dnp->dn_op = DT_TOK_IDENT; dnp->dn_string = name; - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, dtt.dtt_flags); if (dtt.dtt_ctfp == dtp->dt_cdefs->dm_ctfp || dtt.dtt_ctfp == dtp->dt_ddefs->dm_ctfp) @@ -1576,7 +1613,8 @@ dt_node_decl(void) bzero(&idn, sizeof (dt_node_t)); if (idp != NULL && idp->di_type != CTF_ERR) - dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type); + dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type, + B_FALSE); else if (idp != NULL) (void) dt_ident_cook(&idn, idp, NULL); @@ -1785,7 +1823,7 @@ dt_node_offsetof(dt_decl_t *ddp, char *s) } bzero(&dn, sizeof (dn)); - dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type); + dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type, B_FALSE); if (dn.dn_flags & DT_NF_BITFIELD) { xyerror(D_OFFSETOF_BITFIELD, @@ -1841,7 +1879,8 @@ dt_node_op1(int op, dt_node_t *cp) } dt_node_type_assign(cp, dtp->dt_ddefs->dm_ctfp, - ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t")); + ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"), + B_FALSE); cp->dn_kind = DT_NODE_INT; cp->dn_op = DT_TOK_INT; @@ -1919,17 +1958,17 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) case DT_TOK_LOR: dnp->dn_value = l || r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LXOR: dnp->dn_value = (l != 0) ^ (r != 0); dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LAND: dnp->dn_value = l && r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_BOR: dnp->dn_value = l | r; @@ -1946,12 +1985,12 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) case DT_TOK_EQU: dnp->dn_value = l == r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_NEQ: dnp->dn_value = l != r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LT: dt_node_promote(lp, rp, dnp); @@ -1960,7 +1999,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l < r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LE: dt_node_promote(lp, rp, dnp); @@ -1969,7 +2008,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l <= r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_GT: dt_node_promote(lp, rp, dnp); @@ -1978,7 +2017,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l > r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_GE: dt_node_promote(lp, rp, dnp); @@ -1987,7 +2026,7 @@ dt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) else dnp->dn_value = l >= r; dt_node_type_assign(dnp, - DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE); break; case DT_TOK_LSH: dnp->dn_value = l << r; @@ -2228,7 +2267,7 @@ dt_node_inline(dt_node_t *expr) * until we have successfully cooked the right-hand expression, below. */ dnp = dt_node_alloc(DT_NODE_INLINE); - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); dt_node_attr_assign(dnp, _dtrace_defattr); if (dt_node_is_void(dnp)) { @@ -2383,7 +2422,8 @@ dt_node_member(dt_decl_t *ddp, char *name, dt_node_t *expr) dnp->dn_membexpr = expr; if (ddp != NULL) - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags); return (dnp); } @@ -2414,10 +2454,10 @@ dt_node_xlator(dt_decl_t *ddp, dt_decl_t *sdp, char *name, dt_node_t *members) } bzero(&sn, sizeof (sn)); - dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type); + dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type, B_FALSE); bzero(&dn, sizeof (dn)); - dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type); + dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type, B_FALSE); if (dt_xlator_lookup(dtp, &sn, &dn, DT_XLATE_EXACT) != NULL) { xyerror(D_XLATE_REDECL, @@ -2663,7 +2703,7 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create) attr = dt_ident_cook(dnp, idp, NULL); else { dt_node_type_assign(dnp, - DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE); attr = idp->di_attr; } @@ -2739,7 +2779,8 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create) dnp->dn_ident = idp; dnp->dn_flags |= DT_NF_LVALUE; - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags); dt_node_attr_assign(dnp, _dtrace_symattr); if (uref) { @@ -2787,7 +2828,7 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create) attr = dt_ident_cook(dnp, idp, NULL); else { dt_node_type_assign(dnp, - DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE); attr = idp->di_attr; } @@ -2890,7 +2931,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) xyerror(D_TYPE_ERR, "failed to lookup int64_t\n"); dt_ident_type_assign(cp->dn_ident, dtt.dtt_ctfp, dtt.dtt_type); - dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags); } if (cp->dn_kind == DT_NODE_VAR) @@ -2907,7 +2949,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) dnp->dn_ident = &dxp->dx_souid; dt_node_type_assign(dnp, - dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type); + dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type, + cp->dn_flags & DT_NF_USERLAND); break; } @@ -2927,7 +2970,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) "cannot dereference non-pointer type\n"); } - dt_node_type_assign(dnp, cp->dn_ctfp, type); + dt_node_type_assign(dnp, cp->dn_ctfp, type, + cp->dn_flags & DT_NF_USERLAND); base = ctf_type_resolve(cp->dn_ctfp, type); kind = ctf_type_kind(cp->dn_ctfp, base); @@ -2984,7 +3028,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) xyerror(D_OP_SCALAR, "operator %s requires an operand " "of scalar type\n", opstr(dnp->dn_op)); } - dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), + B_FALSE); break; case DT_TOK_ADDROF: @@ -3017,10 +3062,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) dt_node_type_name(cp, n, sizeof (n))); } - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); - - if (cp->dn_flags & DT_NF_USERLAND) - dnp->dn_flags |= DT_NF_USERLAND; + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, + cp->dn_flags & DT_NF_USERLAND); break; case DT_TOK_SIZEOF: @@ -3035,7 +3078,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) } dt_node_type_assign(dnp, dtp->dt_ddefs->dm_ctfp, - ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t")); + ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"), + B_FALSE); break; case DT_TOK_STRINGOF: @@ -3045,7 +3089,8 @@ dt_cook_op1(dt_node_t *dnp, uint_t idflags) "cannot apply stringof to a value of type %s\n", dt_node_type_name(cp, n, sizeof (n))); } - dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp)); + dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp), + cp->dn_flags & DT_NF_USERLAND); break; case DT_TOK_PREINC: @@ -3238,7 +3283,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) "of scalar type\n", opstr(op)); } - dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); break; @@ -3282,7 +3328,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) rp->dn_op = DT_TOK_INT; rp->dn_value = (intmax_t)val; - dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type); + dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type, + B_FALSE); dt_node_attr_assign(rp, _dtrace_symattr); } @@ -3314,7 +3361,8 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) dt_node_type_name(rp, n2, sizeof (n2))); } - dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); + dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); break; @@ -3362,7 +3410,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) dt_node_type_name(rp, n2, sizeof (n2))); } - dt_node_type_assign(dnp, ctfp, type); + dt_node_type_assign(dnp, ctfp, type, B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); if (uref) @@ -3503,7 +3551,7 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags) */ if (lp->dn_kind == DT_NODE_VAR && dt_ident_unref(lp->dn_ident)) { - dt_node_type_assign(lp, ctfp, type); + dt_node_type_assign(lp, ctfp, type, B_FALSE); dt_ident_type_assign(lp->dn_ident, ctfp, type); if (uref) { @@ -3717,7 +3765,7 @@ asgn_common: type = ctf_type_resolve(ctfp, m.ctm_type); kind = ctf_type_kind(ctfp, type); - dt_node_type_assign(dnp, ctfp, m.ctm_type); + dt_node_type_assign(dnp, ctfp, m.ctm_type, B_FALSE); dt_node_attr_assign(dnp, lp->dn_attr); if (op == DT_TOK_PTR && (kind != CTF_K_ARRAY || @@ -3843,7 +3891,8 @@ asgn_common: } dnp->dn_ident = dt_xlator_ident(dxp, lp->dn_ctfp, lp->dn_type); - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(rp->dn_attr, dnp->dn_ident->di_attr)); break; @@ -4008,7 +4057,7 @@ dt_cook_op3(dt_node_t *dnp, uint_t idflags) "used in a conditional context\n"); } - dt_node_type_assign(dnp, ctfp, type); + dt_node_type_assign(dnp, ctfp, type, B_FALSE); dt_node_attr_assign(dnp, dt_attr_min(dnp->dn_expr->dn_attr, dt_attr_min(lp->dn_attr, rp->dn_attr))); @@ -4041,7 +4090,8 @@ dt_cook_aggregation(dt_node_t *dnp, uint_t idflags) dt_node_attr_assign(dnp, dt_ident_cook(dnp, dnp->dn_ident, &dnp->dn_aggtup)); } else { - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), + B_FALSE); dt_node_attr_assign(dnp, dnp->dn_ident->di_attr); } @@ -4243,7 +4293,8 @@ dt_cook_xlator(dt_node_t *dnp, uint_t idflags) } (void) dt_node_cook(mnp, DT_IDFLG_REF); - dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type); + dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type, + B_FALSE); attr = dt_attr_min(attr, mnp->dn_attr); if (dt_node_is_argcompat(mnp, mnp->dn_membexpr) == 0) { @@ -4262,7 +4313,7 @@ dt_cook_xlator(dt_node_t *dnp, uint_t idflags) dxp->dx_souid.di_attr = attr; dxp->dx_ptrid.di_attr = attr; - dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); + dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE); dt_node_attr_assign(dnp, _dtrace_defattr); return (dnp); @@ -4555,7 +4606,9 @@ dt_node_diftype(dtrace_hdl_t *dtp, const dt_node_t *dnp, dtrace_diftype_t *tp) ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type)); } - tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? DIF_TF_BYREF : 0; + tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? + (dnp->dn_flags & DT_NF_USERLAND) ? DIF_TF_BYUREF : + DIF_TF_BYREF : 0; tp->dtdt_pad = 0; tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type); } diff --git a/usr/src/lib/libdtrace/common/dt_parser.h b/usr/src/lib/libdtrace/common/dt_parser.h index 6064efb2e6..38f21c9f2e 100644 --- a/usr/src/lib/libdtrace/common/dt_parser.h +++ b/usr/src/lib/libdtrace/common/dt_parser.h @@ -22,12 +22,14 @@ * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #ifndef _DT_PARSER_H #define _DT_PARSER_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/dtrace.h> @@ -223,7 +225,7 @@ extern void dt_node_list_free(dt_node_t **); extern void dt_node_link_free(dt_node_t **); extern void dt_node_attr_assign(dt_node_t *, dtrace_attribute_t); -extern void dt_node_type_assign(dt_node_t *, ctf_file_t *, ctf_id_t); +extern void dt_node_type_assign(dt_node_t *, ctf_file_t *, ctf_id_t, boolean_t); extern void dt_node_type_propagate(const dt_node_t *, dt_node_t *); extern const char *dt_node_type_name(const dt_node_t *, char *, size_t); extern size_t dt_node_type_size(const dt_node_t *); diff --git a/usr/src/lib/libdtrace/common/dt_pid.c b/usr/src/lib/libdtrace/common/dt_pid.c index 241805154a..881db806f4 100644 --- a/usr/src/lib/libdtrace/common/dt_pid.c +++ b/usr/src/lib/libdtrace/common/dt_pid.c @@ -23,6 +23,9 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <assert.h> #include <strings.h> @@ -33,11 +36,13 @@ #include <alloca.h> #include <libgen.h> #include <stddef.h> +#include <sys/sysmacros.h> #include <dt_impl.h> #include <dt_program.h> #include <dt_pid.h> #include <dt_string.h> +#include <dt_module.h> typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; @@ -755,3 +760,162 @@ dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr) return (ret); } + +/* + * libdtrace has a backroom deal with us to ask us for type information on + * behalf of pid provider probes when fasttrap doesn't return any type + * information. Instead we'll look up the module and see if there is type + * information available. However, if there is no type information available due + * to a lack of CTF data, then we want to make sure that DTrace still carries on + * in face of that. As such we don't have a meaningful exit code about failure. + * We emit information about why we failed to the dtrace debug log so someone + * can figure it out by asking nicely for DTRACE_DEBUG. + */ +void +dt_pid_get_types(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, + dtrace_argdesc_t *adp, int *nargs) +{ + dt_module_t *dmp; + ctf_file_t *fp; + ctf_funcinfo_t f; + ctf_id_t argv[32]; + GElf_Sym sym; + prsyminfo_t si; + struct ps_prochandle *p; + int i, args; + char buf[DTRACE_ARGTYPELEN]; + const char *mptr; + char *eptr; + int ret = 0; + int argc = sizeof (argv) / sizeof (ctf_id_t); + Lmid_t lmid; + + /* Set up a potential outcome */ + args = *nargs; + *nargs = 0; + + /* + * If we don't have an entry or return probe then we can just stop right + * now as we don't have arguments for offset probes. + */ + if (strcmp(pdp->dtpd_name, "entry") != 0 && + strcmp(pdp->dtpd_name, "return") != 0) + return; + + dmp = dt_module_create(dtp, pdp->dtpd_provider); + if (dmp == NULL) { + dt_dprintf("failed to find module for %s\n", + pdp->dtpd_provider); + return; + } + if (dt_module_load(dtp, dmp) != 0) { + dt_dprintf("failed to load module for %s\n", + pdp->dtpd_provider); + return; + } + + /* + * We may be working with a module that doesn't have ctf. If that's the + * case then we just return now and move on with life. + */ + fp = dt_module_getctflib(dtp, dmp, pdp->dtpd_mod); + if (fp == NULL) { + dt_dprintf("no ctf container for %s\n", + pdp->dtpd_mod); + return; + } + p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE); + if (p == NULL) { + dt_dprintf("failed to grab pid\n"); + return; + } + dt_proc_lock(dtp, p); + + /* + * Check to see if the D module has a link map ID and separate that out + * for properly interrogating libproc. + */ + if ((mptr = strchr(pdp->dtpd_mod, '`')) != NULL) { + if (strlen(pdp->dtpd_mod) < 3) { + dt_dprintf("found weird modname with linkmap, " + "aborting: %s\n", pdp->dtpd_mod); + goto out; + } + if (pdp->dtpd_mod[0] != 'L' || pdp->dtpd_mod[1] != 'M') { + dt_dprintf("missing leading 'LM', " + "aborting: %s\n", pdp->dtpd_mod); + goto out; + } + errno = 0; + lmid = strtol(pdp->dtpd_mod + 2, &eptr, 16); + if (errno == ERANGE || eptr != mptr) { + dt_dprintf("failed to parse out lmid, aborting: %s\n", + pdp->dtpd_mod); + goto out; + } + mptr++; + } else { + mptr = pdp->dtpd_mod; + lmid = 0; + } + + if (Pxlookup_by_name(p, lmid, mptr, pdp->dtpd_func, + &sym, &si) != 0) { + dt_dprintf("failed to find function %s in %s`%s\n", + pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod); + goto out; + } + if (ctf_func_info(fp, si.prs_id, &f) == CTF_ERR) { + dt_dprintf("failed to get ctf information for %s in %s`%s\n", + pdp->dtpd_func, pdp->dtpd_provider, pdp->dtpd_mod); + goto out; + } + + (void) snprintf(buf, sizeof (buf), "%s`%s", pdp->dtpd_provider, + pdp->dtpd_mod); + + if (strcmp(pdp->dtpd_name, "return") == 0) { + if (args < 2) + goto out; + + bzero(adp, sizeof (dtrace_argdesc_t)); + adp->dtargd_ndx = 0; + adp->dtargd_id = pdp->dtpd_id; + adp->dtargd_mapping = adp->dtargd_ndx; + /* + * We explicitly leave out the library here, we only care that + * it is some int. We are assuming that there is no ctf + * container in here that is lying about what an int is. + */ + (void) snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN, + "user %s`%s", pdp->dtpd_provider, "int"); + adp++; + bzero(adp, sizeof (dtrace_argdesc_t)); + adp->dtargd_ndx = 1; + adp->dtargd_id = pdp->dtpd_id; + adp->dtargd_mapping = adp->dtargd_ndx; + ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN, + "userland "); + (void) ctf_type_qname(fp, f.ctc_return, adp->dtargd_native + + ret, DTRACE_ARGTYPELEN - ret, buf); + *nargs = 2; + } else { + if (ctf_func_args(fp, si.prs_id, argc, argv) == CTF_ERR) + goto out; + + *nargs = MIN(args, f.ctc_argc); + for (i = 0; i < *nargs; i++, adp++) { + bzero(adp, sizeof (dtrace_argdesc_t)); + adp->dtargd_ndx = i; + adp->dtargd_id = pdp->dtpd_id; + adp->dtargd_mapping = adp->dtargd_ndx; + ret = snprintf(adp->dtargd_native, DTRACE_ARGTYPELEN, + "userland "); + (void) ctf_type_qname(fp, argv[i], adp->dtargd_native + + ret, DTRACE_ARGTYPELEN - ret, buf); + } + } +out: + dt_proc_unlock(dtp, p); + dt_proc_release(dtp, p); +} diff --git a/usr/src/lib/libdtrace/common/dt_pid.h b/usr/src/lib/libdtrace/common/dt_pid.h index 886e33d833..4bf39c8645 100644 --- a/usr/src/lib/libdtrace/common/dt_pid.h +++ b/usr/src/lib/libdtrace/common/dt_pid.h @@ -24,12 +24,13 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #ifndef _DT_PID_H #define _DT_PID_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libproc.h> #include <sys/fasttrap.h> #include <dt_impl.h> @@ -57,6 +58,9 @@ extern int dt_pid_create_offset_probe(struct ps_prochandle *, dtrace_hdl_t *, extern int dt_pid_create_glob_offset_probes(struct ps_prochandle *, dtrace_hdl_t *, fasttrap_probe_spec_t *, const GElf_Sym *, const char *); +extern void dt_pid_get_types(dtrace_hdl_t *, const dtrace_probedesc_t *, + dtrace_argdesc_t *, int *); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libdtrace/common/dt_print.c b/usr/src/lib/libdtrace/common/dt_print.c index e258f9ac54..b71eddbf9d 100644 --- a/usr/src/lib/libdtrace/common/dt_print.c +++ b/usr/src/lib/libdtrace/common/dt_print.c @@ -649,12 +649,16 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename, dt_printarg_t pa; ctf_id_t id; dt_module_t *dmp; + ctf_file_t *ctfp; + int libid; /* * Split the fully-qualified type ID (module`id). This should * always be the format, but if for some reason we don't find the * expected value, return 0 to fall back to the generic trace() - * behavior. + * behavior. In the case of userland CTF modules this will actually be + * of the format (module`lib`id). This is due to the fact that those + * modules have multiple CTF containers which `lib` identifies. */ for (s = typename; *s != '\0' && *s != '`'; s++) ; @@ -665,6 +669,20 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename, object = alloca(s - typename + 1); bcopy(typename, object, s - typename); object[s - typename] = '\0'; + dmp = dt_module_lookup_by_name(dtp, object); + if (dmp == NULL) + return (0); + + if (dmp->dm_pid != 0) { + libid = atoi(s + 1); + s = strchr(s + 1, '`'); + if (s == NULL || libid > dmp->dm_nctflibs) + return (0); + ctfp = dmp->dm_libctfp[libid]; + } else { + ctfp = dt_module_getctf(dtp, dmp); + } + id = atoi(s + 1); /* @@ -672,16 +690,13 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename, * wrong and we can't resolve the ID, bail out and let trace() do the * work. */ - dmp = dt_module_lookup_by_name(dtp, object); - if (dmp == NULL || ctf_type_kind(dt_module_getctf(dtp, dmp), - id) == CTF_ERR) { + if (ctfp == NULL || ctf_type_kind(ctfp, id) == CTF_ERR) return (0); - } /* setup the print structure and kick off the main print routine */ pa.pa_dtp = dtp; pa.pa_addr = addr; - pa.pa_ctfp = dt_module_getctf(dtp, dmp); + pa.pa_ctfp = ctfp; pa.pa_nest = 0; pa.pa_depth = 0; pa.pa_file = fp; diff --git a/usr/src/lib/libdtrace/common/dt_printf.c b/usr/src/lib/libdtrace/common/dt_printf.c index 8d96bd4c71..7bd91b9f48 100644 --- a/usr/src/lib/libdtrace/common/dt_printf.c +++ b/usr/src/lib/libdtrace/common/dt_printf.c @@ -21,8 +21,8 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include <sys/sysmacros.h> @@ -1048,7 +1048,7 @@ dt_printf_validate(dt_pfargv_t *pfv, uint_t flags, xyerror(D_TYPE_ERR, "failed to lookup agg type %s\n", aggtype); bzero(&aggnode, sizeof (aggnode)); - dt_node_type_assign(&aggnode, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(&aggnode, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); for (i = 0, j = 0; i < pfv->pfv_argc; i++, pfd = pfd->pfd_next) { const dt_pfconv_t *pfc = pfd->pfd_conv; diff --git a/usr/src/lib/libdtrace/common/dt_provider.c b/usr/src/lib/libdtrace/common/dt_provider.c index 86e1204e63..ef4b4470d5 100644 --- a/usr/src/lib/libdtrace/common/dt_provider.c +++ b/usr/src/lib/libdtrace/common/dt_provider.c @@ -23,8 +23,9 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <sys/types.h> #include <sys/sysmacros.h> @@ -41,6 +42,8 @@ #include <dt_module.h> #include <dt_string.h> #include <dt_list.h> +#include <dt_pid.h> +#include <dtrace.h> static dt_provider_t * dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h) @@ -269,6 +272,21 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) nc++; /* + * The pid provider believes in giving the kernel a break. No reason to + * give the kernel all the ctf containers that we're keeping ourselves + * just to get it back from it. So if we're coming from a pid provider + * probe and the kernel gave us no argument information we'll get some + * here. If for some crazy reason the kernel knows about our userland + * types then we just ignore this. + */ + if (xc == 0 && nc == 0 && + strncmp(pvp->pv_desc.dtvd_name, "pid", 3) == 0) { + nc = adc; + dt_pid_get_types(dtp, pdp, adv, &nc); + xc = nc; + } + + /* * Now that we have discovered the number of native and translated * arguments from the argument descriptions, allocate a new probe ident * and corresponding dt_probe_t and hash it into the provider. @@ -314,7 +332,8 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) dtt.dtt_type = CTF_ERR; } else { dt_node_type_assign(prp->pr_nargv[adp->dtargd_mapping], - dtt.dtt_ctfp, dtt.dtt_type); + dtt.dtt_ctfp, dtt.dtt_type, + dtt.dtt_flags & DTT_FL_USER ? B_TRUE : B_FALSE); } if (dtt.dtt_type != CTF_ERR && (adp->dtargd_xlate[0] == '\0' || @@ -333,7 +352,7 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) dtt.dtt_type = CTF_ERR; } else { dt_node_type_assign(prp->pr_xargv[i], - dtt.dtt_ctfp, dtt.dtt_type); + dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); } prp->pr_mapping[i] = adp->dtargd_mapping; @@ -634,7 +653,7 @@ dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp) bzero(dnp, sizeof (dt_node_t)); dnp->dn_kind = DT_NODE_TYPE; - dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); + dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); dt_node_attr_assign(dnp, _dtrace_defattr); return (dnp); diff --git a/usr/src/lib/libdtrace/common/dt_xlator.c b/usr/src/lib/libdtrace/common/dt_xlator.c index 7ac0cc42f5..74bd487861 100644 --- a/usr/src/lib/libdtrace/common/dt_xlator.c +++ b/usr/src/lib/libdtrace/common/dt_xlator.c @@ -23,8 +23,10 @@ * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #include <strings.h> #include <assert.h> @@ -69,7 +71,7 @@ dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg) enp->dn_op = DT_TOK_XLATE; enp->dn_xlator = dxp; enp->dn_xmember = mnp; - dt_node_type_assign(enp, dxp->dx_dst_ctfp, type); + dt_node_type_assign(enp, dxp->dx_dst_ctfp, type, B_FALSE); /* * For the member itself, we use a DT_NODE_MEMBER as usual with the @@ -83,7 +85,7 @@ dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg) mnp->dn_membname = strdup(name); mnp->dn_membexpr = enp; - dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type); + dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type, B_FALSE); if (mnp->dn_membname == NULL) return (dt_set_errno(dtp, EDT_NOMEM)); @@ -318,7 +320,8 @@ dt_xlator_lookup(dtrace_hdl_t *dtp, dt_node_t *src, dt_node_t *dst, int flags) for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL; dxp = dt_list_next(dxp)) { - dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type); + dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type, + B_FALSE); if (ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base, dst_ctfp, dst_base) && dt_node_is_argcompat(src, &xn)) goto out; diff --git a/usr/src/lib/libdtrace/common/dtrace.h b/usr/src/lib/libdtrace/common/dtrace.h index 87df1ca440..3fd8ce8940 100644 --- a/usr/src/lib/libdtrace/common/dtrace.h +++ b/usr/src/lib/libdtrace/common/dtrace.h @@ -25,7 +25,8 @@ */ /* - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #ifndef _DTRACE_H @@ -491,8 +492,11 @@ typedef struct dtrace_typeinfo { const char *dtt_object; /* object containing type */ ctf_file_t *dtt_ctfp; /* CTF container handle */ ctf_id_t dtt_type; /* CTF type identifier */ + uint_t dtt_flags; /* Misc. flags */ } dtrace_typeinfo_t; +#define DTT_FL_USER 0x1 /* user type */ + extern int dtrace_lookup_by_type(dtrace_hdl_t *, const char *, const char *, dtrace_typeinfo_t *); diff --git a/usr/src/pkg/manifests/system-dtrace-tests.mf b/usr/src/pkg/manifests/system-dtrace-tests.mf index a71654ab26..27362d7658 100644 --- a/usr/src/pkg/manifests/system-dtrace-tests.mf +++ b/usr/src/pkg/manifests/system-dtrace-tests.mf @@ -119,6 +119,7 @@ dir path=opt/SUNWdtrt/tst/common/tracemem dir path=opt/SUNWdtrt/tst/common/translators dir path=opt/SUNWdtrt/tst/common/typedef dir path=opt/SUNWdtrt/tst/common/types +dir path=opt/SUNWdtrt/tst/common/uctf dir path=opt/SUNWdtrt/tst/common/union dir path=opt/SUNWdtrt/tst/common/usdt dir path=opt/SUNWdtrt/tst/common/ustack @@ -1977,6 +1978,30 @@ file path=opt/SUNWdtrt/tst/common/types/tst.stringconstants.d mode=0444 file path=opt/SUNWdtrt/tst/common/types/tst.struct.d mode=0444 file path=opt/SUNWdtrt/tst/common/types/tst.typedef.d mode=0444 file path=opt/SUNWdtrt/tst/common/types/tst.unaryop.d mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/err.invalidpid.d mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/err.invalidpid2.d mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/err.invalidpid3.d mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/err.invalidtype.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/err.invalidtype2.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/err.user64mode.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.aouttype.exe mode=0555 +file path=opt/SUNWdtrt/tst/common/uctf/tst.aouttype.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.chasestrings.exe mode=0555 +file path=opt/SUNWdtrt/tst/common/uctf/tst.chasestrings.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.chasestrings.ksh.out mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.libtype.exe mode=0555 +file path=opt/SUNWdtrt/tst/common/uctf/tst.libtype.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.linkmap.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.pidprint.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.pidprinttarg.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.printtype.exe mode=0555 +file path=opt/SUNWdtrt/tst/common/uctf/tst.printtype.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.printtype.ksh.out mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.printtypetarg.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.userlandkey.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.userlandkey.ksh.out mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.userstrings.ksh mode=0444 +file path=opt/SUNWdtrt/tst/common/uctf/tst.userstrings.ksh.out mode=0444 file path=opt/SUNWdtrt/tst/common/union/err.D_ADDROF_VAR.UnionPointer.d \ mode=0444 file path=opt/SUNWdtrt/tst/common/union/err.D_DECL_COMBO.UnionWithoutColon.d \ diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c index 3363a0dc55..afff7be41a 100644 --- a/usr/src/uts/common/dtrace/dtrace.c +++ b/usr/src/uts/common/dtrace/dtrace.c @@ -5719,32 +5719,46 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[rd] = dtrace_load64(regs[r1]); break; case DIF_OP_ULDSB: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = (int8_t) dtrace_fuword8((void *)(uintptr_t)regs[r1]); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); break; case DIF_OP_ULDSH: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = (int16_t) dtrace_fuword16((void *)(uintptr_t)regs[r1]); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); break; case DIF_OP_ULDSW: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = (int32_t) dtrace_fuword32((void *)(uintptr_t)regs[r1]); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); break; case DIF_OP_ULDUB: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = dtrace_fuword8((void *)(uintptr_t)regs[r1]); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); break; case DIF_OP_ULDUH: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = dtrace_fuword16((void *)(uintptr_t)regs[r1]); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); break; case DIF_OP_ULDUW: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = dtrace_fuword32((void *)(uintptr_t)regs[r1]); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); break; case DIF_OP_ULDX: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); regs[rd] = dtrace_fuword64((void *)(uintptr_t)regs[r1]); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); break; case DIF_OP_RET: rval = regs[rd]; @@ -6552,6 +6566,63 @@ out: mstate->dtms_scratch_ptr = old; } +static void +dtrace_store_by_ref(dtrace_difo_t *dp, caddr_t tomax, size_t size, + size_t *valoffsp, uint64_t *valp, uint64_t end, int intuple, int dtkind) +{ + volatile uint16_t *flags; + uint64_t val = *valp; + size_t valoffs = *valoffsp; + + flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + ASSERT(dtkind == DIF_TF_BYREF || dtkind == DIF_TF_BYUREF); + + /* + * If this is a string, we're going to only load until we find the zero + * byte -- after which we'll store zero bytes. + */ + if (dp->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING) { + char c = '\0' + 1; + size_t s; + + for (s = 0; s < size; s++) { + if (c != '\0' && dtkind == DIF_TF_BYREF) { + c = dtrace_load8(val++); + } else if (c != '\0' && dtkind == DIF_TF_BYUREF) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); + c = dtrace_fuword8((void *)(uintptr_t)val++); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); + if (*flags & CPU_DTRACE_FAULT) + break; + } + + DTRACE_STORE(uint8_t, tomax, valoffs++, c); + + if (c == '\0' && intuple) + break; + } + } else { + uint8_t c; + while (valoffs < end) { + if (dtkind == DIF_TF_BYREF) { + c = dtrace_load8(val++); + } else if (dtkind == DIF_TF_BYUREF) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); + c = dtrace_fuword8((void *)(uintptr_t)val++); + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); + if (*flags & CPU_DTRACE_FAULT) + break; + } + + DTRACE_STORE(uint8_t, tomax, + valoffs++, c); + } + } + + *valp = val; + *valoffsp = valoffs; +} + /* * If you're looking for the epicenter of DTrace, you just found it. This * is the function called by the provider to fire a probe -- from which all @@ -7043,7 +7114,8 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, ASSERT(0); } - if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF) { + if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF || + dp->dtdo_rtype.dtdt_flags & DIF_TF_BYUREF) { uintptr_t end = valoffs + size; if (tracememsize != 0 && @@ -7052,40 +7124,15 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, tracememsize = 0; } - if (!dtrace_vcanload((void *)(uintptr_t)val, + if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF && + !dtrace_vcanload((void *)(uintptr_t)val, &dp->dtdo_rtype, &mstate, vstate)) continue; - /* - * If this is a string, we're going to only - * load until we find the zero byte -- after - * which we'll store zero bytes. - */ - if (dp->dtdo_rtype.dtdt_kind == - DIF_TYPE_STRING) { - char c = '\0' + 1; - int intuple = act->dta_intuple; - size_t s; - - for (s = 0; s < size; s++) { - if (c != '\0') - c = dtrace_load8(val++); - - DTRACE_STORE(uint8_t, tomax, - valoffs++, c); - - if (c == '\0' && intuple) - break; - } - - continue; - } - - while (valoffs < end) { - DTRACE_STORE(uint8_t, tomax, valoffs++, - dtrace_load8(val++)); - } - + dtrace_store_by_ref(dp, tomax, size, &valoffs, + &val, end, act->dta_intuple, + dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF ? + DIF_TF_BYREF: DIF_TF_BYUREF); continue; } @@ -9203,7 +9250,7 @@ dtrace_difo_validate(dtrace_difo_t *dp, dtrace_vstate_t *vstate, uint_t nregs, "expected 'ret' as last DIF instruction\n"); } - if (!(dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF)) { + if (!(dp->dtdo_rtype.dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF))) { /* * If we're not returning by reference, the size must be either * 0 or the size of one of the base types. diff --git a/usr/src/uts/common/sys/ctf_api.h b/usr/src/uts/common/sys/ctf_api.h index c08acf1950..04d73c3181 100644 --- a/usr/src/uts/common/sys/ctf_api.h +++ b/usr/src/uts/common/sys/ctf_api.h @@ -24,7 +24,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ /* @@ -151,6 +151,7 @@ extern ctf_file_t *ctf_bufopen(const ctf_sect_t *, const ctf_sect_t *, extern ctf_file_t *ctf_fdopen(int, int *); extern ctf_file_t *ctf_open(const char *, int *); extern ctf_file_t *ctf_create(int *); +extern ctf_file_t *ctf_dup(ctf_file_t *); extern void ctf_close(ctf_file_t *); extern ctf_file_t *ctf_parent_file(ctf_file_t *); @@ -176,6 +177,8 @@ extern ctf_id_t ctf_lookup_by_symbol(ctf_file_t *, ulong_t); extern ctf_id_t ctf_type_resolve(ctf_file_t *, ctf_id_t); extern ssize_t ctf_type_lname(ctf_file_t *, ctf_id_t, char *, size_t); extern char *ctf_type_name(ctf_file_t *, ctf_id_t, char *, size_t); +extern char *ctf_type_qname(ctf_file_t *, ctf_id_t, char *, size_t, + const char *); extern ssize_t ctf_type_size(ctf_file_t *, ctf_id_t); extern ssize_t ctf_type_align(ctf_file_t *, ctf_id_t); extern int ctf_type_kind(ctf_file_t *, ctf_id_t); diff --git a/usr/src/uts/common/sys/dtrace.h b/usr/src/uts/common/sys/dtrace.h index 005bd62ebd..9089de4cec 100644 --- a/usr/src/uts/common/sys/dtrace.h +++ b/usr/src/uts/common/sys/dtrace.h @@ -25,8 +25,8 @@ */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #ifndef _SYS_DTRACE_H @@ -354,6 +354,7 @@ typedef struct dtrace_diftype { #define DIF_TYPE_STRING 1 /* type is a D string */ #define DIF_TF_BYREF 0x1 /* type is passed by reference */ +#define DIF_TF_BYUREF 0x2 /* user type is passed by reference */ /* * A DTrace Intermediate Format variable record is used to describe each of the |