1*fae548d3Szrj /* Implementation header.
2*fae548d3Szrj Copyright (C) 2019-2020 Free Software Foundation, Inc.
3*fae548d3Szrj
4*fae548d3Szrj This file is part of libctf.
5*fae548d3Szrj
6*fae548d3Szrj libctf is free software; you can redistribute it and/or modify it under
7*fae548d3Szrj the terms of the GNU General Public License as published by the Free
8*fae548d3Szrj Software Foundation; either version 3, or (at your option) any later
9*fae548d3Szrj version.
10*fae548d3Szrj
11*fae548d3Szrj This program is distributed in the hope that it will be useful, but
12*fae548d3Szrj WITHOUT ANY WARRANTY; without even the implied warranty of
13*fae548d3Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14*fae548d3Szrj See the GNU General Public License for more details.
15*fae548d3Szrj
16*fae548d3Szrj You should have received a copy of the GNU General Public License
17*fae548d3Szrj along with this program; see the file COPYING. If not see
18*fae548d3Szrj <http://www.gnu.org/licenses/>. */
19*fae548d3Szrj
20*fae548d3Szrj #ifndef _CTF_IMPL_H
21*fae548d3Szrj #define _CTF_IMPL_H
22*fae548d3Szrj
23*fae548d3Szrj #include "config.h"
24*fae548d3Szrj #include <errno.h>
25*fae548d3Szrj #include <sys/param.h>
26*fae548d3Szrj #include "ctf-decls.h"
27*fae548d3Szrj #include <ctf-api.h>
28*fae548d3Szrj #include <sys/types.h>
29*fae548d3Szrj #include <stdlib.h>
30*fae548d3Szrj #include <stdarg.h>
31*fae548d3Szrj #include <stdio.h>
32*fae548d3Szrj #include <stdint.h>
33*fae548d3Szrj #include <limits.h>
34*fae548d3Szrj #include <ctype.h>
35*fae548d3Szrj #include <elf.h>
36*fae548d3Szrj #include <bfd.h>
37*fae548d3Szrj
38*fae548d3Szrj #ifdef __cplusplus
39*fae548d3Szrj extern "C"
40*fae548d3Szrj {
41*fae548d3Szrj #endif
42*fae548d3Szrj
43*fae548d3Szrj /* Compiler attributes. */
44*fae548d3Szrj
45*fae548d3Szrj #if defined (__GNUC__)
46*fae548d3Szrj
47*fae548d3Szrj /* GCC. We assume that all compilers claiming to be GCC support sufficiently
48*fae548d3Szrj many GCC attributes that the code below works. If some non-GCC compilers
49*fae548d3Szrj masquerading as GCC in fact do not implement these attributes, version checks
50*fae548d3Szrj may be required. */
51*fae548d3Szrj
52*fae548d3Szrj /* We use the _libctf_*_ pattern to avoid clashes with any future attribute
53*fae548d3Szrj macros glibc may introduce, which have names of the pattern
54*fae548d3Szrj __attribute_blah__. */
55*fae548d3Szrj
56*fae548d3Szrj #define _libctf_printflike_(string_index,first_to_check) \
57*fae548d3Szrj __attribute__ ((__format__ (__printf__, (string_index), (first_to_check))))
58*fae548d3Szrj #define _libctf_unlikely_(x) __builtin_expect ((x), 0)
59*fae548d3Szrj #define _libctf_unused_ __attribute__ ((__unused__))
60*fae548d3Szrj #define _libctf_malloc_ __attribute__((__malloc__))
61*fae548d3Szrj
62*fae548d3Szrj #endif
63*fae548d3Szrj
64*fae548d3Szrj /* libctf in-memory state. */
65*fae548d3Szrj
66*fae548d3Szrj typedef struct ctf_fixed_hash ctf_hash_t; /* Private to ctf-hash.c. */
67*fae548d3Szrj typedef struct ctf_dynhash ctf_dynhash_t; /* Private to ctf-hash.c. */
68*fae548d3Szrj
69*fae548d3Szrj typedef struct ctf_strs
70*fae548d3Szrj {
71*fae548d3Szrj const char *cts_strs; /* Base address of string table. */
72*fae548d3Szrj size_t cts_len; /* Size of string table in bytes. */
73*fae548d3Szrj } ctf_strs_t;
74*fae548d3Szrj
75*fae548d3Szrj typedef struct ctf_strs_writable
76*fae548d3Szrj {
77*fae548d3Szrj char *cts_strs; /* Base address of string table. */
78*fae548d3Szrj size_t cts_len; /* Size of string table in bytes. */
79*fae548d3Szrj } ctf_strs_writable_t;
80*fae548d3Szrj
81*fae548d3Szrj typedef struct ctf_dmodel
82*fae548d3Szrj {
83*fae548d3Szrj const char *ctd_name; /* Data model name. */
84*fae548d3Szrj int ctd_code; /* Data model code. */
85*fae548d3Szrj size_t ctd_pointer; /* Size of void * in bytes. */
86*fae548d3Szrj size_t ctd_char; /* Size of char in bytes. */
87*fae548d3Szrj size_t ctd_short; /* Size of short in bytes. */
88*fae548d3Szrj size_t ctd_int; /* Size of int in bytes. */
89*fae548d3Szrj size_t ctd_long; /* Size of long in bytes. */
90*fae548d3Szrj } ctf_dmodel_t;
91*fae548d3Szrj
92*fae548d3Szrj typedef struct ctf_names
93*fae548d3Szrj {
94*fae548d3Szrj ctf_hash_t *ctn_readonly; /* Hash table when readonly. */
95*fae548d3Szrj ctf_dynhash_t *ctn_writable; /* Hash table when writable. */
96*fae548d3Szrj } ctf_names_t;
97*fae548d3Szrj
98*fae548d3Szrj typedef struct ctf_lookup
99*fae548d3Szrj {
100*fae548d3Szrj const char *ctl_prefix; /* String prefix for this lookup. */
101*fae548d3Szrj size_t ctl_len; /* Length of prefix string in bytes. */
102*fae548d3Szrj ctf_names_t *ctl_hash; /* Pointer to hash table for lookup. */
103*fae548d3Szrj } ctf_lookup_t;
104*fae548d3Szrj
105*fae548d3Szrj typedef struct ctf_fileops
106*fae548d3Szrj {
107*fae548d3Szrj uint32_t (*ctfo_get_kind) (uint32_t);
108*fae548d3Szrj uint32_t (*ctfo_get_root) (uint32_t);
109*fae548d3Szrj uint32_t (*ctfo_get_vlen) (uint32_t);
110*fae548d3Szrj ssize_t (*ctfo_get_ctt_size) (const ctf_file_t *, const ctf_type_t *,
111*fae548d3Szrj ssize_t *, ssize_t *);
112*fae548d3Szrj ssize_t (*ctfo_get_vbytes) (unsigned short, ssize_t, size_t);
113*fae548d3Szrj } ctf_fileops_t;
114*fae548d3Szrj
115*fae548d3Szrj typedef struct ctf_list
116*fae548d3Szrj {
117*fae548d3Szrj struct ctf_list *l_prev; /* Previous pointer or tail pointer. */
118*fae548d3Szrj struct ctf_list *l_next; /* Next pointer or head pointer. */
119*fae548d3Szrj } ctf_list_t;
120*fae548d3Szrj
121*fae548d3Szrj typedef enum
122*fae548d3Szrj {
123*fae548d3Szrj CTF_PREC_BASE,
124*fae548d3Szrj CTF_PREC_POINTER,
125*fae548d3Szrj CTF_PREC_ARRAY,
126*fae548d3Szrj CTF_PREC_FUNCTION,
127*fae548d3Szrj CTF_PREC_MAX
128*fae548d3Szrj } ctf_decl_prec_t;
129*fae548d3Szrj
130*fae548d3Szrj typedef struct ctf_decl_node
131*fae548d3Szrj {
132*fae548d3Szrj ctf_list_t cd_list; /* Linked list pointers. */
133*fae548d3Szrj ctf_id_t cd_type; /* Type identifier. */
134*fae548d3Szrj uint32_t cd_kind; /* Type kind. */
135*fae548d3Szrj uint32_t cd_n; /* Type dimension if array. */
136*fae548d3Szrj } ctf_decl_node_t;
137*fae548d3Szrj
138*fae548d3Szrj typedef struct ctf_decl
139*fae548d3Szrj {
140*fae548d3Szrj ctf_list_t cd_nodes[CTF_PREC_MAX]; /* Declaration node stacks. */
141*fae548d3Szrj int cd_order[CTF_PREC_MAX]; /* Storage order of decls. */
142*fae548d3Szrj ctf_decl_prec_t cd_qualp; /* Qualifier precision. */
143*fae548d3Szrj ctf_decl_prec_t cd_ordp; /* Ordered precision. */
144*fae548d3Szrj char *cd_buf; /* Buffer for output. */
145*fae548d3Szrj int cd_err; /* Saved error value. */
146*fae548d3Szrj int cd_enomem; /* Nonzero if OOM during printing. */
147*fae548d3Szrj } ctf_decl_t;
148*fae548d3Szrj
149*fae548d3Szrj typedef struct ctf_dmdef
150*fae548d3Szrj {
151*fae548d3Szrj ctf_list_t dmd_list; /* List forward/back pointers. */
152*fae548d3Szrj char *dmd_name; /* Name of this member. */
153*fae548d3Szrj ctf_id_t dmd_type; /* Type of this member (for sou). */
154*fae548d3Szrj unsigned long dmd_offset; /* Offset of this member in bits (for sou). */
155*fae548d3Szrj int dmd_value; /* Value of this member (for enum). */
156*fae548d3Szrj } ctf_dmdef_t;
157*fae548d3Szrj
158*fae548d3Szrj typedef struct ctf_dtdef
159*fae548d3Szrj {
160*fae548d3Szrj ctf_list_t dtd_list; /* List forward/back pointers. */
161*fae548d3Szrj ctf_id_t dtd_type; /* Type identifier for this definition. */
162*fae548d3Szrj ctf_type_t dtd_data; /* Type node, including name. */
163*fae548d3Szrj union
164*fae548d3Szrj {
165*fae548d3Szrj ctf_list_t dtu_members; /* struct, union, or enum */
166*fae548d3Szrj ctf_arinfo_t dtu_arr; /* array */
167*fae548d3Szrj ctf_encoding_t dtu_enc; /* integer or float */
168*fae548d3Szrj ctf_id_t *dtu_argv; /* function */
169*fae548d3Szrj ctf_slice_t dtu_slice; /* slice */
170*fae548d3Szrj } dtd_u;
171*fae548d3Szrj } ctf_dtdef_t;
172*fae548d3Szrj
173*fae548d3Szrj typedef struct ctf_dvdef
174*fae548d3Szrj {
175*fae548d3Szrj ctf_list_t dvd_list; /* List forward/back pointers. */
176*fae548d3Szrj char *dvd_name; /* Name associated with variable. */
177*fae548d3Szrj ctf_id_t dvd_type; /* Type of variable. */
178*fae548d3Szrj unsigned long dvd_snapshots; /* Snapshot count when inserted. */
179*fae548d3Szrj } ctf_dvdef_t;
180*fae548d3Szrj
181*fae548d3Szrj typedef struct ctf_bundle
182*fae548d3Szrj {
183*fae548d3Szrj ctf_file_t *ctb_file; /* CTF container handle. */
184*fae548d3Szrj ctf_id_t ctb_type; /* CTF type identifier. */
185*fae548d3Szrj ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any). */
186*fae548d3Szrj } ctf_bundle_t;
187*fae548d3Szrj
188*fae548d3Szrj /* Atoms associate strings with a list of the CTF items that reference that
189*fae548d3Szrj string, so that ctf_update() can instantiate all the strings using the
190*fae548d3Szrj ctf_str_atoms and then reassociate them with the real string later.
191*fae548d3Szrj
192*fae548d3Szrj Strings can be interned into ctf_str_atom without having refs associated
193*fae548d3Szrj with them, for values that are returned to callers, etc. Items are only
194*fae548d3Szrj removed from this table on ctf_close(), but on every ctf_update(), all the
195*fae548d3Szrj csa_refs in all entries are purged. */
196*fae548d3Szrj
197*fae548d3Szrj typedef struct ctf_str_atom
198*fae548d3Szrj {
199*fae548d3Szrj const char *csa_str; /* Backpointer to string (hash key). */
200*fae548d3Szrj ctf_list_t csa_refs; /* This string's refs. */
201*fae548d3Szrj uint32_t csa_offset; /* Strtab offset, if any. */
202*fae548d3Szrj uint32_t csa_external_offset; /* External strtab offset, if any. */
203*fae548d3Szrj unsigned long csa_snapshot_id; /* Snapshot ID at time of creation. */
204*fae548d3Szrj } ctf_str_atom_t;
205*fae548d3Szrj
206*fae548d3Szrj /* The refs of a single string in the atoms table. */
207*fae548d3Szrj
208*fae548d3Szrj typedef struct ctf_str_atom_ref
209*fae548d3Szrj {
210*fae548d3Szrj ctf_list_t caf_list; /* List forward/back pointers. */
211*fae548d3Szrj uint32_t *caf_ref; /* A single ref to this string. */
212*fae548d3Szrj } ctf_str_atom_ref_t;
213*fae548d3Szrj
214*fae548d3Szrj /* The structure used as the key in a ctf_link_type_mapping, which lets the
215*fae548d3Szrj linker machinery determine which type IDs on the input side of a link map to
216*fae548d3Szrj which types on the output side. (The value is a ctf_id_t: another
217*fae548d3Szrj index, not a type.) */
218*fae548d3Szrj
219*fae548d3Szrj typedef struct ctf_link_type_mapping_key
220*fae548d3Szrj {
221*fae548d3Szrj ctf_file_t *cltm_fp;
222*fae548d3Szrj ctf_id_t cltm_idx;
223*fae548d3Szrj } ctf_link_type_mapping_key_t;
224*fae548d3Szrj
225*fae548d3Szrj /* The ctf_file is the structure used to represent a CTF container to library
226*fae548d3Szrj clients, who see it only as an opaque pointer. Modifications can therefore
227*fae548d3Szrj be made freely to this structure without regard to client versioning. The
228*fae548d3Szrj ctf_file_t typedef appears in <ctf-api.h> and declares a forward tag.
229*fae548d3Szrj
230*fae548d3Szrj NOTE: ctf_update() requires that everything inside of ctf_file either be an
231*fae548d3Szrj immediate value, a pointer to dynamically allocated data *outside* of the
232*fae548d3Szrj ctf_file itself, or a pointer to statically allocated data. If you add a
233*fae548d3Szrj pointer to ctf_file that points to something within the ctf_file itself,
234*fae548d3Szrj you must make corresponding changes to ctf_update(). */
235*fae548d3Szrj
236*fae548d3Szrj struct ctf_file
237*fae548d3Szrj {
238*fae548d3Szrj const ctf_fileops_t *ctf_fileops; /* Version-specific file operations. */
239*fae548d3Szrj struct ctf_header *ctf_header; /* The header from this CTF file. */
240*fae548d3Szrj unsigned char ctf_openflags; /* Flags the file had when opened. */
241*fae548d3Szrj ctf_sect_t ctf_data; /* CTF data from object file. */
242*fae548d3Szrj ctf_sect_t ctf_symtab; /* Symbol table from object file. */
243*fae548d3Szrj ctf_sect_t ctf_strtab; /* String table from object file. */
244*fae548d3Szrj ctf_dynhash_t *ctf_prov_strtab; /* Maps provisional-strtab offsets
245*fae548d3Szrj to names. */
246*fae548d3Szrj ctf_dynhash_t *ctf_syn_ext_strtab; /* Maps ext-strtab offsets to names. */
247*fae548d3Szrj void *ctf_data_mmapped; /* CTF data we mmapped, to free later. */
248*fae548d3Szrj size_t ctf_data_mmapped_len; /* Length of CTF data we mmapped. */
249*fae548d3Szrj ctf_names_t ctf_structs; /* Hash table of struct types. */
250*fae548d3Szrj ctf_names_t ctf_unions; /* Hash table of union types. */
251*fae548d3Szrj ctf_names_t ctf_enums; /* Hash table of enum types. */
252*fae548d3Szrj ctf_names_t ctf_names; /* Hash table of remaining type names. */
253*fae548d3Szrj ctf_lookup_t ctf_lookups[5]; /* Pointers to nametabs for name lookup. */
254*fae548d3Szrj ctf_strs_t ctf_str[2]; /* Array of string table base and bounds. */
255*fae548d3Szrj ctf_dynhash_t *ctf_str_atoms; /* Hash table of ctf_str_atoms_t. */
256*fae548d3Szrj uint64_t ctf_str_num_refs; /* Number of refs to cts_str_atoms. */
257*fae548d3Szrj uint32_t ctf_str_prov_offset; /* Latest provisional offset assigned so far. */
258*fae548d3Szrj unsigned char *ctf_base; /* CTF file pointer. */
259*fae548d3Szrj unsigned char *ctf_dynbase; /* Freeable CTF file pointer. */
260*fae548d3Szrj unsigned char *ctf_buf; /* Uncompressed CTF data buffer. */
261*fae548d3Szrj size_t ctf_size; /* Size of CTF header + uncompressed data. */
262*fae548d3Szrj uint32_t *ctf_sxlate; /* Translation table for symtab entries. */
263*fae548d3Szrj unsigned long ctf_nsyms; /* Number of entries in symtab xlate table. */
264*fae548d3Szrj uint32_t *ctf_txlate; /* Translation table for type IDs. */
265*fae548d3Szrj uint32_t *ctf_ptrtab; /* Translation table for pointer-to lookups. */
266*fae548d3Szrj size_t ctf_ptrtab_len; /* Num types storable in ptrtab currently. */
267*fae548d3Szrj struct ctf_varent *ctf_vars; /* Sorted variable->type mapping. */
268*fae548d3Szrj unsigned long ctf_nvars; /* Number of variables in ctf_vars. */
269*fae548d3Szrj unsigned long ctf_typemax; /* Maximum valid type ID number. */
270*fae548d3Szrj const ctf_dmodel_t *ctf_dmodel; /* Data model pointer (see above). */
271*fae548d3Szrj const char *ctf_cuname; /* Compilation unit name (if any). */
272*fae548d3Szrj char *ctf_dyncuname; /* Dynamically allocated name of CU. */
273*fae548d3Szrj struct ctf_file *ctf_parent; /* Parent CTF container (if any). */
274*fae548d3Szrj const char *ctf_parlabel; /* Label in parent container (if any). */
275*fae548d3Szrj const char *ctf_parname; /* Basename of parent (if any). */
276*fae548d3Szrj char *ctf_dynparname; /* Dynamically allocated name of parent. */
277*fae548d3Szrj uint32_t ctf_parmax; /* Highest type ID of a parent type. */
278*fae548d3Szrj uint32_t ctf_refcnt; /* Reference count (for parent links). */
279*fae548d3Szrj uint32_t ctf_flags; /* Libctf flags (see below). */
280*fae548d3Szrj int ctf_errno; /* Error code for most recent error. */
281*fae548d3Szrj int ctf_version; /* CTF data version. */
282*fae548d3Szrj ctf_dynhash_t *ctf_dthash; /* Hash of dynamic type definitions. */
283*fae548d3Szrj ctf_list_t ctf_dtdefs; /* List of dynamic type definitions. */
284*fae548d3Szrj ctf_dynhash_t *ctf_dvhash; /* Hash of dynamic variable mappings. */
285*fae548d3Szrj ctf_list_t ctf_dvdefs; /* List of dynamic variable definitions. */
286*fae548d3Szrj unsigned long ctf_dtoldid; /* Oldest id that has been committed. */
287*fae548d3Szrj unsigned long ctf_snapshots; /* ctf_snapshot() plus ctf_update() count. */
288*fae548d3Szrj unsigned long ctf_snapshot_lu; /* ctf_snapshot() call count at last update. */
289*fae548d3Szrj ctf_archive_t *ctf_archive; /* Archive this ctf_file_t came from. */
290*fae548d3Szrj ctf_dynhash_t *ctf_link_inputs; /* Inputs to this link. */
291*fae548d3Szrj ctf_dynhash_t *ctf_link_outputs; /* Additional outputs from this link. */
292*fae548d3Szrj ctf_dynhash_t *ctf_link_type_mapping; /* Map input types to output types. */
293*fae548d3Szrj ctf_dynhash_t *ctf_link_cu_mapping; /* Map CU names to CTF dict names. */
294*fae548d3Szrj /* Allow the caller to Change the name of link archive members. */
295*fae548d3Szrj ctf_link_memb_name_changer_f *ctf_link_memb_name_changer;
296*fae548d3Szrj void *ctf_link_memb_name_changer_arg; /* Argument for it. */
297*fae548d3Szrj ctf_dynhash_t *ctf_add_processing; /* Types ctf_add_type is working on now. */
298*fae548d3Szrj char *ctf_tmp_typeslice; /* Storage for slicing up type names. */
299*fae548d3Szrj size_t ctf_tmp_typeslicelen; /* Size of the typeslice. */
300*fae548d3Szrj void *ctf_specific; /* Data for ctf_get/setspecific(). */
301*fae548d3Szrj };
302*fae548d3Szrj
303*fae548d3Szrj /* An abstraction over both a ctf_file_t and a ctf_archive_t. */
304*fae548d3Szrj
305*fae548d3Szrj struct ctf_archive_internal
306*fae548d3Szrj {
307*fae548d3Szrj int ctfi_is_archive;
308*fae548d3Szrj ctf_file_t *ctfi_file;
309*fae548d3Szrj struct ctf_archive *ctfi_archive;
310*fae548d3Szrj ctf_sect_t ctfi_symsect;
311*fae548d3Szrj ctf_sect_t ctfi_strsect;
312*fae548d3Szrj void *ctfi_data;
313*fae548d3Szrj bfd *ctfi_abfd; /* Optional source of section data. */
314*fae548d3Szrj void (*ctfi_bfd_close) (struct ctf_archive_internal *);
315*fae548d3Szrj };
316*fae548d3Szrj
317*fae548d3Szrj /* Return x rounded up to an alignment boundary.
318*fae548d3Szrj eg, P2ROUNDUP(0x1234, 0x100) == 0x1300 (0x13*align)
319*fae548d3Szrj eg, P2ROUNDUP(0x5600, 0x100) == 0x5600 (0x56*align) */
320*fae548d3Szrj #define P2ROUNDUP(x, align) (-(-(x) & -(align)))
321*fae548d3Szrj
322*fae548d3Szrj /* * If an offs is not aligned already then round it up and align it. */
323*fae548d3Szrj #define LCTF_ALIGN_OFFS(offs, align) ((offs + (align - 1)) & ~(align - 1))
324*fae548d3Szrj
325*fae548d3Szrj #define LCTF_TYPE_ISPARENT(fp, id) ((id) <= fp->ctf_parmax)
326*fae548d3Szrj #define LCTF_TYPE_ISCHILD(fp, id) ((id) > fp->ctf_parmax)
327*fae548d3Szrj #define LCTF_TYPE_TO_INDEX(fp, id) ((id) & (fp->ctf_parmax))
328*fae548d3Szrj #define LCTF_INDEX_TO_TYPE(fp, id, child) (child ? ((id) | (fp->ctf_parmax+1)) : \
329*fae548d3Szrj (id))
330*fae548d3Szrj
331*fae548d3Szrj #define LCTF_INDEX_TO_TYPEPTR(fp, i) \
332*fae548d3Szrj ((fp->ctf_flags & LCTF_RDWR) ? \
333*fae548d3Szrj &(ctf_dtd_lookup (fp, LCTF_INDEX_TO_TYPE \
334*fae548d3Szrj (fp, i, fp->ctf_flags & LCTF_CHILD))->dtd_data) : \
335*fae548d3Szrj (ctf_type_t *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)]))
336*fae548d3Szrj
337*fae548d3Szrj #define LCTF_INFO_KIND(fp, info) ((fp)->ctf_fileops->ctfo_get_kind(info))
338*fae548d3Szrj #define LCTF_INFO_ISROOT(fp, info) ((fp)->ctf_fileops->ctfo_get_root(info))
339*fae548d3Szrj #define LCTF_INFO_VLEN(fp, info) ((fp)->ctf_fileops->ctfo_get_vlen(info))
340*fae548d3Szrj #define LCTF_VBYTES(fp, kind, size, vlen) \
341*fae548d3Szrj ((fp)->ctf_fileops->ctfo_get_vbytes(kind, size, vlen))
342*fae548d3Szrj
ctf_get_ctt_size(const ctf_file_t * fp,const ctf_type_t * tp,ssize_t * sizep,ssize_t * incrementp)343*fae548d3Szrj static inline ssize_t ctf_get_ctt_size (const ctf_file_t *fp,
344*fae548d3Szrj const ctf_type_t *tp,
345*fae548d3Szrj ssize_t *sizep,
346*fae548d3Szrj ssize_t *incrementp)
347*fae548d3Szrj {
348*fae548d3Szrj return (fp->ctf_fileops->ctfo_get_ctt_size (fp, tp, sizep, incrementp));
349*fae548d3Szrj }
350*fae548d3Szrj
351*fae548d3Szrj #define LCTF_CHILD 0x0001 /* CTF container is a child */
352*fae548d3Szrj #define LCTF_RDWR 0x0002 /* CTF container is writable */
353*fae548d3Szrj #define LCTF_DIRTY 0x0004 /* CTF container has been modified */
354*fae548d3Szrj
355*fae548d3Szrj extern ctf_names_t *ctf_name_table (ctf_file_t *, int);
356*fae548d3Szrj extern const ctf_type_t *ctf_lookup_by_id (ctf_file_t **, ctf_id_t);
357*fae548d3Szrj extern ctf_id_t ctf_lookup_by_rawname (ctf_file_t *, int, const char *);
358*fae548d3Szrj extern ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *, ctf_names_t *, const char *);
359*fae548d3Szrj extern void ctf_set_ctl_hashes (ctf_file_t *);
360*fae548d3Szrj
361*fae548d3Szrj typedef unsigned int (*ctf_hash_fun) (const void *ptr);
362*fae548d3Szrj extern unsigned int ctf_hash_integer (const void *ptr);
363*fae548d3Szrj extern unsigned int ctf_hash_string (const void *ptr);
364*fae548d3Szrj extern unsigned int ctf_hash_type_mapping_key (const void *ptr);
365*fae548d3Szrj
366*fae548d3Szrj typedef int (*ctf_hash_eq_fun) (const void *, const void *);
367*fae548d3Szrj extern int ctf_hash_eq_integer (const void *, const void *);
368*fae548d3Szrj extern int ctf_hash_eq_string (const void *, const void *);
369*fae548d3Szrj extern int ctf_hash_eq_type_mapping_key (const void *, const void *);
370*fae548d3Szrj
371*fae548d3Szrj typedef void (*ctf_hash_free_fun) (void *);
372*fae548d3Szrj
373*fae548d3Szrj typedef void (*ctf_hash_iter_f) (void *key, void *value, void *arg);
374*fae548d3Szrj typedef int (*ctf_hash_iter_remove_f) (void *key, void *value, void *arg);
375*fae548d3Szrj
376*fae548d3Szrj extern ctf_hash_t *ctf_hash_create (unsigned long, ctf_hash_fun, ctf_hash_eq_fun);
377*fae548d3Szrj extern int ctf_hash_insert_type (ctf_hash_t *, ctf_file_t *, uint32_t, uint32_t);
378*fae548d3Szrj extern int ctf_hash_define_type (ctf_hash_t *, ctf_file_t *, uint32_t, uint32_t);
379*fae548d3Szrj extern ctf_id_t ctf_hash_lookup_type (ctf_hash_t *, ctf_file_t *, const char *);
380*fae548d3Szrj extern uint32_t ctf_hash_size (const ctf_hash_t *);
381*fae548d3Szrj extern void ctf_hash_destroy (ctf_hash_t *);
382*fae548d3Szrj
383*fae548d3Szrj extern ctf_dynhash_t *ctf_dynhash_create (ctf_hash_fun, ctf_hash_eq_fun,
384*fae548d3Szrj ctf_hash_free_fun, ctf_hash_free_fun);
385*fae548d3Szrj extern int ctf_dynhash_insert (ctf_dynhash_t *, void *, void *);
386*fae548d3Szrj extern void ctf_dynhash_remove (ctf_dynhash_t *, const void *);
387*fae548d3Szrj extern void ctf_dynhash_empty (ctf_dynhash_t *);
388*fae548d3Szrj extern void *ctf_dynhash_lookup (ctf_dynhash_t *, const void *);
389*fae548d3Szrj extern void ctf_dynhash_destroy (ctf_dynhash_t *);
390*fae548d3Szrj extern void ctf_dynhash_iter (ctf_dynhash_t *, ctf_hash_iter_f, void *);
391*fae548d3Szrj extern void ctf_dynhash_iter_remove (ctf_dynhash_t *, ctf_hash_iter_remove_f,
392*fae548d3Szrj void *);
393*fae548d3Szrj
394*fae548d3Szrj #define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev))
395*fae548d3Szrj #define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next))
396*fae548d3Szrj
397*fae548d3Szrj extern void ctf_list_append (ctf_list_t *, void *);
398*fae548d3Szrj extern void ctf_list_prepend (ctf_list_t *, void *);
399*fae548d3Szrj extern void ctf_list_delete (ctf_list_t *, void *);
400*fae548d3Szrj extern int ctf_list_empty_p (ctf_list_t *lp);
401*fae548d3Szrj
402*fae548d3Szrj extern int ctf_dtd_insert (ctf_file_t *, ctf_dtdef_t *, int);
403*fae548d3Szrj extern void ctf_dtd_delete (ctf_file_t *, ctf_dtdef_t *);
404*fae548d3Szrj extern ctf_dtdef_t *ctf_dtd_lookup (const ctf_file_t *, ctf_id_t);
405*fae548d3Szrj extern ctf_dtdef_t *ctf_dynamic_type (const ctf_file_t *, ctf_id_t);
406*fae548d3Szrj
407*fae548d3Szrj extern int ctf_dvd_insert (ctf_file_t *, ctf_dvdef_t *);
408*fae548d3Szrj extern void ctf_dvd_delete (ctf_file_t *, ctf_dvdef_t *);
409*fae548d3Szrj extern ctf_dvdef_t *ctf_dvd_lookup (const ctf_file_t *, const char *);
410*fae548d3Szrj
411*fae548d3Szrj extern void ctf_add_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type,
412*fae548d3Szrj ctf_file_t *dst_fp, ctf_id_t dst_type);
413*fae548d3Szrj extern ctf_id_t ctf_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type,
414*fae548d3Szrj ctf_file_t **dst_fp);
415*fae548d3Szrj
416*fae548d3Szrj extern void ctf_decl_init (ctf_decl_t *);
417*fae548d3Szrj extern void ctf_decl_fini (ctf_decl_t *);
418*fae548d3Szrj extern void ctf_decl_push (ctf_decl_t *, ctf_file_t *, ctf_id_t);
419*fae548d3Szrj
420*fae548d3Szrj _libctf_printflike_ (2, 3)
421*fae548d3Szrj extern void ctf_decl_sprintf (ctf_decl_t *, const char *, ...);
422*fae548d3Szrj extern char *ctf_decl_buf (ctf_decl_t *cd);
423*fae548d3Szrj
424*fae548d3Szrj extern const char *ctf_strptr (ctf_file_t *, uint32_t);
425*fae548d3Szrj extern const char *ctf_strraw (ctf_file_t *, uint32_t);
426*fae548d3Szrj extern const char *ctf_strraw_explicit (ctf_file_t *, uint32_t,
427*fae548d3Szrj ctf_strs_t *);
428*fae548d3Szrj extern int ctf_str_create_atoms (ctf_file_t *);
429*fae548d3Szrj extern void ctf_str_free_atoms (ctf_file_t *);
430*fae548d3Szrj extern uint32_t ctf_str_add (ctf_file_t *, const char *);
431*fae548d3Szrj extern uint32_t ctf_str_add_ref (ctf_file_t *, const char *, uint32_t *ref);
432*fae548d3Szrj extern int ctf_str_add_external (ctf_file_t *, const char *, uint32_t offset);
433*fae548d3Szrj extern void ctf_str_remove_ref (ctf_file_t *, const char *, uint32_t *ref);
434*fae548d3Szrj extern void ctf_str_rollback (ctf_file_t *, ctf_snapshot_id_t);
435*fae548d3Szrj extern void ctf_str_purge_refs (ctf_file_t *);
436*fae548d3Szrj extern ctf_strs_writable_t ctf_str_write_strtab (ctf_file_t *);
437*fae548d3Szrj
438*fae548d3Szrj extern struct ctf_archive *ctf_arc_open_internal (const char *, int *);
439*fae548d3Szrj extern struct ctf_archive *ctf_arc_bufopen (const void *, size_t, int *);
440*fae548d3Szrj extern void ctf_arc_close_internal (struct ctf_archive *);
441*fae548d3Szrj extern void *ctf_set_open_errno (int *, int);
442*fae548d3Szrj extern unsigned long ctf_set_errno (ctf_file_t *, int);
443*fae548d3Szrj
444*fae548d3Szrj extern ctf_file_t *ctf_simple_open_internal (const char *, size_t, const char *,
445*fae548d3Szrj size_t, size_t,
446*fae548d3Szrj const char *, size_t,
447*fae548d3Szrj ctf_dynhash_t *, int, int *);
448*fae548d3Szrj extern ctf_file_t *ctf_bufopen_internal (const ctf_sect_t *, const ctf_sect_t *,
449*fae548d3Szrj const ctf_sect_t *, ctf_dynhash_t *,
450*fae548d3Szrj int, int *);
451*fae548d3Szrj extern int ctf_serialize (ctf_file_t *);
452*fae548d3Szrj
453*fae548d3Szrj _libctf_malloc_
454*fae548d3Szrj extern void *ctf_mmap (size_t length, size_t offset, int fd);
455*fae548d3Szrj extern void ctf_munmap (void *, size_t);
456*fae548d3Szrj extern ssize_t ctf_pread (int fd, void *buf, ssize_t count, off_t offset);
457*fae548d3Szrj
458*fae548d3Szrj extern void *ctf_realloc (ctf_file_t *, void *, size_t);
459*fae548d3Szrj extern char *ctf_str_append (char *, const char *);
460*fae548d3Szrj extern char *ctf_str_append_noerr (char *, const char *);
461*fae548d3Szrj extern const char *ctf_strerror (int);
462*fae548d3Szrj
463*fae548d3Szrj extern ctf_id_t ctf_type_resolve_unsliced (ctf_file_t *, ctf_id_t);
464*fae548d3Szrj extern int ctf_type_kind_unsliced (ctf_file_t *, ctf_id_t);
465*fae548d3Szrj
466*fae548d3Szrj _libctf_printflike_ (1, 2)
467*fae548d3Szrj extern void ctf_dprintf (const char *, ...);
468*fae548d3Szrj extern void libctf_init_debug (void);
469*fae548d3Szrj
470*fae548d3Szrj extern Elf64_Sym *ctf_sym_to_elf64 (const Elf32_Sym *src, Elf64_Sym *dst);
471*fae548d3Szrj extern const char *ctf_lookup_symbol_name (ctf_file_t *fp, unsigned long symidx);
472*fae548d3Szrj
473*fae548d3Szrj /* Variables, all underscore-prepended. */
474*fae548d3Szrj
475*fae548d3Szrj extern const char _CTF_SECTION[]; /* name of CTF ELF section */
476*fae548d3Szrj extern const char _CTF_NULLSTR[]; /* empty string */
477*fae548d3Szrj
478*fae548d3Szrj extern int _libctf_version; /* library client version */
479*fae548d3Szrj extern int _libctf_debug; /* debugging messages enabled */
480*fae548d3Szrj
481*fae548d3Szrj #ifdef __cplusplus
482*fae548d3Szrj }
483*fae548d3Szrj #endif
484*fae548d3Szrj
485*fae548d3Szrj #endif /* _CTF_IMPL_H */
486