📄 prlink.c
字号:
while (lm) { const char* cp = strrchr(lm->name, PR_DIRECTORY_SEPARATOR); cp = cp ? cp + 1 : lm->name;#ifdef XP_PC /* Windows DLL names are case insensitive... */ if (strcmpi(np, cp) == 0) #else if (strcmp(np, cp) == 0) #endif { /* found */ lm->refCount++; PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("%s incr => %d (find lib)", lm->name, lm->refCount)); return lm; } lm = lm->next; } return NULL;}PR_IMPLEMENT(PRLibrary*)PR_LoadLibraryWithFlags(PRLibSpec libSpec, PRIntn flags){ if (flags == 0) { flags = _PR_DEFAULT_LD_FLAGS; } switch (libSpec.type) { case PR_LibSpec_Pathname: return pr_LoadLibraryByPathname(libSpec.value.pathname, flags);#ifdef XP_MAC case PR_LibSpec_MacNamedFragment: return pr_Mac_LoadNamedFragment( libSpec.value.mac_named_fragment.fsspec, libSpec.value.mac_named_fragment.name); case PR_LibSpec_MacIndexedFragment: return pr_Mac_LoadIndexedFragment( libSpec.value.mac_indexed_fragment.fsspec, libSpec.value.mac_indexed_fragment.index);#endif /* XP_MAC */ default: PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return NULL; }} PR_IMPLEMENT(PRLibrary*) PR_LoadLibrary(const char *name){ PRLibSpec libSpec; libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = name; return PR_LoadLibraryWithFlags(libSpec, 0);}#if TARGET_CARBON/*** Returns a CFBundleRef if the FSSpec refers to a Mac OS X bundle directory.** The caller is responsible for calling CFRelease() to deallocate.*/static CFBundleRef getLibraryBundle(const FSSpec* spec){ CFBundleRef bundle = NULL; FSRef ref; OSErr err = FSpMakeFSRef(spec, &ref); char path[512]; if (err == noErr && ((UInt32)(FSRefMakePath) != kUnresolvedCFragSymbolAddress)) { err = FSRefMakePath(&ref, (UInt8*)path, sizeof(path) - 1); if (err == noErr) { CFStringRef pathRef = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8); if (pathRef) { CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, kCFURLPOSIXPathStyle, true); if (bundleURL != NULL) { bundle = CFBundleCreate(NULL, bundleURL); CFRelease(bundleURL); } CFRelease(pathRef); } } } return bundle;}#endif/*** Dynamically load a library. Only load libraries once, so scan the load** map first.*/static PRLibrary*pr_LoadLibraryByPathname(const char *name, PRIntn flags){ PRLibrary *lm; PRLibrary* result; PRInt32 oserr; if (!_pr_initialized) _PR_ImplicitInitialization(); /* See if library is already loaded */ PR_EnterMonitor(pr_linker_lock); result = pr_UnlockedFindLibrary(name); if (result != NULL) goto unlock; lm = PR_NEWZAP(PRLibrary); if (lm == NULL) { oserr = _MD_ERRNO(); goto unlock; } lm->staticTable = NULL;#ifdef XP_OS2 /* Why isn't all this stuff in MD code?! */ { HMODULE h; UCHAR pszError[_MAX_PATH]; ULONG ulRc = NO_ERROR; retry: ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h); if (ulRc != NO_ERROR) { oserr = ulRc; PR_DELETE(lm); goto unlock; } lm->name = strdup(name); lm->dlh = h; lm->next = pr_loadmap; pr_loadmap = lm; }#endif /* XP_OS2 */#if defined(WIN32) || defined(WIN16) { HINSTANCE h; NODL_PROC *pfn; h = LoadLibrary(name); if (h < (HINSTANCE)HINSTANCE_ERROR) { oserr = _MD_ERRNO(); PR_DELETE(lm); goto unlock; } lm->name = strdup(name); lm->dlh = h; lm->next = pr_loadmap; pr_loadmap = lm; /* ** Try to load a table of "static functions" provided by the DLL */ pfn = (NODL_PROC *)GetProcAddress(h, "NODL_TABLE"); if (pfn != NULL) { lm->staticTable = (*pfn)(); } }#endif /* WIN32 || WIN16 */#if defined(XP_MAC) && TARGET_RT_MAC_CFM { OSErr err; CFragConnectionID connectionID; Str255 errName; Str255 pName; char cName[64]; const char* libName; /* * Algorithm: The "name" passed in could be either a shared * library name that we should look for in the normal library * search paths, or a full path name to a specific library on * disk. Since the full path will always contain a ":" * (shortest possible path is "Volume:File"), and since a * library name can not contain a ":", we can test for the * presence of a ":" to see which type of library we should load. * or its a full UNIX path which we for now assume is Java * enumerating all the paths (see below) */ if (strchr(name, PR_PATH_SEPARATOR) == NULL) { if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) { /* * The name did not contain a ":", so it must be a * library name. Convert the name to a Pascal string * and try to find the library. */ } else { /* name contained a "/" which means we need to suck off the last part */ /* of the path and pass that on the NSGetSharedLibrary */ /* this may not be what we really want to do .. because Java could */ /* be iterating through the whole LD path, and we'll find it if it's */ /* anywhere on that path -- it appears that's what UNIX and the PC do */ /* too...so we'll emulate but it could be wrong. */ name = strrchr(name, PR_DIRECTORY_SEPARATOR) + 1; } PStrFromCStr(name, pName); /* * beard: NSGetSharedLibrary was so broken that I just decided to * use GetSharedLibrary for now. This will need to change for * plugins, but those should go in the Extensions folder anyhow. */#if 0 err = NSGetSharedLibrary(pName, &connectionID, &lm->main);#else err = GetSharedLibrary(pName, kCompiledCFragArch, kReferenceCFrag, &connectionID, &lm->main, errName);#endif if (err != noErr) { oserr = err; PR_DELETE(lm); goto unlock; } libName = name; } else { /* * The name did contain a ":", so it must be a full path name. * Now we have to do a lot of work to convert the path name to * an FSSpec (silly, since we were probably just called from the * MacFE plug-in code that already knew the FSSpec and converted * it to a full path just to pass to us). First we copy out the * volume name (the text leading up to the first ":"); then we * separate the file name (the text following the last ":") from * rest of the path. After converting the strings to Pascal * format we can call GetCatInfo to get the parent directory ID * of the file, and then (finally) make an FSSpec and call * GetDiskFragment. */ FSSpec fileSpec; Boolean tempUnusedBool; PStrFromCStr(name, pName); err = FSMakeFSSpec(0, 0, pName, &fileSpec); if (err != noErr) { oserr = _MD_ERRNO(); PR_DELETE(lm); goto unlock; } /* Resolve an alias if this was one */ err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool, &tempUnusedBool); if (err != noErr) { oserr = err; PR_DELETE(lm); goto unlock; } /* Finally, try to load the library */ err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name, kLoadCFrag, &connectionID, &lm->main, errName); memcpy(cName, fileSpec.name + 1, fileSpec.name[0]); cName[fileSpec.name[0]] = '\0'; libName = cName; if (err != noErr) {#if TARGET_CARBON /* If not a CFM library, perhaps it's a CFBundle. */ lm->bundle = getLibraryBundle(&fileSpec);#ifdef DEBUG fprintf(stderr, "*** loading bundle for library '%s' [%s]. ***\n", libName, lm->bundle ? "SUCCEEDED" : "FAILED");#endif if (lm->bundle == NULL) { oserr = err; PR_DELETE(lm); goto unlock; }#else oserr = err; PR_DELETE(lm); goto unlock;#endif } } lm->name = strdup(libName); lm->dlh = connectionID; lm->next = pr_loadmap; pr_loadmap = lm; }#elif defined(XP_MAC) && !TARGET_RT_MAC_CFM { }#endif#ifdef XP_UNIX#ifdef HAVE_DLL {#if defined(USE_DLFCN)#ifdef NTO /* Neutrino needs RTLD_GROUP to load Netscape plugins. (bug 71179) */ int dl_flags = RTLD_GROUP;#else int dl_flags = 0;#endif void *h; if (flags & PR_LD_LAZY) { dl_flags |= RTLD_LAZY; } if (flags & PR_LD_NOW) { dl_flags |= RTLD_NOW; } if (flags & PR_LD_GLOBAL) { dl_flags |= RTLD_GLOBAL; } if (flags & PR_LD_LOCAL) { dl_flags |= RTLD_LOCAL; } h = dlopen(name, dl_flags);#elif defined(USE_HPSHL) int shl_flags = 0; shl_t h; /* * Use the DYNAMIC_PATH flag only if 'name' is a plain file * name (containing no directory) to match the behavior of * dlopen(). */ if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) { shl_flags |= DYNAMIC_PATH; } if (flags & PR_LD_LAZY) { shl_flags |= BIND_DEFERRED; } if (flags & PR_LD_NOW) { shl_flags |= BIND_IMMEDIATE; } /* No equivalent of PR_LD_GLOBAL and PR_LD_LOCAL. */ h = shl_load(name, shl_flags, 0L);#elif defined(USE_MACH_DYLD) NSObjectFileImage ofi; NSModule h = NULL; if (NSCreateObjectFileImageFromFile(name, &ofi) == NSObjectFileImageSuccess) { h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE); }#else#error Configuration error#endif if (!h) { oserr = _MD_ERRNO(); PR_DELETE(lm); goto unlock; } lm->name = strdup(name); lm->dlh = h; lm->next = pr_loadmap; pr_loadmap = lm; }#endif /* HAVE_DLL */#endif /* XP_UNIX */ lm->refCount = 1;#ifdef XP_BEOS { image_info info; int32 cookie = 0; image_id imageid = B_ERROR; image_id stubid = B_ERROR; PRLibrary *p; for (p = pr_loadmap; p != NULL; p = p->next) { /* hopefully, our caller will always use the same string to refer to the same library */ if (strcmp(name, p->name) == 0) { /* we've already loaded this library */ imageid = info.id; lm->refCount++; break; } } if(imageid == B_ERROR) { /* it appears the library isn't yet loaded - load it now */ char stubName [B_PATH_NAME_LENGTH + 1]; /* the following is a work-around to a "bug" in the beos - the beos system loader allows only 32M (system-wide) to be used by code loaded as "add-ons" (code loaded through the 'load_add_on()' system call, which includes mozilla components), but allows 256M to be used by shared libraries. unfortunately, mozilla is too large to fit into the "add-on" space, so we must trick the loader into loading some of the components as shared libraries. this is accomplished by creating a "stub" add-on (an empty shared object), and linking it with the component (the actual .so file generated by the build process, without any modifications). when this stub is loaded by load_add_on(), the loader will automatically load the component into the shared library space. */ strcpy(stubName, name); strcat(stubName, ".stub"); /* first, attempt to load the stub (thereby loading the component as a shared library */ if ((stubid = load_add_on(stubName)) > B_ERROR) { /* the stub was loaded successfully. */ imageid = B_FILE_NOT_FOUND; cookie = 0; while (get_next_image_info(0, &cookie, &info) == B_OK) { char *endOfSystemName = strrchr(info.name, '/'); char *endOfPassedName = strrchr(name, '/'); if( 0 == endOfSystemName ) endOfSystemName=info.name; else endOfSystemName++; if( 0 == endOfPassedName ) endOfPassedName=name; else endOfPassedName++; if (strcmp(endOfSystemName, endOfPassedName) == 0) { /* this is the actual component - remember it */ imageid = info.id; break; } } } else { /* we failed to load the "stub" - try to load the component directly as an add-on */ stubid = B_ERROR; imageid = load_add_on(name); } } if (imageid <= B_ERROR) { oserr = imageid; PR_DELETE( lm ); goto unlock; } lm->name = strdup(name); lm->dlh = (void*)imageid; lm->stub_dlh = (void*)stubid; lm->next = pr_loadmap; pr_loadmap = lm; }#endif result = lm; /* success */ PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", lm->name)); unlock: if (result == NULL) { PR_SetError(PR_LOAD_LIBRARY_ERROR, oserr); DLLErrorInternal(oserr); /* sets error text */ } PR_ExitMonitor(pr_linker_lock); return result;}PR_IMPLEMENT(PRLibrary*) PR_FindLibrary(const char *name){ PRLibrary* result; if (!_pr_initialized) _PR_ImplicitInitialization();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -