📄 prlink.c
字号:
PR_EnterMonitor(pr_linker_lock); result = pr_UnlockedFindLibrary(name); PR_ExitMonitor(pr_linker_lock); return result;}#ifdef XP_MACstatic PRLibrary*pr_Mac_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName){ PRLibrary* newLib = NULL; PRLibrary* result; FSSpec resolvedSpec = *fileSpec; CFragConnectionID connectionID = 0; Boolean isFolder, wasAlias; OSErr err = noErr; if (!_pr_initialized) _PR_ImplicitInitialization(); /* See if library is already loaded */ PR_EnterMonitor(pr_linker_lock); result = pr_UnlockedFindLibrary(fragmentName); if (result != NULL) goto unlock; newLib = PR_NEWZAP(PRLibrary); if (newLib == NULL) goto unlock; newLib->staticTable = NULL; /* Resolve an alias if this was one */ err = ResolveAliasFile(&resolvedSpec, true, &isFolder, &wasAlias); if (err != noErr) goto unlock; if (isFolder) { err = fnfErr; goto unlock; } /* Finally, try to load the library */ err = NSLoadNamedFragment(&resolvedSpec, fragmentName, &connectionID); if (err != noErr) goto unlock; newLib->name = strdup(fragmentName); newLib->dlh = connectionID; newLib->next = pr_loadmap; pr_loadmap = newLib; result = newLib; /* success */ PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", newLib->name));unlock: if (result == NULL) { if (newLib != NULL) PR_DELETE(newLib); PR_SetError(PR_LOAD_LIBRARY_ERROR, _MD_ERRNO()); DLLErrorInternal(_MD_ERRNO()); /* sets error text */ } PR_ExitMonitor(pr_linker_lock); return result;}static PRLibrary*pr_Mac_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex){ PRLibrary* newLib = NULL; PRLibrary* result; FSSpec resolvedSpec = *fileSpec; char* fragmentName = NULL; UInt32 fragOffset, fragLength; CFragConnectionID connectionID = 0; Boolean isFolder, wasAlias; OSErr err = noErr; if (!_pr_initialized) _PR_ImplicitInitialization(); /* See if library is already loaded */ PR_EnterMonitor(pr_linker_lock); /* Resolve an alias if this was one */ err = ResolveAliasFile(&resolvedSpec, true, &isFolder, &wasAlias); if (err != noErr) goto unlock; if (isFolder) { err = fnfErr; goto unlock; } err = GetIndexedFragmentOffsets(&resolvedSpec, fragIndex, &fragOffset, &fragLength, &fragmentName); if (err != noErr) goto unlock; result = pr_UnlockedFindLibrary(fragmentName); free(fragmentName); fragmentName = NULL; if (result != NULL) goto unlock; newLib = PR_NEWZAP(PRLibrary); if (newLib == NULL) goto unlock; newLib->staticTable = NULL; /* Finally, try to load the library */ err = NSLoadIndexedFragment(&resolvedSpec, fragIndex, &fragmentName, &connectionID); if (err != noErr) { PR_DELETE(newLib); goto unlock; } newLib->name = fragmentName; /* was malloced in NSLoadIndexedFragment */ newLib->dlh = connectionID; newLib->next = pr_loadmap; pr_loadmap = newLib; result = newLib; /* success */ PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", newLib->name));unlock: if (result == NULL) { if (newLib != NULL) PR_DELETE(newLib); PR_SetError(PR_LOAD_LIBRARY_ERROR, _MD_ERRNO()); DLLErrorInternal(_MD_ERRNO()); /* sets error text */ } PR_ExitMonitor(pr_linker_lock); return result;}#endif/*** Unload a shared library which was loaded via PR_LoadLibrary*/PR_IMPLEMENT(PRStatus) PR_UnloadLibrary(PRLibrary *lib){ int result = 0; PRStatus status = PR_SUCCESS; if ((lib == 0) || (lib->refCount <= 0)) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; } PR_EnterMonitor(pr_linker_lock); if (--lib->refCount > 0) { PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("%s decr => %d", lib->name, lib->refCount)); goto done; }#ifdef XP_BEOS if(((image_id)lib->stub_dlh) == B_ERROR) unload_add_on( (image_id) lib->dlh ); else unload_add_on( (image_id) lib->stub_dlh);#endif#ifdef XP_UNIX#ifdef HAVE_DLL#ifdef USE_DLFCN result = dlclose(lib->dlh);#elif defined(USE_HPSHL) result = shl_unload(lib->dlh);#elif defined(USE_MACH_DYLD) result = NSUnLinkModule(lib->dlh, FALSE);#else#error Configuration error#endif#endif /* HAVE_DLL */#endif /* XP_UNIX */#ifdef XP_PC if (lib->dlh) { FreeLibrary((HINSTANCE)(lib->dlh)); lib->dlh = (HINSTANCE)NULL; }#endif /* XP_PC */#if defined(XP_MAC) && TARGET_RT_MAC_CFM /* Close the connection */#if TARGET_CARBON if (lib->bundle) CFRelease(lib->bundle); else#endif CloseConnection(&(lib->dlh));#endif /* unlink from library search list */ if (pr_loadmap == lib) pr_loadmap = pr_loadmap->next; else if (pr_loadmap != NULL) { PRLibrary* prev = pr_loadmap; PRLibrary* next = pr_loadmap->next; while (next != NULL) { if (next == lib) { prev->next = next->next; goto freeLib; } prev = next; next = next->next; } /* * fail (the library is not on the _pr_loadmap list), * but don't wipe out an error from dlclose/shl_unload. */ PR_ASSERT(!"_pr_loadmap and lib->refCount inconsistent"); if (result == 0) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); status = PR_FAILURE; } } /* * We free the PRLibrary structure whether dlclose/shl_unload * succeeds or not. */ freeLib: PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Unloaded library %s", lib->name)); free(lib->name); lib->name = NULL; PR_DELETE(lib); if (result == -1) { PR_SetError(PR_UNLOAD_LIBRARY_ERROR, _MD_ERRNO()); DLLErrorInternal(_MD_ERRNO()); status = PR_FAILURE; }done: PR_ExitMonitor(pr_linker_lock); return status;}static void* pr_FindSymbolInLib(PRLibrary *lm, const char *name){ void *f = NULL; if (lm->staticTable != NULL) { const PRStaticLinkTable* tp; for (tp = lm->staticTable; tp->name; tp++) { if (strcmp(name, tp->name) == 0) { return (void*) tp->fp; } } /* ** If the symbol was not found in the static table then check if ** the symbol was exported in the DLL... Win16 only!! */#if !defined(WIN16) && !defined(XP_BEOS) PR_SetError(PR_FIND_SYMBOL_ERROR, 0); return (void*)NULL;#endif } #ifdef XP_OS2 DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);#endif /* XP_OS2 */#if defined(WIN32) || defined(WIN16) f = GetProcAddress(lm->dlh, name);#endif /* WIN32 || WIN16 */#ifdef XP_MAC#if TARGET_CARBON if (lm->bundle) { CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII); if (nameRef) { f = CFBundleGetFunctionPointerForName(lm->bundle, nameRef); CFRelease(nameRef); } } else#endif { Ptr symAddr; CFragSymbolClass symClass; Str255 pName; PStrFromCStr(name, pName); f = (NSFindSymbol(lm->dlh, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL; if (f == NULL && strcmp(name, "main") == 0) f = lm->main; }#endif /* XP_MAC */#ifdef XP_BEOS if( B_NO_ERROR != get_image_symbol( (image_id)lm->dlh, name, B_SYMBOL_TYPE_TEXT, &f ) ) { f = NULL; }#endif#ifdef XP_UNIX#ifdef HAVE_DLL#ifdef USE_DLFCN f = dlsym(lm->dlh, name);#elif defined(USE_HPSHL) if (shl_findsym(&lm->dlh, name, TYPE_PROCEDURE, &f) == -1) { f = NULL; }#elif defined(USE_MACH_DYLD) { NSSymbol symbol; symbol = NSLookupSymbolInModule(lm->dlh, name); if (symbol != NULL) f = NSAddressOfSymbol(symbol); else f = NULL; }#endif#endif /* HAVE_DLL */#endif /* XP_UNIX */ if (f == NULL) { PR_SetError(PR_FIND_SYMBOL_ERROR, _MD_ERRNO()); DLLErrorInternal(_MD_ERRNO()); } return f;}/*** Called by class loader to resolve missing native's*/PR_IMPLEMENT(void*) PR_FindSymbol(PRLibrary *lib, const char *raw_name){ void *f = NULL;#if defined(NEED_LEADING_UNDERSCORE) char *name;#else const char *name;#endif /* ** Mangle the raw symbol name in any way that is platform specific. */#if defined(NEED_LEADING_UNDERSCORE) /* Need a leading _ */ name = PR_smprintf("_%s", raw_name);#elif defined(AIX) /* ** AIX with the normal linker put's a "." in front of the symbol ** name. When use "svcc" and "svld" then the "." disappears. Go ** figure. */ name = raw_name;#else name = raw_name;#endif PR_EnterMonitor(pr_linker_lock); PR_ASSERT(lib != NULL); f = pr_FindSymbolInLib(lib, name);#if defined(NEED_LEADING_UNDERSCORE) PR_smprintf_free(name);#endif PR_ExitMonitor(pr_linker_lock); return f;}/*** Return the address of the function 'raw_name' in the library 'lib'*/PR_IMPLEMENT(PRFuncPtr) PR_FindFunctionSymbol(PRLibrary *lib, const char *raw_name){ return ((PRFuncPtr) PR_FindSymbol(lib, raw_name));}PR_IMPLEMENT(void*) PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib){ void *f = NULL;#if defined(NEED_LEADING_UNDERSCORE) char *name;#else const char *name;#endif PRLibrary* lm; if (!_pr_initialized) _PR_ImplicitInitialization(); /* ** Mangle the raw symbol name in any way that is platform specific. */#if defined(NEED_LEADING_UNDERSCORE) /* Need a leading _ */ name = PR_smprintf("_%s", raw_name);#elif defined(AIX) /* ** AIX with the normal linker put's a "." in front of the symbol ** name. When use "svcc" and "svld" then the "." disappears. Go ** figure. */ name = raw_name;#else name = raw_name;#endif PR_EnterMonitor(pr_linker_lock); /* search all libraries */ for (lm = pr_loadmap; lm != NULL; lm = lm->next) { f = pr_FindSymbolInLib(lm, name); if (f != NULL) { *lib = lm; lm->refCount++; PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("%s incr => %d (for %s)", lm->name, lm->refCount, name)); break; } }#if defined(NEED_LEADING_UNDERSCORE) PR_smprintf_free(name);#endif PR_ExitMonitor(pr_linker_lock); return f;}PR_IMPLEMENT(PRFuncPtr) PR_FindFunctionSymbolAndLibrary(const char *raw_name, PRLibrary* *lib){ return ((PRFuncPtr) PR_FindSymbolAndLibrary(raw_name, lib));}/*** Add a static library to the list of loaded libraries. If LoadLibrary** is called with the name then we will pretend it was already loaded*/PR_IMPLEMENT(PRLibrary*) PR_LoadStaticLibrary(const char *name, const PRStaticLinkTable *slt){ PRLibrary *lm=NULL; PRLibrary* result = NULL; if (!_pr_initialized) _PR_ImplicitInitialization(); /* See if library is already loaded */ PR_EnterMonitor(pr_linker_lock); /* If the lbrary is already loaded, then add the static table information... */ result = pr_UnlockedFindLibrary(name); if (result != NULL) { PR_ASSERT( (result->staticTable == NULL) || (result->staticTable == slt) ); result->staticTable = slt; goto unlock; } /* Add library to list...Mark it static */ lm = PR_NEWZAP(PRLibrary); if (lm == NULL) goto unlock; lm->name = strdup(name); lm->refCount = 1; lm->dlh = pr_exe_loadmap ? pr_exe_loadmap->dlh : 0; lm->staticTable = slt; lm->next = pr_loadmap; pr_loadmap = lm; result = lm; /* success */ PR_ASSERT(lm->refCount == 1); unlock: PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (static lib)", lm->name)); PR_ExitMonitor(pr_linker_lock); return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -