WIP: add an initial skeleton for a real scsi.device based upon the ata device impleme...
[AROS.git] / rom / debug / unregistermodule.c
blob09006d0ff99d5f974d29ff1c739674e9ee3f79c2
1 /*
2 Copyright © 1995-2016, 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 */
71 D(bug("[Debug] Looking for module matching seglist %p\n", segList));
72 mod = FindModule(segList, DebugBase);
73 D(if (mod) bug("[Debug] Found module '%s'\n", mod->m_name);
74 else bug("[Debug] No module found!\n"));
77 if (mod)
79 if (rangestart == -1) /* Search for new index */
80 i = rangestart = FindIndex(mod, segList);
82 /* Optimization assumes order of segments is similar to order of DOS segments */
83 if ((i >= mod->m_segcnt) || (mod->m_segments[i]->s_seg != segList))
85 /* Order broken, clear ordered segments */
86 RemoveSegmentRange(mod, rangestart, (i - rangestart));
88 /* Restart */
89 i = rangestart = FindIndex(mod, segList);
92 i++;
95 /* Advance to next DOS segment */
96 segList = *(BPTR *)BADDR(segList);
99 if (mod != NULL && rangestart > -1)
100 RemoveSegmentRange(mod, rangestart, (i - rangestart));
102 ReleaseSemaphore(&DBGBASE(DebugBase)->db_ModSem);
104 AROS_LIBFUNC_EXIT
107 static module_t * FindModule(BPTR segList, struct Library * DebugBase)
109 struct DebugBase *debugBase = DBGBASE(DebugBase);
110 module_t *mod;
111 LONG i;
113 ForeachNode(&debugBase->db_Modules, mod)
115 for (i = 0; i < mod->m_segcnt; i++)
117 if (mod->m_segments[i]->s_seg == segList)
119 return mod;
124 return NULL;
127 static LONG FindIndex(module_t * mod, BPTR segList)
129 LONG i;
131 for (i = 0; i < mod->m_segcnt; i++)
133 if (mod->m_segments[i]->s_seg == segList)
135 return i;
139 return -1;
142 static VOID RemoveSegmentRange(module_t * mod, LONG firstidx, LONG count)
144 struct segment * seg;
145 LONG i;
147 D(bug("[Debug] RemoveSegmentRange('%s', %ld, %ld)\n", mod->m_name,
148 firstidx, count));
149 for (i = 0 ; i < count ; i++)
151 seg = mod->m_segments[i + firstidx];
153 FreeMem(seg, sizeof(struct segment));
155 /* If module's segment count reached 0, remove the whole
156 module information */
157 if (--mod->m_segcnt == 0)
159 D(bug("[Debug] Removing module %s\n", mod->m_name));
161 /* Free associated symbols */
162 if (mod->m_symbols) {
163 D(bug("[Debug] Removing symbol table 0x%p\n", mod->m_symbols));
164 FreeVec(mod->m_symbols);
167 /* Free associated string tables */
168 if (mod->m_str) {
169 D(bug("[Debug] Removing symbol name table 0x%p\n", mod->m_str));
170 FreeVec(mod->m_str);
172 if (mod->m_shstr) {
173 D(bug("[Debug] Removing section name table 0x%p\n", mod->m_str));
174 FreeVec(mod->m_shstr);
177 Remove((struct Node *)mod);
178 FreeVec(mod->m_segments);
179 #if AROS_MODULES_DEBUG
180 FreeVec(mod->m_seggdbhlp);
181 #endif
182 /* Free module descriptor at last */
183 FreeVec(mod);
185 return;
189 /* "Shrink" array of segments so that at any given time the array is valid for
190 * binary search
192 for (i = firstidx;i < mod->m_segcnt; i++)
193 mod->m_segments[i] = mod->m_segments[i + count];