1bc1f688Robert Mustacchi/* 2bc1f688Robert Mustacchi * CDDL HEADER START 3bc1f688Robert Mustacchi * 4bc1f688Robert Mustacchi * The contents of this file are subject to the terms of the 5bc1f688Robert Mustacchi * Common Development and Distribution License (the "License"). 6bc1f688Robert Mustacchi * You may not use this file except in compliance with the License. 7bc1f688Robert Mustacchi * 8bc1f688Robert Mustacchi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9bc1f688Robert Mustacchi * or http://www.opensolaris.org/os/licensing. 10bc1f688Robert Mustacchi * See the License for the specific language governing permissions 11bc1f688Robert Mustacchi * and limitations under the License. 12bc1f688Robert Mustacchi * 13bc1f688Robert Mustacchi * When distributing Covered Code, include this CDDL HEADER in each 14bc1f688Robert Mustacchi * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15bc1f688Robert Mustacchi * If applicable, add the following below this CDDL HEADER, with the 16bc1f688Robert Mustacchi * fields enclosed by brackets "[]" replaced with your own identifying 17bc1f688Robert Mustacchi * information: Portions Copyright [yyyy] [name of copyright owner] 18bc1f688Robert Mustacchi * 19bc1f688Robert Mustacchi * CDDL HEADER END 20bc1f688Robert Mustacchi */ 21bc1f688Robert Mustacchi/* 22bc1f688Robert Mustacchi * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23bc1f688Robert Mustacchi * Use is subject to license terms. 24bc1f688Robert Mustacchi */ 25bc1f688Robert Mustacchi/* 26bc1f688Robert Mustacchi * Copyright 2012 Jason King. All rights reserved. 27bc1f688Robert Mustacchi * Use is subject to license terms. 28bc1f688Robert Mustacchi */ 29bc1f688Robert Mustacchi 30bc1f688Robert Mustacchi/* 316ef284fJohn Levon * Copyright 2019, Joyent, Inc. 32bc1f688Robert Mustacchi */ 33bc1f688Robert Mustacchi 34bc1f688Robert Mustacchi/* 35bc1f688Robert Mustacchi * CTF DWARF conversion theory. 36bc1f688Robert Mustacchi * 37bc1f688Robert Mustacchi * DWARF data contains a series of compilation units. Each compilation unit 38bc1f688Robert Mustacchi * generally refers to an object file or what once was, in the case of linked 39bc1f688Robert Mustacchi * binaries and shared objects. Each compilation unit has a series of what DWARF 40bc1f688Robert Mustacchi * calls a DIE (Debugging Information Entry). The set of entries that we care 41bc1f688Robert Mustacchi * about have type information stored in a series of attributes. Each DIE also 42bc1f688Robert Mustacchi * has a tag that identifies the kind of attributes that it has. 43bc1f688Robert Mustacchi * 44bc1f688Robert Mustacchi * A given DIE may itself have children. For example, a DIE that represents a 45bc1f688Robert Mustacchi * structure has children which represent members. Whenever we encounter a DIE 46bc1f688Robert Mustacchi * that has children or other values or types associated with it, we recursively 47bc1f688Robert Mustacchi * process those children first so that way we can then refer to the generated 48bc1f688Robert Mustacchi * CTF type id while processing its parent. This reduces the amount of unknowns 49bc1f688Robert Mustacchi * and fixups that we need. It also ensures that we don't accidentally add types 50bc1f688Robert Mustacchi * that an overzealous compiler might add to the DWARF data but aren't used by 51bc1f688Robert Mustacchi * anything in the system. 52bc1f688Robert Mustacchi * 53bc1f688Robert Mustacchi * Once we do a conversion, we store a mapping in an AVL tree that goes from the 54bc1f688Robert Mustacchi * DWARF's die offset, which is relative to the given compilation unit, to a 55bc1f688Robert Mustacchi * ctf_id_t. 56bc1f688Robert Mustacchi * 57bc1f688Robert Mustacchi * Unfortunately, some compilers actually will emit duplicate entries for a 58bc1f688Robert Mustacchi * given type that look similar, but aren't quite. To that end, we go through 59bc1f688Robert Mustacchi * and do a variant on a merge once we're done processing a single compilation 60bc1f688Robert Mustacchi * unit which deduplicates all of the types that are in the unit. 61bc1f688Robert Mustacchi * 62bc1f688Robert Mustacchi * Finally, if we encounter an object that has multiple compilation units, then 63bc1f688Robert Mustacchi * we'll convert all of the compilation units separately and then do a merge, so 64bc1f688Robert Mustacchi * that way we can result in one single ctf_file_t that represents everything 65bc1f688Robert Mustacchi * for the object. 66bc1f688Robert Mustacchi * 67bc1f688Robert Mustacchi * Conversion Steps 68bc1f688Robert Mustacchi * ---------------- 69bc1f688Robert Mustacchi * 70bc1f688Robert Mustacchi * Because a given object we've been given to convert may have multiple 71bc1f688Robert Mustacchi * compilation units, we break the work into two halves. The first half 72bc1f688Robert Mustacchi * processes each compilation unit (potentially in parallel) and then the second 73bc1f688Robert Mustacchi * half optionally merges all of the dies in the first half. First, we'll cover 74bc1f688Robert Mustacchi * what's involved in converting a single ctf_cu_t's dwarf to CTF. This covers 75bc1f688Robert Mustacchi * the work done in ctf_dwarf_convert_one(). 76bc1f688Robert Mustacchi * 77bc1f688Robert Mustacchi * An individual ctf_cu_t, which represents a compilation unit, is converted to 78bc1f688Robert Mustacchi * CTF in a series of multiple passes. 79bc1f688Robert Mustacchi * 80bc1f688Robert Mustacchi * Pass 1: During the first pass we walk all of the top-level dies and if we 81bc1f688Robert Mustacchi * find a function, variable, struct, union, enum or typedef, we recursively 82bc1f688Robert Mustacchi * transform all of its types. We don't recurse or process everything, because 83bc1f688Robert Mustacchi * we don't want to add some of the types that compilers may add which are 84bc1f688Robert Mustacchi * effectively unused. 85bc1f688Robert Mustacchi * 86bc1f688Robert Mustacchi * During pass 1, if we encounter any structures or unions we mark them for 87bc1f688Robert Mustacchi * fixing up later. This is necessary because we may not be able to determine 88bc1f688Robert Mustacchi * the full size of a structure at the beginning of time. This will happen if 89bc1f688Robert Mustacchi * the DWARF attribute DW_AT_byte_size is not present for a member. Because of 90bc1f688Robert Mustacchi * this possibility we defer adding members to structures or even converting 91bc1f688Robert Mustacchi * them during pass 1 and save that for pass 2. Adding all of the base 92bc1f688Robert Mustacchi * structures without any of their members helps deal with any circular 93bc1f688Robert Mustacchi * dependencies that we might encounter. 94bc1f688Robert Mustacchi * 95bc1f688Robert Mustacchi * Pass 2: This pass is used to do the first half of fixing up structures and 96bc1f688Robert Mustacchi * unions. Rather than walk the entire type space again, we actually walk the 97bc1f688Robert Mustacchi * list of structures and unions that we marked for later fixing up. Here, we 98bc1f688Robert Mustacchi * iterate over every structure and add members to the underlying ctf_file_t, 99bc1f688Robert Mustacchi * but not to the structs themselves. One might wonder why we don't, and the 100bc1f688Robert Mustacchi * main reason is that libctf requires a ctf_update() be done before adding the 101bc1f688Robert Mustacchi * members to structures or unions. 102bc1f688Robert Mustacchi * 103bc1f688Robert Mustacchi * Pass 3: This pass is used to do the second half of fixing up structures and 104bc1f688Robert Mustacchi * unions. During this part we always go through and add members to structures 105bc1f688Robert Mustacchi * and unions that we added to the container in the previous pass. In addition, 106bc1f688Robert Mustacchi * we set the structure and union's actual size, which may have additional 107bc1f688Robert Mustacchi * padding added by the compiler, it isn't simply the last offset. DWARF always 108bc1f688Robert Mustacchi * guarantees an attribute exists for this. Importantly no ctf_id_t's change 109bc1f688Robert Mustacchi * during pass 2. 110bc1f688Robert Mustacchi * 111bc1f688Robert Mustacchi * Pass 4: The next phase is to add CTF entries for all of the symbols and 112bc1f688Robert Mustacchi * variables that are present in this die. During pass 1 we added entries to a 113bc1f688Robert Mustacchi * map for each variable and function. During this pass, we iterate over the 114bc1f688Robert Mustacchi * symbol table and when we encounter a symbol that we have in our lists of 115bc1f688Robert Mustacchi * translated information which matches, we then add it to the ctf_file_t. 116bc1f688Robert Mustacchi * 117bc1f688Robert Mustacchi * Pass 5: Here we go and look for any weak symbols and functions and see if 118bc1f688Robert Mustacchi * they match anything that we recognize. If so, then we add type information 119bc1f688Robert Mustacchi * for them at this point based on the matching type. 120bc1f688Robert Mustacchi * 121bc1f688Robert Mustacchi * Pass 6: This pass is actually a variant on a merge. The traditional merge 122bc1f688Robert Mustacchi * process expects there to be no duplicate types. As such, at the end of 123bc1f688Robert Mustacchi * conversion, we do a dedup on all of the types in the system. The 124bc1f688Robert Mustacchi * deduplication process is described in lib/libctf/common/ctf_merge.c. 125bc1f688Robert Mustacchi * 126bc1f688Robert Mustacchi * Once pass 6 is done, we've finished processing the individual compilation 127bc1f688Robert Mustacchi * unit. 128bc1f688Robert Mustacchi * 129bc1f688Robert Mustacchi * The following steps reflect the general process of doing a conversion. 130bc1f688Robert Mustacchi * 131bc1f688Robert Mustacchi * 1) Walk the dwarf section and determine the number of compilation units 132bc1f688Robert Mustacchi * 2) Create a ctf_cu_t for each compilation unit 133bc1f688Robert Mustacchi * 3) Add all ctf_cu_t's to a workq 134bc1f688Robert Mustacchi * 4) Have the workq process each die with ctf_dwarf_convert_one. This itself 135bc1f688Robert Mustacchi * is comprised of several steps, which were already enumerated. 136bc1f688Robert Mustacchi * 5) If we have multiple cu's, we do a ctf merge of all the dies. The mechanics 137bc1f688Robert Mustacchi * of the merge are discussed in lib/libctf/common/ctf_merge.c. 138bc1f688Robert Mustacchi * 6) Free everything up and return a ctf_file_t to the user. If we only had a 139bc1f688Robert Mustacchi * single compilation unit, then we give that to the user. Otherwise, we 140bc1f688Robert Mustacchi * return the merged ctf_file_t. 141bc1f688Robert Mustacchi * 142bc1f688Robert Mustacchi * Threading 143bc1f688Robert Mustacchi * --------- 144bc1f688Robert Mustacchi * 145bc1f688Robert Mustacchi * The process has been designed to be amenable to threading. Each compilation 146bc1f688Robert Mustacchi * unit has its own type stream, therefore the logical place to divide and 147bc1f688Robert Mustacchi * conquer is at the compilation unit. Each ctf_cu_t has been built to be able 148bc1f688Robert Mustacchi * to be processed independently of the others. It has its own libdwarf handle, 149bc1f688Robert Mustacchi * as a given libdwarf handle may only be used by a single thread at a time. 150bc1f688Robert Mustacchi * This allows the various ctf_cu_t's to be processed in parallel by different 151bc1f688Robert Mustacchi * threads. 152bc1f688Robert Mustacchi * 153bc1f688Robert Mustacchi * All of the ctf_cu_t's are loaded into a workq which allows for a number of 154bc1f688Robert Mustacchi * threads to be specified and used as a thread pool to process all of the 155bc1f688Robert Mustacchi * queued work. We set the number of threads to use in the workq equal to the 156bc1f688Robert Mustacchi * number of threads that the user has specified. 157bc1f688Robert Mustacchi * 158bc1f688Robert Mustacchi * After all of the compilation units have been drained, we use the same number 159bc1f688Robert Mustacchi * of threads when performing a merge of multiple compilation units, if they 160bc1f688Robert Mustacchi * exist. 161bc1f688Robert Mustacchi * 162bc1f688Robert Mustacchi * While all of these different parts do support and allow for multiple threads, 163bc1f688Robert Mustacchi * it's important that when only a single thread is specified, that it be the 164bc1f688Robert Mustacchi * calling thread. This allows the conversion routines to be used in a context 165bc1f688Robert Mustacchi * that doesn't allow additional threads, such as rtld. 166bc1f688Robert Mustacchi * 167bc1f688Robert Mustacchi * Common DWARF Mechanics and Notes 168bc1f688Robert Mustacchi * -------------------------------- 169bc1f688Robert Mustacchi * 170bc1f688Robert Mustacchi * At this time, we really only support DWARFv2, though support for DWARFv4 is 171bc1f688Robert Mustacchi * mostly there. There is no intent to support DWARFv3. 172bc1f688Robert Mustacchi * 173bc1f688Robert Mustacchi * Generally types for something are stored in the DW_AT_type attribute. For 174bc1f688Robert Mustacchi * example, a function's return type will be stored in the local DW_AT_type 175bc1f688Robert Mustacchi * attribute while the arguments will be in child DIEs. There are also various 176bc1f688Robert Mustacchi * times when we don't have any DW_AT_type. In that case, the lack of a type 177bc1f688Robert Mustacchi * implies, at least for C, that its C type is void. Because DWARF doesn't emit 178bc1f688Robert Mustacchi * one, we have a synthetic void type that we create and manipulate instead and 179bc1f688Robert Mustacchi * pass it off to consumers on an as-needed basis. If nothing has a void type, 180bc1f688Robert Mustacchi * it will not be emitted. 181bc1f688Robert Mustacchi * 182bc1f688Robert Mustacchi * Architecture Specific Parts 183bc1f688Robert Mustacchi * --------------------------- 184bc1f688Robert Mustacchi * 185bc1f688Robert Mustacchi * The CTF tooling encodes various information about the various architectures 186bc1f688Robert Mustacchi * in the system. Importantly, the tool assumes that every architecture has a 187bc1f688Robert Mustacchi * data model where long and pointer are the same size. This is currently the 188bc1f688Robert Mustacchi * case, as the two data models illumos supports are ILP32 and LP64. 189bc1f688Robert Mustacchi * 190bc1f688Robert Mustacchi * In addition, we encode the mapping of various floating point sizes to various 191bc1f688Robert Mustacchi * types for each architecture. If a new architecture is being added, it should 192bc1f688Robert Mustacchi * be added to the list. The general design of the ctf conversion tools is to be 193bc1f688Robert Mustacchi * architecture independent. eg. any of the tools here should be able to convert 194bc1f688Robert Mustacchi * any architecture's DWARF into ctf; however, this has not been rigorously 195bc1f688Robert Mustacchi * tested and more importantly, the ctf routines don't currently write out the 196bc1f688Robert Mustacchi * data in an endian-aware form, they only use that of the currently running 197bc1f688Robert Mustacchi * library. 198bc1f688Robert Mustacchi */ 199bc1f688Robert Mustacchi 200bc1f688Robert Mustacchi#include <libctf_impl.h> 201bc1f688Robert Mustacchi#include <sys/avl.h> 202bc1f688Robert Mustacchi#include <sys/debug.h> 203bc1f688Robert Mustacchi#include <gelf.h> 204bc1f688Robert Mustacchi#include <libdwarf.h> 205bc1f688Robert Mustacchi#include <dwarf.h> 206bc1f688Robert Mustacchi#include <libgen.h> 207bc1f688Robert Mustacchi#include <workq.h> 208bc1f688Robert Mustacchi#include <errno.h> 209bc1f688Robert Mustacchi 210bc1f688Robert Mustacchi#define DWARF_VERSION_TWO 2 211bc1f688Robert Mustacchi#define DWARF_VARARGS_NAME "..." 212bc1f688Robert Mustacchi 213bc1f688Robert Mustacchi/* 214bc1f688Robert Mustacchi * Dwarf may refer recursively to other types that we've already processed. To 215bc1f688Robert Mustacchi * see if we've already converted them, we look them up in an AVL tree that's 216bc1f688Robert Mustacchi * sorted by the DWARF id. 217bc1f688Robert Mustacchi */ 218bc1f688Robert Mustacchitypedef struct ctf_dwmap { 219bc1f688Robert Mustacchi avl_node_t cdm_avl; 220bc1f688Robert Mustacchi Dwarf_Off cdm_off; 221bc1f688Robert Mustacchi Dwarf_Die cdm_die; 222bc1f688Robert Mustacchi ctf_id_t cdm_id; 223bc1f688Robert Mustacchi boolean_t cdm_fix; 224bc1f688Robert Mustacchi} ctf_dwmap_t; 225bc1f688Robert Mustacchi 226bc1f688Robert Mustacchitypedef struct ctf_dwvar { 227bc1f688Robert Mustacchi ctf_list_t cdv_list; 228bc1f688Robert Mustacchi char *cdv_name; 229bc1f688Robert Mustacchi ctf_id_t cdv_type; 230bc1f688Robert Mustacchi boolean_t cdv_global; 231bc1f688Robert Mustacchi} ctf_dwvar_t; 232bc1f688Robert Mustacchi 233bc1f688Robert Mustacchitypedef struct ctf_dwfunc { 234bc1f688Robert Mustacchi ctf_list_t cdf_list; 235bc1f688Robert Mustacchi char *cdf_name; 236bc1f688Robert Mustacchi ctf_funcinfo_t cdf_fip; 237bc1f688Robert Mustacchi ctf_id_t *cdf_argv; 238bc1f688Robert Mustacchi boolean_t cdf_global; 239bc1f688Robert Mustacchi} ctf_dwfunc_t; 240bc1f688Robert Mustacchi 241bc1f688Robert Mustacchitypedef struct ctf_dwbitf { 242bc1f688Robert Mustacchi ctf_list_t cdb_list; 243bc1f688Robert Mustacchi ctf_id_t cdb_base; 244bc1f688Robert Mustacchi uint_t cdb_nbits; 245bc1f688Robert Mustacchi ctf_id_t cdb_id; 246bc1f688Robert Mustacchi} ctf_dwbitf_t; 247bc1f688Robert Mustacchi 248bc1f688Robert Mustacchi/* 249bc1f688Robert Mustacchi * The ctf_cu_t represents a single top-level DWARF die unit. While generally, 250bc1f688Robert Mustacchi * the typical object file has only a single die, if we're asked to convert 251bc1f688Robert Mustacchi * something that's been linked from multiple sources, multiple dies will exist. 252bc1f688Robert Mustacchi */ 253bc1f688Robert Mustacchitypedef struct ctf_die { 254bc1f688Robert Mustacchi Elf *cu_elf; /* shared libelf handle */ 255bc1f688Robert Mustacchi char *cu_name; /* basename of the DIE */ 256bc1f688Robert Mustacchi ctf_merge_t *cu_cmh; /* merge handle */ 257bc1f688Robert Mustacchi ctf_list_t cu_vars; /* List of variables */ 258bc1f688Robert Mustacchi ctf_list_t cu_funcs; /* List of functions */ 259bc1f688Robert Mustacchi ctf_list_t cu_bitfields; /* Bit field members */ 260bc1f688Robert Mustacchi Dwarf_Debug cu_dwarf; /* libdwarf handle */ 261bc1f688Robert Mustacchi Dwarf_Die cu_cu; /* libdwarf compilation unit */ 262bc1f688Robert Mustacchi Dwarf_Off cu_cuoff; /* cu's offset */ 263bc1f688Robert Mustacchi Dwarf_Off cu_maxoff; /* maximum offset */ 264bc1f688Robert Mustacchi ctf_file_t *cu_ctfp; /* output CTF file */ 265bc1f688Robert Mustacchi avl_tree_t cu_map; /* map die offsets to CTF types */ 266bc1f688Robert Mustacchi char *cu_errbuf; /* error message buffer */ 267bc1f688Robert Mustacchi size_t cu_errlen; /* error message buffer length */ 268bc1f688Robert Mustacchi size_t cu_ptrsz; /* object's pointer size */ 269bc1f688Robert Mustacchi boolean_t cu_bigend; /* is it big endian */ 270bc1f688Robert Mustacchi boolean_t cu_doweaks; /* should we convert weak symbols? */ 271bc1f688Robert Mustacchi uint_t cu_mach; /* machine type */ 272bc1f688Robert Mustacchi ctf_id_t cu_voidtid; /* void pointer */ 273bc1f688Robert Mustacchi ctf_id_t cu_longtid; /* id for a 'long' */ 274bc1f688Robert Mustacchi} ctf_cu_t; 275bc1f688Robert Mustacchi 276bc1f688Robert Mustacchistatic int ctf_dwarf_offset(ctf_cu_t *, Dwarf_Die, Dwarf_Off *); 277bc1f688Robert Mustacchistatic int ctf_dwarf_convert_die(ctf_cu_t *, Dwarf_Die); 278bc1f688Robert Mustacchistatic int ctf_dwarf_convert_type(ctf_cu_t *, Dwarf_Die, ctf_id_t *, int); 279bc1f688Robert Mustacchi 280bc1f688Robert Mustacchistatic int ctf_dwarf_function_count(ctf_cu_t *, Dwarf_Die, ctf_funcinfo_t *, 281bc1f688Robert Mustacchi boolean_t); 282bc1f688Robert Mustacchistatic int ctf_dwarf_convert_fargs(ctf_cu_t *, Dwarf_Die, ctf_funcinfo_t *, 283bc1f688Robert Mustacchi ctf_id_t *); 284bc1f688Robert Mustacchi 285bc1f688Robert Mustacchi/* 286bc1f688Robert Mustacchi * This is a generic way to set a CTF Conversion backend error depending on what 287bc1f688Robert Mustacchi * we were doing. Unless it was one of a specific set of errors that don't 288bc1f688Robert Mustacchi * indicate a programming / translation bug, eg. ENOMEM, then we transform it 289bc1f688Robert Mustacchi * into a CTF backend error and fill in the error buffer. 290bc1f688Robert Mustacchi */ 291bc1f688Robert Mustacchistatic int 292bc1f688Robert Mustacchictf_dwarf_error(ctf_cu_t *cup, ctf_file_t *cfp, int err, const char *fmt, ...) 293bc1f688Robert Mustacchi{ 294bc1f688Robert Mustacchi va_list ap; 295bc1f688Robert Mustacchi int ret; 296bc1f688Robert Mustacchi size_t off = 0; 297bc1f688Robert Mustacchi ssize_t rem = cup->cu_errlen; 298bc1f688Robert Mustacchi if (cfp != NULL) 299bc1f688Robert Mustacchi err = ctf_errno(cfp); 300bc1f688Robert Mustacchi 301bc1f688Robert Mustacchi if (err == ENOMEM) 302bc1f688Robert Mustacchi return (err); 303bc1f688Robert Mustacchi 304bc1f688Robert Mustacchi ret = snprintf(cup->cu_errbuf, rem, "die %s: ", cup->cu_name); 305bc1f688Robert Mustacchi if (ret < 0) 306bc1f688Robert Mustacchi goto err; 307bc1f688Robert Mustacchi off += ret; 308bc1f688Robert Mustacchi rem = MAX(rem - ret, 0); 309bc1f688Robert Mustacchi 310bc1f688Robert Mustacchi va_start(ap, fmt); 311bc1f688Robert Mustacchi ret = vsnprintf(cup->cu_errbuf + off, rem, fmt, ap); 312bc1f688Robert Mustacchi va_end(ap); 313bc1f688Robert Mustacchi if (ret < 0) 314bc1f688Robert Mustacchi goto err; 315bc1f688Robert Mustacchi 316bc1f688Robert Mustacchi off += ret; 317bc1f688Robert Mustacchi rem = MAX(rem - ret, 0); 318bc1f688Robert Mustacchi if (fmt[strlen(fmt) - 1] != '\n') { 319bc1f688Robert Mustacchi (void) snprintf(cup->cu_errbuf + off, rem, 320bc1f688Robert Mustacchi ": %s\n", ctf_errmsg(err)); 321bc1f688Robert Mustacchi } 322bc1f688Robert Mustacchi va_end(ap); 323bc1f688Robert Mustacchi return (ECTF_CONVBKERR); 324bc1f688Robert Mustacchi 325bc1f688Robert Mustacchierr: 326bc1f688Robert Mustacchi cup->cu_errbuf[0] = '\0'; 327bc1f688Robert Mustacchi return (ECTF_CONVBKERR); 328bc1f688Robert Mustacchi} 329bc1f688Robert Mustacchi 330bc1f688Robert Mustacchi/* 331bc1f688Robert Mustacchi * DWARF often opts to put no explicit type to describe a void type. eg. if we 332bc1f688Robert Mustacchi * have a reference type whose DW_AT_type member doesn't exist, then we should 333bc1f688Robert Mustacchi * instead assume it points to void. Because this isn't represented, we 334bc1f688Robert Mustacchi * instead cause it to come into existence. 335bc1f688Robert Mustacchi */ 336bc1f688Robert Mustacchistatic ctf_id_t 337bc1f688Robert Mustacchictf_dwarf_void(ctf_cu_t *cup) 338bc1f688Robert Mustacchi{ 339bc1f688Robert Mustacchi if (cup->cu_voidtid == CTF_ERR) { 340bc1f688Robert Mustacchi ctf_encoding_t enc = { CTF_INT_SIGNED, 0, 0 }; 341bc1f688Robert Mustacchi cup->cu_voidtid = ctf_add_integer(cup->cu_ctfp, CTF_ADD_ROOT, 342bc1f688Robert Mustacchi "void", &enc); 343bc1f688Robert Mustacchi if (cup->cu_voidtid == CTF_ERR) { 344bc1f688Robert Mustacchi (void) snprintf(cup->cu_errbuf, cup->cu_errlen, 345bc1f688Robert Mustacchi "failed to create void type: %s\n", 346bc1f688Robert Mustacchi ctf_errmsg(ctf_errno(cup->cu_ctfp))); 347bc1f688Robert Mustacchi } 348bc1f688Robert Mustacchi } 349bc1f688Robert Mustacchi 350bc1f688Robert Mustacchi return (cup->cu_voidtid); 351bc1f688Robert Mustacchi} 352bc1f688Robert Mustacchi 353bc1f688Robert Mustacchi/* 354bc1f688Robert Mustacchi * There are many different forms that an array index may take. However, we just 355bc1f688Robert Mustacchi * always force it to be of a type long no matter what. Therefore we use this to 356bc1f688Robert Mustacchi * have a single instance of long across everything. 357bc1f688Robert Mustacchi */ 358bc1f688Robert Mustacchistatic ctf_id_t 359bc1f688Robert Mustacchictf_dwarf_long(ctf_cu_t *cup) 360bc1f688Robert Mustacchi{ 361bc1f688Robert Mustacchi if (cup->cu_longtid == CTF_ERR) { 362bc1f688Robert Mustacchi ctf_encoding_t enc; 363bc1f688Robert Mustacchi 364bc1f688Robert Mustacchi enc.cte_format = CTF_INT_SIGNED; 365bc1f688Robert Mustacchi enc.cte_offset = 0; 366bc1f688Robert Mustacchi /* All illumos systems are LP */ 367bc1f688Robert Mustacchi enc.cte_bits = cup->cu_ptrsz * 8; 368bc1f688Robert Mustacchi cup->cu_longtid = ctf_add_integer(cup->cu_ctfp, CTF_ADD_NONROOT, 369bc1f688Robert Mustacchi "long", &enc); 370bc1f688Robert Mustacchi if (cup->cu_longtid == CTF_ERR) { 371bc1f688Robert Mustacchi (void) snprintf(cup->cu_errbuf, cup->cu_errlen, 372bc1f688Robert Mustacchi "failed to create long type: %s\n", 373bc1f688Robert Mustacchi ctf_errmsg(ctf_errno(cup->cu_ctfp))); 374bc1f688Robert Mustacchi } 375bc1f688Robert Mustacchi 376bc1f688Robert Mustacchi } 377bc1f688Robert Mustacchi 378bc1f688Robert Mustacchi return (cup->cu_longtid); 379bc1f688Robert Mustacchi} 380bc1f688Robert Mustacchi 381