1 /* Symbol, variable and name lookup.
2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
4 This file is part of libctf.
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
25 /* Grow the pptrtab so that it is at least NEW_LEN long. */
27 grow_pptrtab (ctf_dict_t
*fp
, size_t new_len
)
29 uint32_t *new_pptrtab
;
31 if ((new_pptrtab
= realloc (fp
->ctf_pptrtab
, sizeof (uint32_t)
33 return (ctf_set_errno (fp
, ENOMEM
));
35 fp
->ctf_pptrtab
= new_pptrtab
;
37 memset (fp
->ctf_pptrtab
+ fp
->ctf_pptrtab_len
, 0,
38 sizeof (uint32_t) * (new_len
- fp
->ctf_pptrtab_len
));
40 fp
->ctf_pptrtab_len
= new_len
;
44 /* Update entries in the pptrtab that relate to types newly added in the
47 refresh_pptrtab (ctf_dict_t
*fp
, ctf_dict_t
*pfp
)
50 for (i
= fp
->ctf_pptrtab_typemax
; i
<= fp
->ctf_typemax
; i
++)
52 ctf_id_t type
= LCTF_INDEX_TO_TYPE (fp
, i
, 1);
55 if (ctf_type_kind (fp
, type
) != CTF_K_POINTER
)
58 reffed_type
= ctf_type_reference (fp
, type
);
60 if (LCTF_TYPE_ISPARENT (fp
, reffed_type
))
62 uint32_t idx
= LCTF_TYPE_TO_INDEX (fp
, reffed_type
);
64 /* Guard against references to invalid types. No need to consider
65 the CTF dict corrupt in this case: this pointer just can't be a
66 pointer to any type we know about. */
67 if (idx
<= pfp
->ctf_typemax
)
69 if (idx
>= fp
->ctf_pptrtab_len
70 && grow_pptrtab (fp
, pfp
->ctf_ptrtab_len
) < 0)
71 return -1; /* errno is set for us. */
73 fp
->ctf_pptrtab
[idx
] = i
;
78 fp
->ctf_pptrtab_typemax
= fp
->ctf_typemax
;
83 /* Compare the given input string and length against a table of known C storage
84 qualifier keywords. We just ignore these in ctf_lookup_by_name, below. To
85 do this quickly, we use a pre-computed Perfect Hash Function similar to the
86 technique originally described in the classic paper:
88 R.J. Cichelli, "Minimal Perfect Hash Functions Made Simple",
89 Communications of the ACM, Volume 23, Issue 1, January 1980, pp. 17-19.
91 For an input string S of length N, we use hash H = S[N - 1] + N - 105, which
92 for the current set of qualifiers yields a unique H in the range [0 .. 20].
93 The hash can be modified when the keyword set changes as necessary. We also
94 store the length of each keyword and check it prior to the final strcmp().
96 TODO: just use gperf. */
99 isqualifier (const char *s
, size_t len
)
101 static const struct qual
106 {"static", 6}, {"", 0}, {"", 0}, {"", 0},
107 {"volatile", 8}, {"", 0}, {"", 0}, {"", 0}, {"", 0},
108 {"", 0}, {"auto", 4}, {"extern", 6}, {"", 0}, {"", 0},
109 {"", 0}, {"", 0}, {"const", 5}, {"register", 8},
110 {"", 0}, {"restrict", 8}, {"_Restrict", 9}
113 int h
= s
[len
- 1] + (int) len
- 105;
114 const struct qual
*qp
;
116 if (h
< 0 || (size_t) h
>= sizeof (qhash
) / sizeof (qhash
[0]))
121 return ((size_t) len
== qp
->q_len
&&
122 strncmp (qp
->q_name
, s
, qp
->q_len
) == 0);
125 /* Attempt to convert the given C type name into the corresponding CTF type ID.
126 It is not possible to do complete and proper conversion of type names
127 without implementing a more full-fledged parser, which is necessary to
128 handle things like types that are function pointers to functions that
129 have arguments that are function pointers, and fun stuff like that.
130 Instead, this function implements a very simple conversion algorithm that
131 finds the things that we actually care about: structs, unions, enums,
132 integers, floats, typedefs, and pointers to any of these named types. */
135 ctf_lookup_by_name_internal (ctf_dict_t
*fp
, ctf_dict_t
*child
,
138 static const char delimiters
[] = " \t\n\r\v\f*";
140 const ctf_lookup_t
*lp
;
141 const char *p
, *q
, *end
;
143 ctf_id_t ntype
, ptype
;
146 return (ctf_set_typed_errno (fp
, EINVAL
));
148 for (p
= name
, end
= name
+ strlen (name
); *p
!= '\0'; p
= q
)
150 while (isspace ((int) *p
))
151 p
++; /* Skip leading whitespace. */
156 if ((q
= strpbrk (p
+ 1, delimiters
)) == NULL
)
157 q
= end
; /* Compare until end. */
161 /* Find a pointer to type by looking in child->ctf_pptrtab (if child
162 is set) and fp->ctf_ptrtab. If we can't find a pointer to the
163 given type, see if we can compute a pointer to the type resulting
164 from resolving the type down to its base type and use that instead.
165 This helps with cases where the CTF data includes "struct foo *"
166 but not "foo_t *" and the user tries to access "foo_t *" in the
169 There is extra complexity here because uninitialized elements in
170 the pptrtab and ptrtab are set to zero, but zero (as the type ID
171 meaning the unimplemented type) is a valid return type from
172 ctf_lookup_by_name. (Pointers to types are never of type 0, so
173 this is unambiguous, just fiddly to deal with.) */
175 uint32_t idx
= LCTF_TYPE_TO_INDEX (fp
, type
);
179 if (child
&& idx
< child
->ctf_pptrtab_len
)
181 ntype
= child
->ctf_pptrtab
[idx
];
188 if (ntype
== CTF_ERR
)
190 ntype
= fp
->ctf_ptrtab
[idx
];
195 /* Try resolving to its base type and check again. */
196 if (ntype
== CTF_ERR
)
199 ntype
= ctf_type_resolve_unsliced (child
, type
);
201 ntype
= ctf_type_resolve_unsliced (fp
, type
);
203 if (ntype
== CTF_ERR
)
206 idx
= LCTF_TYPE_TO_INDEX (fp
, ntype
);
209 if (child
&& idx
< child
->ctf_pptrtab_len
)
211 ntype
= child
->ctf_pptrtab
[idx
];
218 if (ntype
== CTF_ERR
)
220 ntype
= fp
->ctf_ptrtab
[idx
];
224 if (ntype
== CTF_ERR
)
228 type
= LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)
231 /* We are looking up a type in the parent, but the pointed-to type is
232 in the child. Switch to looking in the child: if we need to go
233 back into the parent, we can recurse again. */
244 if (isqualifier (p
, (size_t) (q
- p
)))
245 continue; /* Skip qualifier keyword. */
247 for (lp
= fp
->ctf_lookups
; lp
->ctl_prefix
!= NULL
; lp
++)
249 /* TODO: This is not MT-safe. */
250 if ((lp
->ctl_prefix
[0] == '\0' ||
251 strncmp (p
, lp
->ctl_prefix
, (size_t) (q
- p
)) == 0) &&
252 (size_t) (q
- p
) >= lp
->ctl_len
)
254 for (p
+= lp
->ctl_len
; isspace ((int) *p
); p
++)
255 continue; /* Skip prefix and next whitespace. */
257 if ((q
= strchr (p
, '*')) == NULL
)
258 q
= end
; /* Compare until end. */
260 while (isspace ((int) q
[-1]))
261 q
--; /* Exclude trailing whitespace. */
263 /* Expand and/or allocate storage for a slice of the name, then
266 if (fp
->ctf_tmp_typeslicelen
>= (size_t) (q
- p
) + 1)
268 memcpy (fp
->ctf_tmp_typeslice
, p
, (size_t) (q
- p
));
269 fp
->ctf_tmp_typeslice
[(size_t) (q
- p
)] = '\0';
273 free (fp
->ctf_tmp_typeslice
);
274 fp
->ctf_tmp_typeslice
= xstrndup (p
, (size_t) (q
- p
));
275 if (fp
->ctf_tmp_typeslice
== NULL
)
276 return ctf_set_typed_errno (fp
, ENOMEM
);
279 if ((type
= ctf_lookup_by_rawhash (fp
, lp
->ctl_hash
,
280 fp
->ctf_tmp_typeslice
)) == 0)
287 if (lp
->ctl_prefix
== NULL
)
291 if (*p
!= '\0' || type
== 0)
292 return (ctf_set_typed_errno (fp
, ECTF_SYNTAX
));
297 ctf_set_errno (fp
, ECTF_NOTYPE
);
298 if (fp
->ctf_parent
!= NULL
)
300 /* Need to look up in the parent, from the child's perspective.
301 Make sure the pptrtab is up to date. */
303 if (fp
->ctf_pptrtab_typemax
< fp
->ctf_typemax
)
305 if (refresh_pptrtab (fp
, fp
->ctf_parent
) < 0)
306 return CTF_ERR
; /* errno is set for us. */
309 if ((ptype
= ctf_lookup_by_name_internal (fp
->ctf_parent
, fp
,
312 return (ctf_set_typed_errno (fp
, ctf_errno (fp
->ctf_parent
)));
319 ctf_lookup_by_name (ctf_dict_t
*fp
, const char *name
)
321 return ctf_lookup_by_name_internal (fp
, NULL
, name
);
324 /* Return the pointer to the internal CTF type data corresponding to the
325 given type ID. If the ID is invalid, the function returns NULL.
326 This function is not exported outside of the library. */
329 ctf_lookup_by_id (ctf_dict_t
**fpp
, ctf_id_t type
)
331 ctf_dict_t
*fp
= *fpp
; /* Caller passes in starting CTF dict. */
334 if ((fp
= ctf_get_dict (fp
, type
)) == NULL
)
336 (void) ctf_set_errno (*fpp
, ECTF_NOPARENT
);
340 /* If this dict is writable, check for a dynamic type. */
342 if (fp
->ctf_flags
& LCTF_RDWR
)
346 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
349 return &dtd
->dtd_data
;
351 (void) ctf_set_errno (*fpp
, ECTF_BADID
);
355 /* Check for a type in the static portion. */
357 idx
= LCTF_TYPE_TO_INDEX (fp
, type
);
358 if (idx
> 0 && (unsigned long) idx
<= fp
->ctf_typemax
)
360 *fpp
= fp
; /* Function returns ending CTF dict. */
361 return (LCTF_INDEX_TO_TYPEPTR (fp
, idx
));
364 (void) ctf_set_errno (*fpp
, ECTF_BADID
);
368 typedef struct ctf_lookup_idx_key
371 const char *clik_name
;
372 uint32_t *clik_names
;
373 } ctf_lookup_idx_key_t
;
375 /* A bsearch function for variable names. */
378 ctf_lookup_var (const void *key_
, const void *lookup_
)
380 const ctf_lookup_idx_key_t
*key
= key_
;
381 const ctf_varent_t
*lookup
= lookup_
;
383 return (strcmp (key
->clik_name
, ctf_strptr (key
->clik_fp
, lookup
->ctv_name
)));
386 /* Given a variable name, return the type of the variable with that name. */
389 ctf_lookup_variable (ctf_dict_t
*fp
, const char *name
)
392 ctf_lookup_idx_key_t key
= { fp
, name
, NULL
};
394 /* This array is sorted, so we can bsearch for it. */
396 ent
= bsearch (&key
, fp
->ctf_vars
, fp
->ctf_nvars
, sizeof (ctf_varent_t
),
401 if (fp
->ctf_parent
!= NULL
)
405 if ((ptype
= ctf_lookup_variable (fp
->ctf_parent
, name
)) != CTF_ERR
)
407 return (ctf_set_typed_errno (fp
, ctf_errno (fp
->ctf_parent
)));
410 return (ctf_set_typed_errno (fp
, ECTF_NOTYPEDAT
));
413 return ent
->ctv_type
;
416 typedef struct ctf_symidx_sort_arg_cb
420 } ctf_symidx_sort_arg_cb_t
;
423 sort_symidx_by_name (const void *one_
, const void *two_
, void *arg_
)
425 const uint32_t *one
= one_
;
426 const uint32_t *two
= two_
;
427 ctf_symidx_sort_arg_cb_t
*arg
= arg_
;
429 return (strcmp (ctf_strptr (arg
->fp
, arg
->names
[*one
]),
430 ctf_strptr (arg
->fp
, arg
->names
[*two
])));
433 /* Sort a symbol index section by name. Takes a 1:1 mapping of names to the
434 corresponding symbol table. Returns a lexicographically sorted array of idx
435 indexes (and thus, of indexes into the corresponding func info / data object
439 ctf_symidx_sort (ctf_dict_t
*fp
, uint32_t *idx
, size_t *nidx
,
445 if ((sorted
= malloc (len
)) == NULL
)
447 ctf_set_errno (fp
, ENOMEM
);
451 *nidx
= len
/ sizeof (uint32_t);
452 for (i
= 0; i
< *nidx
; i
++)
455 if (!(fp
->ctf_header
->cth_flags
& CTF_F_IDXSORTED
))
457 ctf_symidx_sort_arg_cb_t arg
= { fp
, idx
};
458 ctf_dprintf ("Index section unsorted: sorting.");
459 ctf_qsort_r (sorted
, *nidx
, sizeof (uint32_t), sort_symidx_by_name
, &arg
);
460 fp
->ctf_header
->cth_flags
|= CTF_F_IDXSORTED
;
466 /* Given a symbol index, return the name of that symbol from the table provided
467 by ctf_link_shuffle_syms, or failing that from the secondary string table, or
470 ctf_lookup_symbol_name (ctf_dict_t
*fp
, unsigned long symidx
)
472 const ctf_sect_t
*sp
= &fp
->ctf_symtab
;
476 if (fp
->ctf_dynsymidx
)
479 if (symidx
> fp
->ctf_dynsymmax
)
482 ctf_link_sym_t
*symp
= fp
->ctf_dynsymidx
[symidx
];
487 return symp
->st_name
;
491 if (sp
->cts_data
== NULL
)
494 if (symidx
>= fp
->ctf_nsyms
)
497 switch (sp
->cts_entsize
)
499 case sizeof (Elf64_Sym
):
501 const Elf64_Sym
*symp
= (Elf64_Sym
*) sp
->cts_data
+ symidx
;
502 ctf_elf64_to_link_sym (fp
, &sym
, symp
, symidx
);
505 case sizeof (Elf32_Sym
):
507 const Elf32_Sym
*symp
= (Elf32_Sym
*) sp
->cts_data
+ symidx
;
508 ctf_elf32_to_link_sym (fp
, &sym
, symp
, symidx
);
512 ctf_set_errno (fp
, ECTF_SYMTAB
);
516 assert (!sym
.st_nameidx_set
);
524 ret
= ctf_lookup_symbol_name (fp
->ctf_parent
, symidx
);
526 ctf_set_errno (fp
, ctf_errno (fp
->ctf_parent
));
531 ctf_set_errno (fp
, err
);
536 /* Given a symbol name, return the index of that symbol, or -1 on error or if
539 ctf_lookup_symbol_idx (ctf_dict_t
*fp
, const char *symname
)
541 const ctf_sect_t
*sp
= &fp
->ctf_symtab
;
545 ctf_dict_t
*cache
= fp
;
551 ctf_link_sym_t
*symp
;
553 if ((symp
= ctf_dynhash_lookup (fp
->ctf_dynsyms
, symname
)) == NULL
)
556 return symp
->st_symidx
;
560 if (sp
->cts_data
== NULL
)
563 /* First, try a hash lookup to see if we have already spotted this symbol
564 during a past iteration: create the hash first if need be. The lifespan
565 of the strings is equal to the lifespan of the cts_data, so we don't
566 need to strdup them. If this dict was opened as part of an archive,
567 and this archive has designed a crossdict_cache to cache results that
568 are the same across all dicts in an archive, use it. */
570 if (fp
->ctf_archive
&& fp
->ctf_archive
->ctfi_crossdict_cache
)
571 cache
= fp
->ctf_archive
->ctfi_crossdict_cache
;
573 if (!cache
->ctf_symhash
)
574 if ((cache
->ctf_symhash
= ctf_dynhash_create (ctf_hash_string
,
576 NULL
, NULL
)) == NULL
)
579 if (ctf_dynhash_lookup_kv (cache
->ctf_symhash
, symname
, NULL
, &known_idx
))
580 return (unsigned long) (uintptr_t) known_idx
;
582 /* Hash lookup unsuccessful: linear search, populating the hashtab for later
585 for (; cache
->ctf_symhash_latest
< sp
->cts_size
/ sp
->cts_entsize
;
586 cache
->ctf_symhash_latest
++)
588 switch (sp
->cts_entsize
)
590 case sizeof (Elf64_Sym
):
592 Elf64_Sym
*symp
= (Elf64_Sym
*) sp
->cts_data
;
593 ctf_elf64_to_link_sym (fp
, &sym
, &symp
[cache
->ctf_symhash_latest
],
594 cache
->ctf_symhash_latest
);
595 if (!ctf_dynhash_lookup_kv (cache
->ctf_symhash
, sym
.st_name
,
597 if (ctf_dynhash_cinsert (cache
->ctf_symhash
, sym
.st_name
,
598 (const void *) (uintptr_t)
599 cache
->ctf_symhash_latest
) < 0)
601 if (strcmp (sym
.st_name
, symname
) == 0)
602 return cache
->ctf_symhash_latest
++;
605 case sizeof (Elf32_Sym
):
607 Elf32_Sym
*symp
= (Elf32_Sym
*) sp
->cts_data
;
608 ctf_elf32_to_link_sym (fp
, &sym
, &symp
[cache
->ctf_symhash_latest
],
609 cache
->ctf_symhash_latest
);
610 if (!ctf_dynhash_lookup_kv (cache
->ctf_symhash
, sym
.st_name
,
612 if (ctf_dynhash_cinsert (cache
->ctf_symhash
, sym
.st_name
,
613 (const void *) (uintptr_t)
614 cache
->ctf_symhash_latest
) < 0)
616 if (strcmp (sym
.st_name
, symname
) == 0)
617 return cache
->ctf_symhash_latest
++;
621 ctf_set_errno (fp
, ECTF_SYMTAB
);
622 return (unsigned long) -1;
626 /* Searched everything, still not found. */
628 return (unsigned long) -1;
635 if ((psym
= ctf_lookup_symbol_idx (fp
->ctf_parent
, symname
))
636 != (unsigned long) -1)
639 ctf_set_errno (fp
, ctf_errno (fp
->ctf_parent
));
640 return (unsigned long) -1;
644 ctf_set_errno (fp
, err
);
645 return (unsigned long) -1;
648 ctf_set_errno (fp
, ENOMEM
);
649 ctf_err_warn (fp
, 0, ENOMEM
, _("cannot allocate memory for symbol "
651 return (unsigned long) -1;
655 /* Iterate over all symbols with types: if FUNC, function symbols, otherwise,
656 data symbols. The name argument is not optional. The return order is
657 arbitrary, though is likely to be in symbol index or name order. You can
658 change the value of 'functions' in the middle of iteration over non-dynamic
659 dicts, but doing so on dynamic dicts will fail. (This is probably not very
660 useful, but there is no reason to prohibit it.) */
663 ctf_symbol_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
,
666 ctf_id_t sym
= CTF_ERR
;
672 if ((i
= ctf_next_create ()) == NULL
)
673 return ctf_set_typed_errno (fp
, ENOMEM
);
676 i
->ctn_iter_fun
= (void (*) (void)) ctf_symbol_next
;
681 if ((void (*) (void)) ctf_symbol_next
!= i
->ctn_iter_fun
)
682 return (ctf_set_typed_errno (fp
, ECTF_NEXT_WRONGFUN
));
684 if (fp
!= i
->cu
.ctn_fp
)
685 return (ctf_set_typed_errno (fp
, ECTF_NEXT_WRONGFP
));
687 /* We intentionally use raw access, not ctf_lookup_by_symbol, to avoid
688 incurring additional sorting cost for unsorted symtypetabs coming from the
689 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and
690 finally because it's easier to work out what the name of each symbol is if
693 if (fp
->ctf_flags
& LCTF_RDWR
)
695 ctf_dynhash_t
*dynh
= functions
? fp
->ctf_funchash
: fp
->ctf_objthash
;
696 void *dyn_name
= NULL
, *dyn_value
= NULL
;
700 ctf_next_destroy (i
);
701 return (ctf_set_typed_errno (fp
, ECTF_NEXT_END
));
704 err
= ctf_dynhash_next (dynh
, &i
->ctn_next
, &dyn_name
, &dyn_value
);
705 /* This covers errors and also end-of-iteration. */
708 ctf_next_destroy (i
);
710 return ctf_set_typed_errno (fp
, err
);
714 sym
= (ctf_id_t
) (uintptr_t) dyn_value
;
716 else if ((!functions
&& fp
->ctf_objtidx_names
) ||
717 (functions
&& fp
->ctf_funcidx_names
))
719 ctf_header_t
*hp
= fp
->ctf_header
;
720 uint32_t *idx
= functions
? fp
->ctf_funcidx_names
: fp
->ctf_objtidx_names
;
726 len
= (hp
->cth_varoff
- hp
->cth_funcidxoff
) / sizeof (uint32_t);
727 tab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_funcoff
);
731 len
= (hp
->cth_funcidxoff
- hp
->cth_objtidxoff
) / sizeof (uint32_t);
732 tab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_objtoff
);
740 *name
= ctf_strptr (fp
, idx
[i
->ctn_n
]);
741 sym
= tab
[i
->ctn_n
++];
743 while (sym
== -1u || sym
== 0);
747 /* Skip over pads in ctf_xslate, padding for typeless symbols in the
748 symtypetab itself, and symbols in the wrong table. */
749 for (; i
->ctn_n
< fp
->ctf_nsyms
; i
->ctn_n
++)
751 ctf_header_t
*hp
= fp
->ctf_header
;
753 if (fp
->ctf_sxlate
[i
->ctn_n
] == -1u)
756 sym
= *(uint32_t *) ((uintptr_t) fp
->ctf_buf
+ fp
->ctf_sxlate
[i
->ctn_n
]);
763 if (fp
->ctf_sxlate
[i
->ctn_n
] >= hp
->cth_funcoff
764 && fp
->ctf_sxlate
[i
->ctn_n
] < hp
->cth_objtidxoff
)
769 if (fp
->ctf_sxlate
[i
->ctn_n
] >= hp
->cth_objtoff
770 && fp
->ctf_sxlate
[i
->ctn_n
] < hp
->cth_funcoff
)
775 if (i
->ctn_n
>= fp
->ctf_nsyms
)
778 *name
= ctf_lookup_symbol_name (fp
, i
->ctn_n
++);
784 ctf_next_destroy (i
);
786 return (ctf_set_typed_errno (fp
, ECTF_NEXT_END
));
789 /* A bsearch function for function and object index names. */
792 ctf_lookup_idx_name (const void *key_
, const void *idx_
)
794 const ctf_lookup_idx_key_t
*key
= key_
;
795 const uint32_t *idx
= idx_
;
797 return (strcmp (key
->clik_name
, ctf_strptr (key
->clik_fp
, key
->clik_names
[*idx
])));
800 /* Given a symbol name or (failing that) number, look up that symbol in the
801 function or object index table (which must exist). Return 0 if not found
805 ctf_try_lookup_indexed (ctf_dict_t
*fp
, unsigned long symidx
,
806 const char *symname
, int is_function
)
808 struct ctf_header
*hp
= fp
->ctf_header
;
809 uint32_t *symtypetab
;
815 symname
= ctf_lookup_symbol_name (fp
, symidx
);
817 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in "
818 "indexed symtypetab\n", symidx
, symname
);
820 if (symname
[0] == '\0')
821 return CTF_ERR
; /* errno is set for us. */
825 if (!fp
->ctf_funcidx_sxlate
)
827 if ((fp
->ctf_funcidx_sxlate
828 = ctf_symidx_sort (fp
, (uint32_t *)
829 (fp
->ctf_buf
+ hp
->cth_funcidxoff
),
831 hp
->cth_varoff
- hp
->cth_funcidxoff
))
834 ctf_err_warn (fp
, 0, 0, _("cannot sort function symidx"));
835 return CTF_ERR
; /* errno is set for us. */
838 symtypetab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_funcoff
);
839 sxlate
= fp
->ctf_funcidx_sxlate
;
840 names
= fp
->ctf_funcidx_names
;
841 nidx
= fp
->ctf_nfuncidx
;
845 if (!fp
->ctf_objtidx_sxlate
)
847 if ((fp
->ctf_objtidx_sxlate
848 = ctf_symidx_sort (fp
, (uint32_t *)
849 (fp
->ctf_buf
+ hp
->cth_objtidxoff
),
851 hp
->cth_funcidxoff
- hp
->cth_objtidxoff
))
854 ctf_err_warn (fp
, 0, 0, _("cannot sort object symidx"));
855 return CTF_ERR
; /* errno is set for us. */
859 symtypetab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_objtoff
);
860 sxlate
= fp
->ctf_objtidx_sxlate
;
861 names
= fp
->ctf_objtidx_names
;
862 nidx
= fp
->ctf_nobjtidx
;
865 ctf_lookup_idx_key_t key
= { fp
, symname
, names
};
868 idx
= bsearch (&key
, sxlate
, nidx
, sizeof (uint32_t), ctf_lookup_idx_name
);
872 ctf_dprintf ("%s not found in idx\n", symname
);
876 /* Should be impossible, but be paranoid. */
877 if ((idx
- sxlate
) > (ptrdiff_t) nidx
)
878 return (ctf_set_typed_errno (fp
, ECTF_CORRUPT
));
880 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx
, symname
,
882 return symtypetab
[*idx
];
885 /* Given a symbol name or (if NULL) symbol index, return the type of the
886 function or data object described by the corresponding entry in the symbol
887 table. We can only return symbols in read-only dicts and in dicts for which
888 ctf_link_shuffle_syms has been called to assign symbol indexes to symbol
892 ctf_lookup_by_sym_or_name (ctf_dict_t
*fp
, unsigned long symidx
,
895 const ctf_sect_t
*sp
= &fp
->ctf_symtab
;
899 /* Shuffled dynsymidx present? Use that. */
900 if (fp
->ctf_dynsymidx
)
902 const ctf_link_sym_t
*sym
;
905 ctf_dprintf ("Looking up type of object with symname %s in "
906 "writable dict symtypetab\n", symname
);
908 ctf_dprintf ("Looking up type of object with symtab idx %lx in "
909 "writable dict symtypetab\n", symidx
);
911 /* The dict must be dynamic. */
912 if (!ctf_assert (fp
, fp
->ctf_flags
& LCTF_RDWR
))
915 /* No name? Need to look it up. */
919 if (symidx
> fp
->ctf_dynsymmax
)
922 sym
= fp
->ctf_dynsymidx
[symidx
];
923 err
= ECTF_NOTYPEDAT
;
924 if (!sym
|| (sym
->st_shndx
!= STT_OBJECT
&& sym
->st_shndx
!= STT_FUNC
))
927 if (!ctf_assert (fp
, !sym
->st_nameidx_set
))
929 symname
= sym
->st_name
;
932 if (fp
->ctf_objthash
== NULL
933 || ((type
= (ctf_id_t
) (uintptr_t)
934 ctf_dynhash_lookup (fp
->ctf_objthash
, symname
)) == 0))
936 if (fp
->ctf_funchash
== NULL
937 || ((type
= (ctf_id_t
) (uintptr_t)
938 ctf_dynhash_lookup (fp
->ctf_funchash
, symname
)) == 0))
945 /* Lookup by name in a dynamic dict: just do it directly. */
946 if (symname
&& fp
->ctf_flags
& LCTF_RDWR
)
948 if (fp
->ctf_objthash
== NULL
949 || ((type
= (ctf_id_t
) (uintptr_t)
950 ctf_dynhash_lookup (fp
->ctf_objthash
, symname
)) == 0))
952 if (fp
->ctf_funchash
== NULL
953 || ((type
= (ctf_id_t
) (uintptr_t)
954 ctf_dynhash_lookup (fp
->ctf_funchash
, symname
)) == 0))
961 if (sp
->cts_data
== NULL
)
964 /* This covers both out-of-range lookups and a dynamic dict which hasn't been
967 if (symname
== NULL
&& symidx
>= fp
->ctf_nsyms
)
970 if (fp
->ctf_objtidx_names
)
972 if ((type
= ctf_try_lookup_indexed (fp
, symidx
, symname
, 0)) == CTF_ERR
)
973 return CTF_ERR
; /* errno is set for us. */
975 if (type
== 0 && fp
->ctf_funcidx_names
)
977 if ((type
= ctf_try_lookup_indexed (fp
, symidx
, symname
, 1)) == CTF_ERR
)
978 return CTF_ERR
; /* errno is set for us. */
983 err
= ECTF_NOTYPEDAT
;
984 if (fp
->ctf_objtidx_names
&& fp
->ctf_funcidx_names
)
987 /* Table must be nonindexed. */
989 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx
);
992 if ((symidx
= ctf_lookup_symbol_idx (fp
, symname
)) == (unsigned long) -1)
995 if (fp
->ctf_sxlate
[symidx
] == -1u)
998 type
= *(uint32_t *) ((uintptr_t) fp
->ctf_buf
+ fp
->ctf_sxlate
[symidx
]);
1007 ctf_id_t ret
= ctf_lookup_by_sym_or_name (fp
->ctf_parent
, symidx
,
1010 ctf_set_errno (fp
, ctf_errno (fp
->ctf_parent
));
1014 return (ctf_set_typed_errno (fp
, err
));
1017 /* Given a symbol table index, return the type of the function or data object
1018 described by the corresponding entry in the symbol table. */
1020 ctf_lookup_by_symbol (ctf_dict_t
*fp
, unsigned long symidx
)
1022 return ctf_lookup_by_sym_or_name (fp
, symidx
, NULL
);
1025 /* Given a symbol name, return the type of the function or data object described
1026 by the corresponding entry in the symbol table. */
1028 ctf_lookup_by_symbol_name (ctf_dict_t
*fp
, const char *symname
)
1030 return ctf_lookup_by_sym_or_name (fp
, 0, symname
);
1033 /* Given a symbol table index, return the info for the function described
1034 by the corresponding entry in the symbol table, which may be a function
1035 symbol or may be a data symbol that happens to be a function pointer. */
1038 ctf_func_info (ctf_dict_t
*fp
, unsigned long symidx
, ctf_funcinfo_t
*fip
)
1042 if ((type
= ctf_lookup_by_symbol (fp
, symidx
)) == CTF_ERR
)
1043 return -1; /* errno is set for us. */
1045 if (ctf_type_kind (fp
, type
) != CTF_K_FUNCTION
)
1046 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1048 return ctf_func_type_info (fp
, type
, fip
);
1051 /* Given a symbol table index, return the arguments for the function described
1052 by the corresponding entry in the symbol table. */
1055 ctf_func_args (ctf_dict_t
*fp
, unsigned long symidx
, uint32_t argc
,
1060 if ((type
= ctf_lookup_by_symbol (fp
, symidx
)) == CTF_ERR
)
1061 return -1; /* errno is set for us. */
1063 if (ctf_type_kind (fp
, type
) != CTF_K_FUNCTION
)
1064 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1066 return ctf_func_type_args (fp
, type
, argc
, argv
);