1*d3c8c77eSchristos /* $NetBSD: db_elf.c,v 1.29 2017/11/06 04:08:02 christos Exp $ */
25accaea9Sthorpej
35accaea9Sthorpej /*-
4cd6b1c8fSad * Copyright (c) 1997, 2009 The NetBSD Foundation, Inc.
55accaea9Sthorpej * All rights reserved.
65accaea9Sthorpej *
75accaea9Sthorpej * This code is derived from software contributed to The NetBSD Foundation
85accaea9Sthorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9cd6b1c8fSad * NASA Ames Research Center, and by Andrew Doran.
105accaea9Sthorpej *
115accaea9Sthorpej * Redistribution and use in source and binary forms, with or without
125accaea9Sthorpej * modification, are permitted provided that the following conditions
135accaea9Sthorpej * are met:
145accaea9Sthorpej * 1. Redistributions of source code must retain the above copyright
155accaea9Sthorpej * notice, this list of conditions and the following disclaimer.
165accaea9Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
175accaea9Sthorpej * notice, this list of conditions and the following disclaimer in the
185accaea9Sthorpej * documentation and/or other materials provided with the distribution.
195accaea9Sthorpej *
205accaea9Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
215accaea9Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
225accaea9Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
235accaea9Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
245accaea9Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
255accaea9Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
265accaea9Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
275accaea9Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
285accaea9Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
295accaea9Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
305accaea9Sthorpej * POSSIBILITY OF SUCH DAMAGE.
315accaea9Sthorpej */
325accaea9Sthorpej
331ac69d9cSlukem #include <sys/cdefs.h>
34*d3c8c77eSchristos __KERNEL_RCSID(0, "$NetBSD: db_elf.c,v 1.29 2017/11/06 04:08:02 christos Exp $");
351ac69d9cSlukem
365accaea9Sthorpej #include <sys/param.h>
375accaea9Sthorpej #include <sys/systm.h>
385accaea9Sthorpej #include <sys/proc.h>
395accaea9Sthorpej
40ad97afb1Schristos #include <machine/db_machdep.h>
41cd6b1c8fSad #include <machine/pmap.h>
42cd6b1c8fSad #include <machine/vmparam.h>
435accaea9Sthorpej
445accaea9Sthorpej #ifdef DB_ELF_SYMBOLS
455accaea9Sthorpej
46ad97afb1Schristos #include <ddb/ddb.h>
475accaea9Sthorpej #include <sys/exec_elf.h>
485accaea9Sthorpej
494eaa4d66Ssimonb static char *db_elf_find_strtab(db_symtab_t *);
505accaea9Sthorpej
515accaea9Sthorpej #define STAB_TO_SYMSTART(stab) ((Elf_Sym *)((stab)->start))
525accaea9Sthorpej #define STAB_TO_SYMEND(stab) ((Elf_Sym *)((stab)->end))
535accaea9Sthorpej #define STAB_TO_EHDR(stab) ((Elf_Ehdr *)((stab)->private))
545accaea9Sthorpej #define STAB_TO_SHDR(stab, e) ((Elf_Shdr *)((stab)->private + (e)->e_shoff))
555accaea9Sthorpej
56712239e3Sthorpej static bool db_elf_sym_init(int, void *, void *, const char *);
57cd6b1c8fSad static db_sym_t db_elf_lookup(db_symtab_t *, const char *);
584eaa4d66Ssimonb static db_sym_t db_elf_search_symbol(db_symtab_t *, db_addr_t, db_strategy_t,
594eaa4d66Ssimonb db_expr_t *);
60cd6b1c8fSad static void db_elf_symbol_values(db_symtab_t *, db_sym_t, const char **,
614eaa4d66Ssimonb db_expr_t *);
62712239e3Sthorpej static bool db_elf_line_at_pc(db_symtab_t *, db_sym_t, char **, int *,
634eaa4d66Ssimonb db_expr_t);
64712239e3Sthorpej static bool db_elf_sym_numargs(db_symtab_t *, db_sym_t, int *, char **);
654eaa4d66Ssimonb static void db_elf_forall(db_symtab_t *, db_forall_func_t db_forall_func,
664eaa4d66Ssimonb void *);
67c8949352Sthorpej
689aa0a018Sjdolecek const db_symformat_t db_symformat_elf = {
69c8949352Sthorpej "ELF",
70c8949352Sthorpej db_elf_sym_init,
71c8949352Sthorpej db_elf_lookup,
72c8949352Sthorpej db_elf_search_symbol,
73c8949352Sthorpej db_elf_symbol_values,
74c8949352Sthorpej db_elf_line_at_pc,
75c8949352Sthorpej db_elf_sym_numargs,
7641ebaaafSjhawk db_elf_forall
77c8949352Sthorpej };
78c8949352Sthorpej
79cd6b1c8fSad static db_symtab_t db_symtabs;
80cd6b1c8fSad
81cd6b1c8fSad /*
82cd6b1c8fSad * Add symbol table, with given name, to symbol tables.
83cd6b1c8fSad */
84cd6b1c8fSad static int
db_add_symbol_table(char * start,char * end,const char * name,char * ref)85cd6b1c8fSad db_add_symbol_table(char *start, char *end, const char *name, char *ref)
86cd6b1c8fSad {
87cd6b1c8fSad
88cd6b1c8fSad db_symtabs.start = start;
89cd6b1c8fSad db_symtabs.end = end;
90cd6b1c8fSad db_symtabs.name = name;
91cd6b1c8fSad db_symtabs.private = ref;
92cd6b1c8fSad
93cd6b1c8fSad return(0);
94cd6b1c8fSad }
95cd6b1c8fSad
965accaea9Sthorpej /*
975accaea9Sthorpej * Find the symbol table and strings; tell ddb about them.
985accaea9Sthorpej */
99712239e3Sthorpej static bool
db_elf_sym_init(int symsize,void * symtab,void * esymtab,const char * name)1004eaa4d66Ssimonb db_elf_sym_init(
1014eaa4d66Ssimonb int symsize, /* size of symbol table */
1024eaa4d66Ssimonb void *symtab, /* pointer to start of symbol table */
1034eaa4d66Ssimonb void *esymtab, /* pointer to end of string table,
1045accaea9Sthorpej for checking - rounded up to integer
1055accaea9Sthorpej boundary */
1064eaa4d66Ssimonb const char *name
1074eaa4d66Ssimonb )
1085accaea9Sthorpej {
1095accaea9Sthorpej Elf_Ehdr *elf;
1105accaea9Sthorpej Elf_Shdr *shp;
1115accaea9Sthorpej Elf_Sym *symp, *symtab_start, *symtab_end;
11234c3239dSbjh21 char *strtab_start, *strtab_end;
11334c3239dSbjh21 int i, j;
1145accaea9Sthorpej
1155accaea9Sthorpej if (ALIGNED_POINTER(symtab, long) == 0) {
116c8949352Sthorpej printf("[ %s symbol table has bad start address %p ]\n",
117c8949352Sthorpej name, symtab);
1184f3d5a9cSthorpej return (false);
1195accaea9Sthorpej }
1205accaea9Sthorpej
1215accaea9Sthorpej symtab_start = symtab_end = NULL;
1225accaea9Sthorpej strtab_start = strtab_end = NULL;
1235accaea9Sthorpej
1245accaea9Sthorpej /*
1255accaea9Sthorpej * The format of the symbols loaded by the boot program is:
1265accaea9Sthorpej *
1275accaea9Sthorpej * Elf exec header
1285accaea9Sthorpej * first section header
1295accaea9Sthorpej * . . .
1305accaea9Sthorpej * . . .
1315accaea9Sthorpej * last section header
1325accaea9Sthorpej * first symbol or string table section
1335accaea9Sthorpej * . . .
1345accaea9Sthorpej * . . .
1355accaea9Sthorpej * last symbol or string table section
1365accaea9Sthorpej */
1375accaea9Sthorpej
1385accaea9Sthorpej /*
1395accaea9Sthorpej * Validate the Elf header.
1405accaea9Sthorpej */
1415accaea9Sthorpej elf = (Elf_Ehdr *)symtab;
142522cbf02Skleink if (memcmp(elf->e_ident, ELFMAG, SELFMAG) != 0 ||
143522cbf02Skleink elf->e_ident[EI_CLASS] != ELFCLASS)
1445accaea9Sthorpej goto badheader;
1455accaea9Sthorpej
1465accaea9Sthorpej switch (elf->e_machine) {
1475accaea9Sthorpej
14859b90d4aSerh ELFDEFNNAME(MACHDEP_ID_CASES)
1495accaea9Sthorpej
1505accaea9Sthorpej default:
1515accaea9Sthorpej goto badheader;
1525accaea9Sthorpej }
1535accaea9Sthorpej
1545accaea9Sthorpej /*
15534c3239dSbjh21 * Find the first (and, we hope, only) SHT_SYMTAB section in
15634c3239dSbjh21 * the file, and the SHT_STRTAB section that goes with it.
1575accaea9Sthorpej */
158286faf20Sbjh21 if (elf->e_shoff == 0)
159286faf20Sbjh21 goto badheader;
160332d7c13Saugustss shp = (Elf_Shdr *)((char *)symtab + elf->e_shoff);
1615accaea9Sthorpej for (i = 0; i < elf->e_shnum; i++) {
16234c3239dSbjh21 if (shp[i].sh_type == SHT_SYMTAB) {
163286faf20Sbjh21 if (shp[i].sh_offset == 0)
164286faf20Sbjh21 continue;
16534c3239dSbjh21 /* Got the symbol table. */
166332d7c13Saugustss symtab_start = (Elf_Sym *)((char *)symtab +
167332d7c13Saugustss shp[i].sh_offset);
168332d7c13Saugustss symtab_end = (Elf_Sym *)((char *)symtab +
169332d7c13Saugustss shp[i].sh_offset + shp[i].sh_size);
17034c3239dSbjh21 /* Find the string table to go with it. */
17134c3239dSbjh21 j = shp[i].sh_link;
172286faf20Sbjh21 if (shp[j].sh_offset == 0)
173286faf20Sbjh21 continue;
17434c3239dSbjh21 strtab_start = (char *)symtab + shp[j].sh_offset;
17534c3239dSbjh21 strtab_end = (char *)symtab + shp[j].sh_offset +
17634c3239dSbjh21 shp[j].sh_size;
17734c3239dSbjh21 /* There should only be one symbol table. */
17834c3239dSbjh21 break;
1795accaea9Sthorpej }
1805accaea9Sthorpej }
1815accaea9Sthorpej
1825accaea9Sthorpej /*
1835accaea9Sthorpej * Now, sanity check the symbols against the string table.
1845accaea9Sthorpej */
185f576b48bSthorpej if (symtab_start == NULL || strtab_start == NULL ||
186f576b48bSthorpej ALIGNED_POINTER(symtab_start, long) == 0 ||
187f576b48bSthorpej ALIGNED_POINTER(strtab_start, long) == 0)
1885accaea9Sthorpej goto badheader;
1895accaea9Sthorpej for (symp = symtab_start; symp < symtab_end; symp++)
1905accaea9Sthorpej if (symp->st_name + strtab_start > strtab_end)
1915accaea9Sthorpej goto badheader;
1925accaea9Sthorpej
1935accaea9Sthorpej /*
1945accaea9Sthorpej * Link the symbol table into the debugger.
1955accaea9Sthorpej */
1965accaea9Sthorpej if (db_add_symbol_table((char *)symtab_start,
197c8949352Sthorpej (char *)symtab_end, name, (char *)symtab) != -1) {
1984f3d5a9cSthorpej return (true);
199c8949352Sthorpej }
200c8949352Sthorpej
2014f3d5a9cSthorpej return (false);
2025accaea9Sthorpej
2035accaea9Sthorpej badheader:
204c8949352Sthorpej printf("[ %s ELF symbol table not valid ]\n", name);
2054f3d5a9cSthorpej return (false);
2065accaea9Sthorpej }
2075accaea9Sthorpej
2085accaea9Sthorpej /*
2095accaea9Sthorpej * Internal helper function - return a pointer to the string table
2105accaea9Sthorpej * for the current symbol table.
2115accaea9Sthorpej */
2125accaea9Sthorpej static char *
db_elf_find_strtab(db_symtab_t * stab)2134eaa4d66Ssimonb db_elf_find_strtab(db_symtab_t *stab)
2145accaea9Sthorpej {
2155accaea9Sthorpej Elf_Ehdr *elf = STAB_TO_EHDR(stab);
2165accaea9Sthorpej Elf_Shdr *shp = STAB_TO_SHDR(stab, elf);
2175accaea9Sthorpej int i;
2185accaea9Sthorpej
219cd6b1c8fSad stab = &db_symtabs;
220cd6b1c8fSad
221e415081aSchristos /*
222e415081aSchristos * We don't load ELF header for ELF modules.
223e415081aSchristos * Find out if this is a loadable module. If so,
224e415081aSchristos * string table comes right after symbol table.
225e415081aSchristos */
226e415081aSchristos if ((Elf_Sym *)elf == STAB_TO_SYMSTART(stab)) {
227e415081aSchristos return ((char *)STAB_TO_SYMEND(stab));
228e415081aSchristos }
2295accaea9Sthorpej for (i = 0; i < elf->e_shnum; i++) {
23034c3239dSbjh21 if (shp[i].sh_type == SHT_SYMTAB)
23134c3239dSbjh21 return ((char*)elf + shp[shp[i].sh_link].sh_offset);
2325accaea9Sthorpej }
2335accaea9Sthorpej
2345accaea9Sthorpej return (NULL);
2355accaea9Sthorpej }
2365accaea9Sthorpej
2375accaea9Sthorpej /*
2385accaea9Sthorpej * Lookup the symbol with the given name.
2395accaea9Sthorpej */
2404eaa4d66Ssimonb static db_sym_t
db_elf_lookup(db_symtab_t * stab,const char * symstr)241cd6b1c8fSad db_elf_lookup(db_symtab_t *stab, const char *symstr)
2425accaea9Sthorpej {
2435accaea9Sthorpej Elf_Sym *symp, *symtab_start, *symtab_end;
2445accaea9Sthorpej char *strtab;
2455accaea9Sthorpej
246cd6b1c8fSad stab = &db_symtabs;
247cd6b1c8fSad
2485accaea9Sthorpej symtab_start = STAB_TO_SYMSTART(stab);
2495accaea9Sthorpej symtab_end = STAB_TO_SYMEND(stab);
2505accaea9Sthorpej
2515accaea9Sthorpej strtab = db_elf_find_strtab(stab);
2525accaea9Sthorpej if (strtab == NULL)
2535accaea9Sthorpej return ((db_sym_t)0);
2545accaea9Sthorpej
2555accaea9Sthorpej for (symp = symtab_start; symp < symtab_end; symp++) {
2565accaea9Sthorpej if (symp->st_name != 0 &&
2575accaea9Sthorpej db_eqname(strtab + symp->st_name, symstr, 0))
2585accaea9Sthorpej return ((db_sym_t)symp);
2595accaea9Sthorpej }
2605accaea9Sthorpej
2615accaea9Sthorpej return ((db_sym_t)0);
2625accaea9Sthorpej }
2635accaea9Sthorpej
2645accaea9Sthorpej /*
2655accaea9Sthorpej * Search for the symbol with the given address (matching within the
2665accaea9Sthorpej * provided threshold).
2675accaea9Sthorpej */
2684eaa4d66Ssimonb static db_sym_t
db_elf_search_symbol(db_symtab_t * symtab,db_addr_t off,db_strategy_t strategy,db_expr_t * diffp)2694eaa4d66Ssimonb db_elf_search_symbol(db_symtab_t *symtab, db_addr_t off, db_strategy_t strategy,
2704eaa4d66Ssimonb db_expr_t *diffp)
2715accaea9Sthorpej {
2725accaea9Sthorpej Elf_Sym *rsymp, *symp, *symtab_start, *symtab_end;
27364f7cc2aSyamt db_addr_t diff = *diffp;
2745accaea9Sthorpej
275cd6b1c8fSad symtab = &db_symtabs;
276cd6b1c8fSad
2775accaea9Sthorpej symtab_start = STAB_TO_SYMSTART(symtab);
2785accaea9Sthorpej symtab_end = STAB_TO_SYMEND(symtab);
2795accaea9Sthorpej
2805accaea9Sthorpej rsymp = NULL;
2815accaea9Sthorpej
2825accaea9Sthorpej for (symp = symtab_start; symp < symtab_end; symp++) {
2835accaea9Sthorpej if (symp->st_name == 0)
2845accaea9Sthorpej continue;
285cd6b1c8fSad
286a2dd74edSeeh #if 0
287a2dd74edSeeh /* This prevents me from seeing anythin in locore.s -- eeh */
288cd6b1c8fSad if (ELF_ST_TYPE(symp->st_info) != STT_OBJECT &&
289cd6b1c8fSad ELF_ST_TYPE(symp->st_info) != STT_FUNC)
2905accaea9Sthorpej continue;
291a2dd74edSeeh #endif
2925accaea9Sthorpej
2935accaea9Sthorpej if (off >= symp->st_value) {
29464f7cc2aSyamt if (off - symp->st_value < diff) {
2955accaea9Sthorpej diff = off - symp->st_value;
2965accaea9Sthorpej rsymp = symp;
2975accaea9Sthorpej if (diff == 0) {
2985accaea9Sthorpej if (strategy == DB_STGY_PROC &&
299522cbf02Skleink ELFDEFNNAME(ST_TYPE)(symp->st_info)
300522cbf02Skleink == STT_FUNC &&
301522cbf02Skleink ELFDEFNNAME(ST_BIND)(symp->st_info)
302522cbf02Skleink != STB_LOCAL)
3035accaea9Sthorpej break;
3045accaea9Sthorpej if (strategy == DB_STGY_ANY &&
305522cbf02Skleink ELFDEFNNAME(ST_BIND)(symp->st_info)
306522cbf02Skleink != STB_LOCAL)
3075accaea9Sthorpej break;
3085accaea9Sthorpej }
30964f7cc2aSyamt } else if (off - symp->st_value == diff) {
3105accaea9Sthorpej if (rsymp == NULL)
3115accaea9Sthorpej rsymp = symp;
312522cbf02Skleink else if (ELFDEFNNAME(ST_BIND)(rsymp->st_info)
313522cbf02Skleink == STB_LOCAL &&
314522cbf02Skleink ELFDEFNNAME(ST_BIND)(symp->st_info)
315522cbf02Skleink != STB_LOCAL) {
3165accaea9Sthorpej /* pick the external symbol */
3175accaea9Sthorpej rsymp = symp;
3185accaea9Sthorpej }
3195accaea9Sthorpej }
3205accaea9Sthorpej }
3215accaea9Sthorpej }
3225accaea9Sthorpej
3235accaea9Sthorpej if (rsymp == NULL)
3245accaea9Sthorpej *diffp = off;
3255accaea9Sthorpej else
3265accaea9Sthorpej *diffp = diff;
3275accaea9Sthorpej
3285accaea9Sthorpej return ((db_sym_t)rsymp);
3295accaea9Sthorpej }
3305accaea9Sthorpej
3315accaea9Sthorpej /*
3325accaea9Sthorpej * Return the name and value for a symbol.
3335accaea9Sthorpej */
3344eaa4d66Ssimonb static void
db_elf_symbol_values(db_symtab_t * symtab,db_sym_t sym,const char ** namep,db_expr_t * valuep)335cd6b1c8fSad db_elf_symbol_values(db_symtab_t *symtab, db_sym_t sym, const char **namep,
3364eaa4d66Ssimonb db_expr_t *valuep)
3375accaea9Sthorpej {
3385accaea9Sthorpej Elf_Sym *symp = (Elf_Sym *)sym;
3395accaea9Sthorpej char *strtab;
3405accaea9Sthorpej
341cd6b1c8fSad symtab = &db_symtabs;
342cd6b1c8fSad
3435accaea9Sthorpej if (namep) {
3445accaea9Sthorpej strtab = db_elf_find_strtab(symtab);
3455accaea9Sthorpej if (strtab == NULL)
3465accaea9Sthorpej *namep = NULL;
3475accaea9Sthorpej else
3485accaea9Sthorpej *namep = strtab + symp->st_name;
3495accaea9Sthorpej }
3505accaea9Sthorpej
3515accaea9Sthorpej if (valuep)
3525accaea9Sthorpej *valuep = symp->st_value;
3535accaea9Sthorpej }
3545accaea9Sthorpej
3555accaea9Sthorpej /*
3565accaea9Sthorpej * Return the file and line number of the current program counter
3575accaea9Sthorpej * if we can find the appropriate debugging symbol.
3585accaea9Sthorpej */
359712239e3Sthorpej static bool
db_elf_line_at_pc(db_symtab_t * symtab,db_sym_t cursym,char ** filename,int * linenum,db_expr_t off)360454af1c0Sdsl db_elf_line_at_pc(db_symtab_t *symtab, db_sym_t cursym, char **filename, int *linenum, db_expr_t off)
3615accaea9Sthorpej {
3625accaea9Sthorpej
3635accaea9Sthorpej /*
3645accaea9Sthorpej * XXX We don't support this (yet).
3655accaea9Sthorpej */
3664f3d5a9cSthorpej return (false);
3675accaea9Sthorpej }
3685accaea9Sthorpej
3695accaea9Sthorpej /*
3705accaea9Sthorpej * Returns the number of arguments to a function and their
3715accaea9Sthorpej * names if we can find the appropriate debugging symbol.
3725accaea9Sthorpej */
373712239e3Sthorpej static bool
db_elf_sym_numargs(db_symtab_t * symtab,db_sym_t cursym,int * nargp,char ** argnamep)3744eaa4d66Ssimonb db_elf_sym_numargs(db_symtab_t *symtab, db_sym_t cursym, int *nargp,
3754eaa4d66Ssimonb char **argnamep)
3765accaea9Sthorpej {
3775accaea9Sthorpej
3785accaea9Sthorpej /*
3795accaea9Sthorpej * XXX We don't support this (yet).
3805accaea9Sthorpej */
3814f3d5a9cSthorpej return (false);
3825accaea9Sthorpej }
38341ebaaafSjhawk
3844eaa4d66Ssimonb static void
db_elf_forall(db_symtab_t * stab,db_forall_func_t db_forall_func,void * arg)3854eaa4d66Ssimonb db_elf_forall(db_symtab_t *stab, db_forall_func_t db_forall_func, void *arg)
38641ebaaafSjhawk {
38741ebaaafSjhawk char *strtab;
38841ebaaafSjhawk static char suffix[2];
38941ebaaafSjhawk Elf_Sym *symp, *symtab_start, *symtab_end;
39041ebaaafSjhawk
391cd6b1c8fSad stab = &db_symtabs;
392cd6b1c8fSad
39341ebaaafSjhawk symtab_start = STAB_TO_SYMSTART(stab);
39441ebaaafSjhawk symtab_end = STAB_TO_SYMEND(stab);
39541ebaaafSjhawk
39641ebaaafSjhawk strtab = db_elf_find_strtab(stab);
39741ebaaafSjhawk if (strtab == NULL)
39841ebaaafSjhawk return;
39941ebaaafSjhawk
40041ebaaafSjhawk for (symp = symtab_start; symp < symtab_end; symp++)
40141ebaaafSjhawk if (symp->st_name != 0) {
40241ebaaafSjhawk suffix[1] = '\0';
40341ebaaafSjhawk switch (ELFDEFNNAME(ST_TYPE)(symp->st_info)) {
40441ebaaafSjhawk case STT_OBJECT:
40541ebaaafSjhawk suffix[0] = '+';
40641ebaaafSjhawk break;
40741ebaaafSjhawk case STT_FUNC:
40841ebaaafSjhawk suffix[0] = '*';
40941ebaaafSjhawk break;
41041ebaaafSjhawk case STT_SECTION:
41141ebaaafSjhawk suffix[0] = '&';
41241ebaaafSjhawk break;
41341ebaaafSjhawk case STT_FILE:
41441ebaaafSjhawk suffix[0] = '/';
41541ebaaafSjhawk break;
41641ebaaafSjhawk default:
41741ebaaafSjhawk suffix[0] = '\0';
41841ebaaafSjhawk }
41941ebaaafSjhawk (*db_forall_func)(stab, (db_sym_t)symp,
42041ebaaafSjhawk strtab + symp->st_name, suffix, 0, arg);
42141ebaaafSjhawk }
42241ebaaafSjhawk return;
42341ebaaafSjhawk }
4245accaea9Sthorpej #endif /* DB_ELF_SYMBOLS */
425