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