oops .. forgot to offset from objects bounds
[AROS.git] / rom / debug / enumeratesymbolsa.c
blobb62405dbffc5b769ab0bacba8d77de3ecb3264a3
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 struct segment *seg;
92 ForeachNode(&DBGBASE(DebugBase)->db_Modules, seg)
94 module_t *mod = seg->s_mod;
95 dbg_sym_t *sym = mod->m_symbols;
96 ULONG i;
98 D(bug("[Debug] Checking segment 0x%p - 0x%p, num %u, module %s\n",
99 seg->s_lowest, seg->s_highest, seg->s_num, mod->m_name));
101 for (i = 0; i < mod->m_symcnt; i++)
103 APTR highest = sym[i].s_highest;
105 /* Symbols with zero length have zero in s_highest */
106 if (!highest)
107 highest = sym[i].s_lowest;
109 callhook(handler, mod->m_name, sym[i].s_name, sym[i].s_lowest, sym[i].s_highest);
114 static void EnumerateKickstartModules(struct Hook * handler, struct Library * DebugBase)
116 struct ELF_ModuleInfo *kmod;
117 for (kmod = DBGBASE(DebugBase)->db_KernelModules; kmod; kmod = kmod->Next)
119 /* We understand only ELF here */
120 if (kmod->Type == DEBUG_ELF)
122 struct elfheader *eh = kmod->eh;
123 struct sheader *sections = kmod->sh;
124 ULONG int_shnum = eh->shnum;
125 ULONG int_shstrndx = eh->shstrndx;
126 ULONG shstr;
127 ULONG i;
129 /* Get wider versions of shnum and shstrndx from first section header if needed */
130 if (int_shnum == 0)
131 int_shnum = sections[0].size;
132 if (int_shstrndx == SHN_XINDEX)
133 int_shstrndx = sections[0].link;
135 shstr = SHINDEX(int_shstrndx);
137 for (i = 0; i < int_shnum; i++)
139 APTR s_lowest = sections[i].addr;
141 /* Ignore all empty segments */
142 if (s_lowest && sections[i].size)
144 struct symbol *st = (struct symbol *) sections[i].addr;
145 ULONG symcnt = sections[i].size / sizeof(struct symbol);
146 ULONG j, z;
147 STRPTR m_str = NULL;
149 /* Find symbols name table */
150 for (z = 0; z < int_shnum; z++)
152 if ((sections[z].type == SHT_STRTAB) && (z != shstr))
154 m_str = sections[z].addr;
158 if (!(sections[i].addr && sections[i].type == SHT_SYMTAB))
159 continue;
161 for (j = 0; j < symcnt; j++)
163 LONG idx = st[j].shindex;
164 APTR s_lowest, s_highest;
165 STRPTR s_name;
167 /* Ignore these - they should not be here at all */
168 if ((idx == SHN_UNDEF) || (idx == SHN_COMMON))
169 continue;
170 /* TODO: perhaps XINDEX support is needed */
171 if (idx == SHN_XINDEX)
172 continue;
174 s_name = (m_str) ? m_str + st[j].name : NULL;
176 s_lowest = (APTR) st[j].value;
177 if (idx != SHN_ABS)
178 s_lowest += (IPTR) sections[idx].addr;
180 if (st[j].size)
181 s_highest = s_lowest + st[j].size - 1;
182 else
183 s_highest = NULL;
185 callhook(handler, kmod->Name, s_name, s_lowest, s_highest);