1178479Sjb/* 2178479Sjb * CDDL HEADER START 3178479Sjb * 4178479Sjb * The contents of this file are subject to the terms of the 5178479Sjb * Common Development and Distribution License, Version 1.0 only 6178479Sjb * (the "License"). You may not use this file except in compliance 7178479Sjb * with the License. 8178479Sjb * 9178479Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10178479Sjb * or http://www.opensolaris.org/os/licensing. 11178479Sjb * See the License for the specific language governing permissions 12178479Sjb * and limitations under the License. 13178479Sjb * 14178479Sjb * When distributing Covered Code, include this CDDL HEADER in each 15178479Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16178479Sjb * If applicable, add the following below this CDDL HEADER, with the 17178479Sjb * fields enclosed by brackets "[]" replaced with your own identifying 18178479Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 19178479Sjb * 20178479Sjb * CDDL HEADER END 21178479Sjb */ 22178479Sjb/* 23178479Sjb * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24178479Sjb * Use is subject to license terms. 25178479Sjb */ 26178479Sjb 27178479Sjb#pragma ident "%Z%%M% %I% %E% SMI" 28178479Sjb 29178479Sjb#include <sys/types.h> 30178479Sjb#include <strings.h> 31178479Sjb#include <stdlib.h> 32178479Sjb#include <assert.h> 33178479Sjb 34178479Sjb#include <dt_impl.h> 35178479Sjb#include <dt_parser.h> 36178479Sjb#include <dt_as.h> 37178479Sjb 38178479Sjbvoid 39178479Sjbdt_irlist_create(dt_irlist_t *dlp) 40178479Sjb{ 41178479Sjb bzero(dlp, sizeof (dt_irlist_t)); 42178479Sjb dlp->dl_label = 1; 43178479Sjb} 44178479Sjb 45178479Sjbvoid 46178479Sjbdt_irlist_destroy(dt_irlist_t *dlp) 47178479Sjb{ 48178479Sjb dt_irnode_t *dip, *nip; 49178479Sjb 50178479Sjb for (dip = dlp->dl_list; dip != NULL; dip = nip) { 51178479Sjb nip = dip->di_next; 52178479Sjb free(dip); 53178479Sjb } 54178479Sjb} 55178479Sjb 56178479Sjbvoid 57178479Sjbdt_irlist_append(dt_irlist_t *dlp, dt_irnode_t *dip) 58178479Sjb{ 59178479Sjb if (dlp->dl_last != NULL) 60178479Sjb dlp->dl_last->di_next = dip; 61178479Sjb else 62178479Sjb dlp->dl_list = dip; 63178479Sjb 64178479Sjb dlp->dl_last = dip; 65178479Sjb 66178479Sjb if (dip->di_label == DT_LBL_NONE || dip->di_instr != DIF_INSTR_NOP) 67178479Sjb dlp->dl_len++; /* don't count forward refs in instr count */ 68178479Sjb} 69178479Sjb 70178479Sjbuint_t 71178479Sjbdt_irlist_label(dt_irlist_t *dlp) 72178479Sjb{ 73178479Sjb return (dlp->dl_label++); 74178479Sjb} 75178479Sjb 76178479Sjb/*ARGSUSED*/ 77178479Sjbstatic int 78178479Sjbdt_countvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) 79178479Sjb{ 80178479Sjb size_t *np = data; 81178479Sjb 82178479Sjb if (idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW)) 83178479Sjb (*np)++; /* include variable in vartab */ 84178479Sjb 85178479Sjb return (0); 86178479Sjb} 87178479Sjb 88178479Sjb/*ARGSUSED*/ 89178479Sjbstatic int 90178479Sjbdt_copyvar(dt_idhash_t *dhp, dt_ident_t *idp, void *data) 91178479Sjb{ 92178479Sjb dt_pcb_t *pcb = data; 93178479Sjb dtrace_difv_t *dvp; 94178479Sjb ssize_t stroff; 95178479Sjb dt_node_t dn; 96178479Sjb 97178479Sjb if (!(idp->di_flags & (DT_IDFLG_DIFR | DT_IDFLG_DIFW))) 98178479Sjb return (0); /* omit variable from vartab */ 99178479Sjb 100178479Sjb dvp = &pcb->pcb_difo->dtdo_vartab[pcb->pcb_asvidx++]; 101178479Sjb stroff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name); 102178479Sjb 103178479Sjb if (stroff == -1L) 104178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 105178479Sjb if (stroff > DIF_STROFF_MAX) 106178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG); 107178479Sjb 108178479Sjb dvp->dtdv_name = (uint_t)stroff; 109178479Sjb dvp->dtdv_id = idp->di_id; 110178479Sjb dvp->dtdv_flags = 0; 111178479Sjb 112178479Sjb dvp->dtdv_kind = (idp->di_kind == DT_IDENT_ARRAY) ? 113178479Sjb DIFV_KIND_ARRAY : DIFV_KIND_SCALAR; 114178479Sjb 115178479Sjb if (idp->di_flags & DT_IDFLG_LOCAL) 116178479Sjb dvp->dtdv_scope = DIFV_SCOPE_LOCAL; 117178479Sjb else if (idp->di_flags & DT_IDFLG_TLS) 118178479Sjb dvp->dtdv_scope = DIFV_SCOPE_THREAD; 119178479Sjb else 120178479Sjb dvp->dtdv_scope = DIFV_SCOPE_GLOBAL; 121178479Sjb 122178479Sjb if (idp->di_flags & DT_IDFLG_DIFR) 123178479Sjb dvp->dtdv_flags |= DIFV_F_REF; 124178479Sjb if (idp->di_flags & DT_IDFLG_DIFW) 125178479Sjb dvp->dtdv_flags |= DIFV_F_MOD; 126178479Sjb 127178479Sjb bzero(&dn, sizeof (dn)); 128178479Sjb dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type); 129178479Sjb dt_node_diftype(pcb->pcb_hdl, &dn, &dvp->dtdv_type); 130178479Sjb 131178479Sjb idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW); 132178479Sjb return (0); 133178479Sjb} 134178479Sjb 135178479Sjbstatic ssize_t 136178479Sjbdt_copystr(const char *s, size_t n, size_t off, dt_pcb_t *pcb) 137178479Sjb{ 138178479Sjb bcopy(s, pcb->pcb_difo->dtdo_strtab + off, n); 139178479Sjb return (n); 140178479Sjb} 141178479Sjb 142178479Sjb/* 143178479Sjb * Rewrite the xlate/xlarg instruction at dtdo_buf[i] so that the instruction's 144178479Sjb * xltab index reflects the offset 'xi' of the assigned dtdo_xlmtab[] location. 145178479Sjb * We track the cumulative references to translators and members in the pcb's 146178479Sjb * pcb_asxrefs[] array, a two-dimensional array of bitmaps indexed by the 147178479Sjb * global translator id and then by the corresponding translator member id. 148178479Sjb */ 149178479Sjbstatic void 150178479Sjbdt_as_xlate(dt_pcb_t *pcb, dtrace_difo_t *dp, 151178479Sjb uint_t i, uint_t xi, dt_node_t *dnp) 152178479Sjb{ 153178479Sjb dtrace_hdl_t *dtp = pcb->pcb_hdl; 154178479Sjb dt_xlator_t *dxp = dnp->dn_membexpr->dn_xlator; 155178479Sjb 156178479Sjb assert(i < dp->dtdo_len); 157178479Sjb assert(xi < dp->dtdo_xlmlen); 158178479Sjb 159178479Sjb assert(dnp->dn_kind == DT_NODE_MEMBER); 160178479Sjb assert(dnp->dn_membexpr->dn_kind == DT_NODE_XLATOR); 161178479Sjb 162178479Sjb assert(dxp->dx_id < dtp->dt_xlatorid); 163178479Sjb assert(dnp->dn_membid < dxp->dx_nmembers); 164178479Sjb 165178479Sjb if (pcb->pcb_asxrefs == NULL) { 166178479Sjb pcb->pcb_asxreflen = dtp->dt_xlatorid; 167178479Sjb pcb->pcb_asxrefs = 168178479Sjb dt_zalloc(dtp, sizeof (ulong_t *) * pcb->pcb_asxreflen); 169178479Sjb if (pcb->pcb_asxrefs == NULL) 170178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 171178479Sjb } 172178479Sjb 173178479Sjb if (pcb->pcb_asxrefs[dxp->dx_id] == NULL) { 174178479Sjb pcb->pcb_asxrefs[dxp->dx_id] = 175178479Sjb dt_zalloc(dtp, BT_SIZEOFMAP(dxp->dx_nmembers)); 176178479Sjb if (pcb->pcb_asxrefs[dxp->dx_id] == NULL) 177178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 178178479Sjb } 179178479Sjb 180178479Sjb dp->dtdo_buf[i] = DIF_INSTR_XLATE( 181178479Sjb DIF_INSTR_OP(dp->dtdo_buf[i]), xi, DIF_INSTR_RD(dp->dtdo_buf[i])); 182178479Sjb 183178479Sjb BT_SET(pcb->pcb_asxrefs[dxp->dx_id], dnp->dn_membid); 184178479Sjb dp->dtdo_xlmtab[xi] = dnp; 185178479Sjb} 186178479Sjb 187178479Sjbstatic void 188178479Sjbdt_as_undef(const dt_ident_t *idp, uint_t offset) 189178479Sjb{ 190178479Sjb const char *kind, *mark = (idp->di_flags & DT_IDFLG_USER) ? "``" : "`"; 191178479Sjb const dtrace_syminfo_t *dts = idp->di_data; 192178479Sjb 193178479Sjb if (idp->di_flags & DT_IDFLG_USER) 194178479Sjb kind = "user"; 195178479Sjb else if (idp->di_flags & DT_IDFLG_PRIM) 196178479Sjb kind = "primary kernel"; 197178479Sjb else 198178479Sjb kind = "loadable kernel"; 199178479Sjb 200178479Sjb yylineno = idp->di_lineno; 201178479Sjb 202178479Sjb xyerror(D_ASRELO, "relocation remains against %s symbol %s%s%s (offset " 203178479Sjb "0x%x)\n", kind, dts->dts_object, mark, dts->dts_name, offset); 204178479Sjb} 205178479Sjb 206178479Sjbdtrace_difo_t * 207178479Sjbdt_as(dt_pcb_t *pcb) 208178479Sjb{ 209178479Sjb dtrace_hdl_t *dtp = pcb->pcb_hdl; 210178479Sjb dt_irlist_t *dlp = &pcb->pcb_ir; 211178479Sjb uint_t *labels = NULL; 212178479Sjb dt_irnode_t *dip; 213178479Sjb dtrace_difo_t *dp; 214178479Sjb dt_ident_t *idp; 215178479Sjb 216178479Sjb size_t n = 0; 217178479Sjb uint_t i; 218178479Sjb 219178479Sjb uint_t kmask, kbits, umask, ubits; 220178479Sjb uint_t krel = 0, urel = 0, xlrefs = 0; 221178479Sjb 222178479Sjb /* 223178479Sjb * Select bitmasks based upon the desired symbol linking policy. We 224178479Sjb * test (di_extern->di_flags & xmask) == xbits to determine if the 225178479Sjb * symbol should have a relocation entry generated in the loop below. 226178479Sjb * 227178479Sjb * DT_LINK_KERNEL = kernel symbols static, user symbols dynamic 228178479Sjb * DT_LINK_PRIMARY = primary kernel symbols static, others dynamic 229178479Sjb * DT_LINK_DYNAMIC = all symbols dynamic 230178479Sjb * DT_LINK_STATIC = all symbols static 231178479Sjb * 232178479Sjb * By 'static' we mean that we use the symbol's value at compile-time 233178479Sjb * in the final DIF. By 'dynamic' we mean that we create a relocation 234178479Sjb * table entry for the symbol's value so it can be relocated later. 235178479Sjb */ 236178479Sjb switch (dtp->dt_linkmode) { 237178479Sjb case DT_LINK_KERNEL: 238178479Sjb kmask = 0; 239178479Sjb kbits = -1u; 240178479Sjb umask = DT_IDFLG_USER; 241178479Sjb ubits = DT_IDFLG_USER; 242178479Sjb break; 243178479Sjb case DT_LINK_PRIMARY: 244178479Sjb kmask = DT_IDFLG_USER | DT_IDFLG_PRIM; 245178479Sjb kbits = 0; 246178479Sjb umask = DT_IDFLG_USER; 247178479Sjb ubits = DT_IDFLG_USER; 248178479Sjb break; 249178479Sjb case DT_LINK_DYNAMIC: 250178479Sjb kmask = DT_IDFLG_USER; 251178479Sjb kbits = 0; 252178479Sjb umask = DT_IDFLG_USER; 253178479Sjb ubits = DT_IDFLG_USER; 254178479Sjb break; 255178479Sjb case DT_LINK_STATIC: 256178479Sjb kmask = umask = 0; 257178479Sjb kbits = ubits = -1u; 258178479Sjb break; 259178479Sjb default: 260178479Sjb xyerror(D_UNKNOWN, "internal error -- invalid link mode %u\n", 261178479Sjb dtp->dt_linkmode); 262178479Sjb } 263178479Sjb 264178479Sjb assert(pcb->pcb_difo == NULL); 265178479Sjb pcb->pcb_difo = dt_zalloc(dtp, sizeof (dtrace_difo_t)); 266178479Sjb 267178479Sjb if ((dp = pcb->pcb_difo) == NULL) 268178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 269178479Sjb 270178479Sjb dp->dtdo_buf = dt_alloc(dtp, sizeof (dif_instr_t) * dlp->dl_len); 271178479Sjb 272178479Sjb if (dp->dtdo_buf == NULL) 273178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 274178479Sjb 275178479Sjb if ((labels = dt_alloc(dtp, sizeof (uint_t) * dlp->dl_label)) == NULL) 276178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 277178479Sjb 278178479Sjb /* 279178479Sjb * Make an initial pass through the instruction list, filling in the 280178479Sjb * instruction buffer with valid instructions and skipping labeled nops. 281178479Sjb * While doing this, we also fill in our labels[] translation table 282178479Sjb * and we count up the number of relocation table entries we will need. 283178479Sjb */ 284178479Sjb for (i = 0, dip = dlp->dl_list; dip != NULL; dip = dip->di_next) { 285178479Sjb if (dip->di_label != DT_LBL_NONE) 286178479Sjb labels[dip->di_label] = i; 287178479Sjb 288178479Sjb if (dip->di_label == DT_LBL_NONE || 289178479Sjb dip->di_instr != DIF_INSTR_NOP) 290178479Sjb dp->dtdo_buf[i++] = dip->di_instr; 291178479Sjb 292178479Sjb if (dip->di_extern == NULL) 293178479Sjb continue; /* no external references needed */ 294178479Sjb 295178479Sjb switch (DIF_INSTR_OP(dip->di_instr)) { 296178479Sjb case DIF_OP_SETX: 297178479Sjb idp = dip->di_extern; 298178479Sjb if ((idp->di_flags & kmask) == kbits) 299178479Sjb krel++; 300178479Sjb else if ((idp->di_flags & umask) == ubits) 301178479Sjb urel++; 302178479Sjb break; 303178479Sjb case DIF_OP_XLATE: 304178479Sjb case DIF_OP_XLARG: 305178479Sjb xlrefs++; 306178479Sjb break; 307178479Sjb default: 308178479Sjb xyerror(D_UNKNOWN, "unexpected assembler relocation " 309178479Sjb "for opcode 0x%x\n", DIF_INSTR_OP(dip->di_instr)); 310178479Sjb } 311178479Sjb } 312178479Sjb 313178479Sjb assert(i == dlp->dl_len); 314178479Sjb dp->dtdo_len = dlp->dl_len; 315178479Sjb 316178479Sjb /* 317178479Sjb * Make a second pass through the instructions, relocating each branch 318178479Sjb * label to the index of the final instruction in the buffer and noting 319178479Sjb * any other instruction-specific DIFO flags such as dtdo_destructive. 320178479Sjb */ 321178479Sjb for (i = 0; i < dp->dtdo_len; i++) { 322178479Sjb dif_instr_t instr = dp->dtdo_buf[i]; 323178479Sjb uint_t op = DIF_INSTR_OP(instr); 324178479Sjb 325178479Sjb if (op == DIF_OP_CALL) { 326178479Sjb if (DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUT || 327178479Sjb DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUTSTR) 328178479Sjb dp->dtdo_destructive = 1; 329178479Sjb continue; 330178479Sjb } 331178479Sjb 332178479Sjb if (op >= DIF_OP_BA && op <= DIF_OP_BLEU) { 333178479Sjb assert(DIF_INSTR_LABEL(instr) < dlp->dl_label); 334178479Sjb dp->dtdo_buf[i] = DIF_INSTR_BRANCH(op, 335178479Sjb labels[DIF_INSTR_LABEL(instr)]); 336178479Sjb } 337178479Sjb } 338178479Sjb 339178479Sjb dt_free(dtp, labels); 340178479Sjb pcb->pcb_asvidx = 0; 341178479Sjb 342178479Sjb /* 343178479Sjb * Allocate memory for the appropriate number of variable records and 344178479Sjb * then fill in each variable record. As we populate the variable 345178479Sjb * table we insert the corresponding variable names into the strtab. 346178479Sjb */ 347178479Sjb (void) dt_idhash_iter(dtp->dt_tls, dt_countvar, &n); 348178479Sjb (void) dt_idhash_iter(dtp->dt_globals, dt_countvar, &n); 349178479Sjb (void) dt_idhash_iter(pcb->pcb_locals, dt_countvar, &n); 350178479Sjb 351178479Sjb if (n != 0) { 352178479Sjb dp->dtdo_vartab = dt_alloc(dtp, n * sizeof (dtrace_difv_t)); 353178479Sjb dp->dtdo_varlen = (uint32_t)n; 354178479Sjb 355178479Sjb if (dp->dtdo_vartab == NULL) 356178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 357178479Sjb 358178479Sjb (void) dt_idhash_iter(dtp->dt_tls, dt_copyvar, pcb); 359178479Sjb (void) dt_idhash_iter(dtp->dt_globals, dt_copyvar, pcb); 360178479Sjb (void) dt_idhash_iter(pcb->pcb_locals, dt_copyvar, pcb); 361178479Sjb } 362178479Sjb 363178479Sjb /* 364178479Sjb * Allocate memory for the appropriate number of relocation table 365178479Sjb * entries based upon our kernel and user counts from the first pass. 366178479Sjb */ 367178479Sjb if (krel != 0) { 368178479Sjb dp->dtdo_kreltab = dt_alloc(dtp, 369178479Sjb krel * sizeof (dof_relodesc_t)); 370178479Sjb dp->dtdo_krelen = krel; 371178479Sjb 372178479Sjb if (dp->dtdo_kreltab == NULL) 373178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 374178479Sjb } 375178479Sjb 376178479Sjb if (urel != 0) { 377178479Sjb dp->dtdo_ureltab = dt_alloc(dtp, 378178479Sjb urel * sizeof (dof_relodesc_t)); 379178479Sjb dp->dtdo_urelen = urel; 380178479Sjb 381178479Sjb if (dp->dtdo_ureltab == NULL) 382178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 383178479Sjb } 384178479Sjb 385178479Sjb if (xlrefs != 0) { 386178479Sjb dp->dtdo_xlmtab = dt_zalloc(dtp, sizeof (dt_node_t *) * xlrefs); 387178479Sjb dp->dtdo_xlmlen = xlrefs; 388178479Sjb 389178479Sjb if (dp->dtdo_xlmtab == NULL) 390178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 391178479Sjb } 392178479Sjb 393178479Sjb /* 394178479Sjb * If any relocations are needed, make another pass through the 395178479Sjb * instruction list and fill in the relocation table entries. 396178479Sjb */ 397178479Sjb if (krel + urel + xlrefs != 0) { 398178479Sjb uint_t knodef = pcb->pcb_cflags & DTRACE_C_KNODEF; 399178479Sjb uint_t unodef = pcb->pcb_cflags & DTRACE_C_UNODEF; 400178479Sjb 401178479Sjb dof_relodesc_t *krp = dp->dtdo_kreltab; 402178479Sjb dof_relodesc_t *urp = dp->dtdo_ureltab; 403178479Sjb dt_node_t **xlp = dp->dtdo_xlmtab; 404178479Sjb 405178479Sjb i = 0; /* dtdo_buf[] index */ 406178479Sjb 407178479Sjb for (dip = dlp->dl_list; dip != NULL; dip = dip->di_next) { 408178479Sjb dof_relodesc_t *rp; 409178479Sjb ssize_t soff; 410178479Sjb uint_t nodef; 411178479Sjb 412178479Sjb if (dip->di_label != DT_LBL_NONE && 413178479Sjb dip->di_instr == DIF_INSTR_NOP) 414178479Sjb continue; /* skip label declarations */ 415178479Sjb 416178479Sjb i++; /* advance dtdo_buf[] index */ 417178479Sjb 418178479Sjb if (DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLATE || 419178479Sjb DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLARG) { 420178479Sjb assert(dp->dtdo_buf[i - 1] == dip->di_instr); 421178479Sjb dt_as_xlate(pcb, dp, i - 1, (uint_t) 422178479Sjb (xlp++ - dp->dtdo_xlmtab), dip->di_extern); 423178479Sjb continue; 424178479Sjb } 425178479Sjb 426178479Sjb if ((idp = dip->di_extern) == NULL) 427178479Sjb continue; /* no relocation entry needed */ 428178479Sjb 429178479Sjb if ((idp->di_flags & kmask) == kbits) { 430178479Sjb nodef = knodef; 431178479Sjb rp = krp++; 432178479Sjb } else if ((idp->di_flags & umask) == ubits) { 433178479Sjb nodef = unodef; 434178479Sjb rp = urp++; 435178479Sjb } else 436178479Sjb continue; 437178479Sjb 438178479Sjb if (!nodef) 439178479Sjb dt_as_undef(idp, i); 440178479Sjb 441178479Sjb assert(DIF_INSTR_OP(dip->di_instr) == DIF_OP_SETX); 442178479Sjb soff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name); 443178479Sjb 444178479Sjb if (soff == -1L) 445178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 446178479Sjb if (soff > DIF_STROFF_MAX) 447178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG); 448178479Sjb 449178479Sjb rp->dofr_name = (dof_stridx_t)soff; 450178479Sjb rp->dofr_type = DOF_RELO_SETX; 451178479Sjb rp->dofr_offset = DIF_INSTR_INTEGER(dip->di_instr) * 452178479Sjb sizeof (uint64_t); 453178479Sjb rp->dofr_data = 0; 454178479Sjb } 455178479Sjb 456178479Sjb assert(krp == dp->dtdo_kreltab + dp->dtdo_krelen); 457178479Sjb assert(urp == dp->dtdo_ureltab + dp->dtdo_urelen); 458178479Sjb assert(xlp == dp->dtdo_xlmtab + dp->dtdo_xlmlen); 459178479Sjb assert(i == dp->dtdo_len); 460178479Sjb } 461178479Sjb 462178479Sjb /* 463178479Sjb * Allocate memory for the compiled string table and then copy the 464178479Sjb * chunks from the string table into the final string buffer. 465178479Sjb */ 466178479Sjb if ((n = dt_strtab_size(pcb->pcb_strtab)) != 0) { 467178479Sjb if ((dp->dtdo_strtab = dt_alloc(dtp, n)) == NULL) 468178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 469178479Sjb 470178479Sjb (void) dt_strtab_write(pcb->pcb_strtab, 471178479Sjb (dt_strtab_write_f *)dt_copystr, pcb); 472178479Sjb dp->dtdo_strlen = (uint32_t)n; 473178479Sjb } 474178479Sjb 475178479Sjb /* 476178479Sjb * Allocate memory for the compiled integer table and then copy the 477178479Sjb * integer constants from the table into the final integer buffer. 478178479Sjb */ 479178479Sjb if ((n = dt_inttab_size(pcb->pcb_inttab)) != 0) { 480178479Sjb if ((dp->dtdo_inttab = dt_alloc(dtp, 481178479Sjb n * sizeof (uint64_t))) == NULL) 482178479Sjb longjmp(pcb->pcb_jmpbuf, EDT_NOMEM); 483178479Sjb 484178479Sjb dt_inttab_write(pcb->pcb_inttab, dp->dtdo_inttab); 485178479Sjb dp->dtdo_intlen = (uint32_t)n; 486178479Sjb } 487178479Sjb 488178479Sjb /* 489178479Sjb * Fill in the DIFO return type from the type associated with the 490178479Sjb * node saved in pcb_dret, and then clear pcb_difo and pcb_dret 491178479Sjb * now that the assembler has completed successfully. 492178479Sjb */ 493178479Sjb dt_node_diftype(dtp, pcb->pcb_dret, &dp->dtdo_rtype); 494178479Sjb pcb->pcb_difo = NULL; 495178479Sjb pcb->pcb_dret = NULL; 496178479Sjb 497178479Sjb if (pcb->pcb_cflags & DTRACE_C_DIFV) 498178479Sjb dt_dis(dp, stderr); 499178479Sjb 500178479Sjb return (dp); 501178479Sjb} 502