debug.library: migrate to new two-level module index
[AROS.git] / rom / debug / enumeratesymbolsa.c
blobfe6e28907821b7c91da44566dc1747ffcc72920e
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <libraries/debug.h>
10 #include <proto/kernel.h>
11 #include <proto/exec.h>
12 #include <aros/debug.h>
14 #include "debug_intern.h"
16 static void EnumerateLoadedModules(struct Hook * handler, struct Library * DebugBase);
17 static void EnumerateKickstartModules(struct Hook * handler, struct Library * DebugBase);
19 /*****************************************************************************
21 NAME */
22 #include <proto/debug.h>
24 AROS_LH2(void, EnumerateSymbolsA,
26 /* SYNOPSIS */
27 AROS_LHA(struct Hook *, handler, A0),
28 AROS_LHA(struct TagItem *, tags, A1),
30 /* LOCATION */
31 struct Library *, DebugBase, 8, Debug)
33 /* FUNCTION
34 Function will call the handler hook for all symbols from kickstart and
35 loaded modules that match the given search criteria.
37 The message that is passed to hook contains a pointer to struct SymbolInfo.
39 INPUTS
41 RESULT
43 NOTES
45 EXAMPLE
47 BUGS
49 SEE ALSO
51 INTERNALS
53 ******************************************************************************/
55 AROS_LIBFUNC_INIT
57 BOOL super;
59 EnumerateKickstartModules(handler, DebugBase);
61 /* We can be called in supervisor mode. No semaphores in the case! */
62 super = KrnIsSuper();
63 if (!super)
64 ObtainSemaphoreShared(&DBGBASE(DebugBase)->db_ModSem);
66 EnumerateLoadedModules(handler, DebugBase);
68 if (!super)
69 ReleaseSemaphore(&DBGBASE(DebugBase)->db_ModSem);
71 AROS_LIBFUNC_EXIT
74 static inline void callhook(struct Hook * handler, CONST_STRPTR modname, CONST_STRPTR symname,
75 APTR start, APTR end)
77 struct SymbolInfo sinfo = {0};
79 sinfo.si_Size = sizeof(struct SymbolInfo);
80 sinfo.si_ModuleName = modname;
81 sinfo.si_SymbolName = symname;
82 sinfo.si_SymbolStart = start;
83 sinfo.si_SymbolEnd = end;
85 CALLHOOKPKT(handler, NULL, &sinfo);
88 static void EnumerateLoadedModules(struct Hook * handler, struct Library * DebugBase)
90 module_t *mod;
92 ForeachNode(&DBGBASE(DebugBase)->db_LoadedModules, mod)
94 dbg_sym_t *sym = mod->m_symbols;
95 ULONG i;
97 D(bug("[Debug] Checking module %s\n", mod->m_name));
99 for (i = 0; i < mod->m_symcnt; i++)
101 APTR highest = sym[i].s_highest;
103 /* Symbols with zero length have zero in s_highest */
104 if (!highest)
105 highest = sym[i].s_lowest;
107 callhook(handler, mod->m_name, sym[i].s_name, sym[i].s_lowest, sym[i].s_highest);
112 static void EnumerateKickstartModules(struct Hook * handler, struct Library * DebugBase)
114 struct ELF_ModuleInfo *kmod;
115 for (kmod = DBGBASE(DebugBase)->db_KernelModules; kmod; kmod = kmod->Next)
117 /* We understand only ELF here */
118 if (kmod->Type == DEBUG_ELF)
120 struct elfheader *eh = kmod->eh;
121 struct sheader *sections = kmod->sh;
122 ULONG int_shnum = eh->shnum;
123 ULONG int_shstrndx = eh->shstrndx;
124 ULONG shstr;
125 ULONG i;
127 /* Get wider versions of shnum and shstrndx from first section header if needed */
128 if (int_shnum == 0)
129 int_shnum = sections[0].size;
130 if (int_shstrndx == SHN_XINDEX)
131 int_shstrndx = sections[0].link;
133 shstr = SHINDEX(int_shstrndx);
135 for (i = 0; i < int_shnum; i++)
137 APTR s_lowest = sections[i].addr;
139 /* Ignore all empty segments */
140 if (s_lowest && sections[i].size)
142 struct symbol *st = (struct symbol *) sections[i].addr;
143 ULONG symcnt = sections[i].size / sizeof(struct symbol);
144 ULONG j, z;
145 STRPTR m_str = NULL;
147 /* Find symbols name table */
148 for (z = 0; z < int_shnum; z++)
150 if ((sections[z].type == SHT_STRTAB) && (z != shstr))
152 m_str = sections[z].addr;
156 if (!(sections[i].addr && sections[i].type == SHT_SYMTAB))
157 continue;
159 for (j = 0; j < symcnt; j++)
161 LONG idx = st[j].shindex;
162 APTR s_lowest, s_highest;
163 STRPTR s_name;
165 /* Ignore these - they should not be here at all */
166 if ((idx == SHN_UNDEF) || (idx == SHN_COMMON))
167 continue;
168 /* TODO: perhaps XINDEX support is needed */
169 if (idx == SHN_XINDEX)
170 continue;
172 s_name = (m_str) ? m_str + st[j].name : NULL;
174 s_lowest = (APTR) st[j].value;
175 if (idx != SHN_ABS)
176 s_lowest += (IPTR) sections[idx].addr;
178 if (st[j].size)
179 s_highest = s_lowest + st[j].size - 1;
180 else
181 s_highest = NULL;
183 callhook(handler, kmod->Name, s_name, s_lowest, s_highest);