Changeset 2847 for trunk/kLdr/kLdrDyldMod.c
- Timestamp:
- Nov 1, 2006, 8:17:21 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrDyldMod.c
r2846 r2847 50 50 # define KLDRDYLDMOD_ASSERT(expr) do {} while (0) 51 51 #endif 52 53 /******************************************************************************* 54 * Internal Functions * 55 *******************************************************************************/ 56 static void kldrDyldModUnlink(PKLDRDYLDMOD pMod); 52 57 53 58 … … 175 180 void kldrDyldModDestroy(PKLDRDYLDMOD pMod) 176 181 { 182 int rc; 183 177 184 /* 178 185 * Validate the state. … … 191 198 KLDRDYLDMOD_ASSERT(!pMod->cDepRefs); 192 199 193 194 200 /* 195 201 * Ensure that the module is unmapped. 196 202 */ 203 if (pMod->fAllocatedTLS) 204 { 205 kLdrModFreeTLS(pMod->pMod); 206 pMod->fAllocatedTLS = 0; 207 } 197 208 if (pMod->fMapped) 198 kldrDyldModUnmap(pMod); 209 { 210 rc = kLdrModUnmap(pMod->pMod); KLDRDYLDMOD_ASSERT(!rc); 211 pMod->fMapped = 0; 212 } 213 214 /* 215 * Ensure it's unlinked from all chains. 216 */ 217 if (pMod->enmState < KLDRSTATE_PENDING_DESTROY) 218 kldrDyldModUnlink(pMod); 219 220 /* 221 * Free everything associated with the module. 222 */ 223 /* the prerequisite array. */ 224 if (pMod->papPrereqs) 225 { 226 uint32_t i = pMod->cPrereqs; 227 while (i-- > 0) 228 { 229 KLDRDYLDMOD_ASSERT(pMod->papPrereqs[i] == NULL); 230 pMod->papPrereqs[i] = NULL; 231 } 232 233 kldrHlpFree(pMod->papPrereqs); 234 pMod->papPrereqs = NULL; 235 pMod->cPrereqs = 0; 236 } 237 238 /* the module interpreter. */ 239 if (pMod->pMod) 240 { 241 rc = kLdrModClose(pMod->pMod); KLDRDYLDMOD_ASSERT(!rc); 242 pMod->pMod = NULL; 243 } 244 245 246 /* 247 * Finally, change the module state and free the module if 248 * there are not more references to it. If somebody is still 249 * referencing it, postpone the freeing to Deref. 250 */ 251 pMod->enmState = KLDRSTATE_DESTROYED; 252 if (!pMod->cRefs) 253 { 254 pMod->u32MagicHead = 1; 255 pMod->u32MagicTail = 2; 256 kldrHlpFree(pMod); 257 } 199 258 } 200 259 … … 377 436 if ( pMod->enmState == KLDRSTATE_DESTROYED 378 437 && !pMod->cRefs) 438 { 439 pMod->u32MagicHead = 1; 440 pMod->u32MagicTail = 2; 379 441 kldrHlpFree(pMod); 442 } 380 443 } 381 444 … … 511 574 if (pMod2) 512 575 { 576 pMod->papPrereqs[i] = NULL; 577 513 578 /* do the derefering ourselves or we'll end up in a recursive loop here. */ 514 579 KLDRDYLDMOD_ASSERT(pMod2->cDepRefs > 0); … … 603 668 604 669 670 /** 671 * Loads the prerequisite modules this module depends on. 672 * 673 * To find each of the prerequisite modules this method calls 674 * kldrDyldGetPrerequisite() and it will make sure the modules 675 * are added to the load stack frame. 676 * 677 * @returns 0 on success, non-zero native OS or kLdr status code on failure. 678 * The state is changed to LOADED_PREREQUISITES or RELOADED_LOADED_PREREQUISITES. 679 * @param pMod The module. 680 * @param pszPrefix Prefix to use when searching. 681 * @param pszSuffix Suffix to use when searching. 682 * @param enmSearch Method to use when locating the module and any modules it may depend on. 683 * @param fFlags Flags, a combintation of the KLDRYDLD_LOAD_FLAGS_* \#defines. 684 */ 605 685 int kldrDyldModLoadPrerequisites(PKLDRDYLDMOD pMod, const char *pszPrefix, const char *pszSuffix, 606 686 KLDRDYLDSEARCH enmSearch, unsigned fFlags) 607 687 { 608 609 return -1; 610 } 611 612 613 int kldrDyldModCheckPrerequisites(PKLDRDYLDMOD pMod) 614 { 615 return -1; 688 int32_t cPrereqs; 689 uint32_t i; 690 int rc = 0; 691 692 /* sanity */ 693 switch (pMod->enmState) 694 { 695 case KLDRSTATE_MAPPED: 696 case KLDRSTATE_RELOADED: 697 break; 698 default: 699 KLDRDYLDMOD_ASSERT(!"invalid state"); 700 return -1; 701 } 702 703 /* 704 * Query number of prerequiste modules and allocate the array. 705 */ 706 cPrereqs = kLdrModNumberOfImports(pMod->pMod); 707 kldrHlpAssert(cPrereqs >= 0); 708 if (pMod->cPrereqs != cPrereqs) 709 { 710 KLDRDYLDMOD_ASSERT(!pMod->papPrereqs); 711 pMod->papPrereqs = (PPKLDRDYLDMOD)kldrHlpAllocZ(sizeof(pMod->papPrereqs[0]) * cPrereqs); 712 if (!pMod->papPrereqs) 713 return KLDR_ERR_NO_MEMORY; 714 pMod->cPrereqs = cPrereqs; 715 } 716 else 717 KLDRDYLDMOD_ASSERT(pMod->papPrereqs || !pMod->cPrereqs); 718 719 /* 720 * Iterate the prerequisites and load them. 721 */ 722 for (i = 0; i < pMod->cPrereqs; i++) 723 { 724 static char s_szPrereq[260]; 725 PKLDRDYLDMOD pPrereqMod; 726 727 KLDRDYLDMOD_ASSERT(pMod->papPrereqs[i] == NULL); 728 rc = kLdrModGetImport(pMod->pMod, i, s_szPrereq, sizeof(s_szPrereq)); 729 if (rc) 730 break; 731 rc = kldrDyldGetPrerequisite(s_szPrereq, pszPrefix, pszSuffix, enmSearch, fFlags, pMod, &pPrereqMod); 732 if (rc) 733 break; 734 pMod->papPrereqs[i] = pPrereqMod; 735 } 736 737 /* change the state regardless of what happend. */ 738 if (pMod->enmState == KLDRSTATE_MAPPED) 739 pMod->enmState = KLDRSTATE_LOADED_PREREQUISITES; 740 else 741 pMod->enmState = KLDRSTATE_RELOADED_LOADED_PREREQUISITES; 742 return rc; 616 743 } 617 744 … … 679 806 680 807 /* do the job. */ 681 rc = kLdrModFreeTLS(pMod->pMod); 808 if (pMod->fAllocatedTLS) 809 { 810 kLdrModFreeTLS(pMod->pMod); 811 pMod->fAllocatedTLS = 0; 812 } 813 rc = kLdrModUnmap(pMod->pMod); 682 814 if (!rc) 683 815 { 684 rc = kLdrModUnmap(pMod->pMod);685 if ( !rc)816 pMod->fMapped = 0; 817 if (pMod->enmState < KLDRSTATE_PENDING_DESTROY) 686 818 { 687 pMod->fMapped = 0; 688 if (pMod->enmState < KLDRSTATE_PENDING_DESTROY) 689 { 690 pMod->enmState = KLDRSTATE_PENDING_DESTROY; 691 kldrDyldModUnlink(pMod); 692 } 819 pMod->enmState = KLDRSTATE_PENDING_DESTROY; 820 kldrDyldModUnlink(pMod); 693 821 } 694 else 695 kLdrModAllocTLS(pMod->pMod); 696 } 822 } 823 697 824 return rc; 698 825 } … … 716 843 KLDRDYLDMOD_ASSERT(pMod->cRefs > 0); 717 844 KLDRDYLDMOD_ASSERT(pMod->fMapped); 718 KLDRDYLDMOD_ASSERT(pMod->fAllocatedTLS);719 845 720 846 switch (pMod->enmState) … … 729 855 } 730 856 857 /* Free TLS before reloading. */ 858 if (pMod->fAllocatedTLS) 859 { 860 kLdrModFreeTLS(pMod->pMod); 861 pMod->fAllocatedTLS = 0; 862 } 863 731 864 /* Let the module interpreter do the reloading of the mapping. */ 732 865 rc = kLdrModReload(pMod->pMod); 733 866 if (!rc) 734 867 { 735 /* Free and allocate the TLS anew to ensure we get clean entries. */ 736 if (pMod->fAllocatedTLS) 737 rc = kLdrModFreeTLS(pMod->pMod); 868 rc = kLdrModAllocTLS(pMod->pMod); 738 869 if (!rc) 739 870 { 740 pMod->fAllocatedTLS = 0; 741 rc = kLdrModAllocTLS(pMod->pMod); 742 if (!rc) 743 { 744 pMod->fAllocatedTLS = 1; 745 pMod->enmState = KLDRSTATE_RELOADED; 746 } 871 pMod->fAllocatedTLS = 1; 872 pMod->enmState = KLDRSTATE_RELOADED; 747 873 } 748 874 }
Note:
See TracChangeset
for help on using the changeset viewer.