source: trunk/kLdr/kLdrDyldMod.c@ 2845

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

kldrDyldMod* in progress.

File size: 19.8 KB
RevLine 
[2835]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
[2837]37/*******************************************************************************
38* Defined Constants And Macros *
39*******************************************************************************/
[2845]40/** @def KLDRDYLDMOD_STRICT
41 * Define KLDRDYLDMOD_STRICT to enabled strict checks in kLdrDyld. */
42#define KLDRDYLDMOD_STRICT 1
43
[2837]44/** @def KLDRDYLDMOD_ASSERT
45 * Assert that an expression is true when KLDRDYLD_STRICT is defined.
46 */
[2845]47#ifdef KLDRDYLDMOD_STRICT
[2837]48# define KLDRDYLDMOD_ASSERT(expr) kldrHlpAssert(expr)
49#else
50# define KLDRDYLDMOD_ASSERT(expr) do {} while (0)
51#endif
[2835]52
53
54
[2842]55/**
[2845]56 * Creates a module from the specified file provider instance.
57 *
58 * @returns 0 on success and *ppMod pointing to the new instance.
59 * On failure a non-zero kLdr status code is returned.
60 * @param pRdr The file provider instance.
61 * @param ppMod Where to put the pointer to the new module on success.
62 */
63int kldrDyldModCreate(PKLDRRDR pRdr, PPKLDRDYLDMOD ppMod)
64{
65 PKLDRDYLDMOD pMod;
66 PKLDRMOD pRawMod;
67 int rc;
68
69 *ppMod = NULL;
70
71 /*
72 * Try open an module interpreter.
73 */
74 rc = kLdrModOpenFromRdr(pRdr, &pRawMod);
75 if (rc)
76 return kldrDyldFailure(rc, "%s: %rc", kLdrRdrName(pRdr), rc);
77
78 /*
79 * Allocate a new dyld module.
80 */
81 pMod = (PKLDRDYLDMOD)kldrHlpAlloc(sizeof(*pMod));
82 if (pMod)
83 {
84 pMod->enmState = KLDRSTATE_OPEN;
85 pMod->pMod = pRawMod;
86 pMod->hMod = pMod;
87 pMod->cDepRefs = pMod->cDynRefs = pMod->cRefs = 0;
88 pMod->fExecutable = 0;
89 switch (pRawMod->enmType)
90 {
91 case KLDRTYPE_EXECUTABLE_FIXED:
92 case KLDRTYPE_EXECUTABLE_RELOCATABLE:
93 case KLDRTYPE_EXECUTABLE_PIC:
94 pMod->fExecutable = 1;
95 break;
96 }
97 pMod->fGlobalOrSpecific = 0;
98 pMod->fBindable = 0;
99 pMod->fInitList = 0;
100 pMod->fAlreadySeen = 0;
101 pMod->fMapped = 0;
102 pMod->f26Reserved = 0;
103 pMod->InitTerm.pNext = NULL;
104 pMod->InitTerm.pPrev = NULL;
105 pMod->Bind.pNext = NULL;
106 pMod->Bind.pPrev = NULL;
107 pMod->cPrereqs = 0;
108 pMod->papPrereqs = NULL;
109 pMod->u32MagicHead = KLDRDYMOD_MAGIC;
110 pMod->u32MagicTail = KLDRDYMOD_MAGIC;
111
112 /* it. */
113 pMod->Load.pNext = NULL;
114 pMod->Load.pPrev = kLdrDyldTail;
115 if (kLdrDyldTail)
116 kLdrDyldTail->Load.pNext = pMod;
117 else
118 kLdrDyldHead = pMod;
119 kLdrDyldTail = pMod;
120
121 /* we're good. */
122 *ppMod = pMod;
123 rc = 0;
124 }
125 else
126 {
127 kLdrModClose(pRawMod);
128 rc = KLDR_ERR_NO_MEMORY;
129 }
130 return rc;
131}
132
133
134/**
135 * Creates a module for a native module.
136 *
137 * @returns 0 on success and *ppMod pointing to the new instance.
138 * On failure a non-zero kLdr status code is returned.
139 * @param hNativeModule The native handle.
140 * @param ppMod Where to put the pointer to the new module on success.
141 * @remark This function ain't finalized yet.
142 */
143int kldrDyldModCreateNative(uintptr_t hNativeModule)
144{
145#if 0
146 /*
147 * Check if this module is already loaded by the native OS loader.
148 */
149 rc = kld
150 {
151#ifdef __OS2__
152 HMODULE hmod = NULLHANDLE;
153 APIRET rc = DosQueryModuleHandle(kLdrRdrName(pRdr), &hmod);
154 if (!rc)
155
156#elif defined(__WIN__)
157 HMODULE hmod = NULL;
158 if (GetModuleHandle(kLdrRdrName(pRdr))
159
160#else
161# error "Port me"
162#endif
163 }
164#endif
165 return -1;
166}
167
168
169/**
170 * Destroys a module pending destruction.
171 *
172 * @param pMod The module in question.
173 */
174void kldrDyldModDestroy(PKLDRDYLDMOD pMod)
175{
176 /*
177 * Validate the state.
178 */
179 switch (pMod->enmState)
180 {
181 case KLDRSTATE_PENDING_DESTROY:
182 case KLDRSTATE_GC:
183 break;
184 default:
185 KLDRDYLDMOD_ASSERT(!"Invalid state");
186 break;
187 }
188 KLDRDYLDMOD_ASSERT(!pMod->fInitList);
189 KLDRDYLDMOD_ASSERT(!pMod->cDynRefs);
190 KLDRDYLDMOD_ASSERT(!pMod->cDepRefs);
191
192
193 /*
194 * Ensure that the module is unmapped.
195 */
196 if (pMod->fMapped)
197 kldrDyldModUnmap(pMod);
198}
199
200
201/**
202 * Unlinks the module from any list it might be in.
203 * It is assumed that the module is at least linked into the load list.
204 *
205 * @param pMod The moduel.
206 */
207static void kldrDyldModUnlink(PKLDRDYLDMOD pMod)
208{
209 /* load list */
210 if (pMod->Load.pNext)
211 pMod->Load.pNext->Load.pPrev = pMod->Load.pPrev;
212 else
213 kLdrDyldTail = pMod->Load.pPrev;
214 if (pMod->Load.pPrev)
215 pMod->Load.pPrev->Load.pNext = pMod->Load.pNext;
216 else
217 kLdrDyldHead = pMod->Load.pNext;
218
219 /* bind list */
220 if (pMod->fBindable)
221 kldrDyldModClearBindable(pMod);
222
223 /* init term */
224 if (pMod->fInitList)
225 {
226 KLDRDYLDMOD_ASSERT(pMod->enmState < KLDRSTATE_INITIALIZATION_FAILED);
227 pMod->fInitList = 0;
228 if (pMod->InitTerm.pNext)
229 pMod->InitTerm.pNext->InitTerm.pPrev = pMod->InitTerm.pPrev;
230 else
231 g_pkLdrDyldInitTail = pMod->InitTerm.pPrev;
232 if (pMod->InitTerm.pPrev)
233 pMod->InitTerm.pPrev->InitTerm.pNext = pMod->InitTerm.pNext;
234 else
235 g_pkLdrDyldInitHead = pMod->InitTerm.pNext;
236 }
237 else if (pMod->enmState > KLDRSTATE_INITIALIZATION_FAILED)
238 {
239 KLDRDYLDMOD_ASSERT(pMod->enmState >= KLDRSTATE_GOOD);
240 if (pMod->InitTerm.pNext)
241 pMod->InitTerm.pNext->InitTerm.pPrev = pMod->InitTerm.pPrev;
242 else
243 g_pkLdrDyldTermTail = pMod->InitTerm.pPrev;
244 if (pMod->InitTerm.pPrev)
245 pMod->InitTerm.pPrev->InitTerm.pNext = pMod->InitTerm.pNext;
246 else
247 g_pkLdrDyldTermHead = pMod->InitTerm.pNext;
248 }
249 pMod->InitTerm.pNext = NULL;
250 pMod->InitTerm.pPrev = NULL;
251}
252
253
254/**
255 * Adds a reference to the module making sure it won't be freed just yet.
256 *
257 * @param pMod The module.
258 */
259void kldrDyldModAddRef(PKLDRDYLDMOD pMod)
260{
261 pMod->cRefs++;
262}
263
264
265/**
266 * Dereference a module.
267 *
268 * @param pMod
269 */
270void kldrDyldModDeref(PKLDRDYLDMOD pMod)
271{
272 /* validate input */
273 KLDRDYLDMOD_ASSERT(pMod->cRefs > 0);
274 KLDRDYLDMOD_ASSERT(pMod->cRefs >= pMod->cDepRefs + pMod->cDynRefs);
275 KLDRDYLDMOD_ASSERT(pMod->enmState > KLDRSTATE_INVALID && pMod->enmState <= KLDRSTATE_END);
276
277 /* decrement. */
278 if (pMod->cRefs > 0)
279 pMod->cRefs--;
280
281 /* execute delayed freeing. */
282 if ( pMod->enmState == KLDRSTATE_DESTROYED
283 && !pMod->cRefs)
284 kldrHlpFree(pMod);
285}
286
287
288/**
289 * Increment the count of modules depending on this module.
290 *
291 * @param pMod The module.
292 * @param pDep The module which depends on us.
293 */
294void kldrDyldModAddDep(PKLDRDYLDMOD pMod, PKLDRDYLDMOD pDep)
295{
296 (void)pDep;
297
298 /* validate state */
299 switch (pMod->enmState)
300 {
301 case KLDRSTATE_MAPPED:
302 case KLDRSTATE_RELOADED:
303 case KLDRSTATE_LOADED_PREREQUISITES:
304 case KLDRSTATE_RELOADED_LOADED_PREREQUISITES:
305 case KLDRSTATE_PENDING_INITIALIZATION:
306 case KLDRSTATE_INITIALIZING:
307 case KLDRSTATE_GOOD:
308 break;
309 default:
310 KLDRDYLDMOD_ASSERT(!"invalid state");
311 break;
312
313 }
314 KLDRDYLDMOD_ASSERT(pMod->enmState > KLDRSTATE_INVALID && pMod->enmState <= KLDRSTATE_END);
315 pMod->cRefs++;
316 pMod->cDepRefs++;
317}
318
319
320/**
321 * Drop a dependency.
322 *
323 * @param pMod The module.
324 * @param pDep The module which depends on us.
325 */
326void kldrDyldModRemoveDep(PKLDRDYLDMOD pMod, PKLDRDYLDMOD pDep)
327{
328 KLDRDYLDMOD_ASSERT(pMod->cDepRefs > 0);
329 if (pMod->cDepRefs == 0)
330 return;
331 KLDRDYLDMOD_ASSERT(pMod->cDepRefs <= pMod->cRefs);
332 KLDRDYLDMOD_ASSERT(pMod->enmState >= KLDRSTATE_MAPPED && pMod->enmState <= KLDRSTATE_PENDING_DESTROY);
333
334 pMod->cRefs--;
335 pMod->cDepRefs--;
336 if ( pMod->cDepRefs > 0
337 || pMod->cDynRefs > 0)
338 return;
339
340 /*
341 * The module should be unloaded.
342 */
343 kldrDyldModUnloadPrerequisites(pMod);
344}
345
346
347/**
348 * Increment the dynamic load count.
349 *
350 * @returns 0
351 * @param pMod The module.
352 */
353int kldrDyldModDynamicLoad(PKLDRDYLDMOD pMod)
354{
355 KLDRDYLDMOD_ASSERT( pMod->enmState == KLDRSTATE_GOOD
356 || pMod->enmState == KLDRSTATE_PENDING_INITIALIZATION
357 || pMod->enmState == KLDRSTATE_INITIALIZING);
358 pMod->cRefs++;
359 pMod->cDynRefs++;
360 return 0;
361}
362
363
364/**
[2842]365 * Decrement the dynamic load count of the module and unload the module
366 * if the total reference count reaches zero.
367 *
368 * This may cause a cascade of unloading to occure. See kldrDyldModUnloadPrerequisites().
369 *
370 * @returns status code.
371 * @retval 0 on success.
372 * @retval KLDR_ERR_NOT_LOADED_DYNAMICALLY if the module wasn't loaded dynamically.
373 * @param pMod The module to unload.
374 */
375int kldrDyldModDynamicUnload(PKLDRDYLDMOD pMod)
376{
377 if (pMod->cDynRefs == 0)
378 return KLDR_ERR_NOT_LOADED_DYNAMICALLY;
379 KLDRDYLDMOD_ASSERT(pMod->cDynRefs <= pMod->cRefs);
380 KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_GOOD);
[2837]381
[2842]382 pMod->cRefs--;
383 pMod->cDynRefs--;
[2845]384 if ( pMod->cDynRefs > 0
385 || pMod->cDepRefs > 0)
[2842]386 return 0;
387
388 /*
389 * The module should be unloaded.
390 */
391 kldrDyldModUnloadPrerequisites(pMod);
392 return 0;
393}
394
395
396/**
397 * Worker for kldrDyldModUnloadPrerequisites.
398 *
399 * @returns The number of modules that now can be unloaded.
400 * @param pMod The module in question.
401 */
402static uint32_t kldrDyldModUnloadPrerequisitesOne(PKLDRDYLDMOD pMod)
403{
404 PKLDRDYLDMOD pMod2;
405 uint32_t cToUnload = 0;
406 uint32_t i;
407
408 KLDRDYLDMOD_ASSERT(pMod->papPrereqs);
409
410 /*
411 * Release the one in this module.
412 */
413 for (i = 0; i < pMod->cPrereqs; i++)
414 {
415 pMod2 = pMod->papPrereqs[i];
416 if (pMod2)
417 {
418 /* do the derefering ourselves or we'll end up in a recursive loop here. */
419 KLDRDYLDMOD_ASSERT(pMod2->cDepRefs > 0);
420 KLDRDYLDMOD_ASSERT(pMod2->cRefs >= pMod2->cDepRefs);
421 pMod2->cDepRefs--;
422 pMod2->cRefs--;
423 cToUnload += !pMod2->cRefs;
424 }
425 }
426
427 /*
428 * Change the state
429 */
430 switch (pMod->enmState)
431 {
432 case KLDRSTATE_LOADED_PREREQUISITES:
433 case KLDRSTATE_FIXED_UP:
434 pMod->enmState = KLDRSTATE_PENDING_DESTROY;
435 kldrDyldModUnlink(pMod);
436 break;
437
438 case KLDRSTATE_PENDING_INITIALIZATION:
439 pMod->enmState = KLDRSTATE_PENDING_GC;
440 break;
441
442 case KLDRSTATE_RELOADED_FIXED_UP:
443 case KLDRSTATE_RELOADED_LOADED_PREREQUISITES:
444 case KLDRSTATE_GOOD:
445 pMod->enmState = KLDRSTATE_PENDING_TERMINATION;
446 break;
447
448 case KLDRSTATE_INITIALIZATION_FAILED:
449 break;
450
451 default:
452 KLDRDYLDMOD_ASSERT(!"invalid state");
453 break;
454 }
455
456 return cToUnload;
457}
458
459
460/**
461 * This is the heart of the unload code.
462 *
463 * It will recursivly (using the load list) initiate module unloading
464 * of all affected modules.
465 *
[2845]466 * This function will cause a state transition to PENDING_DESTROY, PENDING_GC
[2842]467 * or PENDING_TERMINATION depending on the module state. There is one exception
468 * to this, and that's INITIALIZATION_FAILED, where the state will not be changed.
469 *
470 * @param pMod The module which prerequisites should be unloaded.
471 */
[2837]472void kldrDyldModUnloadPrerequisites(PKLDRDYLDMOD pMod)
473{
[2842]474 uint32_t cToUnload;
[2837]475
[2842]476 /* sanity */
477#ifdef KLDRDYLD_STRICT
478 {
479 PKLDRDYLDMOD pMod2;
480 for (pMod2 = kLdrDyldHead; pMod2; pMod2 = pMod2->Load.pNext)
481 KLDRDYLDMOD_ASSERT(pMod2->enmState != KLDRSTATE_GOOD || pMod2->cRefs);
482 }
483#endif
484 KLDRDYLDMOD_ASSERT(pMod->papPrereqs);
485
486 /*
487 * Unload prereqs of the module we're called on first.
488 */
489 cToUnload = kldrDyldModUnloadPrerequisitesOne(pMod);
490
491 /*
492 * Iterate the load list in a cyclic manner until there are no more
493 * modules that can be pushed on into unloading.
494 */
495 while (cToUnload)
496 {
497 cToUnload = 0;
498 for (pMod = kLdrDyldHead; pMod; pMod = pMod->Load.pNext)
499 {
500 if ( pMod->cRefs
501 || pMod->enmState >= KLDRSTATE_PENDING_TERMINATION
502 || pMod->enmState < KLDRSTATE_LOADED_PREREQUISITES)
503 continue;
504 cToUnload += kldrDyldModUnloadPrerequisitesOne(pMod);
505 }
506 }
[2837]507}
508
509
[2845]510int kldrDyldModLoadPrerequisites(PKLDRDYLDMOD pMod, const char *pszPrefix, const char *pszSuffix,
511 KLDRDYLDSEARCH enmSearch, unsigned fFlags)
512{
513 return -1;
514}
[2842]515
516
[2845]517int kldrDyldModCheckPrerequisites(PKLDRDYLDMOD pMod)
518{
519 return -1;
520}
[2842]521
[2845]522
523/**
524 * Marks the module as global instead of being specific.
525 *
526 * A global module can be a matching result when the request
527 * doesn't specify a path. A specific module will not match
528 * unless the path also matches.
529 *
530 * @param pMod The module.
531 */
532void kldrDyldModMarkGlobal(PKLDRDYLDMOD pMod)
[2837]533{
[2845]534 pMod->fGlobalOrSpecific = 1;
535}
536
537/**
538 * Marks the module as specific instead of global.
539 *
540 * See kldrDyldModMarkGlobal for an explanation of the two terms.
541 *
542 * @param pMod The module.
543 */
544void kldrDyldModMarkSpecific(PKLDRDYLDMOD pMod)
545{
546 pMod->fGlobalOrSpecific = 0;
547}
548
549
550/**
551 * Marks a module as bindable, i.e. it'll be considered when
552 * resolving names the unix way.
553 *
554 * @param pMod The module.
555 * @param fDeep When set the module will be inserted at the head of the
556 * module list used to resolve symbols. This means that the
557 * symbols in this module will be prefered of all the other
558 * modules.
559 */
560void kldrDyldModSetBindable(PKLDRDYLDMOD pMod, unsigned fDeep)
561{
562 KLDRDYLDMOD_ASSERT(pMod->enmState >= KLDRSTATE_OPEN && pMod->enmState < KLDRSTATE_PENDING_GC);
563 if (!pMod->fBindable)
564 {
565 pMod->fBindable = 1;
566 if (!fDeep)
567 {
568 pMod->Bind.pNext = NULL;
569 pMod->Bind.pPrev = g_pkLdrDyldBindTail;
570 if (g_pkLdrDyldBindTail)
571 g_pkLdrDyldBindTail->Bind.pNext = pMod;
572 else
573 g_pkLdrDyldBindHead = pMod;
574 g_pkLdrDyldBindTail = pMod;
575 }
576 else
577 {
578 pMod->Bind.pPrev = NULL;
579 pMod->Bind.pNext = g_pkLdrDyldBindHead;
580 if (g_pkLdrDyldBindHead)
581 g_pkLdrDyldBindHead->Bind.pPrev = pMod;
582 else
583 g_pkLdrDyldBindTail = pMod;
584 g_pkLdrDyldBindHead = pMod;
585 }
586 }
587}
588
589
590/**
591 * Marks a module as not bindable, i.e. it will not be considered when
592 * resolving names the unix way.
593 *
594 * @param pMod The module.
595 */
596void kldrDyldModClearBindable(PKLDRDYLDMOD pMod)
597{
598 KLDRDYLDMOD_ASSERT(pMod->enmState >= KLDRSTATE_OPEN && pMod->enmState < KLDRSTATE_PENDING_DESTROY);
599 if (pMod->fBindable)
600 {
601 pMod->fBindable = 0;
602 if (pMod->Bind.pPrev)
603 pMod->Bind.pPrev->Bind.pNext = pMod->Bind.pNext;
604 else
605 g_pkLdrDyldBindHead = pMod->Bind.pNext;
606 if (pMod->Bind.pNext)
607 pMod->Bind.pNext->Bind.pPrev = pMod->Bind.pPrev;
608 else
609 g_pkLdrDyldBindTail = pMod->Bind.pPrev;
610 pMod->Bind.pNext = NULL;
611 pMod->Bind.pPrev = NULL;
612 }
613}
614
615
616/**
617 * Maps an open module.
618 *
619 * On success the module will be in the MAPPED state.
620 *
621 * @returns 0 on success, non-zero native OS or kLdr status code on failure.
622 * @param pMod The module which needs to be unmapped and set pending for destruction.
623 */
624int kldrDyldModMap(PKLDRDYLDMOD pMod)
625{
626 int rc;
627
628 /* sanity */
[2837]629 KLDRDYLDMOD_ASSERT(pMod->cRefs > 0);
[2845]630 KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_OPEN);
631 KLDRDYLDMOD_ASSERT(!pMod->fMapped);
632 if (pMod->fMapped)
633 return 0;
[2837]634
[2845]635 /* do the job. */
636 rc = kLdrModMap(pMod->pMod);
637 if (!rc)
638 {
639 pMod->fMapped = 1;
640 pMod->enmState = KLDRSTATE_MAPPED;
641 }
642 return rc;
643}
[2837]644
[2845]645
646/**
647 * Unmaps the module, unlinks it from everywhere marks it PENDING_DESTROY.
648 *
649 * @returns 0 on success, non-zero native OS or kLdr status code on failure.
650 * @param pMod The module which needs to be unmapped and set pending for destruction.
651 */
652int kldrDyldModUnmap(PKLDRDYLDMOD pMod)
653{
654 int rc;
655
656 /* sanity */
657 KLDRDYLDMOD_ASSERT(pMod->cRefs > 0);
658 KLDRDYLDMOD_ASSERT(pMod->fMapped);
[2837]659 switch (pMod->enmState)
660 {
661 case KLDRSTATE_MAPPED:
662 case KLDRSTATE_GC:
663 case KLDRSTATE_PENDING_DESTROY:
664 break;
665 default:
[2845]666 KLDRDYLDMOD_ASSERT(!"invalid state");
667 return -1;
[2837]668 }
669
[2845]670 /* do the job. */
671 rc = kLdrModUnmap(pMod->pMod);
672 if (!rc)
[2837]673 {
[2845]674 pMod->fMapped = 0;
675 if (pMod->enmState < KLDRSTATE_PENDING_DESTROY)
[2837]676 {
[2845]677 pMod->enmState = KLDRSTATE_PENDING_DESTROY;
678 kldrDyldModUnlink(pMod);
679 }
680 }
681 return rc;
682}
[2837]683
684
[2845]685/**
686 * Applies fixups to a module which prerequisistes has been
687 * successfully loaded.
688 *
689 * @returns 0 on success, non-zero native OS or kLdr status code on failure.
690 * @param pMod The module which needs to be unmapped and set pending for destruction.
691 */
692int kldrDyldModFixup(PKLDRDYLDMOD pMod)
693{
694 int rc;
[2837]695
[2845]696 /* sanity */
697 KLDRDYLDMOD_ASSERT(pMod->cRefs > 0);
698 KLDRDYLDMOD_ASSERT( pMod->enmState == KLDRSTATE_LOADED_PREREQUISITES
699 || pMod->enmState == KLDRSTATE_RELOADED_LOADED_PREREQUISITES);
[2837]700
[2845]701 /* do the job */
702 rc = kLdrModFixupMapping(pMod->pMod, NULL, NULL);/// @todo fixme.
703 if (!rc)
704 pMod->enmState = KLDRSTATE_FIXED_UP;
705 return rc;
706}
[2837]707
[2845]708
709int kldrDyldModCallInit(PKLDRDYLDMOD pMod);
710void kldrDyldModCallTerm(PKLDRDYLDMOD pMod);
711
712int kldrDyldModReload(PKLDRDYLDMOD pMod);
713int kldrDyldModAttachThread(PKLDRDYLDMOD pMod);
714int kldrDyldModDetachThread(PKLDRDYLDMOD pMod);
715int kldrDyldModGetStackInfo(PKLDRDYLDMOD pMod, void **ppvStack, size_t *pcbStack);
716int kldrDyldModStartExe(PKLDRDYLDMOD pMod);
717
718int kldrDyldModGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName);
719int kldrDyldModGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename);
720int kldrDyldModQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind);
721
722
Note: See TracBrowser for help on using the repository browser.