Page MenuHomeFreeBSD

D9988.1775096702.diff
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

D9988.1775096702.diff

Index: cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
===================================================================
--- cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
+++ cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -242,6 +242,8 @@
{ "copyoutstr", DT_IDENT_FUNC, 0, DIF_SUBR_COPYOUTSTR,
DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "void(char *, uintptr_t, size_t)" },
+{ "copyoutmbuf", DT_IDENT_FUNC, 0, DIF_SUBR_COPYOUTMBUF, DT_ATTR_STABCMN, DT_VERS_1_0,
+ &dt_idops_func, "void *(struct mbuf *, size_t, [size_t])" },
{ "count", DT_IDENT_AGGFUNC, 0, DTRACEAGG_COUNT, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "void()" },
{ "curthread", DT_IDENT_SCALAR, 0, DIF_VAR_CURTHREAD,
Index: cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
===================================================================
--- cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
+++ cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh
@@ -45,7 +45,7 @@
switch (subr) {"
nawk '
-/^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" {
+/^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" && $2 != "DIF_SUBR_FBSD_MIN" && $2 != "DIF_SUBR_FBSD_MAX"{
printf("\tcase %s: return (\"%s\");\n", $2, tolower(substr($2, 10)));
}'
Index: sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -121,6 +121,7 @@
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/mbuf.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/ptrace.h>
@@ -607,6 +608,10 @@
static int dtrace_canstore_remains(uint64_t, size_t, size_t *,
dtrace_mstate_t *, dtrace_vstate_t *);
+#ifdef __FreeBSD__
+void dtrace_mbuf_copydata(const struct mbuf *m, int off, int len, uintptr_t cp);
+#endif /* __FreeBSD__ */
+
/*
* DTrace Probe Context Functions
*
@@ -1333,6 +1338,35 @@
}
/*
+ * DTrace private version of a function to copy data from an mbuf
+ * chain starting "off" bytes from the beginning, continuing for "len"
+ * bytes, into the indicated buffer.
+ */
+#ifdef __FreeBSD__
+void
+dtrace_mbuf_copydata(const struct mbuf *m, int off, int len, uintptr_t cp)
+{
+ u_int count;
+
+
+ while (off > 0) {
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ while (len > 0) {
+ count = min(m->m_len - off, len);
+ dtrace_bcopy(mtod(m, caddr_t) + off, (void *)cp, count);
+ len -= count;
+ cp += count;
+ off = 0;
+ m = m->m_next;
+ }
+}
+#endif /* __FreeBSD__ */
+
+/*
* Compare s1 to s2 using safe memory accesses. The s1 data is assumed to be
* unsafe memory specified by the DIF program. The s2 data is assumed to be
* safe memory that we can access directly because it is managed by DTrace.
@@ -4549,6 +4583,73 @@
break;
}
+#ifdef __FreeBSD__
+ case DIF_SUBR_COPYOUTMBUF: {
+ uintptr_t dest = mstate->dtms_scratch_ptr;
+ struct mbuf *m = (struct mbuf *)tupregs[0].dttk_value;
+ uint64_t len = 0;
+ size_t scratch_size = 0;
+ size_t req_size = tupregs[1].dttk_value;
+ size_t offset = 0;
+
+ if (m == NULL) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+ regs[rd] = 0;
+ break;
+ }
+
+ len = m_length(m, NULL);
+
+ /* Optional 3rd argument is an offset into the packet. */
+ if (nargs > 2) {
+ offset = tupregs[2].dttk_value;
+ /* Be strict with the offset parameter */
+ if ((offset < 0) || (offset >= len) ||
+ ((len - offset) > req_size)) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
+ regs[rd] = 0;
+ break;
+ }
+ }
+
+ len -= offset;
+ scratch_size = (dest - mstate->dtms_scratch_ptr) + len;
+
+ /*
+ * The user can request the whole buffer with arg2 <=
+ * 0 but if they request a size less than the len of
+ * the full chain we will respet their request. This
+ * code also prevents the caller from asking for more
+ * data than is present in the chain.
+ */
+
+ if ((req_size > 0) && (req_size < len)) {
+ len = req_size;
+ scratch_size = (dest - mstate->dtms_scratch_ptr) + len;
+ }
+
+ /*
+ * Rounding up the user allocation size could have overflowed
+ * a large, bogus allocation (like -1ULL) to 0.
+ */
+ if (scratch_size < len ||
+ !DTRACE_INSCRATCH(mstate, scratch_size)) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
+ regs[rd] = 0;
+ break;
+ }
+
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+ dtrace_mbuf_copydata(m, offset, len, dest);
+ DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
+
+ mstate->dtms_scratch_ptr += len;
+ regs[rd] = dest;
+ break;
+ }
+
+#endif /* __FreeBSD__ */
+
#ifdef illumos
case DIF_SUBR_MSGSIZE:
case DIF_SUBR_MSGDSIZE: {
@@ -9944,7 +10045,7 @@
err += efunc(pc, "invalid register %u\n", rd);
break;
case DIF_OP_CALL:
- if (subr > DIF_SUBR_MAX)
+ if (!VALID_SUBR(subr))
err += efunc(pc, "invalid subr %u\n", subr);
if (rd >= nregs)
err += efunc(pc, "invalid register %u\n", rd);
Index: sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -315,7 +315,25 @@
#define DIF_SUBR_GETF 51
#define DIF_SUBR_JSON 52
#define DIF_SUBR_STRTOLL 53
-#define DIF_SUBR_MAX 53 /* max subroutine value */
+#define DIF_SUBR_MAX 53 /* max common subroutine value */
+
+/*
+ * DT_ACT (action) routines are placed directly after the base
+ * subroutines. Leave space up to 200 for these.
+ */
+
+/* Leave space for Apple/xnu specific routines from 200-299 */
+
+/* FreeBSD specific subroutines */
+
+#define DIF_SUBR_FBSD_MIN 300
+#define DIF_SUBR_COPYOUTMBUF 300
+#define DIF_SUBR_FBSD_MAX 300
+
+#define VALID_SUBR(x) \
+ (((x >= 0) && (x <= DIF_SUBR_MAX)) || \
+ ((x >= DIF_SUBR_FBSD_MIN) && (x <= DIF_SUBR_FBSD_MAX)))
+
typedef uint32_t dif_instr_t;

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 2:25 AM (20 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28241523
Default Alt Text
D9988.1775096702.diff (5 KB)

Event Timeline