2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
11 #include <aros/debug.h>
13 #include <libraries/debug.h>
14 #include <proto/exec.h>
15 #include <proto/kernel.h>
19 #include "debug_intern.h"
21 /* Binary search over sorted array of segments */
22 static struct segment
* FindSegmentInModule(void *addr
, module_t
*mod
)
24 LONG idx
, minidx
= 0, maxidx
= mod
->m_segcnt
- 1;
28 idx
= (maxidx
+ minidx
) / 2;
30 if (mod
->m_segments
[idx
]->s_lowest
<= addr
)
32 if (mod
->m_segments
[idx
]->s_highest
>= addr
)
34 return mod
->m_segments
[idx
];
38 /* cut off segments with lower addresses */
44 /* cut off segments with higher addresses */
48 /* Not found, aborting */
56 static struct segment
* FindSegment(void *addr
, struct Library
*DebugBase
)
60 ForeachNode(&DBGBASE(DebugBase
)->db_Modules
, mod
)
62 DSEGS(bug("[Debug] Checking module 0x%p - 0x%p, %s\n", mod
->m_lowest
, mod
->m_highest
, mod
->m_name
));
64 /* if address suits the module bounds, you got a candidate */
65 if (!((mod
->m_gaplowest
<= addr
) && (mod
->m_gaphighest
>= addr
)) &&
66 ((mod
->m_lowest
<= addr
) && (mod
->m_highest
>= addr
)))
68 struct segment
*seg
= FindSegmentInModule(addr
, mod
);
77 static BOOL
FindSymbol(module_t
*mod
, char **function
, void **funstart
, void **funend
, void *addr
)
79 dbg_sym_t
*sym
= mod
->m_symbols
;
82 /* Caller didn't care about symbols? */
90 for (i
= 0; i
< mod
->m_symcnt
; i
++)
92 APTR highest
= sym
[i
].s_highest
;
94 /* Symbols with zero length have zero in s_highest */
96 highest
= sym
[i
].s_lowest
;
98 if (sym
[i
].s_lowest
<= addr
&& highest
>= addr
) {
99 *function
= sym
[i
].s_name
;
100 *funstart
= sym
[i
].s_lowest
;
101 *funend
= sym
[i
].s_highest
;
107 /* Indicate that symbol not found */
111 /*****************************************************************************
114 #include <proto/debug.h>
116 AROS_LH2(int, DecodeLocationA
,
119 AROS_LHA(void *, addr
, A0
),
120 AROS_LHA(struct TagItem
*, tags
, A1
),
123 struct Library
*, DebugBase
, 7, Debug
)
126 Locate the given address in the list of registered modules and return
127 information about it.
130 addr - An address to resolve
131 tags - An optional taglist. ti_Tag can be one of the following tags and
132 ti_Data is always a pointer to a storage of specified type.
133 Resulting values will be placed into specified locations if the
136 DL_ModuleName (char *) - Module name
137 DL_SegmentName (char *) - Segment name. Can be NULL if there were
138 no segment names provided for the module.
139 DL_SegmentPointer (BPTR) - DOS pointer to the corresponding segment.
140 Note that it will be different from
141 KDL_SegmentStart value
143 DL_SegmentNumber (unsigned int) - Order number of the segment in the
145 DL_SegmentStart (void *) - Start address of actual segment contents
147 DL_SegmentEnd (void *) - End address of actual segment contents
149 DL_FirstSegment (BPTR) - DOS pointer to the first segment.
151 The following tags may return NULL values if there was no corresponding
152 information provided for the module:
154 DL_SymbolName (char *) - Symbol name (function or variable name)
155 DL_SymbolStart (void *) - Start address of contents described by this
157 DL_SymbolEnd (void *) - End address of contents described by this
161 Zero if lookup failed and no corresponding module found, nonzero
165 If the function fails values pointed to by taglist will not be changed.
175 ******************************************************************************/
181 char **module
= (char **)&dummy
;
182 char **segment
= (char **)&dummy
;
183 char **function
= (char **)&dummy
;
184 void **secstart
= &dummy
;
185 void **secend
= &dummy
;
186 void **funstart
= &dummy
;
187 void **funend
= &dummy
;
188 BPTR
*secptr
= (BPTR
*)&dummy
;
189 BPTR
*secfirst
= (BPTR
*)&dummy
;
190 unsigned int *secnum
= (unsigned int *)&dummy
;
191 struct TagItem
*tag
, *tstate
= tags
;
192 void *symaddr
= NULL
;
196 D(bug("[Debug] DecodeLocationA(0x%p)\n", addr
));
199 while ((tag
= LibNextTagItem(&tstate
)))
204 module
= (char **)tag
->ti_Data
;
208 segment
= (char **)tag
->ti_Data
;
211 case DL_SegmentPointer
:
212 secptr
= (BPTR
*)tag
->ti_Data
;
215 case DL_SegmentNumber
:
216 secnum
= (unsigned int *)tag
->ti_Data
;
219 case DL_SegmentStart
:
220 secstart
= (void **)tag
->ti_Data
;
224 secend
= (void **)tag
->ti_Data
;
227 case DL_FirstSegment
:
228 secfirst
= (BPTR
*)tag
->ti_Data
;
232 function
= (char **)tag
->ti_Data
;
237 funstart
= (void **)tag
->ti_Data
;
242 funend
= (void **)tag
->ti_Data
;
248 /* We can be called in supervisor mode. No semaphores in the case! */
249 super
= KrnIsSuper();
251 ObtainSemaphoreShared(&DBGBASE(DebugBase
)->db_ModSem
);
253 seg
= FindSegment(addr
, DebugBase
);
256 D(bug("[Debug] Found module %s, Segment %u (%s, 0x%p - 0x%p)\n", seg
->s_mod
->m_name
, seg
->s_num
,
257 seg
->s_name
, seg
->s_lowest
, seg
->s_highest
));
259 *module
= seg
->s_mod
->m_name
;
260 *segment
= seg
->s_name
;
261 *secptr
= seg
->s_seg
;
262 *secnum
= seg
->s_num
;
263 *secstart
= seg
->s_lowest
;
264 *secend
= seg
->s_highest
;
265 *secfirst
= seg
->s_mod
->m_seg
;
267 /* Now look up the function if requested */
268 FindSymbol(seg
->s_mod
, function
, funstart
, funend
, symaddr
);
273 ReleaseSemaphore(&DBGBASE(DebugBase
)->db_ModSem
);