1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <sys/types.h> 30*0Sstevel@tonic-gate #include <strings.h> 31*0Sstevel@tonic-gate #include <stdlib.h> 32*0Sstevel@tonic-gate #include <assert.h> 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate #include <dt_impl.h> 35*0Sstevel@tonic-gate #include <dt_parser.h> 36*0Sstevel@tonic-gate #include <dt_as.h> 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate void 39*0Sstevel@tonic-gate dt_irlist_create(dt_irlist_t *dlp) 40*0Sstevel@tonic-gate { 41*0Sstevel@tonic-gate bzero(dlp, sizeof (dt_irlist_t)); 42*0Sstevel@tonic-gate dlp->dl_label = 1; 43*0Sstevel@tonic-gate } 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate void 46*0Sstevel@tonic-gate dt_irlist_destroy(dt_irlist_t *dlp) 47*0Sstevel@tonic-gate { 48*0Sstevel@tonic-gate dt_irnode_t *dip, *nip; 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate for (dip = dlp->dl_list; dip != NULL; dip = nip) { 51*0Sstevel@tonic-gate nip = dip->di_next; 52*0Sstevel@tonic-gate free(dip); 53*0Sstevel@tonic-gate } 54*0Sstevel@tonic-gate } 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate void 57*0Sstevel@tonic-gate dt_irlist_append(dt_irlist_t *dlp, dt_irnode_t *dip) 58*0Sstevel@tonic-gate { 59*0Sstevel@tonic-gate if (dlp->dl_last != NULL) 60*0Sstevel@tonic-gate dlp->dl_last->di_next = dip; 61*0Sstevel@tonic-gate else 62*0Sstevel@tonic-gate dlp->dl_list = dip; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate dlp->dl_last = dip; 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate if (dip->di_label == DT_LBL_NONE || dip->di_instr != DIF_INSTR_NOP) 67*0Sstevel@tonic-gate dlp->dl_len++; /* don't count forward refs in instr count */ 68*0Sstevel@tonic-gate } 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate uint_t 71*0Sstevel@tonic-gate dt_irlist_label(dt_irlist_t *dlp) 72*0Sstevel@tonic-gate { 73*0Sstevel@tonic-gate return (dlp->dl_label++); 74*0Sstevel@tonic-gate } 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate /*ARGSUSED*/ 77*0Sstevel@tonic-gate static int 78*0Sstevel@tonic-gate dt_countvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) 79*0Sstevel@tonic-gate { 80*0Sstevel@tonic-gate size_t *np = data; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate if (idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW)) 83*0Sstevel@tonic-gate (*np)++; /* include variable in vartab */ 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate return (0); 86*0Sstevel@tonic-gate } 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate /*ARGSUSED*/ 89*0Sstevel@tonic-gate static int 90*0Sstevel@tonic-gate dt_copyvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) 91*0Sstevel@tonic-gate { 92*0Sstevel@tonic-gate dt_pcb_t *pcb = data; 93*0Sstevel@tonic-gate dtrace_difv_t *dvp; 94*0Sstevel@tonic-gate ssize_t stroff; 95*0Sstevel@tonic-gate dt_node_t dn; 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate if (!(idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW))) 98*0Sstevel@tonic-gate return (0); /* omit variable from vartab */ 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate dvp = &pcb->pcb_difo->dtdo_vartab[pcb->pcb_asvidx++]; 101*0Sstevel@tonic-gate stroff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name); 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate if (stroff == -1L) 104*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 105*0Sstevel@tonic-gate if (stroff > DIF_STROFF_MAX) 106*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG); 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate dvp->dtdv_name = (uint_t)stroff; 109*0Sstevel@tonic-gate dvp->dtdv_id = idp->di_id; 110*0Sstevel@tonic-gate dvp->dtdv_flags = 0; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate dvp->dtdv_kind = (idp->di_kind == DT_IDENT_ARRAY) ? 113*0Sstevel@tonic-gate DIFV_KIND_ARRAY : DIFV_KIND_SCALAR; 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_LOCAL) 116*0Sstevel@tonic-gate dvp->dtdv_scope = DIFV_SCOPE_LOCAL; 117*0Sstevel@tonic-gate else if (idp->di_flags & DT_IDFLG_TLS) 118*0Sstevel@tonic-gate dvp->dtdv_scope = DIFV_SCOPE_THREAD; 119*0Sstevel@tonic-gate else 120*0Sstevel@tonic-gate dvp->dtdv_scope = DIFV_SCOPE_GLOBAL; 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_DIFR) 123*0Sstevel@tonic-gate dvp->dtdv_flags |= DIFV_F_REF; 124*0Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_DIFW) 125*0Sstevel@tonic-gate dvp->dtdv_flags |= DIFV_F_MOD; 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate bzero(&dn, sizeof (dn)); 128*0Sstevel@tonic-gate dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type); 129*0Sstevel@tonic-gate dt_node_diftype(&dn, &dvp->dtdv_type); 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW); 132*0Sstevel@tonic-gate return (0); 133*0Sstevel@tonic-gate } 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate static ssize_t 136*0Sstevel@tonic-gate dt_copystr(const char *s, size_t n, size_t off, dt_pcb_t *pcb) 137*0Sstevel@tonic-gate { 138*0Sstevel@tonic-gate bcopy(s, pcb->pcb_difo->dtdo_strtab + off, n); 139*0Sstevel@tonic-gate return (n); 140*0Sstevel@tonic-gate } 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate static void 143*0Sstevel@tonic-gate dt_as_undef(const dt_ident_t *idp, uint_t offset) 144*0Sstevel@tonic-gate { 145*0Sstevel@tonic-gate const char *kind, *mark = (idp->di_flags & DT_IDFLG_USER) ? "``" : "`"; 146*0Sstevel@tonic-gate const dtrace_syminfo_t *dts = idp->di_data; 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate if (idp->di_flags & DT_IDFLG_USER) 149*0Sstevel@tonic-gate kind = "user"; 150*0Sstevel@tonic-gate else if (idp->di_flags & DT_IDFLG_PRIM) 151*0Sstevel@tonic-gate kind = "primary kernel"; 152*0Sstevel@tonic-gate else 153*0Sstevel@tonic-gate kind = "loadable kernel"; 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate yylineno = idp->di_lineno; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate xyerror(D_ASRELO, "relocation remains against %s symbol %s%s%s (offset " 158*0Sstevel@tonic-gate "0x%x)\n", kind, dts->dts_object, mark, dts->dts_name, offset); 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate dtrace_difo_t * 162*0Sstevel@tonic-gate dt_as(dt_pcb_t *pcb) 163*0Sstevel@tonic-gate { 164*0Sstevel@tonic-gate dtrace_hdl_t *dtp = pcb->pcb_hdl; 165*0Sstevel@tonic-gate dt_irlist_t *dlp = &pcb->pcb_ir; 166*0Sstevel@tonic-gate uint_t *labels = NULL; 167*0Sstevel@tonic-gate dt_irnode_t *dip; 168*0Sstevel@tonic-gate dtrace_difo_t *dp; 169*0Sstevel@tonic-gate dt_ident_t *idp; 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate size_t n = 0; 172*0Sstevel@tonic-gate uint_t i; 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate uint_t kmask, kbits, umask, ubits; 175*0Sstevel@tonic-gate uint_t krel = 0, urel = 0; 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate /* 178*0Sstevel@tonic-gate * Select bitmasks based upon the desired symbol linking policy. We 179*0Sstevel@tonic-gate * test (di_ident->di_flags & xmask) == xbits to determine if the 180*0Sstevel@tonic-gate * symbol should have a relocation entry generated in the loop below. 181*0Sstevel@tonic-gate * 182*0Sstevel@tonic-gate * DT_LINK_KERNEL = kernel symbols static, user symbols dynamic 183*0Sstevel@tonic-gate * DT_LINK_PRIMARY = primary kernel symbols static, others dynamic 184*0Sstevel@tonic-gate * DT_LINK_DYNAMIC = all symbols dynamic 185*0Sstevel@tonic-gate * DT_LINK_STATIC = all symbols static 186*0Sstevel@tonic-gate * 187*0Sstevel@tonic-gate * By 'static' we mean that we use the symbol's value at compile-time 188*0Sstevel@tonic-gate * in the final DIF. By 'dynamic' we mean that we create a relocation 189*0Sstevel@tonic-gate * table entry for the symbol's value so it can be relocated later. 190*0Sstevel@tonic-gate */ 191*0Sstevel@tonic-gate switch (dtp->dt_linkmode) { 192*0Sstevel@tonic-gate case DT_LINK_KERNEL: 193*0Sstevel@tonic-gate kmask = 0; 194*0Sstevel@tonic-gate kbits = -1u; 195*0Sstevel@tonic-gate umask = DT_IDFLG_USER; 196*0Sstevel@tonic-gate ubits = DT_IDFLG_USER; 197*0Sstevel@tonic-gate break; 198*0Sstevel@tonic-gate case DT_LINK_PRIMARY: 199*0Sstevel@tonic-gate kmask = DT_IDFLG_USER | DT_IDFLG_PRIM; 200*0Sstevel@tonic-gate kbits = 0; 201*0Sstevel@tonic-gate umask = DT_IDFLG_USER; 202*0Sstevel@tonic-gate ubits = DT_IDFLG_USER; 203*0Sstevel@tonic-gate break; 204*0Sstevel@tonic-gate case DT_LINK_DYNAMIC: 205*0Sstevel@tonic-gate kmask = DT_IDFLG_USER; 206*0Sstevel@tonic-gate kbits = 0; 207*0Sstevel@tonic-gate umask = DT_IDFLG_USER; 208*0Sstevel@tonic-gate ubits = DT_IDFLG_USER; 209*0Sstevel@tonic-gate break; 210*0Sstevel@tonic-gate case DT_LINK_STATIC: 211*0Sstevel@tonic-gate kmask = umask = 0; 212*0Sstevel@tonic-gate kbits = ubits = -1u; 213*0Sstevel@tonic-gate break; 214*0Sstevel@tonic-gate default: 215*0Sstevel@tonic-gate xyerror(D_UNKNOWN, "internal error -- invalid link mode %u\n", 216*0Sstevel@tonic-gate dtp->dt_linkmode); 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate if ((dp = malloc(sizeof (dtrace_difo_t))) == NULL) 220*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate assert(yypcb->pcb_difo == NULL); 223*0Sstevel@tonic-gate yypcb->pcb_difo = dp; 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate bzero(dp, sizeof (dtrace_difo_t)); 226*0Sstevel@tonic-gate dp->dtdo_refcnt = 1; 227*0Sstevel@tonic-gate dp->dtdo_buf = malloc(sizeof (dif_instr_t) * dlp->dl_len); 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate if (dp->dtdo_buf == NULL) 230*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate if ((labels = malloc(sizeof (uint_t) * dlp->dl_label)) == NULL) 233*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate /* 236*0Sstevel@tonic-gate * Make an initial pass through the instruction list, filling in the 237*0Sstevel@tonic-gate * instruction buffer with valid instructions and skipping labeled nops. 238*0Sstevel@tonic-gate * While doing this, we also fill in our labels[] translation table 239*0Sstevel@tonic-gate * and we count up the number of relocation table entries we will need. 240*0Sstevel@tonic-gate */ 241*0Sstevel@tonic-gate for (i = 0, dip = dlp->dl_list; dip != NULL; dip = dip->di_next) { 242*0Sstevel@tonic-gate if (dip->di_label != DT_LBL_NONE) 243*0Sstevel@tonic-gate labels[dip->di_label] = i; 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate if (dip->di_label == DT_LBL_NONE || 246*0Sstevel@tonic-gate dip->di_instr != DIF_INSTR_NOP) 247*0Sstevel@tonic-gate dp->dtdo_buf[i++] = dip->di_instr; 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate if ((idp = dip->di_ident) == NULL) 250*0Sstevel@tonic-gate continue; /* no relocation entry needed */ 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate if ((idp->di_flags & kmask) == kbits) 253*0Sstevel@tonic-gate krel++; 254*0Sstevel@tonic-gate else if ((idp->di_flags & umask) == ubits) 255*0Sstevel@tonic-gate urel++; 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate assert(i == dlp->dl_len); 259*0Sstevel@tonic-gate dp->dtdo_len = dlp->dl_len; 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate /* 262*0Sstevel@tonic-gate * Make a second pass through the instructions, relocating each branch 263*0Sstevel@tonic-gate * label to the index of the final instruction in the buffer and noting 264*0Sstevel@tonic-gate * any other instruction-specific DIFO flags such as dtdo_destructive. 265*0Sstevel@tonic-gate */ 266*0Sstevel@tonic-gate for (i = 0; i < dp->dtdo_len; i++) { 267*0Sstevel@tonic-gate dif_instr_t instr = dp->dtdo_buf[i]; 268*0Sstevel@tonic-gate uint_t op = DIF_INSTR_OP(instr); 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate if (op == DIF_OP_CALL) { 271*0Sstevel@tonic-gate if (DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUT || 272*0Sstevel@tonic-gate DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUTSTR) 273*0Sstevel@tonic-gate dp->dtdo_destructive = 1; 274*0Sstevel@tonic-gate continue; 275*0Sstevel@tonic-gate } 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate if (op >= DIF_OP_BA && op <= DIF_OP_BLEU) { 278*0Sstevel@tonic-gate assert(DIF_INSTR_LABEL(instr) < dlp->dl_label); 279*0Sstevel@tonic-gate dp->dtdo_buf[i] = DIF_INSTR_BRANCH(op, 280*0Sstevel@tonic-gate labels[DIF_INSTR_LABEL(instr)]); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate } 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate free(labels); 285*0Sstevel@tonic-gate yypcb->pcb_asvidx = 0; 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate /* 288*0Sstevel@tonic-gate * Allocate memory for the appropriate number of variable records and 289*0Sstevel@tonic-gate * then fill in each variable record. As we populate the variable 290*0Sstevel@tonic-gate * table we insert the corresponding variable names into the strtab. 291*0Sstevel@tonic-gate */ 292*0Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_tls, dt_countvar, &n); 293*0Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_globals, dt_countvar, &n); 294*0Sstevel@tonic-gate (void) dt_idhash_iter(pcb->pcb_locals, dt_countvar, &n); 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate if (n != 0) { 297*0Sstevel@tonic-gate dp->dtdo_vartab = malloc(n * sizeof (dtrace_difv_t)); 298*0Sstevel@tonic-gate dp->dtdo_varlen = (uint32_t)n; 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate if (dp->dtdo_vartab == NULL) 301*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_tls, dt_copyvar, pcb); 304*0Sstevel@tonic-gate (void) dt_idhash_iter(dtp->dt_globals, dt_copyvar, pcb); 305*0Sstevel@tonic-gate (void) dt_idhash_iter(pcb->pcb_locals, dt_copyvar, pcb); 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate /* 309*0Sstevel@tonic-gate * Allocate memory for the appropriate number of relocation table 310*0Sstevel@tonic-gate * entries based upon our kernel and user counts from the first pass. 311*0Sstevel@tonic-gate */ 312*0Sstevel@tonic-gate if (krel != 0) { 313*0Sstevel@tonic-gate dp->dtdo_kreltab = malloc(krel * sizeof (dof_relodesc_t)); 314*0Sstevel@tonic-gate dp->dtdo_krelen = krel; 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate if (dp->dtdo_kreltab == NULL) 317*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 318*0Sstevel@tonic-gate } 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate if (urel != 0) { 321*0Sstevel@tonic-gate dp->dtdo_ureltab = malloc(urel * sizeof (dof_relodesc_t)); 322*0Sstevel@tonic-gate dp->dtdo_urelen = urel; 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate if (dp->dtdo_ureltab == NULL) 325*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 326*0Sstevel@tonic-gate } 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate /* 329*0Sstevel@tonic-gate * If any relocations are needed, make another pass through the 330*0Sstevel@tonic-gate * instruction list and fill in the relocation table entries. 331*0Sstevel@tonic-gate */ 332*0Sstevel@tonic-gate if (krel + urel != 0) { 333*0Sstevel@tonic-gate uint_t knodef = pcb->pcb_cflags & DTRACE_C_KNODEF; 334*0Sstevel@tonic-gate uint_t unodef = pcb->pcb_cflags & DTRACE_C_UNODEF; 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate dof_relodesc_t *krp = dp->dtdo_kreltab; 337*0Sstevel@tonic-gate dof_relodesc_t *urp = dp->dtdo_ureltab; 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate i = 0; /* dtdo_buf[] index */ 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate for (dip = dlp->dl_list; dip != NULL; dip = dip->di_next) { 342*0Sstevel@tonic-gate dof_relodesc_t *rp; 343*0Sstevel@tonic-gate ssize_t soff; 344*0Sstevel@tonic-gate uint_t nodef; 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate if (dip->di_label != DT_LBL_NONE && 347*0Sstevel@tonic-gate dip->di_instr == DIF_INSTR_NOP) 348*0Sstevel@tonic-gate continue; /* skip label declarations */ 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate i++; /* advance dtdo_buf[] index */ 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate if ((idp = dip->di_ident) == NULL) 353*0Sstevel@tonic-gate continue; /* no relocation entry needed */ 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate if ((idp->di_flags & kmask) == kbits) { 356*0Sstevel@tonic-gate nodef = knodef; 357*0Sstevel@tonic-gate rp = krp++; 358*0Sstevel@tonic-gate } else if ((idp->di_flags & umask) == ubits) { 359*0Sstevel@tonic-gate nodef = unodef; 360*0Sstevel@tonic-gate rp = urp++; 361*0Sstevel@tonic-gate } else 362*0Sstevel@tonic-gate continue; 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gate if (!nodef) 365*0Sstevel@tonic-gate dt_as_undef(idp, i); 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate assert(DIF_INSTR_OP(dip->di_instr) == DIF_OP_SETX); 368*0Sstevel@tonic-gate soff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name); 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate if (soff == -1L) 371*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 372*0Sstevel@tonic-gate if (soff > DIF_STROFF_MAX) 373*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG); 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gate rp->dofr_name = (dof_stridx_t)soff; 376*0Sstevel@tonic-gate rp->dofr_type = DOF_RELO_SETX; 377*0Sstevel@tonic-gate rp->dofr_offset = DIF_INSTR_INTEGER(dip->di_instr) * 378*0Sstevel@tonic-gate sizeof (uint64_t); 379*0Sstevel@tonic-gate rp->dofr_data = 0; 380*0Sstevel@tonic-gate } 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate assert(krp == dp->dtdo_kreltab + dp->dtdo_krelen); 383*0Sstevel@tonic-gate assert(urp == dp->dtdo_ureltab + dp->dtdo_urelen); 384*0Sstevel@tonic-gate assert(i == dp->dtdo_len); 385*0Sstevel@tonic-gate } 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate /* 388*0Sstevel@tonic-gate * Allocate memory for the compiled string table and then copy the 389*0Sstevel@tonic-gate * chunks from the string table into the final string buffer. 390*0Sstevel@tonic-gate */ 391*0Sstevel@tonic-gate if ((n = dt_strtab_size(pcb->pcb_strtab)) != 0) { 392*0Sstevel@tonic-gate if ((dp->dtdo_strtab = malloc(n)) == NULL) 393*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate (void) dt_strtab_write(pcb->pcb_strtab, 396*0Sstevel@tonic-gate (dt_strtab_write_f *)dt_copystr, pcb); 397*0Sstevel@tonic-gate dp->dtdo_strlen = (uint32_t)n; 398*0Sstevel@tonic-gate } 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate /* 401*0Sstevel@tonic-gate * Allocate memory for the compiled integer table and then copy the 402*0Sstevel@tonic-gate * integer constants from the table into the final integer buffer. 403*0Sstevel@tonic-gate */ 404*0Sstevel@tonic-gate if ((n = dt_inttab_size(pcb->pcb_inttab)) != 0) { 405*0Sstevel@tonic-gate if ((dp->dtdo_inttab = malloc(n * sizeof (uint64_t))) == NULL) 406*0Sstevel@tonic-gate longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate dt_inttab_write(pcb->pcb_inttab, dp->dtdo_inttab); 409*0Sstevel@tonic-gate dp->dtdo_intlen = (uint32_t)n; 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate /* 413*0Sstevel@tonic-gate * Fill in the DIFO return type from the type associated with the 414*0Sstevel@tonic-gate * node saved in pcb_dret, and then clear pcb_difo and pcb_dret 415*0Sstevel@tonic-gate * now that the assembler has completed successfully. 416*0Sstevel@tonic-gate */ 417*0Sstevel@tonic-gate dt_node_diftype(pcb->pcb_dret, &dp->dtdo_rtype); 418*0Sstevel@tonic-gate pcb->pcb_difo = NULL; 419*0Sstevel@tonic-gate pcb->pcb_dret = NULL; 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate if (pcb->pcb_cflags & DTRACE_C_DIFV) 422*0Sstevel@tonic-gate dtrace_difo_print(dp, stderr); 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate return (dp); 425*0Sstevel@tonic-gate } 426