Bugzilla: 51655.
authorlarryh%netscape.com
Mon, 06 Nov 2000 23:27:49 +0000
changeset 1620 d4fe8fb52efb56eabe7b555fc21d2fc42171aab0
parent 1617 a34d3e5684436e19f87f885d78cc7f8b7b7ef591
child 1623 0df9f380f26228b17934c4b0d6e38ce76f6fd0cd
push idunknown
push userunknown
push dateunknown
bugs51655
Bugzilla: 51655.
pr/src/linking/prlink.c
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -791,27 +791,84 @@ pr_LoadLibraryByPathname(const char *nam
 
     lm->refCount = 1;
 
 #ifdef XP_BEOS
     {
 	image_info info;
 	int32 cookie = 0;
 	image_id h = B_ERROR;
+	PRLibrary *p;
 
-	while(get_next_image_info(0, &cookie, &info) == B_OK)
-		if(strcmp(name, info.name + strlen(info.name) - strlen(name)) == 0) {
+	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 */
 			h = info.id;
-			lm->refCount++;	/* it has been already loaded implcitly, so pretend it already had a control structure and ref */
+			lm->refCount++;
+			break;
 		}
+	}
 
-	if(h == B_ERROR)
-		h = load_add_on( name );
+	if(h == 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");
 
-	if( h == B_ERROR || h <= 0 ) {
+		/* first, attempt to load the stub (thereby loading the
+		   component as a shared library */
+		if ((h = load_add_on(stubName)) > B_ERROR) {
+			/* the stub was loaded successfully.  however, the stub
+			   itself is useless (so useless, in fact, that we will
+			   simply unload it) */
+			unload_add_on(h);
+			h = B_FILE_NOT_FOUND;
+
+			cookie = 0;
+			while (get_next_image_info(0, &cookie, &info) == B_OK) {
+				char *endOfName = info.name + strlen(info.name) - strlen(name);
+				if (endOfName < info.name)
+					continue;
+
+				if (strcmp(name, endOfName) == 0) {
+					/* this is the actual component - remember it */
+					h = info.id;
+					break;
+				}
+			}
+
+		} else {
+			/* we failed to load the "stub" - try to load the
+			   component directly as an add-on */
+			h = load_add_on(name);
+		}
+	}
+
+	if (h <= B_ERROR) {
 	    oserr = h;
 	    PR_DELETE( lm );
 	    goto unlock;
 	}
 	lm->name = strdup(name);
 	lm->dlh = (void*)h;
 	lm->next = pr_loadmap;
 	pr_loadmap = lm;