1 /* Symbol, variable and name lookup.
2 Copyright (C) 2019-2021 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
= &qhash
[h
];
116 return (h
>= 0 && (size_t) h
< sizeof (qhash
) / sizeof (qhash
[0])
117 && (size_t) len
== qp
->q_len
&&
118 strncmp (qp
->q_name
, s
, qp
->q_len
) == 0);
121 /* Attempt to convert the given C type name into the corresponding CTF type ID.
122 It is not possible to do complete and proper conversion of type names
123 without implementing a more full-fledged parser, which is necessary to
124 handle things like types that are function pointers to functions that
125 have arguments that are function pointers, and fun stuff like that.
126 Instead, this function implements a very simple conversion algorithm that
127 finds the things that we actually care about: structs, unions, enums,
128 integers, floats, typedefs, and pointers to any of these named types. */
131 ctf_lookup_by_name_internal (ctf_dict_t
*fp
, ctf_dict_t
*child
,
134 static const char delimiters
[] = " \t\n\r\v\f*";
136 const ctf_lookup_t
*lp
;
137 const char *p
, *q
, *end
;
139 ctf_id_t ntype
, ptype
;
142 return (ctf_set_errno (fp
, EINVAL
));
144 for (p
= name
, end
= name
+ strlen (name
); *p
!= '\0'; p
= q
)
146 while (isspace ((int) *p
))
147 p
++; /* Skip leading whitespace. */
152 if ((q
= strpbrk (p
+ 1, delimiters
)) == NULL
)
153 q
= end
; /* Compare until end. */
157 /* Find a pointer to type by looking in child->ctf_pptrtab (if child
158 is set) and fp->ctf_ptrtab. If we can't find a pointer to the
159 given type, see if we can compute a pointer to the type resulting
160 from resolving the type down to its base type and use that instead.
161 This helps with cases where the CTF data includes "struct foo *"
162 but not "foo_t *" and the user tries to access "foo_t *" in the
165 There is extra complexity here because uninitialized elements in
166 the pptrtab and ptrtab are set to zero, but zero (as the type ID
167 meaning the unimplemented type) is a valid return type from
168 ctf_lookup_by_name. (Pointers to types are never of type 0, so
169 this is unambiguous, just fiddly to deal with.) */
171 uint32_t idx
= LCTF_TYPE_TO_INDEX (fp
, type
);
175 if (child
&& idx
<= child
->ctf_pptrtab_len
)
177 ntype
= child
->ctf_pptrtab
[idx
];
184 if (ntype
== CTF_ERR
)
186 ntype
= fp
->ctf_ptrtab
[idx
];
191 /* Try resolving to its base type and check again. */
192 if (ntype
== CTF_ERR
)
195 ntype
= ctf_type_resolve_unsliced (child
, type
);
197 ntype
= ctf_type_resolve_unsliced (fp
, type
);
199 if (ntype
== CTF_ERR
)
202 idx
= LCTF_TYPE_TO_INDEX (fp
, ntype
);
205 if (child
&& idx
<= child
->ctf_pptrtab_len
)
207 ntype
= child
->ctf_pptrtab
[idx
];
214 if (ntype
== CTF_ERR
)
216 ntype
= fp
->ctf_ptrtab
[idx
];
220 if (ntype
== CTF_ERR
)
224 type
= LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)
227 /* We are looking up a type in the parent, but the pointed-to type is
228 in the child. Switch to looking in the child: if we need to go
229 back into the parent, we can recurse again. */
240 if (isqualifier (p
, (size_t) (q
- p
)))
241 continue; /* Skip qualifier keyword. */
243 for (lp
= fp
->ctf_lookups
; lp
->ctl_prefix
!= NULL
; lp
++)
245 /* TODO: This is not MT-safe. */
246 if ((lp
->ctl_prefix
[0] == '\0' ||
247 strncmp (p
, lp
->ctl_prefix
, (size_t) (q
- p
)) == 0) &&
248 (size_t) (q
- p
) >= lp
->ctl_len
)
250 for (p
+= lp
->ctl_len
; isspace ((int) *p
); p
++)
251 continue; /* Skip prefix and next whitespace. */
253 if ((q
= strchr (p
, '*')) == NULL
)
254 q
= end
; /* Compare until end. */
256 while (isspace ((int) q
[-1]))
257 q
--; /* Exclude trailing whitespace. */
259 /* Expand and/or allocate storage for a slice of the name, then
262 if (fp
->ctf_tmp_typeslicelen
>= (size_t) (q
- p
) + 1)
264 memcpy (fp
->ctf_tmp_typeslice
, p
, (size_t) (q
- p
));
265 fp
->ctf_tmp_typeslice
[(size_t) (q
- p
)] = '\0';
269 free (fp
->ctf_tmp_typeslice
);
270 fp
->ctf_tmp_typeslice
= xstrndup (p
, (size_t) (q
- p
));
271 if (fp
->ctf_tmp_typeslice
== NULL
)
273 ctf_set_errno (fp
, ENOMEM
);
278 if ((type
= ctf_lookup_by_rawhash (fp
, lp
->ctl_hash
,
279 fp
->ctf_tmp_typeslice
)) == 0)
286 if (lp
->ctl_prefix
== NULL
)
290 if (*p
!= '\0' || type
== 0)
291 return (ctf_set_errno (fp
, ECTF_SYNTAX
));
296 ctf_set_errno (fp
, ECTF_NOTYPE
);
297 if (fp
->ctf_parent
!= NULL
)
299 /* Need to look up in the parent, from the child's perspective.
300 Make sure the pptrtab is up to date. */
302 if (fp
->ctf_pptrtab_typemax
< fp
->ctf_typemax
)
304 if (refresh_pptrtab (fp
, fp
->ctf_parent
) < 0)
305 return -1; /* errno is set for us. */
308 if ((ptype
= ctf_lookup_by_name_internal (fp
->ctf_parent
, fp
,
311 return (ctf_set_errno (fp
, ctf_errno (fp
->ctf_parent
)));
318 ctf_lookup_by_name (ctf_dict_t
*fp
, const char *name
)
320 return ctf_lookup_by_name_internal (fp
, NULL
, name
);
323 /* Return the pointer to the internal CTF type data corresponding to the
324 given type ID. If the ID is invalid, the function returns NULL.
325 This function is not exported outside of the library. */
328 ctf_lookup_by_id (ctf_dict_t
**fpp
, ctf_id_t type
)
330 ctf_dict_t
*fp
= *fpp
; /* Caller passes in starting CTF dict. */
333 if ((fp
= ctf_get_dict (fp
, type
)) == NULL
)
335 (void) ctf_set_errno (*fpp
, ECTF_NOPARENT
);
339 /* If this dict is writable, check for a dynamic type. */
341 if (fp
->ctf_flags
& LCTF_RDWR
)
345 if ((dtd
= ctf_dynamic_type (fp
, type
)) != NULL
)
348 return &dtd
->dtd_data
;
350 (void) ctf_set_errno (*fpp
, ECTF_BADID
);
354 /* Check for a type in the static portion. */
356 idx
= LCTF_TYPE_TO_INDEX (fp
, type
);
357 if (idx
> 0 && (unsigned long) idx
<= fp
->ctf_typemax
)
359 *fpp
= fp
; /* Function returns ending CTF dict. */
360 return (LCTF_INDEX_TO_TYPEPTR (fp
, idx
));
363 (void) ctf_set_errno (*fpp
, ECTF_BADID
);
367 typedef struct ctf_lookup_idx_key
370 const char *clik_name
;
371 uint32_t *clik_names
;
372 } ctf_lookup_idx_key_t
;
374 /* A bsearch function for variable names. */
377 ctf_lookup_var (const void *key_
, const void *lookup_
)
379 const ctf_lookup_idx_key_t
*key
= key_
;
380 const ctf_varent_t
*lookup
= lookup_
;
382 return (strcmp (key
->clik_name
, ctf_strptr (key
->clik_fp
, lookup
->ctv_name
)));
385 /* Given a variable name, return the type of the variable with that name. */
388 ctf_lookup_variable (ctf_dict_t
*fp
, const char *name
)
391 ctf_lookup_idx_key_t key
= { fp
, name
, NULL
};
393 /* This array is sorted, so we can bsearch for it. */
395 ent
= bsearch (&key
, fp
->ctf_vars
, fp
->ctf_nvars
, sizeof (ctf_varent_t
),
400 if (fp
->ctf_parent
!= NULL
)
401 return ctf_lookup_variable (fp
->ctf_parent
, name
);
403 return (ctf_set_errno (fp
, ECTF_NOTYPEDAT
));
406 return ent
->ctv_type
;
409 typedef struct ctf_symidx_sort_arg_cb
413 } ctf_symidx_sort_arg_cb_t
;
416 sort_symidx_by_name (const void *one_
, const void *two_
, void *arg_
)
418 const uint32_t *one
= one_
;
419 const uint32_t *two
= two_
;
420 ctf_symidx_sort_arg_cb_t
*arg
= arg_
;
422 return (strcmp (ctf_strptr (arg
->fp
, arg
->names
[*one
]),
423 ctf_strptr (arg
->fp
, arg
->names
[*two
])));
426 /* Sort a symbol index section by name. Takes a 1:1 mapping of names to the
427 corresponding symbol table. Returns a lexicographically sorted array of idx
428 indexes (and thus, of indexes into the corresponding func info / data object
432 ctf_symidx_sort (ctf_dict_t
*fp
, uint32_t *idx
, size_t *nidx
,
438 if ((sorted
= malloc (len
)) == NULL
)
440 ctf_set_errno (fp
, ENOMEM
);
444 *nidx
= len
/ sizeof (uint32_t);
445 for (i
= 0; i
< *nidx
; i
++)
448 if (!(fp
->ctf_header
->cth_flags
& CTF_F_IDXSORTED
))
450 ctf_symidx_sort_arg_cb_t arg
= { fp
, idx
};
451 ctf_dprintf ("Index section unsorted: sorting.");
452 ctf_qsort_r (sorted
, *nidx
, sizeof (uint32_t), sort_symidx_by_name
, &arg
);
453 fp
->ctf_header
->cth_flags
|= CTF_F_IDXSORTED
;
459 /* Given a symbol index, return the name of that symbol from the table provided
460 by ctf_link_shuffle_syms, or failing that from the secondary string table, or
463 ctf_lookup_symbol_name (ctf_dict_t
*fp
, unsigned long symidx
)
465 const ctf_sect_t
*sp
= &fp
->ctf_symtab
;
469 if (fp
->ctf_dynsymidx
)
472 if (symidx
> fp
->ctf_dynsymmax
)
475 ctf_link_sym_t
*symp
= fp
->ctf_dynsymidx
[symidx
];
480 return symp
->st_name
;
484 if (sp
->cts_data
== NULL
)
487 if (symidx
>= fp
->ctf_nsyms
)
490 switch (sp
->cts_entsize
)
492 case sizeof (Elf64_Sym
):
494 const Elf64_Sym
*symp
= (Elf64_Sym
*) sp
->cts_data
+ symidx
;
495 ctf_elf64_to_link_sym (fp
, &sym
, symp
, symidx
);
498 case sizeof (Elf32_Sym
):
500 const Elf32_Sym
*symp
= (Elf32_Sym
*) sp
->cts_data
+ symidx
;
501 ctf_elf32_to_link_sym (fp
, &sym
, symp
, symidx
);
505 ctf_set_errno (fp
, ECTF_SYMTAB
);
509 assert (!sym
.st_nameidx_set
);
517 ret
= ctf_lookup_symbol_name (fp
->ctf_parent
, symidx
);
519 ctf_set_errno (fp
, ctf_errno (fp
->ctf_parent
));
524 ctf_set_errno (fp
, err
);
529 /* Given a symbol name, return the index of that symbol, or -1 on error or if
532 ctf_lookup_symbol_idx (ctf_dict_t
*fp
, const char *symname
)
534 const ctf_sect_t
*sp
= &fp
->ctf_symtab
;
538 ctf_dict_t
*cache
= fp
;
544 ctf_link_sym_t
*symp
;
546 if ((symp
= ctf_dynhash_lookup (fp
->ctf_dynsyms
, symname
)) == NULL
)
549 return symp
->st_symidx
;
553 if (sp
->cts_data
== NULL
)
556 /* First, try a hash lookup to see if we have already spotted this symbol
557 during a past iteration: create the hash first if need be. The lifespan
558 of the strings is equal to the lifespan of the cts_data, so we don't
559 need to strdup them. If this dict was opened as part of an archive,
560 and this archive has designed a crossdict_cache to cache results that
561 are the same across all dicts in an archive, use it. */
563 if (fp
->ctf_archive
&& fp
->ctf_archive
->ctfi_crossdict_cache
)
564 cache
= fp
->ctf_archive
->ctfi_crossdict_cache
;
566 if (!cache
->ctf_symhash
)
567 if ((cache
->ctf_symhash
= ctf_dynhash_create (ctf_hash_string
,
569 NULL
, NULL
)) == NULL
)
572 if (ctf_dynhash_lookup_kv (cache
->ctf_symhash
, symname
, NULL
, &known_idx
))
573 return (unsigned long) (uintptr_t) known_idx
;
575 /* Hash lookup unsuccessful: linear search, populating the hashtab for later
578 for (; cache
->ctf_symhash_latest
< sp
->cts_size
/ sp
->cts_entsize
;
579 cache
->ctf_symhash_latest
++)
581 switch (sp
->cts_entsize
)
583 case sizeof (Elf64_Sym
):
585 Elf64_Sym
*symp
= (Elf64_Sym
*) sp
->cts_data
;
586 ctf_elf64_to_link_sym (fp
, &sym
, &symp
[cache
->ctf_symhash_latest
],
587 cache
->ctf_symhash_latest
);
588 if (!ctf_dynhash_lookup_kv (cache
->ctf_symhash
, sym
.st_name
,
590 if (ctf_dynhash_cinsert (cache
->ctf_symhash
, sym
.st_name
,
591 (const void *) (uintptr_t)
592 cache
->ctf_symhash_latest
) < 0)
594 if (strcmp (sym
.st_name
, symname
) == 0)
595 return cache
->ctf_symhash_latest
++;
598 case sizeof (Elf32_Sym
):
600 Elf32_Sym
*symp
= (Elf32_Sym
*) sp
->cts_data
;
601 ctf_elf32_to_link_sym (fp
, &sym
, &symp
[cache
->ctf_symhash_latest
],
602 cache
->ctf_symhash_latest
);
603 if (!ctf_dynhash_lookup_kv (cache
->ctf_symhash
, sym
.st_name
,
605 if (ctf_dynhash_cinsert (cache
->ctf_symhash
, sym
.st_name
,
606 (const void *) (uintptr_t)
607 cache
->ctf_symhash_latest
) < 0)
609 if (strcmp (sym
.st_name
, symname
) == 0)
610 return cache
->ctf_symhash_latest
++;
614 ctf_set_errno (fp
, ECTF_SYMTAB
);
615 return (unsigned long) -1;
619 /* Searched everything, still not found. */
621 return (unsigned long) -1;
625 return ctf_lookup_symbol_idx (fp
->ctf_parent
, symname
);
628 ctf_set_errno (fp
, err
);
629 return (unsigned long) -1;
632 ctf_set_errno (fp
, ENOMEM
);
633 ctf_err_warn (fp
, 0, ENOMEM
, _("cannot allocate memory for symbol "
635 return (unsigned long) -1;
639 /* Iterate over all symbols with types: if FUNC, function symbols, otherwise,
640 data symbols. The name argument is not optional. The return order is
641 arbitrary, though is likely to be in symbol index or name order. You can
642 change the value of 'functions' in the middle of iteration over non-dynamic
643 dicts, but doing so on dynamic dicts will fail. (This is probably not very
644 useful, but there is no reason to prohibit it.) */
647 ctf_symbol_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
,
656 if ((i
= ctf_next_create ()) == NULL
)
657 return ctf_set_errno (fp
, ENOMEM
);
660 i
->ctn_iter_fun
= (void (*) (void)) ctf_symbol_next
;
665 if ((void (*) (void)) ctf_symbol_next
!= i
->ctn_iter_fun
)
666 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
668 if (fp
!= i
->cu
.ctn_fp
)
669 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
671 /* We intentionally use raw access, not ctf_lookup_by_symbol, to avoid
672 incurring additional sorting cost for unsorted symtypetabs coming from the
673 compiler, to allow ctf_symbol_next to work in the absence of a symtab, and
674 finally because it's easier to work out what the name of each symbol is if
677 if (fp
->ctf_flags
& LCTF_RDWR
)
679 ctf_dynhash_t
*dynh
= functions
? fp
->ctf_funchash
: fp
->ctf_objthash
;
680 void *dyn_name
= NULL
, *dyn_value
= NULL
;
684 ctf_next_destroy (i
);
685 return (ctf_set_errno (fp
, ECTF_NEXT_END
));
688 err
= ctf_dynhash_next (dynh
, &i
->ctn_next
, &dyn_name
, &dyn_value
);
689 /* This covers errors and also end-of-iteration. */
692 ctf_next_destroy (i
);
694 return ctf_set_errno (fp
, err
);
698 sym
= (ctf_id_t
) (uintptr_t) dyn_value
;
700 else if ((!functions
&& fp
->ctf_objtidx_names
) ||
701 (functions
&& fp
->ctf_funcidx_names
))
703 ctf_header_t
*hp
= fp
->ctf_header
;
704 uint32_t *idx
= functions
? fp
->ctf_funcidx_names
: fp
->ctf_objtidx_names
;
710 len
= (hp
->cth_varoff
- hp
->cth_funcidxoff
) / sizeof (uint32_t);
711 tab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_funcoff
);
715 len
= (hp
->cth_funcidxoff
- hp
->cth_objtidxoff
) / sizeof (uint32_t);
716 tab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_objtoff
);
724 *name
= ctf_strptr (fp
, idx
[i
->ctn_n
]);
725 sym
= tab
[i
->ctn_n
++];
726 } while (sym
== -1u || sym
== 0);
730 /* Skip over pads in ctf_xslate, padding for typeless symbols in the
731 symtypetab itself, and symbols in the wrong table. */
732 for (; i
->ctn_n
< fp
->ctf_nsyms
; i
->ctn_n
++)
734 ctf_header_t
*hp
= fp
->ctf_header
;
736 if (fp
->ctf_sxlate
[i
->ctn_n
] == -1u)
739 sym
= *(uint32_t *) ((uintptr_t) fp
->ctf_buf
+ fp
->ctf_sxlate
[i
->ctn_n
]);
746 if (fp
->ctf_sxlate
[i
->ctn_n
] >= hp
->cth_funcoff
747 && fp
->ctf_sxlate
[i
->ctn_n
] < hp
->cth_objtidxoff
)
752 if (fp
->ctf_sxlate
[i
->ctn_n
] >= hp
->cth_objtoff
753 && fp
->ctf_sxlate
[i
->ctn_n
] < hp
->cth_funcoff
)
758 if (i
->ctn_n
>= fp
->ctf_nsyms
)
761 *name
= ctf_lookup_symbol_name (fp
, i
->ctn_n
++);
767 ctf_next_destroy (i
);
769 return (ctf_set_errno (fp
, ECTF_NEXT_END
));
772 /* A bsearch function for function and object index names. */
775 ctf_lookup_idx_name (const void *key_
, const void *idx_
)
777 const ctf_lookup_idx_key_t
*key
= key_
;
778 const uint32_t *idx
= idx_
;
780 return (strcmp (key
->clik_name
, ctf_strptr (key
->clik_fp
, key
->clik_names
[*idx
])));
783 /* Given a symbol name or (failing that) number, look up that symbol in the
784 function or object index table (which must exist). Return 0 if not found
788 ctf_try_lookup_indexed (ctf_dict_t
*fp
, unsigned long symidx
,
789 const char *symname
, int is_function
)
791 struct ctf_header
*hp
= fp
->ctf_header
;
792 uint32_t *symtypetab
;
798 symname
= ctf_lookup_symbol_name (fp
, symidx
);
800 ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in "
801 "indexed symtypetab\n", symidx
, symname
);
803 if (symname
[0] == '\0')
804 return -1; /* errno is set for us. */
808 if (!fp
->ctf_funcidx_sxlate
)
810 if ((fp
->ctf_funcidx_sxlate
811 = ctf_symidx_sort (fp
, (uint32_t *)
812 (fp
->ctf_buf
+ hp
->cth_funcidxoff
),
814 hp
->cth_varoff
- hp
->cth_funcidxoff
))
817 ctf_err_warn (fp
, 0, 0, _("cannot sort function symidx"));
818 return -1; /* errno is set for us. */
821 symtypetab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_funcoff
);
822 sxlate
= fp
->ctf_funcidx_sxlate
;
823 names
= fp
->ctf_funcidx_names
;
824 nidx
= fp
->ctf_nfuncidx
;
828 if (!fp
->ctf_objtidx_sxlate
)
830 if ((fp
->ctf_objtidx_sxlate
831 = ctf_symidx_sort (fp
, (uint32_t *)
832 (fp
->ctf_buf
+ hp
->cth_objtidxoff
),
834 hp
->cth_funcidxoff
- hp
->cth_objtidxoff
))
837 ctf_err_warn (fp
, 0, 0, _("cannot sort object symidx"));
838 return -1; /* errno is set for us. */
842 symtypetab
= (uint32_t *) (fp
->ctf_buf
+ hp
->cth_objtoff
);
843 sxlate
= fp
->ctf_objtidx_sxlate
;
844 names
= fp
->ctf_objtidx_names
;
845 nidx
= fp
->ctf_nobjtidx
;
848 ctf_lookup_idx_key_t key
= { fp
, symname
, names
};
851 idx
= bsearch (&key
, sxlate
, nidx
, sizeof (uint32_t), ctf_lookup_idx_name
);
855 ctf_dprintf ("%s not found in idx\n", symname
);
859 /* Should be impossible, but be paranoid. */
860 if ((idx
- sxlate
) > (ptrdiff_t) nidx
)
861 return (ctf_set_errno (fp
, ECTF_CORRUPT
));
863 ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx
, symname
,
865 return symtypetab
[*idx
];
868 /* Given a symbol name or (if NULL) symbol index, return the type of the
869 function or data object described by the corresponding entry in the symbol
870 table. We can only return symbols in read-only dicts and in dicts for which
871 ctf_link_shuffle_syms has been called to assign symbol indexes to symbol
875 ctf_lookup_by_sym_or_name (ctf_dict_t
*fp
, unsigned long symidx
,
878 const ctf_sect_t
*sp
= &fp
->ctf_symtab
;
882 /* Shuffled dynsymidx present? Use that. */
883 if (fp
->ctf_dynsymidx
)
885 const ctf_link_sym_t
*sym
;
888 ctf_dprintf ("Looking up type of object with symname %s in "
889 "writable dict symtypetab\n", symname
);
891 ctf_dprintf ("Looking up type of object with symtab idx %lx in "
892 "writable dict symtypetab\n", symidx
);
894 /* The dict must be dynamic. */
895 if (!ctf_assert (fp
, fp
->ctf_flags
& LCTF_RDWR
))
898 /* No name? Need to look it up. */
902 if (symidx
> fp
->ctf_dynsymmax
)
905 sym
= fp
->ctf_dynsymidx
[symidx
];
906 err
= ECTF_NOTYPEDAT
;
907 if (!sym
|| (sym
->st_shndx
!= STT_OBJECT
&& sym
->st_shndx
!= STT_FUNC
))
910 if (!ctf_assert (fp
, !sym
->st_nameidx_set
))
912 symname
= sym
->st_name
;
915 if (fp
->ctf_objthash
== NULL
916 || ((type
= (ctf_id_t
) (uintptr_t)
917 ctf_dynhash_lookup (fp
->ctf_objthash
, symname
)) == 0))
919 if (fp
->ctf_funchash
== NULL
920 || ((type
= (ctf_id_t
) (uintptr_t)
921 ctf_dynhash_lookup (fp
->ctf_funchash
, symname
)) == 0))
928 /* Lookup by name in a dynamic dict: just do it directly. */
929 if (symname
&& fp
->ctf_flags
& LCTF_RDWR
)
931 if (fp
->ctf_objthash
== NULL
932 || ((type
= (ctf_id_t
) (uintptr_t)
933 ctf_dynhash_lookup (fp
->ctf_objthash
, symname
)) == 0))
935 if (fp
->ctf_funchash
== NULL
936 || ((type
= (ctf_id_t
) (uintptr_t)
937 ctf_dynhash_lookup (fp
->ctf_funchash
, symname
)) == 0))
944 if (sp
->cts_data
== NULL
)
947 /* This covers both out-of-range lookups and a dynamic dict which hasn't been
950 if (symname
== NULL
&& symidx
>= fp
->ctf_nsyms
)
953 if (fp
->ctf_objtidx_names
)
955 if ((type
= ctf_try_lookup_indexed (fp
, symidx
, symname
, 0)) == CTF_ERR
)
956 return CTF_ERR
; /* errno is set for us. */
958 if (type
== 0 && fp
->ctf_funcidx_names
)
960 if ((type
= ctf_try_lookup_indexed (fp
, symidx
, symname
, 1)) == CTF_ERR
)
961 return CTF_ERR
; /* errno is set for us. */
966 err
= ECTF_NOTYPEDAT
;
967 if (fp
->ctf_objtidx_names
&& fp
->ctf_funcidx_names
)
970 /* Table must be nonindexed. */
972 ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx
);
975 if ((symidx
= ctf_lookup_symbol_idx (fp
, symname
)) == (unsigned long) -1)
978 if (fp
->ctf_sxlate
[symidx
] == -1u)
981 type
= *(uint32_t *) ((uintptr_t) fp
->ctf_buf
+ fp
->ctf_sxlate
[symidx
]);
990 ctf_id_t ret
= ctf_lookup_by_sym_or_name (fp
->ctf_parent
, symidx
,
993 ctf_set_errno (fp
, ctf_errno (fp
->ctf_parent
));
997 return (ctf_set_errno (fp
, err
));
1000 /* Given a symbol table index, return the type of the function or data object
1001 described by the corresponding entry in the symbol table. */
1003 ctf_lookup_by_symbol (ctf_dict_t
*fp
, unsigned long symidx
)
1005 return ctf_lookup_by_sym_or_name (fp
, symidx
, NULL
);
1008 /* Given a symbol name, return the type of the function or data object described
1009 by the corresponding entry in the symbol table. */
1011 ctf_lookup_by_symbol_name (ctf_dict_t
*fp
, const char *symname
)
1013 return ctf_lookup_by_sym_or_name (fp
, 0, symname
);
1016 /* Given a symbol table index, return the info for the function described
1017 by the corresponding entry in the symbol table, which may be a function
1018 symbol or may be a data symbol that happens to be a function pointer. */
1021 ctf_func_info (ctf_dict_t
*fp
, unsigned long symidx
, ctf_funcinfo_t
*fip
)
1025 if ((type
= ctf_lookup_by_symbol (fp
, symidx
)) == CTF_ERR
)
1026 return -1; /* errno is set for us. */
1028 if (ctf_type_kind (fp
, type
) != CTF_K_FUNCTION
)
1029 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1031 return ctf_func_type_info (fp
, type
, fip
);
1034 /* Given a symbol table index, return the arguments for the function described
1035 by the corresponding entry in the symbol table. */
1038 ctf_func_args (ctf_dict_t
*fp
, unsigned long symidx
, uint32_t argc
,
1043 if ((type
= ctf_lookup_by_symbol (fp
, symidx
)) == CTF_ERR
)
1044 return -1; /* errno is set for us. */
1046 if (ctf_type_kind (fp
, type
) != CTF_K_FUNCTION
)
1047 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1049 return ctf_func_type_args (fp
, type
, argc
, argv
);