4 #include <aros/debug.h>
6 #include <libraries/debug.h>
7 #include <proto/exec.h>
8 #include <proto/kernel.h>
12 #include "debug_intern.h"
14 static BOOL
FindSymbol(module_t
*mod
, char **function
, void **funstart
, void **funend
, void *addr
)
16 dbg_sym_t
*sym
= mod
->m_symbols
;
22 for (i
= 0; i
< mod
->m_symcnt
; i
++)
24 APTR highest
= sym
[i
].s_highest
;
26 /* Symbols with zero length have zero in s_highest */
28 highest
= sym
[i
].s_lowest
;
30 if (sym
[i
].s_lowest
<= addr
&& highest
>= addr
) {
31 *function
= sym
[i
].s_name
;
32 *funstart
= sym
[i
].s_lowest
;
33 *funend
= sym
[i
].s_highest
;
39 /* Indicate that symbol not found */
43 /*****************************************************************************
46 #include <proto/debug.h>
48 AROS_LH2(int, DecodeLocationA
,
51 AROS_LHA(void *, addr
, A0
),
52 AROS_LHA(struct TagItem
*, tags
, A1
),
55 struct Library
*, DebugBase
, 7, Debug
)
58 Locate the given address in the list of registered modules and return
62 addr - An address to resolve
63 tags - An optional taglist. ti_Tag can be one of the following tags and
64 ti_Data is always a pointer to a storage of specified type.
65 Resulting values will be placed into specified locations if the
68 DL_ModuleName (char *) - Module name
69 DL_SegmentName (char *) - Segment name. Can be NULL if there were
70 no segment names provided for the module.
71 DL_SegmentPointer (BPTR) - DOS pointer to the corresponding segment.
72 Note that it will be different from
73 KDL_SegmentStart value
75 DL_SegmentNumber (unsigned int) - Order number of the segment in the
77 DL_SegmentStart (void *) - Start address of actual segment contents
79 DL_SegmentEnd (void *) - End address of actual segment contents
82 The following tags may return NULL values if there was no corresponding
83 information provided for the module:
85 DL_SymbolName (char *) - Symbol name (function or variable name)
86 DL_SymbolStart (void *) - Start address of contents described by this
88 DL_SymbolEnd (void *) - End address of contents described by this
92 Zero if lookup failed and no corresponding module found, nonzero
96 If the function fails values pointed to by taglist will not be changed.
106 ******************************************************************************/
112 char **module
= (char **)&dummy
;
113 char **segment
= (char **)&dummy
;
114 char **function
= (char **)&dummy
;
115 void **secstart
= &dummy
;
116 void **secend
= &dummy
;
117 void **funstart
= &dummy
;
118 void **funend
= &dummy
;
119 BPTR
*secptr
= (BPTR
*)&dummy
;
120 unsigned int *secnum
= (unsigned int *)&dummy
;
121 struct TagItem
*tag
, *tstate
= tags
;
122 void *symaddr
= NULL
;
126 D(bug("[Debug] DecodeLocationA(0x%p)\n", addr
));
129 while ((tag
= LibNextTagItem(&tstate
)))
134 module
= (char **)tag
->ti_Data
;
138 segment
= (char **)tag
->ti_Data
;
141 case DL_SegmentPointer
:
142 secptr
= (BPTR
*)tag
->ti_Data
;
145 case DL_SegmentNumber
:
146 secnum
= (unsigned int *)tag
->ti_Data
;
149 case DL_SegmentStart
:
150 secstart
= (void **)tag
->ti_Data
;
154 secend
= (void **)tag
->ti_Data
;
158 function
= (char **)tag
->ti_Data
;
163 funstart
= (void **)tag
->ti_Data
;
168 funend
= (void **)tag
->ti_Data
;
174 /* We can be called in supervisor mode. No semaphores in the case! */
175 super
= KrnIsSuper();
177 ObtainSemaphoreShared(&DBGBASE(DebugBase
)->db_ModSem
);
179 ForeachNode(&DBGBASE(DebugBase
)->db_Modules
, seg
)
181 DSEGS(bug("[Debug] Checking segment 0x%p - 0x%p, num %u, module %s\n", seg
->s_lowest
, seg
->s_highest
, seg
->s_num
, seg
->s_mod
->m_name
));
183 /* if address suits the segment bounds, you got it */
184 if ((seg
->s_lowest
<= addr
) && (seg
->s_highest
>= addr
))
186 D(bug("[Debug] Found module %s, Segment %u (%s, 0x%p - 0x%p)\n", seg
->s_mod
->m_name
, seg
->s_num
,
187 seg
->s_name
, seg
->s_lowest
, seg
->s_highest
));
189 *module
= seg
->s_mod
->m_name
;
190 *segment
= seg
->s_name
;
191 *secptr
= seg
->s_seg
;
192 *secnum
= seg
->s_num
;
193 *secstart
= seg
->s_lowest
;
194 *secend
= seg
->s_highest
;
196 /* Now look up the function if requested */
197 if (FindSymbol(seg
->s_mod
, function
, funstart
, funend
, symaddr
)) {
205 ReleaseSemaphore(&DBGBASE(DebugBase
)->db_ModSem
);
207 /* Try to search kernel debug information if found nothing */
210 struct ELF_ModuleInfo
*kmod
;
212 D(bug("[Debug] Checking kernel modules...\n"));
214 for (kmod
= DBGBASE(DebugBase
)->db_KernelModules
; kmod
; kmod
= kmod
->Next
)
216 /* We understand only ELF here */
217 if (kmod
->Type
== DEBUG_ELF
)
219 struct elfheader
*eh
= kmod
->eh
;
220 struct sheader
*sections
= kmod
->sh
;
221 ULONG int_shnum
= eh
->shnum
;
222 ULONG int_shstrndx
= eh
->shstrndx
;
226 /* Get wider versions of shnum and shstrndx from first section header if needed */
228 int_shnum
= sections
[0].size
;
229 if (int_shstrndx
== SHN_XINDEX
)
230 int_shstrndx
= sections
[0].link
;
232 shstr
= SHINDEX(int_shstrndx
);
234 D(bug("[Debug] Module %s, %d sections at 0x%p\n", kmod
->Name
, int_shnum
, sections
));
236 for (i
=0; i
< int_shnum
; i
++)
238 void *s_lowest
= sections
[i
].addr
;
240 /* Ignore all empty segments */
241 if (s_lowest
&& sections
[i
].size
)
243 void *s_highest
= s_lowest
+ sections
[i
].size
- 1;
245 if ((s_lowest
<= addr
) && (s_highest
>= addr
))
249 if (sections
[shstr
].type
== SHT_STRTAB
)
250 s_name
= sections
[shstr
].addr
+ sections
[i
].name
;
252 D(bug("[Debug] Found module %s, Segment %u (%s, 0x%p - 0x%p)\n", kmod
->Name
, i
,
253 s_name
, s_lowest
, s_highest
));
255 *module
= (char *)kmod
->Name
;
259 *secstart
= s_lowest
;
268 /* If we are in correct module, let's try to look up the symbol */
273 /* Find symbols name table */
274 for (i
= 0; i
< int_shnum
; i
++)
276 if ((sections
[i
].type
== SHT_STRTAB
) && (i
!= shstr
))
278 m_str
= sections
[i
].addr
;
279 D(bug("[Debug] Symbol name table of length %d in section %d at 0x%p\n", sections
[i
].size
, i
, m_str
));
283 for (i
= 0; i
< int_shnum
; i
++)
285 if (sections
[i
].addr
&& sections
[i
].type
== SHT_SYMTAB
)
287 struct symbol
*st
= (struct symbol
*)sections
[i
].addr
;
288 unsigned int symcnt
= sections
[i
].size
/ sizeof(struct symbol
);
291 for (j
=0; j
< symcnt
; j
++)
293 int idx
= st
[j
].shindex
;
294 void *s_lowest
, *s_highest
, *cmp_highest
;
297 /* Ignore these - they should not be here at all */
298 if ((idx
== SHN_UNDEF
) || (idx
== SHN_COMMON
))
300 /* TODO: perhaps XINDEX support is needed */
301 if (idx
== SHN_XINDEX
)
304 s_name
= (m_str
) ? m_str
+ st
[j
].name
: NULL
;
306 s_lowest
= (void *)st
[j
].value
;
308 s_lowest
+= (IPTR
)sections
[idx
].addr
;
312 s_highest
= s_lowest
+ st
[j
].size
- 1;
313 cmp_highest
= s_highest
;
318 cmp_highest
= s_lowest
;
321 if ((s_lowest
<= addr
) && (cmp_highest
>= addr
))
324 *funstart
= s_lowest
;
333 /* Symbol not found */