Improvements to error handling:
[AROS.git] / rom / debug / unregistermodule.c
bloba7646b55833c56b9d529757f8bb315abc77af363
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 module_t *mod;
105 LONG i;
107 ForeachNode(&DBGBASE(DebugBase)->db_Modules, mod)
109 for (i = 0; i < mod->m_segcnt; i++)
111 if (mod->m_segments[i]->s_seg == segList)
113 return mod;
118 return NULL;
121 static LONG FindIndex(module_t * mod, BPTR segList)
123 LONG i;
125 for (i = 0; i < mod->m_segcnt; i++)
127 if (mod->m_segments[i]->s_seg == segList)
129 return i;
133 return -1;
136 static VOID RemoveSegmentRange(module_t * mod, LONG firstidx, LONG count)
138 struct segment * seg;
139 LONG i;
141 for (i = 0 ; i < count ; i++)
143 seg = mod->m_segments[i + firstidx];
145 FreeMem(seg, sizeof(struct segment));
147 /* If module's segment count reached 0, remove the whole
148 module information */
149 if (--mod->m_segcnt == 0)
151 D(bug("[Debug] Removing module %s\n", mod->m_name));
153 /* Free associated symbols */
154 if (mod->m_symbols) {
155 D(bug("[Debug] Removing symbol table 0x%p\n", mod->m_symbols));
156 FreeVec(mod->m_symbols);
159 /* Free associated string tables */
160 if (mod->m_str) {
161 D(bug("[Debug] Removing symbol name table 0x%p\n", mod->m_str));
162 FreeVec(mod->m_str);
164 if (mod->m_shstr) {
165 D(bug("[Debug] Removing section name table 0x%p\n", mod->m_str));
166 FreeVec(mod->m_shstr);
169 Remove((struct Node *)mod);
170 FreeVec(mod->m_segments);
171 #if AROS_MODULES_DEBUG
172 FreeVec(mod->m_seggdbhlp);
173 #endif
174 /* Free module descriptor at last */
175 FreeVec(mod);
177 return;
181 /* "Shrink" array of segments so that at any given time the array is valid for
182 * binary search
184 for (i = firstidx;i < mod->m_segcnt; i++)
185 mod->m_segments[i] = mod->m_segments[i + count];