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