1178481Sjb/* 2178481Sjb * CDDL HEADER START 3178481Sjb * 4178481Sjb * The contents of this file are subject to the terms of the 5178481Sjb * Common Development and Distribution License (the "License"). 6178481Sjb * You may not use this file except in compliance with the License. 7178481Sjb * 8178481Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9178481Sjb * or http://www.opensolaris.org/os/licensing. 10178481Sjb * See the License for the specific language governing permissions 11178481Sjb * and limitations under the License. 12178481Sjb * 13178481Sjb * When distributing Covered Code, include this CDDL HEADER in each 14178481Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15178481Sjb * If applicable, add the following below this CDDL HEADER, with the 16178481Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17178481Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18178481Sjb * 19178481Sjb * CDDL HEADER END 20178481Sjb */ 21178481Sjb/* 22178481Sjb * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23178481Sjb * Use is subject to license terms. 24178481Sjb */ 25178481Sjb 26178481Sjb/* 27178481Sjb * DWARF to tdata conversion 28178481Sjb * 29178481Sjb * For the most part, conversion is straightforward, proceeding in two passes. 30178481Sjb * On the first pass, we iterate through every die, creating new type nodes as 31178481Sjb * necessary. Referenced tdesc_t's are created in an uninitialized state, thus 32178481Sjb * allowing type reference pointers to be filled in. If the tdesc_t 33178481Sjb * corresponding to a given die can be completely filled out (sizes and offsets 34178481Sjb * calculated, and so forth) without using any referenced types, the tdesc_t is 35178481Sjb * marked as resolved. Consider an array type. If the type corresponding to 36178481Sjb * the array contents has not yet been processed, we will create a blank tdesc 37178481Sjb * for the contents type (only the type ID will be filled in, relying upon the 38178481Sjb * later portion of the first pass to encounter and complete the referenced 39178481Sjb * type). We will then attempt to determine the size of the array. If the 40178481Sjb * array has a byte size attribute, we will have completely characterized the 41178481Sjb * array type, and will be able to mark it as resolved. The lack of a byte 42178481Sjb * size attribute, on the other hand, will prevent us from fully resolving the 43178481Sjb * type, as the size will only be calculable with reference to the contents 44178481Sjb * type, which has not, as yet, been encountered. The array type will thus be 45178481Sjb * left without the resolved flag, and the first pass will continue. 46178481Sjb * 47178481Sjb * When we begin the second pass, we will have created tdesc_t nodes for every 48178481Sjb * type in the section. We will traverse the tree, from the iidescs down, 49178481Sjb * processing each unresolved node. As the referenced nodes will have been 50178481Sjb * populated, the array type used in our example above will be able to use the 51178481Sjb * size of the referenced types (if available) to determine its own type. The 52178481Sjb * traversal will be repeated until all types have been resolved or we have 53178481Sjb * failed to make progress. When all tdescs have been resolved, the conversion 54178481Sjb * is complete. 55178481Sjb * 56178481Sjb * There are, as always, a few special cases that are handled during the first 57178481Sjb * and second passes: 58178481Sjb * 59178481Sjb * 1. Empty enums - GCC will occasionally emit an enum without any members. 60178481Sjb * Later on in the file, it will emit the same enum type, though this time 61178481Sjb * with the full complement of members. All references to the memberless 62178481Sjb * enum need to be redirected to the full definition. During the first 63178481Sjb * pass, each enum is entered in dm_enumhash, along with a pointer to its 64178481Sjb * corresponding tdesc_t. If, during the second pass, we encounter a 65178481Sjb * memberless enum, we use the hash to locate the full definition. All 66178481Sjb * tdescs referencing the empty enum are then redirected. 67178481Sjb * 68178481Sjb * 2. Forward declarations - If the compiler sees a forward declaration for 69178481Sjb * a structure, followed by the definition of that structure, it will emit 70178481Sjb * DWARF data for both the forward declaration and the definition. We need 71178481Sjb * to resolve the forward declarations when possible, by redirecting 72178481Sjb * forward-referencing tdescs to the actual struct/union definitions. This 73178481Sjb * redirection is done completely within the first pass. We begin by 74178481Sjb * recording all forward declarations in dw_fwdhash. When we define a 75178481Sjb * structure, we check to see if there have been any corresponding forward 76178481Sjb * declarations. If so, we redirect the tdescs which referenced the forward 77178481Sjb * declarations to the structure or union definition. 78178481Sjb * 79178481Sjb * XXX see if a post traverser will allow the elimination of repeated pass 2 80178481Sjb * traversals. 81178481Sjb */ 82178481Sjb 83178481Sjb#include <stdio.h> 84178481Sjb#include <stdlib.h> 85178545Sjb#include <string.h> 86178481Sjb#include <strings.h> 87178481Sjb#include <errno.h> 88178481Sjb#include <libelf.h> 89178481Sjb#include <libdwarf.h> 90178481Sjb#include <libgen.h> 91178481Sjb#include <dwarf.h> 92178481Sjb 93178481Sjb#include "ctf_headers.h" 94178481Sjb#include "ctftools.h" 95178481Sjb#include "memory.h" 96178481Sjb#include "list.h" 97178481Sjb#include "traverse.h" 98178481Sjb 99178481Sjb/* The version of DWARF which we support. */ 100178481Sjb#define DWARF_VERSION 2 101178481Sjb 102178481Sjb/* 103178481Sjb * We need to define a couple of our own intrinsics, to smooth out some of the 104178481Sjb * differences between the GCC and DevPro DWARF emitters. See the referenced 105178481Sjb * routines and the special cases in the file comment for more details. 106178481Sjb * 107178481Sjb * Type IDs are 32 bits wide. We're going to use the top of that field to 108178481Sjb * indicate types that we've created ourselves. 109178481Sjb */ 110178481Sjb#define TID_FILEMAX 0x3fffffff /* highest tid from file */ 111178481Sjb#define TID_VOID 0x40000001 /* see die_void() */ 112178481Sjb#define TID_LONG 0x40000002 /* see die_array() */ 113178481Sjb 114178481Sjb#define TID_MFGTID_BASE 0x40000003 /* first mfg'd tid */ 115178481Sjb 116178481Sjb/* 117178481Sjb * To reduce the staggering amount of error-handling code that would otherwise 118178481Sjb * be required, the attribute-retrieval routines handle most of their own 119178481Sjb * errors. If the following flag is supplied as the value of the `req' 120178481Sjb * argument, they will also handle the absence of a requested attribute by 121178481Sjb * terminating the program. 122178481Sjb */ 123178481Sjb#define DW_ATTR_REQ 1 124178481Sjb 125178481Sjb#define TDESC_HASH_BUCKETS 511 126178481Sjb 127178481Sjbtypedef struct dwarf { 128178481Sjb Dwarf_Debug dw_dw; /* for libdwarf */ 129178481Sjb Dwarf_Error dw_err; /* for libdwarf */ 130178545Sjb Dwarf_Off dw_maxoff; /* highest legal offset in this cu */ 131178481Sjb tdata_t *dw_td; /* root of the tdesc/iidesc tree */ 132178481Sjb hash_t *dw_tidhash; /* hash of tdescs by t_id */ 133178481Sjb hash_t *dw_fwdhash; /* hash of fwd decls by name */ 134178481Sjb hash_t *dw_enumhash; /* hash of memberless enums by name */ 135178481Sjb tdesc_t *dw_void; /* manufactured void type */ 136178481Sjb tdesc_t *dw_long; /* manufactured long type for arrays */ 137178481Sjb size_t dw_ptrsz; /* size of a pointer in this file */ 138178481Sjb tid_t dw_mfgtid_last; /* last mfg'd type ID used */ 139178481Sjb uint_t dw_nunres; /* count of unresolved types */ 140178481Sjb char *dw_cuname; /* name of compilation unit */ 141178481Sjb} dwarf_t; 142178481Sjb 143178481Sjbstatic void die_create_one(dwarf_t *, Dwarf_Die); 144178481Sjbstatic void die_create(dwarf_t *, Dwarf_Die); 145178481Sjb 146178481Sjbstatic tid_t 147178481Sjbmfgtid_next(dwarf_t *dw) 148178481Sjb{ 149178481Sjb return (++dw->dw_mfgtid_last); 150178481Sjb} 151178481Sjb 152178481Sjbstatic void 153178481Sjbtdesc_add(dwarf_t *dw, tdesc_t *tdp) 154178481Sjb{ 155178481Sjb hash_add(dw->dw_tidhash, tdp); 156178481Sjb} 157178481Sjb 158178481Sjbstatic tdesc_t * 159178481Sjbtdesc_lookup(dwarf_t *dw, int tid) 160178481Sjb{ 161178545Sjb tdesc_t tmpl; 162178545Sjb void *tdp; 163178481Sjb 164178481Sjb tmpl.t_id = tid; 165178481Sjb 166178545Sjb if (hash_find(dw->dw_tidhash, &tmpl, &tdp)) 167178481Sjb return (tdp); 168178481Sjb else 169178481Sjb return (NULL); 170178481Sjb} 171178481Sjb 172178481Sjb/* 173178481Sjb * Resolve a tdesc down to a node which should have a size. Returns the size, 174178481Sjb * zero if the size hasn't yet been determined. 175178481Sjb */ 176178481Sjbstatic size_t 177178481Sjbtdesc_size(tdesc_t *tdp) 178178481Sjb{ 179178481Sjb for (;;) { 180178481Sjb switch (tdp->t_type) { 181178481Sjb case INTRINSIC: 182178481Sjb case POINTER: 183178481Sjb case ARRAY: 184178481Sjb case FUNCTION: 185178481Sjb case STRUCT: 186178481Sjb case UNION: 187178481Sjb case ENUM: 188178481Sjb return (tdp->t_size); 189178481Sjb 190178481Sjb case FORWARD: 191178481Sjb return (0); 192178481Sjb 193178481Sjb case TYPEDEF: 194178481Sjb case VOLATILE: 195178481Sjb case CONST: 196178481Sjb case RESTRICT: 197178481Sjb tdp = tdp->t_tdesc; 198178481Sjb continue; 199178481Sjb 200178481Sjb case 0: /* not yet defined */ 201178481Sjb return (0); 202178481Sjb 203178481Sjb default: 204178481Sjb terminate("tdp %u: tdesc_size on unknown type %d\n", 205178481Sjb tdp->t_id, tdp->t_type); 206178481Sjb } 207178481Sjb } 208178481Sjb} 209178481Sjb 210178481Sjbstatic size_t 211178481Sjbtdesc_bitsize(tdesc_t *tdp) 212178481Sjb{ 213178481Sjb for (;;) { 214178481Sjb switch (tdp->t_type) { 215178481Sjb case INTRINSIC: 216178481Sjb return (tdp->t_intr->intr_nbits); 217178481Sjb 218178481Sjb case ARRAY: 219178481Sjb case FUNCTION: 220178481Sjb case STRUCT: 221178481Sjb case UNION: 222178481Sjb case ENUM: 223178481Sjb case POINTER: 224178481Sjb return (tdp->t_size * NBBY); 225178481Sjb 226178481Sjb case FORWARD: 227178481Sjb return (0); 228178481Sjb 229178481Sjb case TYPEDEF: 230178481Sjb case VOLATILE: 231178481Sjb case RESTRICT: 232178481Sjb case CONST: 233178481Sjb tdp = tdp->t_tdesc; 234178481Sjb continue; 235178481Sjb 236178481Sjb case 0: /* not yet defined */ 237178481Sjb return (0); 238178481Sjb 239178481Sjb default: 240178481Sjb terminate("tdp %u: tdesc_bitsize on unknown type %d\n", 241178481Sjb tdp->t_id, tdp->t_type); 242178481Sjb } 243178481Sjb } 244178481Sjb} 245178481Sjb 246178481Sjbstatic tdesc_t * 247178481Sjbtdesc_basetype(tdesc_t *tdp) 248178481Sjb{ 249178481Sjb for (;;) { 250178481Sjb switch (tdp->t_type) { 251178481Sjb case TYPEDEF: 252178481Sjb case VOLATILE: 253178481Sjb case RESTRICT: 254178481Sjb case CONST: 255178481Sjb tdp = tdp->t_tdesc; 256178481Sjb break; 257178481Sjb case 0: /* not yet defined */ 258178481Sjb return (NULL); 259178481Sjb default: 260178481Sjb return (tdp); 261178481Sjb } 262178481Sjb } 263178481Sjb} 264178481Sjb 265178481Sjbstatic Dwarf_Off 266178481Sjbdie_off(dwarf_t *dw, Dwarf_Die die) 267178481Sjb{ 268178481Sjb Dwarf_Off off; 269178481Sjb 270178481Sjb if (dwarf_dieoffset(die, &off, &dw->dw_err) == DW_DLV_OK) 271178481Sjb return (off); 272178481Sjb 273178481Sjb terminate("failed to get offset for die: %s\n", 274178545Sjb dwarf_errmsg(&dw->dw_err)); 275178481Sjb /*NOTREACHED*/ 276178481Sjb return (0); 277178481Sjb} 278178481Sjb 279178481Sjbstatic Dwarf_Die 280178481Sjbdie_sibling(dwarf_t *dw, Dwarf_Die die) 281178481Sjb{ 282178481Sjb Dwarf_Die sib; 283178481Sjb int rc; 284178481Sjb 285178481Sjb if ((rc = dwarf_siblingof(dw->dw_dw, die, &sib, &dw->dw_err)) == 286178481Sjb DW_DLV_OK) 287178481Sjb return (sib); 288178481Sjb else if (rc == DW_DLV_NO_ENTRY) 289178481Sjb return (NULL); 290178481Sjb 291178481Sjb terminate("die %llu: failed to find type sibling: %s\n", 292178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 293178481Sjb /*NOTREACHED*/ 294178481Sjb return (NULL); 295178481Sjb} 296178481Sjb 297178481Sjbstatic Dwarf_Die 298178481Sjbdie_child(dwarf_t *dw, Dwarf_Die die) 299178481Sjb{ 300178481Sjb Dwarf_Die child; 301178481Sjb int rc; 302178481Sjb 303178481Sjb if ((rc = dwarf_child(die, &child, &dw->dw_err)) == DW_DLV_OK) 304178481Sjb return (child); 305178481Sjb else if (rc == DW_DLV_NO_ENTRY) 306178481Sjb return (NULL); 307178481Sjb 308178481Sjb terminate("die %llu: failed to find type child: %s\n", 309178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 310178481Sjb /*NOTREACHED*/ 311178481Sjb return (NULL); 312178481Sjb} 313178481Sjb 314178481Sjbstatic Dwarf_Half 315178481Sjbdie_tag(dwarf_t *dw, Dwarf_Die die) 316178481Sjb{ 317178481Sjb Dwarf_Half tag; 318178481Sjb 319178481Sjb if (dwarf_tag(die, &tag, &dw->dw_err) == DW_DLV_OK) 320178481Sjb return (tag); 321178481Sjb 322178481Sjb terminate("die %llu: failed to get tag for type: %s\n", 323178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 324178481Sjb /*NOTREACHED*/ 325178481Sjb return (0); 326178481Sjb} 327178481Sjb 328178481Sjbstatic Dwarf_Attribute 329178481Sjbdie_attr(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, int req) 330178481Sjb{ 331178481Sjb Dwarf_Attribute attr; 332178481Sjb int rc; 333178481Sjb 334178481Sjb if ((rc = dwarf_attr(die, name, &attr, &dw->dw_err)) == DW_DLV_OK) { 335178481Sjb return (attr); 336178481Sjb } else if (rc == DW_DLV_NO_ENTRY) { 337178481Sjb if (req) { 338178481Sjb terminate("die %llu: no attr 0x%x\n", die_off(dw, die), 339178481Sjb name); 340178481Sjb } else { 341178481Sjb return (NULL); 342178481Sjb } 343178481Sjb } 344178481Sjb 345178481Sjb terminate("die %llu: failed to get attribute for type: %s\n", 346178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 347178481Sjb /*NOTREACHED*/ 348178481Sjb return (NULL); 349178481Sjb} 350178481Sjb 351178481Sjbstatic int 352178481Sjbdie_signed(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Signed *valp, 353178481Sjb int req) 354178481Sjb{ 355178545Sjb *valp = 0; 356178545Sjb if (dwarf_attrval_signed(die, name, valp, &dw->dw_err) != DWARF_E_NONE) { 357178545Sjb if (req) 358178545Sjb terminate("die %llu: failed to get signed: %s\n", 359178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 360178545Sjb return (0); 361178481Sjb } 362178481Sjb 363178481Sjb return (1); 364178481Sjb} 365178481Sjb 366178481Sjbstatic int 367178481Sjbdie_unsigned(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp, 368178481Sjb int req) 369178481Sjb{ 370178545Sjb *valp = 0; 371178545Sjb if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != DWARF_E_NONE) { 372178545Sjb if (req) 373178545Sjb terminate("die %llu: failed to get unsigned: %s\n", 374178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 375178545Sjb return (0); 376178481Sjb } 377178481Sjb 378178481Sjb return (1); 379178481Sjb} 380178481Sjb 381178481Sjbstatic int 382178481Sjbdie_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req) 383178481Sjb{ 384178545Sjb *valp = 0; 385178481Sjb 386178545Sjb if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DWARF_E_NONE) { 387178545Sjb if (req) 388178545Sjb terminate("die %llu: failed to get flag: %s\n", 389178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 390178545Sjb return (0); 391178481Sjb } 392178481Sjb 393178481Sjb return (1); 394178481Sjb} 395178481Sjb 396178481Sjbstatic int 397178481Sjbdie_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req) 398178481Sjb{ 399178545Sjb const char *str = NULL; 400178481Sjb 401178545Sjb if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DWARF_E_NONE || 402178545Sjb str == NULL) { 403178545Sjb if (req) 404178545Sjb terminate("die %llu: failed to get string: %s\n", 405178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 406178545Sjb else 407178545Sjb *strp = NULL; 408178545Sjb return (0); 409178545Sjb } else 410178545Sjb *strp = xstrdup(str); 411178481Sjb 412178481Sjb return (1); 413178481Sjb} 414178481Sjb 415178481Sjbstatic Dwarf_Off 416178481Sjbdie_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name) 417178481Sjb{ 418178481Sjb Dwarf_Off off; 419178481Sjb 420178545Sjb if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DWARF_E_NONE) { 421178545Sjb terminate("die %llu: failed to get ref: %s\n", 422178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 423178481Sjb } 424178481Sjb 425178481Sjb return (off); 426178481Sjb} 427178481Sjb 428178481Sjbstatic char * 429178481Sjbdie_name(dwarf_t *dw, Dwarf_Die die) 430178481Sjb{ 431178481Sjb char *str = NULL; 432178481Sjb 433178481Sjb (void) die_string(dw, die, DW_AT_name, &str, 0); 434178481Sjb 435178481Sjb return (str); 436178481Sjb} 437178481Sjb 438178481Sjbstatic int 439178481Sjbdie_isdecl(dwarf_t *dw, Dwarf_Die die) 440178481Sjb{ 441178481Sjb Dwarf_Bool val; 442178481Sjb 443178481Sjb return (die_bool(dw, die, DW_AT_declaration, &val, 0) && val); 444178481Sjb} 445178481Sjb 446178481Sjbstatic int 447178481Sjbdie_isglobal(dwarf_t *dw, Dwarf_Die die) 448178481Sjb{ 449178481Sjb Dwarf_Signed vis; 450178481Sjb Dwarf_Bool ext; 451178481Sjb 452178481Sjb /* 453178481Sjb * Some compilers (gcc) use DW_AT_external to indicate function 454178481Sjb * visibility. Others (Sun) use DW_AT_visibility. 455178481Sjb */ 456178481Sjb if (die_signed(dw, die, DW_AT_visibility, &vis, 0)) 457178481Sjb return (vis == DW_VIS_exported); 458178481Sjb else 459178481Sjb return (die_bool(dw, die, DW_AT_external, &ext, 0) && ext); 460178481Sjb} 461178481Sjb 462178481Sjbstatic tdesc_t * 463178481Sjbdie_add(dwarf_t *dw, Dwarf_Off off) 464178481Sjb{ 465178481Sjb tdesc_t *tdp = xcalloc(sizeof (tdesc_t)); 466178481Sjb 467178481Sjb tdp->t_id = off; 468178481Sjb 469178481Sjb tdesc_add(dw, tdp); 470178481Sjb 471178481Sjb return (tdp); 472178481Sjb} 473178481Sjb 474178481Sjbstatic tdesc_t * 475178481Sjbdie_lookup_pass1(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name) 476178481Sjb{ 477178481Sjb Dwarf_Off ref = die_attr_ref(dw, die, name); 478178481Sjb tdesc_t *tdp; 479178481Sjb 480178481Sjb if ((tdp = tdesc_lookup(dw, ref)) != NULL) 481178481Sjb return (tdp); 482178481Sjb 483178481Sjb return (die_add(dw, ref)); 484178481Sjb} 485178481Sjb 486178481Sjbstatic int 487178481Sjbdie_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, 488178545Sjb Dwarf_Unsigned *valp, int req __unused) 489178481Sjb{ 490178545Sjb Dwarf_Locdesc *loc = NULL; 491178545Sjb Dwarf_Signed locnum = 0; 492263915Sdim Dwarf_Attribute at; 493263915Sdim Dwarf_Half form; 494178481Sjb 495263915Sdim if (name != DW_AT_data_member_location) 496263915Sdim terminate("die %llu: can only process attribute " 497263915Sdim "DW_AT_data_member_location\n", die_off(dw, die)); 498263915Sdim 499263915Sdim if ((at = die_attr(dw, die, name, 0)) == NULL) 500178545Sjb return (0); 501178481Sjb 502263915Sdim if (dwarf_whatform(at, &form, &dw->dw_err) != DW_DLV_OK) 503263915Sdim return (0); 504263915Sdim 505263915Sdim switch (form) { 506263915Sdim case DW_FORM_block: 507263915Sdim case DW_FORM_block1: 508263915Sdim case DW_FORM_block2: 509263915Sdim case DW_FORM_block4: 510263915Sdim /* 511263915Sdim * GCC in base and Clang (3.3 or below) generates 512263915Sdim * DW_AT_data_member_location attribute with DW_FORM_block* 513263915Sdim * form. The attribute contains one DW_OP_plus_uconst 514263915Sdim * operator. The member offset stores in the operand. 515263915Sdim */ 516263915Sdim if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != 517263915Sdim DW_DLV_OK) 518263915Sdim return (0); 519263915Sdim if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) { 520263915Sdim terminate("die %llu: cannot parse member offset\n", 521263915Sdim die_off(dw, die)); 522263915Sdim } 523263915Sdim *valp = loc->ld_s->lr_number; 524263915Sdim break; 525263915Sdim 526263915Sdim case DW_FORM_data1: 527263915Sdim case DW_FORM_data2: 528263915Sdim case DW_FORM_data4: 529263915Sdim case DW_FORM_data8: 530263915Sdim case DW_FORM_udata: 531263915Sdim /* 532263915Sdim * Clang 3.4 generates DW_AT_data_member_location attribute 533263915Sdim * with DW_FORM_data* form (constant class). The attribute 534263915Sdim * stores a contant value which is the member offset. 535263915Sdim */ 536263915Sdim if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != 537263915Sdim DW_DLV_OK) 538263915Sdim return (0); 539263915Sdim break; 540263915Sdim 541263915Sdim default: 542263915Sdim terminate("die %llu: cannot parse member offset with form " 543263915Sdim "%u\n", die_off(dw, die), form); 544178481Sjb } 545178481Sjb 546178545Sjb if (loc != NULL) 547178545Sjb if (dwarf_locdesc_free(loc, &dw->dw_err) != DW_DLV_OK) 548178545Sjb terminate("die %llu: cannot free location descriptor: %s\n", 549178545Sjb die_off(dw, die), dwarf_errmsg(&dw->dw_err)); 550178481Sjb 551178481Sjb return (1); 552178481Sjb} 553178481Sjb 554178481Sjbstatic tdesc_t * 555178481Sjbtdesc_intr_common(dwarf_t *dw, int tid, const char *name, size_t sz) 556178481Sjb{ 557178481Sjb tdesc_t *tdp; 558178481Sjb intr_t *intr; 559178481Sjb 560178481Sjb intr = xcalloc(sizeof (intr_t)); 561178481Sjb intr->intr_type = INTR_INT; 562178481Sjb intr->intr_signed = 1; 563178481Sjb intr->intr_nbits = sz * NBBY; 564178481Sjb 565178481Sjb tdp = xcalloc(sizeof (tdesc_t)); 566178481Sjb tdp->t_name = xstrdup(name); 567178481Sjb tdp->t_size = sz; 568178481Sjb tdp->t_id = tid; 569178481Sjb tdp->t_type = INTRINSIC; 570178481Sjb tdp->t_intr = intr; 571178481Sjb tdp->t_flags = TDESC_F_RESOLVED; 572178481Sjb 573178481Sjb tdesc_add(dw, tdp); 574178481Sjb 575178481Sjb return (tdp); 576178481Sjb} 577178481Sjb 578178481Sjb/* 579178481Sjb * Manufacture a void type. Used for gcc-emitted stabs, where the lack of a 580178481Sjb * type reference implies a reference to a void type. A void *, for example 581178481Sjb * will be represented by a pointer die without a DW_AT_type. CTF requires 582178481Sjb * that pointer nodes point to something, so we'll create a void for use as 583178481Sjb * the target. Note that the DWARF data may already create a void type. Ours 584178481Sjb * would then be a duplicate, but it'll be removed in the self-uniquification 585178481Sjb * merge performed at the completion of DWARF->tdesc conversion. 586178481Sjb */ 587178481Sjbstatic tdesc_t * 588178481Sjbtdesc_intr_void(dwarf_t *dw) 589178481Sjb{ 590178481Sjb if (dw->dw_void == NULL) 591178481Sjb dw->dw_void = tdesc_intr_common(dw, TID_VOID, "void", 0); 592178481Sjb 593178481Sjb return (dw->dw_void); 594178481Sjb} 595178481Sjb 596178481Sjbstatic tdesc_t * 597178481Sjbtdesc_intr_long(dwarf_t *dw) 598178481Sjb{ 599178481Sjb if (dw->dw_long == NULL) { 600178481Sjb dw->dw_long = tdesc_intr_common(dw, TID_LONG, "long", 601178481Sjb dw->dw_ptrsz); 602178481Sjb } 603178481Sjb 604178481Sjb return (dw->dw_long); 605178481Sjb} 606178481Sjb 607178481Sjb/* 608178481Sjb * Used for creating bitfield types. We create a copy of an existing intrinsic, 609178481Sjb * adjusting the size of the copy to match what the caller requested. The 610178481Sjb * caller can then use the copy as the type for a bitfield structure member. 611178481Sjb */ 612178481Sjbstatic tdesc_t * 613178481Sjbtdesc_intr_clone(dwarf_t *dw, tdesc_t *old, size_t bitsz) 614178481Sjb{ 615178481Sjb tdesc_t *new = xcalloc(sizeof (tdesc_t)); 616178481Sjb 617178481Sjb if (!(old->t_flags & TDESC_F_RESOLVED)) { 618178481Sjb terminate("tdp %u: attempt to make a bit field from an " 619178481Sjb "unresolved type\n", old->t_id); 620178481Sjb } 621178481Sjb 622178481Sjb new->t_name = xstrdup(old->t_name); 623178481Sjb new->t_size = old->t_size; 624178481Sjb new->t_id = mfgtid_next(dw); 625178481Sjb new->t_type = INTRINSIC; 626178481Sjb new->t_flags = TDESC_F_RESOLVED; 627178481Sjb 628178481Sjb new->t_intr = xcalloc(sizeof (intr_t)); 629178481Sjb bcopy(old->t_intr, new->t_intr, sizeof (intr_t)); 630178481Sjb new->t_intr->intr_nbits = bitsz; 631178481Sjb 632178481Sjb tdesc_add(dw, new); 633178481Sjb 634178481Sjb return (new); 635178481Sjb} 636178481Sjb 637178481Sjbstatic void 638178481Sjbtdesc_array_create(dwarf_t *dw, Dwarf_Die dim, tdesc_t *arrtdp, 639178481Sjb tdesc_t *dimtdp) 640178481Sjb{ 641178481Sjb Dwarf_Unsigned uval; 642178481Sjb Dwarf_Signed sval; 643178545Sjb tdesc_t *ctdp = NULL; 644178481Sjb Dwarf_Die dim2; 645178481Sjb ardef_t *ar; 646178481Sjb 647178481Sjb if ((dim2 = die_sibling(dw, dim)) == NULL) { 648178481Sjb ctdp = arrtdp; 649178481Sjb } else if (die_tag(dw, dim2) == DW_TAG_subrange_type) { 650178481Sjb ctdp = xcalloc(sizeof (tdesc_t)); 651178481Sjb ctdp->t_id = mfgtid_next(dw); 652178481Sjb debug(3, "die %llu: creating new type %u for sub-dimension\n", 653178481Sjb die_off(dw, dim2), ctdp->t_id); 654178481Sjb tdesc_array_create(dw, dim2, arrtdp, ctdp); 655178481Sjb } else { 656178481Sjb terminate("die %llu: unexpected non-subrange node in array\n", 657178481Sjb die_off(dw, dim2)); 658178481Sjb } 659178481Sjb 660178481Sjb dimtdp->t_type = ARRAY; 661178481Sjb dimtdp->t_ardef = ar = xcalloc(sizeof (ardef_t)); 662178481Sjb 663178481Sjb /* 664178481Sjb * Array bounds can be signed or unsigned, but there are several kinds 665178481Sjb * of signless forms (data1, data2, etc) that take their sign from the 666178481Sjb * routine that is trying to interpret them. That is, data1 can be 667178481Sjb * either signed or unsigned, depending on whether you use the signed or 668178481Sjb * unsigned accessor function. GCC will use the signless forms to store 669178481Sjb * unsigned values which have their high bit set, so we need to try to 670178481Sjb * read them first as unsigned to get positive values. We could also 671178481Sjb * try signed first, falling back to unsigned if we got a negative 672178481Sjb * value. 673178481Sjb */ 674178481Sjb if (die_unsigned(dw, dim, DW_AT_upper_bound, &uval, 0)) 675178481Sjb ar->ad_nelems = uval + 1; 676178481Sjb else if (die_signed(dw, dim, DW_AT_upper_bound, &sval, 0)) 677178481Sjb ar->ad_nelems = sval + 1; 678178481Sjb else 679178481Sjb ar->ad_nelems = 0; 680178481Sjb 681178481Sjb /* 682178481Sjb * Different compilers use different index types. Force the type to be 683178481Sjb * a common, known value (long). 684178481Sjb */ 685178481Sjb ar->ad_idxtype = tdesc_intr_long(dw); 686178481Sjb ar->ad_contents = ctdp; 687178481Sjb 688178481Sjb if (ar->ad_contents->t_size != 0) { 689178481Sjb dimtdp->t_size = ar->ad_contents->t_size * ar->ad_nelems; 690178481Sjb dimtdp->t_flags |= TDESC_F_RESOLVED; 691178481Sjb } 692178481Sjb} 693178481Sjb 694178481Sjb/* 695178481Sjb * Create a tdesc from an array node. Some arrays will come with byte size 696178481Sjb * attributes, and thus can be resolved immediately. Others don't, and will 697178481Sjb * need to wait until the second pass for resolution. 698178481Sjb */ 699178481Sjbstatic void 700178481Sjbdie_array_create(dwarf_t *dw, Dwarf_Die arr, Dwarf_Off off, tdesc_t *tdp) 701178481Sjb{ 702178481Sjb tdesc_t *arrtdp = die_lookup_pass1(dw, arr, DW_AT_type); 703178481Sjb Dwarf_Unsigned uval; 704178481Sjb Dwarf_Die dim; 705178481Sjb 706178545Sjb debug(3, "die %llu <%llx>: creating array\n", off, off); 707178481Sjb 708178481Sjb if ((dim = die_child(dw, arr)) == NULL || 709178481Sjb die_tag(dw, dim) != DW_TAG_subrange_type) 710178481Sjb terminate("die %llu: failed to retrieve array bounds\n", off); 711178481Sjb 712178481Sjb tdesc_array_create(dw, dim, arrtdp, tdp); 713178481Sjb 714178481Sjb if (die_unsigned(dw, arr, DW_AT_byte_size, &uval, 0)) { 715178481Sjb tdesc_t *dimtdp; 716178481Sjb int flags; 717178481Sjb 718253661Spfg /* Check for bogus gcc DW_AT_byte_size attribute */ 719253661Spfg if (uval == (unsigned)-1) { 720253661Spfg printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n", 721253661Spfg __func__); 722253661Spfg uval = 0; 723253661Spfg } 724253661Spfg 725178481Sjb tdp->t_size = uval; 726178481Sjb 727178481Sjb /* 728178481Sjb * Ensure that sub-dimensions have sizes too before marking 729178481Sjb * as resolved. 730178481Sjb */ 731178481Sjb flags = TDESC_F_RESOLVED; 732178481Sjb for (dimtdp = tdp->t_ardef->ad_contents; 733178481Sjb dimtdp->t_type == ARRAY; 734178481Sjb dimtdp = dimtdp->t_ardef->ad_contents) { 735178481Sjb if (!(dimtdp->t_flags & TDESC_F_RESOLVED)) { 736178481Sjb flags = 0; 737178481Sjb break; 738178481Sjb } 739178481Sjb } 740178481Sjb 741178481Sjb tdp->t_flags |= flags; 742178481Sjb } 743178481Sjb 744178545Sjb debug(3, "die %llu <%llx>: array nelems %u size %u\n", off, off, 745178481Sjb tdp->t_ardef->ad_nelems, tdp->t_size); 746178481Sjb} 747178481Sjb 748178481Sjb/*ARGSUSED1*/ 749178481Sjbstatic int 750178545Sjbdie_array_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private) 751178481Sjb{ 752178481Sjb dwarf_t *dw = private; 753178481Sjb size_t sz; 754178481Sjb 755178481Sjb if (tdp->t_flags & TDESC_F_RESOLVED) 756178481Sjb return (1); 757178481Sjb 758178481Sjb debug(3, "trying to resolve array %d (cont %d)\n", tdp->t_id, 759178481Sjb tdp->t_ardef->ad_contents->t_id); 760178481Sjb 761178481Sjb if ((sz = tdesc_size(tdp->t_ardef->ad_contents)) == 0) { 762178481Sjb debug(3, "unable to resolve array %s (%d) contents %d\n", 763178481Sjb tdesc_name(tdp), tdp->t_id, 764178481Sjb tdp->t_ardef->ad_contents->t_id); 765178481Sjb 766178481Sjb dw->dw_nunres++; 767178481Sjb return (1); 768178481Sjb } 769178481Sjb 770178481Sjb tdp->t_size = sz * tdp->t_ardef->ad_nelems; 771178481Sjb tdp->t_flags |= TDESC_F_RESOLVED; 772178481Sjb 773178481Sjb debug(3, "resolved array %d: %u bytes\n", tdp->t_id, tdp->t_size); 774178481Sjb 775178481Sjb return (1); 776178481Sjb} 777178481Sjb 778178481Sjb/*ARGSUSED1*/ 779178481Sjbstatic int 780178545Sjbdie_array_failed(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private __unused) 781178481Sjb{ 782178481Sjb tdesc_t *cont = tdp->t_ardef->ad_contents; 783178481Sjb 784178481Sjb if (tdp->t_flags & TDESC_F_RESOLVED) 785178481Sjb return (1); 786178481Sjb 787178481Sjb fprintf(stderr, "Array %d: failed to size contents type %s (%d)\n", 788178481Sjb tdp->t_id, tdesc_name(cont), cont->t_id); 789178481Sjb 790178481Sjb return (1); 791178481Sjb} 792178481Sjb 793178481Sjb/* 794178481Sjb * Most enums (those with members) will be resolved during this first pass. 795178481Sjb * Others - those without members (see the file comment) - won't be, and will 796178481Sjb * need to wait until the second pass when they can be matched with their full 797178481Sjb * definitions. 798178481Sjb */ 799178481Sjbstatic void 800178481Sjbdie_enum_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 801178481Sjb{ 802178481Sjb Dwarf_Die mem; 803178481Sjb Dwarf_Unsigned uval; 804178481Sjb Dwarf_Signed sval; 805178481Sjb 806178481Sjb debug(3, "die %llu: creating enum\n", off); 807178481Sjb 808178481Sjb tdp->t_type = ENUM; 809178481Sjb 810178481Sjb (void) die_unsigned(dw, die, DW_AT_byte_size, &uval, DW_ATTR_REQ); 811253661Spfg /* Check for bogus gcc DW_AT_byte_size attribute */ 812253661Spfg if (uval == (unsigned)-1) { 813253661Spfg printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n", 814253661Spfg __func__); 815253661Spfg uval = 0; 816253661Spfg } 817178481Sjb tdp->t_size = uval; 818178481Sjb 819178481Sjb if ((mem = die_child(dw, die)) != NULL) { 820178481Sjb elist_t **elastp = &tdp->t_emem; 821178481Sjb 822178481Sjb do { 823178481Sjb elist_t *el; 824178481Sjb 825178481Sjb if (die_tag(dw, mem) != DW_TAG_enumerator) { 826178481Sjb /* Nested type declaration */ 827178481Sjb die_create_one(dw, mem); 828178481Sjb continue; 829178481Sjb } 830178481Sjb 831178481Sjb el = xcalloc(sizeof (elist_t)); 832178481Sjb el->el_name = die_name(dw, mem); 833178481Sjb 834178481Sjb if (die_signed(dw, mem, DW_AT_const_value, &sval, 0)) { 835178481Sjb el->el_number = sval; 836178481Sjb } else if (die_unsigned(dw, mem, DW_AT_const_value, 837178481Sjb &uval, 0)) { 838178481Sjb el->el_number = uval; 839178481Sjb } else { 840178481Sjb terminate("die %llu: enum %llu: member without " 841178481Sjb "value\n", off, die_off(dw, mem)); 842178481Sjb } 843178481Sjb 844178481Sjb debug(3, "die %llu: enum %llu: created %s = %d\n", off, 845178481Sjb die_off(dw, mem), el->el_name, el->el_number); 846178481Sjb 847178481Sjb *elastp = el; 848178481Sjb elastp = &el->el_next; 849178481Sjb 850178481Sjb } while ((mem = die_sibling(dw, mem)) != NULL); 851178481Sjb 852178481Sjb hash_add(dw->dw_enumhash, tdp); 853178481Sjb 854178481Sjb tdp->t_flags |= TDESC_F_RESOLVED; 855178481Sjb 856178481Sjb if (tdp->t_name != NULL) { 857178481Sjb iidesc_t *ii = xcalloc(sizeof (iidesc_t)); 858178481Sjb ii->ii_type = II_SOU; 859178481Sjb ii->ii_name = xstrdup(tdp->t_name); 860178481Sjb ii->ii_dtype = tdp; 861178481Sjb 862178481Sjb iidesc_add(dw->dw_td->td_iihash, ii); 863178481Sjb } 864178481Sjb } 865178481Sjb} 866178481Sjb 867178481Sjbstatic int 868178481Sjbdie_enum_match(void *arg1, void *arg2) 869178481Sjb{ 870178481Sjb tdesc_t *tdp = arg1, **fullp = arg2; 871178481Sjb 872178481Sjb if (tdp->t_emem != NULL) { 873178481Sjb *fullp = tdp; 874178481Sjb return (-1); /* stop the iteration */ 875178481Sjb } 876178481Sjb 877178481Sjb return (0); 878178481Sjb} 879178481Sjb 880178481Sjb/*ARGSUSED1*/ 881178481Sjbstatic int 882178545Sjbdie_enum_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private) 883178481Sjb{ 884178481Sjb dwarf_t *dw = private; 885178481Sjb tdesc_t *full = NULL; 886178481Sjb 887178481Sjb if (tdp->t_flags & TDESC_F_RESOLVED) 888178481Sjb return (1); 889178481Sjb 890178481Sjb (void) hash_find_iter(dw->dw_enumhash, tdp, die_enum_match, &full); 891178481Sjb 892178481Sjb /* 893178481Sjb * The answer to this one won't change from iteration to iteration, 894178481Sjb * so don't even try. 895178481Sjb */ 896178481Sjb if (full == NULL) { 897178481Sjb terminate("tdp %u: enum %s has no members\n", tdp->t_id, 898178481Sjb tdesc_name(tdp)); 899178481Sjb } 900178481Sjb 901178481Sjb debug(3, "tdp %u: enum %s redirected to %u\n", tdp->t_id, 902178481Sjb tdesc_name(tdp), full->t_id); 903178481Sjb 904178481Sjb tdp->t_flags |= TDESC_F_RESOLVED; 905178481Sjb 906178481Sjb return (1); 907178481Sjb} 908178481Sjb 909178481Sjbstatic int 910178481Sjbdie_fwd_map(void *arg1, void *arg2) 911178481Sjb{ 912178481Sjb tdesc_t *fwd = arg1, *sou = arg2; 913178481Sjb 914178481Sjb debug(3, "tdp %u: mapped forward %s to sou %u\n", fwd->t_id, 915178481Sjb tdesc_name(fwd), sou->t_id); 916178481Sjb fwd->t_tdesc = sou; 917178481Sjb 918178481Sjb return (0); 919178481Sjb} 920178481Sjb 921178481Sjb/* 922178481Sjb * Structures and unions will never be resolved during the first pass, as we 923178481Sjb * won't be able to fully determine the member sizes. The second pass, which 924178481Sjb * have access to sizing information, will be able to complete the resolution. 925178481Sjb */ 926178481Sjbstatic void 927178481Sjbdie_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp, 928178481Sjb int type, const char *typename) 929178481Sjb{ 930253661Spfg Dwarf_Unsigned sz, bitsz, bitoff, maxsz=0; 931263915Sdim#if BYTE_ORDER == _LITTLE_ENDIAN 932263915Sdim Dwarf_Unsigned bysz; 933263915Sdim#endif 934178481Sjb Dwarf_Die mem; 935178481Sjb mlist_t *ml, **mlastp; 936178481Sjb iidesc_t *ii; 937178481Sjb 938178481Sjb tdp->t_type = (die_isdecl(dw, str) ? FORWARD : type); 939178481Sjb 940178481Sjb debug(3, "die %llu: creating %s %s\n", off, 941178481Sjb (tdp->t_type == FORWARD ? "forward decl" : typename), 942178481Sjb tdesc_name(tdp)); 943178481Sjb 944178481Sjb if (tdp->t_type == FORWARD) { 945178481Sjb hash_add(dw->dw_fwdhash, tdp); 946178481Sjb return; 947178481Sjb } 948178481Sjb 949178481Sjb (void) hash_find_iter(dw->dw_fwdhash, tdp, die_fwd_map, tdp); 950178481Sjb 951178481Sjb (void) die_unsigned(dw, str, DW_AT_byte_size, &sz, DW_ATTR_REQ); 952178481Sjb tdp->t_size = sz; 953178481Sjb 954178481Sjb /* 955178481Sjb * GCC allows empty SOUs as an extension. 956178481Sjb */ 957178545Sjb if ((mem = die_child(dw, str)) == NULL) { 958178481Sjb goto out; 959178545Sjb } 960178481Sjb 961178481Sjb mlastp = &tdp->t_members; 962178481Sjb 963178481Sjb do { 964178481Sjb Dwarf_Off memoff = die_off(dw, mem); 965178481Sjb Dwarf_Half tag = die_tag(dw, mem); 966178481Sjb Dwarf_Unsigned mloff; 967178481Sjb 968178481Sjb if (tag != DW_TAG_member) { 969178481Sjb /* Nested type declaration */ 970178481Sjb die_create_one(dw, mem); 971178481Sjb continue; 972178481Sjb } 973178481Sjb 974178481Sjb debug(3, "die %llu: mem %llu: creating member\n", off, memoff); 975178481Sjb 976178481Sjb ml = xcalloc(sizeof (mlist_t)); 977178481Sjb 978178481Sjb /* 979178481Sjb * This could be a GCC anon struct/union member, so we'll allow 980178481Sjb * an empty name, even though nothing can really handle them 981178481Sjb * properly. Note that some versions of GCC miss out debug 982178481Sjb * info for anon structs, though recent versions are fixed (gcc 983178481Sjb * bug 11816). 984178481Sjb */ 985178481Sjb if ((ml->ml_name = die_name(dw, mem)) == NULL) 986178545Sjb ml->ml_name = NULL; 987178481Sjb 988178481Sjb ml->ml_type = die_lookup_pass1(dw, mem, DW_AT_type); 989253661Spfg debug(3, "die_sou_create(): ml_type = %p t_id = %d\n", 990253661Spfg ml->ml_type, ml->ml_type->t_id); 991178481Sjb 992178481Sjb if (die_mem_offset(dw, mem, DW_AT_data_member_location, 993178481Sjb &mloff, 0)) { 994178481Sjb debug(3, "die %llu: got mloff %llx\n", off, 995178481Sjb (u_longlong_t)mloff); 996178481Sjb ml->ml_offset = mloff * 8; 997178481Sjb } 998178481Sjb 999178481Sjb if (die_unsigned(dw, mem, DW_AT_bit_size, &bitsz, 0)) 1000178481Sjb ml->ml_size = bitsz; 1001178481Sjb else 1002178481Sjb ml->ml_size = tdesc_bitsize(ml->ml_type); 1003178481Sjb 1004178481Sjb if (die_unsigned(dw, mem, DW_AT_bit_offset, &bitoff, 0)) { 1005178545Sjb#if BYTE_ORDER == _BIG_ENDIAN 1006178481Sjb ml->ml_offset += bitoff; 1007178481Sjb#else 1008263915Sdim /* 1009263915Sdim * Note that Clang 3.4 will sometimes generate 1010263915Sdim * member DIE before generating the DIE for the 1011263915Sdim * member's type. The code can not handle this 1012263915Sdim * properly so that tdesc_bitsize(ml->ml_type) will 1013263915Sdim * return 0 because ml->ml_type is unknown. As a 1014263915Sdim * result, a wrong member offset will be calculated. 1015263915Sdim * To workaround this, we can instead try to 1016263915Sdim * retrieve the value of DW_AT_byte_size attribute 1017263915Sdim * which stores the byte size of the space occupied 1018263915Sdim * by the type. If this attribute exists, its value 1019263915Sdim * should equal to tdesc_bitsize(ml->ml_type)/NBBY. 1020263915Sdim */ 1021263915Sdim if (die_unsigned(dw, mem, DW_AT_byte_size, &bysz, 0) && 1022263915Sdim bysz > 0) 1023263915Sdim ml->ml_offset += bysz * NBBY - bitoff - 1024263915Sdim ml->ml_size; 1025263915Sdim else 1026263915Sdim ml->ml_offset += tdesc_bitsize(ml->ml_type) - 1027263915Sdim bitoff - ml->ml_size; 1028178481Sjb#endif 1029178481Sjb } 1030178481Sjb 1031178481Sjb debug(3, "die %llu: mem %llu: created \"%s\" (off %u sz %u)\n", 1032178481Sjb off, memoff, ml->ml_name, ml->ml_offset, ml->ml_size); 1033178481Sjb 1034178481Sjb *mlastp = ml; 1035178481Sjb mlastp = &ml->ml_next; 1036253661Spfg 1037253661Spfg /* Find the size of the largest member to work around a gcc 1038253661Spfg * bug. See GCC Bugzilla 35998. 1039253661Spfg */ 1040253661Spfg if (maxsz < ml->ml_size) 1041253661Spfg maxsz = ml->ml_size; 1042253661Spfg 1043178481Sjb } while ((mem = die_sibling(dw, mem)) != NULL); 1044178481Sjb 1045253661Spfg /* See if we got a bogus DW_AT_byte_size. GCC will sometimes 1046253661Spfg * emit this. 1047253661Spfg */ 1048253661Spfg if (sz == (unsigned)-1) { 1049253661Spfg printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n", 1050253661Spfg __func__); 1051253661Spfg tdp->t_size = maxsz / 8; /* maxsz is in bits, t_size is bytes */ 1052253661Spfg } 1053253661Spfg 1054178481Sjb /* 1055178481Sjb * GCC will attempt to eliminate unused types, thus decreasing the 1056178481Sjb * size of the emitted dwarf. That is, if you declare a foo_t in your 1057178481Sjb * header, include said header in your source file, and neglect to 1058178481Sjb * actually use (directly or indirectly) the foo_t in the source file, 1059178481Sjb * the foo_t won't make it into the emitted DWARF. So, at least, goes 1060178481Sjb * the theory. 1061178481Sjb * 1062178481Sjb * Occasionally, it'll emit the DW_TAG_structure_type for the foo_t, 1063178481Sjb * and then neglect to emit the members. Strangely, the loner struct 1064178481Sjb * tag will always be followed by a proper nested declaration of 1065178481Sjb * something else. This is clearly a bug, but we're not going to have 1066178481Sjb * time to get it fixed before this goo goes back, so we'll have to work 1067178481Sjb * around it. If we see a no-membered struct with a nested declaration 1068178481Sjb * (i.e. die_child of the struct tag won't be null), we'll ignore it. 1069178481Sjb * Being paranoid, we won't simply remove it from the hash. Instead, 1070178481Sjb * we'll decline to create an iidesc for it, thus ensuring that this 1071178481Sjb * type won't make it into the output file. To be safe, we'll also 1072178481Sjb * change the name. 1073178481Sjb */ 1074178481Sjb if (tdp->t_members == NULL) { 1075178481Sjb const char *old = tdesc_name(tdp); 1076178481Sjb size_t newsz = 7 + strlen(old) + 1; 1077178481Sjb char *new = xmalloc(newsz); 1078178481Sjb (void) snprintf(new, newsz, "orphan %s", old); 1079178481Sjb 1080178481Sjb debug(3, "die %llu: worked around %s %s\n", off, typename, old); 1081178481Sjb 1082178481Sjb if (tdp->t_name != NULL) 1083178481Sjb free(tdp->t_name); 1084178481Sjb tdp->t_name = new; 1085178481Sjb return; 1086178481Sjb } 1087178481Sjb 1088178481Sjbout: 1089178481Sjb if (tdp->t_name != NULL) { 1090178481Sjb ii = xcalloc(sizeof (iidesc_t)); 1091178481Sjb ii->ii_type = II_SOU; 1092178481Sjb ii->ii_name = xstrdup(tdp->t_name); 1093178481Sjb ii->ii_dtype = tdp; 1094178481Sjb 1095178481Sjb iidesc_add(dw->dw_td->td_iihash, ii); 1096178481Sjb } 1097178481Sjb} 1098178481Sjb 1099178481Sjbstatic void 1100178481Sjbdie_struct_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1101178481Sjb{ 1102178481Sjb die_sou_create(dw, die, off, tdp, STRUCT, "struct"); 1103178481Sjb} 1104178481Sjb 1105178481Sjbstatic void 1106178481Sjbdie_union_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1107178481Sjb{ 1108178481Sjb die_sou_create(dw, die, off, tdp, UNION, "union"); 1109178481Sjb} 1110178481Sjb 1111178481Sjb/*ARGSUSED1*/ 1112178481Sjbstatic int 1113178545Sjbdie_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private) 1114178481Sjb{ 1115178481Sjb dwarf_t *dw = private; 1116178481Sjb mlist_t *ml; 1117178481Sjb tdesc_t *mt; 1118178481Sjb 1119178481Sjb if (tdp->t_flags & TDESC_F_RESOLVED) 1120178481Sjb return (1); 1121178481Sjb 1122178481Sjb debug(3, "resolving sou %s\n", tdesc_name(tdp)); 1123178481Sjb 1124178481Sjb for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) { 1125178481Sjb if (ml->ml_size == 0) { 1126178481Sjb mt = tdesc_basetype(ml->ml_type); 1127178481Sjb 1128178481Sjb if ((ml->ml_size = tdesc_bitsize(mt)) != 0) 1129178481Sjb continue; 1130178481Sjb 1131178481Sjb /* 1132178481Sjb * For empty members, or GCC/C99 flexible array 1133178481Sjb * members, a size of 0 is correct. 1134178481Sjb */ 1135178481Sjb if (mt->t_members == NULL) 1136178481Sjb continue; 1137178481Sjb if (mt->t_type == ARRAY && mt->t_ardef->ad_nelems == 0) 1138178481Sjb continue; 1139178481Sjb 1140178481Sjb dw->dw_nunres++; 1141178481Sjb return (1); 1142178481Sjb } 1143178481Sjb 1144178481Sjb if ((mt = tdesc_basetype(ml->ml_type)) == NULL) { 1145178481Sjb dw->dw_nunres++; 1146178481Sjb return (1); 1147178481Sjb } 1148178481Sjb 1149178481Sjb if (ml->ml_size != 0 && mt->t_type == INTRINSIC && 1150253661Spfg mt->t_intr->intr_nbits != (int)ml->ml_size) { 1151178481Sjb /* 1152178481Sjb * This member is a bitfield, and needs to reference 1153178481Sjb * an intrinsic type with the same width. If the 1154178481Sjb * currently-referenced type isn't of the same width, 1155178481Sjb * we'll copy it, adjusting the width of the copy to 1156178481Sjb * the size we'd like. 1157178481Sjb */ 1158178481Sjb debug(3, "tdp %u: creating bitfield for %d bits\n", 1159178481Sjb tdp->t_id, ml->ml_size); 1160178481Sjb 1161178481Sjb ml->ml_type = tdesc_intr_clone(dw, mt, ml->ml_size); 1162178481Sjb } 1163178481Sjb } 1164178481Sjb 1165178481Sjb tdp->t_flags |= TDESC_F_RESOLVED; 1166178481Sjb 1167178481Sjb return (1); 1168178481Sjb} 1169178481Sjb 1170178481Sjb/*ARGSUSED1*/ 1171178481Sjbstatic int 1172178545Sjbdie_sou_failed(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private __unused) 1173178481Sjb{ 1174178481Sjb const char *typename = (tdp->t_type == STRUCT ? "struct" : "union"); 1175178481Sjb mlist_t *ml; 1176178481Sjb 1177178481Sjb if (tdp->t_flags & TDESC_F_RESOLVED) 1178178481Sjb return (1); 1179178481Sjb 1180178481Sjb for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) { 1181178481Sjb if (ml->ml_size == 0) { 1182178545Sjb fprintf(stderr, "%s %d <%x>: failed to size member \"%s\" " 1183178545Sjb "of type %s (%d <%x>)\n", typename, tdp->t_id, 1184178545Sjb tdp->t_id, 1185178481Sjb ml->ml_name, tdesc_name(ml->ml_type), 1186178545Sjb ml->ml_type->t_id, ml->ml_type->t_id); 1187178481Sjb } 1188178481Sjb } 1189178481Sjb 1190178481Sjb return (1); 1191178481Sjb} 1192178481Sjb 1193178481Sjbstatic void 1194178481Sjbdie_funcptr_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1195178481Sjb{ 1196178481Sjb Dwarf_Attribute attr; 1197178481Sjb Dwarf_Half tag; 1198178481Sjb Dwarf_Die arg; 1199178481Sjb fndef_t *fn; 1200178481Sjb int i; 1201178481Sjb 1202178545Sjb debug(3, "die %llu <%llx>: creating function pointer\n", off, off); 1203178481Sjb 1204178481Sjb /* 1205178481Sjb * We'll begin by processing any type definition nodes that may be 1206178481Sjb * lurking underneath this one. 1207178481Sjb */ 1208178481Sjb for (arg = die_child(dw, die); arg != NULL; 1209178481Sjb arg = die_sibling(dw, arg)) { 1210178481Sjb if ((tag = die_tag(dw, arg)) != DW_TAG_formal_parameter && 1211178481Sjb tag != DW_TAG_unspecified_parameters) { 1212178481Sjb /* Nested type declaration */ 1213178481Sjb die_create_one(dw, arg); 1214178481Sjb } 1215178481Sjb } 1216178481Sjb 1217178481Sjb if (die_isdecl(dw, die)) { 1218178481Sjb /* 1219178481Sjb * This is a prototype. We don't add prototypes to the 1220178481Sjb * tree, so we're going to drop the tdesc. Unfortunately, 1221178481Sjb * it has already been added to the tree. Nobody will reference 1222178481Sjb * it, though, and it will be leaked. 1223178481Sjb */ 1224178481Sjb return; 1225178481Sjb } 1226178481Sjb 1227178481Sjb fn = xcalloc(sizeof (fndef_t)); 1228178481Sjb 1229178481Sjb tdp->t_type = FUNCTION; 1230178481Sjb 1231178481Sjb if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) { 1232178481Sjb fn->fn_ret = die_lookup_pass1(dw, die, DW_AT_type); 1233178481Sjb } else { 1234178481Sjb fn->fn_ret = tdesc_intr_void(dw); 1235178481Sjb } 1236178481Sjb 1237178481Sjb /* 1238178481Sjb * Count the arguments to the function, then read them in. 1239178481Sjb */ 1240178481Sjb for (fn->fn_nargs = 0, arg = die_child(dw, die); arg != NULL; 1241178481Sjb arg = die_sibling(dw, arg)) { 1242178481Sjb if ((tag = die_tag(dw, arg)) == DW_TAG_formal_parameter) 1243178481Sjb fn->fn_nargs++; 1244178481Sjb else if (tag == DW_TAG_unspecified_parameters && 1245178481Sjb fn->fn_nargs > 0) 1246178481Sjb fn->fn_vargs = 1; 1247178481Sjb } 1248178481Sjb 1249178481Sjb if (fn->fn_nargs != 0) { 1250178481Sjb debug(3, "die %llu: adding %d argument%s\n", off, fn->fn_nargs, 1251178481Sjb (fn->fn_nargs > 1 ? "s" : "")); 1252178481Sjb 1253178481Sjb fn->fn_args = xcalloc(sizeof (tdesc_t *) * fn->fn_nargs); 1254178481Sjb for (i = 0, arg = die_child(dw, die); 1255178545Sjb arg != NULL && i < (int) fn->fn_nargs; 1256178481Sjb arg = die_sibling(dw, arg)) { 1257178481Sjb if (die_tag(dw, arg) != DW_TAG_formal_parameter) 1258178481Sjb continue; 1259178481Sjb 1260178481Sjb fn->fn_args[i++] = die_lookup_pass1(dw, arg, 1261178481Sjb DW_AT_type); 1262178481Sjb } 1263178481Sjb } 1264178481Sjb 1265178481Sjb tdp->t_fndef = fn; 1266178481Sjb tdp->t_flags |= TDESC_F_RESOLVED; 1267178481Sjb} 1268178481Sjb 1269178481Sjb/* 1270178481Sjb * GCC and DevPro use different names for the base types. While the terms are 1271178481Sjb * the same, they are arranged in a different order. Some terms, such as int, 1272178481Sjb * are implied in one, and explicitly named in the other. Given a base type 1273178481Sjb * as input, this routine will return a common name, along with an intr_t 1274178481Sjb * that reflects said name. 1275178481Sjb */ 1276178481Sjbstatic intr_t * 1277178481Sjbdie_base_name_parse(const char *name, char **newp) 1278178481Sjb{ 1279178481Sjb char buf[100]; 1280178545Sjb char const *base; 1281178545Sjb char *c; 1282178481Sjb int nlong = 0, nshort = 0, nchar = 0, nint = 0; 1283178481Sjb int sign = 1; 1284178481Sjb char fmt = '\0'; 1285178481Sjb intr_t *intr; 1286178481Sjb 1287178481Sjb if (strlen(name) > sizeof (buf) - 1) 1288178481Sjb terminate("base type name \"%s\" is too long\n", name); 1289178481Sjb 1290178481Sjb strncpy(buf, name, sizeof (buf)); 1291178481Sjb 1292178481Sjb for (c = strtok(buf, " "); c != NULL; c = strtok(NULL, " ")) { 1293178481Sjb if (strcmp(c, "signed") == 0) 1294178481Sjb sign = 1; 1295178481Sjb else if (strcmp(c, "unsigned") == 0) 1296178481Sjb sign = 0; 1297178481Sjb else if (strcmp(c, "long") == 0) 1298178481Sjb nlong++; 1299178481Sjb else if (strcmp(c, "char") == 0) { 1300178481Sjb nchar++; 1301178481Sjb fmt = 'c'; 1302178481Sjb } else if (strcmp(c, "short") == 0) 1303178481Sjb nshort++; 1304178481Sjb else if (strcmp(c, "int") == 0) 1305178481Sjb nint++; 1306178481Sjb else { 1307178481Sjb /* 1308178481Sjb * If we don't recognize any of the tokens, we'll tell 1309178481Sjb * the caller to fall back to the dwarf-provided 1310178481Sjb * encoding information. 1311178481Sjb */ 1312178481Sjb return (NULL); 1313178481Sjb } 1314178481Sjb } 1315178481Sjb 1316178481Sjb if (nchar > 1 || nshort > 1 || nint > 1 || nlong > 2) 1317178481Sjb return (NULL); 1318178481Sjb 1319178481Sjb if (nchar > 0) { 1320178481Sjb if (nlong > 0 || nshort > 0 || nint > 0) 1321178481Sjb return (NULL); 1322178481Sjb 1323178481Sjb base = "char"; 1324178481Sjb 1325178481Sjb } else if (nshort > 0) { 1326178481Sjb if (nlong > 0) 1327178481Sjb return (NULL); 1328178481Sjb 1329178481Sjb base = "short"; 1330178481Sjb 1331178481Sjb } else if (nlong > 0) { 1332178481Sjb base = "long"; 1333178481Sjb 1334178481Sjb } else { 1335178481Sjb base = "int"; 1336178481Sjb } 1337178481Sjb 1338178481Sjb intr = xcalloc(sizeof (intr_t)); 1339178481Sjb intr->intr_type = INTR_INT; 1340178481Sjb intr->intr_signed = sign; 1341178481Sjb intr->intr_iformat = fmt; 1342178481Sjb 1343178481Sjb snprintf(buf, sizeof (buf), "%s%s%s", 1344178481Sjb (sign ? "" : "unsigned "), 1345178481Sjb (nlong > 1 ? "long " : ""), 1346178481Sjb base); 1347178481Sjb 1348178481Sjb *newp = xstrdup(buf); 1349178481Sjb return (intr); 1350178481Sjb} 1351178481Sjb 1352178481Sjbtypedef struct fp_size_map { 1353178481Sjb size_t fsm_typesz[2]; /* size of {32,64} type */ 1354178481Sjb uint_t fsm_enc[3]; /* CTF_FP_* for {bare,cplx,imagry} type */ 1355178481Sjb} fp_size_map_t; 1356178481Sjb 1357178481Sjbstatic const fp_size_map_t fp_encodings[] = { 1358178481Sjb { { 4, 4 }, { CTF_FP_SINGLE, CTF_FP_CPLX, CTF_FP_IMAGRY } }, 1359178481Sjb { { 8, 8 }, { CTF_FP_DOUBLE, CTF_FP_DCPLX, CTF_FP_DIMAGRY } }, 1360178481Sjb#ifdef __sparc 1361178481Sjb { { 16, 16 }, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } }, 1362178481Sjb#else 1363178481Sjb { { 12, 16 }, { CTF_FP_LDOUBLE, CTF_FP_LDCPLX, CTF_FP_LDIMAGRY } }, 1364178481Sjb#endif 1365178545Sjb { { 0, 0 }, { 0, 0, 0 } } 1366178481Sjb}; 1367178481Sjb 1368178481Sjbstatic uint_t 1369178481Sjbdie_base_type2enc(dwarf_t *dw, Dwarf_Off off, Dwarf_Signed enc, size_t sz) 1370178481Sjb{ 1371178481Sjb const fp_size_map_t *map = fp_encodings; 1372178481Sjb uint_t szidx = dw->dw_ptrsz == sizeof (uint64_t); 1373178481Sjb uint_t mult = 1, col = 0; 1374178481Sjb 1375178481Sjb if (enc == DW_ATE_complex_float) { 1376178481Sjb mult = 2; 1377178481Sjb col = 1; 1378178545Sjb } else if (enc == DW_ATE_imaginary_float 1379178545Sjb#if defined(sun) 1380178545Sjb || enc == DW_ATE_SUN_imaginary_float 1381178545Sjb#endif 1382178545Sjb ) 1383178481Sjb col = 2; 1384178481Sjb 1385178481Sjb while (map->fsm_typesz[szidx] != 0) { 1386178481Sjb if (map->fsm_typesz[szidx] * mult == sz) 1387178481Sjb return (map->fsm_enc[col]); 1388178481Sjb map++; 1389178481Sjb } 1390178481Sjb 1391178481Sjb terminate("die %llu: unrecognized real type size %u\n", off, sz); 1392178481Sjb /*NOTREACHED*/ 1393178481Sjb return (0); 1394178481Sjb} 1395178481Sjb 1396178481Sjbstatic intr_t * 1397178481Sjbdie_base_from_dwarf(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, size_t sz) 1398178481Sjb{ 1399178481Sjb intr_t *intr = xcalloc(sizeof (intr_t)); 1400178481Sjb Dwarf_Signed enc; 1401178481Sjb 1402178481Sjb (void) die_signed(dw, base, DW_AT_encoding, &enc, DW_ATTR_REQ); 1403178481Sjb 1404178481Sjb switch (enc) { 1405178481Sjb case DW_ATE_unsigned: 1406178481Sjb case DW_ATE_address: 1407178481Sjb intr->intr_type = INTR_INT; 1408178481Sjb break; 1409178481Sjb case DW_ATE_unsigned_char: 1410178481Sjb intr->intr_type = INTR_INT; 1411178481Sjb intr->intr_iformat = 'c'; 1412178481Sjb break; 1413178481Sjb case DW_ATE_signed: 1414178481Sjb intr->intr_type = INTR_INT; 1415178481Sjb intr->intr_signed = 1; 1416178481Sjb break; 1417178481Sjb case DW_ATE_signed_char: 1418178481Sjb intr->intr_type = INTR_INT; 1419178481Sjb intr->intr_signed = 1; 1420178481Sjb intr->intr_iformat = 'c'; 1421178481Sjb break; 1422178481Sjb case DW_ATE_boolean: 1423178481Sjb intr->intr_type = INTR_INT; 1424178481Sjb intr->intr_signed = 1; 1425178481Sjb intr->intr_iformat = 'b'; 1426178481Sjb break; 1427178481Sjb case DW_ATE_float: 1428178481Sjb case DW_ATE_complex_float: 1429178481Sjb case DW_ATE_imaginary_float: 1430178545Sjb#if defined(sun) 1431178481Sjb case DW_ATE_SUN_imaginary_float: 1432178481Sjb case DW_ATE_SUN_interval_float: 1433178545Sjb#endif 1434178481Sjb intr->intr_type = INTR_REAL; 1435178481Sjb intr->intr_signed = 1; 1436178481Sjb intr->intr_fformat = die_base_type2enc(dw, off, enc, sz); 1437178481Sjb break; 1438178481Sjb default: 1439178481Sjb terminate("die %llu: unknown base type encoding 0x%llx\n", 1440178481Sjb off, enc); 1441178481Sjb } 1442178481Sjb 1443178481Sjb return (intr); 1444178481Sjb} 1445178481Sjb 1446178481Sjbstatic void 1447178481Sjbdie_base_create(dwarf_t *dw, Dwarf_Die base, Dwarf_Off off, tdesc_t *tdp) 1448178481Sjb{ 1449178481Sjb Dwarf_Unsigned sz; 1450178481Sjb intr_t *intr; 1451178481Sjb char *new; 1452178481Sjb 1453178481Sjb debug(3, "die %llu: creating base type\n", off); 1454178481Sjb 1455178481Sjb /* 1456178481Sjb * The compilers have their own clever (internally inconsistent) ideas 1457178481Sjb * as to what base types should look like. Some times gcc will, for 1458178481Sjb * example, use DW_ATE_signed_char for char. Other times, however, it 1459178481Sjb * will use DW_ATE_signed. Needless to say, this causes some problems 1460178481Sjb * down the road, particularly with merging. We do, however, use the 1461178481Sjb * DWARF idea of type sizes, as this allows us to avoid caring about 1462178481Sjb * the data model. 1463178481Sjb */ 1464178481Sjb (void) die_unsigned(dw, base, DW_AT_byte_size, &sz, DW_ATTR_REQ); 1465178481Sjb 1466253661Spfg /* Check for bogus gcc DW_AT_byte_size attribute */ 1467253661Spfg if (sz == (unsigned)-1) { 1468253661Spfg printf("dwarf.c:%s() working around bogus -1 DW_AT_byte_size\n", 1469253661Spfg __func__); 1470253661Spfg sz = 0; 1471253661Spfg } 1472253661Spfg 1473178481Sjb if (tdp->t_name == NULL) 1474178481Sjb terminate("die %llu: base type without name\n", off); 1475178481Sjb 1476178481Sjb /* XXX make a name parser for float too */ 1477178481Sjb if ((intr = die_base_name_parse(tdp->t_name, &new)) != NULL) { 1478178481Sjb /* Found it. We'll use the parsed version */ 1479178481Sjb debug(3, "die %llu: name \"%s\" remapped to \"%s\"\n", off, 1480178481Sjb tdesc_name(tdp), new); 1481178481Sjb 1482178481Sjb free(tdp->t_name); 1483178481Sjb tdp->t_name = new; 1484178481Sjb } else { 1485178481Sjb /* 1486178481Sjb * We didn't recognize the type, so we'll create an intr_t 1487178481Sjb * based on the DWARF data. 1488178481Sjb */ 1489178481Sjb debug(3, "die %llu: using dwarf data for base \"%s\"\n", off, 1490178481Sjb tdesc_name(tdp)); 1491178481Sjb 1492178481Sjb intr = die_base_from_dwarf(dw, base, off, sz); 1493178481Sjb } 1494178481Sjb 1495178481Sjb intr->intr_nbits = sz * 8; 1496178481Sjb 1497178481Sjb tdp->t_type = INTRINSIC; 1498178481Sjb tdp->t_intr = intr; 1499178481Sjb tdp->t_size = sz; 1500178481Sjb 1501178481Sjb tdp->t_flags |= TDESC_F_RESOLVED; 1502178481Sjb} 1503178481Sjb 1504178481Sjbstatic void 1505178481Sjbdie_through_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp, 1506178481Sjb int type, const char *typename) 1507178481Sjb{ 1508178481Sjb Dwarf_Attribute attr; 1509178481Sjb 1510178545Sjb debug(3, "die %llu <%llx>: creating %s type %d\n", off, off, typename, type); 1511178481Sjb 1512178481Sjb tdp->t_type = type; 1513178481Sjb 1514178481Sjb if ((attr = die_attr(dw, die, DW_AT_type, 0)) != NULL) { 1515178481Sjb tdp->t_tdesc = die_lookup_pass1(dw, die, DW_AT_type); 1516178481Sjb } else { 1517178481Sjb tdp->t_tdesc = tdesc_intr_void(dw); 1518178481Sjb } 1519178481Sjb 1520178481Sjb if (type == POINTER) 1521178481Sjb tdp->t_size = dw->dw_ptrsz; 1522178481Sjb 1523178481Sjb tdp->t_flags |= TDESC_F_RESOLVED; 1524178481Sjb 1525178481Sjb if (type == TYPEDEF) { 1526178481Sjb iidesc_t *ii = xcalloc(sizeof (iidesc_t)); 1527178481Sjb ii->ii_type = II_TYPE; 1528178481Sjb ii->ii_name = xstrdup(tdp->t_name); 1529178481Sjb ii->ii_dtype = tdp; 1530178481Sjb 1531178481Sjb iidesc_add(dw->dw_td->td_iihash, ii); 1532178481Sjb } 1533178481Sjb} 1534178481Sjb 1535178481Sjbstatic void 1536178481Sjbdie_typedef_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1537178481Sjb{ 1538178481Sjb die_through_create(dw, die, off, tdp, TYPEDEF, "typedef"); 1539178481Sjb} 1540178481Sjb 1541178481Sjbstatic void 1542178481Sjbdie_const_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1543178481Sjb{ 1544178481Sjb die_through_create(dw, die, off, tdp, CONST, "const"); 1545178481Sjb} 1546178481Sjb 1547178481Sjbstatic void 1548178481Sjbdie_pointer_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1549178481Sjb{ 1550178481Sjb die_through_create(dw, die, off, tdp, POINTER, "pointer"); 1551178481Sjb} 1552178481Sjb 1553178481Sjbstatic void 1554178481Sjbdie_restrict_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1555178481Sjb{ 1556178481Sjb die_through_create(dw, die, off, tdp, RESTRICT, "restrict"); 1557178481Sjb} 1558178481Sjb 1559178481Sjbstatic void 1560178481Sjbdie_volatile_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp) 1561178481Sjb{ 1562178481Sjb die_through_create(dw, die, off, tdp, VOLATILE, "volatile"); 1563178481Sjb} 1564178481Sjb 1565178481Sjb/*ARGSUSED3*/ 1566178481Sjbstatic void 1567178545Sjbdie_function_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp __unused) 1568178481Sjb{ 1569178481Sjb Dwarf_Die arg; 1570178481Sjb Dwarf_Half tag; 1571178481Sjb iidesc_t *ii; 1572178481Sjb char *name; 1573178481Sjb 1574178545Sjb debug(3, "die %llu <%llx>: creating function definition\n", off, off); 1575178481Sjb 1576178481Sjb /* 1577178481Sjb * We'll begin by processing any type definition nodes that may be 1578178481Sjb * lurking underneath this one. 1579178481Sjb */ 1580178481Sjb for (arg = die_child(dw, die); arg != NULL; 1581178481Sjb arg = die_sibling(dw, arg)) { 1582178481Sjb if ((tag = die_tag(dw, arg)) != DW_TAG_formal_parameter && 1583178481Sjb tag != DW_TAG_variable) { 1584178481Sjb /* Nested type declaration */ 1585178481Sjb die_create_one(dw, arg); 1586178481Sjb } 1587178481Sjb } 1588178481Sjb 1589178481Sjb if (die_isdecl(dw, die) || (name = die_name(dw, die)) == NULL) { 1590178481Sjb /* 1591178481Sjb * We process neither prototypes nor subprograms without 1592178481Sjb * names. 1593178481Sjb */ 1594178481Sjb return; 1595178481Sjb } 1596178481Sjb 1597178481Sjb ii = xcalloc(sizeof (iidesc_t)); 1598178481Sjb ii->ii_type = die_isglobal(dw, die) ? II_GFUN : II_SFUN; 1599178481Sjb ii->ii_name = name; 1600178481Sjb if (ii->ii_type == II_SFUN) 1601178481Sjb ii->ii_owner = xstrdup(dw->dw_cuname); 1602178481Sjb 1603178481Sjb debug(3, "die %llu: function %s is %s\n", off, ii->ii_name, 1604178481Sjb (ii->ii_type == II_GFUN ? "global" : "static")); 1605178481Sjb 1606178481Sjb if (die_attr(dw, die, DW_AT_type, 0) != NULL) 1607178481Sjb ii->ii_dtype = die_lookup_pass1(dw, die, DW_AT_type); 1608178481Sjb else 1609178481Sjb ii->ii_dtype = tdesc_intr_void(dw); 1610178481Sjb 1611178481Sjb for (arg = die_child(dw, die); arg != NULL; 1612178481Sjb arg = die_sibling(dw, arg)) { 1613178545Sjb char *name1; 1614178481Sjb 1615178481Sjb debug(3, "die %llu: looking at sub member at %llu\n", 1616178481Sjb off, die_off(dw, die)); 1617178481Sjb 1618178481Sjb if (die_tag(dw, arg) != DW_TAG_formal_parameter) 1619178481Sjb continue; 1620178481Sjb 1621178545Sjb if ((name1 = die_name(dw, arg)) == NULL) { 1622178481Sjb terminate("die %llu: func arg %d has no name\n", 1623178481Sjb off, ii->ii_nargs + 1); 1624178481Sjb } 1625178481Sjb 1626178545Sjb if (strcmp(name1, "...") == 0) { 1627178545Sjb free(name1); 1628178481Sjb ii->ii_vargs = 1; 1629178481Sjb continue; 1630178481Sjb } 1631178481Sjb 1632178481Sjb ii->ii_nargs++; 1633178481Sjb } 1634178481Sjb 1635178481Sjb if (ii->ii_nargs > 0) { 1636178481Sjb int i; 1637178481Sjb 1638178481Sjb debug(3, "die %llu: function has %d argument%s\n", off, 1639178481Sjb ii->ii_nargs, (ii->ii_nargs == 1 ? "" : "s")); 1640178481Sjb 1641178481Sjb ii->ii_args = xcalloc(sizeof (tdesc_t) * ii->ii_nargs); 1642178481Sjb 1643178481Sjb for (arg = die_child(dw, die), i = 0; 1644178481Sjb arg != NULL && i < ii->ii_nargs; 1645178481Sjb arg = die_sibling(dw, arg)) { 1646178481Sjb if (die_tag(dw, arg) != DW_TAG_formal_parameter) 1647178481Sjb continue; 1648178481Sjb 1649178481Sjb ii->ii_args[i++] = die_lookup_pass1(dw, arg, 1650178481Sjb DW_AT_type); 1651178481Sjb } 1652178481Sjb } 1653178481Sjb 1654178481Sjb iidesc_add(dw->dw_td->td_iihash, ii); 1655178481Sjb} 1656178481Sjb 1657178481Sjb/*ARGSUSED3*/ 1658178481Sjbstatic void 1659178545Sjbdie_variable_create(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off, tdesc_t *tdp __unused) 1660178481Sjb{ 1661178481Sjb iidesc_t *ii; 1662178481Sjb char *name; 1663178481Sjb 1664178481Sjb debug(3, "die %llu: creating object definition\n", off); 1665178481Sjb 1666178481Sjb if (die_isdecl(dw, die) || (name = die_name(dw, die)) == NULL) 1667178481Sjb return; /* skip prototypes and nameless objects */ 1668178481Sjb 1669178481Sjb ii = xcalloc(sizeof (iidesc_t)); 1670178481Sjb ii->ii_type = die_isglobal(dw, die) ? II_GVAR : II_SVAR; 1671178481Sjb ii->ii_name = name; 1672178481Sjb ii->ii_dtype = die_lookup_pass1(dw, die, DW_AT_type); 1673178481Sjb if (ii->ii_type == II_SVAR) 1674178481Sjb ii->ii_owner = xstrdup(dw->dw_cuname); 1675178481Sjb 1676178481Sjb iidesc_add(dw->dw_td->td_iihash, ii); 1677178481Sjb} 1678178481Sjb 1679178481Sjb/*ARGSUSED2*/ 1680178481Sjbstatic int 1681178545Sjbdie_fwd_resolve(tdesc_t *fwd, tdesc_t **fwdp, void *private __unused) 1682178481Sjb{ 1683178481Sjb if (fwd->t_flags & TDESC_F_RESOLVED) 1684178481Sjb return (1); 1685178481Sjb 1686178481Sjb if (fwd->t_tdesc != NULL) { 1687178481Sjb debug(3, "tdp %u: unforwarded %s\n", fwd->t_id, 1688178481Sjb tdesc_name(fwd)); 1689178481Sjb *fwdp = fwd->t_tdesc; 1690178481Sjb } 1691178481Sjb 1692178481Sjb fwd->t_flags |= TDESC_F_RESOLVED; 1693178481Sjb 1694178481Sjb return (1); 1695178481Sjb} 1696178481Sjb 1697178481Sjb/*ARGSUSED*/ 1698178481Sjbstatic void 1699178545Sjbdie_lexblk_descend(dwarf_t *dw, Dwarf_Die die, Dwarf_Off off __unused, tdesc_t *tdp __unused) 1700178481Sjb{ 1701178481Sjb Dwarf_Die child = die_child(dw, die); 1702178481Sjb 1703178481Sjb if (child != NULL) 1704178481Sjb die_create(dw, child); 1705178481Sjb} 1706178481Sjb 1707178481Sjb/* 1708178481Sjb * Used to map the die to a routine which can parse it, using the tag to do the 1709178481Sjb * mapping. While the processing of most tags entails the creation of a tdesc, 1710178481Sjb * there are a few which don't - primarily those which result in the creation of 1711178481Sjb * iidescs which refer to existing tdescs. 1712178481Sjb */ 1713178481Sjb 1714178481Sjb#define DW_F_NOTDP 0x1 /* Don't create a tdesc for the creator */ 1715178481Sjb 1716178481Sjbtypedef struct die_creator { 1717178481Sjb Dwarf_Half dc_tag; 1718178481Sjb uint16_t dc_flags; 1719178481Sjb void (*dc_create)(dwarf_t *, Dwarf_Die, Dwarf_Off, tdesc_t *); 1720178481Sjb} die_creator_t; 1721178481Sjb 1722178481Sjbstatic const die_creator_t die_creators[] = { 1723178481Sjb { DW_TAG_array_type, 0, die_array_create }, 1724178481Sjb { DW_TAG_enumeration_type, 0, die_enum_create }, 1725178481Sjb { DW_TAG_lexical_block, DW_F_NOTDP, die_lexblk_descend }, 1726178481Sjb { DW_TAG_pointer_type, 0, die_pointer_create }, 1727178481Sjb { DW_TAG_structure_type, 0, die_struct_create }, 1728178481Sjb { DW_TAG_subroutine_type, 0, die_funcptr_create }, 1729178481Sjb { DW_TAG_typedef, 0, die_typedef_create }, 1730178481Sjb { DW_TAG_union_type, 0, die_union_create }, 1731178481Sjb { DW_TAG_base_type, 0, die_base_create }, 1732178481Sjb { DW_TAG_const_type, 0, die_const_create }, 1733178481Sjb { DW_TAG_subprogram, DW_F_NOTDP, die_function_create }, 1734178481Sjb { DW_TAG_variable, DW_F_NOTDP, die_variable_create }, 1735178481Sjb { DW_TAG_volatile_type, 0, die_volatile_create }, 1736178481Sjb { DW_TAG_restrict_type, 0, die_restrict_create }, 1737178545Sjb { 0, 0, NULL } 1738178481Sjb}; 1739178481Sjb 1740178481Sjbstatic const die_creator_t * 1741178481Sjbdie_tag2ctor(Dwarf_Half tag) 1742178481Sjb{ 1743178481Sjb const die_creator_t *dc; 1744178481Sjb 1745178481Sjb for (dc = die_creators; dc->dc_create != NULL; dc++) { 1746178481Sjb if (dc->dc_tag == tag) 1747178481Sjb return (dc); 1748178481Sjb } 1749178481Sjb 1750178481Sjb return (NULL); 1751178481Sjb} 1752178481Sjb 1753178481Sjbstatic void 1754178481Sjbdie_create_one(dwarf_t *dw, Dwarf_Die die) 1755178481Sjb{ 1756178481Sjb Dwarf_Off off = die_off(dw, die); 1757178481Sjb const die_creator_t *dc; 1758178481Sjb Dwarf_Half tag; 1759178481Sjb tdesc_t *tdp; 1760178481Sjb 1761178545Sjb debug(3, "die %llu <%llx>: create_one\n", off, off); 1762178481Sjb 1763178481Sjb if (off > dw->dw_maxoff) { 1764178481Sjb terminate("illegal die offset %llu (max %llu)\n", off, 1765178481Sjb dw->dw_maxoff); 1766178481Sjb } 1767178481Sjb 1768178481Sjb tag = die_tag(dw, die); 1769178481Sjb 1770178481Sjb if ((dc = die_tag2ctor(tag)) == NULL) { 1771178481Sjb debug(2, "die %llu: ignoring tag type %x\n", off, tag); 1772178481Sjb return; 1773178481Sjb } 1774178481Sjb 1775178481Sjb if ((tdp = tdesc_lookup(dw, off)) == NULL && 1776178481Sjb !(dc->dc_flags & DW_F_NOTDP)) { 1777178481Sjb tdp = xcalloc(sizeof (tdesc_t)); 1778178481Sjb tdp->t_id = off; 1779178481Sjb tdesc_add(dw, tdp); 1780178481Sjb } 1781178481Sjb 1782178481Sjb if (tdp != NULL) 1783178481Sjb tdp->t_name = die_name(dw, die); 1784178481Sjb 1785178481Sjb dc->dc_create(dw, die, off, tdp); 1786178481Sjb} 1787178481Sjb 1788178481Sjbstatic void 1789178481Sjbdie_create(dwarf_t *dw, Dwarf_Die die) 1790178481Sjb{ 1791178481Sjb do { 1792178481Sjb die_create_one(dw, die); 1793178481Sjb } while ((die = die_sibling(dw, die)) != NULL); 1794178481Sjb} 1795178481Sjb 1796178481Sjbstatic tdtrav_cb_f die_resolvers[] = { 1797178481Sjb NULL, 1798178481Sjb NULL, /* intrinsic */ 1799178481Sjb NULL, /* pointer */ 1800178481Sjb die_array_resolve, /* array */ 1801178481Sjb NULL, /* function */ 1802178481Sjb die_sou_resolve, /* struct */ 1803178481Sjb die_sou_resolve, /* union */ 1804178481Sjb die_enum_resolve, /* enum */ 1805178481Sjb die_fwd_resolve, /* forward */ 1806178481Sjb NULL, /* typedef */ 1807178481Sjb NULL, /* typedef unres */ 1808178481Sjb NULL, /* volatile */ 1809178481Sjb NULL, /* const */ 1810178481Sjb NULL, /* restrict */ 1811178481Sjb}; 1812178481Sjb 1813178481Sjbstatic tdtrav_cb_f die_fail_reporters[] = { 1814178481Sjb NULL, 1815178481Sjb NULL, /* intrinsic */ 1816178481Sjb NULL, /* pointer */ 1817178481Sjb die_array_failed, /* array */ 1818178481Sjb NULL, /* function */ 1819178481Sjb die_sou_failed, /* struct */ 1820178481Sjb die_sou_failed, /* union */ 1821178481Sjb NULL, /* enum */ 1822178481Sjb NULL, /* forward */ 1823178481Sjb NULL, /* typedef */ 1824178481Sjb NULL, /* typedef unres */ 1825178481Sjb NULL, /* volatile */ 1826178481Sjb NULL, /* const */ 1827178481Sjb NULL, /* restrict */ 1828178481Sjb}; 1829178481Sjb 1830178481Sjbstatic void 1831178481Sjbdie_resolve(dwarf_t *dw) 1832178481Sjb{ 1833178481Sjb int last = -1; 1834178481Sjb int pass = 0; 1835178481Sjb 1836178481Sjb do { 1837178481Sjb pass++; 1838178481Sjb dw->dw_nunres = 0; 1839178481Sjb 1840178481Sjb (void) iitraverse_hash(dw->dw_td->td_iihash, 1841178481Sjb &dw->dw_td->td_curvgen, NULL, NULL, die_resolvers, dw); 1842178481Sjb 1843178481Sjb debug(3, "resolve: pass %d, %u left\n", pass, dw->dw_nunres); 1844178481Sjb 1845178545Sjb if ((int) dw->dw_nunres == last) { 1846178481Sjb fprintf(stderr, "%s: failed to resolve the following " 1847178481Sjb "types:\n", progname); 1848178481Sjb 1849178481Sjb (void) iitraverse_hash(dw->dw_td->td_iihash, 1850178481Sjb &dw->dw_td->td_curvgen, NULL, NULL, 1851178481Sjb die_fail_reporters, dw); 1852178481Sjb 1853178481Sjb terminate("failed to resolve types\n"); 1854178481Sjb } 1855178481Sjb 1856178481Sjb last = dw->dw_nunres; 1857178481Sjb 1858178481Sjb } while (dw->dw_nunres != 0); 1859178481Sjb} 1860178481Sjb 1861254941Spfg/* 1862254941Spfg * Any object containing a function or object symbol at any scope should also 1863254941Spfg * contain DWARF data. 1864254941Spfg */ 1865254941Spfgstatic boolean_t 1866254941Spfgshould_have_dwarf(Elf *elf) 1867254941Spfg{ 1868254941Spfg Elf_Scn *scn = NULL; 1869254941Spfg Elf_Data *data = NULL; 1870254941Spfg GElf_Shdr shdr; 1871254941Spfg GElf_Sym sym; 1872254941Spfg uint32_t symdx = 0; 1873254941Spfg size_t nsyms = 0; 1874254941Spfg boolean_t found = B_FALSE; 1875254941Spfg 1876254941Spfg while ((scn = elf_nextscn(elf, scn)) != NULL) { 1877254941Spfg gelf_getshdr(scn, &shdr); 1878254941Spfg 1879254941Spfg if (shdr.sh_type == SHT_SYMTAB) { 1880254941Spfg found = B_TRUE; 1881254941Spfg break; 1882254941Spfg } 1883254941Spfg } 1884254941Spfg 1885254941Spfg if (!found) 1886254941Spfg terminate("cannot convert stripped objects\n"); 1887254941Spfg 1888254941Spfg data = elf_getdata(scn, NULL); 1889254941Spfg nsyms = shdr.sh_size / shdr.sh_entsize; 1890254941Spfg 1891254941Spfg for (symdx = 0; symdx < nsyms; symdx++) { 1892254941Spfg gelf_getsym(data, symdx, &sym); 1893254941Spfg 1894254941Spfg if ((GELF_ST_TYPE(sym.st_info) == STT_FUNC) || 1895254941Spfg (GELF_ST_TYPE(sym.st_info) == STT_TLS) || 1896254941Spfg (GELF_ST_TYPE(sym.st_info) == STT_OBJECT)) { 1897254941Spfg char *name; 1898254941Spfg 1899254941Spfg name = elf_strptr(elf, shdr.sh_link, sym.st_name); 1900254941Spfg 1901254941Spfg /* Studio emits these local symbols regardless */ 1902254941Spfg if ((strcmp(name, "Bbss.bss") != 0) && 1903254941Spfg (strcmp(name, "Ttbss.bss") != 0) && 1904254941Spfg (strcmp(name, "Ddata.data") != 0) && 1905254941Spfg (strcmp(name, "Ttdata.data") != 0) && 1906254941Spfg (strcmp(name, "Drodata.rodata") != 0)) 1907254941Spfg return (B_TRUE); 1908254941Spfg } 1909254941Spfg } 1910254941Spfg 1911254941Spfg return (B_FALSE); 1912254941Spfg} 1913254941Spfg 1914178481Sjb/*ARGSUSED*/ 1915178481Sjbint 1916178545Sjbdw_read(tdata_t *td, Elf *elf, char *filename __unused) 1917178481Sjb{ 1918178481Sjb Dwarf_Unsigned abboff, hdrlen, nxthdr; 1919178481Sjb Dwarf_Half vers, addrsz; 1920178545Sjb Dwarf_Die cu = 0; 1921178545Sjb Dwarf_Die child = 0; 1922178481Sjb dwarf_t dw; 1923178481Sjb char *prod = NULL; 1924178481Sjb int rc; 1925178481Sjb 1926178481Sjb bzero(&dw, sizeof (dwarf_t)); 1927178481Sjb dw.dw_td = td; 1928178481Sjb dw.dw_ptrsz = elf_ptrsz(elf); 1929178481Sjb dw.dw_mfgtid_last = TID_MFGTID_BASE; 1930178481Sjb dw.dw_tidhash = hash_new(TDESC_HASH_BUCKETS, tdesc_idhash, tdesc_idcmp); 1931178481Sjb dw.dw_fwdhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash, 1932178481Sjb tdesc_namecmp); 1933178481Sjb dw.dw_enumhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash, 1934178481Sjb tdesc_namecmp); 1935178481Sjb 1936178545Sjb if ((rc = dwarf_elf_init(elf, DW_DLC_READ, &dw.dw_dw, 1937178481Sjb &dw.dw_err)) == DW_DLV_NO_ENTRY) { 1938254941Spfg if (should_have_dwarf(elf)) { 1939254941Spfg errno = ENOENT; 1940254941Spfg return (-1); 1941254941Spfg } else { 1942254941Spfg return (0); 1943254941Spfg } 1944178481Sjb } else if (rc != DW_DLV_OK) { 1945178545Sjb if (dwarf_errno(&dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) { 1946178481Sjb /* 1947178481Sjb * There's no type data in the DWARF section, but 1948178481Sjb * libdwarf is too clever to handle that properly. 1949178481Sjb */ 1950178481Sjb return (0); 1951178481Sjb } 1952178481Sjb 1953178481Sjb terminate("failed to initialize DWARF: %s\n", 1954178545Sjb dwarf_errmsg(&dw.dw_err)); 1955178481Sjb } 1956178481Sjb 1957178481Sjb if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff, 1958178545Sjb &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK) 1959178545Sjb terminate("rc = %d %s\n", rc, dwarf_errmsg(&dw.dw_err)); 1960178545Sjb 1961254941Spfg if ((cu = die_sibling(&dw, NULL)) == NULL || 1962254941Spfg (((child = die_child(&dw, cu)) == NULL) && 1963254941Spfg should_have_dwarf(elf))) { 1964178481Sjb terminate("file does not contain dwarf type data " 1965178481Sjb "(try compiling with -g)\n"); 1966254941Spfg } else if (child == NULL) { 1967254941Spfg return (0); 1968254941Spfg } 1969178481Sjb 1970178481Sjb dw.dw_maxoff = nxthdr - 1; 1971178481Sjb 1972178481Sjb if (dw.dw_maxoff > TID_FILEMAX) 1973178481Sjb terminate("file contains too many types\n"); 1974178481Sjb 1975178481Sjb debug(1, "DWARF version: %d\n", vers); 1976178481Sjb if (vers != DWARF_VERSION) { 1977178481Sjb terminate("file contains incompatible version %d DWARF code " 1978178481Sjb "(version 2 required)\n", vers); 1979178481Sjb } 1980178481Sjb 1981178481Sjb if (die_string(&dw, cu, DW_AT_producer, &prod, 0)) { 1982178481Sjb debug(1, "DWARF emitter: %s\n", prod); 1983178481Sjb free(prod); 1984178481Sjb } 1985178481Sjb 1986178481Sjb if ((dw.dw_cuname = die_name(&dw, cu)) != NULL) { 1987178481Sjb char *base = xstrdup(basename(dw.dw_cuname)); 1988178481Sjb free(dw.dw_cuname); 1989178481Sjb dw.dw_cuname = base; 1990178481Sjb 1991178481Sjb debug(1, "CU name: %s\n", dw.dw_cuname); 1992178481Sjb } 1993178481Sjb 1994178545Sjb if ((child = die_child(&dw, cu)) != NULL) 1995178545Sjb die_create(&dw, child); 1996178481Sjb 1997178481Sjb if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff, 1998178481Sjb &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY) 1999178481Sjb terminate("multiple compilation units not supported\n"); 2000178481Sjb 2001178545Sjb (void) dwarf_finish(&dw.dw_dw, &dw.dw_err); 2002178481Sjb 2003178481Sjb die_resolve(&dw); 2004178481Sjb 2005178481Sjb cvt_fixups(td, dw.dw_ptrsz); 2006178481Sjb 2007178481Sjb /* leak the dwarf_t */ 2008178481Sjb 2009178481Sjb return (0); 2010178481Sjb} 2011