1482 if (props != NULL)
1483 mdb_free(props, nprops * sizeof (uintptr_t));
1484
1485 if (descs != NULL)
1486 mdb_free(descs, ndescs * sizeof (uintptr_t));
1487
1488 if (content != NULL && V8_PROP_IDX_CONTENT != -1)
1489 mdb_free(content, ncontent * sizeof (uintptr_t));
1490
1491 return (rval);
1492 }
1493
1494 /*
1495 * Given the line endings table in "lendsp", computes the line number for the
1496 * given token position and print the result into "buf". If "lendsp" is
1497 * undefined, prints the token position instead.
1498 */
1499 static int
1500 jsfunc_lineno(uintptr_t lendsp, uintptr_t tokpos, char *buf, size_t buflen)
1501 {
1502 uintptr_t size, bufsz, lower, upper, ii;
1503 uintptr_t *data;
1504
1505 if (jsobj_is_undefined(lendsp)) {
1506 /*
1507 * The token position is an SMI, but it comes in as its raw
1508 * value so we can more easily compare it to values in the line
1509 * endings table. If we're just printing the position directly,
1510 * we must convert it here.
1511 */
1512 mdb_snprintf(buf, buflen, "position %d", V8_SMI_VALUE(tokpos));
1513 return (0);
1514 }
1515
1516 if (read_heap_smi(&size, lendsp, V8_OFF_FIXEDARRAY_LENGTH) != 0)
1517 return (-1);
1518
1519 bufsz = size * sizeof (data[0]);
1520
1521 if ((data = mdb_alloc(bufsz, UM_NOSLEEP)) == NULL) {
1522 v8_warn("failed to alloc %d bytes for FixedArray data", bufsz);
2817
2818 if ((buf = bufp = mdb_zalloc(bufsz, UM_NOSLEEP)) == NULL)
2819 return (DCMD_ERR);
2820
2821 jsop.jsop_bufp = &bufp;
2822 jsop.jsop_lenp = &len;
2823
2824 rv = jsobj_print(addr, &jsop);
2825 (void) mdb_printf("%s\n", buf);
2826 mdb_free(buf, bufsz);
2827 return (rv == 0 ? DCMD_OK : DCMD_ERR);
2828 }
2829
2830 /* ARGSUSED */
2831 static int
2832 dcmd_v8field(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2833 {
2834 v8_class_t *clp;
2835 v8_field_t *flp;
2836 const char *klass, *field;
2837 uintptr_t offset;
2838
2839 /*
2840 * We may be invoked with either two arguments (class and field name) or
2841 * three (an offset to save).
2842 */
2843 if (argc != 2 && argc != 3)
2844 return (DCMD_USAGE);
2845
2846 if (argv[0].a_type != MDB_TYPE_STRING ||
2847 argv[1].a_type != MDB_TYPE_STRING)
2848 return (DCMD_USAGE);
2849
2850 klass = argv[0].a_un.a_str;
2851 field = argv[1].a_un.a_str;
2852
2853 if (argc == 3) {
2854 if (argv[2].a_type != MDB_TYPE_STRING)
2855 return (DCMD_USAGE);
2856
2857 offset = mdb_strtoull(argv[2].a_un.a_str);
2977 "in the target binary. However, it's possible to use the module\n"
2978 "with a binary not built with metadata by loading one of the\n"
2979 "canned configurations.\n\n");
2980
2981 mdb_printf("Available configurations:\n");
2982
2983 (void) mdb_inc_indent(4);
2984
2985 for (cfgpp = v8_cfgs; *cfgpp != NULL; cfgpp++) {
2986 cfp = *cfgpp;
2987 mdb_printf("%-10s %s\n", cfp->v8cfg_name, cfp->v8cfg_label);
2988 }
2989
2990 (void) mdb_dec_indent(4);
2991 }
2992
2993 /* ARGSUSED */
2994 static int
2995 dcmd_v8load(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2996 {
2997 v8_cfg_t *cfgp, **cfgpp;
2998
2999 if (v8_classes != NULL) {
3000 mdb_warn("v8 module already configured\n");
3001 return (DCMD_ERR);
3002 }
3003
3004 if (argc < 1 || argv->a_type != MDB_TYPE_STRING)
3005 return (DCMD_USAGE);
3006
3007 for (cfgpp = v8_cfgs; *cfgpp != NULL; cfgpp++) {
3008 cfgp = *cfgpp;
3009 if (strcmp(argv->a_un.a_str, cfgp->v8cfg_name) == 0)
3010 break;
3011 }
3012
3013 if (cfgp->v8cfg_name == NULL) {
3014 mdb_warn("unknown configuration: \"%s\"\n", argv->a_un.a_str);
3015 return (DCMD_ERR);
3016 }
3017
3018 if (autoconfigure(cfgp) == -1) {
3019 mdb_warn("autoconfigure failed\n");
3020 return (DCMD_ERR);
3021 }
3022
3023 mdb_printf("V8 dmod configured based on %s\n", cfgp->v8cfg_name);
3024 return (DCMD_OK);
3025 }
3026
3027 static int
3028 walk_jsframes_init(mdb_walk_state_t *wsp)
3029 {
3030 if (wsp->walk_addr != NULL)
3031 return (WALK_NEXT);
3032
3033 if (load_current_context(&wsp->walk_addr, NULL) != 0)
|
1482 if (props != NULL)
1483 mdb_free(props, nprops * sizeof (uintptr_t));
1484
1485 if (descs != NULL)
1486 mdb_free(descs, ndescs * sizeof (uintptr_t));
1487
1488 if (content != NULL && V8_PROP_IDX_CONTENT != -1)
1489 mdb_free(content, ncontent * sizeof (uintptr_t));
1490
1491 return (rval);
1492 }
1493
1494 /*
1495 * Given the line endings table in "lendsp", computes the line number for the
1496 * given token position and print the result into "buf". If "lendsp" is
1497 * undefined, prints the token position instead.
1498 */
1499 static int
1500 jsfunc_lineno(uintptr_t lendsp, uintptr_t tokpos, char *buf, size_t buflen)
1501 {
1502 uintptr_t size, bufsz, lower, upper, ii = 0;
1503 uintptr_t *data;
1504
1505 if (jsobj_is_undefined(lendsp)) {
1506 /*
1507 * The token position is an SMI, but it comes in as its raw
1508 * value so we can more easily compare it to values in the line
1509 * endings table. If we're just printing the position directly,
1510 * we must convert it here.
1511 */
1512 mdb_snprintf(buf, buflen, "position %d", V8_SMI_VALUE(tokpos));
1513 return (0);
1514 }
1515
1516 if (read_heap_smi(&size, lendsp, V8_OFF_FIXEDARRAY_LENGTH) != 0)
1517 return (-1);
1518
1519 bufsz = size * sizeof (data[0]);
1520
1521 if ((data = mdb_alloc(bufsz, UM_NOSLEEP)) == NULL) {
1522 v8_warn("failed to alloc %d bytes for FixedArray data", bufsz);
2817
2818 if ((buf = bufp = mdb_zalloc(bufsz, UM_NOSLEEP)) == NULL)
2819 return (DCMD_ERR);
2820
2821 jsop.jsop_bufp = &bufp;
2822 jsop.jsop_lenp = &len;
2823
2824 rv = jsobj_print(addr, &jsop);
2825 (void) mdb_printf("%s\n", buf);
2826 mdb_free(buf, bufsz);
2827 return (rv == 0 ? DCMD_OK : DCMD_ERR);
2828 }
2829
2830 /* ARGSUSED */
2831 static int
2832 dcmd_v8field(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2833 {
2834 v8_class_t *clp;
2835 v8_field_t *flp;
2836 const char *klass, *field;
2837 uintptr_t offset = 0;
2838
2839 /*
2840 * We may be invoked with either two arguments (class and field name) or
2841 * three (an offset to save).
2842 */
2843 if (argc != 2 && argc != 3)
2844 return (DCMD_USAGE);
2845
2846 if (argv[0].a_type != MDB_TYPE_STRING ||
2847 argv[1].a_type != MDB_TYPE_STRING)
2848 return (DCMD_USAGE);
2849
2850 klass = argv[0].a_un.a_str;
2851 field = argv[1].a_un.a_str;
2852
2853 if (argc == 3) {
2854 if (argv[2].a_type != MDB_TYPE_STRING)
2855 return (DCMD_USAGE);
2856
2857 offset = mdb_strtoull(argv[2].a_un.a_str);
2977 "in the target binary. However, it's possible to use the module\n"
2978 "with a binary not built with metadata by loading one of the\n"
2979 "canned configurations.\n\n");
2980
2981 mdb_printf("Available configurations:\n");
2982
2983 (void) mdb_inc_indent(4);
2984
2985 for (cfgpp = v8_cfgs; *cfgpp != NULL; cfgpp++) {
2986 cfp = *cfgpp;
2987 mdb_printf("%-10s %s\n", cfp->v8cfg_name, cfp->v8cfg_label);
2988 }
2989
2990 (void) mdb_dec_indent(4);
2991 }
2992
2993 /* ARGSUSED */
2994 static int
2995 dcmd_v8load(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2996 {
2997 v8_cfg_t *cfgp = NULL, **cfgpp;
2998
2999 if (v8_classes != NULL) {
3000 mdb_warn("v8 module already configured\n");
3001 return (DCMD_ERR);
3002 }
3003
3004 if (argc < 1 || argv->a_type != MDB_TYPE_STRING)
3005 return (DCMD_USAGE);
3006
3007 for (cfgpp = v8_cfgs; *cfgpp != NULL; cfgpp++) {
3008 cfgp = *cfgpp;
3009 if (strcmp(argv->a_un.a_str, cfgp->v8cfg_name) == 0)
3010 break;
3011 }
3012
3013 if (cfgp == NULL || cfgp->v8cfg_name == NULL) {
3014 mdb_warn("unknown configuration: \"%s\"\n", argv->a_un.a_str);
3015 return (DCMD_ERR);
3016 }
3017
3018 if (autoconfigure(cfgp) == -1) {
3019 mdb_warn("autoconfigure failed\n");
3020 return (DCMD_ERR);
3021 }
3022
3023 mdb_printf("V8 dmod configured based on %s\n", cfgp->v8cfg_name);
3024 return (DCMD_OK);
3025 }
3026
3027 static int
3028 walk_jsframes_init(mdb_walk_state_t *wsp)
3029 {
3030 if (wsp->walk_addr != NULL)
3031 return (WALK_NEXT);
3032
3033 if (load_current_context(&wsp->walk_addr, NULL) != 0)
|