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