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_Modules
, seg
)
94 module_t
*mod
= seg
->s_mod
;
95 dbg_sym_t
*sym
= mod
->m_symbols
;
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 */
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
;
129 /* Get wider versions of shnum and shstrndx from first section header if needed */
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
);
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
))
161 for (j
= 0; j
< symcnt
; j
++)
163 LONG idx
= st
[j
].shindex
;
164 APTR s_lowest
, s_highest
;
167 /* Ignore these - they should not be here at all */
168 if ((idx
== SHN_UNDEF
) || (idx
== SHN_COMMON
))
170 /* TODO: perhaps XINDEX support is needed */
171 if (idx
== SHN_XINDEX
)
174 s_name
= (m_str
) ? m_str
+ st
[j
].name
: NULL
;
176 s_lowest
= (APTR
) st
[j
].value
;
178 s_lowest
+= (IPTR
) sections
[idx
].addr
;
181 s_highest
= s_lowest
+ st
[j
].size
- 1;
185 callhook(handler
, kmod
->Name
, s_name
, s_lowest
, s_highest
);