summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Sonnenschein <johns@joyent.com>2011-12-21 01:00:08 +0000
committerJohn Sonnenschein <johns@joyent.com>2011-12-21 01:00:08 +0000
commitfb6e21bb3f28235e9b2c406dff9f6c5d49a03128 (patch)
treefc50ff3fb0191895828671198e8ee7cb93cb5859
parent84c9e00cfac0317d1e164e792a2386a9440b833a (diff)
parente7c3f416aa65d7864d1198dcfead49a8d7583a58 (diff)
downloadillumos-joyent-fb6e21bb3f28235e9b2c406dff9f6c5d49a03128.tar.gz
Merge branch 'master' into gcc4
-rw-r--r--manifest1
-rw-r--r--usr/src/cmd/mdb/Makefile.common3
-rw-r--r--usr/src/cmd/mdb/common/modules/v8/mdb_v8.c1939
-rw-r--r--usr/src/cmd/mdb/common/modules/v8/mdb_v8_cfg.c715
-rw-r--r--usr/src/cmd/mdb/common/modules/v8/v8cfg.h53
-rw-r--r--usr/src/cmd/mdb/common/modules/v8/v8dbg.h81
-rw-r--r--usr/src/cmd/mdb/intel/ia32/v8/Makefile42
-rw-r--r--usr/src/pkg/manifests/developer-build-onbld.mf8
-rw-r--r--usr/src/tools/scripts/Makefile24
-rw-r--r--usr/src/tools/scripts/flg.flp.sh8
-rw-r--r--usr/src/tools/scripts/git-pbchk.194
-rwxr-xr-xusr/src/tools/scripts/git-pbchk.py285
-rw-r--r--usr/src/tools/scripts/nightly.sh4
-rw-r--r--usr/src/tools/scripts/webrev.120
-rw-r--r--usr/src/tools/scripts/webrev.sh258
-rw-r--r--usr/src/tools/scripts/which_scm.12
-rw-r--r--usr/src/tools/scripts/ws.sh16
-rw-r--r--usr/src/uts/common/dtrace/dtrace.c2
-rw-r--r--usr/src/uts/common/fs/zfs/dbuf.c3
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_raidz.c2
20 files changed, 3429 insertions, 131 deletions
diff --git a/manifest b/manifest
index 672c463ec5..b03f1b678d 100644
--- a/manifest
+++ b/manifest
@@ -9500,6 +9500,7 @@ f usr/lib/mdb/proc/mdb_ds.so 0555 root sys
f usr/lib/mdb/proc/mdb_test.so 0555 root sys
f usr/lib/mdb/proc/svc.configd.so 0555 root sys
f usr/lib/mdb/proc/svc.startd.so 0555 root sys
+f usr/lib/mdb/proc/v8.so 0555 root sys
d usr/lib/mdb/raw 0755 root sys
d usr/lib/mdb/raw/amd64 0755 root sys
f usr/lib/mdb/raw/amd64/dof.so 0555 root sys
diff --git a/usr/src/cmd/mdb/Makefile.common b/usr/src/cmd/mdb/Makefile.common
index 4e282bf001..3bbca8d4e0 100644
--- a/usr/src/cmd/mdb/Makefile.common
+++ b/usr/src/cmd/mdb/Makefile.common
@@ -45,7 +45,8 @@ COMMON_MODULES_PROC = \
#
COMMON_MODULES_PROC_32BIT = \
svc.configd \
- svc.startd
+ svc.startd \
+ v8
#
# MDB modules used for debugging kernels.
diff --git a/usr/src/cmd/mdb/common/modules/v8/mdb_v8.c b/usr/src/cmd/mdb/common/modules/v8/mdb_v8.c
new file mode 100644
index 0000000000..7f4d2e7110
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/v8/mdb_v8.c
@@ -0,0 +1,1939 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * mdb(1M) module for debugging the V8 JavaScript engine. This implementation
+ * makes heavy use of metadata defined in the V8 binary for inspecting in-memory
+ * structures. Canned configurations can be manually loaded for V8 binaries
+ * that predate this metadata. See mdb_v8_cfg.c for details.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/mdb_modapi.h>
+
+#include "v8dbg.h"
+#include "v8cfg.h"
+
+/*
+ * The "v8_class" and "v8_field" structures describe the C++ classes used to
+ * represent V8 heap objects.
+ */
+typedef struct v8_class {
+ struct v8_class *v8c_next; /* list linkage */
+ struct v8_class *v8c_parent; /* parent class (inheritance) */
+ struct v8_field *v8c_fields; /* array of class fields */
+ size_t v8c_start; /* offset of first class field */
+ size_t v8c_end; /* offset of first subclass field */
+ char v8c_name[64]; /* heap object class name */
+} v8_class_t;
+
+typedef struct v8_field {
+ struct v8_field *v8f_next; /* list linkage */
+ ssize_t v8f_offset; /* field offset */
+ char v8f_name[64]; /* field name */
+ boolean_t v8f_isbyte; /* 1-byte int field */
+} v8_field_t;
+
+/*
+ * Similarly, the "v8_enum" structure describes an enum from V8.
+ */
+typedef struct {
+ char v8e_name[64];
+ uint_t v8e_value;
+} v8_enum_t;
+
+/*
+ * During configuration, the dmod updates these globals with the actual set of
+ * classes, types, and frame types based on the debug metadata.
+ */
+static v8_class_t *v8_classes;
+
+static v8_enum_t v8_types[128];
+static int v8_next_type;
+
+static v8_enum_t v8_frametypes[16];
+static int v8_next_frametype;
+
+/*
+ * The following constants describe offsets from the frame pointer that are used
+ * to inspect each stack frame. They're initialized from the debug metadata.
+ */
+static ssize_t V8_OFF_FP_CONTEXT;
+static ssize_t V8_OFF_FP_MARKER;
+static ssize_t V8_OFF_FP_FUNCTION;
+static ssize_t V8_OFF_FP_ARGS;
+
+/*
+ * The following constants are used by macros defined in heap-dbg-common.h to
+ * examine the types of various V8 heap objects. In general, the macros should
+ * be preferred to using the constants directly. The values of these constants
+ * are initialized from the debug metadata.
+ */
+static intptr_t V8_FirstNonstringType;
+static intptr_t V8_IsNotStringMask;
+static intptr_t V8_StringTag;
+static intptr_t V8_NotStringTag;
+static intptr_t V8_StringEncodingMask;
+static intptr_t V8_TwoByteStringTag;
+static intptr_t V8_AsciiStringTag;
+static intptr_t V8_StringRepresentationMask;
+static intptr_t V8_SeqStringTag;
+static intptr_t V8_ConsStringTag;
+static intptr_t V8_ExternalStringTag;
+static intptr_t V8_FailureTag;
+static intptr_t V8_FailureTagMask;
+static intptr_t V8_HeapObjectTag;
+static intptr_t V8_HeapObjectTagMask;
+static intptr_t V8_SmiTag;
+static intptr_t V8_SmiTagMask;
+static intptr_t V8_SmiValueShift;
+static intptr_t V8_PointerSizeLog2;
+
+static intptr_t V8_PROP_IDX_CONTENT;
+static intptr_t V8_PROP_IDX_FIRST;
+static intptr_t V8_PROP_TYPE_FIELD;
+static intptr_t V8_PROP_FIRST_PHANTOM;
+static intptr_t V8_PROP_TYPE_MASK;
+
+/*
+ * Although we have this information in v8_classes, the following offsets are
+ * defined explicitly because they're used directly in code below.
+ */
+static ssize_t V8_OFF_FIXEDARRAY_DATA;
+static ssize_t V8_OFF_SEQASCIISTR_CHARS;
+
+static const char *V8_FIXEDARRAY_BASE;
+
+#define NODE_OFF_EXTSTR_DATA 0x4 /* see node_string.h */
+
+/*
+ * Table of constants used directly by this file.
+ */
+typedef struct v8_constant {
+ intptr_t *v8c_valp;
+ const char *v8c_symbol;
+} v8_constant_t;
+
+static v8_constant_t v8_constants[] = {
+ { &V8_OFF_FP_CONTEXT, "v8dbg_off_fp_context" },
+ { &V8_OFF_FP_FUNCTION, "v8dbg_off_fp_function" },
+ { &V8_OFF_FP_MARKER, "v8dbg_off_fp_marker" },
+ { &V8_OFF_FP_ARGS, "v8dbg_off_fp_args" },
+
+ { &V8_FirstNonstringType, "v8dbg_FirstNonstringType" },
+ { &V8_IsNotStringMask, "v8dbg_IsNotStringMask" },
+ { &V8_StringTag, "v8dbg_StringTag" },
+ { &V8_NotStringTag, "v8dbg_NotStringTag" },
+ { &V8_StringEncodingMask, "v8dbg_StringEncodingMask" },
+ { &V8_TwoByteStringTag, "v8dbg_TwoByteStringTag" },
+ { &V8_AsciiStringTag, "v8dbg_AsciiStringTag" },
+ { &V8_StringRepresentationMask, "v8dbg_StringRepresentationMask" },
+ { &V8_SeqStringTag, "v8dbg_SeqStringTag" },
+ { &V8_ConsStringTag, "v8dbg_ConsStringTag" },
+ { &V8_ExternalStringTag, "v8dbg_ExternalStringTag" },
+ { &V8_FailureTag, "v8dbg_FailureTag" },
+ { &V8_FailureTagMask, "v8dbg_FailureTagMask" },
+ { &V8_HeapObjectTag, "v8dbg_HeapObjectTag" },
+ { &V8_HeapObjectTagMask, "v8dbg_HeapObjectTagMask" },
+ { &V8_SmiTag, "v8dbg_SmiTag" },
+ { &V8_SmiTagMask, "v8dbg_SmiTagMask" },
+ { &V8_SmiValueShift, "v8dbg_SmiValueShift" },
+ { &V8_PointerSizeLog2, "v8dbg_PointerSizeLog2" },
+
+ { &V8_PROP_IDX_CONTENT, "v8dbg_prop_idx_content" },
+ { &V8_PROP_IDX_FIRST, "v8dbg_prop_idx_first" },
+ { &V8_PROP_TYPE_FIELD, "v8dbg_prop_type_field" },
+ { &V8_PROP_FIRST_PHANTOM, "v8dbg_prop_type_first_phantom" },
+ { &V8_PROP_TYPE_MASK, "v8dbg_prop_type_mask" },
+};
+
+static int v8_nconstants = sizeof (v8_constants) / sizeof (v8_constants[0]);
+
+static int autoconf_iter_symbol(mdb_symbol_t *, void *);
+static v8_class_t *conf_class_findcreate(const char *);
+static v8_field_t *conf_field_create(v8_class_t *, const char *, size_t);
+static char *conf_next_part(char *, char *);
+static int conf_update_parent(const char *);
+static int conf_update_field(v8_cfg_t *, const char *);
+static int conf_update_enum(v8_cfg_t *, const char *, const char *,
+ v8_enum_t *);
+static int conf_update_type(v8_cfg_t *, const char *);
+static int conf_update_frametype(v8_cfg_t *, const char *);
+static void conf_class_compute_offsets(v8_class_t *);
+
+static int heap_offset(const char *, const char *, ssize_t *, boolean_t);
+
+/*
+ * Invoked when this dmod is initially loaded to load the set of classes, enums,
+ * and other constants from the metadata in the target binary.
+ */
+static int
+autoconfigure(v8_cfg_t *cfgp)
+{
+ v8_class_t *clp;
+ struct v8_constant *cnp;
+ ssize_t unused;
+ int ii;
+
+ assert(v8_classes == NULL);
+
+ /*
+ * Iterate all global symbols looking for metadata.
+ */
+ if (cfgp->v8cfg_iter(cfgp, autoconf_iter_symbol, cfgp) != 0) {
+ mdb_warn("failed to autoconfigure V8 support\n");
+ return (-1);
+ }
+
+ /*
+ * By now we've configured all of the classes so we can update the
+ * "start" and "end" fields in each class with information from its
+ * parent class.
+ */
+ for (clp = v8_classes; clp != NULL; clp = clp->v8c_next) {
+ if (clp->v8c_end != (size_t)-1)
+ continue;
+
+ conf_class_compute_offsets(clp);
+ };
+
+ /*
+ * Finally, load various constants used directly in the module.
+ */
+ for (ii = 0; ii < v8_nconstants; ii++) {
+ cnp = &v8_constants[ii];
+
+ if (cfgp->v8cfg_readsym(cfgp, cnp->v8c_symbol,
+ cnp->v8c_valp) == -1) {
+ mdb_warn("failed to read \"%s\"", cnp->v8c_symbol);
+ return (-1);
+ }
+ }
+
+ if (heap_offset("SeqAsciiString", "chars", &V8_OFF_SEQASCIISTR_CHARS,
+ B_FALSE) != 0 || heap_offset("FixedArray", "data",
+ &V8_OFF_FIXEDARRAY_DATA, B_FALSE) != 0)
+ return (-1);
+
+ /*
+ * The V8 included in node v0.6 uses a FixedArrayBase class to contain
+ * the "length" field, while the one in v0.4 has no such base class and
+ * stores the field directly in FixedArray. We handle both cases here.
+ */
+ V8_FIXEDARRAY_BASE = heap_offset("FixedArray", "length", &unused,
+ B_TRUE) == 0 ? "FixedArray" : "FixedArrayBase";
+
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+autoconf_iter_symbol(mdb_symbol_t *symp, void *arg)
+{
+ v8_cfg_t *cfgp = arg;
+
+ if (strncmp(symp->sym_name, "v8dbg_parent_",
+ sizeof ("v8dbg_parent_") - 1) == 0)
+ return (conf_update_parent(symp->sym_name));
+
+ if (strncmp(symp->sym_name, "v8dbg_class_",
+ sizeof ("v8dbg_class_") - 1) == 0)
+ return (conf_update_field(cfgp, symp->sym_name));
+
+ if (strncmp(symp->sym_name, "v8dbg_type_",
+ sizeof ("v8dbg_type_") - 1) == 0)
+ return (conf_update_type(cfgp, symp->sym_name));
+
+ if (strncmp(symp->sym_name, "v8dbg_frametype_",
+ sizeof ("v8dbg_frametype_") - 1) == 0)
+ return (conf_update_frametype(cfgp, symp->sym_name));
+
+ return (0);
+}
+
+/*
+ * Extracts the next field of a string whose fields are separated by "__" (as
+ * the V8 metadata symbols are).
+ */
+static char *
+conf_next_part(char *buf, char *start)
+{
+ char *pp;
+
+ if ((pp = strstr(start, "__")) == NULL) {
+ mdb_warn("malformed symbol name: %s\n", buf);
+ return (NULL);
+ }
+
+ *pp = '\0';
+ return (pp + sizeof ("__") - 1);
+}
+
+static v8_class_t *
+conf_class_findcreate(const char *name)
+{
+ v8_class_t *clp, *iclp, **ptr;
+ int cmp;
+
+ if (v8_classes == NULL || strcmp(v8_classes->v8c_name, name) > 0) {
+ ptr = &v8_classes;
+ } else {
+ for (iclp = v8_classes; iclp->v8c_next != NULL;
+ iclp = iclp->v8c_next) {
+ cmp = strcmp(iclp->v8c_next->v8c_name, name);
+
+ if (cmp == 0)
+ return (iclp->v8c_next);
+
+ if (cmp > 0)
+ break;
+ }
+
+ ptr = &iclp->v8c_next;
+ }
+
+ if ((clp = mdb_zalloc(sizeof (*clp), UM_NOSLEEP)) == NULL)
+ return (NULL);
+
+ (void) strlcpy(clp->v8c_name, name, sizeof (clp->v8c_name));
+ clp->v8c_end = (size_t)-1;
+
+ clp->v8c_next = *ptr;
+ *ptr = clp;
+ return (clp);
+}
+
+static v8_field_t *
+conf_field_create(v8_class_t *clp, const char *name, size_t offset)
+{
+ v8_field_t *flp, *iflp;
+
+ if ((flp = mdb_zalloc(sizeof (*flp), UM_NOSLEEP)) == NULL)
+ return (NULL);
+
+ (void) strlcpy(flp->v8f_name, name, sizeof (flp->v8f_name));
+ flp->v8f_offset = offset;
+
+ if (clp->v8c_fields == NULL || clp->v8c_fields->v8f_offset > offset) {
+ flp->v8f_next = clp->v8c_fields;
+ clp->v8c_fields = flp;
+ return (flp);
+ }
+
+ for (iflp = clp->v8c_fields; iflp->v8f_next != NULL;
+ iflp = iflp->v8f_next) {
+ if (iflp->v8f_next->v8f_offset > offset)
+ break;
+ }
+
+ flp->v8f_next = iflp->v8f_next;
+ iflp->v8f_next = flp;
+ return (flp);
+}
+
+/*
+ * Given a "v8dbg_parent_X__Y", symbol, update the parent of class X to class Y.
+ * Note that neither class necessarily exists already.
+ */
+static int
+conf_update_parent(const char *symbol)
+{
+ char *pp, *qq;
+ char buf[128];
+ v8_class_t *clp, *pclp;
+
+ (void) strlcpy(buf, symbol, sizeof (buf));
+ pp = buf + sizeof ("v8dbg_parent_") - 1;
+ qq = conf_next_part(buf, pp);
+
+ if (qq == NULL)
+ return (-1);
+
+ clp = conf_class_findcreate(pp);
+ pclp = conf_class_findcreate(qq);
+
+ if (clp == NULL || pclp == NULL) {
+ mdb_warn("mdb_v8: out of memory\n");
+ return (-1);
+ }
+
+ clp->v8c_parent = pclp;
+ return (0);
+}
+
+/*
+ * Given a "v8dbg_class_CLASS__FIELD__TYPE", symbol, save field "FIELD" into
+ * class CLASS with the offset described by the symbol. Note that CLASS does
+ * not necessarily exist already.
+ */
+static int
+conf_update_field(v8_cfg_t *cfgp, const char *symbol)
+{
+ v8_class_t *clp;
+ v8_field_t *flp;
+ intptr_t offset;
+ char *pp, *qq, *tt;
+ char buf[128];
+
+ (void) strlcpy(buf, symbol, sizeof (buf));
+
+ pp = buf + sizeof ("v8dbg_class_") - 1;
+ qq = conf_next_part(buf, pp);
+
+ if (qq == NULL || (tt = conf_next_part(buf, qq)) == NULL)
+ return (-1);
+
+ if (cfgp->v8cfg_readsym(cfgp, symbol, &offset) == -1) {
+ mdb_warn("failed to read symbol \"%s\"", symbol);
+ return (-1);
+ }
+
+ if ((clp = conf_class_findcreate(pp)) == NULL ||
+ (flp = conf_field_create(clp, qq, (size_t)offset)) == NULL)
+ return (-1);
+
+ if (strcmp(tt, "int") == 0)
+ flp->v8f_isbyte = B_TRUE;
+
+ return (0);
+}
+
+static int
+conf_update_enum(v8_cfg_t *cfgp, const char *symbol, const char *name,
+ v8_enum_t *enp)
+{
+ intptr_t value;
+
+ if (cfgp->v8cfg_readsym(cfgp, symbol, &value) == -1) {
+ mdb_warn("failed to read symbol \"%s\"", symbol);
+ return (-1);
+ }
+
+ enp->v8e_value = (int)value;
+ (void) strlcpy(enp->v8e_name, name, sizeof (enp->v8e_name));
+ return (0);
+}
+
+/*
+ * Given a "v8dbg_type_TYPENAME" constant, save the type name in v8_types. Note
+ * that this enum has multiple integer values with the same string label.
+ */
+static int
+conf_update_type(v8_cfg_t *cfgp, const char *symbol)
+{
+ char *klass;
+ v8_enum_t *enp;
+ char buf[128];
+
+ if (v8_next_type > sizeof (v8_types) / sizeof (v8_types[0])) {
+ mdb_warn("too many V8 types\n");
+ return (-1);
+ }
+
+ (void) strlcpy(buf, symbol, sizeof (buf));
+
+ klass = buf + sizeof ("v8dbg_type_") - 1;
+ if (conf_next_part(buf, klass) == NULL)
+ return (-1);
+
+ enp = &v8_types[v8_next_type++];
+ return (conf_update_enum(cfgp, symbol, klass, enp));
+}
+
+/*
+ * Given a "v8dbg_frametype_TYPENAME" constant, save the frame type in
+ * v8_frametypes.
+ */
+static int
+conf_update_frametype(v8_cfg_t *cfgp, const char *symbol)
+{
+ const char *frametype;
+ v8_enum_t *enp;
+
+ if (v8_next_frametype >
+ sizeof (v8_frametypes) / sizeof (v8_frametypes[0])) {
+ mdb_warn("too many V8 frame types\n");
+ return (-1);
+ }
+
+ enp = &v8_frametypes[v8_next_frametype++];
+ frametype = symbol + sizeof ("v8dbg_frametype_") - 1;
+ return (conf_update_enum(cfgp, symbol, frametype, enp));
+}
+
+/*
+ * Now that all classes have been loaded, update the "start" and "end" fields of
+ * each class based on the values of its parent class.
+ */
+static void
+conf_class_compute_offsets(v8_class_t *clp)
+{
+ v8_field_t *flp;
+
+ assert(clp->v8c_start == 0);
+ assert(clp->v8c_end == (size_t)-1);
+
+ if (clp->v8c_parent != NULL) {
+ if (clp->v8c_parent->v8c_end == (size_t)-1)
+ conf_class_compute_offsets(clp->v8c_parent);
+
+ clp->v8c_start = clp->v8c_parent->v8c_end;
+ }
+
+ if (clp->v8c_fields == NULL) {
+ clp->v8c_end = clp->v8c_start;
+ return;
+ }
+
+ for (flp = clp->v8c_fields; flp->v8f_next != NULL; flp = flp->v8f_next)
+ ;
+
+ if (flp == NULL)
+ clp->v8c_end = clp->v8c_start;
+ else
+ clp->v8c_end = flp->v8f_offset + sizeof (uintptr_t);
+}
+
+/*
+ * Utility functions
+ */
+static int jsstr_print(uintptr_t, boolean_t, char **, size_t *);
+
+static const char *
+enum_lookup_str(v8_enum_t *enums, int val, const char *dflt)
+{
+ v8_enum_t *ep;
+
+ for (ep = enums; ep->v8e_name[0] != '\0'; ep++) {
+ if (ep->v8e_value == val)
+ return (ep->v8e_name);
+ }
+
+ return (dflt);
+}
+
+static void
+enum_print(v8_enum_t *enums)
+{
+ v8_enum_t *itp;
+
+ for (itp = enums; itp->v8e_name[0] != '\0'; itp++)
+ mdb_printf("%-30s = 0x%02x\n", itp->v8e_name, itp->v8e_value);
+}
+
+/*
+ * b[v]snprintf behave like [v]snprintf(3c), except that they update the buffer
+ * and length arguments based on how much buffer space is used by the operation.
+ * This makes it much easier to combine multiple calls in sequence without
+ * worrying about buffer overflow.
+ */
+static size_t
+bvsnprintf(char **bufp, size_t *buflenp, const char *format, va_list alist)
+{
+ size_t rv, len;
+
+ if (*buflenp == 0)
+ return (vsnprintf(NULL, 0, format, alist));
+
+ rv = vsnprintf(*bufp, *buflenp, format, alist);
+
+ len = MIN(rv, *buflenp);
+ *buflenp -= len;
+ *bufp += len;
+
+ return (len);
+}
+
+static size_t
+bsnprintf(char **bufp, size_t *buflenp, const char *format, ...)
+{
+ va_list alist;
+ size_t rv;
+
+ va_start(alist, format);
+ rv = bvsnprintf(bufp, buflenp, format, alist);
+ va_end(alist);
+
+ return (rv);
+}
+
+/*
+ * Returns in "offp" the offset of field "field" in C++ class "klass".
+ */
+static int
+heap_offset(const char *klass, const char *field, ssize_t *offp,
+ boolean_t silent)
+{
+ v8_class_t *clp;
+ v8_field_t *flp;
+
+ for (clp = v8_classes; clp != NULL; clp = clp->v8c_next) {
+ if (strcmp(klass, clp->v8c_name) == 0)
+ break;
+ }
+
+ if (clp == NULL) {
+ if (!silent)
+ mdb_warn("couldn't find class \"%s\"\n", klass);
+ return (-1);
+ }
+
+ for (flp = clp->v8c_fields; flp != NULL; flp = flp->v8f_next) {
+ if (strcmp(field, flp->v8f_name) == 0)
+ break;
+ }
+
+ if (flp == NULL) {
+ if (!silent)
+ mdb_warn("couldn't find class \"%s\" field \"%s\"\n",
+ klass, field);
+ return (-1);
+ }
+
+ *offp = V8_OFF_HEAP(flp->v8f_offset);
+ return (0);
+}
+
+/*
+ * Assuming "addr" is an instance of the C++ heap class "klass", read into *valp
+ * the pointer-sized value of field "field".
+ */
+static int
+read_heap_ptr(uintptr_t *valp, uintptr_t addr, const char *klass,
+ const char *field)
+{
+ ssize_t off;
+
+ if (heap_offset(klass, field, &off, B_FALSE) != 0)
+ return (-1);
+
+ if (mdb_vread(valp, sizeof (*valp), addr + off) == -1) {
+ mdb_warn("failed to read heap value at %p", addr + off);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Like read_heap_ptr, but assume the field is an SMI and store the actual value
+ * into *valp rather than the encoded representation.
+ */
+static int
+read_heap_smi(uintptr_t *valp, uintptr_t addr, const char *klass,
+ const char *field)
+{
+ if (read_heap_ptr(valp, addr, klass, field) != 0)
+ return (-1);
+
+ if (!V8_IS_SMI(*valp)) {
+ mdb_warn("expected SMI, got %p\n", *valp);
+ return (-1);
+ }
+
+ *valp = V8_SMI_VALUE(*valp);
+
+ return (0);
+}
+
+static int
+read_heap_double(double *valp, uintptr_t addr, const char *klass,
+ const char *field)
+{
+ ssize_t off;
+
+ if (heap_offset(klass, field, &off, B_FALSE) != 0)
+ return (-1);
+
+ if (mdb_vread(valp, sizeof (*valp), addr + off) == -1) {
+ mdb_warn("failed to read heap value at %p", addr + off);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Assuming "addr" refers to a FixedArray, return a newly-allocated array
+ * representing its contents.
+ */
+static int
+read_heap_array(uintptr_t addr, uintptr_t **retp, size_t *lenp)
+{
+ uintptr_t len;
+
+ if (read_heap_smi(&len, addr, V8_FIXEDARRAY_BASE, "length") != 0)
+ return (-1);
+
+ *lenp = len;
+
+ if (len == 0) {
+ *retp = NULL;
+ return (0);
+ }
+
+ if ((*retp = mdb_zalloc(len * sizeof (uintptr_t), UM_GC)) == NULL)
+ return (-1);
+
+ if (mdb_vread(*retp, len * sizeof (uintptr_t),
+ addr + V8_OFF_FIXEDARRAY_DATA) == -1)
+ return (-1);
+
+ return (0);
+}
+
+static int
+read_heap_byte(uint8_t *valp, uintptr_t addr, const char *klass,
+ const char *field)
+{
+ ssize_t off;
+
+ if (heap_offset(klass, field, &off, B_FALSE) != 0)
+ return (-1);
+
+ if (mdb_vread(valp, sizeof (*valp), addr + off) == -1) {
+ mdb_warn("failed to read heap value at %p", addr + off);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Given a heap object, returns in *valp the byte describing the type of the
+ * object. This is shorthand for first retrieving the Map at the start of the
+ * heap object and then retrieving the type byte from the Map object.
+ */
+static int
+read_typebyte(uint8_t *valp, uintptr_t addr)
+{
+ uintptr_t mapaddr;
+
+ if (read_heap_ptr(&mapaddr, addr, "HeapObject", "map") != 0)
+ return (-1);
+
+ if (!V8_IS_HEAPOBJECT(mapaddr)) {
+ mdb_warn("heap object map is not itself a heap object\n");
+ return (-1);
+ }
+
+ if (read_heap_byte(valp, mapaddr, "Map", "instance_attributes") == -1)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Given a heap object, returns in *valp the size of the object. For
+ * variable-size objects, returns an undefined value.
+ */
+static int
+read_size(size_t *valp, uintptr_t addr)
+{
+ uintptr_t mapaddr;
+ uint8_t size;
+
+ if (read_heap_ptr(&mapaddr, addr, "HeapObject", "map") != 0)
+ return (-1);
+
+ if (!V8_IS_HEAPOBJECT(mapaddr)) {
+ mdb_warn("heap object map is not itself a heap object\n");
+ return (-1);
+ }
+
+ if (read_heap_byte(&size, mapaddr, "Map", "instance_size") != 0)
+ return (-1);
+
+ *valp = size << V8_PointerSizeLog2;
+ return (0);
+}
+
+/*
+ * Returns in "buf" a description of the type of "addr" suitable for printing.
+ */
+static int
+obj_jstype(uintptr_t addr, char **bufp, size_t *lenp, uint8_t *typep)
+{
+ uint8_t typebyte;
+ uintptr_t strptr;
+ const char *typename;
+
+ if (V8_IS_FAILURE(addr)) {
+ if (typep)
+ *typep = 0;
+ (void) bsnprintf(bufp, lenp, "'Failure' object");
+ return (0);
+ }
+
+ if (V8_IS_SMI(addr)) {
+ if (typep)
+ *typep = 0;
+ (void) bsnprintf(bufp, lenp, "SMI: value = %d",
+ V8_SMI_VALUE(addr));
+ return (0);
+ }
+
+ if (read_typebyte(&typebyte, addr) != 0)
+ return (-1);
+
+ if (typep)
+ *typep = typebyte;
+
+ typename = enum_lookup_str(v8_types, typebyte, "<unknown>");
+ (void) bsnprintf(bufp, lenp, typename);
+
+ if (strcmp(typename, "Oddball") == 0) {
+ if (read_heap_ptr(&strptr, addr, "Oddball",
+ "to_string") != -1) {
+ (void) bsnprintf(bufp, lenp, ": \"");
+ (void) jsstr_print(strptr, B_FALSE, bufp, lenp);
+ (void) bsnprintf(bufp, lenp, "\"");
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Print out the fields of the given object that come from the given class.
+ */
+static int
+obj_print_fields(uintptr_t baddr, v8_class_t *clp)
+{
+ v8_field_t *flp;
+ uintptr_t addr, value;
+ int rv;
+ char *bufp;
+ size_t len;
+ uint8_t type;
+ char buf[256];
+
+ for (flp = clp->v8c_fields; flp != NULL; flp = flp->v8f_next) {
+ bufp = buf;
+ len = sizeof (buf);
+
+ addr = baddr + V8_OFF_HEAP(flp->v8f_offset);
+
+ if (flp->v8f_isbyte) {
+ uint8_t sv;
+ if (mdb_vread(&sv, sizeof (sv), addr) == -1) {
+ mdb_printf("%p %s (unreadable)\n",
+ addr, flp->v8f_name);
+ continue;
+ }
+
+ mdb_printf("%p %s = 0x%x\n", addr, flp->v8f_name, sv);
+ continue;
+ }
+
+ rv = mdb_vread((void *)&value, sizeof (value), addr);
+
+ if (rv != sizeof (value) ||
+ obj_jstype(value, &bufp, &len, &type) != 0) {
+ mdb_printf("%p %s (unreadable)\n", addr, flp->v8f_name);
+ continue;
+ }
+
+ if (type != 0 && V8_TYPE_STRING(type)) {
+ (void) bsnprintf(&bufp, &len, ": \"");
+ (void) jsstr_print(value, B_FALSE, &bufp, &len);
+ (void) bsnprintf(&bufp, &len, "\"");
+ }
+
+ mdb_printf("%p %s = %p (%s)\n", addr, flp->v8f_name, value,
+ buf);
+ }
+
+ return (DCMD_OK);
+}
+
+/*
+ * Print out all fields of the given object, starting with the root of the class
+ * hierarchy and working down the most specific type.
+ */
+static int
+obj_print_class(uintptr_t addr, v8_class_t *clp)
+{
+ int rv = 0;
+
+ /*
+ * If we have no fields, we just print a simple inheritance hierarchy.
+ * If we have fields but our parent doesn't, our header includes the
+ * inheritance hierarchy.
+ */
+ if (clp->v8c_end == 0) {
+ mdb_printf("%s ", clp->v8c_name);
+
+ if (clp->v8c_parent != NULL) {
+ mdb_printf("< ");
+ (void) obj_print_class(addr, clp->v8c_parent);
+ }
+
+ return (0);
+ }
+
+ mdb_printf("%p %s", addr, clp->v8c_name);
+
+ if (clp->v8c_start == 0 && clp->v8c_parent != NULL) {
+ mdb_printf(" < ");
+ (void) obj_print_class(addr, clp->v8c_parent);
+ }
+
+ mdb_printf(" {\n");
+ (void) mdb_inc_indent(4);
+
+ if (clp->v8c_start > 0 && clp->v8c_parent != NULL)
+ rv = obj_print_class(addr, clp->v8c_parent);
+
+ rv |= obj_print_fields(addr, clp);
+ (void) mdb_dec_indent(4);
+ mdb_printf("}\n");
+
+ return (rv);
+}
+
+/*
+ * Print the ASCII string for the given ASCII JS string, expanding ConsStrings
+ * and ExternalStrings as needed.
+ */
+static int jsstr_print_seq(uintptr_t, boolean_t, char **, size_t *);
+static int jsstr_print_cons(uintptr_t, boolean_t, char **, size_t *);
+static int jsstr_print_external(uintptr_t, boolean_t, char **, size_t *);
+
+static int
+jsstr_print(uintptr_t addr, boolean_t verbose, char **bufp, size_t *lenp)
+{
+ uint8_t typebyte;
+ int err = 0;
+ char *lbufp;
+ size_t llen;
+ char buf[64];
+
+ if (read_typebyte(&typebyte, addr) != 0)
+ return (0);
+
+ if (!V8_TYPE_STRING(typebyte)) {
+ (void) bsnprintf(bufp, lenp, "<not a string>");
+ return (0);
+ }
+
+ if (!V8_STRENC_ASCII(typebyte)) {
+ (void) bsnprintf(bufp, lenp, "<two-byte string>");
+ return (0);
+ }
+
+ if (verbose) {
+ lbufp = buf;
+ llen = sizeof (buf);
+ (void) obj_jstype(addr, &lbufp, &llen, NULL);
+ mdb_printf("%s\n", buf);
+ (void) mdb_inc_indent(4);
+ }
+
+ if (V8_STRREP_SEQ(typebyte))
+ err = jsstr_print_seq(addr, verbose, bufp, lenp);
+ else if (V8_STRREP_CONS(typebyte))
+ err = jsstr_print_cons(addr, verbose, bufp, lenp);
+ else if (V8_STRREP_EXT(typebyte))
+ err = jsstr_print_external(addr, verbose, bufp, lenp);
+ else {
+ (void) bsnprintf(bufp, lenp, "<unknown string type>");
+ err = -1;
+ }
+
+ if (verbose)
+ (void) mdb_dec_indent(4);
+
+ return (err);
+}
+
+static int
+jsstr_print_seq(uintptr_t addr, boolean_t verbose, char **bufp, size_t *lenp)
+{
+ uintptr_t len, rlen;
+ char buf[256];
+
+ if (read_heap_smi(&len, addr, "String", "length") != 0)
+ return (-1);
+
+ rlen = len <= sizeof (buf) - 1 ? len : sizeof (buf) - sizeof ("[...]");
+
+ if (verbose)
+ mdb_printf("length: %d, will read: %d\n", len, rlen);
+
+ buf[0] = '\0';
+
+ if (rlen > 0 && mdb_readstr(buf, rlen + 1,
+ addr + V8_OFF_SEQASCIISTR_CHARS) == -1) {
+ mdb_warn("failed to read SeqString data");
+ return (-1);
+ }
+
+ if (rlen != len)
+ (void) strlcat(buf, "[...]", sizeof (buf));
+
+ if (verbose)
+ mdb_printf("value: \"%s\"\n", buf);
+
+ (void) bsnprintf(bufp, lenp, "%s", buf);
+ return (0);
+}
+
+static int
+jsstr_print_cons(uintptr_t addr, boolean_t verbose, char **bufp, size_t *lenp)
+{
+ uintptr_t ptr1, ptr2;
+
+ if (read_heap_ptr(&ptr1, addr, "ConsString", "first") != 0 ||
+ read_heap_ptr(&ptr2, addr, "ConsString", "second") != 0)
+ return (-1);
+
+ if (verbose) {
+ mdb_printf("ptr1: %p\n", ptr1);
+ mdb_printf("ptr2: %p\n", ptr2);
+ }
+
+ if (jsstr_print(ptr1, verbose, bufp, lenp) != 0)
+ return (-1);
+
+ return (jsstr_print(ptr2, verbose, bufp, lenp));
+}
+
+static int
+jsstr_print_external(uintptr_t addr, boolean_t verbose, char **bufp,
+ size_t *lenp)
+{
+ uintptr_t ptr1, ptr2;
+ char buf[256];
+
+ if (verbose)
+ mdb_printf("assuming Node.js string\n");
+
+ if (read_heap_ptr(&ptr1, addr, "ExternalString", "resource") != 0)
+ return (-1);
+
+ if (mdb_vread(&ptr2, sizeof (ptr2),
+ ptr1 + NODE_OFF_EXTSTR_DATA) == -1) {
+ mdb_warn("failed to read node external pointer: %p",
+ ptr1 + NODE_OFF_EXTSTR_DATA);
+ return (-1);
+ }
+
+ if (mdb_readstr(buf, sizeof (buf), ptr2) == -1) {
+ mdb_warn("failed to read ExternalString data");
+ return (-1);
+ }
+
+ if (buf[0] != '\0' && !isascii(buf[0])) {
+ mdb_warn("failed to read ExternalString ascii data\n");
+ return (-1);
+ }
+
+ (void) bsnprintf(bufp, lenp, "%s", buf);
+ return (0);
+}
+
+/*
+ * Returns true if the given address refers to the "undefined" object. Returns
+ * false on failure (since we shouldn't fail on the actual "undefined" value).
+ */
+static boolean_t
+jsobj_is_undefined(uintptr_t addr)
+{
+ uint8_t type;
+ uintptr_t strptr;
+ const char *typename;
+ char buf[16];
+ char *bufp = buf;
+ size_t len = sizeof (buf);
+
+ if (read_typebyte(&type, addr) != 0)
+ return (B_FALSE);
+
+ typename = enum_lookup_str(v8_types, type, "<unknown>");
+ if (strcmp(typename, "Oddball") != 0)
+ return (B_FALSE);
+
+ if (read_heap_ptr(&strptr, addr, "Oddball", "to_string") == -1)
+ return (B_FALSE);
+
+ if (jsstr_print(strptr, B_FALSE, &bufp, &len) != 0)
+ return (B_FALSE);
+
+ return (strcmp(buf, "undefined") == 0);
+}
+
+/*
+ * Given the line endings table in "lendsp", computes the line number for the
+ * given token position and print the result into "buf". If "lendsp" is
+ * undefined, prints the token position instead.
+ */
+static int
+jsfunc_lineno(uintptr_t lendsp, uintptr_t tokpos, char *buf, size_t buflen)
+{
+ uintptr_t size, bufsz, lower, upper, ii;
+ uintptr_t *data;
+
+ if (jsobj_is_undefined(lendsp)) {
+ mdb_snprintf(buf, buflen, "position %d", tokpos);
+ return (0);
+ }
+
+ if (read_heap_smi(&size, lendsp, V8_FIXEDARRAY_BASE, "length") != 0)
+ return (-1);
+
+ bufsz = size * sizeof (data[0]);
+
+ if ((data = mdb_alloc(bufsz, UM_NOSLEEP)) == NULL) {
+ mdb_warn("failed to alloc %d bytes for FixedArray data", bufsz);
+ return (-1);
+ }
+
+ if (mdb_vread(data, bufsz, lendsp + V8_OFF_FIXEDARRAY_DATA) != bufsz) {
+ mdb_warn("failed to read FixedArray data");
+ mdb_free(data, bufsz);
+ return (-1);
+ }
+
+ lower = 0;
+ upper = size - 1;
+
+ if (tokpos > data[upper]) {
+ (void) strlcpy(buf, "position out of range", buflen);
+ mdb_free(data, bufsz);
+ return (0);
+ }
+
+ if (tokpos <= data[0]) {
+ (void) strlcpy(buf, "line 1", buflen);
+ mdb_free(data, bufsz);
+ return (0);
+ }
+
+ while (upper >= 1) {
+ ii = (lower + upper) >> 1;
+ if (tokpos > data[ii])
+ lower = ii + 1;
+ else if (tokpos <= data[ii - 1])
+ upper = ii - 1;
+ else
+ break;
+ }
+
+ (void) mdb_snprintf(buf, buflen, "line %d", ii + 1);
+ mdb_free(data, bufsz);
+ return (0);
+}
+
+/*
+ * Given a SharedFunctionInfo object, prints into bufp a name of the function
+ * suitable for printing. This function attempts to infer a name for anonymous
+ * functions.
+ */
+static int
+jsfunc_name(uintptr_t funcinfop, char **bufp, size_t *lenp)
+{
+ uintptr_t ptrp;
+ char *bufs = *bufp;
+
+ if (read_heap_ptr(&ptrp, funcinfop, "SharedFunctionInfo",
+ "name") != 0 || jsstr_print(ptrp, B_FALSE, bufp, lenp) != 0)
+ return (-1);
+
+ if (*bufp != bufs)
+ return (0);
+
+ if (read_heap_ptr(&ptrp, funcinfop, "SharedFunctionInfo",
+ "inferred_name") != 0) {
+ (void) bsnprintf(bufp, lenp, "<anonymous>");
+ return (0);
+ }
+
+ (void) bsnprintf(bufp, lenp, "<anonymous> (as ");
+ bufs = *bufp;
+
+ if (jsstr_print(ptrp, B_FALSE, bufp, lenp) != 0)
+ return (-1);
+
+ if (*bufp == bufs)
+ (void) bsnprintf(bufp, lenp, "<anon>");
+
+ (void) bsnprintf(bufp, lenp, ")");
+
+ return (0);
+}
+
+/*
+ * JavaScript-level object printing
+ */
+static int jsobj_print_number(uintptr_t, char **, size_t *);
+static int jsobj_print_oddball(uintptr_t, char **, size_t *);
+static int jsobj_print_jsobject(uintptr_t, boolean_t, int, int, char **,
+ size_t *);
+static int jsobj_print_jsarray(uintptr_t, boolean_t, int, int, char **,
+ size_t *);
+static int jsobj_print_jsfunction(uintptr_t, char **, size_t *);
+
+static int
+jsobj_print(uintptr_t addr, boolean_t printaddr, int indent, int depth,
+ char **bufp, size_t *lenp)
+{
+ uint8_t type;
+ const char *klass;
+
+ if (printaddr)
+ (void) bsnprintf(bufp, lenp, "%p: ", addr);
+
+ if (V8_IS_SMI(addr)) {
+ (void) bsnprintf(bufp, lenp, "%d", V8_SMI_VALUE(addr));
+ return (0);
+ }
+
+ if (!V8_IS_HEAPOBJECT(addr)) {
+ mdb_warn("not a heap object: %p\n", addr);
+ return (-1);
+ }
+
+ if (read_typebyte(&type, addr) != 0)
+ return (-1);
+
+ if (V8_TYPE_STRING(type))
+ return (jsstr_print(addr, B_FALSE, bufp, lenp));
+
+ klass = enum_lookup_str(v8_types, type, "<unknown>");
+ if (strcmp(klass, "HeapNumber") == 0)
+ return (jsobj_print_number(addr, bufp, lenp));
+ if (strcmp(klass, "Oddball") == 0)
+ return (jsobj_print_oddball(addr, bufp, lenp));
+ if (strcmp(klass, "JSObject") == 0)
+ return (jsobj_print_jsobject(addr, printaddr, indent, depth,
+ bufp, lenp));
+ if (strcmp(klass, "JSArray") == 0)
+ return (jsobj_print_jsarray(addr, printaddr, indent, depth,
+ bufp, lenp));
+ if (strcmp(klass, "JSFunction") == 0)
+ return (jsobj_print_jsfunction(addr, bufp, lenp));
+
+ mdb_warn("unknown JavaScript object type \"%s\"\n", klass);
+ return (-1);
+}
+
+static int
+jsobj_print_number(uintptr_t addr, char **bufp, size_t *lenp)
+{
+ double numval;
+
+ if (read_heap_double(&numval, addr, "HeapNumber", "value") == -1)
+ return (-1);
+
+ if (numval == (long long)numval)
+ (void) bsnprintf(bufp, lenp, "%lld", (long long)numval);
+ else
+ (void) bsnprintf(bufp, lenp, "%e", numval);
+
+ return (0);
+}
+
+static int
+jsobj_print_oddball(uintptr_t addr, char **bufp, size_t *lenp)
+{
+ uintptr_t strptr;
+
+ if (read_heap_ptr(&strptr, addr, "Oddball", "to_string") != 0)
+ return (-1);
+
+ return (jsstr_print(strptr, B_FALSE, bufp, lenp));
+}
+
+static int
+jsobj_print_jsobject(uintptr_t addr, boolean_t printaddr, int indent,
+ int depth, char **bufp, size_t *lenp)
+{
+ uintptr_t ptr, map;
+ uintptr_t *props, *descs, *content;
+ size_t ii, size, nprops, rndescs, ndescs, ncontent;
+ uint8_t type, ninprops;
+
+ if (depth == 0) {
+ (void) bsnprintf(bufp, lenp, "[...]");
+ return (0);
+ }
+
+ /*
+ * Objects have either "fast" properties represented with a FixedArray
+ * or slow properties represented with a Dictionary. We only support
+ * the former, so we check that up front.
+ */
+ if (read_heap_ptr(&ptr, addr, "JSObject", "properties") != 0)
+ return (-1);
+
+ if (read_typebyte(&type, ptr) != 0)
+ return (-1);
+
+ if (strcmp(enum_lookup_str(v8_types, type, ""), "FixedArray") != 0) {
+ (void) bsnprintf(bufp, lenp, "{ /* unknown property */ }");
+ return (0);
+ }
+
+ if (read_heap_array(ptr, &props, &nprops) != 0)
+ return (-1);
+
+ /*
+ * To iterate the properties, we need to examine the instance
+ * descriptors of the associated Map object. Some properties may be
+ * stored inside the object itself, in which case we need to know how
+ * big the object is and how many such properties there are.
+ */
+ if (read_heap_ptr(&map, addr, "HeapObject", "map") != 0 ||
+ read_heap_ptr(&ptr, map, "Map", "instance_descriptors") != 0 ||
+ read_heap_array(ptr, &descs, &ndescs) != 0)
+ return (-1);
+
+ if (read_size(&size, addr) != 0)
+ size = 0;
+
+ if (read_heap_byte(&ninprops, map, "Map", "inobject_properties") != 0)
+ return (-1);
+
+ if (V8_PROP_IDX_CONTENT < ndescs &&
+ read_heap_array(descs[V8_PROP_IDX_CONTENT], &content,
+ &ncontent) != 0)
+ return (-1);
+
+ (void) bsnprintf(bufp, lenp, "{");
+
+ /*
+ * The first FIRST (2) entries in the descriptors array are special.
+ */
+ rndescs = ndescs <= V8_PROP_IDX_FIRST ? 0 : ndescs - V8_PROP_IDX_FIRST;
+
+ for (ii = 0; ii < rndescs; ii++) {
+ uintptr_t keyidx, validx, detidx;
+ intptr_t val;
+
+ keyidx = V8_DESC_KEYIDX(ii);
+ validx = V8_DESC_VALIDX(ii);
+ detidx = V8_DESC_DETIDX(ii);
+
+ if (detidx >= ncontent) {
+ mdb_warn("property descriptor %d: detidx (%d) "
+ "out of bounds for content array (length %d)\n",
+ ii, detidx, ncontent);
+ continue;
+ }
+
+ if (!V8_DESC_ISFIELD(content[detidx]))
+ continue;
+
+ if (keyidx >= ndescs) {
+ mdb_warn("property descriptor %d: keyidx (%d) "
+ "out of bounds for descriptor array (length %d)\n",
+ ii, keyidx, ndescs);
+ continue;
+ }
+
+ (void) bsnprintf(bufp, lenp, "\n%*s", indent + 4, "");
+ if (jsstr_print(descs[keyidx], B_FALSE, bufp, lenp) != 0)
+ continue;
+
+ (void) bsnprintf(bufp, lenp, ": ");
+
+ val = (intptr_t)content[validx];
+
+ if (!V8_IS_SMI(val)) {
+ mdb_warn("property descriptor %d: value index value "
+ "is not an SMI: %p\n", ii, val);
+ continue;
+ }
+
+ val = V8_SMI_VALUE(val) - ninprops;
+
+ if (val < 0) {
+ /* property is stored directly in the object */
+ if (mdb_vread(&ptr, sizeof (ptr), addr + V8_OFF_HEAP(
+ size + val * sizeof (uintptr_t))) == -1) {
+ mdb_warn("failed to read in-object "
+ "property at %p\n", addr + V8_OFF_HEAP(
+ size + val * sizeof (uintptr_t)));
+ continue;
+ }
+ } else {
+ /* property should be in "props" array */
+ if (val >= nprops) {
+ mdb_warn("property descriptor %d: value index "
+ "value (%d) out of bounds (%d)\n", ii, val,
+ nprops);
+ continue;
+ }
+
+ ptr = props[val];
+ }
+
+
+ (void) jsobj_print(ptr, printaddr, indent + 4,
+ depth - 1, bufp, lenp);
+
+ (void) bsnprintf(bufp, lenp, ",");
+ }
+
+ if (ii > 0)
+ (void) bsnprintf(bufp, lenp, "\n%*s", indent, "");
+
+ (void) bsnprintf(bufp, lenp, "}");
+
+ return (DCMD_OK);
+}
+
+static int
+jsobj_print_jsarray(uintptr_t addr, boolean_t printaddr, int indent,
+ int depth, char **bufp, size_t *lenp)
+{
+ uintptr_t ptr;
+ uintptr_t *elts;
+ size_t ii, len;
+
+ if (depth == 0) {
+ (void) bsnprintf(bufp, lenp, "[...]");
+ return (0);
+ }
+
+ if (read_heap_ptr(&ptr, addr, "JSObject", "elements") != 0 ||
+ read_heap_array(ptr, &elts, &len) != 0)
+ return (-1);
+
+ if (len == 0) {
+ (void) bsnprintf(bufp, lenp, "[]");
+ return (0);
+ }
+
+ if (len == 1) {
+ (void) bsnprintf(bufp, lenp, "[ ");
+ (void) jsobj_print(elts[0], printaddr, indent + 4,
+ depth - 1, bufp, lenp);
+ (void) bsnprintf(bufp, lenp, " ]");
+ return (0);
+ }
+
+ (void) bsnprintf(bufp, lenp, "[\n");
+ for (ii = 0; ii < len; ii++) {
+ (void) bsnprintf(bufp, lenp, "%*s", indent + 4, "");
+ (void) jsobj_print(elts[ii], printaddr, indent + 4,
+ depth - 1, bufp, lenp);
+ (void) bsnprintf(bufp, lenp, ",\n");
+ }
+
+ (void) bsnprintf(bufp, lenp, "%*s", indent, "");
+ (void) bsnprintf(bufp, lenp, "]");
+
+ return (0);
+}
+
+static int
+jsobj_print_jsfunction(uintptr_t addr, char **bufp, size_t *lenp)
+{
+ uintptr_t shared;
+
+ if (read_heap_ptr(&shared, addr, "JSFunction", "shared") != 0)
+ return (-1);
+
+ (void) bsnprintf(bufp, lenp, "function ");
+ return (jsfunc_name(shared, bufp, lenp) != 0);
+}
+
+/*
+ * dcmd implementations
+ */
+
+/* ARGSUSED */
+static int
+dcmd_v8classes(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ v8_class_t *clp;
+
+ for (clp = v8_classes; clp != NULL; clp = clp->v8c_next)
+ mdb_printf("%s\n", clp->v8c_name);
+
+ return (DCMD_OK);
+}
+
+static void
+dcmd_v8print_help(void)
+{
+ mdb_printf(
+ "Prints out \".\" (a V8 heap object) as an instance of its C++\n"
+ "class. With no arguments, the appropriate class is detected\n"
+ "automatically. The 'class' argument overrides this to print an\n"
+ "object as an instance of the given class. The list of known\n"
+ "classes can be viewed with ::jsclasses.");
+}
+
+/* ARGSUSED */
+static int
+dcmd_v8print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ const char *rqclass;
+ v8_class_t *clp;
+ char *bufp;
+ size_t len;
+ uint8_t type;
+ char buf[256];
+
+ if (argc < 1) {
+ /*
+ * If no type was specified, determine it automatically.
+ */
+ bufp = buf;
+ len = sizeof (buf);
+ if (obj_jstype(addr, &bufp, &len, &type) != 0)
+ return (DCMD_ERR);
+
+ if (type == 0) {
+ /* For SMI or Failure, just print out the type. */
+ mdb_printf("%s\n", buf);
+ return (DCMD_OK);
+ }
+
+ if ((rqclass = enum_lookup_str(v8_types, type, NULL)) == NULL) {
+ mdb_warn("object has unknown type\n");
+ return (DCMD_ERR);
+ }
+ } else {
+ if (argv[0].a_type != MDB_TYPE_STRING)
+ return (DCMD_USAGE);
+
+ rqclass = argv[0].a_un.a_str;
+ }
+
+ for (clp = v8_classes; clp != NULL; clp = clp->v8c_next) {
+ if (strcmp(rqclass, clp->v8c_name) == 0)
+ break;
+ }
+
+ if (clp == NULL) {
+ mdb_warn("unknown class '%s'\n", rqclass);
+ return (DCMD_USAGE);
+ }
+
+ return (obj_print_class(addr, clp));
+}
+
+/* ARGSUSED */
+static int
+dcmd_v8type(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ char buf[64];
+ char *bufp = buf;
+ size_t len = sizeof (buf);
+
+ if (obj_jstype(addr, &bufp, &len, NULL) != 0)
+ return (DCMD_ERR);
+
+ mdb_printf("0x%p: %s\n", addr, buf);
+ return (DCMD_OK);
+}
+
+/* ARGSUSED */
+static int
+dcmd_v8types(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ enum_print(v8_types);
+ return (DCMD_OK);
+}
+
+/* ARGSUSED */
+static int
+dcmd_jsframe(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ uintptr_t ftype, funcp, funcinfop, tokpos, scriptp, lendsp, ptrp;
+ uintptr_t ii, nargs;
+ boolean_t opt_v = B_FALSE;
+ char typebuf[256];
+ char funcname[64];
+ char *bufp;
+ size_t len;
+
+ if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, B_TRUE, &opt_v,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ /*
+ * First figure out what kind of frame this is using the same algorithm
+ * as V8's ComputeType function. We only print useful information for
+ * JavaScriptFrames. Conveniently, most other frame types are indicated
+ * by the presence of a frame type identifier on the stack. For
+ * ArgumentsAdaptorFrames, the type identifier is in the "context" slot,
+ * while for other frames the type identifier is in the "marker" slot.
+ * Like V8, we check for the AdaptorFrame first, then look for other
+ * types, and if we haven't found a frame type identifier then we assume
+ * we're looking at a JavaScriptFrame.
+ */
+ if (mdb_vread(&ftype, sizeof (ftype), addr + V8_OFF_FP_CONTEXT) == -1)
+ return (DCMD_ERR);
+
+ if (!V8_IS_SMI(ftype) &&
+ mdb_vread(&ftype, sizeof (ftype), addr + V8_OFF_FP_MARKER) == -1)
+ return (DCMD_ERR);
+
+ if (V8_IS_SMI(ftype)) {
+ mdb_printf("%p <%s>\n", addr, enum_lookup_str(
+ v8_frametypes, V8_SMI_VALUE(ftype), "<unknown>"));
+ return (DCMD_OK);
+ }
+
+ if (mdb_vread(&funcp, sizeof (funcp), addr + V8_OFF_FP_FUNCTION) == -1)
+ return (DCMD_ERR);
+
+ if (read_heap_ptr(&funcinfop, funcp, "JSFunction", "shared") != 0)
+ return (DCMD_ERR);
+
+ bufp = funcname;
+ len = sizeof (funcname);
+ if (jsfunc_name(funcinfop, &bufp, &len) != 0)
+ return (DCMD_ERR);
+
+ mdb_printf("%p %s", addr, funcname);
+
+ /*
+ * Although the token position is technically an SMI, we're going to
+ * byte-compare it to other SMI values so we don't want decode it here.
+ */
+ if (read_heap_ptr(&tokpos, funcinfop,
+ "SharedFunctionInfo", "function_token_position") != 0)
+ return (DCMD_ERR);
+
+ if (read_heap_ptr(&scriptp, funcinfop,
+ "SharedFunctionInfo", "script") != 0)
+ return (DCMD_ERR);
+
+ if (read_heap_ptr(&ptrp, scriptp, "Script", "name") != 0)
+ return (DCMD_ERR);
+
+ bufp = typebuf;
+ len = sizeof (typebuf);
+ (void) jsstr_print(ptrp, B_FALSE, &bufp, &len);
+
+ if (opt_v) {
+ mdb_printf("\n");
+ (void) mdb_inc_indent(4);
+ mdb_printf("func: %p\n", funcp);
+ mdb_printf("file: %s\n", typebuf);
+ } else {
+ mdb_printf(" at %s ", typebuf);
+ }
+
+ if (read_heap_ptr(&lendsp, scriptp, "Script", "line_ends") != 0)
+ return (DCMD_ERR);
+
+ (void) jsfunc_lineno(lendsp, tokpos, typebuf, sizeof (typebuf));
+
+ if (opt_v)
+ mdb_printf("posn: %s\n", typebuf);
+ else
+ mdb_printf("%s\n", typebuf);
+
+ if (opt_v) {
+ if (read_heap_smi(&nargs, funcinfop,
+ "SharedFunctionInfo", "length") == 0) {
+ for (ii = 0; ii < nargs; ii++) {
+ uintptr_t argptr;
+
+ if (mdb_vread(&argptr, sizeof (argptr),
+ addr + V8_OFF_FP_ARGS + (nargs - ii - 1) *
+ sizeof (uintptr_t)) == -1)
+ continue;
+
+ bufp = typebuf;
+ len = sizeof (typebuf);
+ (void) obj_jstype(argptr, &bufp, &len, NULL);
+
+ mdb_printf("arg%d: %p (%s)\n", (ii + 1),
+ argptr, typebuf);
+ }
+ }
+
+ (void) mdb_dec_indent(4);
+ }
+
+ return (DCMD_OK);
+}
+
+/* ARGSUSED */
+static int
+dcmd_jsprint(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ char *buf;
+ char *bufp;
+ size_t len, bufsz = 262144;
+ boolean_t verbose;
+ uint64_t depth;
+ int rv;
+
+ verbose = B_FALSE;
+ depth = 2;
+
+ if (mdb_getopts(argc, argv,
+ 'a', MDB_OPT_SETBITS, B_TRUE, &verbose,
+ 'd', MDB_OPT_UINT64, &depth, NULL) != argc)
+ return (DCMD_USAGE);
+
+ if ((buf = mdb_zalloc(bufsz, UM_NOSLEEP)) == NULL)
+ return (DCMD_ERR);
+
+ bufp = buf;
+ len = bufsz;
+ rv = jsobj_print(addr, verbose, 0, (int)depth, &bufp, &len);
+ (void) mdb_printf("%s\n", buf);
+ mdb_free(buf, bufsz);
+ return (rv == 0 ? DCMD_OK : DCMD_ERR);
+}
+
+/* ARGSUSED */
+static int
+dcmd_v8array(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ uint8_t type;
+ uintptr_t *array;
+ size_t ii, len;
+
+ if (read_typebyte(&type, addr) != 0)
+ return (DCMD_ERR);
+
+ if (strcmp(enum_lookup_str(v8_types, type, ""), "FixedArray") != 0) {
+ mdb_warn("%p is not an instance of FixedArray\n", addr);
+ return (DCMD_ERR);
+ }
+
+ if (read_heap_array(addr, &array, &len) != 0)
+ return (DCMD_ERR);
+
+ for (ii = 0; ii < len; ii++)
+ mdb_printf("%p\n", array[ii]);
+
+ return (DCMD_OK);
+}
+
+/* ARGSUSED */
+static int
+dcmd_jsstack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ if (mdb_walk_dcmd("jsframe", "jsframe", argc, argv) == -1)
+ return (DCMD_ERR);
+
+ return (DCMD_OK);
+}
+
+/* ARGSUSED */
+static int
+dcmd_v8str(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ boolean_t opt_v = B_FALSE;
+ char buf[256];
+ char *bufp;
+ size_t len;
+
+ if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, B_TRUE, &opt_v,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ bufp = buf;
+ len = sizeof (buf);
+ if (jsstr_print(addr, opt_v, &bufp, &len) != 0)
+ return (DCMD_ERR);
+
+ mdb_printf("%s\n", buf);
+ return (DCMD_OK);
+}
+
+static void
+dcmd_v8load_help(void)
+{
+ v8_cfg_t *cfp;
+
+ mdb_printf(
+ "To traverse in-memory V8 structures, the V8 dmod requires\n"
+ "configuration that describes the layout of various V8 structures\n"
+ "in memory. Normally, this information is pulled from metadata\n"
+ "in the target binary. However, it's possible to use the module\n"
+ "with a binary not built with metadata by loading one of the\n"
+ "canned configurations.\n\n");
+
+ mdb_printf("Available configurations:\n");
+
+ (void) mdb_inc_indent(4);
+
+ for (cfp = v8_cfgs; cfp->v8cfg_name != NULL; cfp++)
+ mdb_printf("%-10s %s\n", cfp->v8cfg_name, cfp->v8cfg_label);
+
+ (void) mdb_dec_indent(4);
+}
+
+/* ARGSUSED */
+static int
+dcmd_v8load(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ v8_cfg_t *cfgp;
+
+ if (v8_classes != NULL) {
+ mdb_warn("v8 module already configured\n");
+ return (DCMD_ERR);
+ }
+
+ if (argc < 1 || argv->a_type != MDB_TYPE_STRING)
+ return (DCMD_USAGE);
+
+ for (cfgp = v8_cfgs; cfgp->v8cfg_name != NULL; cfgp++) {
+ if (strcmp(argv->a_un.a_str, cfgp->v8cfg_name) == 0)
+ break;
+ }
+
+ if (cfgp->v8cfg_name == NULL) {
+ mdb_warn("unknown configuration: \"%s\"\n", argv->a_un.a_str);
+ return (DCMD_ERR);
+ }
+
+ if (autoconfigure(cfgp) == -1) {
+ mdb_warn("autoconfigure failed\n");
+ return (DCMD_ERR);
+ }
+
+ mdb_printf("V8 dmod configured based on %s\n", cfgp->v8cfg_name);
+ return (DCMD_OK);
+}
+
+static int
+walk_jsframes_init(mdb_walk_state_t *wsp)
+{
+ mdb_tid_t tid;
+ mdb_reg_t reg;
+
+ tid = wsp->walk_addr != NULL ?
+ (mdb_tid_t)wsp->walk_addr : 1;
+
+ if (mdb_getareg(tid, "ebp", &reg) != 0) {
+ mdb_warn("failed to read ebp for thread %d", tid);
+ return (WALK_ERR);
+ }
+
+ wsp->walk_addr = (uintptr_t)reg;
+ return (WALK_NEXT);
+}
+
+static int
+walk_jsframes_step(mdb_walk_state_t *wsp)
+{
+ uintptr_t ftype, addr, next;
+ int rv;
+
+ addr = wsp->walk_addr;
+ rv = wsp->walk_callback(wsp->walk_addr, NULL, wsp->walk_cbdata);
+
+ if (rv != WALK_NEXT)
+ return (rv);
+
+ /*
+ * Figure out the type of this frame.
+ */
+ if (mdb_vread(&ftype, sizeof (ftype), addr + V8_OFF_FP_MARKER) == -1)
+ return (WALK_ERR);
+
+ if (V8_IS_SMI(ftype) && V8_SMI_VALUE(ftype) == 0)
+ return (WALK_DONE);
+
+ if (mdb_vread(&next, sizeof (next), addr) == -1)
+ return (WALK_ERR);
+
+ wsp->walk_addr = next;
+ return (WALK_NEXT);
+}
+
+/*
+ * MDB linkage
+ */
+
+static const mdb_dcmd_t v8_mdb_dcmds[] = {
+ /*
+ * Commands to inspect JavaScript-level state
+ */
+ { "jsframe", ":[-v]", "summarize a JavaScript stack frame",
+ dcmd_jsframe },
+ { "jsprint", ":[-a] [-d depth]", "print a JavaScript object",
+ dcmd_jsprint },
+ { "jsstack", "[-v]", "print a JavaScript stacktrace",
+ dcmd_jsstack },
+
+ /*
+ * Commands to inspect V8-level state
+ */
+ { "v8array", ":", "print elements of a V8 FixedArray",
+ dcmd_v8array },
+ { "v8classes", NULL, "list known V8 heap object C++ classes",
+ dcmd_v8classes },
+ { "v8load", "version", "load canned config for a specific V8 version",
+ dcmd_v8load, dcmd_v8load_help },
+ { "v8print", ":[class]", "print a V8 heap object",
+ dcmd_v8print, dcmd_v8print_help },
+ { "v8str", ":[-v]", "print the contents of a V8 string",
+ dcmd_v8str },
+ { "v8type", ":", "print the type of a V8 heap object",
+ dcmd_v8type },
+ { "v8types", NULL, "list known V8 heap object types",
+ dcmd_v8types },
+
+ { NULL }
+};
+
+static const mdb_walker_t v8_mdb_walkers[] = {
+ { "jsframe", "walk V8 JavaScript stack frames",
+ walk_jsframes_init, walk_jsframes_step },
+ { NULL }
+};
+
+static mdb_modinfo_t v8_mdb = { MDB_API_VERSION, v8_mdb_dcmds, v8_mdb_walkers };
+
+const mdb_modinfo_t *
+_mdb_init(void)
+{
+ GElf_Sym sym;
+
+ /*
+ * Do a quick check first for debug metadata included in the binary. If
+ * it's there, we autoconfigure based on this metadata. If not, we
+ * assume this is not a V8 binary and there's nothing for us to do. If
+ * there's no metadata but this really is V8, the user can attempt to
+ * load a canned configuration using ::v8load.
+ */
+ if (mdb_lookup_by_name("v8dbg_SmiTag", &sym) == 0) {
+ if (autoconfigure(&v8_cfg_target) != 0)
+ mdb_warn("failed to autoconfigure from target\n");
+ else
+ mdb_printf("Loaded V8 support.\n");
+ }
+
+ return (&v8_mdb);
+}
diff --git a/usr/src/cmd/mdb/common/modules/v8/mdb_v8_cfg.c b/usr/src/cmd/mdb/common/modules/v8/mdb_v8_cfg.c
new file mode 100644
index 0000000000..05d25b65d6
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/v8/mdb_v8_cfg.c
@@ -0,0 +1,715 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * mdb_v8_cfg.c: canned configurations for previous V8 versions.
+ *
+ * The functions and data defined here enable this dmod to support debugging
+ * Node.js binaries that predated V8's built-in postmortem debugging support.
+ */
+
+#include "v8cfg.h"
+
+/*ARGSUSED*/
+static int
+v8cfg_target_iter(v8_cfg_t *cfgp, int (*func)(mdb_symbol_t *, void *),
+ void *arg)
+{
+ return (mdb_symbol_iter(MDB_OBJ_EVERY, MDB_SYMTAB,
+ MDB_BIND_GLOBAL | MDB_TYPE_OBJECT | MDB_TYPE_FUNC,
+ func, arg));
+}
+
+/*ARGSUSED*/
+static int
+v8cfg_target_readsym(v8_cfg_t *cfgp, const char *name, intptr_t *valp)
+{
+ return (mdb_readsym(valp, sizeof (valp), name));
+}
+
+/*
+ * Analog of mdb_symbol_iter() for a canned configuration.
+ */
+static int
+v8cfg_canned_iter(v8_cfg_t *cfgp, int (*func)(mdb_symbol_t *, void *),
+ void *arg)
+{
+ v8_cfg_symbol_t *v8sym;
+ mdb_symbol_t mdbsym;
+ int rv;
+
+ for (v8sym = cfgp->v8cfg_symbols; v8sym->v8cs_name != NULL; v8sym++) {
+ mdbsym.sym_name = v8sym->v8cs_name;
+ mdbsym.sym_object = NULL;
+ mdbsym.sym_sym = NULL;
+ mdbsym.sym_table = 0;
+ mdbsym.sym_id = 0;
+
+ if ((rv = func(&mdbsym, arg)) != 0)
+ return (rv);
+ }
+
+ return (0);
+}
+
+/*
+ * Analog of mdb_readsym() for a canned configuration.
+ */
+static int
+v8cfg_canned_readsym(v8_cfg_t *cfgp, const char *name, intptr_t *valp)
+{
+ v8_cfg_symbol_t *v8sym;
+
+ for (v8sym = cfgp->v8cfg_symbols; v8sym->v8cs_name != NULL; v8sym++) {
+ if (strcmp(name, v8sym->v8cs_name) == 0)
+ break;
+ }
+
+ if (v8sym->v8cs_name == NULL) {
+ mdb_warn("no such canned symbol: %s\n", name);
+ return (-1);
+ }
+
+ *valp = v8sym->v8cs_value;
+ return (0);
+}
+
+/*
+ * Canned configuration for the V8 bundled with Node.js v0.4.8 and later.
+ */
+static v8_cfg_symbol_t v8_cfg_node_04[] = {
+ { "v8dbg_type_AccessCheckInfo__ACCESS_CHECK_INFO_TYPE", 0x91 },
+ { "v8dbg_type_AccessorInfo__ACCESSOR_INFO_TYPE", 0x90 },
+ { "v8dbg_type_BreakPointInfo__BREAK_POINT_INFO_TYPE", 0x9b },
+ { "v8dbg_type_ByteArray__BYTE_ARRAY_TYPE", 0x86 },
+ { "v8dbg_type_CallHandlerInfo__CALL_HANDLER_INFO_TYPE", 0x93 },
+ { "v8dbg_type_Code__CODE_TYPE", 0x81 },
+ { "v8dbg_type_CodeCache__CODE_CACHE_TYPE", 0x99 },
+ { "v8dbg_type_ConsString__CONS_ASCII_STRING_TYPE", 0x5 },
+ { "v8dbg_type_ConsString__CONS_ASCII_SYMBOL_TYPE", 0x45 },
+ { "v8dbg_type_ConsString__CONS_STRING_TYPE", 0x1 },
+ { "v8dbg_type_ConsString__CONS_SYMBOL_TYPE", 0x41 },
+ { "v8dbg_type_DebugInfo__DEBUG_INFO_TYPE", 0x9a },
+ { "v8dbg_type_ExternalAsciiString__EXTERNAL_ASCII_STRING_TYPE", 0x6 },
+ { "v8dbg_type_ExternalAsciiString__EXTERNAL_ASCII_SYMBOL_TYPE", 0x46 },
+ { "v8dbg_type_ExternalByteArray__EXTERNAL_BYTE_ARRAY_TYPE", 0x88 },
+ { "v8dbg_type_ExternalFloatArray__EXTERNAL_FLOAT_ARRAY_TYPE", 0x8e },
+ { "v8dbg_type_ExternalIntArray__EXTERNAL_INT_ARRAY_TYPE", 0x8c },
+ { "v8dbg_type_ExternalShortArray__EXTERNAL_SHORT_ARRAY_TYPE", 0x8a },
+ { "v8dbg_type_ExternalString__EXTERNAL_STRING_TYPE", 0x2 },
+ { "v8dbg_type_ExternalString__EXTERNAL_SYMBOL_TYPE", 0x42 },
+ { "v8dbg_type_ExternalUnsignedByteArray__"
+ "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", 0x89 },
+ { "v8dbg_type_ExternalUnsignedIntArray__"
+ "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", 0x8d },
+ { "v8dbg_type_ExternalUnsignedShortArray__"
+ "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", 0x8b },
+ { "v8dbg_type_FixedArray__FIXED_ARRAY_TYPE", 0x9c },
+ { "v8dbg_type_FunctionTemplateInfo__"
+ "FUNCTION_TEMPLATE_INFO_TYPE", 0x94 },
+ { "v8dbg_type_HeapNumber__HEAP_NUMBER_TYPE", 0x84 },
+ { "v8dbg_type_InterceptorInfo__INTERCEPTOR_INFO_TYPE", 0x92 },
+ { "v8dbg_type_JSArray__JS_ARRAY_TYPE", 0xa5 },
+ { "v8dbg_type_JSBuiltinsObject__JS_BUILTINS_OBJECT_TYPE", 0xa3 },
+ { "v8dbg_type_JSFunction__JS_FUNCTION_TYPE", 0xa7 },
+ { "v8dbg_type_JSGlobalObject__JS_GLOBAL_OBJECT_TYPE", 0xa2 },
+ { "v8dbg_type_JSGlobalPropertyCell__"
+ "JS_GLOBAL_PROPERTY_CELL_TYPE", 0x83 },
+ { "v8dbg_type_JSGlobalProxy__JS_GLOBAL_PROXY_TYPE", 0xa4 },
+ { "v8dbg_type_JSMessageObject__JS_MESSAGE_OBJECT_TYPE", 0x9e },
+ { "v8dbg_type_JSObject__JS_OBJECT_TYPE", 0xa0 },
+ { "v8dbg_type_JSRegExp__JS_REGEXP_TYPE", 0xa6 },
+ { "v8dbg_type_JSValue__JS_VALUE_TYPE", 0x9f },
+ { "v8dbg_type_Map__MAP_TYPE", 0x80 },
+ { "v8dbg_type_ObjectTemplateInfo__OBJECT_TEMPLATE_INFO_TYPE", 0x95 },
+ { "v8dbg_type_Oddball__ODDBALL_TYPE", 0x82 },
+ { "v8dbg_type_Script__SCRIPT_TYPE", 0x98 },
+ { "v8dbg_type_SeqAsciiString__ASCII_STRING_TYPE", 0x4 },
+ { "v8dbg_type_SeqAsciiString__ASCII_SYMBOL_TYPE", 0x44 },
+ { "v8dbg_type_SharedFunctionInfo__SHARED_FUNCTION_INFO_TYPE", 0x9d },
+ { "v8dbg_type_SignatureInfo__SIGNATURE_INFO_TYPE", 0x96 },
+ { "v8dbg_type_String__STRING_TYPE", 0x0 },
+ { "v8dbg_type_String__SYMBOL_TYPE", 0x40 },
+ { "v8dbg_type_TypeSwitchInfo__TYPE_SWITCH_INFO_TYPE", 0x97 },
+
+ { "v8dbg_class_AccessCheckInfo__data__Object", 0xc },
+ { "v8dbg_class_AccessCheckInfo__indexed_callback__Object", 0x8 },
+ { "v8dbg_class_AccessCheckInfo__named_callback__Object", 0x4 },
+ { "v8dbg_class_AccessorInfo__data__Object", 0xc },
+ { "v8dbg_class_AccessorInfo__flag__Smi", 0x14 },
+ { "v8dbg_class_AccessorInfo__getter__Object", 0x4 },
+ { "v8dbg_class_AccessorInfo__name__Object", 0x10 },
+ { "v8dbg_class_AccessorInfo__setter__Object", 0x8 },
+ { "v8dbg_class_BreakPointInfo__break_point_objects__Object", 0x10 },
+ { "v8dbg_class_BreakPointInfo__code_position__Smi", 0x4 },
+ { "v8dbg_class_BreakPointInfo__source_position__Smi", 0x8 },
+ { "v8dbg_class_BreakPointInfo__statement_position__Smi", 0xc },
+ { "v8dbg_class_ByteArray__length__SMI", 0x4 },
+ { "v8dbg_class_CallHandlerInfo__callback__Object", 0x4 },
+ { "v8dbg_class_CallHandlerInfo__data__Object", 0x8 },
+ { "v8dbg_class_Code__deoptimization_data__FixedArray", 0xc },
+ { "v8dbg_class_Code__relocation_info__ByteArray", 0x8 },
+ { "v8dbg_class_CodeCache__default_cache__FixedArray", 0x4 },
+ { "v8dbg_class_CodeCache__normal_type_cache__Object", 0x8 },
+ { "v8dbg_class_ConsString__first__String", 0xc },
+ { "v8dbg_class_ConsString__second__String", 0x10 },
+ { "v8dbg_class_DebugInfo__break_points__FixedArray", 0x14 },
+ { "v8dbg_class_DebugInfo__code__Code", 0xc },
+ { "v8dbg_class_DebugInfo__original_code__Code", 0x8 },
+ { "v8dbg_class_DebugInfo__shared__SharedFunctionInfo", 0x4 },
+ { "v8dbg_class_ExternalString__resource__Object", 0xc },
+ { "v8dbg_class_FixedArray__data__uintptr_t", 0x8 },
+ { "v8dbg_class_FixedArray__length__SMI", 0x4 },
+ { "v8dbg_class_FunctionTemplateInfo__access_check_info__Object", 0x38 },
+ { "v8dbg_class_FunctionTemplateInfo__call_code__Object", 0x10 },
+ { "v8dbg_class_FunctionTemplateInfo__class_name__Object", 0x2c },
+ { "v8dbg_class_FunctionTemplateInfo__flag__Smi", 0x3c },
+ { "v8dbg_class_FunctionTemplateInfo__"
+ "indexed_property_handler__Object", 0x24 },
+ { "v8dbg_class_FunctionTemplateInfo__"
+ "instance_call_handler__Object", 0x34 },
+ { "v8dbg_class_FunctionTemplateInfo__instance_template__Object", 0x28 },
+ { "v8dbg_class_FunctionTemplateInfo__"
+ "named_property_handler__Object", 0x20 },
+ { "v8dbg_class_FunctionTemplateInfo__parent_template__Object", 0x1c },
+ { "v8dbg_class_FunctionTemplateInfo__"
+ "property_accessors__Object", 0x14 },
+ { "v8dbg_class_FunctionTemplateInfo__"
+ "prototype_template__Object", 0x18 },
+ { "v8dbg_class_FunctionTemplateInfo__serial_number__Object", 0xc },
+ { "v8dbg_class_FunctionTemplateInfo__signature__Object", 0x30 },
+ { "v8dbg_class_GlobalObject__builtins__JSBuiltinsObject", 0xc },
+ { "v8dbg_class_GlobalObject__global_context__Context", 0x10 },
+ { "v8dbg_class_GlobalObject__global_receiver__JSObject", 0x14 },
+ { "v8dbg_class_HeapNumber__value__SMI", 0x4 },
+ { "v8dbg_class_HeapObject__map__Map", 0x0 },
+ { "v8dbg_class_InterceptorInfo__data__Object", 0x18 },
+ { "v8dbg_class_InterceptorInfo__deleter__Object", 0x10 },
+ { "v8dbg_class_InterceptorInfo__enumerator__Object", 0x14 },
+ { "v8dbg_class_InterceptorInfo__getter__Object", 0x4 },
+ { "v8dbg_class_InterceptorInfo__query__Object", 0xc },
+ { "v8dbg_class_InterceptorInfo__setter__Object", 0x8 },
+ { "v8dbg_class_JSArray__length__Object", 0xc },
+ { "v8dbg_class_JSFunction__literals__FixedArray", 0x1c },
+ { "v8dbg_class_JSFunction__next_function_link__Object", 0x20 },
+ { "v8dbg_class_JSFunction__prototype_or_initial_map__Object", 0x10 },
+ { "v8dbg_class_JSFunction__shared__SharedFunctionInfo", 0x14 },
+ { "v8dbg_class_JSGlobalProxy__context__Object", 0xc },
+ { "v8dbg_class_JSMessageObject__arguments__JSArray", 0x10 },
+ { "v8dbg_class_JSMessageObject__end_position__SMI", 0x24 },
+ { "v8dbg_class_JSMessageObject__script__Object", 0x14 },
+ { "v8dbg_class_JSMessageObject__stack_frames__Object", 0x1c },
+ { "v8dbg_class_JSMessageObject__stack_trace__Object", 0x18 },
+ { "v8dbg_class_JSMessageObject__start_position__SMI", 0x20 },
+ { "v8dbg_class_JSMessageObject__type__String", 0xc },
+ { "v8dbg_class_JSObject__elements__Object", 0x8 },
+ { "v8dbg_class_JSObject__properties__FixedArray", 0x4 },
+ { "v8dbg_class_JSRegExp__data__Object", 0xc },
+ { "v8dbg_class_JSValue__value__Object", 0xc },
+ { "v8dbg_class_Map__code_cache__Object", 0x18 },
+ { "v8dbg_class_Map__constructor__Object", 0x10 },
+ { "v8dbg_class_Map__inobject_properties__int", 0x5 },
+ { "v8dbg_class_Map__instance_size__int", 0x4 },
+ { "v8dbg_class_Map__instance_attributes__int", 0x8 },
+ { "v8dbg_class_Map__instance_descriptors__DescriptorArray", 0x14 },
+ { "v8dbg_class_ObjectTemplateInfo__constructor__Object", 0xc },
+ { "v8dbg_class_ObjectTemplateInfo__"
+ "internal_field_count__Object", 0x10 },
+ { "v8dbg_class_Oddball__to_number__Object", 0x8 },
+ { "v8dbg_class_Oddball__to_string__String", 0x4 },
+ { "v8dbg_class_Script__column_offset__Smi", 0x10 },
+ { "v8dbg_class_Script__compilation_type__Smi", 0x24 },
+ { "v8dbg_class_Script__context_data__Object", 0x18 },
+ { "v8dbg_class_Script__data__Object", 0x14 },
+ { "v8dbg_class_Script__eval_from_instructions_offset__Smi", 0x34 },
+ { "v8dbg_class_Script__eval_from_shared__Object", 0x30 },
+ { "v8dbg_class_Script__id__Object", 0x2c },
+ { "v8dbg_class_Script__line_ends__Object", 0x28 },
+ { "v8dbg_class_Script__line_offset__Smi", 0xc },
+ { "v8dbg_class_Script__name__Object", 0x8 },
+ { "v8dbg_class_Script__source__Object", 0x4 },
+ { "v8dbg_class_Script__type__Smi", 0x20 },
+ { "v8dbg_class_Script__wrapper__Proxy", 0x1c },
+ { "v8dbg_class_SeqAsciiString__chars__char", 0xc },
+ { "v8dbg_class_SharedFunctionInfo__compiler_hints__SMI", 0x50 },
+ { "v8dbg_class_SharedFunctionInfo__construct_stub__Code", 0x10 },
+ { "v8dbg_class_SharedFunctionInfo__debug_info__Object", 0x20 },
+ { "v8dbg_class_SharedFunctionInfo__end_position__SMI", 0x48 },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "expected_nof_properties__SMI", 0x3c },
+ { "v8dbg_class_SharedFunctionInfo__formal_parameter_count__SMI", 0x38 },
+ { "v8dbg_class_SharedFunctionInfo__function_data__Object", 0x18 },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "function_token_position__SMI", 0x4c },
+ { "v8dbg_class_SharedFunctionInfo__inferred_name__String", 0x24 },
+ { "v8dbg_class_SharedFunctionInfo__initial_map__Object", 0x28 },
+ { "v8dbg_class_SharedFunctionInfo__instance_class_name__Object", 0x14 },
+ { "v8dbg_class_SharedFunctionInfo__length__SMI", 0x34 },
+ { "v8dbg_class_SharedFunctionInfo__name__Object", 0x4 },
+ { "v8dbg_class_SharedFunctionInfo__num_literals__SMI", 0x40 },
+ { "v8dbg_class_SharedFunctionInfo__opt_count__SMI", 0x58 },
+ { "v8dbg_class_SharedFunctionInfo__script__Object", 0x1c },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "start_position_and_type__SMI", 0x44 },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "this_property_assignments__Object", 0x2c },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "this_property_assignments_count__SMI", 0x54 },
+ { "v8dbg_class_SignatureInfo__args__Object", 0x8 },
+ { "v8dbg_class_SignatureInfo__receiver__Object", 0x4 },
+ { "v8dbg_class_String__length__SMI", 0x4 },
+ { "v8dbg_class_TemplateInfo__property_list__Object", 0x8 },
+ { "v8dbg_class_TemplateInfo__tag__Object", 0x4 },
+ { "v8dbg_class_TypeSwitchInfo__types__Object", 0x4 },
+
+ { "v8dbg_parent_AccessCheckInfo__Struct", 0x0 },
+ { "v8dbg_parent_AccessorInfo__Struct", 0x0 },
+ { "v8dbg_parent_BreakPointInfo__Struct", 0x0 },
+ { "v8dbg_parent_ByteArray__HeapObject", 0x0 },
+ { "v8dbg_parent_CallHandlerInfo__Struct", 0x0 },
+ { "v8dbg_parent_Code__HeapObject", 0x0 },
+ { "v8dbg_parent_CodeCache__Struct", 0x0 },
+ { "v8dbg_parent_ConsString__String", 0x0 },
+ { "v8dbg_parent_DebugInfo__Struct", 0x0 },
+ { "v8dbg_parent_DeoptimizationInputData__FixedArray", 0x0 },
+ { "v8dbg_parent_DeoptimizationOutputData__FixedArray", 0x0 },
+ { "v8dbg_parent_DescriptorArray__FixedArray", 0x0 },
+ { "v8dbg_parent_ExternalArray__HeapObject", 0x0 },
+ { "v8dbg_parent_ExternalAsciiString__ExternalString", 0x0 },
+ { "v8dbg_parent_ExternalByteArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalFloatArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalIntArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalShortArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalString__String", 0x0 },
+ { "v8dbg_parent_ExternalTwoByteString__ExternalString", 0x0 },
+ { "v8dbg_parent_ExternalUnsignedByteArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalUnsignedIntArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalUnsignedShortArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_Failure__MaybeObject", 0x0 },
+ { "v8dbg_parent_FixedArray__HeapObject", 0x0 },
+ { "v8dbg_parent_FunctionTemplateInfo__TemplateInfo", 0x0 },
+ { "v8dbg_parent_GlobalObject__JSObject", 0x0 },
+ { "v8dbg_parent_HeapNumber__HeapObject", 0x0 },
+ { "v8dbg_parent_HeapObject__Object", 0x0 },
+ { "v8dbg_parent_InterceptorInfo__Struct", 0x0 },
+ { "v8dbg_parent_JSArray__JSObject", 0x0 },
+ { "v8dbg_parent_JSBuiltinsObject__GlobalObject", 0x0 },
+ { "v8dbg_parent_JSFunction__JSObject", 0x0 },
+ { "v8dbg_parent_JSFunctionResultCache__FixedArray", 0x0 },
+ { "v8dbg_parent_JSGlobalObject__GlobalObject", 0x0 },
+ { "v8dbg_parent_JSGlobalPropertyCell__HeapObject", 0x0 },
+ { "v8dbg_parent_JSGlobalProxy__JSObject", 0x0 },
+ { "v8dbg_parent_JSMessageObject__JSObject", 0x0 },
+ { "v8dbg_parent_JSObject__HeapObject", 0x0 },
+ { "v8dbg_parent_JSRegExp__JSObject", 0x0 },
+ { "v8dbg_parent_JSRegExpResult__JSArray", 0x0 },
+ { "v8dbg_parent_JSValue__JSObject", 0x0 },
+ { "v8dbg_parent_Map__HeapObject", 0x0 },
+ { "v8dbg_parent_NormalizedMapCache__FixedArray", 0x0 },
+ { "v8dbg_parent_Object__MaybeObject", 0x0 },
+ { "v8dbg_parent_ObjectTemplateInfo__TemplateInfo", 0x0 },
+ { "v8dbg_parent_Oddball__HeapObject", 0x0 },
+ { "v8dbg_parent_Script__Struct", 0x0 },
+ { "v8dbg_parent_SeqAsciiString__SeqString", 0x0 },
+ { "v8dbg_parent_SeqString__String", 0x0 },
+ { "v8dbg_parent_SeqTwoByteString__SeqString", 0x0 },
+ { "v8dbg_parent_SharedFunctionInfo__HeapObject", 0x0 },
+ { "v8dbg_parent_SignatureInfo__Struct", 0x0 },
+ { "v8dbg_parent_Smi__Object", 0x0 },
+ { "v8dbg_parent_String__HeapObject", 0x0 },
+ { "v8dbg_parent_Struct__HeapObject", 0x0 },
+ { "v8dbg_parent_TemplateInfo__Struct", 0x0 },
+ { "v8dbg_parent_TypeSwitchInfo__Struct", 0x0 },
+
+ { "v8dbg_frametype_ArgumentsAdaptorFrame", 0x8 },
+ { "v8dbg_frametype_ConstructFrame", 0x7 },
+ { "v8dbg_frametype_EntryConstructFrame", 0x2 },
+ { "v8dbg_frametype_EntryFrame", 0x1 },
+ { "v8dbg_frametype_ExitFrame", 0x3 },
+ { "v8dbg_frametype_InternalFrame", 0x6 },
+ { "v8dbg_frametype_JavaScriptFrame", 0x4 },
+ { "v8dbg_frametype_OptimizedFrame", 0x5 },
+
+ { "v8dbg_off_fp_context", -0x4 },
+ { "v8dbg_off_fp_function", -0x8 },
+ { "v8dbg_off_fp_marker", -0x8 },
+ { "v8dbg_off_fp_args", 0x8 },
+
+ { "v8dbg_prop_idx_content", 0x0 },
+ { "v8dbg_prop_idx_first", 0x2 },
+ { "v8dbg_prop_type_field", 0x1 },
+ { "v8dbg_prop_type_first_phantom", 0x6 },
+ { "v8dbg_prop_type_mask", 0xf },
+
+ { "v8dbg_AsciiStringTag", 0x4 },
+ { "v8dbg_ConsStringTag", 0x1 },
+ { "v8dbg_ExternalStringTag", 0x2 },
+ { "v8dbg_FailureTag", 0x3 },
+ { "v8dbg_FailureTagMask", 0x3 },
+ { "v8dbg_FirstNonstringType", 0x80 },
+ { "v8dbg_HeapObjectTag", 0x1 },
+ { "v8dbg_HeapObjectTagMask", 0x3 },
+ { "v8dbg_IsNotStringMask", 0x80 },
+ { "v8dbg_NotStringTag", 0x80 },
+ { "v8dbg_SeqStringTag", 0x0 },
+ { "v8dbg_SmiTag", 0x0 },
+ { "v8dbg_SmiTagMask", 0x1 },
+ { "v8dbg_SmiValueShift", 0x1 },
+ { "v8dbg_StringEncodingMask", 0x4 },
+ { "v8dbg_StringRepresentationMask", 0x3 },
+ { "v8dbg_StringTag", 0x0 },
+ { "v8dbg_TwoByteStringTag", 0x0 },
+ { "v8dbg_PointerSizeLog2", 0x2 },
+
+ { NULL }
+};
+
+/*
+ * Canned configuration for the V8 bundled with Node.js v0.6.5.
+ */
+static v8_cfg_symbol_t v8_cfg_node_065[] = {
+ { "v8dbg_type_AccessCheckInfo__ACCESS_CHECK_INFO_TYPE", 0x93 },
+ { "v8dbg_type_AccessorInfo__ACCESSOR_INFO_TYPE", 0x92 },
+ { "v8dbg_type_BreakPointInfo__BREAK_POINT_INFO_TYPE", 0x9e },
+ { "v8dbg_type_ByteArray__BYTE_ARRAY_TYPE", 0x86 },
+ { "v8dbg_type_CallHandlerInfo__CALL_HANDLER_INFO_TYPE", 0x95 },
+ { "v8dbg_type_Code__CODE_TYPE", 0x81 },
+ { "v8dbg_type_CodeCache__CODE_CACHE_TYPE", 0x9b },
+ { "v8dbg_type_ConsString__CONS_ASCII_STRING_TYPE", 0x5 },
+ { "v8dbg_type_ConsString__CONS_ASCII_SYMBOL_TYPE", 0x45 },
+ { "v8dbg_type_ConsString__CONS_STRING_TYPE", 0x1 },
+ { "v8dbg_type_ConsString__CONS_SYMBOL_TYPE", 0x41 },
+ { "v8dbg_type_DebugInfo__DEBUG_INFO_TYPE", 0x9d },
+ { "v8dbg_type_ExternalAsciiString__EXTERNAL_ASCII_STRING_TYPE", 0x6 },
+ { "v8dbg_type_ExternalAsciiString__EXTERNAL_ASCII_SYMBOL_TYPE", 0x46 },
+ { "v8dbg_type_ExternalByteArray__EXTERNAL_BYTE_ARRAY_TYPE", 0x87 },
+ { "v8dbg_type_ExternalDoubleArray__EXTERNAL_DOUBLE_ARRAY_TYPE", 0x8e },
+ { "v8dbg_type_ExternalFloatArray__EXTERNAL_FLOAT_ARRAY_TYPE", 0x8d },
+ { "v8dbg_type_ExternalIntArray__EXTERNAL_INT_ARRAY_TYPE", 0x8b },
+ { "v8dbg_type_ExternalPixelArray__EXTERNAL_PIXEL_ARRAY_TYPE", 0x8f },
+ { "v8dbg_type_ExternalShortArray__EXTERNAL_SHORT_ARRAY_TYPE", 0x89 },
+ { "v8dbg_type_ExternalTwoByteString__EXTERNAL_STRING_TYPE", 0x2 },
+ { "v8dbg_type_ExternalTwoByteString__EXTERNAL_SYMBOL_TYPE", 0x42 },
+ { "v8dbg_type_ExternalUnsignedByteArray__"
+ "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", 0x88 },
+ { "v8dbg_type_ExternalUnsignedIntArray__"
+ "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", 0x8c },
+ { "v8dbg_type_ExternalUnsignedShortArray__"
+ "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", 0x8a },
+ { "v8dbg_type_FixedArray__FIXED_ARRAY_TYPE", 0x9f },
+ { "v8dbg_type_FixedDoubleArray__FIXED_DOUBLE_ARRAY_TYPE", 0x90 },
+ { "v8dbg_type_Foreign__FOREIGN_TYPE", 0x85 },
+ { "v8dbg_type_FunctionTemplateInfo__FUNCTION_TEMPLATE_INFO_TYPE",
+ 0x96 },
+ { "v8dbg_type_HeapNumber__HEAP_NUMBER_TYPE", 0x84 },
+ { "v8dbg_type_InterceptorInfo__INTERCEPTOR_INFO_TYPE", 0x94 },
+ { "v8dbg_type_JSArray__JS_ARRAY_TYPE", 0xa8 },
+ { "v8dbg_type_JSBuiltinsObject__JS_BUILTINS_OBJECT_TYPE", 0xa6 },
+ { "v8dbg_type_JSFunction__JS_FUNCTION_TYPE", 0xac },
+ { "v8dbg_type_JSFunctionProxy__JS_FUNCTION_PROXY_TYPE", 0xad },
+ { "v8dbg_type_JSGlobalObject__JS_GLOBAL_OBJECT_TYPE", 0xa5 },
+ { "v8dbg_type_JSGlobalPropertyCell__JS_GLOBAL_PROPERTY_CELL_TYPE",
+ 0x83 },
+ { "v8dbg_type_JSMessageObject__JS_MESSAGE_OBJECT_TYPE", 0xa1 },
+ { "v8dbg_type_JSObject__JS_OBJECT_TYPE", 0xa3 },
+ { "v8dbg_type_JSProxy__JS_PROXY_TYPE", 0xa9 },
+ { "v8dbg_type_JSRegExp__JS_REGEXP_TYPE", 0xab },
+ { "v8dbg_type_JSValue__JS_VALUE_TYPE", 0xa2 },
+ { "v8dbg_type_JSWeakMap__JS_WEAK_MAP_TYPE", 0xaa },
+ { "v8dbg_type_Map__MAP_TYPE", 0x80 },
+ { "v8dbg_type_ObjectTemplateInfo__OBJECT_TEMPLATE_INFO_TYPE", 0x97 },
+ { "v8dbg_type_Oddball__ODDBALL_TYPE", 0x82 },
+ { "v8dbg_type_PolymorphicCodeCache__POLYMORPHIC_CODE_CACHE_TYPE",
+ 0x9c },
+ { "v8dbg_type_Script__SCRIPT_TYPE", 0x9a },
+ { "v8dbg_type_SeqAsciiString__ASCII_STRING_TYPE", 0x4 },
+ { "v8dbg_type_SeqAsciiString__ASCII_SYMBOL_TYPE", 0x44 },
+ { "v8dbg_type_SeqTwoByteString__STRING_TYPE", 0x0 },
+ { "v8dbg_type_SeqTwoByteString__SYMBOL_TYPE", 0x40 },
+ { "v8dbg_type_SharedFunctionInfo__SHARED_FUNCTION_INFO_TYPE", 0xa0 },
+ { "v8dbg_type_SignatureInfo__SIGNATURE_INFO_TYPE", 0x98 },
+ { "v8dbg_type_SlicedString__SLICED_ASCII_STRING_TYPE", 0x7 },
+ { "v8dbg_type_SlicedString__SLICED_STRING_TYPE", 0x3 },
+ { "v8dbg_type_TypeSwitchInfo__TYPE_SWITCH_INFO_TYPE", 0x99 },
+
+ { "v8dbg_class_AccessCheckInfo__data__Object", 0xc },
+ { "v8dbg_class_AccessCheckInfo__indexed_callback__Object", 0x8 },
+ { "v8dbg_class_AccessCheckInfo__named_callback__Object", 0x4 },
+ { "v8dbg_class_AccessorInfo__data__Object", 0xc },
+ { "v8dbg_class_AccessorInfo__flag__Smi", 0x14 },
+ { "v8dbg_class_AccessorInfo__getter__Object", 0x4 },
+ { "v8dbg_class_AccessorInfo__name__Object", 0x10 },
+ { "v8dbg_class_AccessorInfo__setter__Object", 0x8 },
+ { "v8dbg_class_BreakPointInfo__break_point_objects__Object", 0x10 },
+ { "v8dbg_class_BreakPointInfo__code_position__Smi", 0x4 },
+ { "v8dbg_class_BreakPointInfo__source_position__Smi", 0x8 },
+ { "v8dbg_class_BreakPointInfo__statement_position__Smi", 0xc },
+ { "v8dbg_class_CallHandlerInfo__callback__Object", 0x4 },
+ { "v8dbg_class_CallHandlerInfo__data__Object", 0x8 },
+ { "v8dbg_class_Code__deoptimization_data__FixedArray", 0xc },
+ { "v8dbg_class_Code__next_code_flushing_candidate__Object", 0x10 },
+ { "v8dbg_class_Code__relocation_info__ByteArray", 0x8 },
+ { "v8dbg_class_CodeCache__default_cache__FixedArray", 0x4 },
+ { "v8dbg_class_CodeCache__normal_type_cache__Object", 0x8 },
+ { "v8dbg_class_ConsString__first__String", 0xc },
+ { "v8dbg_class_ConsString__second__String", 0x10 },
+ { "v8dbg_class_DebugInfo__break_points__FixedArray", 0x14 },
+ { "v8dbg_class_DebugInfo__code__Code", 0xc },
+ { "v8dbg_class_DebugInfo__original_code__Code", 0x8 },
+ { "v8dbg_class_DebugInfo__shared__SharedFunctionInfo", 0x4 },
+ { "v8dbg_class_ExternalString__resource__Object", 0xc },
+ { "v8dbg_class_FixedArray__data__uintptr_t", 0x8 },
+ { "v8dbg_class_FixedArrayBase__length__SMI", 0x4 },
+ { "v8dbg_class_FunctionTemplateInfo__access_check_info__Object", 0x38 },
+ { "v8dbg_class_FunctionTemplateInfo__call_code__Object", 0x10 },
+ { "v8dbg_class_FunctionTemplateInfo__class_name__Object", 0x2c },
+ { "v8dbg_class_FunctionTemplateInfo__flag__Smi", 0x3c },
+ { "v8dbg_class_FunctionTemplateInfo__indexed_property_handler__Object",
+ 0x24 },
+ { "v8dbg_class_FunctionTemplateInfo__instance_call_handler__Object",
+ 0x34 },
+ { "v8dbg_class_FunctionTemplateInfo__instance_template__Object", 0x28 },
+ { "v8dbg_class_FunctionTemplateInfo__named_property_handler__Object",
+ 0x20 },
+ { "v8dbg_class_FunctionTemplateInfo__parent_template__Object", 0x1c },
+ { "v8dbg_class_FunctionTemplateInfo__property_accessors__Object",
+ 0x14 },
+ { "v8dbg_class_FunctionTemplateInfo__prototype_template__Object",
+ 0x18 },
+ { "v8dbg_class_FunctionTemplateInfo__serial_number__Object", 0xc },
+ { "v8dbg_class_FunctionTemplateInfo__signature__Object", 0x30 },
+ { "v8dbg_class_GlobalObject__builtins__JSBuiltinsObject", 0xc },
+ { "v8dbg_class_GlobalObject__global_context__Context", 0x10 },
+ { "v8dbg_class_GlobalObject__global_receiver__JSObject", 0x14 },
+ { "v8dbg_class_HeapNumber__value__double", 0x4 },
+ { "v8dbg_class_HeapObject__map__Map", 0x0 },
+ { "v8dbg_class_InterceptorInfo__data__Object", 0x18 },
+ { "v8dbg_class_InterceptorInfo__deleter__Object", 0x10 },
+ { "v8dbg_class_InterceptorInfo__enumerator__Object", 0x14 },
+ { "v8dbg_class_InterceptorInfo__getter__Object", 0x4 },
+ { "v8dbg_class_InterceptorInfo__query__Object", 0xc },
+ { "v8dbg_class_InterceptorInfo__setter__Object", 0x8 },
+ { "v8dbg_class_JSArray__length__Object", 0xc },
+ { "v8dbg_class_JSFunction__literals__FixedArray", 0x1c },
+ { "v8dbg_class_JSFunction__next_function_link__Object", 0x20 },
+ { "v8dbg_class_JSFunction__prototype_or_initial_map__Object", 0x10 },
+ { "v8dbg_class_JSFunction__shared__SharedFunctionInfo", 0x14 },
+ { "v8dbg_class_JSFunctionProxy__call_trap__Object", 0x8 },
+ { "v8dbg_class_JSFunctionProxy__construct_trap__Object", 0xc },
+ { "v8dbg_class_JSGlobalProxy__context__Object", 0xc },
+ { "v8dbg_class_JSMessageObject__arguments__JSArray", 0x10 },
+ { "v8dbg_class_JSMessageObject__end_position__SMI", 0x24 },
+ { "v8dbg_class_JSMessageObject__script__Object", 0x14 },
+ { "v8dbg_class_JSMessageObject__stack_frames__Object", 0x1c },
+ { "v8dbg_class_JSMessageObject__stack_trace__Object", 0x18 },
+ { "v8dbg_class_JSMessageObject__start_position__SMI", 0x20 },
+ { "v8dbg_class_JSMessageObject__type__String", 0xc },
+ { "v8dbg_class_JSObject__elements__Object", 0x8 },
+ { "v8dbg_class_JSObject__properties__FixedArray", 0x4 },
+ { "v8dbg_class_JSProxy__handler__Object", 0x4 },
+ { "v8dbg_class_JSRegExp__data__Object", 0xc },
+ { "v8dbg_class_JSValue__value__Object", 0xc },
+ { "v8dbg_class_JSWeakMap__next__Object", 0x10 },
+ { "v8dbg_class_JSWeakMap__table__ObjectHashTable", 0xc },
+ { "v8dbg_class_Map__code_cache__Object", 0x18 },
+ { "v8dbg_class_Map__constructor__Object", 0x10 },
+ { "v8dbg_class_Map__inobject_properties__int", 0x5 },
+ { "v8dbg_class_Map__instance_attributes__int", 0x8 },
+ { "v8dbg_class_Map__instance_descriptors__int", 0x14 },
+ { "v8dbg_class_Map__instance_size__int", 0x4 },
+ { "v8dbg_class_Map__prototype_transitions__FixedArray", 0x1c },
+ { "v8dbg_class_ObjectTemplateInfo__constructor__Object", 0xc },
+ { "v8dbg_class_ObjectTemplateInfo__internal_field_count__Object",
+ 0x10 },
+ { "v8dbg_class_Oddball__to_number__Object", 0x8 },
+ { "v8dbg_class_Oddball__to_string__String", 0x4 },
+ { "v8dbg_class_PolymorphicCodeCache__cache__Object", 0x4 },
+ { "v8dbg_class_Script__column_offset__Smi", 0x10 },
+ { "v8dbg_class_Script__compilation_type__Smi", 0x24 },
+ { "v8dbg_class_Script__context_data__Object", 0x18 },
+ { "v8dbg_class_Script__data__Object", 0x14 },
+ { "v8dbg_class_Script__eval_from_instructions_offset__Smi", 0x34 },
+ { "v8dbg_class_Script__eval_from_shared__Object", 0x30 },
+ { "v8dbg_class_Script__id__Object", 0x2c },
+ { "v8dbg_class_Script__line_ends__Object", 0x28 },
+ { "v8dbg_class_Script__line_offset__Smi", 0xc },
+ { "v8dbg_class_Script__name__Object", 0x8 },
+ { "v8dbg_class_Script__source__Object", 0x4 },
+ { "v8dbg_class_Script__type__Smi", 0x20 },
+ { "v8dbg_class_Script__wrapper__Foreign", 0x1c },
+ { "v8dbg_class_SeqAsciiString__chars__char", 0xc },
+ { "v8dbg_class_SharedFunctionInfo__compiler_hints__SMI", 0x50 },
+ { "v8dbg_class_SharedFunctionInfo__construct_stub__Code", 0x10 },
+ { "v8dbg_class_SharedFunctionInfo__debug_info__Object", 0x20 },
+ { "v8dbg_class_SharedFunctionInfo__end_position__SMI", 0x48 },
+ { "v8dbg_class_SharedFunctionInfo__expected_nof_properties__SMI",
+ 0x3c },
+ { "v8dbg_class_SharedFunctionInfo__formal_parameter_count__SMI", 0x38 },
+ { "v8dbg_class_SharedFunctionInfo__function_data__Object", 0x18 },
+ { "v8dbg_class_SharedFunctionInfo__function_token_position__SMI",
+ 0x4c },
+ { "v8dbg_class_SharedFunctionInfo__inferred_name__String", 0x24 },
+ { "v8dbg_class_SharedFunctionInfo__initial_map__Object", 0x28 },
+ { "v8dbg_class_SharedFunctionInfo__instance_class_name__Object", 0x14 },
+ { "v8dbg_class_SharedFunctionInfo__length__SMI", 0x34 },
+ { "v8dbg_class_SharedFunctionInfo__name__Object", 0x4 },
+ { "v8dbg_class_SharedFunctionInfo__num_literals__SMI", 0x40 },
+ { "v8dbg_class_SharedFunctionInfo__opt_count__SMI", 0x58 },
+ { "v8dbg_class_SharedFunctionInfo__script__Object", 0x1c },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "start_position_and_type__SMI", 0x44 },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "this_property_assignments__Object", 0x2c },
+ { "v8dbg_class_SharedFunctionInfo__"
+ "this_property_assignments_count__SMI", 0x54 },
+ { "v8dbg_class_SignatureInfo__args__Object", 0x8 },
+ { "v8dbg_class_SignatureInfo__receiver__Object", 0x4 },
+ { "v8dbg_class_SlicedString__offset__SMI", 0x10 },
+ { "v8dbg_class_String__length__SMI", 0x4 },
+ { "v8dbg_class_TemplateInfo__property_list__Object", 0x8 },
+ { "v8dbg_class_TemplateInfo__tag__Object", 0x4 },
+ { "v8dbg_class_TypeSwitchInfo__types__Object", 0x4 },
+
+ { "v8dbg_parent_AccessCheckInfo__Struct", 0x0 },
+ { "v8dbg_parent_AccessorInfo__Struct", 0x0 },
+ { "v8dbg_parent_BreakPointInfo__Struct", 0x0 },
+ { "v8dbg_parent_ByteArray__FixedArrayBase", 0x0 },
+ { "v8dbg_parent_CallHandlerInfo__Struct", 0x0 },
+ { "v8dbg_parent_Code__HeapObject", 0x0 },
+ { "v8dbg_parent_CodeCache__Struct", 0x0 },
+ { "v8dbg_parent_ConsString__String", 0x0 },
+ { "v8dbg_parent_DebugInfo__Struct", 0x0 },
+ { "v8dbg_parent_DeoptimizationInputData__FixedArray", 0x0 },
+ { "v8dbg_parent_DeoptimizationOutputData__FixedArray", 0x0 },
+ { "v8dbg_parent_DescriptorArray__FixedArray", 0x0 },
+ { "v8dbg_parent_ExternalArray__FixedArrayBase", 0x0 },
+ { "v8dbg_parent_ExternalAsciiString__ExternalString", 0x0 },
+ { "v8dbg_parent_ExternalByteArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalDoubleArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalFloatArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalIntArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalPixelArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalShortArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalString__String", 0x0 },
+ { "v8dbg_parent_ExternalTwoByteString__ExternalString", 0x0 },
+ { "v8dbg_parent_ExternalUnsignedByteArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalUnsignedIntArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_ExternalUnsignedShortArray__ExternalArray", 0x0 },
+ { "v8dbg_parent_Failure__MaybeObject", 0x0 },
+ { "v8dbg_parent_FixedArray__FixedArrayBase", 0x0 },
+ { "v8dbg_parent_FixedArrayBase__HeapObject", 0x0 },
+ { "v8dbg_parent_FixedDoubleArray__FixedArrayBase", 0x0 },
+ { "v8dbg_parent_Foreign__HeapObject", 0x0 },
+ { "v8dbg_parent_FunctionTemplateInfo__TemplateInfo", 0x0 },
+ { "v8dbg_parent_GlobalObject__JSObject", 0x0 },
+ { "v8dbg_parent_HashTable__FixedArray", 0x0 },
+ { "v8dbg_parent_HeapNumber__HeapObject", 0x0 },
+ { "v8dbg_parent_HeapObject__Object", 0x0 },
+ { "v8dbg_parent_InterceptorInfo__Struct", 0x0 },
+ { "v8dbg_parent_JSArray__JSObject", 0x0 },
+ { "v8dbg_parent_JSBuiltinsObject__GlobalObject", 0x0 },
+ { "v8dbg_parent_JSFunction__JSObject", 0x0 },
+ { "v8dbg_parent_JSFunctionProxy__JSProxy", 0x0 },
+ { "v8dbg_parent_JSFunctionResultCache__FixedArray", 0x0 },
+ { "v8dbg_parent_JSGlobalObject__GlobalObject", 0x0 },
+ { "v8dbg_parent_JSGlobalPropertyCell__HeapObject", 0x0 },
+ { "v8dbg_parent_JSMessageObject__JSObject", 0x0 },
+ { "v8dbg_parent_JSObject__JSReceiver", 0x0 },
+ { "v8dbg_parent_JSProxy__JSReceiver", 0x0 },
+ { "v8dbg_parent_JSReceiver__HeapObject", 0x0 },
+ { "v8dbg_parent_JSRegExp__JSObject", 0x0 },
+ { "v8dbg_parent_JSRegExpResult__JSArray", 0x0 },
+ { "v8dbg_parent_JSValue__JSObject", 0x0 },
+ { "v8dbg_parent_JSWeakMap__JSObject", 0x0 },
+ { "v8dbg_parent_Map__HeapObject", 0x0 },
+ { "v8dbg_parent_NormalizedMapCache__FixedArray", 0x0 },
+ { "v8dbg_parent_ObjectTemplateInfo__TemplateInfo", 0x0 },
+ { "v8dbg_parent_Oddball__HeapObject", 0x0 },
+ { "v8dbg_parent_PolymorphicCodeCache__Struct", 0x0 },
+ { "v8dbg_parent_Script__Struct", 0x0 },
+ { "v8dbg_parent_SeqAsciiString__SeqString", 0x0 },
+ { "v8dbg_parent_SeqString__String", 0x0 },
+ { "v8dbg_parent_SeqTwoByteString__SeqString", 0x0 },
+ { "v8dbg_parent_SharedFunctionInfo__HeapObject", 0x0 },
+ { "v8dbg_parent_SignatureInfo__Struct", 0x0 },
+ { "v8dbg_parent_SlicedString__String", 0x0 },
+ { "v8dbg_parent_Smi__Object", 0x0 },
+ { "v8dbg_parent_String__HeapObject", 0x0 },
+ { "v8dbg_parent_Struct__HeapObject", 0x0 },
+ { "v8dbg_parent_TemplateInfo__Struct", 0x0 },
+ { "v8dbg_parent_TypeSwitchInfo__Struct", 0x0 },
+
+ { "v8dbg_frametype_ArgumentsAdaptorFrame", 0x8 },
+ { "v8dbg_frametype_ConstructFrame", 0x7 },
+ { "v8dbg_frametype_EntryConstructFrame", 0x2 },
+ { "v8dbg_frametype_EntryFrame", 0x1 },
+ { "v8dbg_frametype_ExitFrame", 0x3 },
+ { "v8dbg_frametype_InternalFrame", 0x6 },
+ { "v8dbg_frametype_JavaScriptFrame", 0x4 },
+ { "v8dbg_frametype_OptimizedFrame", 0x5 },
+
+ { "v8dbg_off_fp_args", 0x8 },
+ { "v8dbg_off_fp_context", -0x4 },
+ { "v8dbg_off_fp_function", -0x8 },
+ { "v8dbg_off_fp_marker", -0x8 },
+
+ { "v8dbg_prop_idx_content", 0x1 },
+ { "v8dbg_prop_idx_first", 0x3 },
+ { "v8dbg_prop_type_field", 0x1 },
+ { "v8dbg_prop_type_first_phantom", 0x6 },
+ { "v8dbg_prop_type_mask", 0xf },
+
+ { "v8dbg_AsciiStringTag", 0x4 },
+ { "v8dbg_PointerSizeLog2", 0x2 },
+ { "v8dbg_SeqStringTag", 0x0 },
+ { "v8dbg_SmiTag", 0x0 },
+ { "v8dbg_SmiTagMask", 0x1 },
+ { "v8dbg_SmiValueShift", 0x1 },
+ { "v8dbg_StringEncodingMask", 0x4 },
+ { "v8dbg_StringRepresentationMask", 0x3 },
+ { "v8dbg_StringTag", 0x0 },
+ { "v8dbg_TwoByteStringTag", 0x0 },
+ { "v8dbg_ConsStringTag", 0x1 },
+ { "v8dbg_ExternalStringTag", 0x2 },
+ { "v8dbg_FailureTag", 0x3 },
+ { "v8dbg_FailureTagMask", 0x3 },
+ { "v8dbg_FirstNonstringType", 0x80 },
+ { "v8dbg_HeapObjectTag", 0x1 },
+ { "v8dbg_HeapObjectTagMask", 0x3 },
+ { "v8dbg_IsNotStringMask", 0x80 },
+ { "v8dbg_NotStringTag", 0x80 },
+
+ { NULL },
+};
+
+v8_cfg_t v8_cfgs[] = {
+ { "node-0.4", "node 0.4 versions starting with 0.4.8", v8_cfg_node_04,
+ v8cfg_canned_iter, v8cfg_canned_readsym },
+ { "node-0.6.5", "node v0.6.5", v8_cfg_node_065,
+ v8cfg_canned_iter, v8cfg_canned_readsym },
+ { NULL }
+};
+
+v8_cfg_t v8_cfg_target = { NULL, NULL, NULL, v8cfg_target_iter,
+ v8cfg_target_readsym };
diff --git a/usr/src/cmd/mdb/common/modules/v8/v8cfg.h b/usr/src/cmd/mdb/common/modules/v8/v8cfg.h
new file mode 100644
index 0000000000..398e9b418b
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/v8/v8cfg.h
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * v8cfg.h: canned configurations for previous V8 versions
+ */
+
+#ifndef V8CFG_H
+#define V8CFG_H
+
+#include <sys/types.h>
+#include <sys/mdb_modapi.h>
+
+typedef struct {
+ const char *v8cs_name; /* symbol name */
+ intptr_t v8cs_value; /* symbol value */
+} v8_cfg_symbol_t;
+
+typedef struct v8_cfg {
+ const char *v8cfg_name; /* canned config name */
+ const char *v8cfg_label; /* description */
+ v8_cfg_symbol_t *v8cfg_symbols; /* actual symbol values */
+
+ int (*v8cfg_iter)(struct v8_cfg *, int (*)(mdb_symbol_t *, void *),
+ void *);
+ int (*v8cfg_readsym)(struct v8_cfg *, const char *, intptr_t *);
+} v8_cfg_t;
+
+extern v8_cfg_t v8_cfg_target;
+extern v8_cfg_t v8_cfgs[];
+
+#endif
diff --git a/usr/src/cmd/mdb/common/modules/v8/v8dbg.h b/usr/src/cmd/mdb/common/modules/v8/v8dbg.h
new file mode 100644
index 0000000000..486ac5e255
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/v8/v8dbg.h
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * v8dbg.h: macros for use by V8 heap inspection tools. The consumer must
+ * define values for various tags and shifts. The MDB module gets these
+ * constants from information encoded in the binary itself.
+ */
+
+#ifndef _V8DBG_H
+#define _V8DBG_H
+
+/*
+ * Recall that while V8 heap objects are always 4-byte aligned, heap object
+ * pointers always have the last bit set. So when looking for a field nominally
+ * at offset X, one must be sure to clear the tag bit first.
+ */
+#define V8_OFF_HEAP(x) ((x) - V8_HeapObjectTag)
+
+/*
+ * Determine whether a given pointer refers to a SMI, Failure, or HeapObject.
+ */
+#define V8_IS_SMI(ptr) (((ptr) & V8_SmiTagMask) == V8_SmiTag)
+#define V8_IS_FAILURE(ptr) (((ptr) & V8_FailureTagMask) == V8_FailureTag)
+#define V8_IS_HEAPOBJECT(ptr) \
+ (((ptr) & V8_HeapObjectTagMask) == V8_HeapObjectTag)
+
+/*
+ * Extract the value of a SMI "pointer". Recall that small integers are stored
+ * using the upper 31 bits.
+ */
+#define V8_SMI_VALUE(smi) ((smi) >> V8_SmiValueShift)
+
+/*
+ * Determine the encoding and representation of a V8 string.
+ */
+#define V8_TYPE_STRING(type) (((type) & V8_IsNotStringMask) == V8_StringTag)
+
+#define V8_STRENC_ASCII(type) \
+ (((type) & V8_StringEncodingMask) == V8_AsciiStringTag)
+
+#define V8_STRREP_SEQ(type) \
+ (((type) & V8_StringRepresentationMask) == V8_SeqStringTag)
+#define V8_STRREP_CONS(type) \
+ (((type) & V8_StringRepresentationMask) == V8_ConsStringTag)
+#define V8_STRREP_EXT(type) \
+ (((type) & V8_StringRepresentationMask) == V8_ExternalStringTag)
+
+/*
+ * Several of the following constants and transformations are hardcoded in V8 as
+ * well, so there's no way to extract them programmatically from the binary.
+ */
+#define V8_DESC_KEYIDX(x) ((x) + V8_PROP_IDX_FIRST)
+#define V8_DESC_VALIDX(x) ((x) << 1)
+#define V8_DESC_DETIDX(x) (((x) << 1) + 1)
+
+#define V8_DESC_ISFIELD(x) \
+ (V8_SMI_VALUE((x) & V8_PROP_TYPE_MASK) == V8_PROP_TYPE_FIELD)
+
+#endif /* _V8DBG_H */
diff --git a/usr/src/cmd/mdb/intel/ia32/v8/Makefile b/usr/src/cmd/mdb/intel/ia32/v8/Makefile
new file mode 100644
index 0000000000..a824d4a8e3
--- /dev/null
+++ b/usr/src/cmd/mdb/intel/ia32/v8/Makefile
@@ -0,0 +1,42 @@
+#
+# 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 (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+MODULE = v8.so
+MDBTGT = proc
+
+MODSRCS_DIR = ../../../common/modules/v8
+
+MODSRCS = mdb_v8.c mdb_v8_cfg.c
+
+include ../../../../Makefile.cmd
+include ../../Makefile.ia32
+include ../../../Makefile.module
+
+%.o: $(MODSRCS_DIR)/%.c
+ $(COMPILE.c) $<
+ $(CTFCONVERT_O)
+
+%.ln: $(MODSRCS_DIR)/%.c
+ $(LINT.c) -c $<
diff --git a/usr/src/pkg/manifests/developer-build-onbld.mf b/usr/src/pkg/manifests/developer-build-onbld.mf
index 3d44a0cccb..acfefd75cf 100644
--- a/usr/src/pkg/manifests/developer-build-onbld.mf
+++ b/usr/src/pkg/manifests/developer-build-onbld.mf
@@ -21,9 +21,8 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
# Copyright 2010, Richard Lowe
+#
set name=pkg.fmri value=pkg:/developer/build/onbld@$(PKGVERS)
set name=pkg.description value="tools used to build the OS-Net consolidation"
@@ -107,7 +106,7 @@ file path=opt/onbld/bin/findcrypto mode=0555
file path=opt/onbld/bin/flg.flp mode=0555
file path=opt/onbld/bin/genoffsets mode=0555
file path=opt/onbld/bin/get_depend_info mode=0555
-file path=opt/onbld/bin/git-active mode=0555
+file path=opt/onbld/bin/git-pbchk mode=0555
file path=opt/onbld/bin/hdrchk mode=0555
file path=opt/onbld/bin/hg-active mode=0555
file path=opt/onbld/bin/hgsetup mode=0555
@@ -237,6 +236,7 @@ file path=opt/onbld/man/man1/cw.1
file path=opt/onbld/man/man1/find_elf.1
file path=opt/onbld/man/man1/findunref.1
file path=opt/onbld/man/man1/flg.flp.1
+file path=opt/onbld/man/man1/git-pbchk.1
file path=opt/onbld/man/man1/hdrchk.1
file path=opt/onbld/man/man1/hgsetup.1
file path=opt/onbld/man/man1/interface_check.1
@@ -266,7 +266,9 @@ license usr/src/tools/ctf/dwarf/THIRDPARTYLICENSE \
license=usr/src/tools/ctf/dwarf/THIRDPARTYLICENSE
license usr/src/tools/onbld/THIRDPARTYLICENSE \
license=usr/src/tools/onbld/THIRDPARTYLICENSE
+link path=opt/onbld/bin/git-nits target=git-pbchk
link path=opt/onbld/lib/python target=python2.4
+link path=opt/onbld/man/man1/git-nits.1 target=git-pbchk.1
# DbLookups.py requires elementtree
depend fmri=library/python-2/python-extra-24 type=require
# webrev(1) requires ps2pdf
diff --git a/usr/src/tools/scripts/Makefile b/usr/src/tools/scripts/Makefile
index 7849565fde..19e58d0244 100644
--- a/usr/src/tools/scripts/Makefile
+++ b/usr/src/tools/scripts/Makefile
@@ -68,13 +68,16 @@ PERLMODULES= \
PYFILES= \
cddlchk \
copyrightchk \
- git-active \
+ git-pbchk \
hdrchk \
hg-active \
mapfilechk \
validate_pkg \
wsdiff
+SCRIPTLINKS= \
+ git-nits
+
MAN1FILES= \
Install.1 \
bldenv.1 \
@@ -85,6 +88,7 @@ MAN1FILES= \
cstyle.1 \
find_elf.1 \
flg.flp.1 \
+ git-pbchk.1 \
hdrchk.1 \
interface_check.1 \
interface_cmp.1 \
@@ -100,6 +104,9 @@ MAN1FILES= \
wsdiff.1 \
xref.1
+MAN1LINKS= \
+ git-nits.1
+
MAKEFILES= \
xref.mk
@@ -117,6 +124,8 @@ CLEANFILES = $(SHFILES) $(PERLFILES) $(PYFILES) bldenv.1
include ../Makefile.tools
+ROOTONBLDSCRIPTLINKS = $(SCRIPTLINKS:%=$(ROOTONBLDBIN)/%)
+ROOTONBLDMAN1LINKS = $(MAN1LINKS:%=$(ROOTONBLDMAN1)/%)
$(ROOTONBLDETCFILES) := FILEMODE= 644
$(ROOTONBLDEXCEPTFILES) := FILEMODE= 644
@@ -129,10 +138,19 @@ $(ROOTONBLDMAN1FILES) := FILEMODE= 644
all: $(SHFILES) $(PERLFILES) $(PERLMODULES) $(PYFILES) \
$(MAN1FILES) $(MAKEFILES)
+$(ROOTONBLDBIN)/git-nits:
+ $(RM) $(ROOTONBLDBIN)/git-nits
+ $(SYMLINK) git-pbchk $(ROOTONBLDBIN)/git-nits
+
+$(ROOTONBLDMAN1)/git-nits.1:
+ $(RM) $(ROOTONBLDMAN1)/git-nits.1
+ $(SYMLINK) git-pbchk.1 $(ROOTONBLDMAN1)/git-nits.1
+
install: all .WAIT $(ROOTONBLDSHFILES) $(ROOTONBLDPERLFILES) \
$(ROOTONBLDPERLMODULES) $(ROOTONBLDPYFILES) \
- $(ROOTONBLDMAN1FILES) $(ROOTONBLDMAKEFILES) \
- $(ROOTONBLDETCFILES) $(ROOTONBLDEXCEPTFILES)
+ $(ROOTONBLDSCRIPTLINKS) $(ROOTONBLDMAN1FILES) \
+ $(ROOTONBLDMAKEFILES) $(ROOTONBLDETCFILES) \
+ $(ROOTONBLDEXCEPTFILES) $(ROOTONBLDMAN1LINKS)
clean:
$(RM) $(CLEANFILES)
diff --git a/usr/src/tools/scripts/flg.flp.sh b/usr/src/tools/scripts/flg.flp.sh
index 40239cf9e7..38d6278e4e 100644
--- a/usr/src/tools/scripts/flg.flp.sh
+++ b/usr/src/tools/scripts/flg.flp.sh
@@ -72,7 +72,7 @@ find_files()
pat=$1
shift
- if [ "$SCM_MODE" = "teamware" ] ; then
+ if [[ "$SCM_MODE" = "teamware" ]]; then
for dir; do
if [ -d $CODEMGR_WS/$dir ]; then
cd $CODEMGR_WS
@@ -81,7 +81,7 @@ find_files()
cd - > /dev/null
fi
done
- elif [ "$SCM_MODE" = "mercurial" ]; then
+ elif [[ "$SCM_MODE" = "mercurial" || "$SCM_MODE" == "git" ]]; then
dirs=""
for dir; do
if [ -d $CODEMGR_WS/$dir ]; then
@@ -179,7 +179,9 @@ which_scm | read SCM_MODE CODEMGR_WS || exit 1
if [[ $SCM_MODE == "unknown" ]]; then
fail "Unable to determine SCM type currently in use."
elif [[ $SCM_MODE == "mercurial" ]]; then
- FILELIST=`hg manifest`
+ FILELIST=$(hg manifest)
+elif [[ $SCM_MODE == "git" ]]; then
+ FILELIST=$(cd $(dirname $(git rev-parse --git-dir)); git ls-files)
elif [[ $SCM_MODE != "teamware" ]]; then
fail "Unsupported SCM in use: $SCM_MODE"
fi
diff --git a/usr/src/tools/scripts/git-pbchk.1 b/usr/src/tools/scripts/git-pbchk.1
new file mode 100644
index 0000000000..bb672e7182
--- /dev/null
+++ b/usr/src/tools/scripts/git-pbchk.1
@@ -0,0 +1,94 @@
+'\" t
+.\"
+.\" 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 2011 Richard Lowe.
+.\"
+
+.TH "GIT\-PBCHK" "1" "December 2011" "" ""
+
+.SH "NAME"
+\fBgit\-pbchk\fR \- nits and pre\-putback checks for git
+
+.SH "SYNOPSIS"
+git\-pbchk [\-b \fIbranch\fR]
+
+.P
+git\-nits [\-b \fIbranch\fR]
+
+.SH "DESCRIPTION"
+Check your workspace for common nits and putback\-ending mistakes, a simple set of checks are run over various parts of your workspace and errors encountered are reported, afll of which should, generally, be fixed\.
+
+.TP
+Comment format
+Check that putback comments follow the prescribed format (only run for pbchk)
+
+.TP
+Copyrights
+Check that each source file contains a copyright notice for the current year\. You need to fix this if you, the potential new copyright holder, chooses not to
+
+.TP
+C style
+Check that C source files conform to the Illumos C style rules
+
+.TP
+Header check
+Check that C header files conform to the Illumos header style rules (in addition to the general C rules)
+
+.TP
+Java style
+Check that Java source files conform to the Illumos Java style rules (which differ from the traditionally recommended Java style)
+
+.TP
+SCCS Keywords
+Check that no source files contain unexpanded SCCS keywords\. It is possible that this check may false positive on certain inputs\. It is generally obvious when this is the case\.
+
+.IP
+This check does not check for expanded SCCS keywords, though the common \'ident\'\-style lines should be removed regardless of whether they are expanded\.
+
+.TP
+Mapfile check
+Check that linker mapfiles contain a comment directing anyone editing to read the directions in \fBusr/lib/README\.mapfiles\fR\.
+
+.SH "OPTIONS"
+
+.TP
+\fB\-b branch\fR:
+
+.IP
+Compare the current workspace to /branch/ for the purposes of generating file and comment lists\.
+
+.IP
+If this option is not specified an attempt is made to determine this automatically, if the git branch configuration contains this information\.
+
+.IP
+If no branch is specified and none can be determined automatically \fBorigin/master\fR is used\.
+
+.SH "FILES"
+\fBgit nits\fR and \fBgit pbchk\fR support NOT files of the form used by Cadmium with Mercurial\. These are looked for in \fB$CODEMGR_WS/\.git/\fR and in \fB$CODEMGR_WS/exception_lists/\fR as normal\. The files are named after the check from which they exclude files\.
+
+.IP "\(bu" 4
+\fBcopyright\.NOT\fR: exclude files listed from copyright checking
+
+.IP "\(bu" 4
+\fBcstyle\.NOT\fR: exclude files from the C style check
+
+.IP "\(bu" 4
+\fBhdrchk\.NOT\fR: exclude files from the C header style check
+
+.IP "\(bu" 4
+\fBkeywords\.NOT\fR: exclude files from the SCCS keywords check
+
+.IP "\(bu" 4
+\fBmapfilechk\.NOT\fR: exclude files from the linker mapfile check
+
+.IP "" 0
+
diff --git a/usr/src/tools/scripts/git-pbchk.py b/usr/src/tools/scripts/git-pbchk.py
new file mode 100755
index 0000000000..2bcac59d2c
--- /dev/null
+++ b/usr/src/tools/scripts/git-pbchk.py
@@ -0,0 +1,285 @@
+#!/usr/bin/python2.4
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2008, 2011 Richard Lowe
+#
+
+import getopt
+import os
+import re
+import subprocess
+import sys
+
+from cStringIO import StringIO
+
+# This is necessary because, in a fit of pique, we used hg-format ignore lists
+# for NOT files.
+from mercurial import ignore
+
+sys.path.insert(1, os.path.join('/opt/onbld/lib',
+ "python%d.%d" % sys.version_info[:2]))
+
+from onbld.Checks import Comments, Copyright, CStyle, HdrChk
+from onbld.Checks import JStyle, Keywords, Mapfile
+
+def run(command):
+ if type(command) != list:
+ command = command.split()
+
+ p = subprocess.Popen(command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+
+ err = p.wait()
+ return err != 0 and None or p.stdout
+
+def git_root():
+ p = run('git rev-parse --git-dir')
+
+ if not p:
+ sys.stderr.write("Failed finding git workspace\n")
+ sys.exit(err)
+
+ return os.path.abspath(os.path.join(p.readlines()[0],
+ os.path.pardir))
+
+def git_branch():
+ p = run('git branch')
+
+ if not p:
+ sys.stderr.write("Failed finding git branch\n")
+ sys.exit(err)
+
+ for elt in p:
+ if elt[0] == '*':
+ return elt.split()[1]
+
+def git_parent_branch(branch):
+ p = run(["git", "for-each-ref",
+ "--format=%(refname:short) %(upstream:short)",
+ "refs/heads/"])
+
+ if not p:
+ sys.stderr.write("Failed finding git parent branch\n")
+ sys.exit(err)
+
+ for line in p:
+ # Git 1.7 will leave a ' ' trailing any non-tracking branch
+ if ' ' in line and not line.endswith(' \n'):
+ local, remote = line.split()
+ if local == branch:
+ return remote
+ return 'origin/master'
+
+def git_comments(branch):
+ p = run('git log --pretty=format:%%B %s..' % branch)
+
+ if not p:
+ sys.stderr.write("Failed getting git comments\n")
+ sys.exit(err)
+
+ return map(lambda x: x.strip(), p.readlines())
+
+
+def git_file_list(branch, paths=''):
+ '''Set of files which have ever changed between BRANCH and here'''
+ p = run("git log --name-only --pretty=format: %s.. %s" %
+ (branch, paths))
+
+ if not p:
+ sys.stderr.write("Failed building file-list from git\n")
+ sys.exit(err)
+
+ ret = set()
+ for fname in p:
+ if fname and not fname.isspace() and fname not in ret:
+ ret.add(fname.strip())
+
+ return ret
+
+
+def not_check(root, cmd):
+ '''Return a function to do NOT matching'''
+
+ ignorefiles = filter(os.path.exists,
+ [os.path.join(root, ".git", "%s.NOT" % cmd),
+ os.path.join(root, "exception_lists", cmd)])
+ if len(ignorefiles) > 0:
+ return ignore.ignore(root, ignorefiles, sys.stderr.write)
+ else:
+ return lambda x: False
+
+
+def gen_files(root, branch, paths, exclude):
+ # Taken entirely from 2.6's os.path.relpath which we would use if we
+ # could.
+ def relpath(path, here):
+ c = os.path.abspath(os.path.join(root, path)).split(os.path.sep)
+ s = os.path.abspath(here).split(os.path.sep)
+ l = len(os.path.commonprefix((s, c)))
+ return os.path.join(*[os.path.pardir] * (len(s)-l) + c[l:])
+
+ def ret(select=lambda x: True):
+ for f in git_file_list(branch, paths):
+ f = relpath(f, '.')
+ if (os.path.exists(f) and select(f) and not exclude(f)):
+ yield f
+ return ret
+
+def comchk(root, branch, flist, output):
+ output.write("Comments:\n")
+
+ return Comments.comchk(git_comments(branch), check_db=True,
+ output=output)
+
+def mapfilechk(root, branch, flist, output):
+ ret = 0
+
+ # We are interested in examining any file that has the following
+ # in its final path segment:
+ # - Contains the word 'mapfile'
+ # - Begins with 'map.'
+ # - Ends with '.map'
+ # We don't want to match unless these things occur in final path segment
+ # because directory names with these strings don't indicate a mapfile.
+ # We also ignore files with suffixes that tell us that the files
+ # are not mapfiles.
+ MapfileRE = re.compile(r'.*((mapfile[^/]*)|(/map\.+[^/]*)|(\.map))$',
+ re.IGNORECASE)
+ NotMapSuffixRE = re.compile(r'.*\.[ch]$', re.IGNORECASE)
+
+ output.write("Mapfile comments:\n")
+
+ for f in flist(lambda x: MapfileRE.match(x) and not
+ NotMapSuffixRE.match(x)):
+ fh = open(f, 'r')
+ ret |= Mapfile.mapfilechk(fh, output=output)
+ fh.close()
+ return ret
+
+
+def copyright(root, branch, flist, output):
+ ret = 0
+ output.write("Copyrights:\n")
+ for f in flist():
+ fh = open(f, 'r')
+ ret |= Copyright.copyright(fh, output=output)
+ fh.close()
+ return ret
+
+
+def hdrchk(root, branch, flist, output):
+ ret = 0
+ output.write("Header format:\n")
+ for f in flist(lambda x: x.endswith('.h')):
+ fh = open(f, 'r')
+ ret |= HdrChk.hdrchk(fh, lenient=True, output=output)
+ fh.close()
+ return ret
+
+
+def cstyle(root, branch, flist, output):
+ ret = 0
+ output.write("C style:\n")
+ for f in flist(lambda x: x.endswith('.c') or x.endswith('.h')):
+ fh = open(f, 'r')
+ ret |= CStyle.cstyle(fh, output=output, picky=True,
+ check_posix_types=True,
+ check_continuation=True)
+ fh.close()
+ return ret
+
+
+def jstyle(root, branch, flist, output):
+ ret = 0
+ output.write("Java style:\n")
+ for f in flist(lambda x: x.endswith('.java')):
+ fh = open(f, 'r')
+ ret |= JStyle.jstyle(fh, output=output, picky=True)
+ fh.close()
+ return ret
+
+
+def keywords(root, branch, flist, output):
+ ret = 0
+ output.write("SCCS Keywords:\n")
+ for f in flist():
+ fh = open(f, 'r')
+ ret |= Keywords.keywords(fh, output=output)
+ fh.close()
+ return ret
+
+
+def run_checks(root, branch, cmds, paths='', opts={}):
+ ret = 0
+
+ for cmd in cmds:
+ s = StringIO()
+
+ exclude = not_check(root, cmd.func_name)
+ result = cmd(root, branch, gen_files(root, branch, paths, exclude),
+ output=s)
+ ret |= result
+
+ if result != 0:
+ print s.getvalue()
+
+ return ret
+
+
+def nits(root, branch, paths=''):
+ cmds = [copyright,
+ cstyle,
+ hdrchk,
+ jstyle,
+ keywords,
+ mapfilechk]
+ run_checks(root, branch, cmds, paths='')
+
+def pbchk(root, branch):
+ cmds = [comchk,
+ copyright,
+ cstyle,
+ hdrchk,
+ jstyle,
+ keywords,
+ mapfilechk]
+ run_checks(root, branch, cmds)
+
+if __name__ == '__main__':
+ branch = None
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'b:')
+ except getopt.GetoptError, e:
+ sys.stderr.write(str(e))
+ sys.stderr.write("Usage: git-nits [-b branch] [path...]\n")
+ sys.exit(1)
+
+ for opt, arg in opts:
+ if opt == '-b':
+ branch = arg
+
+ if not branch:
+ branch = git_parent_branch(git_branch())
+
+ func = nits
+ if sys.argv[0].endswith('/git-pbchk'):
+ func = pbchk
+
+ func(git_root(), branch)
diff --git a/usr/src/tools/scripts/nightly.sh b/usr/src/tools/scripts/nightly.sh
index abebb16b51..b64ed6f8ad 100644
--- a/usr/src/tools/scripts/nightly.sh
+++ b/usr/src/tools/scripts/nightly.sh
@@ -2138,7 +2138,7 @@ if [ "$i_FLAG" = "n" -a -d "$SRC" ]; then
# Remove all .make.state* files, just in case we are restarting
# the build after having interrupted a previous 'make clobber'.
- find . \( -name SCCS -o -name .hg -o -name .svn -o -name .git \
+ find . \( -name SCCS -o -name .hg -o -name .svn -o name .git \
-o -name 'interfaces.*' \) -prune \
-o -name '.make.*' -print | xargs rm -f
@@ -2173,7 +2173,7 @@ if [ "$i_FLAG" = "n" -a -d "$SRC" ]; then
# under source code control, so leave them alone.
# We should probably blow away temporary directories too.
cd $SRC
- find $relsrcdirs \( -name SCCS -o -name .hg -o -name .svn -o -name .git\
+ find $relsrcdirs \( -name SCCS -o -name .hg -o -name .svn -o name .git\
-o -name 'interfaces.*' \) -prune -o \
\( -name '.make.*' -o -name 'lib*.a' -o -name 'lib*.so*' -o \
-name '*.o' \) -print | \
diff --git a/usr/src/tools/scripts/webrev.1 b/usr/src/tools/scripts/webrev.1
index e83acd80f8..b0cf41080e 100644
--- a/usr/src/tools/scripts/webrev.1
+++ b/usr/src/tools/scripts/webrev.1
@@ -22,7 +22,7 @@
.\" Use is subject to license terms.
.\"
.\"
-.TH webrev 1 "22 Feb 2010"
+.TH webrev 1 "6 Dec 2010"
.SH NAME
webrev \- Generate HTML codereview materials
.SH SYNOPSIS
@@ -60,7 +60,7 @@ Note that the -l option is only applicable to TeamWare workspaces.
.B webrev
builds a set of HTML files suitable for performing code review of
source changes in a web browser.
-It supports Mercurial, Subversion and Teamware repositories.
+It supports Mercurial, Git, Subversion and Teamware repositories.
At its most basic, usage is:
.nf
$ webrev
@@ -174,9 +174,22 @@ or to reference a teamware flp (file list program).
In the case of Mercurial \fBwebrev\fR will attempt to use the output
from the
.BR hg (1)
-"hg root" to identify the workspace root, and the
+"hg root" command to identify the workspace root, and the
"hg path default" command to identify the parent workspace.
+.SS Git
+In the case of Git \fBwebrev\fR will attempt to use the output from the
+.BR git (1)
+"git rev-parse --git-dir" command to identify the workspace root, and will
+attempt to use the remote branch which the current branch is tracking as the
+parent, if none is specified 'origin/master' will be used.
+
+The parent specified when git is, in all cases, a git 'tree-ish' and never an
+actual git repository, remote or otherwise. Anything specifiable to git as a
+tree-ish should, similarly, be specifiable as a parent for webrev. This
+includes branches, explicit revisions, reflog entries, etc. See
+.BR git-rev-parse (1)
+
.SS Subversion
In the case of Subversion \fBwebrev\fR will attempt to use the output
from the
@@ -458,6 +471,7 @@ This will remove just the \fIbugfix.onnv\fR directory.
.BR putback "(1),"
.BR workspace "(1),"
.BR hg "(1),"
+.BR git "(1),"
.BR ssh_config "(4),"
.BR svn "(1),"
.BR which_scm "(1)"
diff --git a/usr/src/tools/scripts/webrev.sh b/usr/src/tools/scripts/webrev.sh
index 018341fe71..318feff6cb 100644
--- a/usr/src/tools/scripts/webrev.sh
+++ b/usr/src/tools/scripts/webrev.sh
@@ -516,6 +516,16 @@ html_quote()
$SED -e "s/&/\&amp;/g" -e "s/</\&lt;/g" -e "s/>/\&gt;/g" "$@" | expand
}
+#
+# Trim a digest-style revision to a conventionally readable yet useful length
+#
+trim_digest()
+{
+ typeset digest=$1
+
+ echo $digest | $SED -e 's/\([0-9a-f]\{12\}\).*/\1/'
+}
+
#
# input_cmd | its2url | output_cmd
#
@@ -1780,36 +1790,75 @@ function flist_from_mercurial
}
#
-# Call git-active to get the active list output in the wx active list format
+# Transform a specified 'git log' output format into a wx-like active list.
#
-function git_active_wxfile
+function git_wxfile
{
- typeset child=$1
- typeset parent=$2
+ typeset child="$1"
+ typeset parent="$2"
TMPFLIST=/tmp/$$.active
- $GIT_ACTIVE -w $child -p $parent -o $TMPFLIST
+ $PERL -e 'my (%files, %realfiles, $msg);
+ my $branch = $ARGV[0];
+
+ open(F, "git diff -M --name-status $branch |");
+ while (<F>) {
+ chomp;
+ if (/^R(\d+)\s+([^ ]+)\s+([^ ]+)/) { # rename
+ if ($1 >= 75) { # Probably worth treating as a rename
+ $realfiles{$3} = $2
+ } else {
+ $realfiles{$3} = $3;
+ $realfiles{$2} = $2;
+ }
+ } else {
+ my $f = (split /\s+/, $_)[1];
+ $realfiles{$f} = $f;
+ }
+ }
+ close(F);
+
+ my $state = 1; # 0|comments, 1|files
+ open(F, "git whatchanged --pretty=format:%B $branch.. |");
+ while (<F>) {
+ chomp;
+ if (/^:[0-9]{6}/) {
+ my $fname = (split /\t/, $_)[1];
+ next if !defined($realfiles{$fname}); # No real change
+ $state = 1;
+ $files{$fname} = $msg;
+ } else {
+ if ($state == 1) {
+ $state = 0;
+ $msg = /^\n/ ? "" : "\n";
+ }
+ $msg .= "$_\n" if ($_);
+ }
+ }
+ close(F);
+
+ for (sort keys %files) {
+ if ($realfiles{$_} ne $_) {
+ print "$_ $realfiles{$_}\n$files{$_}\n";
+ } else {
+ print "$_\n$files{$_}\n"
+ }
+ }' ${parent} > $TMPFLIST
+
wxfile=$TMPFLIST
}
#
# flist_from_git
-# Call git-active to get a wx-style active list, and hand it off to
-# flist_from_wx
+# Build a wx-style active list, and hand it off to flist_from_wx
#
function flist_from_git
{
typeset child=$1
typeset parent=$2
- print " File list from: git-active -p $parent ...\c"
-
- if [[ ! -x $GIT_ACTIVE ]]; then
- print # Blank line for the \c above
- print -u2 "Error: git-active tool not found. Exiting"
- exit 1
- fi
- git_active_wxfile $child $parent
+ print " File list from: git ...\c"
+ git_wxfile "$child" "$parent";
# flist_from_wx prints the Done, so we don't have to.
flist_from_wx $TMPFLIST
@@ -2039,36 +2088,41 @@ function build_old_new_git
{
typeset olddir="$1"
typeset newdir="$2"
- typeset ws_top_dir=$(dirname $3)
typeset o_mode=
typeset n_mode=
typeset o_object=
typeset n_object=
+ typeset OWD=$PWD
typeset file
typeset type
+ cd $CWS
+
#
# Get old file and its mode from the git object tree
#
if [[ "$PDIR" == "." ]]; then
file="$PF"
else
- file="$PDIR/$PF"
+ file="$PDIR/$PF"
fi
- curr_dir=$(pwd)
- cd $ws_top_dir
-
- git ls-tree $GIT_PARENT $file | read o_mode type o_object junk
- git cat-file $type $o_object > $olddir/$file 2>/dev/null
-
- if (( $? != 0 )); then
- rm -f $olddir/$file
- elif [[ -n $o_mode ]]; then
- chmod $o_mode $olddir/$file
+ if [[ -n $parent_webrev && -e $PWS/$PDIR/$PF ]]; then
+ cp $PWS/$PDIR/$PF $olddir/$PDIR/$PF
else
- # should never happen
- print -u2 "ERROR: set mode of $olddir/$file"
+ $GIT ls-tree $GIT_PARENT $file | read o_mode type o_object junk
+ $GIT cat-file $type $o_object > $olddir/$file 2>/dev/null
+
+ if (( $? != 0 )); then
+ rm -f $olddir/$file
+ elif [[ -n $o_mode ]]; then
+ # Strip the first 3 digits, to get a regular octal mode
+ o_mode=${o_mode/???/}
+ chmod $o_mode $olddir/$file
+ else
+ # should never happen
+ print -u2 "ERROR: set mode of $olddir/$file"
+ fi
fi
#
@@ -2080,16 +2134,12 @@ function build_old_new_git
file="$DIR/$F"
fi
rm -rf $newdir/$file
- git ls-tree HEAD $file | read n_mode type n_object junk
- git cat-file $type $n_object > $newdir/$file 2>/dev/null
- cd $curr_dir
- if [[ -n $n_mode ]]; then
- chmod $n_mode $newdir/$file
- else
- # should never happen
- print -u2 "ERROR: set mode of $newdir/$file"
- fi
+ if [[ -e $CWS/$DIR/$F ]]; then
+ cp $CWS/$DIR/$F $newdir/$DIR/$F
+ chmod $(get_file_mode $CWS/$DIR/$F) $newdir/$DIR/$F
+ fi
+ cd $OWD
}
function build_old_new_subversion
@@ -2153,7 +2203,7 @@ function build_old_new
elif [[ $SCM_MODE == "mercurial" ]]; then
build_old_new_mercurial "$olddir" "$newdir"
elif [[ $SCM_MODE == "git" ]]; then
- build_old_new_git "$olddir" "$newdir" "$CWS"
+ build_old_new_git "$olddir" "$newdir"
elif [[ $SCM_MODE == "subversion" ]]; then
build_old_new_subversion "$olddir" "$newdir"
elif [[ $SCM_MODE == "unknown" ]]; then
@@ -2215,12 +2265,12 @@ trap "rm -f /tmp/$$.* ; exit" 0 1 2 3 15
set +o noclobber
-PATH=$(dirname $(whence $0)):$PATH
+PATH=$(dirname "$(whence $0)"):$PATH
[[ -z $WDIFF ]] && WDIFF=`look_for_prog wdiff`
[[ -z $WX ]] && WX=`look_for_prog wx`
[[ -z $HG_ACTIVE ]] && HG_ACTIVE=`look_for_prog hg-active`
-[[ -z $GIT_ACTIVE ]] && GIT_ACTIVE=`look_for_prog git-active`
+[[ -z $GIT ]] && GIT=`look_for_prog git`
[[ -z $WHICH_SCM ]] && WHICH_SCM=`look_for_prog which_scm`
[[ -z $CODEREVIEW ]] && CODEREVIEW=`look_for_prog codereview`
[[ -z $PS2PDF ]] && PS2PDF=`look_for_prog ps2pdf`
@@ -2410,15 +2460,16 @@ elif [[ $SCM_MODE == "git" ]]; then
# 2. git rev-parse --git-dir from directory of invocation
#
[[ -z $codemgr_ws && -n $CODEMGR_WS ]] && \
- codemgr_ws=$(git --git-dir=$CODEMGR_WS rev-parse --git-dir \
- 2>/dev/null)
+ codemgr_ws=$($GIT --git-dir=$CODEMGR_WS/.git rev-parse --git-dir \
+ 2>/dev/null)
[[ -z $codemgr_ws ]] && \
- codemgr_ws=$(git rev-parse --git-dir 2>/dev/null)
+ codemgr_ws=$($GIT rev-parse --git-dir 2>/dev/null)
if [[ "$codemgr_ws" == ".git" ]]; then
- codemgr_ws="$PWD/.git"
+ codemgr_ws="${PWD}/${codemgr_ws}"
fi
+ codemgr_ws=$(dirname $codemgr_ws) # Lose the '/.git'
CWS="$codemgr_ws"
elif [[ $SCM_MODE == "subversion" ]]; then
#
@@ -2471,8 +2522,8 @@ fi
# then note that fact and set the parent to the raw_files/new subdirectory.
#
if [[ -n $pflag && -d $codemgr_parent/raw_files/new ]]; then
- parent_webrev="$codemgr_parent"
- codemgr_parent="$codemgr_parent/raw_files/new"
+ parent_webrev=$(readlink -f "$codemgr_parent")
+ codemgr_parent=$(readlink -f "$codemgr_parent/raw_files/new")
fi
if [[ -z $wflag && -z $lflag ]]; then
@@ -2665,7 +2716,6 @@ elif [[ $SCM_MODE == "mercurial" ]]; then
codemgr_parent=`hg path -R $codemgr_ws default 2>/dev/null`
fi
- CWS_REV=`hg parent -R $codemgr_ws --template '{node|short}' 2>/dev/null`
PWS=$codemgr_parent
#
@@ -2729,23 +2779,36 @@ elif [[ $SCM_MODE == "mercurial" ]]; then
print -u2 "Error: Cannot discover parent revision"
exit 1
fi
+
+ pnode=$(trim_digest $HG_PARENT)
+ PRETTY_PWS="${PWS} (at ${pnode})"
+ cnode=$(hg parent -R $codemgr_ws --template '{node|short}' \
+ 2>/dev/null)
+ PRETTY_CWS="${CWS} (at ${cnode})"}
elif [[ $SCM_MODE == "git" ]]; then
#
- # Parent can either be specified with -p
- # Specified with CODEMGR_PARENT in the environment
- # or taken from git config.
+ # Parent can either be specified with -p, or specified with
+ # CODEMGR_PARENT in the environment.
#
if [[ -z $codemgr_parent && -n $CODEMGR_PARENT ]]; then
codemgr_parent=$CODEMGR_PARENT
fi
+ # Try to figure out the parent based on the branch the current
+ # branch is tracking, if we fail, use origin/master
+ this_branch=$($GIT branch | nawk '$1 == "*" { print $2 }')
+ par_branch="origin/master"
+
+ $GIT for-each-ref \
+ --format='%(refname:short) %(upstream:short)' refs/heads/ | \
+ while read local remote; do \
+ [[ "$local" == "$this_branch" ]] && par_branch="$remote"; \
+ done
+
if [[ -z $codemgr_parent ]]; then
- codemgr_parent=$(git --git-dir=$codemgr_ws config \
- remote.origin.url 2>/dev/null)
+ codemgr_parent=$par_branch
fi
-
- CWS_REV=$(git --git-dir=$codemgr_ws rev-parse HEAD 2>/dev/null)
PWS=$codemgr_parent
#
@@ -2753,63 +2816,56 @@ elif [[ $SCM_MODE == "git" ]]; then
# the natural workspace parent (file list, comments, etc)
#
if [[ -n $parent_webrev ]]; then
- real_parent=$(git --git-dir $codemgr_ws config \
- remote.origin.url 2>/dev/null)
+ real_parent=$par_branch
else
real_parent=$PWS
fi
- #
- # If git-active exists, then we run it. In the case of no explicit
- # flist given, we'll use it for our comments. In the case of an
- # explicit flist given we'll try to use it for comments for any
- # files mentioned in the flist.
- #
if [[ -z $flist_done ]]; then
- flist_from_git $CWS $real_parent
+ flist_from_git "$CWS" "$real_parent"
flist_done=1
fi
#
# If we have a file list now, pull out any variables set
- # therein. We do this now (rather than when we possibly use
- # git-active to find comments) to avoid stomping specifications
- # in the user-specified flist.
+ # therein.
#
if [[ -n $flist_done ]]; then
env_from_flist
fi
#
- # Only call git-active if we don't have a wx formatted file already
+ # If we don't have a wx-format file list, build one we can pull change
+ # comments from.
#
- if [[ -x $GIT_ACTIVE && -z $wxfile ]]; then
- print " Comments from: git-active -p $real_parent ...\c"
- git_active_wxfile $CWS $real_parent
+ if [[ -z $wxfile ]]; then
+ print " Comments from: git...\c"
+ git_wxfile "$CWS" "$real_parent"
print " Done."
fi
- #
- # At this point we must have a wx flist either from git-active,
- # or in general. Use it to try and find our parent revision,
- # if we don't have one.
- #
if [[ -z $GIT_PARENT ]]; then
- eval `$SED -e "s/#.*$//" $wxfile | $GREP GIT_PARENT=`
+ GIT_PARENT=$($GIT merge-base "$real_parent" HEAD)
fi
-
- #
- # If we still don't have a parent, we must have been given a
- # wx-style active list with no GIT_PARENT specification, run
- # git-active and pull an GIT_PARENT out of it, ignore the rest.
- #
- if [[ -z $GIT_PARENT && -x $GIT_ACTIVE ]]; then
- $GIT_ACTIVE -w $codemgr_ws -p $real_parent | \
- eval `$SED -e "s/#.*$//" | $GREP GIT_PARENT=`
- elif [[ -z $GIT_PARENT ]]; then
+ if [[ -z $GIT_PARENT ]]; then
print -u2 "Error: Cannot discover parent revision"
exit 1
fi
+
+ pnode=$(trim_digest $GIT_PARENT)
+
+ if [[ $real_parent == */* ]]; then
+ origin=$(echo $real_parent | cut -d/ -f1)
+ origin=$($GIT remote -v | \
+ $AWK '$1 == "'$origin'" { print $2; exit }')
+ PRETTY_PWS="${PWS} (${origin} at ${pnode})"
+ else
+ PRETTY_PWS="${PWS} (at ${pnode})"
+ fi
+
+ cnode=$($GIT --git-dir=${codemgr_ws}/.git rev-parse --short=12 HEAD \
+ 2>/dev/null)
+ PRETTY_CWS="${CWS} (at ${cnode})"
elif [[ $SCM_MODE == "subversion" ]]; then
#
@@ -2876,7 +2932,7 @@ typeset -A itsinfo
typeset -r its_sed_script=/tmp/$$.its_sed
valid_prefixes=
if [[ -z $nflag ]]; then
- DEFREGFILE="$(dirname $(whence $0))/../etc/its.reg"
+ DEFREGFILE="$(dirname "$(whence $0)")/../etc/its.reg"
if [[ -n $Iflag ]]; then
REGFILE=$ITSREG
elif [[ -r $HOME/.its.reg ]]; then
@@ -2905,7 +2961,7 @@ if [[ -z $nflag ]]; then
done
- DEFCONFFILE="$(dirname $(whence $0))/../etc/its.conf"
+ DEFCONFFILE="$(dirname "$(whence $0)")/../etc/its.conf"
CONFFILES=$DEFCONFFILE
if [[ -r $HOME/.its.conf ]]; then
CONFFILES="${CONFFILES} $HOME/.its.conf"
@@ -3094,21 +3150,11 @@ fi
#
# Summarize what we're going to do.
#
-if [[ -n $CWS_REV ]]; then
- print " Workspace: $CWS (at $CWS_REV)"
-else
- print " Workspace: $CWS"
-fi
+print " Workspace: ${PRETTY_CWS:-$CWS}"
if [[ -n $parent_webrev ]]; then
print "Compare against: webrev at $parent_webrev"
else
- if [[ -n $HG_PARENT ]]; then
- hg_parent_short=`echo $HG_PARENT \
- | $SED -e 's/\([0-9a-f]\{12\}\).*/\1/'`
- print "Compare against: $PWS (at $hg_parent_short)"
- else
- print "Compare against: $PWS"
- fi
+ print "Compare against: ${PRETTY_PWS:-$PWS}"
fi
[[ -n $INCLUDE_FILE ]] && print " Including: $INCLUDE_FILE"
@@ -3459,19 +3505,13 @@ fi
PREPDATE=$(LC_ALL=C /usr/bin/date +%Y-%b-%d\ %R\ %z\ %Z)
print "<tr><th>Prepared by:</th><td>$preparer on $PREPDATE</td></tr>"
-print "<tr><th>Workspace:</th><td>$CWS"
-if [[ -n $CWS_REV ]]; then
- print "(at $CWS_REV)"
-fi
+print "<tr><th>Workspace:</th><td>${PRETTY_CWS:-$CWS}"
print "</td></tr>"
print "<tr><th>Compare against:</th><td>"
if [[ -n $parent_webrev ]]; then
print "webrev at $parent_webrev"
else
- print "$PWS"
- if [[ -n $hg_parent_short ]]; then
- print "(at $hg_parent_short)"
- fi
+ print "${PRETTY_PWS:-$PWS}"
fi
print "</td></tr>"
print "<tr><th>Summary of changes:</th><td>"
diff --git a/usr/src/tools/scripts/which_scm.1 b/usr/src/tools/scripts/which_scm.1
index 25510f3c7e..c7e4c671be 100644
--- a/usr/src/tools/scripts/which_scm.1
+++ b/usr/src/tools/scripts/which_scm.1
@@ -21,7 +21,7 @@
.\" Copyright 2008 Sun Microsystems, Inc. All rights reserved.
.\" Use is subject to license terms.
.\"
-.TH which_scm 1 "5 October 2010"
+.TH which_scm 1 "18 September 2009"
.SH NAME
which_scm \- Report Source Code Management system
.SH SYNOPSIS
diff --git a/usr/src/tools/scripts/ws.sh b/usr/src/tools/scripts/ws.sh
index afe91916f2..9ffa7bf171 100644
--- a/usr/src/tools/scripts/ws.sh
+++ b/usr/src/tools/scripts/ws.sh
@@ -87,6 +87,14 @@ check_proto()
"${proto##https://}" == "$proto" ]; then
echo "${proto}/root_${MACH}"
fi
+ elif [ "$SCM_MODE" = "git" ]; then
+ #
+ # For git, we make no attempt to deal with the possibility of
+ # remote parent workspaces because, in the protodefs file, we
+ # don't actually acknowledge the concept of a parent workspace
+ # at all, in keeping with the rest of our git support.
+ #
+ echo "${1}/root_${MACH}"
fi
}
@@ -105,7 +113,7 @@ else
setenv=false
fi
-WHICH_SCM=$(dirname $(whence $0))/which_scm
+WHICH_SCM=$(/bin/dirname $(whence $0))/which_scm
if [[ ! -x $WHICH_SCM ]]; then
WHICH_SCM=which_scm
fi
@@ -217,6 +225,10 @@ elif [ "$SCM_MODE" = "mercurial" -a -d ${wsname}/.hg ]; then
CM_DATA=".hg"
wsosdir=$CODEMGR_WS/$CM_DATA
protofile=$wsosdir/org.opensolaris.protodefs
+elif [ "$SCM_MODE" = "git" -a -d ${wsname}/.git ]; then
+ CM_DATA=".git"
+ wsosdir=$CODEMGR_WS/$CM_DATA
+ protofile=$wsosdir/org.opensolaris.protodefs
else
echo "$wsname is not a supported workspace; type is $SCM_MODE" >&2
if $setenv; then
@@ -362,7 +374,7 @@ if [[ ! -v CLOSED_IS_PRESENT ]]; then
fi
if [[ -z "$ONBLD_DIR" ]]; then
- ONBLD_DIR=$(dirname $(whence $0))
+ ONBLD_DIR=$(/bin/dirname $(whence $0))
fi
if ! echo ":$PATH:" | grep ":${ONBLD_DIR}:" > /dev/null; then
diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c
index 0f880f2458..290494147f 100644
--- a/usr/src/uts/common/dtrace/dtrace.c
+++ b/usr/src/uts/common/dtrace/dtrace.c
@@ -119,7 +119,7 @@ dtrace_optval_t dtrace_dof_maxsize = (256 * 1024);
size_t dtrace_global_maxsize = (16 * 1024);
size_t dtrace_actions_max = (16 * 1024);
size_t dtrace_retain_max = 1024;
-dtrace_optval_t dtrace_helper_actions_max = 32;
+dtrace_optval_t dtrace_helper_actions_max = 1024;
dtrace_optval_t dtrace_helper_providers_max = 32;
dtrace_optval_t dtrace_dstate_defsize = (1 * 1024 * 1024);
size_t dtrace_strsize_default = 256;
diff --git a/usr/src/uts/common/fs/zfs/dbuf.c b/usr/src/uts/common/fs/zfs/dbuf.c
index 7a0abd22b5..16e42b951a 100644
--- a/usr/src/uts/common/fs/zfs/dbuf.c
+++ b/usr/src/uts/common/fs/zfs/dbuf.c
@@ -2703,7 +2703,8 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
dr->dt.dl.dr_copies);
mutex_exit(&db->db_mtx);
} else if (db->db_state == DB_NOFILL) {
- ASSERT(zp.zp_checksum == ZIO_CHECKSUM_OFF);
+ ASSERT(zp.zp_checksum == ZIO_CHECKSUM_OFF ||
+ zp.zp_checksum == ZIO_CHECKSUM_NOPARITY);
dr->dr_zio = zio_write(zio, os->os_spa, txg,
db->db_blkptr, NULL, db->db.db_size, &zp,
dbuf_write_nofill_ready, dbuf_write_nofill_done, db,
diff --git a/usr/src/uts/common/fs/zfs/vdev_raidz.c b/usr/src/uts/common/fs/zfs/vdev_raidz.c
index 736683b6ef..6094e01876 100644
--- a/usr/src/uts/common/fs/zfs/vdev_raidz.c
+++ b/usr/src/uts/common/fs/zfs/vdev_raidz.c
@@ -1546,8 +1546,6 @@ vdev_raidz_physio(vdev_t *vd, caddr_t data, size_t size,
SPA_MAXBLOCKSIZE, origoffset, tvd->vdev_ashift, vd->vdev_children,
vd->vdev_nparity);
- ASSERT3U(rm->rm_asize, ==, vdev_psize_to_asize(vd, size));
-
coloffset = origoffset;
for (c = rm->rm_firstdatacol; c < rm->rm_cols;