2 Copyright © 2013, The AROS Development Team. All rights reserved.
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 /*****************************************************************************
22 #include <proto/debug.h>
24 AROS_LH2(void, EnumerateSymbolsA
,
27 AROS_LHA(struct Hook
*, handler
, A0
),
28 AROS_LHA(struct TagItem
*, tags
, A1
),
31 struct Library
*, DebugBase
, 8, Debug
)
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.
53 ******************************************************************************/
59 EnumerateKickstartModules(handler
, DebugBase
);
61 /* We can be called in supervisor mode. No semaphores in the case! */
64 ObtainSemaphoreShared(&DBGBASE(DebugBase
)->db_ModSem
);
66 EnumerateLoadedModules(handler
, DebugBase
);
69 ReleaseSemaphore(&DBGBASE(DebugBase
)->db_ModSem
);
74 static inline void callhook(struct Hook
* handler
, CONST_STRPTR modname
, CONST_STRPTR symname
,
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
)
92 ForeachNode(&DBGBASE(DebugBase
)->db_LoadedModules
, mod
)
94 dbg_sym_t
*sym
= mod
->m_symbols
;
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 */
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
;
127 /* Get wider versions of shnum and shstrndx from first section header if needed */
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
);
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
))
159 for (j
= 0; j
< symcnt
; j
++)
161 LONG idx
= st
[j
].shindex
;
162 APTR s_lowest
, s_highest
;
165 /* Ignore these - they should not be here at all */
166 if ((idx
== SHN_UNDEF
) || (idx
== SHN_COMMON
))
168 /* TODO: perhaps XINDEX support is needed */
169 if (idx
== SHN_XINDEX
)
172 s_name
= (m_str
) ? m_str
+ st
[j
].name
: NULL
;
174 s_lowest
= (APTR
) st
[j
].value
;
176 s_lowest
+= (IPTR
) sections
[idx
].addr
;
179 s_highest
= s_lowest
+ st
[j
].size
- 1;
183 callhook(handler
, kmod
->Name
, s_name
, s_lowest
, s_highest
);