10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 230Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <sys/types.h> 300Sstevel@tonic-gate #include <strings.h> 310Sstevel@tonic-gate #include <stdlib.h> 320Sstevel@tonic-gate #include <assert.h> 330Sstevel@tonic-gate 340Sstevel@tonic-gate #include <dt_impl.h> 350Sstevel@tonic-gate #include <dt_parser.h> 360Sstevel@tonic-gate #include <dt_as.h> 370Sstevel@tonic-gate 380Sstevel@tonic-gate void 390Sstevel@tonic-gate dt_irlist_create(dt_irlist_t *dlp) 400Sstevel@tonic-gate { 410Sstevel@tonic-gate bzero(dlp, sizeof (dt_irlist_t)); 420Sstevel@tonic-gate dlp->dl_label = 1; 430Sstevel@tonic-gate } 440Sstevel@tonic-gate 450Sstevel@tonic-gate void 460Sstevel@tonic-gate dt_irlist_destroy(dt_irlist_t *dlp) 470Sstevel@tonic-gate { 480Sstevel@tonic-gate dt_irnode_t *dip, *nip; 490Sstevel@tonic-gate 500Sstevel@tonic-gate for (dip = dlp->dl_list; dip != NULL; dip = nip) { 510Sstevel@tonic-gate nip = dip->di_next; 520Sstevel@tonic-gate free(dip); 530Sstevel@tonic-gate } 540Sstevel@tonic-gate } 550Sstevel@tonic-gate 560Sstevel@tonic-gate void 570Sstevel@tonic-gate dt_irlist_append(dt_irlist_t *dlp, dt_irnode_t *dip) 580Sstevel@tonic-gate { 590Sstevel@tonic-gate if (dlp->dl_last != NULL) 600Sstevel@tonic-gate dlp->dl_last->di_next = dip; 610Sstevel@tonic-gate else 620Sstevel@tonic-gate dlp->dl_list = dip; 630Sstevel@tonic-gate 640Sstevel@tonic-gate dlp->dl_last = dip; 650Sstevel@tonic-gate 660Sstevel@tonic-gate if (dip->di_label == DT_LBL_NONE || dip->di_instr != DIF_INSTR_NOP) 670Sstevel@tonic-gate dlp->dl_len++; /* don't count forward refs in instr count */ 680Sstevel@tonic-gate } 690Sstevel@tonic-gate 700Sstevel@tonic-gate uint_t 710Sstevel@tonic-gate dt_irlist_label(dt_irlist_t *dlp) 720Sstevel@tonic-gate { 730Sstevel@tonic-gate return (dlp->dl_label++); 740Sstevel@tonic-gate } 750Sstevel@tonic-gate 760Sstevel@tonic-gate /*ARGSUSED*/ 770Sstevel@tonic-gate static int 780Sstevel@tonic-gate dt_countvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) 790Sstevel@tonic-gate { 800Sstevel@tonic-gate size_t *np = data; 810Sstevel@tonic-gate 820Sstevel@tonic-gate if (idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW)) 830Sstevel@tonic-gate (*np)++; /* include variable in vartab */ 840Sstevel@tonic-gate 850Sstevel@tonic-gate return (0); 860Sstevel@tonic-gate } 870Sstevel@tonic-gate 880Sstevel@tonic-gate /*ARGSUSED*/ 890Sstevel@tonic-gate static int 900Sstevel@tonic-gate dt_copyvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) 910Sstevel@tonic-gate { 920Sstevel@tonic-gate dt_pcb_t *pcb = data; 930Sstevel@tonic-gate dtrace_difv_t *dvp; 940Sstevel@tonic-gate ssize_t stroff; 950Sstevel@tonic-gate dt_node_t dn; 960Sstevel@tonic-gate 970Sstevel@tonic-gate if (!(idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW))) 980Sstevel@tonic-gate return (0); /* omit variable from vartab */ 990Sstevel@tonic-gate 1000Sstevel@tonic-gate dvp = &pcb->pcb_difo->dtdo_vartab[pcb->pcb_asvidx++]; 1010Sstevel@tonic-gate stroff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name); 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate if (stroff == -1L) 1040Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 1050Sstevel@tonic-gate if (stroff > DIF_STROFF_MAX) 1060Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG); 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate dvp->dtdv_name = (uint_t)stroff; 1090Sstevel@tonic-gate dvp->dtdv_id = idp->di_id; 1100Sstevel@tonic-gate dvp->dtdv_flags = 0; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate dvp->dtdv_kind = (idp->di_kind == DT_IDENT_ARRAY) ? 1130Sstevel@tonic-gate DIFV_KIND_ARRAY : DIFV_KIND_SCALAR; 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_LOCAL) 1160Sstevel@tonic-gate dvp->dtdv_scope = DIFV_SCOPE_LOCAL; 1170Sstevel@tonic-gate else if (idp->di_flags & DT_IDFLG_TLS) 1180Sstevel@tonic-gate dvp->dtdv_scope = DIFV_SCOPE_THREAD; 1190Sstevel@tonic-gate else 1200Sstevel@tonic-gate dvp->dtdv_scope = DIFV_SCOPE_GLOBAL; 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_DIFR) 1230Sstevel@tonic-gate dvp->dtdv_flags |= DIFV_F_REF; 1240Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_DIFW) 1250Sstevel@tonic-gate dvp->dtdv_flags |= DIFV_F_MOD; 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate bzero(&dn, sizeof (dn)); 1280Sstevel@tonic-gate dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type); 129*265Smws dt_node_diftype(pcb->pcb_hdl, &dn, &dvp->dtdv_type); 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW); 1320Sstevel@tonic-gate return (0); 1330Sstevel@tonic-gate } 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate static ssize_t 1360Sstevel@tonic-gate dt_copystr(const char *s, size_t n, size_t off, dt_pcb_t *pcb) 1370Sstevel@tonic-gate { 1380Sstevel@tonic-gate bcopy(s, pcb->pcb_difo->dtdo_strtab + off, n); 1390Sstevel@tonic-gate return (n); 1400Sstevel@tonic-gate } 1410Sstevel@tonic-gate 142*265Smws /* 143*265Smws * Rewrite the xlate/xlarg instruction at dtdo_buf[i] so that the instruction's 144*265Smws * xltab index reflects the offset 'xi' of the assigned dtdo_xlmtab[] location. 145*265Smws * We track the cumulative references to translators and members in the pcb's 146*265Smws * pcb_asxrefs[] array, a two-dimensional array of bitmaps indexed by the 147*265Smws * global translator id and then by the corresponding translator member id. 148*265Smws */ 149*265Smws static void 150*265Smws dt_as_xlate(dt_pcb_t *pcb, dtrace_difo_t *dp, 151*265Smws uint_t i, uint_t xi, dt_node_t *dnp) 152*265Smws { 153*265Smws dtrace_hdl_t *dtp = pcb->pcb_hdl; 154*265Smws dt_xlator_t *dxp = dnp->dn_membexpr->dn_xlator; 155*265Smws 156*265Smws assert(i < dp->dtdo_len); 157*265Smws assert(xi < dp->dtdo_xlmlen); 158*265Smws 159*265Smws assert(dnp->dn_kind == DT_NODE_MEMBER); 160*265Smws assert(dnp->dn_membexpr->dn_kind == DT_NODE_XLATOR); 161*265Smws 162*265Smws assert(dxp->dx_id < dtp->dt_xlatorid); 163*265Smws assert(dnp->dn_membid < dxp->dx_nmembers); 164*265Smws 165*265Smws if (pcb->pcb_asxrefs == NULL) { 166*265Smws pcb->pcb_asxreflen = dtp->dt_xlatorid; 167*265Smws pcb->pcb_asxrefs = 168*265Smws dt_zalloc(dtp, sizeof (ulong_t *) * pcb->pcb_asxreflen); 169*265Smws if (pcb->pcb_asxrefs == NULL) 170*265Smws longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 171*265Smws } 172*265Smws 173*265Smws if (pcb->pcb_asxrefs[dxp->dx_id] == NULL) { 174*265Smws pcb->pcb_asxrefs[dxp->dx_id] = 175*265Smws dt_zalloc(dtp, BT_SIZEOFMAP(dxp->dx_nmembers)); 176*265Smws if (pcb->pcb_asxrefs[dxp->dx_id] == NULL) 177*265Smws longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 178*265Smws } 179*265Smws 180*265Smws dp->dtdo_buf[i] = DIF_INSTR_XLATE( 181*265Smws DIF_INSTR_OP(dp->dtdo_buf[i]), xi, DIF_INSTR_RD(dp->dtdo_buf[i])); 182*265Smws 183*265Smws BT_SET(pcb->pcb_asxrefs[dxp->dx_id], dnp->dn_membid); 184*265Smws dp->dtdo_xlmtab[xi] = dnp; 185*265Smws } 186*265Smws 1870Sstevel@tonic-gate static void 1880Sstevel@tonic-gate dt_as_undef(const dt_ident_t *idp, uint_t offset) 1890Sstevel@tonic-gate { 1900Sstevel@tonic-gate const char *kind, *mark = (idp->di_flags & DT_IDFLG_USER) ? "``" : "`"; 1910Sstevel@tonic-gate const dtrace_syminfo_t *dts = idp->di_data; 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_USER) 1940Sstevel@tonic-gate kind = "user"; 1950Sstevel@tonic-gate else if (idp->di_flags & DT_IDFLG_PRIM) 1960Sstevel@tonic-gate kind = "primary kernel"; 1970Sstevel@tonic-gate else 1980Sstevel@tonic-gate kind = "loadable kernel"; 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate yylineno = idp->di_lineno; 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate xyerror(D_ASRELO, "relocation remains against %s symbol %s%s%s (offset " 2030Sstevel@tonic-gate "0x%x)\n", kind, dts->dts_object, mark, dts->dts_name, offset); 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate dtrace_difo_t * 2070Sstevel@tonic-gate dt_as(dt_pcb_t *pcb) 2080Sstevel@tonic-gate { 2090Sstevel@tonic-gate dtrace_hdl_t *dtp = pcb->pcb_hdl; 2100Sstevel@tonic-gate dt_irlist_t *dlp = &pcb->pcb_ir; 2110Sstevel@tonic-gate uint_t *labels = NULL; 2120Sstevel@tonic-gate dt_irnode_t *dip; 2130Sstevel@tonic-gate dtrace_difo_t *dp; 2140Sstevel@tonic-gate dt_ident_t *idp; 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate size_t n = 0; 2170Sstevel@tonic-gate uint_t i; 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate uint_t kmask, kbits, umask, ubits; 220*265Smws uint_t krel = 0, urel = 0, xlrefs = 0; 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate /* 2230Sstevel@tonic-gate * Select bitmasks based upon the desired symbol linking policy. We 224*265Smws * test (di_extern->di_flags & xmask) == xbits to determine if the 2250Sstevel@tonic-gate * symbol should have a relocation entry generated in the loop below. 2260Sstevel@tonic-gate * 2270Sstevel@tonic-gate * DT_LINK_KERNEL = kernel symbols static, user symbols dynamic 2280Sstevel@tonic-gate * DT_LINK_PRIMARY = primary kernel symbols static, others dynamic 2290Sstevel@tonic-gate * DT_LINK_DYNAMIC = all symbols dynamic 2300Sstevel@tonic-gate * DT_LINK_STATIC = all symbols static 2310Sstevel@tonic-gate * 2320Sstevel@tonic-gate * By 'static' we mean that we use the symbol's value at compile-time 2330Sstevel@tonic-gate * in the final DIF. By 'dynamic' we mean that we create a relocation 2340Sstevel@tonic-gate * table entry for the symbol's value so it can be relocated later. 2350Sstevel@tonic-gate */ 2360Sstevel@tonic-gate switch (dtp->dt_linkmode) { 2370Sstevel@tonic-gate case DT_LINK_KERNEL: 2380Sstevel@tonic-gate kmask = 0; 2390Sstevel@tonic-gate kbits = -1u; 2400Sstevel@tonic-gate umask = DT_IDFLG_USER; 2410Sstevel@tonic-gate ubits = DT_IDFLG_USER; 2420Sstevel@tonic-gate break; 2430Sstevel@tonic-gate case DT_LINK_PRIMARY: 2440Sstevel@tonic-gate kmask = DT_IDFLG_USER | DT_IDFLG_PRIM; 2450Sstevel@tonic-gate kbits = 0; 2460Sstevel@tonic-gate umask = DT_IDFLG_USER; 2470Sstevel@tonic-gate ubits = DT_IDFLG_USER; 2480Sstevel@tonic-gate break; 2490Sstevel@tonic-gate case DT_LINK_DYNAMIC: 2500Sstevel@tonic-gate kmask = DT_IDFLG_USER; 2510Sstevel@tonic-gate kbits = 0; 2520Sstevel@tonic-gate umask = DT_IDFLG_USER; 2530Sstevel@tonic-gate ubits = DT_IDFLG_USER; 2540Sstevel@tonic-gate break; 2550Sstevel@tonic-gate case DT_LINK_STATIC: 2560Sstevel@tonic-gate kmask = umask = 0; 2570Sstevel@tonic-gate kbits = ubits = -1u; 2580Sstevel@tonic-gate break; 2590Sstevel@tonic-gate default: 2600Sstevel@tonic-gate xyerror(D_UNKNOWN, "internal error -- invalid link mode %u\n", 2610Sstevel@tonic-gate dtp->dt_linkmode); 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 264*265Smws assert(pcb->pcb_difo == NULL); 265*265Smws pcb->pcb_difo = dt_zalloc(dtp, sizeof (dtrace_difo_t)); 266*265Smws 267*265Smws if ((dp = pcb->pcb_difo) == NULL) 2680Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 2690Sstevel@tonic-gate 270*265Smws dp->dtdo_buf = dt_alloc(dtp, sizeof (dif_instr_t) * dlp->dl_len); 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate if (dp->dtdo_buf == NULL) 2730Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 2740Sstevel@tonic-gate 275*265Smws if ((labels = dt_alloc(dtp, sizeof (uint_t) * dlp->dl_label)) == NULL) 2760Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate /* 2790Sstevel@tonic-gate * Make an initial pass through the instruction list, filling in the 2800Sstevel@tonic-gate * instruction buffer with valid instructions and skipping labeled nops. 2810Sstevel@tonic-gate * While doing this, we also fill in our labels[] translation table 2820Sstevel@tonic-gate * and we count up the number of relocation table entries we will need. 2830Sstevel@tonic-gate */ 2840Sstevel@tonic-gate for (i = 0, dip = dlp->dl_list; dip != NULL; dip = dip->di_next) { 2850Sstevel@tonic-gate if (dip->di_label != DT_LBL_NONE) 2860Sstevel@tonic-gate labels[dip->di_label] = i; 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate if (dip->di_label == DT_LBL_NONE || 2890Sstevel@tonic-gate dip->di_instr != DIF_INSTR_NOP) 2900Sstevel@tonic-gate dp->dtdo_buf[i++] = dip->di_instr; 2910Sstevel@tonic-gate 292*265Smws if (dip->di_extern == NULL) 293*265Smws continue; /* no external references needed */ 2940Sstevel@tonic-gate 295*265Smws switch (DIF_INSTR_OP(dip->di_instr)) { 296*265Smws case DIF_OP_SETX: 297*265Smws idp = dip->di_extern; 298*265Smws if ((idp->di_flags & kmask) == kbits) 299*265Smws krel++; 300*265Smws else if ((idp->di_flags & umask) == ubits) 301*265Smws urel++; 302*265Smws break; 303*265Smws case DIF_OP_XLATE: 304*265Smws case DIF_OP_XLARG: 305*265Smws xlrefs++; 306*265Smws break; 307*265Smws default: 308*265Smws xyerror(D_UNKNOWN, "unexpected assembler relocation " 309*265Smws "for opcode 0x%x\n", DIF_INSTR_OP(dip->di_instr)); 310*265Smws } 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate assert(i == dlp->dl_len); 3140Sstevel@tonic-gate dp->dtdo_len = dlp->dl_len; 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate /* 3170Sstevel@tonic-gate * Make a second pass through the instructions, relocating each branch 3180Sstevel@tonic-gate * label to the index of the final instruction in the buffer and noting 3190Sstevel@tonic-gate * any other instruction-specific DIFO flags such as dtdo_destructive. 3200Sstevel@tonic-gate */ 3210Sstevel@tonic-gate for (i = 0; i < dp->dtdo_len; i++) { 3220Sstevel@tonic-gate dif_instr_t instr = dp->dtdo_buf[i]; 3230Sstevel@tonic-gate uint_t op = DIF_INSTR_OP(instr); 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate if (op == DIF_OP_CALL) { 3260Sstevel@tonic-gate if (DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUT || 3270Sstevel@tonic-gate DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUTSTR) 3280Sstevel@tonic-gate dp->dtdo_destructive = 1; 3290Sstevel@tonic-gate continue; 3300Sstevel@tonic-gate } 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate if (op >= DIF_OP_BA && op <= DIF_OP_BLEU) { 3330Sstevel@tonic-gate assert(DIF_INSTR_LABEL(instr) < dlp->dl_label); 3340Sstevel@tonic-gate dp->dtdo_buf[i] = DIF_INSTR_BRANCH(op, 3350Sstevel@tonic-gate labels[DIF_INSTR_LABEL(instr)]); 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate } 3380Sstevel@tonic-gate 339*265Smws dt_free(dtp, labels); 340*265Smws pcb->pcb_asvidx = 0; 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate /* 3430Sstevel@tonic-gate * Allocate memory for the appropriate number of variable records and 3440Sstevel@tonic-gate * then fill in each variable record. As we populate the variable 3450Sstevel@tonic-gate * table we insert the corresponding variable names into the strtab. 3460Sstevel@tonic-gate */ 3470Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_tls, dt_countvar, &n); 3480Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_globals, dt_countvar, &n); 3490Sstevel@tonic-gate (void) dt_idhash_iter(pcb->pcb_locals, dt_countvar, &n); 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate if (n != 0) { 352*265Smws dp->dtdo_vartab = dt_alloc(dtp, n * sizeof (dtrace_difv_t)); 3530Sstevel@tonic-gate dp->dtdo_varlen = (uint32_t)n; 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate if (dp->dtdo_vartab == NULL) 3560Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_tls, dt_copyvar, pcb); 3590Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_globals, dt_copyvar, pcb); 3600Sstevel@tonic-gate (void) dt_idhash_iter(pcb->pcb_locals, dt_copyvar, pcb); 3610Sstevel@tonic-gate } 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate /* 3640Sstevel@tonic-gate * Allocate memory for the appropriate number of relocation table 3650Sstevel@tonic-gate * entries based upon our kernel and user counts from the first pass. 3660Sstevel@tonic-gate */ 3670Sstevel@tonic-gate if (krel != 0) { 368*265Smws dp->dtdo_kreltab = dt_alloc(dtp, 369*265Smws krel * sizeof (dof_relodesc_t)); 3700Sstevel@tonic-gate dp->dtdo_krelen = krel; 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate if (dp->dtdo_kreltab == NULL) 3730Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate if (urel != 0) { 377*265Smws dp->dtdo_ureltab = dt_alloc(dtp, 378*265Smws urel * sizeof (dof_relodesc_t)); 3790Sstevel@tonic-gate dp->dtdo_urelen = urel; 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate if (dp->dtdo_ureltab == NULL) 3820Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 3830Sstevel@tonic-gate } 3840Sstevel@tonic-gate 385*265Smws if (xlrefs != 0) { 386*265Smws dp->dtdo_xlmtab = dt_zalloc(dtp, sizeof (dt_node_t *) * xlrefs); 387*265Smws dp->dtdo_xlmlen = xlrefs; 388*265Smws 389*265Smws if (dp->dtdo_xlmtab == NULL) 390*265Smws longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 391*265Smws } 392*265Smws 3930Sstevel@tonic-gate /* 3940Sstevel@tonic-gate * If any relocations are needed, make another pass through the 3950Sstevel@tonic-gate * instruction list and fill in the relocation table entries. 3960Sstevel@tonic-gate */ 397*265Smws if (krel + urel + xlrefs != 0) { 3980Sstevel@tonic-gate uint_t knodef = pcb->pcb_cflags & DTRACE_C_KNODEF; 3990Sstevel@tonic-gate uint_t unodef = pcb->pcb_cflags & DTRACE_C_UNODEF; 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate dof_relodesc_t *krp = dp->dtdo_kreltab; 4020Sstevel@tonic-gate dof_relodesc_t *urp = dp->dtdo_ureltab; 403*265Smws dt_node_t **xlp = dp->dtdo_xlmtab; 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate i = 0; /* dtdo_buf[] index */ 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate for (dip = dlp->dl_list; dip != NULL; dip = dip->di_next) { 4080Sstevel@tonic-gate dof_relodesc_t *rp; 4090Sstevel@tonic-gate ssize_t soff; 4100Sstevel@tonic-gate uint_t nodef; 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate if (dip->di_label != DT_LBL_NONE && 4130Sstevel@tonic-gate dip->di_instr == DIF_INSTR_NOP) 4140Sstevel@tonic-gate continue; /* skip label declarations */ 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate i++; /* advance dtdo_buf[] index */ 4170Sstevel@tonic-gate 418*265Smws if (DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLATE || 419*265Smws DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLARG) { 420*265Smws assert(dp->dtdo_buf[i - 1] == dip->di_instr); 421*265Smws dt_as_xlate(pcb, dp, i - 1, (uint_t) 422*265Smws (xlp++ - dp->dtdo_xlmtab), dip->di_extern); 423*265Smws continue; 424*265Smws } 425*265Smws 426*265Smws if ((idp = dip->di_extern) == NULL) 4270Sstevel@tonic-gate continue; /* no relocation entry needed */ 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate if ((idp->di_flags & kmask) == kbits) { 4300Sstevel@tonic-gate nodef = knodef; 4310Sstevel@tonic-gate rp = krp++; 4320Sstevel@tonic-gate } else if ((idp->di_flags & umask) == ubits) { 4330Sstevel@tonic-gate nodef = unodef; 4340Sstevel@tonic-gate rp = urp++; 4350Sstevel@tonic-gate } else 4360Sstevel@tonic-gate continue; 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate if (!nodef) 4390Sstevel@tonic-gate dt_as_undef(idp, i); 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate assert(DIF_INSTR_OP(dip->di_instr) == DIF_OP_SETX); 4420Sstevel@tonic-gate soff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name); 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate if (soff == -1L) 4450Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 4460Sstevel@tonic-gate if (soff > DIF_STROFF_MAX) 4470Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG); 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate rp->dofr_name = (dof_stridx_t)soff; 4500Sstevel@tonic-gate rp->dofr_type = DOF_RELO_SETX; 4510Sstevel@tonic-gate rp->dofr_offset = DIF_INSTR_INTEGER(dip->di_instr) * 4520Sstevel@tonic-gate sizeof (uint64_t); 4530Sstevel@tonic-gate rp->dofr_data = 0; 4540Sstevel@tonic-gate } 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate assert(krp == dp->dtdo_kreltab + dp->dtdo_krelen); 4570Sstevel@tonic-gate assert(urp == dp->dtdo_ureltab + dp->dtdo_urelen); 458*265Smws assert(xlp == dp->dtdo_xlmtab + dp->dtdo_xlmlen); 4590Sstevel@tonic-gate assert(i == dp->dtdo_len); 4600Sstevel@tonic-gate } 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate /* 4630Sstevel@tonic-gate * Allocate memory for the compiled string table and then copy the 4640Sstevel@tonic-gate * chunks from the string table into the final string buffer. 4650Sstevel@tonic-gate */ 4660Sstevel@tonic-gate if ((n = dt_strtab_size(pcb->pcb_strtab)) != 0) { 467*265Smws if ((dp->dtdo_strtab = dt_alloc(dtp, n)) == NULL) 4680Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate (void) dt_strtab_write(pcb->pcb_strtab, 4710Sstevel@tonic-gate (dt_strtab_write_f *)dt_copystr, pcb); 4720Sstevel@tonic-gate dp->dtdo_strlen = (uint32_t)n; 4730Sstevel@tonic-gate } 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate /* 4760Sstevel@tonic-gate * Allocate memory for the compiled integer table and then copy the 4770Sstevel@tonic-gate * integer constants from the table into the final integer buffer. 4780Sstevel@tonic-gate */ 4790Sstevel@tonic-gate if ((n = dt_inttab_size(pcb->pcb_inttab)) != 0) { 480*265Smws if ((dp->dtdo_inttab = dt_alloc(dtp, 481*265Smws n * sizeof (uint64_t))) == NULL) 4820Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate dt_inttab_write(pcb->pcb_inttab, dp->dtdo_inttab); 4850Sstevel@tonic-gate dp->dtdo_intlen = (uint32_t)n; 4860Sstevel@tonic-gate } 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate /* 4890Sstevel@tonic-gate * Fill in the DIFO return type from the type associated with the 4900Sstevel@tonic-gate * node saved in pcb_dret, and then clear pcb_difo and pcb_dret 4910Sstevel@tonic-gate * now that the assembler has completed successfully. 4920Sstevel@tonic-gate */ 493*265Smws dt_node_diftype(dtp, pcb->pcb_dret, &dp->dtdo_rtype); 4940Sstevel@tonic-gate pcb->pcb_difo = NULL; 4950Sstevel@tonic-gate pcb->pcb_dret = NULL; 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate if (pcb->pcb_cflags & DTRACE_C_DIFV) 498*265Smws dt_dis(dp, stderr); 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate return (dp); 5010Sstevel@tonic-gate } 502