diff options
Diffstat (limited to 'cddl/contrib/opensolaris')
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, |