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