configure: when detecting linux include directory for kernel compiler use target...
[AROS.git] / rom / debug / unregistermodule.c
blob56e3805f8c3fecaf0fe91b487b822ccd58161eff
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 */
8 #include <aros/debug.h>
9 #include <aros/kernel.h>
10 #include <aros/libcall.h>
11 #include <exec/lists.h>
12 #include <proto/exec.h>
14 #include <string.h>
16 #include "debug_intern.h"
18 static module_t * FindModule(BPTR segList, struct Library * DebugBase);
19 static LONG FindIndex(module_t * mod, BPTR segList);
20 static VOID RemoveSegmentRange(module_t * mod, LONG firstidx, LONG count);
22 /*****************************************************************************
24 NAME */
25 #include <proto/debug.h>
27 AROS_LH1(void, UnregisterModule,
29 /* SYNOPSIS */
30 AROS_LHA(BPTR, segList, A0),
32 /* LOCATION */
33 struct Library *, DebugBase, 6, Debug)
35 /* FUNCTION
36 Remove previously registered module from the debug information database
38 INPUTS
39 segList - DOS segment list for the module to remove
41 RESULT
42 None
44 NOTES
45 The function correctly supports partial removal of the module
46 (when an existing seglist is broken and only a part of the module
47 is unloaded).
49 EXAMPLE
51 BUGS
53 SEE ALSO
55 INTERNALS
57 ******************************************************************************/
59 AROS_LIBFUNC_INIT
61 module_t *mod = NULL;
62 LONG i = 0, rangestart = -1;
64 D(bug("[Debug] UnregisterModule(0x%p)\n", segList));
65 ObtainSemaphore(&DBGBASE(DebugBase)->db_ModSem);
67 while (segList)
69 if (mod == NULL) /* Search for new module */
70 mod = FindModule(segList, DebugBase);
72 if (mod)
74 if (rangestart == -1) /* Search for new index */
75 i = rangestart = FindIndex(mod, segList);
77 /* Optimization assumes order of segments is similar to order of DOS segments */
78 if ((i >= mod->m_segcnt) || (mod->m_segments[i]->s_seg != segList))
80 /* Order broken, clear ordered segments */
81 RemoveSegmentRange(mod, rangestart, (i - rangestart));
83 /* Restart */
84 i = rangestart = FindIndex(mod, segList);
87 i++;
90 /* Advance to next DOS segment */
91 segList = *(BPTR *)BADDR(segList);
94 if (mod != NULL && rangestart > -1)
95 RemoveSegmentRange(mod, rangestart, (i - rangestart));
97 ReleaseSemaphore(&DBGBASE(DebugBase)->db_ModSem);
99 AROS_LIBFUNC_EXIT
102 static module_t * FindModule(BPTR segList, struct Library * DebugBase)
104 struct DebugBase *debugBase = DBGBASE(DebugBase);
105 module_t *mod;
106 LONG i;
108 ForeachNode(&debugBase->db_Modules, mod)
110 for (i = 0; i < mod->m_segcnt; i++)
112 if (mod->m_segments[i]->s_seg == segList)
114 return mod;
119 return NULL;
122 static LONG FindIndex(module_t * mod, BPTR segList)
124 LONG i;
126 for (i = 0; i < mod->m_segcnt; i++)
128 if (mod->m_segments[i]->s_seg == segList)
130 return i;
134 return -1;
137 static VOID RemoveSegmentRange(module_t * mod, LONG firstidx, LONG count)
139 struct segment * seg;
140 LONG i;
142 for (i = 0 ; i < count ; i++)
144 seg = mod->m_segments[i + firstidx];
146 FreeMem(seg, sizeof(struct segment));
148 /* If module's segment count reached 0, remove the whole
149 module information */
150 if (--mod->m_segcnt == 0)
152 D(bug("[Debug] Removing module %s\n", mod->m_name));
154 /* Free associated symbols */
155 if (mod->m_symbols) {
156 D(bug("[Debug] Removing symbol table 0x%p\n", mod->m_symbols));
157 FreeVec(mod->m_symbols);
160 /* Free associated string tables */
161 if (mod->m_str) {
162 D(bug("[Debug] Removing symbol name table 0x%p\n", mod->m_str));
163 FreeVec(mod->m_str);
165 if (mod->m_shstr) {
166 D(bug("[Debug] Removing section name table 0x%p\n", mod->m_str));
167 FreeVec(mod->m_shstr);
170 Remove((struct Node *)mod);
171 FreeVec(mod->m_segments);
172 #if AROS_MODULES_DEBUG
173 FreeVec(mod->m_seggdbhlp);
174 #endif
175 /* Free module descriptor at last */
176 FreeVec(mod);
178 return;
182 /* "Shrink" array of segments so that at any given time the array is valid for
183 * binary search
185 for (i = firstidx;i < mod->m_segcnt; i++)
186 mod->m_segments[i] = mod->m_segments[i + count];