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
)
58 struct DebugBase
*debugBase
= DBGBASE(DebugBase
);
61 ForeachNode(&debugBase
->db_Modules
, mod
)
63 DSEGS(bug("[Debug] Checking module 0x%p - 0x%p, %s\n", mod
->m_lowest
, mod
->m_highest
, mod
->m_name
));
65 /* if address suits the module bounds, you got a candidate */
66 if (!((mod
->m_gaplowest
<= addr
) && (mod
->m_gaphighest
>= addr
)) &&
67 ((mod
->m_lowest
<= addr
) && (mod
->m_highest
>= addr
)))
69 struct segment
*seg
= FindSegmentInModule(addr
, mod
);
78 static BOOL
FindSymbol(module_t
*mod
, char **function
, void **funstart
, void **funend
, void *addr
)
80 dbg_sym_t
*sym
= mod
->m_symbols
;
83 /* Caller didn't care about symbols? */
91 for (i
= 0; i
< mod
->m_symcnt
; i
++)
93 APTR highest
= sym
[i
].s_highest
;
95 /* Symbols with zero length have zero in s_highest */
97 highest
= sym
[i
].s_lowest
;
99 if (sym
[i
].s_lowest
<= addr
&& highest
>= addr
) {
100 *function
= sym
[i
].s_name
;
101 *funstart
= sym
[i
].s_lowest
;
102 *funend
= sym
[i
].s_highest
;
108 /* Indicate that symbol not found */
112 /*****************************************************************************
115 #include <proto/debug.h>
117 AROS_LH2(int, DecodeLocationA
,
120 AROS_LHA(void *, addr
, A0
),
121 AROS_LHA(struct TagItem
*, tags
, A1
),
124 struct Library
*, DebugBase
, 7, Debug
)
127 Locate the given address in the list of registered modules and return
128 information about it.
131 addr - An address to resolve
132 tags - An optional taglist. ti_Tag can be one of the following tags and
133 ti_Data is always a pointer to a storage of specified type.
134 Resulting values will be placed into specified locations if the
137 DL_ModuleName (char *) - Module name
138 DL_SegmentName (char *) - Segment name. Can be NULL if there were
139 no segment names provided for the module.
140 DL_SegmentPointer (BPTR) - DOS pointer to the corresponding segment.
141 Note that it will be different from
142 KDL_SegmentStart value
144 DL_SegmentNumber (unsigned int) - Order number of the segment in the
146 DL_SegmentStart (void *) - Start address of actual segment contents
148 DL_SegmentEnd (void *) - End address of actual segment contents
150 DL_FirstSegment (BPTR) - DOS pointer to the first segment.
152 The following tags may return NULL values if there was no corresponding
153 information provided for the module:
155 DL_SymbolName (char *) - Symbol name (function or variable name)
156 DL_SymbolStart (void *) - Start address of contents described by this
158 DL_SymbolEnd (void *) - End address of contents described by this
162 Zero if lookup failed and no corresponding module found, nonzero
166 If the function fails values pointed to by taglist will not be changed.
176 ******************************************************************************/
182 char **module
= (char **)&dummy
;
183 char **segment
= (char **)&dummy
;
184 char **function
= (char **)&dummy
;
185 void **secstart
= &dummy
;
186 void **secend
= &dummy
;
187 void **funstart
= &dummy
;
188 void **funend
= &dummy
;
189 BPTR
*secptr
= (BPTR
*)&dummy
;
190 BPTR
*secfirst
= (BPTR
*)&dummy
;
191 unsigned int *secnum
= (unsigned int *)&dummy
;
192 struct TagItem
*tag
, *tstate
= tags
;
193 void *symaddr
= NULL
;
197 D(bug("[Debug] DecodeLocationA(0x%p)\n", addr
));
200 while ((tag
= LibNextTagItem(&tstate
)))
205 module
= (char **)tag
->ti_Data
;
209 segment
= (char **)tag
->ti_Data
;
212 case DL_SegmentPointer
:
213 secptr
= (BPTR
*)tag
->ti_Data
;
216 case DL_SegmentNumber
:
217 secnum
= (unsigned int *)tag
->ti_Data
;
220 case DL_SegmentStart
:
221 secstart
= (void **)tag
->ti_Data
;
225 secend
= (void **)tag
->ti_Data
;
228 case DL_FirstSegment
:
229 secfirst
= (BPTR
*)tag
->ti_Data
;
233 function
= (char **)tag
->ti_Data
;
238 funstart
= (void **)tag
->ti_Data
;
243 funend
= (void **)tag
->ti_Data
;
249 /* We can be called in supervisor mode. No semaphores in the case! */
250 super
= KrnIsSuper();
252 ObtainSemaphoreShared(&DBGBASE(DebugBase
)->db_ModSem
);
254 seg
= FindSegment(addr
, DebugBase
);
257 D(bug("[Debug] Found module %s, Segment %u (%s, 0x%p - 0x%p)\n", seg
->s_mod
->m_name
, seg
->s_num
,
258 seg
->s_name
, seg
->s_lowest
, seg
->s_highest
));
260 *module
= seg
->s_mod
->m_name
;
261 *segment
= seg
->s_name
;
262 *secptr
= seg
->s_seg
;
263 *secnum
= seg
->s_num
;
264 *secstart
= seg
->s_lowest
;
265 *secend
= seg
->s_highest
;
266 *secfirst
= seg
->s_mod
->m_seg
;
268 /* Now look up the function if requested */
269 FindSymbol(seg
->s_mod
, function
, funstart
, funend
, symaddr
);
274 ReleaseSemaphore(&DBGBASE(DebugBase
)->db_ModSem
);