Changeset 101840 in vbox for trunk/src/libs/xpcom18a4
- Timestamp:
- Nov 5, 2023 5:39:13 PM (15 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/nsprpub/pr/src/linking/prlink.c
r101775 r101840 41 41 #include <string.h> 42 42 43 #ifdef VBOX_USE_MORE_IPRT_IN_NSPR44 43 # include <iprt/ldr.h> 45 44 # include <iprt/path.h> … … 50 49 # endif 51 50 52 # ifdef XP_MAC 53 # error "Misconfiguration: XP_MAC && VBOX_USE_MORE_IPRT_IN_NSPR are not intended to work together" 51 # ifdef USE_DLFCN 52 # include <dlfcn.h> 53 /* Define these on systems that don't have them. */ 54 # ifndef RTLD_NOW 55 # define RTLD_NOW 0 56 # endif 57 # ifndef RTLD_LAZY 58 # define RTLD_LAZY RTLD_NOW 59 # endif 60 # ifndef RTLD_GLOBAL 61 # define RTLD_GLOBAL 0 62 # endif 63 # ifndef RTLD_LOCAL 64 # define RTLD_LOCAL 0 65 # endif 54 66 # endif 55 67 56 #else /* ! VBOX_USE_MORE_IPRT_IN_NSPR */57 58 #ifdef XP_BEOS59 #include <image.h>60 #endif61 62 #if defined(XP_MAC) || defined(XP_MACOSX)63 #include <CodeFragments.h>64 #include <TextUtils.h>65 #include <Types.h>66 #include <Aliases.h>67 68 #if TARGET_CARBON69 #include <CFURL.h>70 #include <CFBundle.h>71 #include <CFString.h>72 #include <CFDictionary.h>73 #include <CFData.h>74 #endif75 76 #if defined(XP_MACOSX)77 #define PStrFromCStr(src, dst) c2pstrcpy(dst, src)78 #else79 #include "macdll.h"80 #include "mdmac.h"81 #endif /* XP_MACOSX */82 #endif83 84 #ifdef XP_UNIX85 #ifdef USE_DLFCN86 #include <dlfcn.h>87 /* Define these on systems that don't have them. */88 #ifndef RTLD_NOW89 #define RTLD_NOW 090 #endif91 #ifndef RTLD_LAZY92 #define RTLD_LAZY RTLD_NOW93 #endif94 #ifndef RTLD_GLOBAL95 #define RTLD_GLOBAL 096 #endif97 #ifndef RTLD_LOCAL98 #define RTLD_LOCAL 099 #endif100 #ifdef AIX101 #include <sys/ldr.h>102 #endif103 #ifdef OSF1104 #include <loader.h>105 #include <rld_interface.h>106 #endif107 #elif defined(USE_HPSHL)108 #include <dl.h>109 #elif defined(USE_MACH_DYLD)110 #include <mach-o/dyld.h>111 #endif112 #endif /* XP_UNIX */113 114 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */115 68 #ifdef VBOX_USE_IPRT_IN_NSPR 116 69 # include <iprt/mem.h> … … 122 75 #define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY 123 76 124 #ifdef VMS125 /* These are all require for the PR_GetLibraryFilePathname implementation */126 #include <descrip.h>127 #include <dvidef.h>128 #include <fibdef.h>129 #include <iodef.h>130 #include <lib$routines.h>131 #include <ssdef.h>132 #include <starlet.h>133 #include <stsdef.h>134 #include <unixlib.h>135 136 #pragma __nostandard137 #pragma __member_alignment __save138 #pragma __nomember_alignment139 #ifdef __INITIAL_POINTER_SIZE140 #pragma __required_pointer_size __save141 #pragma __required_pointer_size __short142 #endif143 144 typedef struct _imcb {145 struct _imcb *imcb$l_flink;146 struct _imcb *imcb$l_blink;147 unsigned short int imcb$w_size;148 unsigned char imcb$b_type;149 char imcb$b_resv_1;150 unsigned char imcb$b_access_mode;151 unsigned char imcb$b_act_code;152 unsigned short int imcb$w_chan;153 unsigned int imcb$l_flags;154 char imcb$t_image_name [40];155 unsigned int imcb$l_symvec_size;156 unsigned __int64 imcb$q_ident;157 void *imcb$l_starting_address;158 void *imcb$l_end_address;159 } IMCB;160 161 #pragma __member_alignment __restore162 #ifdef __INITIAL_POINTER_SIZE163 #pragma __required_pointer_size __restore164 #endif165 #pragma __standard166 167 typedef struct {168 short buflen;169 short itmcode;170 void *buffer;171 void *retlen;172 } ITMLST;173 174 typedef struct {175 short cond;176 short count;177 int rest;178 } IOSB;179 180 typedef unsigned long int ulong_t;181 182 struct _imcb *IAC$GL_IMAGE_LIST = NULL;183 184 #define MAX_DEVNAM 64185 #define MAX_FILNAM 255186 #endif /* VMS */187 188 /*189 * On these platforms, symbols have a leading '_'.190 */191 #ifndef VBOX_USE_MORE_IPRT_IN_NSPR /* RTLdr hides this. */192 #if defined(SUNOS4) || defined(DARWIN) || defined(NEXTSTEP) \193 || defined(WIN16) || defined(XP_OS2) \194 || ((defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__))195 #define NEED_LEADING_UNDERSCORE196 #endif197 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */198 199 #ifdef XP_PC200 typedef PRStaticLinkTable *NODL_PROC(void);201 #endif202 203 77 /************************************************************************/ 204 78 … … 207 81 PRLibrary* next; 208 82 int refCount; 209 const PRStaticLinkTable* staticTable; 210 211 #ifdef VBOX_USE_MORE_IPRT_IN_NSPR 83 212 84 RTLDRMOD dlh; 213 #else /* !VBOX_USE_MORE_IPRT_IN_NSPR */214 215 #ifdef XP_PC216 #ifdef XP_OS2217 HMODULE dlh;218 #else219 HINSTANCE dlh;220 #endif221 #endif222 223 #if defined(XP_MAC) || defined(XP_MACOSX)224 CFragConnectionID connection;225 226 #if TARGET_CARBON227 CFBundleRef bundle;228 #endif229 230 Ptr main;231 232 #if defined(XP_MACOSX)233 CFMutableDictionaryRef wrappers;234 const struct mach_header* image;235 #endif /* XP_MACOSX */236 #endif237 238 #ifdef XP_UNIX239 #if defined(USE_HPSHL)240 shl_t dlh;241 #elif defined(USE_MACH_DYLD)242 NSModule dlh;243 #else244 void* dlh;245 #endif246 #endif247 248 #ifdef XP_BEOS249 void* dlh;250 void* stub_dlh;251 #endif252 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */253 85 }; 254 86 … … 259 91 260 92 static PRLibrary *pr_LoadLibraryByPathname(const char *name, PRIntn flags); 261 #ifdef XP_MAC262 static PRLibrary *pr_Mac_LoadNamedFragment(const FSSpec *fileSpec,263 const char* fragmentName);264 static PRLibrary *pr_Mac_LoadIndexedFragment(const FSSpec *fileSpec,265 PRUint32 fragIndex);266 #endif /* XP_MAC */267 93 268 94 /************************************************************************/ 269 270 #if !defined(USE_DLFCN) && !defined(HAVE_STRERROR) && !defined(VBOX_USE_MORE_IPRT_IN_NSPR)271 static char* errStrBuf = NULL;272 #define ERR_STR_BUF_LENGTH 20273 static char* errno_string(PRIntn oserr)274 {275 if (errStrBuf == NULL)276 errStrBuf = PR_MALLOC(ERR_STR_BUF_LENGTH);277 PR_snprintf(errStrBuf, ERR_STR_BUF_LENGTH, "error %d", oserr);278 return errStrBuf;279 }280 #endif281 95 282 96 static void DLLErrorInternal(PRIntn oserr) … … 301 115 void _PR_InitLinker(void) 302 116 { 303 #if (!defined(XP_MAC) && !defined(XP_BEOS)) || defined(VBOX_USE_MORE_IPRT_IN_NSPR)304 117 PRLibrary *lm; 305 #endif306 #ifdef XP_UNIX307 void *h;308 #endif309 118 310 119 if (!pr_linker_lock) { … … 313 122 PR_EnterMonitor(pr_linker_lock); 314 123 315 #if defined(XP_PC) || defined(VBOX_USE_MORE_IPRT_IN_NSPR)316 124 lm = PR_NEWZAP(PRLibrary); 317 125 lm->name = strdup("Executable"); 318 #ifdef VBOX_USE_MORE_IPRT_IN_NSPR319 126 lm->dlh = NIL_RTLDRMOD; 320 #else /* !VBOX_USE_MORE_IPRT_IN_NSPR */321 /*322 ** In WIN32, GetProcAddress(...) expects a module handle in order to323 ** get exported symbols from the executable...324 **325 ** However, in WIN16 this is accomplished by passing NULL to326 ** GetProcAddress(...)327 */328 #if defined(_WIN32)329 lm->dlh = GetModuleHandle(NULL);330 #else331 lm->dlh = (HINSTANCE)NULL;332 #endif /* ! _WIN32 */333 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */334 335 127 lm->refCount = 1; 336 lm->staticTable = NULL;337 128 pr_exe_loadmap = lm; 338 129 pr_loadmap = lm; 339 130 340 #elif defined(XP_UNIX)341 #ifdef HAVE_DLL342 #ifdef USE_DLFCN343 h = dlopen(0, RTLD_LAZY);344 if (!h) {345 char *error;346 347 DLLErrorInternal(_MD_ERRNO());348 error = (char*)PR_MALLOC(PR_GetErrorTextLength());349 (void) PR_GetErrorText(error);350 fprintf(stderr, "failed to initialize shared libraries [%s]\n",351 error);352 PR_DELETE(error);353 abort();/* XXX */354 }355 #elif defined(USE_HPSHL)356 h = NULL;357 /* don't abort with this NULL */358 #elif defined(USE_MACH_DYLD)359 h = NULL; /* XXXX toshok */360 #else361 #error no dll strategy362 #endif /* USE_DLFCN */363 364 lm = PR_NEWZAP(PRLibrary);365 if (lm) {366 lm->name = strdup("a.out");367 lm->refCount = 1;368 lm->dlh = h;369 lm->staticTable = NULL;370 }371 pr_exe_loadmap = lm;372 pr_loadmap = lm;373 #endif /* HAVE_DLL */374 #endif /* XP_UNIX */375 376 #if !defined(XP_MAC) && !defined(XP_BEOS) || defined(VBOX_USE_MORE_IPRT_IN_NSPR)377 131 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (init)", lm?lm->name:"NULL")); 378 #endif 379 380 PR_ExitMonitor(pr_linker_lock); 381 } 382 383 #if defined(WIN16) 384 /* 385 * _PR_ShutdownLinker unloads all dlls loaded by the application via 386 * calls to PR_LoadLibrary 387 */ 388 void _PR_ShutdownLinker(void) 389 { 390 PR_EnterMonitor(pr_linker_lock); 391 392 while (pr_loadmap) { 393 if (pr_loadmap->refCount > 1) { 394 #ifdef DEBUG 395 fprintf(stderr, "# Forcing library to unload: %s (%d outstanding references)\n", 396 pr_loadmap->name, pr_loadmap->refCount); 397 #endif 398 pr_loadmap->refCount = 1; 399 } 400 PR_UnloadLibrary(pr_loadmap); 401 } 402 403 PR_ExitMonitor(pr_linker_lock); 404 405 PR_DestroyMonitor(pr_linker_lock); 406 pr_linker_lock = NULL; 407 } 408 #else 132 PR_ExitMonitor(pr_linker_lock); 133 } 134 409 135 /* 410 136 * _PR_ShutdownLinker was originally only used on WIN16 (see above), … … 424 150 425 151 if (_pr_currentLibPath) { 426 #ifdef VBOX_USE_IPRT_IN_NSPR427 152 RTStrFree(_pr_currentLibPath); 428 #else429 free(_pr_currentLibPath);430 #endif431 153 _pr_currentLibPath = NULL; 432 154 } 433 434 #if !defined(USE_DLFCN) && !defined(HAVE_STRERROR) && !defined(VBOX_USE_MORE_IPRT_IN_NSPR) 435 PR_DELETE(errStrBuf); 436 #endif 437 } 438 #endif 155 } 439 156 440 157 /******************************************************************************/ … … 447 164 PR_EnterMonitor(pr_linker_lock); 448 165 if (_pr_currentLibPath) { 449 #ifdef VBOX_USE_IPRT_IN_NSPR450 166 RTStrFree(_pr_currentLibPath); 451 #else452 free(_pr_currentLibPath);453 #endif454 167 } 455 168 if (path) { … … 483 196 /* initialize pr_currentLibPath */ 484 197 485 #ifdef XP_PC486 ev = getenv("LD_LIBRARY_PATH");487 if (!ev) {488 ev = ".;\\lib";489 }490 ev = strdup(ev);491 #endif492 493 #ifdef XP_MAC494 {495 char *p;496 int len;497 498 ev = getenv("LD_LIBRARY_PATH");499 500 if (!ev)501 ev = "";502 503 len = strlen(ev) + 1; /* +1 for the null */504 # ifdef VBOX_USE_IPRT_IN_NSPR505 p = (char*) RTStrAlloc(len);506 # else507 p = (char*) malloc(len);508 # endif509 if (p) {510 strcpy(p, ev);511 }512 ev = p;513 }514 #endif515 516 198 #if defined(XP_UNIX) || defined(XP_BEOS) 517 199 #if defined(USE_DLFCN) || defined(USE_MACH_DYLD) || defined(XP_BEOS) … … 520 202 int len; 521 203 522 #ifdef XP_BEOS523 ev = getenv("LIBRARY_PATH");524 if (!ev) {525 ev = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";526 }527 #else528 204 # if defined(VBOX) && defined(XP_MACOSX) 529 205 ev = getenv("DYLD_LIBRARY_PATH"); … … 534 210 ev = "/usr/lib:/lib"; 535 211 } 536 #endif 212 537 213 len = strlen(ev) + 1; /* +1 for the null */ 538 214 539 # ifdef VBOX_USE_IPRT_IN_NSPR540 215 p = (char*) RTStrAlloc(len); 541 # else542 p = (char*) malloc(len);543 # endif544 216 if (p) { 545 217 strcpy(p, ev); … … 562 234 exit: 563 235 if (_pr_currentLibPath) { 564 #ifdef VBOX_USE_IPRT_IN_NSPR565 236 copy = RTMemDup(_pr_currentLibPath, strlen(_pr_currentLibPath) + 1); 566 #else567 copy = strdup(_pr_currentLibPath);568 #endif569 237 } 570 238 PR_ExitMonitor(pr_linker_lock); … … 583 251 char *fullname; 584 252 585 #ifdef XP_PC586 if (strstr(lib, PR_DLL_SUFFIX) == NULL)587 {588 if (path) {589 fullname = PR_smprintf("%s\\%s%s", path, lib, PR_DLL_SUFFIX);590 } else {591 fullname = PR_smprintf("%s%s", lib, PR_DLL_SUFFIX);592 }593 } else {594 if (path) {595 fullname = PR_smprintf("%s\\%s", path, lib);596 } else {597 fullname = PR_smprintf("%s", lib);598 }599 }600 #endif /* XP_PC */601 #ifdef XP_MAC602 if (path) {603 fullname = PR_smprintf("%s%s", path, lib);604 } else {605 fullname = PR_smprintf("%s", lib);606 }607 #endif608 253 #if defined(XP_UNIX) || defined(XP_BEOS) 609 254 if (strstr(lib, PR_DLL_SUFFIX) == NULL) … … 643 288 const char* cp = strrchr(lm->name, PR_DIRECTORY_SEPARATOR); 644 289 cp = cp ? cp + 1 : lm->name; 645 #ifdef WIN32 646 /* Windows DLL names are case insensitive... */ 647 if (strcmpi(np, cp) == 0) 648 #elif defined(XP_OS2) 649 if (stricmp(np, cp) == 0) 650 #else 290 651 291 if (strcmp(np, cp) == 0) 652 #endif653 292 { 654 293 /* found */ … … 673 312 case PR_LibSpec_Pathname: 674 313 return pr_LoadLibraryByPathname(libSpec.value.pathname, flags); 675 #ifdef XP_MAC676 case PR_LibSpec_MacNamedFragment:677 return pr_Mac_LoadNamedFragment(678 libSpec.value.mac_named_fragment.fsspec,679 libSpec.value.mac_named_fragment.name);680 case PR_LibSpec_MacIndexedFragment:681 return pr_Mac_LoadIndexedFragment(682 libSpec.value.mac_indexed_fragment.fsspec,683 libSpec.value.mac_indexed_fragment.index);684 #endif /* XP_MAC */685 314 default: 686 315 PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); … … 698 327 return PR_LoadLibraryWithFlags(libSpec, 0); 699 328 } 700 701 #ifndef VBOX_USE_MORE_IPRT_IN_NSPR /* exclude big chunk */702 #if defined(USE_MACH_DYLD)703 static NSModule704 pr_LoadMachDyldModule(const char *name)705 {706 NSObjectFileImage ofi;707 NSModule h = NULL;708 if (NSCreateObjectFileImageFromFile(name, &ofi)709 == NSObjectFileImageSuccess) {710 h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE711 | NSLINKMODULE_OPTION_RETURN_ON_ERROR);712 /*713 * TODO: If NSLinkModule fails, use NSLinkEditError to retrieve714 * error information.715 */716 if (NSDestroyObjectFileImage(ofi) == FALSE) {717 if (h) {718 (void)NSUnLinkModule(h, NSUNLINKMODULE_OPTION_NONE);719 h = NULL;720 }721 }722 }723 return h;724 }725 #endif726 727 #if defined(XP_MAC) || defined(XP_MACOSX)728 729 #ifdef XP_MACOSX730 static void* TV2FP(CFMutableDictionaryRef dict, const char* name, void *tvp)731 {732 static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 };733 uint32* newGlue = NULL;734 735 if (tvp != NULL) {736 CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);737 if (nameRef) {738 CFMutableDataRef glueData = (CFMutableDataRef) CFDictionaryGetValue(dict, nameRef);739 if (glueData == NULL) {740 glueData = CFDataCreateMutable(NULL, sizeof(glue));741 if (glueData != NULL) {742 newGlue = (uint32*) CFDataGetMutableBytePtr(glueData);743 memcpy(newGlue, glue, sizeof(glue));744 newGlue[0] |= ((UInt32)tvp >> 16);745 newGlue[1] |= ((UInt32)tvp & 0xFFFF);746 MakeDataExecutable(newGlue, sizeof(glue));747 CFDictionaryAddValue(dict, nameRef, glueData);748 CFRelease(glueData);749 750 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: created wrapper for CFM function %s().", name));751 }752 } else {753 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: found wrapper for CFM function %s().", name));754 755 newGlue = (uint32*) CFDataGetMutableBytePtr(glueData);756 }757 CFRelease(nameRef);758 }759 }760 761 return newGlue;762 }763 #endif764 765 /*766 ** macLibraryLoadProc is a function definition for a Mac shared library767 ** loading method. The "name" param is the same full or partial pathname768 ** that was passed to pr_LoadLibraryByPathName. The function must fill769 ** in the fields of "lm" which apply to its library type. Returns770 ** PR_SUCCESS if successful.771 */772 773 typedef PRStatus (*macLibraryLoadProc)(const char *name, PRLibrary *lm);774 775 static PRStatus776 pr_LoadViaCFM(const char *name, PRLibrary *lm)777 {778 OSErr err;779 char cName[64];780 Str255 errName;781 782 #if !defined(XP_MACOSX)783 Str255 pName;784 /*785 * Algorithm: The "name" passed in could be either a shared786 * library name that we should look for in the normal library787 * search paths, or a full path name to a specific library on788 * disk. Since the full path will always contain a ":"789 * (shortest possible path is "Volume:File"), and since a790 * library name can not contain a ":", we can test for the791 * presence of a ":" to see which type of library we should load.792 * or its a full UNIX path which we for now assume is Java793 * enumerating all the paths (see below)794 */795 if (strchr(name, PR_PATH_SEPARATOR) == NULL) {796 if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) {797 /*798 * The name did not contain a ":", so it must be a799 * library name. Convert the name to a Pascal string800 * and try to find the library.801 */802 } else {803 /*804 * name contained a "/" which means we need to suck off805 * the last part of the path and pass that on the806 * NSGetSharedLibrary. this may not be what we really807 * want to do .. because Java could be iterating through808 * the whole LD path, and we'll find it if it's anywhere809 * on that path -- it appears that's what UNIX and the810 * PC do too...so we'll emulate but it could be wrong.811 */812 name = strrchr(name, PR_DIRECTORY_SEPARATOR) + 1;813 }814 815 PStrFromCStr(name, pName);816 817 /*818 * beard: NSGetSharedLibrary was so broken that I just decided to819 * use GetSharedLibrary for now. This will need to change for820 * plugins, but those should go in the Extensions folder anyhow.821 */822 err = GetSharedLibrary(pName, kCompiledCFragArch, kReferenceCFrag,823 &lm->connection, &lm->main, errName);824 if (err != noErr)825 return PR_FAILURE;826 }827 else828 #endif829 {830 /*831 * The name did contain a ":", so it must be a full path name.832 * Now we have to do a lot of work to convert the path name to833 * an FSSpec (silly, since we were probably just called from the834 * MacFE plug-in code that already knew the FSSpec and converted835 * it to a full path just to pass to us). Make an FSSpec from836 * the full path and call GetDiskFragment.837 */838 FSSpec fileSpec;839 Boolean tempUnusedBool;840 841 #if defined(XP_MACOSX)842 {843 /* Use direct conversion of POSIX path to FSRef to FSSpec. */844 FSRef ref;845 err = FSPathMakeRef((const UInt8*)name, &ref, NULL);846 if (err == noErr)847 err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL,848 &fileSpec, NULL);849 }850 #else851 PStrFromCStr(name, pName);852 err = FSMakeFSSpec(0, 0, pName, &fileSpec);853 #endif854 if (err != noErr)855 return PR_FAILURE;856 857 /* Resolve an alias if this was one */858 err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool,859 &tempUnusedBool);860 if (err != noErr)861 return PR_FAILURE;862 863 /* Finally, try to load the library */864 err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name,865 kLoadCFrag, &lm->connection, &lm->main, errName);866 867 #if TARGET_CARBON868 p2cstrcpy(cName, fileSpec.name);869 #else870 memcpy(cName, fileSpec.name + 1, fileSpec.name[0]);871 cName[fileSpec.name[0]] = '\0';872 #endif873 874 #ifdef XP_MACOSX875 if (err == noErr && lm->connection) {876 /*877 * if we're a mach-o binary, need to wrap all CFM function878 * pointers. need a hash-table of already seen function879 * pointers, etc.880 */881 lm->wrappers = CFDictionaryCreateMutable(NULL, 16,882 &kCFTypeDictionaryKeyCallBacks,883 &kCFTypeDictionaryValueCallBacks);884 if (lm->wrappers) {885 lm->main = TV2FP(lm->wrappers, "main", lm->main);886 } else887 err = memFullErr;888 }889 #endif890 }891 return (err == noErr) ? PR_SUCCESS : PR_FAILURE;892 }893 894 /*895 ** Creates a CFBundleRef if the pathname refers to a Mac OS X bundle896 ** directory. The caller is responsible for calling CFRelease() to897 ** deallocate.898 */899 900 #if TARGET_CARBON901 static PRStatus902 pr_LoadCFBundle(const char *name, PRLibrary *lm)903 {904 CFURLRef bundleURL;905 CFBundleRef bundle = NULL;906 907 #ifdef XP_MACOSX908 char pathBuf[PATH_MAX];909 const char *resolvedPath;910 CFStringRef pathRef;911 912 /* Takes care of relative paths and symlinks */913 resolvedPath = realpath(name, pathBuf);914 if (!resolvedPath)915 return PR_FAILURE;916 917 pathRef = CFStringCreateWithCString(NULL, pathBuf, kCFStringEncodingUTF8);918 if (pathRef) {919 bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef,920 kCFURLPOSIXPathStyle, true);921 if (bundleURL) {922 bundle = CFBundleCreate(NULL, bundleURL);923 CFRelease(bundleURL);924 }925 CFRelease(pathRef);926 }927 #else928 OSErr err;929 Str255 pName;930 FSSpec fsSpec;931 FSRef fsRef;932 933 if ((UInt32)(CFURLCreateFromFSRef) == kUnresolvedCFragSymbolAddress)934 return PR_FAILURE;935 PStrFromCStr(name, pName);936 err = FSMakeFSSpec(0, 0, pName, &fsSpec);937 if (err != noErr)938 return PR_FAILURE;939 err = FSpMakeFSRef(&fsSpec, &fsRef);940 if (err != noErr)941 return PR_FAILURE;942 bundleURL = CFURLCreateFromFSRef(NULL, &fsRef);943 if (bundleURL) {944 bundle = CFBundleCreate(NULL, bundleURL);945 CFRelease(bundleURL);946 }947 #endif948 949 lm->bundle = bundle;950 return (bundle != NULL) ? PR_SUCCESS : PR_FAILURE;951 }952 #endif953 954 #ifdef XP_MACOSX955 static PRStatus956 pr_LoadViaDyld(const char *name, PRLibrary *lm)957 {958 lm->dlh = pr_LoadMachDyldModule(name);959 if (lm->dlh == NULL) {960 lm->image = NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ON_ERROR961 | NSADDIMAGE_OPTION_WITH_SEARCHING);962 /*963 * TODO: If NSAddImage fails, use NSLinkEditError to retrieve964 * error information.965 */966 }967 return (lm->dlh != NULL || lm->image != NULL) ? PR_SUCCESS : PR_FAILURE;968 }969 #endif970 971 #endif /* defined(XP_MAC) || defined(XP_MACOSX) */972 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */973 329 974 330 /* … … 996 352 goto unlock; 997 353 } 998 lm->staticTable = NULL; 999 1000 #ifdef VBOX_USE_MORE_IPRT_IN_NSPR 354 1001 355 oserr = RTLdrLoad(name, &lm->dlh); 1002 356 if (RT_FAILURE(oserr)) … … 1007 361 pr_loadmap = lm; 1008 362 1009 #else /* !VBOX_USE_MORE_IPRT_IN_NSPR */1010 #ifdef XP_OS2 /* Why isn't all this stuff in MD code?! */1011 {1012 HMODULE h;1013 UCHAR pszError[_MAX_PATH];1014 ULONG ulRc = NO_ERROR;1015 1016 ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h);1017 if (ulRc != NO_ERROR) {1018 oserr = ulRc;1019 PR_DELETE(lm);1020 goto unlock;1021 }1022 lm->name = strdup(name);1023 lm->dlh = h;1024 lm->next = pr_loadmap;1025 pr_loadmap = lm;1026 }1027 #endif /* XP_OS2 */1028 1029 #if defined(WIN32) || defined(WIN16)1030 {1031 HINSTANCE h;1032 NODL_PROC *pfn;1033 1034 h = LoadLibrary(name);1035 if (h < (HINSTANCE)HINSTANCE_ERROR) {1036 oserr = _MD_ERRNO();1037 PR_DELETE(lm);1038 goto unlock;1039 }1040 lm->name = strdup(name);1041 lm->dlh = h;1042 lm->next = pr_loadmap;1043 pr_loadmap = lm;1044 1045 /*1046 ** Try to load a table of "static functions" provided by the DLL1047 */1048 1049 pfn = (NODL_PROC *)GetProcAddress(h, "NODL_TABLE");1050 if (pfn != NULL) {1051 lm->staticTable = (*pfn)();1052 }1053 }1054 #endif /* WIN32 || WIN16 */1055 1056 #if defined(XP_MAC) || defined(XP_MACOSX)1057 {1058 int i;1059 PRStatus status;1060 1061 static const macLibraryLoadProc loadProcs[] = {1062 #if defined(XP_MACOSX)1063 pr_LoadViaDyld, pr_LoadCFBundle, pr_LoadViaCFM1064 #elif TARGET_CARBON1065 pr_LoadViaCFM, pr_LoadCFBundle1066 #else1067 pr_LoadViaCFM1068 #endif1069 };1070 1071 for (i = 0; i < sizeof(loadProcs) / sizeof(loadProcs[0]); i++) {1072 if ((status = loadProcs[i](name, lm)) == PR_SUCCESS)1073 break;1074 }1075 if (status != PR_SUCCESS) {1076 oserr = cfragNoLibraryErr;1077 PR_DELETE(lm);1078 goto unlock;1079 }1080 lm->name = strdup(name);1081 lm->next = pr_loadmap;1082 pr_loadmap = lm;1083 }1084 #endif1085 1086 #if defined(XP_UNIX) && !defined(XP_MACOSX)1087 #ifdef HAVE_DLL1088 {1089 #if defined(USE_DLFCN)1090 #ifdef NTO1091 /* Neutrino needs RTLD_GROUP to load Netscape plugins. (bug 71179) */1092 int dl_flags = RTLD_GROUP;1093 #elif defined(AIX)1094 /* AIX needs RTLD_MEMBER to load an archive member. (bug 228899) */1095 int dl_flags = RTLD_MEMBER;1096 #else1097 int dl_flags = 0;1098 #endif1099 void *h;1100 1101 if (flags & PR_LD_LAZY) {1102 dl_flags |= RTLD_LAZY;1103 }1104 if (flags & PR_LD_NOW) {1105 dl_flags |= RTLD_NOW;1106 }1107 if (flags & PR_LD_GLOBAL) {1108 dl_flags |= RTLD_GLOBAL;1109 }1110 if (flags & PR_LD_LOCAL) {1111 dl_flags |= RTLD_LOCAL;1112 }1113 h = dlopen(name, dl_flags);1114 #elif defined(USE_HPSHL)1115 int shl_flags = 0;1116 shl_t h;1117 1118 /*1119 * Use the DYNAMIC_PATH flag only if 'name' is a plain file1120 * name (containing no directory) to match the behavior of1121 * dlopen().1122 */1123 if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) {1124 shl_flags |= DYNAMIC_PATH;1125 }1126 if (flags & PR_LD_LAZY) {1127 shl_flags |= BIND_DEFERRED;1128 }1129 if (flags & PR_LD_NOW) {1130 shl_flags |= BIND_IMMEDIATE;1131 }1132 /* No equivalent of PR_LD_GLOBAL and PR_LD_LOCAL. */1133 h = shl_load(name, shl_flags, 0L);1134 #elif defined(USE_MACH_DYLD)1135 NSModule h = pr_LoadMachDyldModule(name);1136 #else1137 #error Configuration error1138 #endif1139 if (!h) {1140 oserr = _MD_ERRNO();1141 #ifdef DEBUG1142 fprintf(stderr, "pr_LoadLibraryByPathname(): Failed to load '%s'\n", name);1143 #endif1144 PR_DELETE(lm);1145 goto unlock;1146 }1147 lm->name = strdup(name);1148 lm->dlh = h;1149 lm->next = pr_loadmap;1150 pr_loadmap = lm;1151 }1152 #endif /* HAVE_DLL */1153 #endif /* XP_UNIX */1154 1155 lm->refCount = 1;1156 1157 #ifdef XP_BEOS1158 {1159 image_info info;1160 int32 cookie = 0;1161 image_id imageid = B_ERROR;1162 image_id stubid = B_ERROR;1163 PRLibrary *p;1164 1165 for (p = pr_loadmap; p != NULL; p = p->next) {1166 /* hopefully, our caller will always use the same string1167 to refer to the same library */1168 if (strcmp(name, p->name) == 0) {1169 /* we've already loaded this library */1170 imageid = info.id;1171 lm->refCount++;1172 break;1173 }1174 }1175 1176 if(imageid == B_ERROR) {1177 /* it appears the library isn't yet loaded - load it now */1178 char stubName [B_PATH_NAME_LENGTH + 1];1179 1180 /* the following is a work-around to a "bug" in the beos -1181 the beos system loader allows only 32M (system-wide)1182 to be used by code loaded as "add-ons" (code loaded1183 through the 'load_add_on()' system call, which includes1184 mozilla components), but allows 256M to be used by1185 shared libraries.1186 1187 unfortunately, mozilla is too large to fit into the1188 "add-on" space, so we must trick the loader into1189 loading some of the components as shared libraries. this1190 is accomplished by creating a "stub" add-on (an empty1191 shared object), and linking it with the component1192 (the actual .so file generated by the build process,1193 without any modifications). when this stub is loaded1194 by load_add_on(), the loader will automatically load the1195 component into the shared library space.1196 */1197 1198 strcpy(stubName, name);1199 strcat(stubName, ".stub");1200 1201 /* first, attempt to load the stub (thereby loading the1202 component as a shared library */1203 if ((stubid = load_add_on(stubName)) > B_ERROR) {1204 /* the stub was loaded successfully. */1205 imageid = B_FILE_NOT_FOUND;1206 1207 cookie = 0;1208 while (get_next_image_info(0, &cookie, &info) == B_OK) {1209 const char *endOfSystemName = strrchr(info.name, '/');1210 const char *endOfPassedName = strrchr(name, '/');1211 if( 0 == endOfSystemName )1212 endOfSystemName = info.name;1213 else1214 endOfSystemName++;1215 if( 0 == endOfPassedName )1216 endOfPassedName = name;1217 else1218 endOfPassedName++;1219 if (strcmp(endOfSystemName, endOfPassedName) == 0) {1220 /* this is the actual component - remember it */1221 imageid = info.id;1222 break;1223 }1224 }1225 1226 } else {1227 /* we failed to load the "stub" - try to load the1228 component directly as an add-on */1229 stubid = B_ERROR;1230 imageid = load_add_on(name);1231 }1232 }1233 1234 if (imageid <= B_ERROR) {1235 oserr = imageid;1236 PR_DELETE( lm );1237 goto unlock;1238 }1239 lm->name = strdup(name);1240 lm->dlh = (void*)imageid;1241 lm->stub_dlh = (void*)stubid;1242 lm->next = pr_loadmap;1243 pr_loadmap = lm;1244 }1245 #endif1246 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */1247 1248 363 result = lm; /* success */ 1249 364 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", lm->name)); … … 1270 385 } 1271 386 1272 1273 #ifdef XP_MAC1274 1275 static PRLibrary*1276 pr_Mac_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName)1277 {1278 PRLibrary* newLib = NULL;1279 PRLibrary* result;1280 FSSpec resolvedSpec = *fileSpec;1281 CFragConnectionID connectionID = 0;1282 Boolean isFolder, wasAlias;1283 OSErr err = noErr;1284 1285 if (!_pr_initialized) _PR_ImplicitInitialization();1286 1287 /* See if library is already loaded */1288 PR_EnterMonitor(pr_linker_lock);1289 1290 result = pr_UnlockedFindLibrary(fragmentName);1291 if (result != NULL) goto unlock;1292 1293 newLib = PR_NEWZAP(PRLibrary);1294 if (newLib == NULL) goto unlock;1295 newLib->staticTable = NULL;1296 1297 1298 /* Resolve an alias if this was one */1299 err = ResolveAliasFile(&resolvedSpec, true, &isFolder, &wasAlias);1300 if (err != noErr)1301 goto unlock;1302 1303 if (isFolder)1304 {1305 err = fnfErr;1306 goto unlock;1307 }1308 1309 /* Finally, try to load the library */1310 err = NSLoadNamedFragment(&resolvedSpec, fragmentName, &connectionID);1311 if (err != noErr)1312 goto unlock;1313 1314 newLib->name = strdup(fragmentName);1315 newLib->connection = connectionID;1316 newLib->next = pr_loadmap;1317 pr_loadmap = newLib;1318 1319 result = newLib; /* success */1320 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", newLib->name));1321 1322 unlock:1323 if (result == NULL) {1324 if (newLib != NULL)1325 PR_DELETE(newLib);1326 PR_SetError(PR_LOAD_LIBRARY_ERROR, _MD_ERRNO());1327 DLLErrorInternal(_MD_ERRNO()); /* sets error text */1328 }1329 PR_ExitMonitor(pr_linker_lock);1330 return result;1331 }1332 1333 1334 static PRLibrary*1335 pr_Mac_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex)1336 {1337 PRLibrary* newLib = NULL;1338 PRLibrary* result;1339 FSSpec resolvedSpec = *fileSpec;1340 char* fragmentName = NULL;1341 UInt32 fragOffset, fragLength;1342 CFragConnectionID connectionID = 0;1343 Boolean isFolder, wasAlias;1344 OSErr err = noErr;1345 1346 if (!_pr_initialized) _PR_ImplicitInitialization();1347 1348 /* See if library is already loaded */1349 PR_EnterMonitor(pr_linker_lock);1350 1351 /* Resolve an alias if this was one */1352 err = ResolveAliasFile(&resolvedSpec, true, &isFolder, &wasAlias);1353 if (err != noErr)1354 goto unlock;1355 1356 if (isFolder)1357 {1358 err = fnfErr;1359 goto unlock;1360 }1361 err = GetIndexedFragmentOffsets(&resolvedSpec, fragIndex, &fragOffset, &fragLength, &fragmentName);1362 if (err != noErr) goto unlock;1363 1364 result = pr_UnlockedFindLibrary(fragmentName);1365 free(fragmentName);1366 fragmentName = NULL;1367 if (result != NULL) goto unlock;1368 1369 newLib = PR_NEWZAP(PRLibrary);1370 if (newLib == NULL) goto unlock;1371 newLib->staticTable = NULL;1372 1373 /* Finally, try to load the library */1374 err = NSLoadIndexedFragment(&resolvedSpec, fragIndex, &fragmentName, &connectionID);1375 if (err != noErr) {1376 PR_DELETE(newLib);1377 goto unlock;1378 }1379 1380 newLib->name = fragmentName; /* was malloced in NSLoadIndexedFragment */1381 newLib->connection = connectionID;1382 newLib->next = pr_loadmap;1383 pr_loadmap = newLib;1384 1385 result = newLib; /* success */1386 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", newLib->name));1387 1388 unlock:1389 if (result == NULL) {1390 if (newLib != NULL)1391 PR_DELETE(newLib);1392 PR_SetError(PR_LOAD_LIBRARY_ERROR, _MD_ERRNO());1393 DLLErrorInternal(_MD_ERRNO()); /* sets error text */1394 }1395 PR_ExitMonitor(pr_linker_lock);1396 return result;1397 }1398 1399 1400 #endif1401 387 1402 388 /* … … 1422 408 } 1423 409 1424 #ifdef VBOX_USE_MORE_IPRT_IN_NSPR1425 410 result = RTLdrClose(lib->dlh); 1426 411 lib->dlh = NIL_RTLDRMOD; 1427 1428 #else /* !VBOX_USE_MORE_IPRT_IN_NSPR */1429 #ifdef XP_BEOS1430 if(((image_id)lib->stub_dlh) == B_ERROR)1431 unload_add_on( (image_id) lib->dlh );1432 else1433 unload_add_on( (image_id) lib->stub_dlh);1434 #endif1435 1436 #ifdef XP_UNIX1437 #ifdef HAVE_DLL1438 #ifdef USE_DLFCN1439 result = dlclose(lib->dlh);1440 #elif defined(USE_HPSHL)1441 result = shl_unload(lib->dlh);1442 #elif defined(USE_MACH_DYLD)1443 result = NSUnLinkModule(lib->dlh, NSUNLINKMODULE_OPTION_NONE) ? 0 : -1;1444 #else1445 #error Configuration error1446 #endif1447 #endif /* HAVE_DLL */1448 #endif /* XP_UNIX */1449 #ifdef XP_PC1450 if (lib->dlh) {1451 FreeLibrary((HINSTANCE)(lib->dlh));1452 lib->dlh = (HINSTANCE)NULL;1453 }1454 #endif /* XP_PC */1455 1456 #if defined(XP_MAC) || defined(XP_MACOSX)1457 /* Close the connection */1458 if (lib->connection)1459 CloseConnection(&(lib->connection));1460 #if TARGET_CARBON1461 if (lib->bundle)1462 CFRelease(lib->bundle);1463 #endif1464 #if defined(XP_MACOSX)1465 if (lib->wrappers)1466 CFRelease(lib->wrappers);1467 /* No way to unload an image (lib->image) */1468 #endif1469 #endif1470 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */1471 412 1472 413 /* unlink from library search list */ … … 1501 442 freeLib: 1502 443 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Unloaded library %s", lib->name)); 1503 #ifdef VBOX_USE_IPRT_IN_NSPR1504 444 RTStrFree(lib->name); 1505 #else 1506 free(lib->name); 1507 #endif 445 1508 446 lib->name = NULL; 1509 447 PR_DELETE(lib); … … 1523 461 { 1524 462 void *f = NULL; 1525 #ifdef XP_OS2 1526 int rc; 1527 #endif 1528 1529 if (lm->staticTable != NULL) { 1530 const PRStaticLinkTable* tp; 1531 for (tp = lm->staticTable; tp->name; tp++) { 1532 if (strcmp(name, tp->name) == 0) { 1533 return (void*) tp->fp; 1534 } 1535 } 1536 /* 1537 ** If the symbol was not found in the static table then check if 1538 ** the symbol was exported in the DLL... Win16 only!! 1539 */ 1540 #if !defined(WIN16) && !defined(XP_BEOS) 1541 PR_SetError(PR_FIND_SYMBOL_ERROR, 0); 1542 return (void*)NULL; 1543 #endif 1544 } 1545 1546 #ifdef VBOX_USE_MORE_IPRT_IN_NSPR 463 1547 464 if (RT_FAILURE(RTLdrGetSymbol(lm->dlh, name, &f))) 1548 465 f = NULL; 1549 466 1550 #else /* !VBOX_USE_MORE_IPRT_IN_NSPR */1551 #ifdef XP_OS21552 rc = DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);1553 #if defined(NEED_LEADING_UNDERSCORE)1554 /*1555 * Older plugins (not built using GCC) will have symbols that are not1556 * underscore prefixed. We check for that here.1557 */1558 if (rc != NO_ERROR) {1559 name++;1560 DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);1561 }1562 #endif1563 #endif /* XP_OS2 */1564 1565 #if defined(WIN32) || defined(WIN16)1566 f = GetProcAddress(lm->dlh, name);1567 #endif /* WIN32 || WIN16 */1568 1569 #if defined(XP_MAC) || defined(XP_MACOSX)1570 #if defined(NEED_LEADING_UNDERSCORE)1571 #define SYM_OFFSET 11572 #else1573 #define SYM_OFFSET 01574 #endif1575 #if TARGET_CARBON1576 if (lm->bundle) {1577 CFStringRef nameRef = CFStringCreateWithCString(NULL, name + SYM_OFFSET, kCFStringEncodingASCII);1578 if (nameRef) {1579 f = CFBundleGetFunctionPointerForName(lm->bundle, nameRef);1580 CFRelease(nameRef);1581 }1582 }1583 #endif1584 if (lm->connection) {1585 Ptr symAddr;1586 CFragSymbolClass symClass;1587 Str255 pName;1588 1589 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Looking up symbol: %s", name + SYM_OFFSET));1590 1591 PStrFromCStr(name + SYM_OFFSET, pName);1592 1593 #if defined(XP_MACOSX)1594 f = (FindSymbol(lm->connection, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL;1595 #else1596 f = (NSFindSymbol(lm->connection, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL;1597 #endif1598 1599 #if defined(XP_MACOSX)1600 /* callers expect mach-o function pointers, so must wrap tvectors with glue. */1601 if (f && symClass == kTVectorCFragSymbol) {1602 f = TV2FP(lm->wrappers, name + SYM_OFFSET, f);1603 }1604 #endif1605 1606 if (f == NULL && strcmp(name + SYM_OFFSET, "main") == 0) f = lm->main;1607 }1608 #if defined(XP_MACOSX)1609 if (lm->image) {1610 NSSymbol symbol;1611 symbol = NSLookupSymbolInImage(lm->image, name,1612 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND1613 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);1614 if (symbol != NULL)1615 f = NSAddressOfSymbol(symbol);1616 else1617 f = NULL;1618 }1619 #endif1620 #undef SYM_OFFSET1621 #endif /* XP_MAC */1622 1623 #ifdef XP_BEOS1624 if( B_NO_ERROR != get_image_symbol( (image_id)lm->dlh, name, B_SYMBOL_TYPE_TEXT, &f ) ) {1625 f = NULL;1626 }1627 #endif1628 1629 #ifdef XP_UNIX1630 #ifdef HAVE_DLL1631 #ifdef USE_DLFCN1632 f = dlsym(lm->dlh, name);1633 #elif defined(USE_HPSHL)1634 if (shl_findsym(&lm->dlh, name, TYPE_PROCEDURE, &f) == -1) {1635 f = NULL;1636 }1637 #elif defined(USE_MACH_DYLD)1638 if (lm->dlh) {1639 NSSymbol symbol;1640 symbol = NSLookupSymbolInModule(lm->dlh, name);1641 if (symbol != NULL)1642 f = NSAddressOfSymbol(symbol);1643 else1644 f = NULL;1645 }1646 #endif1647 #endif /* HAVE_DLL */1648 #endif /* XP_UNIX */1649 #endif /* !VBOX_USE_MORE_IPRT_IN_NSPR */1650 467 if (f == NULL) { 1651 468 PR_SetError(PR_FIND_SYMBOL_ERROR, _MD_ERRNO()); … … 1662 479 { 1663 480 void *f = NULL; 1664 #if defined(NEED_LEADING_UNDERSCORE)1665 char *name;1666 #else1667 481 const char *name; 1668 #endif 1669 /* 1670 ** Mangle the raw symbol name in any way that is platform specific. 1671 */ 1672 #if defined(NEED_LEADING_UNDERSCORE) 1673 /* Need a leading _ */ 1674 name = PR_smprintf("_%s", raw_name); 1675 #elif defined(AIX) 1676 /* 1677 ** AIX with the normal linker put's a "." in front of the symbol 1678 ** name. When use "svcc" and "svld" then the "." disappears. Go 1679 ** figure. 1680 */ 482 1681 483 name = raw_name; 1682 #else1683 name = raw_name;1684 #endif1685 484 1686 485 PR_EnterMonitor(pr_linker_lock); … … 1688 487 f = pr_FindSymbolInLib(lib, name); 1689 488 1690 #if defined(NEED_LEADING_UNDERSCORE)1691 PR_smprintf_free(name);1692 #endif1693 1694 489 PR_ExitMonitor(pr_linker_lock); 1695 490 return f; … … 1709 504 { 1710 505 void *f = NULL; 1711 #if defined(NEED_LEADING_UNDERSCORE)1712 char *name;1713 #else1714 506 const char *name; 1715 #endif1716 507 PRLibrary* lm; 1717 508 1718 509 if (!_pr_initialized) _PR_ImplicitInitialization(); 1719 /* 1720 ** Mangle the raw symbol name in any way that is platform specific. 1721 */ 1722 #if defined(NEED_LEADING_UNDERSCORE) 1723 /* Need a leading _ */ 1724 name = PR_smprintf("_%s", raw_name); 1725 #elif defined(AIX) 1726 /* 1727 ** AIX with the normal linker put's a "." in front of the symbol 1728 ** name. When use "svcc" and "svld" then the "." disappears. Go 1729 ** figure. 1730 */ 510 1731 511 name = raw_name; 1732 #else1733 name = raw_name;1734 #endif1735 512 1736 513 PR_EnterMonitor(pr_linker_lock); … … 1748 525 } 1749 526 } 1750 #if defined(NEED_LEADING_UNDERSCORE)1751 PR_smprintf_free(name);1752 #endif1753 527 1754 528 PR_ExitMonitor(pr_linker_lock); 1755 529 return f; 1756 }1757 1758 PR_IMPLEMENT(PRFuncPtr)1759 PR_FindFunctionSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)1760 {1761 return ((PRFuncPtr) PR_FindSymbolAndLibrary(raw_name, lib));1762 }1763 1764 /*1765 ** Add a static library to the list of loaded libraries. If LoadLibrary1766 ** is called with the name then we will pretend it was already loaded1767 */1768 PR_IMPLEMENT(PRLibrary*)1769 PR_LoadStaticLibrary(const char *name, const PRStaticLinkTable *slt)1770 {1771 PRLibrary *lm=NULL;1772 PRLibrary* result = NULL;1773 1774 if (!_pr_initialized) _PR_ImplicitInitialization();1775 1776 /* See if library is already loaded */1777 PR_EnterMonitor(pr_linker_lock);1778 1779 /* If the lbrary is already loaded, then add the static table information... */1780 result = pr_UnlockedFindLibrary(name);1781 if (result != NULL) {1782 PR_ASSERT( (result->staticTable == NULL) || (result->staticTable == slt) );1783 result->staticTable = slt;1784 goto unlock;1785 }1786 1787 /* Add library to list...Mark it static */1788 lm = PR_NEWZAP(PRLibrary);1789 if (lm == NULL) goto unlock;1790 1791 lm->name = strdup(name);1792 lm->refCount = 1;1793 #if defined(XP_MAC) && !defined(VBOX_USE_MORE_IPRT_IN_NSPR)1794 lm->connection = pr_exe_loadmap ? pr_exe_loadmap->connection : 0;1795 #else1796 lm->dlh = pr_exe_loadmap ? pr_exe_loadmap->dlh : 0;1797 #endif1798 lm->staticTable = slt;1799 lm->next = pr_loadmap;1800 pr_loadmap = lm;1801 1802 result = lm; /* success */1803 PR_ASSERT(lm->refCount == 1);1804 unlock:1805 PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (static lib)", lm->name));1806 PR_ExitMonitor(pr_linker_lock);1807 return result;1808 530 } 1809 531 … … 1842 564 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); 1843 565 return NULL; 1844 #elif defined(AIX)1845 char *result;1846 #define LD_INFO_INCREMENT 641847 struct ld_info *info;1848 unsigned int info_length = LD_INFO_INCREMENT * sizeof(struct ld_info);1849 struct ld_info *infop;1850 1851 for (;;) {1852 info = PR_Malloc(info_length);1853 if (info == NULL) {1854 return NULL;1855 }1856 /* If buffer is too small, loadquery fails with ENOMEM. */1857 if (loadquery(L_GETINFO, info, info_length) != -1) {1858 break;1859 }1860 PR_Free(info);1861 if (errno != ENOMEM) {1862 /* should not happen */1863 _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());1864 return NULL;1865 }1866 /* retry with a larger buffer */1867 info_length += LD_INFO_INCREMENT * sizeof(struct ld_info);1868 }1869 1870 for (infop = info;1871 ;1872 infop = (struct ld_info *)((char *)infop + infop->ldinfo_next)) {1873 if (strstr(infop->ldinfo_filename, name) != NULL) {1874 result = PR_Malloc(strlen(infop->ldinfo_filename)+1);1875 if (result != NULL) {1876 strcpy(result, infop->ldinfo_filename);1877 }1878 break;1879 }1880 if (!infop->ldinfo_next) {1881 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);1882 result = NULL;1883 break;1884 }1885 }1886 PR_Free(info);1887 return result;1888 #elif defined(OSF1)1889 /* Contributed by Steve Streeter of HP */1890 ldr_process_t process, ldr_my_process();1891 ldr_module_t mod_id;1892 ldr_module_info_t info;1893 ldr_region_t regno;1894 ldr_region_info_t reginfo;1895 size_t retsize;1896 int rv;1897 char *result;1898 1899 /* Get process for which dynamic modules will be listed */1900 1901 process = ldr_my_process();1902 1903 /* Attach to process */1904 1905 rv = ldr_xattach(process);1906 if (rv) {1907 /* should not happen */1908 _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());1909 return NULL;1910 }1911 1912 /* Print information for list of modules */1913 1914 mod_id = LDR_NULL_MODULE;1915 1916 for (;;) {1917 1918 /* Get information for the next module in the module list. */1919 1920 ldr_next_module(process, &mod_id);1921 if (ldr_inq_module(process, mod_id, &info, sizeof(info),1922 &retsize) != 0) {1923 /* No more modules */1924 break;1925 }1926 if (retsize < sizeof(info)) {1927 continue;1928 }1929 1930 /*1931 * Get information for each region in the module and check if any1932 * contain the address of this function.1933 */1934 1935 for (regno = 0; ; regno++) {1936 if (ldr_inq_region(process, mod_id, regno, ®info,1937 sizeof(reginfo), &retsize) != 0) {1938 /* No more regions */1939 break;1940 }1941 if (((unsigned long)reginfo.lri_mapaddr <=1942 (unsigned long)addr) &&1943 (((unsigned long)reginfo.lri_mapaddr + reginfo.lri_size) >1944 (unsigned long)addr)) {1945 /* Found it. */1946 result = PR_Malloc(strlen(info.lmi_name)+1);1947 if (result != NULL) {1948 strcpy(result, info.lmi_name);1949 }1950 return result;1951 }1952 }1953 }1954 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);1955 return NULL;1956 #elif defined(VMS)1957 /* Contributed by Colin Blake of HP */1958 struct _imcb *icb;1959 ulong_t status;1960 char device_name[MAX_DEVNAM];1961 int device_name_len;1962 $DESCRIPTOR (device_name_desc, device_name);1963 struct fibdef fib;1964 struct dsc$descriptor_s fib_desc =1965 { sizeof(struct fibdef), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *)&fib } ;1966 IOSB iosb;1967 ITMLST devlst[2] = {1968 {MAX_DEVNAM, DVI$_ALLDEVNAM, device_name, &device_name_len},1969 {0,0,0,0}};1970 short file_name_len;1971 char file_name[MAX_FILNAM+1];1972 char *result = NULL;1973 struct dsc$descriptor_s file_name_desc =1974 { MAX_FILNAM, DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &file_name[0] } ;1975 1976 /*1977 ** The address for the process image list could change in future versions1978 ** of the operating system. 7FFD0688 is valid for V7.2 and V7.3 releases,1979 ** so we use that for the default, but allow an environment variable1980 ** (logical name) to override.1981 */1982 if (IAC$GL_IMAGE_LIST == NULL) {1983 char *p = getenv("MOZILLA_IAC_GL_IMAGE_LIST");1984 if (p)1985 IAC$GL_IMAGE_LIST = (struct _imcb *) strtol(p,NULL,0);1986 else1987 IAC$GL_IMAGE_LIST = (struct _imcb *) 0x7FFD0688;1988 }1989 1990 for (icb = IAC$GL_IMAGE_LIST->imcb$l_flink;1991 icb != IAC$GL_IMAGE_LIST;1992 icb = icb->imcb$l_flink) {1993 if (((void *)addr >= icb->imcb$l_starting_address) &&1994 ((void *)addr <= icb->imcb$l_end_address)) {1995 /*1996 ** This is the correct image.1997 ** Get the device name.1998 */1999 status = sys$getdviw(0,icb->imcb$w_chan,0,&devlst,0,0,0,0);2000 if ($VMS_STATUS_SUCCESS(status))2001 device_name_desc.dsc$w_length = device_name_len;2002 2003 /*2004 ** Get the FID.2005 */2006 memset(&fib,0,sizeof(struct fibdef));2007 status = sys$qiow(0,icb->imcb$w_chan,IO$_ACCESS,&iosb,2008 0,0,&fib_desc,0,0,0,0,0);2009 2010 /*2011 ** If we got the FID, now look up its name (if for some reason2012 ** we didn't get the device name, this call will fail).2013 */2014 if (($VMS_STATUS_SUCCESS(status)) && ($VMS_STATUS_SUCCESS(iosb.cond))) {2015 status = lib$fid_to_name (2016 &device_name_desc,2017 &fib.fib$w_fid,2018 &file_name_desc,2019 &file_name_len,2020 0, 0);2021 2022 /*2023 ** If we succeeded then remove the version number and2024 ** return a copy of the UNIX format version of the file name.2025 */2026 if ($VMS_STATUS_SUCCESS(status)) {2027 char *p, *result;2028 file_name[file_name_len] = 0;2029 p = strrchr(file_name,';');2030 if (p) *p = 0;2031 p = decc$translate_vms(&file_name[0]);2032 result = PR_Malloc(strlen(p)+1);2033 if (result != NULL) {2034 strcpy(result, p);2035 }2036 return result;2037 }2038 }2039 }2040 }2041 2042 /* Didn't find it */2043 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);2044 return NULL;2045 2046 #elif defined(HPUX) && defined(USE_HPSHL)2047 int index;2048 struct shl_descriptor desc;2049 char *result;2050 2051 for (index = 0; shl_get_r(index, &desc) == 0; index++) {2052 if (strstr(desc.filename, name) != NULL) {2053 result = PR_Malloc(strlen(desc.filename)+1);2054 if (result != NULL) {2055 strcpy(result, desc.filename);2056 }2057 return result;2058 }2059 }2060 /*2061 * Since the index value of a library is decremented if2062 * a library preceding it in the shared library search2063 * list was unloaded, it is possible that we missed some2064 * libraries as we went up the list. So we should go2065 * down the list to be sure that we not miss anything.2066 */2067 for (index--; index >= 0; index--) {2068 if ((shl_get_r(index, &desc) == 0)2069 && (strstr(desc.filename, name) != NULL)) {2070 result = PR_Malloc(strlen(desc.filename)+1);2071 if (result != NULL) {2072 strcpy(result, desc.filename);2073 }2074 return result;2075 }2076 }2077 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);2078 return NULL;2079 #elif defined(HPUX) && defined(USE_DLFCN)2080 struct load_module_desc desc;2081 char *result;2082 const char *module_name;2083 2084 if (dlmodinfo((unsigned long)addr, &desc, sizeof desc, NULL, 0, 0) == 0) {2085 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());2086 DLLErrorInternal(_MD_ERRNO());2087 return NULL;2088 }2089 module_name = dlgetname(&desc, sizeof desc, NULL, 0, 0);2090 if (module_name == NULL) {2091 /* should not happen */2092 _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());2093 DLLErrorInternal(_MD_ERRNO());2094 return NULL;2095 }2096 result = PR_Malloc(strlen(module_name)+1);2097 if (result != NULL) {2098 strcpy(result, module_name);2099 }2100 return result;2101 #elif defined(WIN32)2102 HMODULE handle;2103 char module_name[MAX_PATH];2104 char *result;2105 2106 handle = GetModuleHandle(name);2107 if (handle == NULL) {2108 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());2109 DLLErrorInternal(_MD_ERRNO());2110 return NULL;2111 }2112 if (GetModuleFileName(handle, module_name, sizeof module_name) == 0) {2113 /* should not happen */2114 _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());2115 return NULL;2116 }2117 result = PR_Malloc(strlen(module_name)+1);2118 if (result != NULL) {2119 strcpy(result, module_name);2120 }2121 return result;2122 #elif defined(XP_OS2)2123 HMODULE module = NULL;2124 char module_name[_MAX_PATH];2125 char *result;2126 APIRET ulrc = DosQueryModFromEIP(&module, NULL, 0, NULL, NULL, (ULONG) addr);2127 if ((NO_ERROR != ulrc) || (NULL == module) ) {2128 PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());2129 DLLErrorInternal(_MD_ERRNO());2130 return NULL;2131 }2132 ulrc = DosQueryModuleName(module, sizeof module_name, module_name);2133 if (NO_ERROR != ulrc) {2134 /* should not happen */2135 _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());2136 return NULL;2137 }2138 result = PR_Malloc(strlen(module_name)+1);2139 if (result != NULL) {2140 strcpy(result, module_name);2141 }2142 return result;2143 566 #else 2144 567 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
Note:
See TracChangeset
for help on using the changeset viewer.