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 (the "License"). 6 1.1 darran * You may not use this file except in compliance with the License. 7 1.1 darran * 8 1.1 darran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 1.1 darran * or http://www.opensolaris.org/os/licensing. 10 1.1 darran * See the License for the specific language governing permissions 11 1.1 darran * and limitations under the License. 12 1.1 darran * 13 1.1 darran * When distributing Covered Code, include this CDDL HEADER in each 14 1.1 darran * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 1.1 darran * If applicable, add the following below this CDDL HEADER, with the 16 1.1 darran * fields enclosed by brackets "[]" replaced with your own identifying 17 1.1 darran * information: Portions Copyright [yyyy] [name of copyright owner] 18 1.1 darran * 19 1.1 darran * CDDL HEADER END 20 1.1 darran */ 21 1.1 darran /* 22 1.4 haad * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 1.1 darran * Use is subject to license terms. 24 1.1 darran */ 25 1.1 darran 26 1.1 darran /* 27 1.1 darran * Create and parse buffers containing CTF data. 28 1.1 darran */ 29 1.1 darran 30 1.3 darran #if HAVE_NBTOOL_CONFIG_H 31 1.3 darran #include "nbtool_config.h" 32 1.3 darran #endif 33 1.3 darran 34 1.1 darran #include <sys/types.h> 35 1.1 darran #include <stdio.h> 36 1.1 darran #include <stdlib.h> 37 1.1 darran #include <strings.h> 38 1.1 darran #include <ctype.h> 39 1.1 darran #include <zlib.h> 40 1.1 darran #include <elf.h> 41 1.1 darran 42 1.1 darran #include "ctf_headers.h" 43 1.1 darran #include "ctftools.h" 44 1.1 darran #include "strtab.h" 45 1.1 darran #include "memory.h" 46 1.1 darran 47 1.1 darran /* 48 1.1 darran * Name of the file currently being read, used to print error messages. We 49 1.1 darran * assume that only one file will be read at a time, and thus make no attempt 50 1.1 darran * to allow curfile to be used simultaneously by multiple threads. 51 1.1 darran * 52 1.1 darran * The value is only valid during a call to ctf_load. 53 1.1 darran */ 54 1.7 christos static char *curfile; 55 1.6 darran 56 1.1 darran #define CTF_BUF_CHUNK_SIZE (64 * 1024) 57 1.1 darran #define RES_BUF_CHUNK_SIZE (64 * 1024) 58 1.1 darran 59 1.1 darran struct ctf_buf { 60 1.1 darran strtab_t ctb_strtab; /* string table */ 61 1.1 darran caddr_t ctb_base; /* pointer to base of buffer */ 62 1.1 darran caddr_t ctb_end; /* pointer to end of buffer */ 63 1.1 darran caddr_t ctb_ptr; /* pointer to empty buffer space */ 64 1.1 darran size_t ctb_size; /* size of buffer */ 65 1.15 christos size_t nptent; /* number of processed types */ 66 1.15 christos size_t ntholes; /* number of type holes */ 67 1.1 darran }; 68 1.1 darran 69 1.7 christos /* 70 1.7 christos * Macros to reverse byte order 71 1.7 christos */ 72 1.7 christos #define BSWAP_8(x) ((x) & 0xff) 73 1.7 christos #define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) 74 1.7 christos #define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16)) 75 1.7 christos 76 1.7 christos #define SWAP_16(x) (x) = BSWAP_16(x) 77 1.7 christos #define SWAP_32(x) (x) = BSWAP_32(x) 78 1.7 christos 79 1.7 christos static int target_requires_swap; 80 1.7 christos 81 1.1 darran /*PRINTFLIKE1*/ 82 1.10 roy static void __printflike(1, 2) __dead 83 1.2 darran parseterminate(const char *fmt, ...) 84 1.1 darran { 85 1.1 darran static char msgbuf[1024]; /* sigh */ 86 1.1 darran va_list ap; 87 1.1 darran 88 1.1 darran va_start(ap, fmt); 89 1.1 darran vsnprintf(msgbuf, sizeof (msgbuf), fmt, ap); 90 1.1 darran va_end(ap); 91 1.1 darran 92 1.1 darran terminate("%s: %s\n", curfile, msgbuf); 93 1.1 darran } 94 1.1 darran 95 1.2 darran static void 96 1.1 darran ctf_buf_grow(ctf_buf_t *b) 97 1.1 darran { 98 1.1 darran off_t ptroff = b->ctb_ptr - b->ctb_base; 99 1.1 darran 100 1.1 darran b->ctb_size += CTF_BUF_CHUNK_SIZE; 101 1.1 darran b->ctb_base = xrealloc(b->ctb_base, b->ctb_size); 102 1.1 darran b->ctb_end = b->ctb_base + b->ctb_size; 103 1.1 darran b->ctb_ptr = b->ctb_base + ptroff; 104 1.1 darran } 105 1.1 darran 106 1.2 darran static ctf_buf_t * 107 1.1 darran ctf_buf_new(void) 108 1.1 darran { 109 1.1 darran ctf_buf_t *b = xcalloc(sizeof (ctf_buf_t)); 110 1.1 darran 111 1.1 darran strtab_create(&b->ctb_strtab); 112 1.1 darran ctf_buf_grow(b); 113 1.1 darran 114 1.1 darran return (b); 115 1.1 darran } 116 1.1 darran 117 1.2 darran static void 118 1.1 darran ctf_buf_free(ctf_buf_t *b) 119 1.1 darran { 120 1.1 darran strtab_destroy(&b->ctb_strtab); 121 1.1 darran free(b->ctb_base); 122 1.1 darran free(b); 123 1.1 darran } 124 1.1 darran 125 1.2 darran static uint_t 126 1.1 darran ctf_buf_cur(ctf_buf_t *b) 127 1.1 darran { 128 1.1 darran return (b->ctb_ptr - b->ctb_base); 129 1.1 darran } 130 1.1 darran 131 1.2 darran static void 132 1.2 darran ctf_buf_write(ctf_buf_t *b, void const *p, size_t n) 133 1.1 darran { 134 1.1 darran size_t len; 135 1.1 darran 136 1.1 darran while (n != 0) { 137 1.1 darran if (b->ctb_ptr == b->ctb_end) 138 1.1 darran ctf_buf_grow(b); 139 1.1 darran 140 1.1 darran len = MIN((size_t)(b->ctb_end - b->ctb_ptr), n); 141 1.1 darran bcopy(p, b->ctb_ptr, len); 142 1.1 darran b->ctb_ptr += len; 143 1.1 darran 144 1.2 darran p = (char const *)p + len; 145 1.1 darran n -= len; 146 1.1 darran } 147 1.1 darran } 148 1.1 darran 149 1.1 darran static int 150 1.2 darran write_label(void *arg1, void *arg2) 151 1.1 darran { 152 1.2 darran labelent_t *le = arg1; 153 1.2 darran ctf_buf_t *b = arg2; 154 1.1 darran ctf_lblent_t ctl; 155 1.1 darran 156 1.1 darran ctl.ctl_label = strtab_insert(&b->ctb_strtab, le->le_name); 157 1.1 darran ctl.ctl_typeidx = le->le_idx; 158 1.1 darran 159 1.7 christos if (target_requires_swap) { 160 1.7 christos SWAP_32(ctl.ctl_label); 161 1.7 christos SWAP_32(ctl.ctl_typeidx); 162 1.7 christos } 163 1.7 christos 164 1.1 darran ctf_buf_write(b, &ctl, sizeof (ctl)); 165 1.1 darran 166 1.1 darran return (1); 167 1.1 darran } 168 1.1 darran 169 1.1 darran static void 170 1.1 darran write_objects(iidesc_t *idp, ctf_buf_t *b) 171 1.1 darran { 172 1.15 christos uint_t id = (idp ? idp->ii_dtype->t_id : 0); 173 1.1 darran 174 1.7 christos if (target_requires_swap) { 175 1.15 christos SWAP_32(id); 176 1.7 christos } 177 1.7 christos 178 1.11 christos ctf_buf_write(b, &id, sizeof (id)); 179 1.11 christos 180 1.1 darran debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id); 181 1.1 darran } 182 1.1 darran 183 1.1 darran static void 184 1.1 darran write_functions(iidesc_t *idp, ctf_buf_t *b) 185 1.1 darran { 186 1.15 christos uint_t fdata[2]; 187 1.15 christos uint_t id; 188 1.1 darran int nargs; 189 1.1 darran int i; 190 1.1 darran 191 1.1 darran if (!idp) { 192 1.1 darran fdata[0] = 0; 193 1.1 darran ctf_buf_write(b, &fdata[0], sizeof (fdata[0])); 194 1.1 darran 195 1.1 darran debug(3, "Wrote function (null)\n"); 196 1.1 darran return; 197 1.1 darran } 198 1.1 darran 199 1.1 darran nargs = idp->ii_nargs + (idp->ii_vargs != 0); 200 1.4 haad 201 1.15 christos if (nargs > CTF_V3_MAX_VLEN) { 202 1.4 haad terminate("function %s has too many args: %d > %d\n", 203 1.15 christos idp->ii_name, nargs, CTF_V3_MAX_VLEN); 204 1.4 haad } 205 1.4 haad 206 1.15 christos fdata[0] = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, 1, nargs); 207 1.1 darran fdata[1] = idp->ii_dtype->t_id; 208 1.7 christos 209 1.7 christos if (target_requires_swap) { 210 1.15 christos SWAP_32(fdata[0]); 211 1.15 christos SWAP_32(fdata[1]); 212 1.7 christos } 213 1.7 christos 214 1.1 darran ctf_buf_write(b, fdata, sizeof (fdata)); 215 1.1 darran 216 1.1 darran for (i = 0; i < idp->ii_nargs; i++) { 217 1.1 darran id = idp->ii_args[i]->t_id; 218 1.7 christos 219 1.7 christos if (target_requires_swap) { 220 1.15 christos SWAP_32(id); 221 1.7 christos } 222 1.7 christos 223 1.1 darran ctf_buf_write(b, &id, sizeof (id)); 224 1.1 darran } 225 1.1 darran 226 1.1 darran if (idp->ii_vargs) { 227 1.1 darran id = 0; 228 1.1 darran ctf_buf_write(b, &id, sizeof (id)); 229 1.1 darran } 230 1.1 darran 231 1.1 darran debug(3, "Wrote function %s (%d args)\n", idp->ii_name, nargs); 232 1.1 darran } 233 1.1 darran 234 1.1 darran /* 235 1.1 darran * Depending on the size of the type being described, either a ctf_stype_t (for 236 1.1 darran * types with size < CTF_LSTRUCT_THRESH) or a ctf_type_t (all others) will be 237 1.1 darran * written. We isolate the determination here so the rest of the writer code 238 1.1 darran * doesn't need to care. 239 1.1 darran */ 240 1.1 darran static void 241 1.15 christos write_sized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt, size_t size) 242 1.1 darran { 243 1.15 christos if (size > CTF_V3_MAX_SIZE) { 244 1.15 christos ctt->ctt_size = CTF_V3_LSIZE_SENT; 245 1.1 darran ctt->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size); 246 1.1 darran ctt->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size); 247 1.7 christos if (target_requires_swap) { 248 1.7 christos SWAP_32(ctt->ctt_name); 249 1.15 christos SWAP_32(ctt->ctt_info); 250 1.15 christos SWAP_32(ctt->ctt_size); 251 1.7 christos SWAP_32(ctt->ctt_lsizehi); 252 1.7 christos SWAP_32(ctt->ctt_lsizelo); 253 1.7 christos } 254 1.1 darran ctf_buf_write(b, ctt, sizeof (*ctt)); 255 1.1 darran } else { 256 1.15 christos struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt; 257 1.1 darran 258 1.15 christos cts->ctt_size = size; 259 1.7 christos 260 1.7 christos if (target_requires_swap) { 261 1.7 christos SWAP_32(cts->ctt_name); 262 1.15 christos SWAP_32(cts->ctt_info); 263 1.15 christos SWAP_32(cts->ctt_size); 264 1.7 christos } 265 1.7 christos 266 1.1 darran ctf_buf_write(b, cts, sizeof (*cts)); 267 1.1 darran } 268 1.1 darran } 269 1.1 darran 270 1.1 darran static void 271 1.15 christos write_unsized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt) 272 1.1 darran { 273 1.15 christos struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt; 274 1.1 darran 275 1.7 christos if (target_requires_swap) { 276 1.7 christos SWAP_32(cts->ctt_name); 277 1.15 christos SWAP_32(cts->ctt_info); 278 1.15 christos SWAP_32(cts->ctt_size); 279 1.7 christos } 280 1.7 christos 281 1.1 darran ctf_buf_write(b, cts, sizeof (*cts)); 282 1.1 darran } 283 1.1 darran 284 1.1 darran static int 285 1.2 darran write_type(void *arg1, void *arg2) 286 1.1 darran { 287 1.2 darran tdesc_t *tp = arg1; 288 1.2 darran ctf_buf_t *b = arg2; 289 1.1 darran elist_t *ep; 290 1.1 darran mlist_t *mp; 291 1.1 darran intr_t *ip; 292 1.1 darran 293 1.1 darran size_t offset; 294 1.1 darran uint_t encoding; 295 1.1 darran uint_t data; 296 1.1 darran int isroot = tp->t_flags & TDESC_F_ISROOT; 297 1.1 darran int i; 298 1.1 darran 299 1.15 christos struct ctf_type_v3 ctt; 300 1.15 christos struct ctf_array_v3 cta; 301 1.15 christos struct ctf_member_v3 ctm; 302 1.15 christos struct ctf_lmember_v3 ctlm; 303 1.15 christos struct ctf_enum cte; 304 1.15 christos uint_t id; 305 1.1 darran 306 1.1 darran /* 307 1.1 darran * There shouldn't be any holes in the type list (where a hole is 308 1.1 darran * defined as two consecutive tdescs without consecutive ids), but 309 1.1 darran * check for them just in case. If we do find holes, we need to make 310 1.1 darran * fake entries to fill the holes, or we won't be able to reconstruct 311 1.1 darran * the tree from the written data. 312 1.1 darran */ 313 1.15 christos if (++b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) { 314 1.15 christos debug(2, "genctf: type hole from %zu < x < %d\n", 315 1.15 christos b->nptent - 1, CTF_V3_TYPE_TO_INDEX(tp->t_id)); 316 1.1 darran 317 1.1 darran ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, 0); 318 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(0, 0, 0); 319 1.15 christos while (b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) { 320 1.1 darran write_sized_type_rec(b, &ctt, 0); 321 1.1 darran b->nptent++; 322 1.1 darran } 323 1.1 darran } 324 1.1 darran 325 1.1 darran offset = strtab_insert(&b->ctb_strtab, tp->t_name); 326 1.1 darran ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); 327 1.1 darran 328 1.1 darran switch (tp->t_type) { 329 1.1 darran case INTRINSIC: 330 1.1 darran ip = tp->t_intr; 331 1.1 darran if (ip->intr_type == INTR_INT) 332 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_INTEGER, 333 1.1 darran isroot, 1); 334 1.1 darran else 335 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FLOAT, isroot, 1); 336 1.1 darran write_sized_type_rec(b, &ctt, tp->t_size); 337 1.1 darran 338 1.1 darran encoding = 0; 339 1.1 darran 340 1.1 darran if (ip->intr_type == INTR_INT) { 341 1.1 darran if (ip->intr_signed) 342 1.1 darran encoding |= CTF_INT_SIGNED; 343 1.1 darran if (ip->intr_iformat == 'c') 344 1.1 darran encoding |= CTF_INT_CHAR; 345 1.1 darran else if (ip->intr_iformat == 'b') 346 1.1 darran encoding |= CTF_INT_BOOL; 347 1.1 darran else if (ip->intr_iformat == 'v') 348 1.1 darran encoding |= CTF_INT_VARARGS; 349 1.1 darran } else 350 1.1 darran encoding = ip->intr_fformat; 351 1.1 darran 352 1.1 darran data = CTF_INT_DATA(encoding, ip->intr_offset, ip->intr_nbits); 353 1.7 christos if (target_requires_swap) { 354 1.7 christos SWAP_32(data); 355 1.7 christos } 356 1.1 darran ctf_buf_write(b, &data, sizeof (data)); 357 1.1 darran break; 358 1.1 darran 359 1.1 darran case POINTER: 360 1.13 christos case REFERENCE: /* XXX: */ 361 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_POINTER, isroot, 0); 362 1.1 darran ctt.ctt_type = tp->t_tdesc->t_id; 363 1.1 darran write_unsized_type_rec(b, &ctt); 364 1.1 darran break; 365 1.1 darran 366 1.1 darran case ARRAY: 367 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ARRAY, isroot, 1); 368 1.1 darran write_sized_type_rec(b, &ctt, tp->t_size); 369 1.1 darran 370 1.1 darran cta.cta_contents = tp->t_ardef->ad_contents->t_id; 371 1.1 darran cta.cta_index = tp->t_ardef->ad_idxtype->t_id; 372 1.1 darran cta.cta_nelems = tp->t_ardef->ad_nelems; 373 1.7 christos if (target_requires_swap) { 374 1.15 christos SWAP_32(cta.cta_contents); 375 1.15 christos SWAP_32(cta.cta_index); 376 1.7 christos SWAP_32(cta.cta_nelems); 377 1.7 christos } 378 1.1 darran ctf_buf_write(b, &cta, sizeof (cta)); 379 1.1 darran break; 380 1.1 darran 381 1.1 darran case STRUCT: 382 1.1 darran case UNION: 383 1.12 christos case CLASS: 384 1.1 darran for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next) 385 1.1 darran i++; /* count up struct or union members */ 386 1.1 darran 387 1.15 christos if (i > CTF_V3_MAX_VLEN) { 388 1.15 christos terminate("sou %s has too many members: %d > %d\n", 389 1.15 christos tdesc_name(tp), i, CTF_V3_MAX_VLEN); 390 1.4 haad } 391 1.4 haad 392 1.1 darran if (tp->t_type == STRUCT) 393 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_STRUCT, isroot, i); 394 1.1 darran else 395 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_UNION, isroot, i); 396 1.1 darran 397 1.1 darran write_sized_type_rec(b, &ctt, tp->t_size); 398 1.1 darran 399 1.15 christos if (tp->t_size < CTF_V3_LSTRUCT_THRESH) { 400 1.15 christos for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { 401 1.1 darran offset = strtab_insert(&b->ctb_strtab, 402 1.1 darran mp->ml_name); 403 1.1 darran 404 1.1 darran ctm.ctm_name = CTF_TYPE_NAME(CTF_STRTAB_0, 405 1.1 darran offset); 406 1.1 darran ctm.ctm_type = mp->ml_type->t_id; 407 1.1 darran ctm.ctm_offset = mp->ml_offset; 408 1.7 christos if (target_requires_swap) { 409 1.7 christos SWAP_32(ctm.ctm_name); 410 1.15 christos SWAP_32(ctm.ctm_type); 411 1.15 christos SWAP_32(ctm.ctm_offset); 412 1.7 christos } 413 1.1 darran ctf_buf_write(b, &ctm, sizeof (ctm)); 414 1.1 darran } 415 1.1 darran } else { 416 1.15 christos for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { 417 1.1 darran offset = strtab_insert(&b->ctb_strtab, 418 1.1 darran mp->ml_name); 419 1.1 darran 420 1.1 darran ctlm.ctlm_name = CTF_TYPE_NAME(CTF_STRTAB_0, 421 1.1 darran offset); 422 1.1 darran ctlm.ctlm_type = mp->ml_type->t_id; 423 1.1 darran ctlm.ctlm_offsethi = 424 1.1 darran CTF_OFFSET_TO_LMEMHI(mp->ml_offset); 425 1.1 darran ctlm.ctlm_offsetlo = 426 1.1 darran CTF_OFFSET_TO_LMEMLO(mp->ml_offset); 427 1.7 christos 428 1.7 christos if (target_requires_swap) { 429 1.7 christos SWAP_32(ctlm.ctlm_name); 430 1.15 christos SWAP_32(ctlm.ctlm_type); 431 1.7 christos SWAP_32(ctlm.ctlm_offsethi); 432 1.7 christos SWAP_32(ctlm.ctlm_offsetlo); 433 1.7 christos } 434 1.7 christos 435 1.1 darran ctf_buf_write(b, &ctlm, sizeof (ctlm)); 436 1.1 darran } 437 1.1 darran } 438 1.1 darran break; 439 1.1 darran 440 1.1 darran case ENUM: 441 1.1 darran for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next) 442 1.1 darran i++; /* count up enum members */ 443 1.1 darran 444 1.15 christos if (i > CTF_V3_MAX_VLEN) { 445 1.7 christos warning("enum %s has too many values: %d > %d\n", 446 1.15 christos tdesc_name(tp), i, CTF_V3_MAX_VLEN); 447 1.15 christos i = CTF_V3_MAX_VLEN; 448 1.4 haad } 449 1.4 haad 450 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ENUM, isroot, i); 451 1.1 darran write_sized_type_rec(b, &ctt, tp->t_size); 452 1.1 darran 453 1.7 christos for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) { 454 1.1 darran offset = strtab_insert(&b->ctb_strtab, ep->el_name); 455 1.1 darran cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); 456 1.1 darran cte.cte_value = ep->el_number; 457 1.7 christos 458 1.7 christos if (target_requires_swap) { 459 1.7 christos SWAP_32(cte.cte_name); 460 1.7 christos SWAP_32(cte.cte_value); 461 1.7 christos } 462 1.7 christos 463 1.1 darran ctf_buf_write(b, &cte, sizeof (cte)); 464 1.7 christos i--; 465 1.1 darran } 466 1.1 darran break; 467 1.1 darran 468 1.1 darran case FORWARD: 469 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FORWARD, isroot, 0); 470 1.1 darran ctt.ctt_type = 0; 471 1.1 darran write_unsized_type_rec(b, &ctt); 472 1.1 darran break; 473 1.1 darran 474 1.1 darran case TYPEDEF: 475 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0); 476 1.1 darran ctt.ctt_type = tp->t_tdesc->t_id; 477 1.1 darran write_unsized_type_rec(b, &ctt); 478 1.1 darran break; 479 1.1 darran 480 1.1 darran case VOLATILE: 481 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_VOLATILE, isroot, 0); 482 1.1 darran ctt.ctt_type = tp->t_tdesc->t_id; 483 1.1 darran write_unsized_type_rec(b, &ctt); 484 1.1 darran break; 485 1.1 darran 486 1.1 darran case CONST: 487 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_CONST, isroot, 0); 488 1.1 darran ctt.ctt_type = tp->t_tdesc->t_id; 489 1.1 darran write_unsized_type_rec(b, &ctt); 490 1.1 darran break; 491 1.1 darran 492 1.1 darran case FUNCTION: 493 1.4 haad i = tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs; 494 1.4 haad 495 1.15 christos if (i > CTF_V3_MAX_VLEN) { 496 1.4 haad terminate("function %s has too many args: %d > %d\n", 497 1.15 christos tdesc_name(tp), i, CTF_V3_MAX_VLEN); 498 1.4 haad } 499 1.4 haad 500 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, isroot, i); 501 1.1 darran ctt.ctt_type = tp->t_fndef->fn_ret->t_id; 502 1.1 darran write_unsized_type_rec(b, &ctt); 503 1.1 darran 504 1.2 darran for (i = 0; i < (int) tp->t_fndef->fn_nargs; i++) { 505 1.1 darran id = tp->t_fndef->fn_args[i]->t_id; 506 1.7 christos 507 1.7 christos if (target_requires_swap) { 508 1.15 christos SWAP_32(id); 509 1.7 christos } 510 1.7 christos 511 1.1 darran ctf_buf_write(b, &id, sizeof (id)); 512 1.1 darran } 513 1.1 darran 514 1.1 darran if (tp->t_fndef->fn_vargs) { 515 1.1 darran id = 0; 516 1.1 darran ctf_buf_write(b, &id, sizeof (id)); 517 1.1 darran i++; 518 1.1 darran } 519 1.1 darran break; 520 1.1 darran 521 1.1 darran case RESTRICT: 522 1.15 christos ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_RESTRICT, isroot, 0); 523 1.1 darran ctt.ctt_type = tp->t_tdesc->t_id; 524 1.1 darran write_unsized_type_rec(b, &ctt); 525 1.1 darran break; 526 1.1 darran 527 1.1 darran default: 528 1.1 darran warning("Can't write unknown type %d\n", tp->t_type); 529 1.1 darran } 530 1.1 darran 531 1.1 darran debug(3, "Wrote type %d %s\n", tp->t_id, tdesc_name(tp)); 532 1.1 darran 533 1.1 darran return (1); 534 1.1 darran } 535 1.1 darran 536 1.1 darran typedef struct resbuf { 537 1.1 darran caddr_t rb_base; 538 1.1 darran caddr_t rb_ptr; 539 1.1 darran size_t rb_size; 540 1.1 darran z_stream rb_zstr; 541 1.1 darran } resbuf_t; 542 1.1 darran 543 1.1 darran static void 544 1.1 darran rbzs_grow(resbuf_t *rb) 545 1.1 darran { 546 1.1 darran off_t ptroff = (caddr_t)rb->rb_zstr.next_out - rb->rb_base; 547 1.1 darran 548 1.1 darran rb->rb_size += RES_BUF_CHUNK_SIZE; 549 1.1 darran rb->rb_base = xrealloc(rb->rb_base, rb->rb_size); 550 1.1 darran rb->rb_ptr = rb->rb_base + ptroff; 551 1.1 darran rb->rb_zstr.next_out = (Bytef *)(rb->rb_ptr); 552 1.1 darran rb->rb_zstr.avail_out += RES_BUF_CHUNK_SIZE; 553 1.1 darran } 554 1.1 darran 555 1.1 darran static void 556 1.1 darran compress_start(resbuf_t *rb) 557 1.1 darran { 558 1.1 darran int rc; 559 1.1 darran 560 1.1 darran rb->rb_zstr.zalloc = (alloc_func)0; 561 1.1 darran rb->rb_zstr.zfree = (free_func)0; 562 1.1 darran rb->rb_zstr.opaque = (voidpf)0; 563 1.1 darran 564 1.1 darran if ((rc = deflateInit(&rb->rb_zstr, Z_BEST_COMPRESSION)) != Z_OK) 565 1.1 darran parseterminate("zlib start failed: %s", zError(rc)); 566 1.1 darran } 567 1.1 darran 568 1.1 darran static ssize_t 569 1.2 darran compress_buffer(void *buf, size_t n, void *data) 570 1.1 darran { 571 1.1 darran resbuf_t *rb = (resbuf_t *)data; 572 1.1 darran int rc; 573 1.1 darran 574 1.1 darran rb->rb_zstr.next_out = (Bytef *)rb->rb_ptr; 575 1.1 darran rb->rb_zstr.avail_out = rb->rb_size - (rb->rb_ptr - rb->rb_base); 576 1.2 darran rb->rb_zstr.next_in = buf; 577 1.1 darran rb->rb_zstr.avail_in = n; 578 1.1 darran 579 1.1 darran while (rb->rb_zstr.avail_in) { 580 1.1 darran if (rb->rb_zstr.avail_out == 0) 581 1.1 darran rbzs_grow(rb); 582 1.1 darran 583 1.1 darran if ((rc = deflate(&rb->rb_zstr, Z_NO_FLUSH)) != Z_OK) 584 1.1 darran parseterminate("zlib deflate failed: %s", zError(rc)); 585 1.1 darran } 586 1.1 darran rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out; 587 1.1 darran 588 1.1 darran return (n); 589 1.1 darran } 590 1.1 darran 591 1.1 darran static void 592 1.1 darran compress_flush(resbuf_t *rb, int type) 593 1.1 darran { 594 1.1 darran int rc; 595 1.1 darran 596 1.1 darran for (;;) { 597 1.1 darran if (rb->rb_zstr.avail_out == 0) 598 1.1 darran rbzs_grow(rb); 599 1.1 darran 600 1.1 darran rc = deflate(&rb->rb_zstr, type); 601 1.1 darran if ((type == Z_FULL_FLUSH && rc == Z_BUF_ERROR) || 602 1.1 darran (type == Z_FINISH && rc == Z_STREAM_END)) 603 1.1 darran break; 604 1.1 darran else if (rc != Z_OK) 605 1.1 darran parseterminate("zlib finish failed: %s", zError(rc)); 606 1.1 darran } 607 1.1 darran rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out; 608 1.1 darran } 609 1.1 darran 610 1.1 darran static void 611 1.1 darran compress_end(resbuf_t *rb) 612 1.1 darran { 613 1.1 darran int rc; 614 1.1 darran 615 1.1 darran compress_flush(rb, Z_FINISH); 616 1.1 darran 617 1.1 darran if ((rc = deflateEnd(&rb->rb_zstr)) != Z_OK) 618 1.1 darran parseterminate("zlib end failed: %s", zError(rc)); 619 1.1 darran } 620 1.1 darran 621 1.1 darran /* 622 1.1 darran * Pad the buffer to a power-of-2 boundary 623 1.1 darran */ 624 1.1 darran static void 625 1.1 darran pad_buffer(ctf_buf_t *buf, int align) 626 1.1 darran { 627 1.1 darran uint_t cur = ctf_buf_cur(buf); 628 1.1 darran ssize_t topad = (align - (cur % align)) % align; 629 1.1 darran static const char pad[8] = { 0 }; 630 1.1 darran 631 1.1 darran while (topad > 0) { 632 1.1 darran ctf_buf_write(buf, pad, (topad > 8 ? 8 : topad)); 633 1.1 darran topad -= 8; 634 1.1 darran } 635 1.1 darran } 636 1.1 darran 637 1.1 darran static ssize_t 638 1.2 darran bcopy_data(void *buf, size_t n, void *data) 639 1.1 darran { 640 1.1 darran caddr_t *posp = (caddr_t *)data; 641 1.1 darran bcopy(buf, *posp, n); 642 1.1 darran *posp += n; 643 1.1 darran return (n); 644 1.1 darran } 645 1.1 darran 646 1.1 darran static caddr_t 647 1.1 darran write_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp) 648 1.1 darran { 649 1.1 darran caddr_t outbuf; 650 1.1 darran caddr_t bufpos; 651 1.1 darran 652 1.1 darran outbuf = xmalloc(sizeof (ctf_header_t) + (buf->ctb_ptr - buf->ctb_base) 653 1.1 darran + buf->ctb_strtab.str_size); 654 1.1 darran 655 1.1 darran bufpos = outbuf; 656 1.1 darran (void) bcopy_data(h, sizeof (ctf_header_t), &bufpos); 657 1.1 darran (void) bcopy_data(buf->ctb_base, buf->ctb_ptr - buf->ctb_base, 658 1.1 darran &bufpos); 659 1.1 darran (void) strtab_write(&buf->ctb_strtab, bcopy_data, &bufpos); 660 1.1 darran *resszp = bufpos - outbuf; 661 1.1 darran return (outbuf); 662 1.1 darran } 663 1.1 darran 664 1.1 darran /* 665 1.1 darran * Create the compression buffer, and fill it with the CTF and string 666 1.1 darran * table data. We flush the compression state between the two so the 667 1.1 darran * dictionary used for the string tables won't be polluted with values 668 1.1 darran * that made sense for the CTF data. 669 1.1 darran */ 670 1.1 darran static caddr_t 671 1.1 darran write_compressed_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp) 672 1.1 darran { 673 1.1 darran resbuf_t resbuf; 674 1.1 darran resbuf.rb_size = RES_BUF_CHUNK_SIZE; 675 1.1 darran resbuf.rb_base = xmalloc(resbuf.rb_size); 676 1.1 darran bcopy(h, resbuf.rb_base, sizeof (ctf_header_t)); 677 1.1 darran resbuf.rb_ptr = resbuf.rb_base + sizeof (ctf_header_t); 678 1.1 darran 679 1.1 darran compress_start(&resbuf); 680 1.1 darran (void) compress_buffer(buf->ctb_base, buf->ctb_ptr - buf->ctb_base, 681 1.1 darran &resbuf); 682 1.1 darran compress_flush(&resbuf, Z_FULL_FLUSH); 683 1.1 darran (void) strtab_write(&buf->ctb_strtab, compress_buffer, &resbuf); 684 1.1 darran compress_end(&resbuf); 685 1.1 darran 686 1.1 darran *resszp = (resbuf.rb_ptr - resbuf.rb_base); 687 1.1 darran return (resbuf.rb_base); 688 1.1 darran } 689 1.1 darran 690 1.1 darran caddr_t 691 1.1 darran ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress) 692 1.1 darran { 693 1.1 darran ctf_buf_t *buf = ctf_buf_new(); 694 1.1 darran ctf_header_t h; 695 1.1 darran caddr_t outbuf; 696 1.1 darran 697 1.1 darran int i; 698 1.1 darran 699 1.7 christos target_requires_swap = do_compress & CTF_SWAP_BYTES; 700 1.7 christos do_compress &= ~CTF_SWAP_BYTES; 701 1.7 christos 702 1.1 darran /* 703 1.1 darran * Prepare the header, and create the CTF output buffers. The data 704 1.1 darran * object section and function section are both lists of 2-byte 705 1.1 darran * integers; we pad these out to the next 4-byte boundary if needed. 706 1.1 darran */ 707 1.1 darran h.cth_magic = CTF_MAGIC; 708 1.15 christos h.cth_version = CTF_VERSION_3; 709 1.1 darran h.cth_flags = do_compress ? CTF_F_COMPRESS : 0; 710 1.1 darran h.cth_parlabel = strtab_insert(&buf->ctb_strtab, 711 1.1 darran iiburst->iib_td->td_parlabel); 712 1.1 darran h.cth_parname = strtab_insert(&buf->ctb_strtab, 713 1.1 darran iiburst->iib_td->td_parname); 714 1.1 darran 715 1.1 darran h.cth_lbloff = 0; 716 1.2 darran (void) list_iter(iiburst->iib_td->td_labels, write_label, 717 1.1 darran buf); 718 1.1 darran 719 1.1 darran pad_buffer(buf, 2); 720 1.1 darran h.cth_objtoff = ctf_buf_cur(buf); 721 1.1 darran for (i = 0; i < iiburst->iib_nobjts; i++) 722 1.1 darran write_objects(iiburst->iib_objts[i], buf); 723 1.1 darran 724 1.1 darran pad_buffer(buf, 2); 725 1.1 darran h.cth_funcoff = ctf_buf_cur(buf); 726 1.1 darran for (i = 0; i < iiburst->iib_nfuncs; i++) 727 1.1 darran write_functions(iiburst->iib_funcs[i], buf); 728 1.1 darran 729 1.1 darran pad_buffer(buf, 4); 730 1.1 darran h.cth_typeoff = ctf_buf_cur(buf); 731 1.2 darran (void) list_iter(iiburst->iib_types, write_type, buf); 732 1.1 darran 733 1.1 darran debug(2, "CTF wrote %d types\n", list_count(iiburst->iib_types)); 734 1.1 darran 735 1.1 darran h.cth_stroff = ctf_buf_cur(buf); 736 1.1 darran h.cth_strlen = strtab_size(&buf->ctb_strtab); 737 1.1 darran 738 1.7 christos if (target_requires_swap) { 739 1.7 christos SWAP_16(h.cth_preamble.ctp_magic); 740 1.7 christos SWAP_32(h.cth_parlabel); 741 1.7 christos SWAP_32(h.cth_parname); 742 1.7 christos SWAP_32(h.cth_lbloff); 743 1.7 christos SWAP_32(h.cth_objtoff); 744 1.7 christos SWAP_32(h.cth_funcoff); 745 1.7 christos SWAP_32(h.cth_typeoff); 746 1.7 christos SWAP_32(h.cth_stroff); 747 1.7 christos SWAP_32(h.cth_strlen); 748 1.7 christos } 749 1.7 christos 750 1.1 darran /* 751 1.1 darran * We only do compression for ctfmerge, as ctfconvert is only 752 1.1 darran * supposed to be used on intermediary build objects. This is 753 1.1 darran * significantly faster. 754 1.1 darran */ 755 1.1 darran if (do_compress) 756 1.1 darran outbuf = write_compressed_buffer(&h, buf, resszp); 757 1.1 darran else 758 1.1 darran outbuf = write_buffer(&h, buf, resszp); 759 1.1 darran 760 1.1 darran ctf_buf_free(buf); 761 1.1 darran return (outbuf); 762 1.1 darran } 763 1.1 darran 764 1.2 darran static void 765 1.15 christos get_ctt_info(ctf_header_t *h, void *v, uint_t *kind, uint_t *vlen, int *isroot) 766 1.1 darran { 767 1.15 christos if (h->cth_version == CTF_VERSION_2) { 768 1.15 christos struct ctf_type_v2 *ctt = v; 769 1.15 christos 770 1.15 christos *kind = CTF_V2_INFO_KIND(ctt->ctt_info); 771 1.15 christos *vlen = CTF_V2_INFO_VLEN(ctt->ctt_info); 772 1.15 christos *isroot = CTF_V2_INFO_ISROOT(ctt->ctt_info); 773 1.1 darran } else { 774 1.15 christos struct ctf_type_v3 *ctt = v; 775 1.15 christos 776 1.15 christos *kind = CTF_V3_INFO_KIND(ctt->ctt_info); 777 1.15 christos *vlen = CTF_V3_INFO_VLEN(ctt->ctt_info); 778 1.15 christos *isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info); 779 1.15 christos } 780 1.15 christos } 781 1.15 christos 782 1.15 christos static void 783 1.15 christos get_ctt_size(ctf_header_t *h, void *v, size_t *sizep, size_t *incrementp) 784 1.15 christos { 785 1.15 christos if (h->cth_version == CTF_VERSION_2) { 786 1.15 christos struct ctf_type_v2 *ctt = v; 787 1.15 christos 788 1.15 christos if (ctt->ctt_size == CTF_V2_LSIZE_SENT) { 789 1.15 christos *sizep = (size_t)CTF_TYPE_LSIZE(ctt); 790 1.15 christos *incrementp = sizeof (struct ctf_type_v2); 791 1.15 christos } else { 792 1.15 christos *sizep = ctt->ctt_size; 793 1.15 christos *incrementp = sizeof (struct ctf_stype_v2); 794 1.15 christos } 795 1.15 christos } else { 796 1.15 christos struct ctf_type_v3 *ctt = v; 797 1.15 christos 798 1.15 christos if (ctt->ctt_size == CTF_V3_LSIZE_SENT) { 799 1.15 christos *sizep = (size_t)CTF_TYPE_LSIZE(ctt); 800 1.15 christos *incrementp = sizeof (struct ctf_type_v3); 801 1.15 christos } else { 802 1.15 christos *sizep = ctt->ctt_size; 803 1.15 christos *incrementp = sizeof (struct ctf_stype_v3); 804 1.15 christos } 805 1.1 darran } 806 1.1 darran } 807 1.1 darran 808 1.1 darran static int 809 1.1 darran count_types(ctf_header_t *h, caddr_t data) 810 1.1 darran { 811 1.1 darran caddr_t dptr = data + h->cth_typeoff; 812 1.15 christos uint_t version = h->cth_version; 813 1.15 christos size_t idwidth; 814 1.1 darran int count = 0; 815 1.1 darran 816 1.15 christos idwidth = version == CTF_VERSION_2 ? 2 : 4; 817 1.1 darran dptr = data + h->cth_typeoff; 818 1.1 darran while (dptr < data + h->cth_stroff) { 819 1.2 darran void *v = (void *) dptr; 820 1.1 darran size_t size, increment; 821 1.15 christos uint_t vlen, kind; 822 1.15 christos int isroot; 823 1.1 darran 824 1.15 christos get_ctt_info(h, v, &kind, &vlen, &isroot); 825 1.15 christos get_ctt_size(h, v, &size, &increment); 826 1.1 darran 827 1.15 christos switch (kind) { 828 1.1 darran case CTF_K_INTEGER: 829 1.1 darran case CTF_K_FLOAT: 830 1.1 darran dptr += 4; 831 1.1 darran break; 832 1.1 darran case CTF_K_POINTER: 833 1.1 darran case CTF_K_FORWARD: 834 1.1 darran case CTF_K_TYPEDEF: 835 1.1 darran case CTF_K_VOLATILE: 836 1.1 darran case CTF_K_CONST: 837 1.1 darran case CTF_K_RESTRICT: 838 1.1 darran case CTF_K_FUNCTION: 839 1.15 christos dptr += idwidth * vlen; 840 1.16 christos if (kind == CTF_K_FUNCTION) 841 1.16 christos dptr = (caddr_t) roundup2((uintptr_t) dptr, 4); 842 1.1 darran break; 843 1.1 darran case CTF_K_ARRAY: 844 1.15 christos if (version == CTF_VERSION_2) 845 1.15 christos dptr += sizeof (struct ctf_array_v2); 846 1.15 christos else 847 1.15 christos dptr += sizeof (struct ctf_array_v3); 848 1.1 darran break; 849 1.1 darran case CTF_K_STRUCT: 850 1.1 darran case CTF_K_UNION: 851 1.15 christos if (version == CTF_VERSION_2) { 852 1.15 christos if (size < CTF_V2_LSTRUCT_THRESH) 853 1.15 christos dptr += sizeof (struct ctf_member_v2) * 854 1.15 christos vlen; 855 1.15 christos else 856 1.15 christos dptr += sizeof (struct ctf_lmember_v2) * 857 1.15 christos vlen; 858 1.15 christos } else { 859 1.15 christos if (size < CTF_V3_LSTRUCT_THRESH) 860 1.15 christos dptr += sizeof (struct ctf_member_v3) * 861 1.15 christos vlen; 862 1.15 christos else 863 1.15 christos dptr += sizeof (struct ctf_lmember_v3) * 864 1.15 christos vlen; 865 1.15 christos } 866 1.1 darran break; 867 1.1 darran case CTF_K_ENUM: 868 1.1 darran dptr += sizeof (ctf_enum_t) * vlen; 869 1.1 darran break; 870 1.1 darran case CTF_K_UNKNOWN: 871 1.1 darran break; 872 1.1 darran default: 873 1.15 christos parseterminate("Unknown CTF type %d (#%d) at %#tx", 874 1.15 christos kind, count, dptr - data); 875 1.1 darran } 876 1.1 darran 877 1.1 darran dptr += increment; 878 1.1 darran count++; 879 1.1 darran } 880 1.1 darran 881 1.1 darran debug(3, "CTF read %d types\n", count); 882 1.1 darran 883 1.1 darran return (count); 884 1.1 darran } 885 1.1 darran 886 1.1 darran /* 887 1.1 darran * Resurrect the labels stored in the CTF data, returning the index associated 888 1.1 darran * with a label provided by the caller. There are several cases, outlined 889 1.1 darran * below. Note that, given two labels, the one associated with the lesser type 890 1.1 darran * index is considered to be older than the other. 891 1.1 darran * 892 1.1 darran * 1. matchlbl == NULL - return the index of the most recent label. 893 1.1 darran * 2. matchlbl == "BASE" - return the index of the oldest label. 894 1.1 darran * 3. matchlbl != NULL, but doesn't match any labels in the section - warn 895 1.1 darran * the user, and proceed as if matchlbl == "BASE" (for safety). 896 1.1 darran * 4. matchlbl != NULL, and matches one of the labels in the section - return 897 1.1 darran * the type index associated with the label. 898 1.1 darran */ 899 1.1 darran static int 900 1.1 darran resurrect_labels(ctf_header_t *h, tdata_t *td, caddr_t ctfdata, char *matchlbl) 901 1.1 darran { 902 1.1 darran caddr_t buf = ctfdata + h->cth_lbloff; 903 1.1 darran caddr_t sbuf = ctfdata + h->cth_stroff; 904 1.1 darran size_t bufsz = h->cth_objtoff - h->cth_lbloff; 905 1.1 darran int lastidx = 0, baseidx = -1; 906 1.2 darran char *baselabel = NULL; 907 1.1 darran ctf_lblent_t *ctl; 908 1.2 darran void *v = (void *) buf; 909 1.1 darran 910 1.2 darran for (ctl = v; (caddr_t)ctl < buf + bufsz; ctl++) { 911 1.1 darran char *label = sbuf + ctl->ctl_label; 912 1.1 darran 913 1.1 darran lastidx = ctl->ctl_typeidx; 914 1.1 darran 915 1.1 darran debug(3, "Resurrected label %s type idx %d\n", label, lastidx); 916 1.1 darran 917 1.1 darran tdata_label_add(td, label, lastidx); 918 1.1 darran 919 1.1 darran if (baseidx == -1) { 920 1.1 darran baseidx = lastidx; 921 1.1 darran baselabel = label; 922 1.1 darran if (matchlbl != NULL && streq(matchlbl, "BASE")) 923 1.1 darran return (lastidx); 924 1.1 darran } 925 1.1 darran 926 1.1 darran if (matchlbl != NULL && streq(label, matchlbl)) 927 1.1 darran return (lastidx); 928 1.1 darran } 929 1.1 darran 930 1.1 darran if (matchlbl != NULL) { 931 1.1 darran /* User provided a label that didn't match */ 932 1.1 darran warning("%s: Cannot find label `%s' - using base (%s)\n", 933 1.1 darran curfile, matchlbl, (baselabel ? baselabel : "NONE")); 934 1.1 darran 935 1.1 darran tdata_label_free(td); 936 1.1 darran tdata_label_add(td, baselabel, baseidx); 937 1.1 darran 938 1.1 darran return (baseidx); 939 1.1 darran } 940 1.1 darran 941 1.1 darran return (lastidx); 942 1.1 darran } 943 1.1 darran 944 1.1 darran static void 945 1.1 darran resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 946 1.1 darran caddr_t ctfdata, symit_data_t *si) 947 1.1 darran { 948 1.1 darran caddr_t buf = ctfdata + h->cth_objtoff; 949 1.1 darran size_t bufsz = h->cth_funcoff - h->cth_objtoff; 950 1.1 darran caddr_t dptr; 951 1.15 christos size_t idwidth; 952 1.15 christos 953 1.15 christos idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4; 954 1.1 darran 955 1.1 darran symit_reset(si); 956 1.15 christos for (dptr = buf; dptr < buf + bufsz; dptr += idwidth) { 957 1.15 christos uint32_t id = 0; 958 1.15 christos 959 1.15 christos memcpy(&id, (void *) dptr, idwidth); 960 1.1 darran iidesc_t *ii; 961 1.1 darran GElf_Sym *sym; 962 1.1 darran 963 1.1 darran if (!(sym = symit_next(si, STT_OBJECT)) && id != 0) { 964 1.1 darran parseterminate( 965 1.8 christos "Unexpected end of object symbols at %ju of %zu", 966 1.8 christos (intmax_t)(dptr - buf), bufsz); 967 1.1 darran } 968 1.1 darran 969 1.1 darran if (id == 0) { 970 1.1 darran debug(3, "Skipping null object\n"); 971 1.1 darran continue; 972 1.1 darran } else if (id >= tdsize) { 973 1.7 christos parseterminate("Reference to invalid type %d", id); 974 1.1 darran } 975 1.1 darran 976 1.1 darran ii = iidesc_new(symit_name(si)); 977 1.1 darran ii->ii_dtype = tdarr[id]; 978 1.1 darran if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 979 1.1 darran ii->ii_type = II_SVAR; 980 1.1 darran ii->ii_owner = xstrdup(symit_curfile(si)); 981 1.1 darran } else 982 1.1 darran ii->ii_type = II_GVAR; 983 1.1 darran hash_add(td->td_iihash, ii); 984 1.1 darran 985 1.1 darran debug(3, "Resurrected %s object %s (%d) from %s\n", 986 1.1 darran (ii->ii_type == II_GVAR ? "global" : "static"), 987 1.1 darran ii->ii_name, id, (ii->ii_owner ? ii->ii_owner : "(none)")); 988 1.1 darran } 989 1.1 darran } 990 1.1 darran 991 1.1 darran static void 992 1.1 darran resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 993 1.1 darran caddr_t ctfdata, symit_data_t *si) 994 1.1 darran { 995 1.1 darran caddr_t buf = ctfdata + h->cth_funcoff; 996 1.1 darran size_t bufsz = h->cth_typeoff - h->cth_funcoff; 997 1.15 christos size_t idwidth; 998 1.1 darran caddr_t dptr = buf; 999 1.1 darran iidesc_t *ii; 1000 1.1 darran GElf_Sym *sym; 1001 1.1 darran int i; 1002 1.1 darran 1003 1.15 christos idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4; 1004 1.15 christos 1005 1.1 darran symit_reset(si); 1006 1.1 darran while (dptr < buf + bufsz) { 1007 1.15 christos uint32_t id, info, retid; 1008 1.15 christos 1009 1.15 christos info = 0; 1010 1.15 christos memcpy(&info, (void *) dptr, idwidth); 1011 1.15 christos dptr += idwidth; 1012 1.1 darran 1013 1.1 darran if (!(sym = symit_next(si, STT_FUNC)) && info != 0) 1014 1.1 darran parseterminate("Unexpected end of function symbols"); 1015 1.1 darran 1016 1.1 darran if (info == 0) { 1017 1.1 darran debug(3, "Skipping null function (%s)\n", 1018 1.1 darran symit_name(si)); 1019 1.1 darran continue; 1020 1.1 darran } 1021 1.1 darran 1022 1.15 christos retid = 0; 1023 1.15 christos memcpy(&retid, (void *) dptr, idwidth); 1024 1.15 christos dptr += idwidth; 1025 1.1 darran 1026 1.1 darran if (retid >= tdsize) 1027 1.7 christos parseterminate("Reference to invalid type %d", retid); 1028 1.1 darran 1029 1.1 darran ii = iidesc_new(symit_name(si)); 1030 1.1 darran ii->ii_dtype = tdarr[retid]; 1031 1.1 darran if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1032 1.1 darran ii->ii_type = II_SFUN; 1033 1.1 darran ii->ii_owner = xstrdup(symit_curfile(si)); 1034 1.1 darran } else 1035 1.1 darran ii->ii_type = II_GFUN; 1036 1.15 christos if (h->cth_version == CTF_VERSION_2) 1037 1.15 christos ii->ii_nargs = CTF_V2_INFO_VLEN(info); 1038 1.15 christos else 1039 1.15 christos ii->ii_nargs = CTF_V3_INFO_VLEN(info); 1040 1.1 darran if (ii->ii_nargs) 1041 1.1 darran ii->ii_args = 1042 1.1 darran xmalloc(sizeof (tdesc_t *) * ii->ii_nargs); 1043 1.1 darran 1044 1.15 christos for (i = 0; i < ii->ii_nargs; i++, dptr += idwidth) { 1045 1.15 christos id = 0; 1046 1.15 christos memcpy(&id, (void *) dptr, idwidth); 1047 1.1 darran if (id >= tdsize) 1048 1.7 christos parseterminate("Reference to invalid type %d", 1049 1.7 christos id); 1050 1.1 darran ii->ii_args[i] = tdarr[id]; 1051 1.1 darran } 1052 1.1 darran 1053 1.1 darran if (ii->ii_nargs && ii->ii_args[ii->ii_nargs - 1] == NULL) { 1054 1.1 darran ii->ii_nargs--; 1055 1.1 darran ii->ii_vargs = 1; 1056 1.1 darran } 1057 1.1 darran 1058 1.1 darran hash_add(td->td_iihash, ii); 1059 1.1 darran 1060 1.1 darran debug(3, "Resurrected %s function %s (%d, %d args)\n", 1061 1.1 darran (ii->ii_type == II_GFUN ? "global" : "static"), 1062 1.1 darran ii->ii_name, retid, ii->ii_nargs); 1063 1.1 darran } 1064 1.1 darran } 1065 1.1 darran 1066 1.1 darran static void 1067 1.1 darran resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 1068 1.1 darran caddr_t ctfdata, int maxid) 1069 1.1 darran { 1070 1.1 darran caddr_t buf = ctfdata + h->cth_typeoff; 1071 1.1 darran size_t bufsz = h->cth_stroff - h->cth_typeoff; 1072 1.1 darran caddr_t sbuf = ctfdata + h->cth_stroff; 1073 1.1 darran caddr_t dptr = buf; 1074 1.1 darran tdesc_t *tdp; 1075 1.1 darran uint_t data; 1076 1.1 darran uint_t encoding; 1077 1.15 christos size_t idwidth, size, increment; 1078 1.1 darran int tcnt; 1079 1.1 darran int iicnt = 0; 1080 1.1 darran tid_t tid, argid; 1081 1.15 christos int isroot; 1082 1.15 christos u_int kind, vlen; 1083 1.15 christos int i, version; 1084 1.1 darran 1085 1.1 darran elist_t **epp; 1086 1.1 darran mlist_t **mpp; 1087 1.1 darran intr_t *ip; 1088 1.1 darran 1089 1.15 christos version = h->cth_version; 1090 1.15 christos idwidth = version == CTF_VERSION_2 ? 2 : 4; 1091 1.1 darran 1092 1.1 darran /* 1093 1.1 darran * A maxid of zero indicates a request to resurrect all types, so reset 1094 1.1 darran * maxid to the maximum type id. 1095 1.1 darran */ 1096 1.15 christos if (maxid == 0) { 1097 1.15 christos maxid = version == CTF_VERSION_2 ? 1098 1.15 christos CTF_V2_MAX_TYPE : CTF_V3_MAX_TYPE; 1099 1.15 christos } 1100 1.1 darran 1101 1.1 darran for (dptr = buf, tcnt = 0, tid = 1; dptr < buf + bufsz; tcnt++, tid++) { 1102 1.15 christos ctf_enum_t *cte; 1103 1.15 christos uint_t name, type; 1104 1.15 christos void *v; 1105 1.15 christos 1106 1.1 darran if (tid > maxid) 1107 1.1 darran break; 1108 1.1 darran 1109 1.1 darran if (tid >= tdsize) 1110 1.7 christos parseterminate("Reference to invalid type %d", tid); 1111 1.1 darran 1112 1.15 christos get_ctt_info(h, dptr, &kind, &vlen, &isroot); 1113 1.15 christos get_ctt_size(h, dptr, &size, &increment); 1114 1.15 christos if (version == CTF_VERSION_2) { 1115 1.15 christos struct ctf_type_v2 *ctt = (void *) dptr; 1116 1.15 christos 1117 1.15 christos name = ctt->ctt_name; 1118 1.15 christos type = ctt->ctt_type; 1119 1.15 christos } else { 1120 1.15 christos struct ctf_type_v3 *ctt = (void *) dptr; 1121 1.1 darran 1122 1.15 christos name = ctt->ctt_name; 1123 1.15 christos type = ctt->ctt_type; 1124 1.15 christos } 1125 1.1 darran dptr += increment; 1126 1.1 darran 1127 1.1 darran tdp = tdarr[tid]; 1128 1.1 darran 1129 1.15 christos if (CTF_NAME_STID(name) != CTF_STRTAB_0) 1130 1.1 darran parseterminate( 1131 1.4 haad "Unable to cope with non-zero strtab id"); 1132 1.15 christos if (CTF_NAME_OFFSET(name) != 0) { 1133 1.15 christos tdp->t_name = xstrdup(sbuf + CTF_NAME_OFFSET(name)); 1134 1.1 darran } else 1135 1.1 darran tdp->t_name = NULL; 1136 1.1 darran 1137 1.1 darran switch (kind) { 1138 1.1 darran case CTF_K_INTEGER: 1139 1.1 darran tdp->t_type = INTRINSIC; 1140 1.1 darran tdp->t_size = size; 1141 1.1 darran 1142 1.2 darran v = (void *) dptr; 1143 1.2 darran data = *((uint_t *)v); 1144 1.1 darran dptr += sizeof (uint_t); 1145 1.1 darran encoding = CTF_INT_ENCODING(data); 1146 1.1 darran 1147 1.1 darran ip = xmalloc(sizeof (intr_t)); 1148 1.1 darran ip->intr_type = INTR_INT; 1149 1.1 darran ip->intr_signed = (encoding & CTF_INT_SIGNED) ? 1 : 0; 1150 1.1 darran 1151 1.1 darran if (encoding & CTF_INT_CHAR) 1152 1.1 darran ip->intr_iformat = 'c'; 1153 1.1 darran else if (encoding & CTF_INT_BOOL) 1154 1.1 darran ip->intr_iformat = 'b'; 1155 1.1 darran else if (encoding & CTF_INT_VARARGS) 1156 1.1 darran ip->intr_iformat = 'v'; 1157 1.1 darran else 1158 1.1 darran ip->intr_iformat = '\0'; 1159 1.1 darran 1160 1.1 darran ip->intr_offset = CTF_INT_OFFSET(data); 1161 1.1 darran ip->intr_nbits = CTF_INT_BITS(data); 1162 1.1 darran tdp->t_intr = ip; 1163 1.1 darran break; 1164 1.1 darran 1165 1.1 darran case CTF_K_FLOAT: 1166 1.1 darran tdp->t_type = INTRINSIC; 1167 1.1 darran tdp->t_size = size; 1168 1.1 darran 1169 1.2 darran v = (void *) dptr; 1170 1.2 darran data = *((uint_t *)v); 1171 1.1 darran dptr += sizeof (uint_t); 1172 1.1 darran 1173 1.1 darran ip = xcalloc(sizeof (intr_t)); 1174 1.1 darran ip->intr_type = INTR_REAL; 1175 1.1 darran ip->intr_fformat = CTF_FP_ENCODING(data); 1176 1.1 darran ip->intr_offset = CTF_FP_OFFSET(data); 1177 1.1 darran ip->intr_nbits = CTF_FP_BITS(data); 1178 1.1 darran tdp->t_intr = ip; 1179 1.1 darran break; 1180 1.1 darran 1181 1.1 darran case CTF_K_POINTER: 1182 1.1 darran tdp->t_type = POINTER; 1183 1.15 christos tdp->t_tdesc = tdarr[type]; 1184 1.1 darran break; 1185 1.1 darran 1186 1.15 christos case CTF_K_ARRAY: { 1187 1.15 christos uint_t contents, index, nelems; 1188 1.15 christos 1189 1.1 darran tdp->t_type = ARRAY; 1190 1.1 darran tdp->t_size = size; 1191 1.1 darran 1192 1.15 christos if (version == CTF_VERSION_2) { 1193 1.15 christos struct ctf_array_v2 *cta = (void *) dptr; 1194 1.15 christos contents = cta->cta_contents; 1195 1.15 christos index = cta->cta_index; 1196 1.15 christos nelems = cta->cta_nelems; 1197 1.15 christos dptr += sizeof (*cta); 1198 1.15 christos } else { 1199 1.15 christos struct ctf_array_v3 *cta = (void *) dptr; 1200 1.15 christos contents = cta->cta_contents; 1201 1.15 christos index = cta->cta_index; 1202 1.15 christos nelems = cta->cta_nelems; 1203 1.15 christos dptr += sizeof (*cta); 1204 1.15 christos } 1205 1.1 darran 1206 1.1 darran tdp->t_ardef = xmalloc(sizeof (ardef_t)); 1207 1.15 christos tdp->t_ardef->ad_contents = tdarr[contents]; 1208 1.15 christos tdp->t_ardef->ad_idxtype = tdarr[index]; 1209 1.15 christos tdp->t_ardef->ad_nelems = nelems; 1210 1.1 darran break; 1211 1.15 christos } 1212 1.1 darran 1213 1.1 darran case CTF_K_STRUCT: 1214 1.15 christos case CTF_K_UNION: { 1215 1.1 darran tdp->t_type = (kind == CTF_K_STRUCT ? STRUCT : UNION); 1216 1.1 darran tdp->t_size = size; 1217 1.1 darran 1218 1.15 christos if (version == CTF_VERSION_2) { 1219 1.15 christos if (size < CTF_V2_LSTRUCT_THRESH) { 1220 1.15 christos for (i = 0, mpp = &tdp->t_members; i < vlen; 1221 1.15 christos i++, mpp = &((*mpp)->ml_next)) { 1222 1.15 christos v = (void *) dptr; 1223 1.15 christos struct ctf_member_v2 *ctm = v; 1224 1.15 christos dptr += sizeof (struct ctf_member_v2); 1225 1.15 christos 1226 1.15 christos *mpp = xmalloc(sizeof (mlist_t)); 1227 1.15 christos (*mpp)->ml_name = xstrdup(sbuf + 1228 1.15 christos ctm->ctm_name); 1229 1.15 christos (*mpp)->ml_type = tdarr[ctm->ctm_type]; 1230 1.15 christos (*mpp)->ml_offset = ctm->ctm_offset; 1231 1.15 christos (*mpp)->ml_size = 0; 1232 1.15 christos } 1233 1.15 christos } else { 1234 1.15 christos for (i = 0, mpp = &tdp->t_members; i < vlen; 1235 1.15 christos i++, mpp = &((*mpp)->ml_next)) { 1236 1.15 christos v = (void *) dptr; 1237 1.15 christos struct ctf_lmember_v2 *ctlm = v; 1238 1.15 christos dptr += sizeof (struct ctf_lmember_v2); 1239 1.15 christos 1240 1.15 christos *mpp = xmalloc(sizeof (mlist_t)); 1241 1.15 christos (*mpp)->ml_name = xstrdup(sbuf + 1242 1.15 christos ctlm->ctlm_name); 1243 1.15 christos (*mpp)->ml_type = 1244 1.15 christos tdarr[ctlm->ctlm_type]; 1245 1.15 christos (*mpp)->ml_offset = 1246 1.15 christos (int)CTF_LMEM_OFFSET(ctlm); 1247 1.15 christos (*mpp)->ml_size = 0; 1248 1.15 christos } 1249 1.1 darran } 1250 1.1 darran } else { 1251 1.15 christos if (size < CTF_V3_LSTRUCT_THRESH) { 1252 1.15 christos for (i = 0, mpp = &tdp->t_members; i < vlen; 1253 1.15 christos i++, mpp = &((*mpp)->ml_next)) { 1254 1.15 christos v = (void *) dptr; 1255 1.15 christos struct ctf_member_v3 *ctm = v; 1256 1.15 christos dptr += sizeof (struct ctf_member_v3); 1257 1.15 christos 1258 1.15 christos *mpp = xmalloc(sizeof (mlist_t)); 1259 1.15 christos (*mpp)->ml_name = xstrdup(sbuf + 1260 1.15 christos ctm->ctm_name); 1261 1.15 christos (*mpp)->ml_type = tdarr[ctm->ctm_type]; 1262 1.15 christos (*mpp)->ml_offset = ctm->ctm_offset; 1263 1.15 christos (*mpp)->ml_size = 0; 1264 1.15 christos } 1265 1.15 christos } else { 1266 1.15 christos for (i = 0, mpp = &tdp->t_members; i < vlen; 1267 1.15 christos i++, mpp = &((*mpp)->ml_next)) { 1268 1.15 christos v = (void *) dptr; 1269 1.15 christos struct ctf_lmember_v3 *ctlm = v; 1270 1.15 christos dptr += sizeof (struct ctf_lmember_v3); 1271 1.15 christos 1272 1.15 christos *mpp = xmalloc(sizeof (mlist_t)); 1273 1.15 christos (*mpp)->ml_name = xstrdup(sbuf + 1274 1.15 christos ctlm->ctlm_name); 1275 1.15 christos (*mpp)->ml_type = 1276 1.15 christos tdarr[ctlm->ctlm_type]; 1277 1.15 christos (*mpp)->ml_offset = 1278 1.15 christos (int)CTF_LMEM_OFFSET(ctlm); 1279 1.15 christos (*mpp)->ml_size = 0; 1280 1.15 christos } 1281 1.1 darran } 1282 1.1 darran } 1283 1.1 darran 1284 1.1 darran *mpp = NULL; 1285 1.1 darran break; 1286 1.15 christos } 1287 1.1 darran 1288 1.1 darran case CTF_K_ENUM: 1289 1.1 darran tdp->t_type = ENUM; 1290 1.1 darran tdp->t_size = size; 1291 1.1 darran 1292 1.1 darran for (i = 0, epp = &tdp->t_emem; i < vlen; 1293 1.1 darran i++, epp = &((*epp)->el_next)) { 1294 1.2 darran v = (void *) dptr; 1295 1.2 darran cte = v; 1296 1.1 darran dptr += sizeof (ctf_enum_t); 1297 1.1 darran 1298 1.1 darran *epp = xmalloc(sizeof (elist_t)); 1299 1.1 darran (*epp)->el_name = xstrdup(sbuf + cte->cte_name); 1300 1.1 darran (*epp)->el_number = cte->cte_value; 1301 1.1 darran } 1302 1.1 darran *epp = NULL; 1303 1.1 darran break; 1304 1.1 darran 1305 1.1 darran case CTF_K_FORWARD: 1306 1.1 darran tdp->t_type = FORWARD; 1307 1.1 darran list_add(&td->td_fwdlist, tdp); 1308 1.1 darran break; 1309 1.1 darran 1310 1.1 darran case CTF_K_TYPEDEF: 1311 1.1 darran tdp->t_type = TYPEDEF; 1312 1.15 christos tdp->t_tdesc = tdarr[type]; 1313 1.1 darran break; 1314 1.1 darran 1315 1.1 darran case CTF_K_VOLATILE: 1316 1.1 darran tdp->t_type = VOLATILE; 1317 1.15 christos tdp->t_tdesc = tdarr[type]; 1318 1.1 darran break; 1319 1.1 darran 1320 1.1 darran case CTF_K_CONST: 1321 1.1 darran tdp->t_type = CONST; 1322 1.15 christos tdp->t_tdesc = tdarr[type]; 1323 1.1 darran break; 1324 1.1 darran 1325 1.1 darran case CTF_K_FUNCTION: 1326 1.1 darran tdp->t_type = FUNCTION; 1327 1.1 darran tdp->t_fndef = xcalloc(sizeof (fndef_t)); 1328 1.15 christos tdp->t_fndef->fn_ret = tdarr[type]; 1329 1.1 darran 1330 1.15 christos v = (void *) (dptr + (idwidth * (vlen - 1))); 1331 1.15 christos if (vlen > 0 && *(uint_t *)v == 0) 1332 1.1 darran tdp->t_fndef->fn_vargs = 1; 1333 1.1 darran 1334 1.1 darran tdp->t_fndef->fn_nargs = vlen - tdp->t_fndef->fn_vargs; 1335 1.1 darran tdp->t_fndef->fn_args = xcalloc(sizeof (tdesc_t) * 1336 1.1 darran vlen - tdp->t_fndef->fn_vargs); 1337 1.1 darran 1338 1.1 darran for (i = 0; i < vlen; i++) { 1339 1.2 darran v = (void *) dptr; 1340 1.15 christos memcpy(&argid, v, idwidth); 1341 1.15 christos dptr += idwidth; 1342 1.1 darran 1343 1.1 darran if (argid != 0) 1344 1.1 darran tdp->t_fndef->fn_args[i] = tdarr[argid]; 1345 1.1 darran } 1346 1.1 darran 1347 1.15 christos dptr = (caddr_t) roundup2((uintptr_t) dptr, 4); 1348 1.1 darran break; 1349 1.1 darran 1350 1.1 darran case CTF_K_RESTRICT: 1351 1.1 darran tdp->t_type = RESTRICT; 1352 1.15 christos tdp->t_tdesc = tdarr[type]; 1353 1.1 darran break; 1354 1.1 darran 1355 1.1 darran case CTF_K_UNKNOWN: 1356 1.1 darran break; 1357 1.1 darran 1358 1.1 darran default: 1359 1.1 darran warning("Can't parse unknown CTF type %d\n", kind); 1360 1.1 darran } 1361 1.1 darran 1362 1.15 christos if (isroot) { 1363 1.1 darran iidesc_t *ii = iidesc_new(tdp->t_name); 1364 1.1 darran if (tdp->t_type == STRUCT || tdp->t_type == UNION || 1365 1.1 darran tdp->t_type == ENUM) 1366 1.1 darran ii->ii_type = II_SOU; 1367 1.1 darran else 1368 1.1 darran ii->ii_type = II_TYPE; 1369 1.1 darran ii->ii_dtype = tdp; 1370 1.1 darran hash_add(td->td_iihash, ii); 1371 1.1 darran 1372 1.1 darran iicnt++; 1373 1.1 darran } 1374 1.1 darran 1375 1.1 darran debug(3, "Resurrected %d %stype %s (%d)\n", tdp->t_type, 1376 1.15 christos (isroot ? "root " : ""), tdesc_name(tdp), tdp->t_id); 1377 1.1 darran } 1378 1.1 darran 1379 1.1 darran debug(3, "Resurrected %d types (%d were roots)\n", tcnt, iicnt); 1380 1.1 darran } 1381 1.1 darran 1382 1.1 darran /* 1383 1.1 darran * For lack of other inspiration, we're going to take the boring route. We 1384 1.1 darran * count the number of types. This lets us malloc that many tdesc structs 1385 1.1 darran * before we start filling them in. This has the advantage of allowing us to 1386 1.1 darran * avoid a merge-esque remap step. 1387 1.1 darran */ 1388 1.1 darran static tdata_t * 1389 1.1 darran ctf_parse(ctf_header_t *h, caddr_t buf, symit_data_t *si, char *label) 1390 1.1 darran { 1391 1.1 darran tdata_t *td = tdata_new(); 1392 1.1 darran tdesc_t **tdarr; 1393 1.14 chs int ntypes = count_types(h, buf); 1394 1.1 darran int idx, i; 1395 1.1 darran 1396 1.1 darran /* shudder */ 1397 1.1 darran tdarr = xcalloc(sizeof (tdesc_t *) * (ntypes + 1)); 1398 1.1 darran tdarr[0] = NULL; 1399 1.1 darran for (i = 1; i <= ntypes; i++) { 1400 1.1 darran tdarr[i] = xcalloc(sizeof (tdesc_t)); 1401 1.1 darran tdarr[i]->t_id = i; 1402 1.1 darran } 1403 1.1 darran 1404 1.1 darran td->td_parlabel = xstrdup(buf + h->cth_stroff + h->cth_parlabel); 1405 1.1 darran 1406 1.1 darran /* we have the technology - we can rebuild them */ 1407 1.1 darran idx = resurrect_labels(h, td, buf, label); 1408 1.1 darran 1409 1.1 darran resurrect_objects(h, td, tdarr, ntypes + 1, buf, si); 1410 1.1 darran resurrect_functions(h, td, tdarr, ntypes + 1, buf, si); 1411 1.1 darran resurrect_types(h, td, tdarr, ntypes + 1, buf, idx); 1412 1.1 darran 1413 1.1 darran free(tdarr); 1414 1.1 darran 1415 1.1 darran td->td_nextid = ntypes + 1; 1416 1.1 darran 1417 1.1 darran return (td); 1418 1.1 darran } 1419 1.1 darran 1420 1.1 darran static size_t 1421 1.1 darran decompress_ctf(caddr_t cbuf, size_t cbufsz, caddr_t dbuf, size_t dbufsz) 1422 1.1 darran { 1423 1.1 darran z_stream zstr; 1424 1.1 darran int rc; 1425 1.1 darran 1426 1.1 darran zstr.zalloc = (alloc_func)0; 1427 1.1 darran zstr.zfree = (free_func)0; 1428 1.1 darran zstr.opaque = (voidpf)0; 1429 1.1 darran 1430 1.1 darran zstr.next_in = (Bytef *)cbuf; 1431 1.1 darran zstr.avail_in = cbufsz; 1432 1.1 darran zstr.next_out = (Bytef *)dbuf; 1433 1.1 darran zstr.avail_out = dbufsz; 1434 1.1 darran 1435 1.1 darran if ((rc = inflateInit(&zstr)) != Z_OK || 1436 1.1 darran (rc = inflate(&zstr, Z_NO_FLUSH)) != Z_STREAM_END || 1437 1.1 darran (rc = inflateEnd(&zstr)) != Z_OK) { 1438 1.1 darran warning("CTF decompress zlib error %s\n", zError(rc)); 1439 1.2 darran return (0); 1440 1.1 darran } 1441 1.1 darran 1442 1.15 christos debug(3, "reflated %lu bytes to %lu, pointer at %td\n", 1443 1.15 christos zstr.total_in, zstr.total_out, (caddr_t)zstr.next_in - cbuf); 1444 1.1 darran 1445 1.1 darran return (zstr.total_out); 1446 1.1 darran } 1447 1.1 darran 1448 1.1 darran /* 1449 1.1 darran * Reconstruct the type tree from a given buffer of CTF data. Only the types 1450 1.1 darran * up to the type associated with the provided label, inclusive, will be 1451 1.1 darran * reconstructed. If a NULL label is provided, all types will be reconstructed. 1452 1.1 darran * 1453 1.1 darran * This function won't work on files that have been uniquified. 1454 1.1 darran */ 1455 1.1 darran tdata_t * 1456 1.1 darran ctf_load(char *file, caddr_t buf, size_t bufsz, symit_data_t *si, char *label) 1457 1.1 darran { 1458 1.1 darran ctf_header_t *h; 1459 1.1 darran caddr_t ctfdata; 1460 1.1 darran size_t ctfdatasz; 1461 1.1 darran tdata_t *td; 1462 1.1 darran 1463 1.1 darran curfile = file; 1464 1.1 darran 1465 1.1 darran if (bufsz < sizeof (ctf_header_t)) 1466 1.1 darran parseterminate("Corrupt CTF - short header"); 1467 1.1 darran 1468 1.2 darran void *v = (void *) buf; 1469 1.2 darran h = v; 1470 1.1 darran buf += sizeof (ctf_header_t); 1471 1.1 darran bufsz -= sizeof (ctf_header_t); 1472 1.1 darran 1473 1.1 darran if (h->cth_magic != CTF_MAGIC) 1474 1.1 darran parseterminate("Corrupt CTF - bad magic 0x%x", h->cth_magic); 1475 1.1 darran 1476 1.15 christos if (h->cth_version != CTF_VERSION_2 && h->cth_version != CTF_VERSION_3) 1477 1.1 darran parseterminate("Unknown CTF version %d", h->cth_version); 1478 1.1 darran 1479 1.1 darran ctfdatasz = h->cth_stroff + h->cth_strlen; 1480 1.1 darran if (h->cth_flags & CTF_F_COMPRESS) { 1481 1.1 darran size_t actual; 1482 1.1 darran 1483 1.1 darran ctfdata = xmalloc(ctfdatasz); 1484 1.1 darran if ((actual = decompress_ctf(buf, bufsz, ctfdata, ctfdatasz)) != 1485 1.1 darran ctfdatasz) { 1486 1.1 darran parseterminate("Corrupt CTF - short decompression " 1487 1.8 christos "(was %zu, expecting %zu)", actual, ctfdatasz); 1488 1.1 darran } 1489 1.1 darran } else { 1490 1.1 darran ctfdata = buf; 1491 1.1 darran ctfdatasz = bufsz; 1492 1.1 darran } 1493 1.1 darran 1494 1.1 darran td = ctf_parse(h, ctfdata, si, label); 1495 1.1 darran 1496 1.1 darran if (h->cth_flags & CTF_F_COMPRESS) 1497 1.1 darran free(ctfdata); 1498 1.1 darran 1499 1.1 darran curfile = NULL; 1500 1.1 darran 1501 1.1 darran return (td); 1502 1.1 darran } 1503