Changeset 2836 for trunk/kLdr/kLdrDyld.c
- Timestamp:
- Oct 26, 2006, 5:58:53 AM (19 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrDyld.c
r2833 r2836 32 32 #include "kLdrHlp.h" 33 33 #include "kLdrInternal.h" 34 35 36 /******************************************************************************* 37 * Defined Constants And Macros * 38 *******************************************************************************/ 39 /** @def KLDRDYLD_STRICT 40 * Define KLDRDYLD_STRICT to enabled strict checks in kLdrDyld. */ 41 #define KLDRDYLD_STRICT 1 42 43 /** @def KLDRDYLD_ASSERT 44 * Assert that an expression is true when KLDRDYLD_STRICT is defined. 45 */ 46 #ifdef KLDRDYLD_STRICT 47 # define KLDRDYLD_ASSERT(expr) kldrHlpAssert(expr) 48 #else 49 # define KLDRDYLD_ASSERT(expr) do {} while (0) 50 #endif 34 51 35 52 … … 43 60 * (This is exported, so no prefix.) */ 44 61 PKLDRDYLDMOD kLdrDyldTail = NULL; 62 /** Pointer to the head module of the termination order list. */ 63 PKLDRDYLDMOD g_pkLdrDyldTermHead; 64 /** Pointer to the tail module of the termination order list. */ 65 PKLDRDYLDMOD g_pkLdrDyldTermTail; 66 /** Pointer to the head module of the bind order list. 67 * The modules in this list makes up the global namespace used when binding symbol unix fashion. */ 68 PKLDRDYLDMOD g_pkLdrDyldBindHead; 69 /** Pointer to the tail module of the bind order list. */ 70 PKLDRDYLDMOD g_pkLdrDyldBindTail; 71 72 /** Stack of modules involved in the active loads. 73 * 74 * The main purpose is to allow module init routines to loading and unloading 75 * modules without upsetting the init order and to assist in dereferencing 76 * modules on load failure. 77 * 78 * Each call to kLdrDyldLoad and kLdrDyldLoadExe will start a load frame 79 * when doing a fresh load. All dependant modules will be pushed on each 80 * reference. The frame is completed when all the dependant modules has 81 * been resolved (or a failure occurs). After doing fixups, the frame is 82 * used to do module initialization. Should an error occur during the load 83 * the frame will be used to dereference all the modules involved in the 84 * load operation (it will not however, be used for termination calls as 85 * they are postponed till the last load operation completes). 86 * 87 * Should any of the init calls load a module, a new frame will be created 88 * for that operation and processed before the init call returns to the 89 * previous frame. 90 */ 91 PPKLDRDYLDMOD g_pakLdrDyld; 92 /** The number of used entries in the g_pakLdrDyld array. */ 93 uint32_t g_ckLdrDyld; 94 /** The number of entries allocated for the g_pakLdrDyld array. */ 95 uint32_t g_ckLdrDyldAllocated; 96 97 /** The global error buffer. */ 98 char g_szkLdrDyldError[1024]; 99 45 100 /** The Library search path. */ 46 101 char kLdrDyldLibraryPath[4096]; … … 52 107 * Internal Functions * 53 108 *******************************************************************************/ 54 static int kldrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 55 unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr); 56 static int kldrDyldUnload(PKLDRDYLDMOD pMod); 57 static int kldrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PPKLDRDYLDMOD ppMod); 58 static int kldrDyldFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment); 59 static int kldrDyldGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName); 60 static int kldrDyldGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename); 61 static int kldrDyldQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind); 109 static int kldrDyldDoLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 110 unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr); 111 static int kldrDyldDoUnload(PKLDRDYLDMOD pMod); 112 static int kldrDyldDoFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 113 unsigned fFlags, PPKLDRDYLDMOD ppMod); 114 static int kldrDyldDoFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment); 115 static int kldrDyldDoGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName); 116 static int kldrDyldDoGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename); 117 static int kldrDyldDoQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind); 118 static void kldrDyldStartLoading(void); 119 static void kldrDyldStopLoading(void); 120 static int kldrDyldCopyError(int rc, char *pszErr, size_t cchErr); 62 121 63 122 … … 68 127 int kldrDyInit(void) 69 128 { 70 kLdrDyldHead = NULL; 71 kLdrDyldTail = NULL; 129 kLdrDyldHead = kLdrDyldTail = NULL; 130 g_pkLdrDyldTermHead = g_pkLdrDyldTermTail = NULL; 131 g_pkLdrDyldBindHead = g_pkLdrDyldBindTail = NULL; 72 132 kLdrDyldFlags = 0; 133 g_szkLdrDyldError[0] = '\0'; 73 134 return 0; 74 135 } … … 117 178 { 118 179 PKLDRDYLDMOD pMod = NULL; 119 rc = kldrDyld Load(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, phMod, pszErr, cchErr);180 rc = kldrDyldDoLoad(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, phMod, pszErr, cchErr); 120 181 kldrHlpSemRelease(); 121 182 *phMod = pMod; … … 142 203 if (!rc) 143 204 { 144 rc = kldrDyld Unload(hMod);205 rc = kldrDyldDoUnload(hMod); 145 206 kldrHlpSemRelease(); 146 207 } … … 158 219 * @returns KLDR_ERR_MODULE_NOT_FOUND on failure. 159 220 * @param pszDll The name of the dll to look for. 160 * @param pszDefPrefix Prefix t o usewhen searching.161 * @param pszDefSuffix Suffix t o usewhen searching.221 * @param pszDefPrefix Prefix than can be used when searching. 222 * @param pszDefSuffix Suffix than can be used when searching. 162 223 * @param enmSearch Method to use when locating the module. 224 * @param fFlags Flags, a combintation of the KLDRYDLD_LOAD_FLAGS_* \#defines. 163 225 * @param phMod Where to store the handle of the module on success. 164 226 */ 165 int kLdrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PHKLDRMOD phMod) 227 int kLdrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 228 unsigned fFlags, PHKLDRMOD phMod) 166 229 { 167 230 int rc; … … 176 239 { 177 240 PKLDRDYLDMOD pMod = NULL; 178 rc = kldrDyld FindByName(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, phMod);241 rc = kldrDyldDoFindByName(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, phMod); 179 242 kldrHlpSemRelease(); 180 243 *phMod = pMod; … … 213 276 { 214 277 PKLDRDYLDMOD pMod = NULL; 215 rc = kldrDyld FindByAddress(Address, &pMod, piSegment, poffSegment);278 rc = kldrDyldDoFindByAddress(Address, &pMod, piSegment, poffSegment); 216 279 kldrHlpSemRelease(); 217 280 *phMod = pMod; … … 245 308 if (!rc) 246 309 { 247 rc = kldrDyld GetName(hMod, pszName, cchName);310 rc = kldrDyldDoGetName(hMod, pszName, cchName); 248 311 kldrHlpSemRelease(); 249 312 } … … 276 339 if (!rc) 277 340 { 278 rc = kldrDyld GetFilename(hMod, pszFilename, cchFilename);341 rc = kldrDyldDoGetFilename(hMod, pszFilename, cchFilename); 279 342 kldrHlpSemRelease(); 280 343 } … … 312 375 if (!rc) 313 376 { 314 rc = kldrDyld QuerySymbol(hMod, uSymbolOrdinal, pszSymbolName, pValue, pfKind);377 rc = kldrDyldDoQuerySymbol(hMod, uSymbolOrdinal, pszSymbolName, pValue, pfKind); 315 378 kldrHlpSemRelease(); 316 379 } … … 322 385 323 386 324 325 /** 326 * Worker for kldrDyldLoad(). 387 /** 388 * Worker for kLdrDyldLoad(). 327 389 * @internal 328 390 */ 329 static int kldrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 330 unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr) 331 { 332 /* 333 * Open the module. 334 */ 335 336 337 return -1; 338 } 339 340 341 /** 342 * Worker for kldrDyldUnload(). 391 static int kldrDyldDoLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 392 unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr) 393 { 394 int rc; 395 396 /* 397 * Try find it among the modules that's already loaded. 398 */ 399 rc = kldrDyldFindExistingModule(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, ppMod); 400 if (!rc) 401 { 402 /* 403 * If we're in a module termination call we must check that all the modules we 404 * depend on are loaded and initialized. 405 */ 406 //continue here if ((*ppMod)->enmState::KLDRSTATE_LOADED) 407 { 408 kldrHlpAssert(!"implement me"); 409 } 410 return kldrDyldModDynamicLoad(*ppMod); 411 } 412 413 /* 414 * Try open it. 415 */ 416 kldrDyldStartLoading(); 417 rc = kldrDyldFindNewModule(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, ppMod); 418 if (!rc) 419 { 420 421 422 } 423 return kldrDyldCopyError(rc, pszErr, cchErr); 424 } 425 426 427 /** 428 * Worker for kLdrDyldUnload(). 343 429 * @internal 344 430 */ 345 static int kldrDyld Unload(HKLDRMOD hMod)346 { 347 return -1;431 static int kldrDyldDoUnload(PKLDRDYLDMOD pMod) 432 { 433 return kldrDyldModDynamicUnload(pMod); 348 434 } 349 435 … … 353 439 * @internal 354 440 */ 355 static int kldrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PPKLDRDYLDMOD ppMod) 356 { 357 return -1; 441 static int kldrDyldDoFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 442 unsigned fFlags, PPKLDRDYLDMOD ppMod) 443 { 444 return kldrDyldFindExistingModule(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, ppMod); 358 445 } 359 446 … … 363 450 * @internal 364 451 */ 365 static int kldrDyldFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment) 366 { 367 return -1; 452 static int kldrDyldDoFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment) 453 { 454 /* Scan the segments of each module in the load list. */ 455 PKLDRDYLDMOD pMod = kLdrDyldHead; 456 while (pMod) 457 { 458 uint32_t iSeg; 459 for (iSeg = 0; iSeg < pMod->pMod->cSegments; iSeg++) 460 { 461 uintmax_t off = (uintmax_t)Address - pMod->pMod->aSegments[iSeg].LoadAddress; 462 if (off < pMod->pMod->aSegments[iSeg].cb) 463 { 464 *ppMod = pMod->hMod; 465 if (piSegment) 466 *piSegment = iSeg; 467 if (poffSegment) 468 *poffSegment = (uintptr_t)off; 469 return 0; 470 } 471 } 472 473 /* next */ 474 pMod = pMod->Load.pNext; 475 } 476 477 return KLDR_ERR_MODULE_NOT_FOUND; 368 478 } 369 479 … … 373 483 * @internal 374 484 */ 375 static int kldrDyld GetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName)376 { 377 return -1;485 static int kldrDyldDoGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName) 486 { 487 return kldrDyldModGetName(pMod, pszName, cchName); 378 488 } 379 489 … … 383 493 * @internal 384 494 */ 385 static int kldrDyld GetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename)386 { 387 return -1;495 static int kldrDyldDoGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename) 496 { 497 return kldrDyldModGetFilename(pMod, pszFilename, cchFilename); 388 498 } 389 499 … … 393 503 * @internal 394 504 */ 395 static int kldrDyld QuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind)396 { 397 return -1;505 static int kldrDyldDoQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind) 506 { 507 return kldrDyldModQuerySymbol(pMod, uSymbolOrdinal, pszSymbolName, pValue, pfKind); 398 508 } 399 509 … … 482 592 } 483 593 594 #endif 595 596 /** 597 * Starts loading a new module and its dependencies. 598 */ 599 static void kldrDyldStartLoading(void) 600 { 601 #ifdef KLDRDYLD_STRICT 602 /* check that all modules are in the correct state */ 603 PKLDRDYLDMOD pMod = kLdrDyldHead; 604 while (pMod) 605 { 606 //KLDRDYLD_ASSERT(pMod->enmState == KLDRSTATE_LOADED); 607 608 /* next */ 609 pMod = pMod->Load.pNext; 610 } 611 #endif 612 } 613 614 615 /** 616 * Records the loading of the module. 617 * 618 * @return 0 on success, KLDR_ERR_NO_MEMORY if we can't expand the table. 619 * @param pMod The module to record. 620 */ 621 static int kldrDyldRecord(PKLDRDYLDMOD pMod) 622 { 623 624 } 625 626 627 628 /** 629 * Done loading a module and its dependencies. 630 * 631 * If the load failed, unload all the modules involved. 632 * If the load succeeded, 633 * 634 * @returns rc. 635 * @param rc The status code. 636 */ 637 static void kldrDyldDoneLoading(int rc) 638 { 639 640 } 641 642 484 643 485 644 /** … … 493 652 int kldrFailure(int rc, const char *pszFormat, ...) 494 653 { 495 kldrExit(1); 496 return rc; 497 } 498 499 #endif 500 654 kldrHlpExit(1); 655 return rc; 656 } 657 658 659 /** 660 * Copies the error string to the user buffer. 661 * 662 * @returns rc. 663 * @param rc The status code. 664 * @param pszErr Where to copy the error string to. 665 * @param cchErr The size of the destination buffer. 666 */ 667 static int kldrDyldCopyError(int rc, char *pszErr, size_t cchErr) 668 { 669 size_t cchToCopy; 670 671 /* if no error string, format the rc into a string. */ 672 if (!g_szkLdrDyldError[0] && rc) 673 kldrHlpInt2Ascii(g_szkLdrDyldError, sizeof(g_szkLdrDyldError), rc, 10); 674 675 /* copy it if we got something. */ 676 if (cchErr && pszErr && g_szkLdrDyldError[0]) 677 { 678 cchToCopy = kLdrHlpStrLen(g_szkLdrDyldError); 679 if (cchToCopy >= cchErr) 680 cchToCopy = cchErr - 1; 681 kLdrHlpMemCopy(pszErr, g_szkLdrDyldError, cchToCopy); 682 pszErr[cchToCopy] = '\0'; 683 } 684 685 return rc; 686 } 687
Note:
See TracChangeset
for help on using the changeset viewer.