aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib/opensolaris')
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.120
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/dtrace.c9
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/kinst/tst.basic.ksh48
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh2
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d12
-rw-r--r--cddl/contrib/opensolaris/cmd/lockstat/lockstat.c6
-rw-r--r--cddl/contrib/opensolaris/cmd/lockstat/sym.c21
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c16
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h1
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c142
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c30
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c14
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c2
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c3
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c295
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h6
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c29
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h3
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c75
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/memory.c14
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/memory.h1
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/utils.c24
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/common/utils.h2
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c13
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/dump/dump.c2
25 files changed, 312 insertions, 478 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
index 8724b27f4cbb..42367b99b786 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1
@@ -20,7 +20,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 7, 2021
+.Dd February 24, 2023
.Dt DTRACE 1
.Os
.Sh NAME
@@ -29,7 +29,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl 32 | Fl 64
-.Op Fl aACeFGhHlqSvVwZ
+.Op Fl aACdeFGhHlqSvVwZ
.Op Fl b Ar bufsz
.Op Fl c Ar cmd
.Op Fl D Ar name Op Ns = Ns value
@@ -195,6 +195,12 @@ option.
For a description of the set of tokens defined by the D compiler when invoking
the C preprocessor, see
.Fl X .
+.It Fl d
+Dump the D script to standard output, after syntactic transformations have been
+applied.
+For example, if-statements in D are implemented using such transformations: a
+conditional clause in a probe body is replaced at compile-time by a separate
+probe predicated on the original condition.
.It Fl D Ar name Op Ns = Ns value
Define
.Ar name
@@ -803,11 +809,6 @@ failed or that the specified request could not be satisfied.
.It 2
Invalid command line options or arguments were specified.
.El
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Fx 7.1 .
.Sh SEE ALSO
.Xr cpp 1 ,
.Xr elf 5 ,
@@ -815,3 +816,8 @@ utility first appeared in
.Rs
.%T Solaris Dynamic Tracing Guide
.Re
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 7.1 .
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
index 06eff2055c17..cdc476a43b08 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
+++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
@@ -77,7 +77,7 @@ typedef struct dtrace_cmd {
#define E_USAGE 2
static const char DTRACE_OPTSTR[] =
- "3:6:aAb:Bc:CD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
+ "3:6:aAb:Bc:CdD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
static char **g_argv;
static int g_argc;
@@ -130,7 +130,7 @@ usage(FILE *fp)
{
static const char predact[] = "[[ predicate ] action ]";
- (void) fprintf(fp, "Usage: %s [-32|-64] [-aACeFGhHlqSvVwZ] "
+ (void) fprintf(fp, "Usage: %s [-32|-64] [-aACdeFGhHlqSvVwZ] "
"[-b bufsz] [-c cmd] [-D name[=def]]\n\t[-I path] [-L path] "
"[-o output] [-p pid] [-s script] [-U name]\n\t"
"[-x opt[=val]] [-X a|c|s|t]\n\n"
@@ -152,6 +152,7 @@ usage(FILE *fp)
"\t-b set trace buffer size\n"
"\t-c run specified command and exit upon its completion\n"
"\t-C run cpp(1) preprocessor on script files\n"
+ "\t-d dump script after syntactic transformations\n"
"\t-D define symbol when invoking preprocessor\n"
"\t-e exit after compiling request but prior to enabling probes\n"
"\t-f enable or list probes matching the specified function name\n"
@@ -1559,6 +1560,10 @@ main(int argc, char *argv[])
g_cflags |= DTRACE_C_CPP;
break;
+ case 'd':
+ g_cflags |= DTRACE_C_SUGAR;
+ break;
+
case 'D':
if (dtrace_setopt(g_dtp, "define", optarg) != 0)
dfatal("failed to set -D %s", optarg);
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/kinst/tst.basic.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/kinst/tst.basic.ksh
new file mode 100644
index 000000000000..3005da74c895
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/kinst/tst.basic.ksh
@@ -0,0 +1,48 @@
+#!/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) 2022 Mark Johnston <markj@FreeBSD.org>
+#
+
+script()
+{
+ $dtrace -q -s /dev/stdin <<__EOF__
+kinst::vm_fault: {}
+kinst::amd64_syscall: {}
+kinst::exit1: {}
+kinst::spinlock_enter: {}
+kinst::memcpy: {}
+
+tick-10s {exit(0);}
+__EOF__
+}
+
+spin()
+{
+ while true; do
+ ls -la / >/dev/null 2>&1
+ done
+}
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+
+spin &
+child=$!
+
+script
+exit $?
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh
index 59094e3da37f..1c23b2a0b9e0 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exitcore.ksh
@@ -61,7 +61,7 @@ EOF
sleeper()
{
while true; do
- $longsleep &
+ limits -c unlimited $longsleep &
/bin/sleep 1
kill -SEGV $!
done
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d
index cd4715319913..c6bfff2181e6 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/translators/tst.OutputAliasTrans.d
@@ -37,23 +37,23 @@
#pragma D option quiet
-struct input_struct {
+struct dtrace_input_struct {
int ii;
char ic;
};
-struct output_struct {
+struct dtrace_output_struct {
int oi;
char oc;
};
-typedef struct output_struct output_t;
+typedef struct dtrace_output_struct dtrace_output_t;
-translator output_t < struct input_struct *ivar >
+translator dtrace_output_t < struct dtrace_input_struct *ivar >
{
- oi = ((struct input_struct *) ivar)->ii;
- oc = ((struct input_struct *) ivar)->ic;
+ oi = ((struct dtrace_input_struct *) ivar)->ii;
+ oc = ((struct dtrace_input_struct *) ivar)->ic;
};
BEGIN
diff --git a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c
index a7378980bc56..2cbad3442efb 100644
--- a/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c
+++ b/cddl/contrib/opensolaris/cmd/lockstat/lockstat.c
@@ -606,14 +606,14 @@ predicate_add(char **pred, char *what, char *cmp, uintptr_t value)
if (*pred[0] != '\0') {
if (cmp != NULL) {
- (void) sprintf(new, "(%s) && (%s %s 0x%p)",
+ (void) sprintf(new, "(%s) && (%s %s %p)",
*pred, what, cmp, (void *)value);
} else {
(void) sprintf(new, "(%s) && (%s)", *pred, what);
}
} else {
if (cmp != NULL) {
- (void) sprintf(new, "%s %s 0x%p",
+ (void) sprintf(new, "%s %s %p",
what, cmp, (void *)value);
} else {
(void) sprintf(new, "%s", what);
@@ -632,7 +632,7 @@ predicate_destroy(char **pred)
}
static void
-filter_add(char **filt, char *what, uintptr_t base, uintptr_t size)
+filter_add(char **filt, char *what, uintptr_t base, size_t size)
{
char buf[256], *c = buf, *new;
int len, newlen;
diff --git a/cddl/contrib/opensolaris/cmd/lockstat/sym.c b/cddl/contrib/opensolaris/cmd/lockstat/sym.c
index b5366c566857..7516e7d435f4 100644
--- a/cddl/contrib/opensolaris/cmd/lockstat/sym.c
+++ b/cddl/contrib/opensolaris/cmd/lockstat/sym.c
@@ -42,6 +42,7 @@
#include <libelf.h>
#include <link.h>
#include <elf.h>
+#include <gelf.h>
#ifdef illumos
#include <sys/machelf.h>
@@ -54,7 +55,6 @@
#endif
#include <sys/cpuvar.h>
-
typedef struct syment {
uintptr_t addr;
char *name;
@@ -73,11 +73,6 @@ static char maxsymname[64];
#endif
#endif
-#define __sElfN(x) typedef __CONCAT(__CONCAT(__CONCAT(Elf,__ELF_WORD_SIZE),_),x) x
-__sElfN(Sym);
-__sElfN(Shdr);
-#define elf_getshdr __elfN(getshdr)
-
static void
add_symbol(char *name, uintptr_t addr, size_t size)
{
@@ -174,7 +169,7 @@ symtab_init(void)
{
Elf *elf;
Elf_Scn *scn = NULL;
- Sym *symtab, *symp, *lastsym;
+ GElf_Sym *symtab, *symp, *lastsym;
char *strtab;
uint_t cnt;
int fd;
@@ -198,13 +193,13 @@ symtab_init(void)
(void) elf_version(EV_CURRENT);
elf = elf_begin(fd, ELF_C_READ, NULL);
-
for (cnt = 1; (scn = elf_nextscn(elf, scn)) != NULL; cnt++) {
- Shdr *shdr = elf_getshdr(scn);
- if (shdr->sh_type == SHT_SYMTAB) {
- symtab = (Sym *)elf_getdata(scn, NULL)->d_buf;
- nsyms = shdr->sh_size / shdr->sh_entsize;
- strindex = shdr->sh_link;
+ GElf_Shdr shdr;
+ (void) gelf_getshdr(scn, &shdr);
+ if (shdr.sh_type == SHT_SYMTAB) {
+ symtab = (GElf_Sym *)elf_getdata(scn, NULL)->d_buf;
+ nsyms = shdr.sh_size / shdr.sh_entsize;
+ strindex = shdr.sh_link;
}
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
index e63771c91e08..f3fda4af834e 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
@@ -2478,10 +2478,7 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
"not referenced)\n", yypcb->pcb_sargv[argc - 1], argc - 1);
}
- /*
- * Perform sugar transformations (for "if" / "else") and replace the
- * existing clause chain with the new one.
- */
+ /* Perform sugar transformations. */
if (context == DT_CTX_DPROG) {
dt_node_t *dnp, *next_dnp;
dt_node_t *new_list = NULL;
@@ -2492,8 +2489,17 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
next_dnp = dnp->dn_list;
dnp->dn_list = NULL;
- if (dnp->dn_kind == DT_NODE_CLAUSE)
+ if (dnp->dn_kind == DT_NODE_CLAUSE) {
dnp = dt_compile_sugar(dtp, dnp);
+ if (cflags & DTRACE_C_SUGAR) {
+ dt_node_t *p;
+
+ dt_printd(dnp, stdout, 0);
+ for (p = dnp->dn_list; p != NULL;
+ p = p->dn_list)
+ dt_printd(p, stdout, 0);
+ }
+ }
/* append node to the new list */
new_list = dt_node_link(new_list, dnp);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
index b3f69bb6329d..1e62bd6b21db 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
@@ -323,6 +323,7 @@ struct dtrace_hdl {
#endif
int dt_fd; /* file descriptor for dtrace pseudo-device */
int dt_ftfd; /* file descriptor for fasttrap pseudo-device */
+ int dt_kinstfd; /* file descriptor for kinst pseudo-device */
int dt_fterr; /* saved errno from failed open of dt_ftfd */
int dt_cdefs_fd; /* file descriptor for C CTF debugging cache */
int dt_ddefs_fd; /* file descriptor for D CTF debugging cache */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
index 0b3dac0224f9..442c6f940733 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -215,10 +215,6 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
dofr[j].dofr_offset;
rel->r_info = ELF32_R_INFO(count + dep->de_global,
R_386_PC32);
-#elif defined(__mips__)
-/* XXX */
- printf("%s:%s(%d): MIPS not implemented\n",
- __FUNCTION__, __FILE__, __LINE__);
#elif defined(__powerpc__)
/*
* Add 4 bytes to hit the low half of this 64-bit
@@ -229,9 +225,9 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
rel->r_info = ELF32_R_INFO(count + dep->de_global,
R_PPC_REL32);
#elif defined(__riscv)
-/* XXX */
- printf("%s:%s(%d): RISC-V not implemented\n",
- __FUNCTION__, __FILE__, __LINE__);
+ rel->r_offset = s->dofs_offset + dofr[j].dofr_offset;
+ rel->r_info = ELF32_R_INFO(count + dep->de_global,
+ R_RISCV_32_PCREL);
#else
#error unknown ISA
#endif
@@ -401,15 +397,15 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
R_AARCH64_PREL64);
#elif defined(__arm__)
/* XXX */
-#elif defined(__mips__)
-/* XXX */
#elif defined(__powerpc__)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
rel->r_info = ELF64_R_INFO(count + dep->de_global,
R_PPC64_REL64);
#elif defined(__riscv)
-/* XXX */
+ rel->r_offset = s->dofs_offset + dofr[j].dofr_offset;
+ rel->r_info = ELF64_R_INFO(count + dep->de_global,
+ R_RISCV_32_PCREL);
#elif defined(__i386) || defined(__amd64)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
@@ -504,14 +500,28 @@ dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
elf_file.ehdr.e_type = ET_REL;
#if defined(__arm__)
elf_file.ehdr.e_machine = EM_ARM;
-#elif defined(__mips__)
- elf_file.ehdr.e_machine = EM_MIPS;
#elif defined(__powerpc__)
elf_file.ehdr.e_machine = EM_PPC;
#elif defined(__i386) || defined(__amd64)
elf_file.ehdr.e_machine = EM_386;
#elif defined(__aarch64__)
elf_file.ehdr.e_machine = EM_AARCH64;
+#elif defined(__riscv)
+ elf_file.ehdr.e_machine = EM_RISCV;
+
+ /* Set the ELF flags according to our current ABI */
+#if defined(__riscv_compressed)
+ elf_file.ehdr.e_flags |= EF_RISCV_RVC;
+#endif
+#if defined(__riscv_float_abi_soft)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SOFT;
+#endif
+#if defined(__riscv_float_abi_single)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SINGLE;
+#endif
+#if defined(__riscv_float_abi_double)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_DOUBLE;
+#endif
#endif
elf_file.ehdr.e_version = EV_CURRENT;
elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr);
@@ -572,7 +582,7 @@ dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
} else {
shp = &elf_file.shdr[ESHDR_REL];
shp->sh_name = 37; /* DTRACE_SHSTRTAB32[37] = ".rel.SUNW_dof" */
- shp->sh_flags = SHF_ALLOC;
+ shp->sh_flags = 0;
shp->sh_type = SHT_REL;
shp->sh_entsize = sizeof (de.de_rel[0]);
shp->sh_link = ESHDR_SYMTAB;
@@ -644,8 +654,6 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
elf_file.ehdr.e_type = ET_REL;
#if defined(__arm__)
elf_file.ehdr.e_machine = EM_ARM;
-#elif defined(__mips__)
- elf_file.ehdr.e_machine = EM_MIPS;
#elif defined(__powerpc64__)
#if defined(_CALL_ELF) && _CALL_ELF == 2
elf_file.ehdr.e_flags = 2;
@@ -655,6 +663,22 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
elf_file.ehdr.e_machine = EM_AMD64;
#elif defined(__aarch64__)
elf_file.ehdr.e_machine = EM_AARCH64;
+#elif defined(__riscv)
+ elf_file.ehdr.e_machine = EM_RISCV;
+
+ /* Set the ELF flags according to our current ABI */
+#if defined(__riscv_compressed)
+ elf_file.ehdr.e_flags |= EF_RISCV_RVC;
+#endif
+#if defined(__riscv_float_abi_soft)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SOFT;
+#endif
+#if defined(__riscv_float_abi_single)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SINGLE;
+#endif
+#if defined(__riscv_float_abi_double)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_DOUBLE;
+#endif
#endif
elf_file.ehdr.e_version = EV_CURRENT;
elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr);
@@ -715,7 +739,7 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
} else {
shp = &elf_file.shdr[ESHDR_REL];
shp->sh_name = 37; /* DTRACE_SHSTRTAB64[37] = ".rel.SUNW_dof" */
- shp->sh_flags = SHF_ALLOC;
+ shp->sh_flags = 0;
shp->sh_type = SHT_RELA;
shp->sh_entsize = sizeof (de.de_rel[0]);
shp->sh_link = ESHDR_SYMTAB;
@@ -843,17 +867,6 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
__LINE__);
return (-1);
}
-#elif defined(__mips__)
-#define DT_REL_NONE R_MIPS_NONE
-
-static int
-dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
- uint32_t *off)
-{
- printf("%s:%s(%d): MIPS not implemented\n", __FUNCTION__, __FILE__,
- __LINE__);
- return (-1);
-}
#elif defined(__powerpc__)
/* The sentinel is 'xor r3,r3,r3'. */
#define DT_OP_XOR_R3 0x7c631a78
@@ -938,14 +951,74 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
return (0);
}
#elif defined(__riscv)
+#define DT_OP_NOP 0x00000013 /* addi x0, x0, 0 */
+#define DT_OP_RET 0x00008067 /* jalr x0, x1, 0 */
+#define DT_OP_IS_AUIPC(op) (((op) & 0x7f) == 0x17)
+#define DT_OP_IS_JALR(op) (((op) & 0x707f) == 0x67)
+#define DT_OP_JALR_CALL 0x000080e7 /* jalr x1, x1, 0 */
+#define DT_OP_JALR_TAIL 0x00030067 /* jalr x0, x6, 0 */
#define DT_REL_NONE R_RISCV_NONE
+
static int
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
uint32_t *off)
{
- printf("%s:%s(%d): RISC-V implementation required\n", __FUNCTION__,
- __FILE__, __LINE__);
- return (-1);
+ uint32_t *ip;
+
+ /*
+ * XXX: this implementation is untested, but should serve as a decent
+ * starting point.
+ */
+
+ /*
+ * Ensure that the offset is aligned on a compressed-instruction
+ * boundary.
+ */
+ if ((rela->r_offset & (sizeof (uint16_t) - 1)) != 0)
+ return (-1);
+
+ /*
+ * We only know about some specific relocation types.
+ * We also recognize relocation type NONE, since that gets used for
+ * relocations of USDT probes, and we might be re-processing a file.
+ */
+ if (GELF_R_TYPE(rela->r_info) != R_RISCV_CALL &&
+ GELF_R_TYPE(rela->r_info) != R_RISCV_CALL_PLT &&
+ GELF_R_TYPE(rela->r_info) != R_RISCV_NONE)
+ return (-1);
+
+ ip = (uint32_t *)(p + rela->r_offset);
+
+ /*
+ * We may have already processed this object file in an earlier linker
+ * invocation. Check to see if the present instruction sequence matches
+ * the one we would install below.
+ */
+ if (ip[0] == DT_OP_NOP && (ip[1] == DT_OP_NOP || ip[1] == DT_OP_RET))
+ return (0);
+
+ /*
+ * We expect a auipc+jalr pair, either from a call or a tail.
+ * - call: auipc x1 0; jalr x1, x1, 0
+ * - tail: auipc x6 0; jalr x0, x6, 0
+ */
+ if (!DT_OP_IS_AUIPC(ip[0]) || !DT_OP_IS_JALR(ip[1]))
+ return (-1);
+
+ /*
+ * On riscv, we do not have to differentiate between regular probes and
+ * is-enabled probes. Calls are to be converted into a no-op whereas
+ * tail calls should become a return.
+ */
+ if (ip[1] == DT_OP_JALR_CALL) {
+ ip[0] = DT_OP_NOP;
+ ip[1] = DT_OP_NOP;
+ } else {
+ ip[0] = DT_OP_NOP;
+ ip[1] = DT_OP_RET;
+ }
+
+ return (0);
}
#elif defined(__i386) || defined(__amd64)
@@ -1167,9 +1240,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
if (dtp->dt_oflags & DTRACE_O_LP64) {
eclass = ELFCLASS64;
-#if defined(__mips__)
- emachine1 = emachine2 = EM_MIPS;
-#elif defined(__powerpc__)
+#if defined(__powerpc__)
emachine1 = emachine2 = EM_PPC64;
#if !defined(_CALL_ELF) || _CALL_ELF == 1
uses_funcdesc = 1;
@@ -1178,14 +1249,14 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
emachine1 = emachine2 = EM_AMD64;
#elif defined(__aarch64__)
emachine1 = emachine2 = EM_AARCH64;
+#elif defined(__riscv)
+ emachine1 = emachine2 = EM_RISCV;
#endif
symsize = sizeof (Elf64_Sym);
} else {
eclass = ELFCLASS32;
#if defined(__arm__)
emachine1 = emachine2 = EM_ARM;
-#elif defined(__mips__)
- emachine1 = emachine2 = EM_MIPS;
#elif defined(__powerpc__)
emachine1 = emachine2 = EM_PPC;
#elif defined(__i386) || defined(__amd64)
@@ -1612,6 +1683,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
* invocation.
*/
if (rsym.st_shndx != SHN_ABS) {
+ rsym.st_info = GELF_ST_INFO(STB_WEAK, STT_FUNC);
rsym.st_shndx = SHN_ABS;
(void) gelf_update_sym(data_sym, ndx, &rsym);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
index b9408944f8c5..281c787de533 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
@@ -1129,33 +1129,21 @@ dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
* including the path.
*/
static void
-#ifdef illumos
-dt_module_update(dtrace_hdl_t *dtp, const char *name)
-#else
dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
-#endif
{
char fname[MAXPATHLEN];
struct stat64 st;
int fd, err, bits;
-#ifdef __FreeBSD__
struct module_stat ms;
dt_kmodule_t *dkmp;
uint_t h;
int modid;
-#endif
-
dt_module_t *dmp;
const char *s;
size_t shstrs;
GElf_Shdr sh;
Elf_Data *dp;
Elf_Scn *sp;
-
-#ifdef illumos
- (void) snprintf(fname, sizeof (fname),
- "%s/%s/object", OBJFS_ROOT, name);
-#else
GElf_Ehdr ehdr;
GElf_Phdr ph;
char name[MAXPATHLEN];
@@ -1165,7 +1153,6 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
(void) strlcpy(name, k_stat->name, sizeof(name));
(void) strlcpy(fname, k_stat->pathname, sizeof(fname));
-#endif
if ((fd = open(fname, O_RDONLY)) == -1 || fstat64(fd, &st) == -1 ||
(dmp = dt_module_create(dtp, name)) == NULL) {
@@ -1174,6 +1161,9 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
return;
}
+ (void) strlcpy(dmp->dm_file, fname, sizeof(dmp->dm_file));
+ dmp->dm_modid = k_stat->id;
+
/*
* Since the module can unload out from under us (and /system/object
* will return ENOENT), tell libelf to cook the entire file now and
@@ -1206,7 +1196,6 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
dt_module_destroy(dtp, dmp);
return;
}
-#if defined(__FreeBSD__)
mapbase = (uintptr_t)k_stat->address;
gelf_getehdr(dmp->dm_elf, &ehdr);
is_elf_obj = (ehdr.e_type == ET_REL);
@@ -1219,7 +1208,6 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
return;
}
}
-#endif
/*
* Iterate over the section headers locating various sections of
* interest and use their attributes to flesh out the dt_module_t.
@@ -1228,7 +1216,6 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
(s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)
continue; /* skip any malformed sections */
-#if defined(__FreeBSD__)
if (sh.sh_size == 0)
continue;
if (sh.sh_type == SHT_PROGBITS || sh.sh_type == SHT_NOBITS) {
@@ -1240,7 +1227,6 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
dmp->dm_sec_offsets[elf_ndxscn(sp)] = sh.sh_addr;
mapbase += sh.sh_size;
}
-#endif
if (strcmp(s, ".text") == 0) {
dmp->dm_text_size = sh.sh_size;
dmp->dm_text_va = sh.sh_addr;
@@ -1254,17 +1240,10 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
(dp = elf_getdata(sp, NULL)) != NULL) {
bcopy(dp->d_buf, &dmp->dm_info,
MIN(sh.sh_size, sizeof (dmp->dm_info)));
- } else if (strcmp(s, ".filename") == 0 &&
- (dp = elf_getdata(sp, NULL)) != NULL) {
- (void) strlcpy(dmp->dm_file,
- dp->d_buf, sizeof (dmp->dm_file));
}
}
dmp->dm_flags |= DT_DM_KERNEL;
-#ifdef illumos
- dmp->dm_modid = (int)OBJFS_MODID(st.st_ino);
-#else
/*
* Include .rodata and special sections into .text.
* This depends on default section layout produced by GNU ld
@@ -1285,12 +1264,10 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
}
}
#endif
-#endif /* illumos */
if (dmp->dm_info.objfs_info_primary)
dmp->dm_flags |= DT_DM_PRIMARY;
-#ifdef __FreeBSD__
ms.version = sizeof(ms);
for (modid = kldfirstmod(k_stat->id); modid > 0;
modid = modnext(modid)) {
@@ -1315,7 +1292,6 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
dkmp->dkm_module = dmp;
dtp->dt_kmods[h] = dkmp;
}
-#endif
dt_dprintf("opened %d-bit module %s (%s) [%d]\n",
bits, dmp->dm_name, dmp->dm_file, dmp->dm_modid);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
index f55d488f4d91..fd770e180b47 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -416,6 +416,8 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_func, "void(int)" },
{ "rand", DT_IDENT_FUNC, 0, DIF_SUBR_RAND, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "int()" },
+{ "regs", DT_IDENT_ARRAY, 0, DIF_VAR_REGS, DT_ATTR_STABCMN, DT_VERS_1_13,
+ &dt_idops_regs, NULL },
{ "rindex", DT_IDENT_FUNC, 0, DIF_SUBR_RINDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
&dt_idops_func, "int(const char *, const char *, [int])" },
#ifdef illumos
@@ -1113,6 +1115,15 @@ dt_vopen(int version, int flags, int *errp,
*/
if (err == ENOENT && modfind("dtraceall") < 0) {
kldload("dtraceall"); /* ignore the error */
+#if __SIZEOF_LONG__ == 8
+ if (modfind("linux64elf") >= 0)
+ kldload("systrace_linux");
+ if (modfind("linuxelf") >= 0)
+ kldload("systrace_linux32");
+#else
+ if (modfind("linuxelf") >= 0)
+ kldload("systrace_linux");
+#endif
dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
err = errno;
}
@@ -1171,6 +1182,7 @@ alloc:
dtp->dt_version = version;
dtp->dt_fd = dtfd;
dtp->dt_ftfd = ftfd;
+ dtp->dt_kinstfd = -1;
dtp->dt_fterr = fterr;
dtp->dt_cdefs_fd = -1;
dtp->dt_ddefs_fd = -1;
@@ -1679,6 +1691,8 @@ dtrace_close(dtrace_hdl_t *dtp)
(void) close(dtp->dt_fd);
if (dtp->dt_ftfd != -1)
(void) close(dtp->dt_ftfd);
+ if (dtp->dt_kinstfd != -1)
+ (void) close(dtp->dt_kinstfd);
if (dtp->dt_cdefs_fd != -1)
(void) close(dtp->dt_cdefs_fd);
if (dtp->dt_ddefs_fd != -1)
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
index f028f99ccf64..2b85dd2b26b6 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.c
@@ -4767,8 +4767,8 @@ dt_printd(dt_node_t *dnp, FILE *fp, int depth)
dt_printd(dnp->dn_pred, fp, 0);
(void) fprintf(fp, "/\n");
}
- (void) fprintf(fp, "{\n");
+ (void) fprintf(fp, "{\n");
for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
dt_printd(arg, fp, depth + 1);
(void) fprintf(fp, "}\n");
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
index 57a7db4ad0fd..c33ae955ba61 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
@@ -317,8 +317,7 @@ pfprint_fp(dtrace_hdl_t *dtp, FILE *fp, const char *format,
case sizeof (double):
return (dt_printf(dtp, fp, format,
*((double *)addr) / n));
-#if !defined(__arm__) && !defined(__powerpc__) && \
- !defined(__mips__) && !defined(__riscv)
+#if !defined(__arm__) && !defined(__powerpc__) && !defined(__riscv)
case sizeof (long double):
return (dt_printf(dtp, fp, format,
*((long double *)addr) / ldn));
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
index 34bcc15b9ac7..b32dcea1f8ba 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c
@@ -80,10 +80,8 @@
* up using this condition and will then call the client handler as necessary.
*/
+#include <sys/syscall.h>
#include <sys/wait.h>
-#ifdef illumos
-#include <sys/lwp.h>
-#endif
#include <strings.h>
#include <signal.h>
#include <assert.h>
@@ -93,14 +91,10 @@
#include <dt_pid.h>
#include <dt_impl.h>
-#ifndef illumos
-#include <sys/syscall.h>
#include <libproc_compat.h>
-#define SYS_forksys SYS_fork
-#endif
#define IS_SYS_EXEC(w) (w == SYS_execve)
-#define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys)
+#define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_fork)
static dt_bkpt_t *
dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data)
@@ -147,38 +141,23 @@ dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts)
static void
dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr)
{
-#ifdef illumos
- const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp;
-#else
unsigned long pc;
-#endif
dt_bkpt_t *dbp;
assert(DT_MUTEX_HELD(&dpr->dpr_lock));
-#ifndef illumos
proc_regget(dpr->dpr_proc, REG_PC, &pc);
proc_bkptregadj(&pc);
-#endif
for (dbp = dt_list_next(&dpr->dpr_bps);
dbp != NULL; dbp = dt_list_next(dbp)) {
-#ifdef illumos
- if (psp->pr_reg[R_PC] == dbp->dbp_addr)
- break;
-#else
if (pc == dbp->dbp_addr)
break;
-#endif
}
if (dbp == NULL) {
dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n",
-#ifdef illumos
- (int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]);
-#else
(int)dpr->dpr_pid, pc);
-#endif
return;
}
@@ -346,12 +325,8 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname)
}
(void) dt_proc_bpcreate(dpr, rdn.u.bptaddr,
-#ifdef illumos
- (dt_bkpt_f *)dt_proc_rdevent, (void *)evname);
-#else
/* XXX ugly */
(dt_bkpt_f *)dt_proc_rdevent, __DECONST(void *, evname));
-#endif
}
/*
@@ -361,34 +336,18 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname)
static void
dt_proc_attach(dt_proc_t *dpr, int exec)
{
-#ifdef illumos
- const pstatus_t *psp = Pstatus(dpr->dpr_proc);
-#endif
rd_err_e err;
GElf_Sym sym;
assert(DT_MUTEX_HELD(&dpr->dpr_lock));
if (exec) {
-#ifdef illumos
- if (psp->pr_lwp.pr_errno != 0)
- return; /* exec failed: nothing needs to be done */
-#endif
dt_proc_bpdestroy(dpr, B_FALSE);
-#ifdef illumos
- Preset_maps(dpr->dpr_proc);
-#endif
}
if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL &&
(err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) {
-#ifdef illumos
- dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT");
-#endif
dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT");
-#ifdef illumos
- dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY");
-#endif
} else {
dt_dprintf("pid %d: failed to enable rtld events: %s\n",
(int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) :
@@ -407,84 +366,6 @@ dt_proc_attach(dt_proc_t *dpr, int exec)
}
}
-/*
- * Wait for a stopped process to be set running again by some other debugger.
- * This is typically not required by /proc-based debuggers, since the usual
- * model is that one debugger controls one victim. But DTrace, as usual, has
- * its own needs: the stop() action assumes that prun(1) or some other tool
- * will be applied to resume the victim process. This could be solved by
- * adding a PCWRUN directive to /proc, but that seems like overkill unless
- * other debuggers end up needing this functionality, so we implement a cheap
- * equivalent to PCWRUN using the set of existing kernel mechanisms.
- *
- * Our intent is really not just to wait for the victim to run, but rather to
- * wait for it to run and then stop again for a reason other than the current
- * PR_REQUESTED stop. Since PCWSTOP/Pstopstatus() can be applied repeatedly
- * to a stopped process and will return the same result without affecting the
- * victim, we can just perform these operations repeatedly until Pstate()
- * changes, the representative LWP ID changes, or the stop timestamp advances.
- * dt_proc_control() will then rediscover the new state and continue as usual.
- * When the process is still stopped in the same exact state, we sleep for a
- * brief interval before waiting again so as not to spin consuming CPU cycles.
- */
-static void
-dt_proc_waitrun(dt_proc_t *dpr)
-{
- printf("%s:%s(%d): not implemented\n", __FUNCTION__, __FILE__,
- __LINE__);
-#ifdef DOODAD
- struct ps_prochandle *P = dpr->dpr_proc;
- const lwpstatus_t *psp = &Pstatus(P)->pr_lwp;
-
- int krflag = psp->pr_flags & (PR_KLC | PR_RLC);
- timestruc_t tstamp = psp->pr_tstamp;
- lwpid_t lwpid = psp->pr_lwpid;
-
- const long wstop = PCWSTOP;
- int pfd = Pctlfd(P);
-
- assert(DT_MUTEX_HELD(&dpr->dpr_lock));
- assert(psp->pr_flags & PR_STOPPED);
- assert(Pstate(P) == PS_STOP);
-
- /*
- * While we are waiting for the victim to run, clear PR_KLC and PR_RLC
- * so that if the libdtrace client is killed, the victim stays stopped.
- * dt_proc_destroy() will also observe this and perform PRELEASE_HANG.
- */
- (void) Punsetflags(P, krflag);
- Psync(P);
-
- (void) pthread_mutex_unlock(&dpr->dpr_lock);
-
- while (!dpr->dpr_quit) {
- if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR)
- continue; /* check dpr_quit and continue waiting */
-
- (void) pthread_mutex_lock(&dpr->dpr_lock);
- (void) Pstopstatus(P, PCNULL, 0);
- psp = &Pstatus(P)->pr_lwp;
-
- /*
- * If we've reached a new state, found a new representative, or
- * the stop timestamp has changed, restore PR_KLC/PR_RLC to its
- * original setting and then return with dpr_lock held.
- */
- if (Pstate(P) != PS_STOP || psp->pr_lwpid != lwpid ||
- bcmp(&psp->pr_tstamp, &tstamp, sizeof (tstamp)) != 0) {
- (void) Psetflags(P, krflag);
- Psync(P);
- return;
- }
-
- (void) pthread_mutex_unlock(&dpr->dpr_lock);
- (void) poll(NULL, 0, MILLISEC / 2);
- }
-
- (void) pthread_mutex_lock(&dpr->dpr_lock);
-#endif
-}
-
typedef struct dt_proc_control_data {
dtrace_hdl_t *dpcd_hdl; /* DTrace handle */
dt_proc_t *dpcd_proc; /* proccess to control */
@@ -511,12 +392,6 @@ dt_proc_control(void *arg)
dt_proc_hash_t *dph = dtp->dt_procs;
struct ps_prochandle *P = dpr->dpr_proc;
int pid = dpr->dpr_pid;
-
-#ifdef illumos
- int pfd = Pctlfd(P);
-
- const long wstop = PCWSTOP;
-#endif
int notify = B_FALSE;
/*
@@ -534,44 +409,14 @@ dt_proc_control(void *arg)
*/
(void) pthread_mutex_lock(&dpr->dpr_lock);
-#ifdef illumos
- (void) Punsetflags(P, PR_ASYNC); /* require synchronous mode */
- (void) Psetflags(P, PR_BPTADJ); /* always adjust eip on x86 */
- (void) Punsetflags(P, PR_FORK); /* do not inherit on fork */
-
- (void) Pfault(P, FLTBPT, B_TRUE); /* always trace breakpoints */
- (void) Pfault(P, FLTTRACE, B_TRUE); /* always trace single-step */
-
- /*
- * We must trace exit from exec() system calls so that if the exec is
- * successful, we can reset our breakpoints and re-initialize libproc.
- */
- (void) Psysexit(P, SYS_execve, B_TRUE);
-
- /*
- * We must trace entry and exit for fork() system calls in order to
- * disable our breakpoints temporarily during the fork. We do not set
- * the PR_FORK flag, so if fork succeeds the child begins executing and
- * does not inherit any other tracing behaviors or a control thread.
- */
- (void) Psysentry(P, SYS_vfork, B_TRUE);
- (void) Psysexit(P, SYS_vfork, B_TRUE);
- (void) Psysentry(P, SYS_forksys, B_TRUE);
- (void) Psysexit(P, SYS_forksys, B_TRUE);
-
- Psync(P); /* enable all /proc changes */
-#endif
dt_proc_attach(dpr, B_FALSE); /* enable rtld breakpoints */
/*
- * If PR_KLC is set, we created the process; otherwise we grabbed it.
- * Check for an appropriate stop request and wait for dt_proc_continue.
+ * If DT_CLOSE_KILL is set, we created the process; otherwise we
+ * grabbed it. Check for an appropriate stop request and wait for
+ * dt_proc_continue.
*/
-#ifdef illumos
- if (Pstatus(P)->pr_flags & PR_KLC)
-#else
- if (proc_getflags(P) & PR_KLC)
-#endif
+ if (dpr->dpr_close == DT_CLOSE_KILL)
dt_proc_stop(dpr, DT_PROC_STOP_CREATE);
else
dt_proc_stop(dpr, DT_PROC_STOP_GRAB);
@@ -595,55 +440,21 @@ dt_proc_control(void *arg)
while (!dpr->dpr_quit) {
const lwpstatus_t *psp;
-#ifdef illumos
- if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR)
- continue; /* check dpr_quit and continue waiting */
-#else
/* Wait for the process to report status. */
proc_wstatus(P);
if (errno == EINTR)
continue; /* check dpr_quit and continue waiting */
-#endif
(void) pthread_mutex_lock(&dpr->dpr_lock);
-#ifdef illumos
-pwait_locked:
- if (Pstopstatus(P, PCNULL, 0) == -1 && errno == EINTR) {
- (void) pthread_mutex_unlock(&dpr->dpr_lock);
- continue; /* check dpr_quit and continue waiting */
- }
-#endif
-
switch (Pstate(P)) {
case PS_STOP:
-#ifdef illumos
- psp = &Pstatus(P)->pr_lwp;
-#else
psp = proc_getlwpstatus(P);
-#endif
dt_dprintf("pid %d: proc stopped showing %d/%d\n",
pid, psp->pr_why, psp->pr_what);
/*
- * If the process stops showing PR_REQUESTED, then the
- * DTrace stop() action was applied to it or another
- * debugging utility (e.g. pstop(1)) asked it to stop.
- * In either case, the user's intention is for the
- * process to remain stopped until another external
- * mechanism (e.g. prun(1)) is applied. So instead of
- * setting the process running ourself, we wait for
- * someone else to do so. Once that happens, we return
- * to our normal loop waiting for an event of interest.
- */
- if (psp->pr_why == PR_REQUESTED) {
- dt_proc_waitrun(dpr);
- (void) pthread_mutex_unlock(&dpr->dpr_lock);
- continue;
- }
-
- /*
* If the process stops showing one of the events that
* we are tracing, perform the appropriate response.
* Note that we ignore PR_SUSPENDED, PR_CHECKPOINT, and
@@ -666,11 +477,6 @@ pwait_locked:
break;
case PS_LOST:
-#ifdef illumos
- if (Preopen(P) == 0)
- goto pwait_locked;
-#endif
-
dt_dprintf("pid %d: proc lost: %s\n",
pid, strerror(errno));
@@ -685,9 +491,19 @@ pwait_locked:
break;
}
- if (Pstate(P) != PS_UNDEAD && Psetrun(P, 0, 0) == -1) {
- dt_dprintf("pid %d: failed to set running: %s\n",
- (int)dpr->dpr_pid, strerror(errno));
+ if (Pstate(P) != PS_UNDEAD) {
+ if (dpr->dpr_quit && dpr->dpr_close == DT_CLOSE_KILL) {
+ /*
+ * We're about to kill the child, so don't
+ * bother resuming it. In some cases, such as
+ * an initialization error, we shouldn't have
+ * started it in the first place, so letting it
+ * run could be harmful.
+ */
+ } else if (Psetrun(P, 0, 0) == -1) {
+ dt_dprintf("pid %d: failed to set running: "
+ "%s\n", (int)dpr->dpr_pid, strerror(errno));
+ }
}
(void) pthread_mutex_unlock(&dpr->dpr_lock);
@@ -739,11 +555,7 @@ dt_proc_t *
dt_proc_lookup(dtrace_hdl_t *dtp, struct ps_prochandle *P, int remove)
{
dt_proc_hash_t *dph = dtp->dt_procs;
-#ifdef illumos
- pid_t pid = Pstatus(P)->pr_pid;
-#else
pid_t pid = proc_getpid(P);
-#endif
dt_proc_t *dpr, **dpp = &dph->dph_hash[pid & (dph->dph_hashlen - 1)];
for (dpr = *dpp; dpr != NULL; dpr = dpr->dpr_hash) {
@@ -772,28 +584,15 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P)
assert(dpr != NULL);
- /*
- * If neither PR_KLC nor PR_RLC is set, then the process is stopped by
- * an external debugger and we were waiting in dt_proc_waitrun().
- * Leave the process in this condition using PRELEASE_HANG.
- */
-#ifdef illumos
- if (!(Pstatus(dpr->dpr_proc)->pr_flags & (PR_KLC | PR_RLC))) {
-#else
- if (!(proc_getflags(dpr->dpr_proc) & (PR_KLC | PR_RLC))) {
-#endif
- dt_dprintf("abandoning pid %d\n", (int)dpr->dpr_pid);
- rflag = PRELEASE_HANG;
-#ifdef illumos
- } else if (Pstatus(dpr->dpr_proc)->pr_flags & PR_KLC) {
-#else
- } else if (proc_getflags(dpr->dpr_proc) & PR_KLC) {
-#endif
+ switch (dpr->dpr_close) {
+ case DT_CLOSE_KILL:
dt_dprintf("killing pid %d\n", (int)dpr->dpr_pid);
- rflag = PRELEASE_KILL; /* apply kill-on-last-close */
- } else {
+ rflag = PRELEASE_KILL;
+ break;
+ case DT_CLOSE_RUN:
dt_dprintf("releasing pid %d\n", (int)dpr->dpr_pid);
- rflag = 0; /* apply run-on-last-close */
+ rflag = 0;
+ break;
}
if (dpr->dpr_tid) {
@@ -813,11 +612,7 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P)
*/
(void) pthread_mutex_lock(&dpr->dpr_lock);
dpr->dpr_quit = B_TRUE;
-#ifdef illumos
- (void) _lwp_kill(dpr->dpr_tid, SIGCANCEL);
-#else
pthread_kill(dpr->dpr_tid, SIGTHR);
-#endif
/*
* If the process is currently idling in dt_proc_stop(), re-
@@ -885,11 +680,7 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
(void) sigfillset(&nset);
(void) sigdelset(&nset, SIGABRT); /* unblocked for assert() */
-#ifdef illumos
- (void) sigdelset(&nset, SIGCANCEL); /* see dt_proc_destroy() */
-#else
(void) sigdelset(&nset, SIGUSR1); /* see dt_proc_destroy() */
-#endif
data.dpcd_hdl = dtp;
data.dpcd_proc = dpr;
@@ -917,14 +708,8 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
* small amount of useful information to help figure it out.
*/
if (dpr->dpr_done) {
-#ifdef illumos
- const psinfo_t *prp = Ppsinfo(dpr->dpr_proc);
- int stat = prp ? prp->pr_wstat : 0;
- int pid = dpr->dpr_pid;
-#else
int stat = proc_getwstat(dpr->dpr_proc);
int pid = proc_getpid(dpr->dpr_proc);
-#endif
if (proc_state(dpr->dpr_proc) == PS_LOST) {
(void) dt_proc_error(dpr->dpr_hdl, dpr,
"failed to control pid %d: process exec'd "
@@ -968,29 +753,15 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
(void) pthread_mutex_init(&dpr->dpr_lock, NULL);
(void) pthread_cond_init(&dpr->dpr_cv, NULL);
-#ifdef illumos
- dpr->dpr_proc = Pxcreate(file, argv, dtp->dt_proc_env, &err, NULL, 0);
- if (dpr->dpr_proc == NULL) {
- return (dt_proc_error(dtp, dpr,
- "failed to execute %s: %s\n", file, Pcreate_error(err)));
- }
-#else
if ((err = proc_create(file, argv, dtp->dt_proc_env, pcf, child_arg,
&dpr->dpr_proc)) != 0) {
return (dt_proc_error(dtp, dpr,
"failed to execute %s: %s\n", file, Pcreate_error(err)));
}
-#endif
dpr->dpr_hdl = dtp;
-#ifdef illumos
- dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid;
-#else
dpr->dpr_pid = proc_getpid(dpr->dpr_proc);
-#endif
-
- (void) Punsetflags(dpr->dpr_proc, PR_RLC);
- (void) Psetflags(dpr->dpr_proc, PR_KLC);
+ dpr->dpr_close = DT_CLOSE_KILL;
if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0)
return (NULL); /* dt_proc_error() has been called for us */
@@ -1048,20 +819,14 @@ dt_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags, int nomonitor)
(void) pthread_mutex_init(&dpr->dpr_lock, NULL);
(void) pthread_cond_init(&dpr->dpr_cv, NULL);
-#ifdef illumos
- if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) {
-#else
if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) {
-#endif
return (dt_proc_error(dtp, dpr,
"failed to grab pid %d: %s\n", (int)pid, Pgrab_error(err)));
}
dpr->dpr_hdl = dtp;
dpr->dpr_pid = pid;
-
- (void) Punsetflags(dpr->dpr_proc, PR_KLC);
- (void) Psetflags(dpr->dpr_proc, PR_RLC);
+ dpr->dpr_close = DT_CLOSE_RUN;
/*
* If we are attempting to grab the process without a monitor
@@ -1227,11 +992,7 @@ dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg);
if (P != NULL && idp != NULL && idp->di_id == 0) {
-#ifdef illumos
- idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */
-#else
idp->di_id = proc_getpid(P); /* $target = created pid */
-#endif
}
return (P);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
index beae6f6d5cda..458e9902881f 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h
@@ -40,6 +40,11 @@
extern "C" {
#endif
+enum dt_close_action {
+ DT_CLOSE_RUN,
+ DT_CLOSE_KILL,
+};
+
typedef struct dt_proc {
dt_list_t dpr_list; /* prev/next pointers for lru chain */
struct dt_proc *dpr_hash; /* next pointer for pid hash chain */
@@ -60,6 +65,7 @@ typedef struct dt_proc {
uint8_t dpr_rdonly; /* proc flag: opened read-only */
pthread_t dpr_tid; /* control thread (or zero if none) */
dt_list_t dpr_bps; /* list of dt_bkpt_t structures */
+ enum dt_close_action dpr_close; /* do this to child when exiting */
} dt_proc_t;
typedef struct dt_proc_notify {
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
index 7cf352d4d505..2391690afc0b 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
@@ -48,6 +48,7 @@
#include <dt_list.h>
#include <dt_pid.h>
#include <dtrace.h>
+#include <kinst.h>
static dt_provider_t *
dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h)
@@ -699,6 +700,34 @@ dt_probe_info(dtrace_hdl_t *dtp,
prp = idp->di_data;
else if (pdp->dtpd_id != DTRACE_IDNONE)
prp = dt_probe_discover(pvp, pdp);
+
+ if (strcmp(pvp->pv_desc.dtvd_name, "kinst") == 0) {
+ dtrace_kinst_probedesc_t pd;
+
+ if (dtp->dt_kinstfd == -1) {
+ int fd;
+
+ fd = open("/dev/dtrace/kinst", O_WRONLY);
+ if (fd < 0) {
+ (void) dt_set_errno(dtp, errno);
+ return (NULL);
+ }
+ dtp->dt_kinstfd = fd;
+ }
+ memset(&pd, 0, sizeof(pd));
+ strlcpy(pd.kpd_func, pdp->dtpd_func,
+ sizeof (pd.kpd_func));
+
+ if (n_is_glob)
+ pd.kpd_off = -1;
+ else
+ pd.kpd_off = strtol(pdp->dtpd_name, NULL, 10);
+ if (ioctl(dtp->dt_kinstfd, KINSTIOC_MAKEPROBE, &pd) !=
+ 0) {
+ (void) dt_set_errno(dtp, errno);
+ return (NULL);
+ }
+ }
}
/*
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
index f0bc83a7fc7b..af0213695f32 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
@@ -119,10 +119,11 @@ typedef struct dtrace_proginfo {
#define DTRACE_C_PSPEC 0x0080 /* Interpret ambiguous specifiers as probes */
#define DTRACE_C_ETAGS 0x0100 /* Prefix error messages with error tags */
#define DTRACE_C_ARGREF 0x0200 /* Do not require all macro args to be used */
+#define DTRACE_C_SUGAR 0x0400 /* Dump D script post-dt_sugar */
#define DTRACE_C_DEFARG 0x0800 /* Use 0/"" as value for unspecified args */
#define DTRACE_C_NOLIBS 0x1000 /* Do not process D system libraries */
#define DTRACE_C_CTL 0x2000 /* Only process control directives */
-#define DTRACE_C_MASK 0x3bff /* mask of all valid flags to dtrace_*compile */
+#define DTRACE_C_MASK 0x3fff /* mask of all valid flags to dtrace_*compile */
extern dtrace_prog_t *dtrace_program_strcompile(dtrace_hdl_t *,
const char *, dtrace_probespec_t, uint_t, int, char *const []);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c
deleted file mode 100644
index 1aeb95f3dfd7..000000000000
--- a/cddl/contrib/opensolaris/lib/libdtrace/mips/dt_isadep.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdlib.h>
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <libgen.h>
-
-#include <dt_impl.h>
-#include <dt_pid.h>
-
-/*ARGSUSED*/
-int
-dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
- fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
-{
-
- dt_dprintf("%s: unimplemented\n", __func__);
- return (DT_PROC_ERR);
-}
-
-int
-dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
- fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
-{
-
- dt_dprintf("%s: unimplemented\n", __func__);
- return (DT_PROC_ERR);
-}
-
-/*ARGSUSED*/
-int
-dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
- fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
-{
-
- dt_dprintf("%s: unimplemented\n", __func__);
- return (DT_PROC_ERR);
-}
-
-/*ARGSUSED*/
-int
-dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
- fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
-{
-
- dt_dprintf("%s: unimplemented\n", __func__);
- return (DT_PROC_ERR);
-}
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/memory.c b/cddl/contrib/opensolaris/tools/ctf/common/memory.c
index e16044a8b672..66296c5b114d 100644
--- a/cddl/contrib/opensolaris/tools/ctf/common/memory.c
+++ b/cddl/contrib/opensolaris/tools/ctf/common/memory.c
@@ -44,6 +44,20 @@ memory_bailout(void)
exit(1);
}
+int
+xasprintf(char **s, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vasprintf(s, fmt, ap);
+ va_end(ap);
+ if (ret == -1)
+ memory_bailout();
+ return (ret);
+}
+
void *
xmalloc(size_t size)
{
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/memory.h b/cddl/contrib/opensolaris/tools/ctf/common/memory.h
index 88ca31bec65a..72706b5f7fdb 100644
--- a/cddl/contrib/opensolaris/tools/ctf/common/memory.h
+++ b/cddl/contrib/opensolaris/tools/ctf/common/memory.h
@@ -39,6 +39,7 @@
extern "C" {
#endif
+int xasprintf(char **, const char *, ...);
void *xmalloc(size_t);
void *xcalloc(size_t);
char *xstrdup(const char *);
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/utils.c b/cddl/contrib/opensolaris/tools/ctf/common/utils.c
index f74eb8de40fa..fda29486d94b 100644
--- a/cddl/contrib/opensolaris/tools/ctf/common/utils.c
+++ b/cddl/contrib/opensolaris/tools/ctf/common/utils.c
@@ -35,30 +35,6 @@
/*LINTLIBRARY*/
-static const char *pname;
-
-#pragma init(getpname)
-const char *
-getpname(void)
-{
- const char *p, *q;
-
- if (pname != NULL)
- return (pname);
-
- if ((p = getexecname()) != NULL)
- q = strrchr(p, '/');
- else
- q = NULL;
-
- if (q == NULL)
- pname = p;
- else
- pname = q + 1;
-
- return (pname);
-}
-
void
vdie(const char *format, va_list alist)
{
diff --git a/cddl/contrib/opensolaris/tools/ctf/common/utils.h b/cddl/contrib/opensolaris/tools/ctf/common/utils.h
index 99378bb4f251..6918bdab89aa 100644
--- a/cddl/contrib/opensolaris/tools/ctf/common/utils.h
+++ b/cddl/contrib/opensolaris/tools/ctf/common/utils.h
@@ -42,8 +42,6 @@ extern "C" {
extern void vdie(const char *, va_list);
extern void die(const char *, ...);
-extern const char *getpname(void);
-
#ifdef __cplusplus
}
#endif
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
index 2d686e53fed1..ec5a3c58856d 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c
@@ -618,7 +618,7 @@ tdesc_intr_long(dwarf_t *dw)
* caller can then use the copy as the type for a bitfield structure member.
*/
static tdesc_t *
-tdesc_intr_clone(dwarf_t *dw, tdesc_t *old, size_t bitsz)
+tdesc_intr_clone(dwarf_t *dw, tdesc_t *old, size_t bitsz, const char *suffix)
{
tdesc_t *new = xcalloc(sizeof (tdesc_t));
@@ -627,7 +627,7 @@ tdesc_intr_clone(dwarf_t *dw, tdesc_t *old, size_t bitsz)
"unresolved type\n", old->t_id);
}
- new->t_name = xstrdup(old->t_name);
+ xasprintf(&new->t_name, "%s %s", old->t_name, suffix);
new->t_size = old->t_size;
new->t_id = mfgtid_next(dw);
new->t_type = INTRINSIC;
@@ -1158,7 +1158,8 @@ die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
debug(3, "tdp %u: creating bitfield for %d bits\n",
tdp->t_id, ml->ml_size);
- ml->ml_type = tdesc_intr_clone(dw, mt, ml->ml_size);
+ ml->ml_type = tdesc_intr_clone(dw, mt, ml->ml_size,
+ "bitfield");
}
}
@@ -1366,7 +1367,7 @@ static const fp_size_map_t fp_encodings[] = {
};
static uint_t
-die_base_type2enc(dwarf_t *dw, Dwarf_Off off, Dwarf_Signed enc, size_t sz)
+die_base_type2enc(dwarf_t *dw, Dwarf_Off off, Dwarf_Unsigned enc, size_t sz)
{
const fp_size_map_t *map = fp_encodings;
uint_t szidx = dw->dw_ptrsz == sizeof (uint64_t);
@@ -1397,9 +1398,9 @@ static intr_t *
die_base_from_dwarf(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, size_t sz)
{
intr_t *intr = xcalloc(sizeof (intr_t));
- Dwarf_Signed enc;
+ Dwarf_Unsigned enc;
- (void) die_signed(dw, base, DW_AT_encoding, &enc, DW_ATTR_REQ);
+ (void) die_unsigned(dw, base, DW_AT_encoding, &enc, DW_ATTR_REQ);
switch (enc) {
case DW_ATE_unsigned:
diff --git a/cddl/contrib/opensolaris/tools/ctf/dump/dump.c b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
index 06c00a7b0e7f..5cbf46af1b73 100644
--- a/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
+++ b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
@@ -856,7 +856,7 @@ print_stats(void)
static int
print_usage(FILE *fp, int verbose)
{
- (void) fprintf(fp, "Usage: %s [-dfhlsSt] [-u file] file\n", getpname());
+ (void) fprintf(fp, "Usage: %s [-dfhlsSt] [-u file] file\n", getprogname());
if (verbose) {
(void) fprintf(fp,