source: trunk/kLdr/kLdrDyldMod.c@ 2837

Last change on this file since 2837 was 2837, checked in by bird, 19 years ago

in progress...

File size: 4.5 KB
Line 
1/* $Id: $ */
2/** @file
3 *
4 * kLdr - The Dynamic Loader, Dyld module methods.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird-kbuild-src@anduin.net>
7 *
8 *
9 * This file is part of kLdr.
10 *
11 * kLdr is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kLdr is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kLdr; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28
29/*******************************************************************************
30* Header Files *
31*******************************************************************************/
32#include <kLdr.h>
33#include "kLdrInternal.h"
34#include "kLdrHlp.h"
35
36
37/*******************************************************************************
38* Defined Constants And Macros *
39*******************************************************************************/
40/** @def KLDRDYLDMOD_ASSERT
41 * Assert that an expression is true when KLDRDYLD_STRICT is defined.
42 */
43#ifdef KLDRDYLD_STRICT
44# define KLDRDYLDMOD_ASSERT(expr) kldrHlpAssert(expr)
45#else
46# define KLDRDYLDMOD_ASSERT(expr) do {} while (0)
47#endif
48
49
50
51
52void kldrDyldModUnloadPrerequisites(PKLDRDYLDMOD pMod)
53{
54
55}
56
57
58void kldrDyldModDeref(PKLDRDYLDMOD pMod)
59{
60 /* validate input */
61 KLDRDYLDMOD_ASSERT(pMod->enmState > KLDRSTATE_INVALID && pMod->enmState < KLDRSTATE_END);
62 KLDRDYLDMOD_ASSERT(pMod->cRefs > 0);
63 KLDRDYLDMOD_ASSERT(pMod->cRefs >= pMod->cDepRefs + pMod->cDynRefs);
64
65 /* decrement. */
66 if (pMod->cRefs > 0)
67 pMod->cRefs--;
68
69 /*
70 * Drop prerequisites for stats that implies that no recursion can have taken place yet.
71 * This ASSUMES that we're only dereferencing modules when an operation completes.
72 * (This is *required* for the reloaded state.)
73 */
74 switch (pMod->enmState)
75 {
76 case KLDRSTATE_MAPPED:
77 case KLDRSTATE_LOADED_PREREQUISITES:
78 case KLDRSTATE_FIXED_UP:
79 case KLDRSTATE_RELOADED:
80 kldrDyldModUnloadPrerequisites(pMod);
81 pMod->enmState = KLDRSTATE_PENDING_GC;
82 break;
83
84 case KLDRSTATE_PENDING_INITIALIZATION:
85 case KLDRSTATE_INITIALIZING:
86 case KLDRSTATE_GOOD:
87 case KLDRSTATE_PENDING_TERMINATION:
88 case KLDRSTATE_TERMINATING:
89 case KLDRSTATE_PENDING_GC:
90 case KLDRSTATE_GC:
91 case KLDRSTATE_PENDING_DESTROY:
92 break;
93
94 default:
95 KLDRDYLDMOD_ASSERT(!"Invalid deref state");
96 break;
97 }
98
99 /*
100 * Also drop prerequisites if noone is referencing the module.
101 */
102 if (!pMod->cDepRefs && !pMod->cDynRefs)
103 {
104 switch (pMod->enmState)
105 {
106 case KLDRSTATE_MAPPED:
107 case KLDRSTATE_LOADED_PREREQUISITES:
108 case KLDRSTATE_FIXED_UP:
109 case KLDRSTATE_RELOADED:
110 /* already dropped. */
111 break;
112
113 case KLDRSTATE_PENDING_INITIALIZATION:
114 kldrDyldModUnloadPrerequisites(pMod);
115 pMod->enmState = KLDRSTATE_PENDING_GC;
116 break;
117
118 case KLDRSTATE_GOOD:
119 pMod->enmState = KLDRSTATE_PENDING_TERMINATION;
120 case KLDRSTATE_PENDING_TERMINATION:
121 case KLDRSTATE_PENDING_GC:
122 kldrDyldModUnloadPrerequisites(pMod);
123 break;
124
125 case KLDRSTATE_TERMINATING:
126 case KLDRSTATE_GC:
127 case KLDRSTATE_PENDING_DESTROY:
128 break;
129
130 default:
131 KLDRDYLDMOD_ASSERT(!"Invalid deref state (b)");
132 break;
133 }
134 }
135
136 /*
137 * If there are no references whatsoever now and the module
138 * is pending destruction, destroy it.
139 */
140 if ( !pMod->cRefs
141 && ( pMod->enmState == KLDRSTATE_PENDING_DESTROY
142 || pMod->enmState == KLDRSTATE_GC))
143 kldrDyldModDestroy(pMod);
144}
Note: See TracBrowser for help on using the repository browser.