dynamic loading for aix fixed
authorClaus Gittinger <cg@exept.de>
Mon, 29 Jul 1996 16:32:28 +0200
changeset 321 9428bae4c62e
parent 320 54bfd6fd28b9
child 322 a844e84b16fd
dynamic loading for aix fixed
ObjFLoader.st
ObjectFileLoader.st
--- a/ObjFLoader.st	Fri Jul 26 22:58:38 1996 +0200
+++ b/ObjFLoader.st	Mon Jul 29 16:32:28 1996 +0200
@@ -14,7 +14,7 @@
 	instanceVariableNames:''
 	classVariableNames:'MySymbolTable Verbose LastError LinkErrorMessage NextHandleID
 		LoadedObjects PreviouslyLoadedObjects ActuallyLoadedObjects
-		SearchedLibraries'
+		SearchedLibraries LibPath'
 	poolDictionaries:''
 	category:'System-Compiler'
 !
@@ -239,7 +239,7 @@
 
         "/ default set of libraries to be considered when
         "/ unresolved symbols are encountered during the load.
-        "/ only req'd for linux and sunos non-ELF systems.
+        "/ Only req'd for linux and sunos non-ELF systems.
         "/ Can (should) be set in the smalltalk.rc file.
 
         SearchedLibraries := #().
@@ -254,6 +254,21 @@
                 ]
             ]
         ].
+
+	"/ default libraryPath where shared objects are expected
+	"/ when a sharedObject load requires other objects to be loaded.
+	"/ Only req'd for aix.
+	"/ For more compatibility with ELF systems, look for a shell variable
+	"/ named LD_LIBRARY_PATH, and - if present - take that instead if a default.
+	"/ Can (should) be set in the smalltalk.rc file.
+
+	systemType = 'aix' ifTrue:[
+	    LibPath := OperatingSystem getEnvironment:'LD_LIBRARY_PATH'.
+	    LibPath isNil ifTrue:[
+	        LibPath := '.:/usr/local/smalltalk/lib:/usr/local/lib:/usr/lib:/lib'.
+	    ]
+	].
+
     ]
 
     "
@@ -267,6 +282,27 @@
     ^ LastError
 !
 
+libPath
+    "see comment in #libPath:"
+
+    ^ LibPath
+!
+
+libPath:aSharedLibraryPath
+    "set the pathnames of directories, where other shared objects
+     are searched, in case a loaded module requires another module shared
+     library object to be loaded.
+     Currently, this is only required to be set for AIX systems;
+     ELF based linux and solaris systems specify the libPath in the 
+     LD_LIBRARY_PATH environment variable."
+
+    LibPath := aSharedLibraryPath
+
+    "
+     ObjectFileLoader libPath:'.:/usr/lib:/usr/local/lib'
+    "
+!
+
 linkErrorMessage
     ^ LinkErrorMessage
 !
@@ -286,7 +322,7 @@
      shared libraries. The dynamic loader then cares about loading those
      modules (keeping track of which modules are already loaded).
      Only systems in which the dynamic load is done 'manually' by st/x
-     (i.e. currently only linux) need to set this."
+     (i.e. currently only linux and a.out-sunos) need to set this."
 
     SearchedLibraries := aCollectionOfArchivePathNames
 !
@@ -560,11 +596,6 @@
         "try with added underscore"
         symName := '__' , aClassName , '_Init'.
         initAddr := self getFunction:symName from:handle.
-        initAddr isNil ifTrue:[
-            "try with added period (AIX)"
-            symName := '._' , aClassName , '_Init'.
-            initAddr := self getFunction:symName from:handle.
-        ]
     ].
 
     knownToBeOk := true.
@@ -1032,14 +1063,7 @@
      Handle must be the one returned previously from loadDynamicObject.
      Return the address of the function, or nil on any error."
 
-    |fName|
-
-    OperatingSystem getSystemType = 'aix' ifTrue:[
-	fName := '.' , aString 
-    ] ifFalse:[
-	fName := aString
-    ].
-    ^ self getSymbol:fName function:true from:handle
+    ^ self getSymbol:aString function:true from:handle
 !
 
 getListOfUndefinedSymbolsFrom:aHandle
@@ -1273,10 +1297,16 @@
     int val;
     struct nlist nl[2];
     OBJ low = sysHandle1, hi = sysHandle2;
+    char nameBuffer[256];
+    static struct funcDescriptor {
+	unsigned vaddr;
+	unsigned long2;
+	unsigned long3;
+    } descriptor;
 
     if (__bothSmallInteger(low, hi)
      && __isString(aString) && __isString(pathName)) {
-	val = (_intVal(hi) << 16) + _intVal(low);
+	val = (__intVal(hi) << 16) + __intVal(low);
 	h = (void *)(val);
 
 	if (ObjectFileLoader_Verbose == true) {
@@ -1284,7 +1314,29 @@
 			__stringVal(aString), h, __stringVal(pathName));
 	}
 
-	nl[0].n_name = __stringVal(aString);
+#define USE_ENTRY
+#ifdef USE_ENTRY
+	/*
+	 * only works, if the entry-function is the Init function
+	 * (i.e. linked with -e _xxx_Init)
+	 */
+	if (ObjectFileLoader_Verbose == true) {
+	    printf("return handle as addr = %x\n", h);
+	}
+	address = __MKUINT( (int)(h) );
+#else
+
+# ifdef USE_DESCRIPTOR
+	if (isFunction == true) {
+# else
+	if (0) {
+# endif
+	    nameBuffer[0] = '.';
+	    strcpy(nameBuffer+1, aString);
+	    nl[0].n_name = nameBuffer;
+	} else {
+	    nl[0].n_name = __stringVal(aString);
+	}
 	nl[1].n_name = "";
 
 	if (nlist(__stringVal(pathName), &nl) == -1) {
@@ -1294,17 +1346,33 @@
 	} else {
 	    addr = (void *)((unsigned)nl[0].n_value + (unsigned)h);
 
+	    if (isFunction == true) {
+# ifdef USE_DESCRIPTOR
+		printf("daddr = %x\n", addr);
+		printf("daddr[0] = %x\n", ((long *)addr)[0]);
+		printf("daddr[1] = %x\n", ((long *)addr)[1]);
+		printf("daddr[2] = %x\n", ((long *)addr)[2]);
+# endif
+	    }
+
 	    if (ObjectFileLoader_Verbose == true) {
 		printf("value=%x section=%d type=%x sclass=%d\n", 
 			nl[0].n_value, nl[0].n_scnum, nl[0].n_type, nl[0].n_sclass);
-		printf("addr = %x\n", addr);
+		printf("vaddr = %x\n", addr);
 	    }
-
+# ifdef DOES_NOT_WORK
 	    address = __MKUINT( (int)addr );
+# else
+	    descriptor.vaddr = (unsigned) addr;
+	    descriptor.long2 = 0;
+	    descriptor.long3 = 0;
+	    address = __MKUINT( (int)(&descriptor) );
+# endif
 	}
+#endif /* dont USE_ENTRY */
     }
   }
-#endif
+#endif /* AIX_DL */
 
 #ifdef SUN_DL
   {
@@ -1693,18 +1761,25 @@
 #ifdef AIX_DL
   {
     extern char *__myName__;
-    char *ldname;
+    char *objName, *libPath;
     int *handle;
     extern errno;
 
     if (__isString(pathName)) {
-	if ( (handle = (int *) load(__stringVal(pathName), 0, 0)) == 0 ) {
+	objName = __stringVal(pathName);
+
+	if (__isString(@global(LibPath))) {
+	    libPath = __stringVal(@global(LibPath));
+	} else {
+	    libPath = (char *)0;
+	}
+	if ( (handle = (int *) load(objName, 0, libPath)) == 0 ) {
 	    if (ObjectFileLoader_Verbose == true) {
 		char *messages[64];
 		int i;
 
 		printf ("load file %s failed errno=%d\n", 
-				__stringVal(pathName), errno);
+				objName, errno);
 		switch (errno) {
 		    case ENOEXEC:
 			printf("   load messages:\n");
@@ -1718,7 +1793,7 @@
 	    RETURN ( nil );
 	}
 	if (ObjectFileLoader_Verbose == true) {
-	    printf("load %s handle = %x\n", __stringVal(pathName), handle);
+	    printf("load %s handle = %x\n", objName, handle);
 	}
 
 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (int)handle & 0xFFFF );
@@ -2825,6 +2900,6 @@
 !ObjectFileLoader  class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/Attic/ObjFLoader.st,v 1.106 1996-07-26 20:58:38 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/Attic/ObjFLoader.st,v 1.107 1996-07-29 14:32:28 cg Exp $'
 ! !
 ObjectFileLoader initialize!
--- a/ObjectFileLoader.st	Fri Jul 26 22:58:38 1996 +0200
+++ b/ObjectFileLoader.st	Mon Jul 29 16:32:28 1996 +0200
@@ -14,7 +14,7 @@
 	instanceVariableNames:''
 	classVariableNames:'MySymbolTable Verbose LastError LinkErrorMessage NextHandleID
 		LoadedObjects PreviouslyLoadedObjects ActuallyLoadedObjects
-		SearchedLibraries'
+		SearchedLibraries LibPath'
 	poolDictionaries:''
 	category:'System-Compiler'
 !
@@ -239,7 +239,7 @@
 
         "/ default set of libraries to be considered when
         "/ unresolved symbols are encountered during the load.
-        "/ only req'd for linux and sunos non-ELF systems.
+        "/ Only req'd for linux and sunos non-ELF systems.
         "/ Can (should) be set in the smalltalk.rc file.
 
         SearchedLibraries := #().
@@ -254,6 +254,21 @@
                 ]
             ]
         ].
+
+	"/ default libraryPath where shared objects are expected
+	"/ when a sharedObject load requires other objects to be loaded.
+	"/ Only req'd for aix.
+	"/ For more compatibility with ELF systems, look for a shell variable
+	"/ named LD_LIBRARY_PATH, and - if present - take that instead if a default.
+	"/ Can (should) be set in the smalltalk.rc file.
+
+	systemType = 'aix' ifTrue:[
+	    LibPath := OperatingSystem getEnvironment:'LD_LIBRARY_PATH'.
+	    LibPath isNil ifTrue:[
+	        LibPath := '.:/usr/local/smalltalk/lib:/usr/local/lib:/usr/lib:/lib'.
+	    ]
+	].
+
     ]
 
     "
@@ -267,6 +282,27 @@
     ^ LastError
 !
 
+libPath
+    "see comment in #libPath:"
+
+    ^ LibPath
+!
+
+libPath:aSharedLibraryPath
+    "set the pathnames of directories, where other shared objects
+     are searched, in case a loaded module requires another module shared
+     library object to be loaded.
+     Currently, this is only required to be set for AIX systems;
+     ELF based linux and solaris systems specify the libPath in the 
+     LD_LIBRARY_PATH environment variable."
+
+    LibPath := aSharedLibraryPath
+
+    "
+     ObjectFileLoader libPath:'.:/usr/lib:/usr/local/lib'
+    "
+!
+
 linkErrorMessage
     ^ LinkErrorMessage
 !
@@ -286,7 +322,7 @@
      shared libraries. The dynamic loader then cares about loading those
      modules (keeping track of which modules are already loaded).
      Only systems in which the dynamic load is done 'manually' by st/x
-     (i.e. currently only linux) need to set this."
+     (i.e. currently only linux and a.out-sunos) need to set this."
 
     SearchedLibraries := aCollectionOfArchivePathNames
 !
@@ -560,11 +596,6 @@
         "try with added underscore"
         symName := '__' , aClassName , '_Init'.
         initAddr := self getFunction:symName from:handle.
-        initAddr isNil ifTrue:[
-            "try with added period (AIX)"
-            symName := '._' , aClassName , '_Init'.
-            initAddr := self getFunction:symName from:handle.
-        ]
     ].
 
     knownToBeOk := true.
@@ -1032,14 +1063,7 @@
      Handle must be the one returned previously from loadDynamicObject.
      Return the address of the function, or nil on any error."
 
-    |fName|
-
-    OperatingSystem getSystemType = 'aix' ifTrue:[
-	fName := '.' , aString 
-    ] ifFalse:[
-	fName := aString
-    ].
-    ^ self getSymbol:fName function:true from:handle
+    ^ self getSymbol:aString function:true from:handle
 !
 
 getListOfUndefinedSymbolsFrom:aHandle
@@ -1273,10 +1297,16 @@
     int val;
     struct nlist nl[2];
     OBJ low = sysHandle1, hi = sysHandle2;
+    char nameBuffer[256];
+    static struct funcDescriptor {
+	unsigned vaddr;
+	unsigned long2;
+	unsigned long3;
+    } descriptor;
 
     if (__bothSmallInteger(low, hi)
      && __isString(aString) && __isString(pathName)) {
-	val = (_intVal(hi) << 16) + _intVal(low);
+	val = (__intVal(hi) << 16) + __intVal(low);
 	h = (void *)(val);
 
 	if (ObjectFileLoader_Verbose == true) {
@@ -1284,7 +1314,29 @@
 			__stringVal(aString), h, __stringVal(pathName));
 	}
 
-	nl[0].n_name = __stringVal(aString);
+#define USE_ENTRY
+#ifdef USE_ENTRY
+	/*
+	 * only works, if the entry-function is the Init function
+	 * (i.e. linked with -e _xxx_Init)
+	 */
+	if (ObjectFileLoader_Verbose == true) {
+	    printf("return handle as addr = %x\n", h);
+	}
+	address = __MKUINT( (int)(h) );
+#else
+
+# ifdef USE_DESCRIPTOR
+	if (isFunction == true) {
+# else
+	if (0) {
+# endif
+	    nameBuffer[0] = '.';
+	    strcpy(nameBuffer+1, aString);
+	    nl[0].n_name = nameBuffer;
+	} else {
+	    nl[0].n_name = __stringVal(aString);
+	}
 	nl[1].n_name = "";
 
 	if (nlist(__stringVal(pathName), &nl) == -1) {
@@ -1294,17 +1346,33 @@
 	} else {
 	    addr = (void *)((unsigned)nl[0].n_value + (unsigned)h);
 
+	    if (isFunction == true) {
+# ifdef USE_DESCRIPTOR
+		printf("daddr = %x\n", addr);
+		printf("daddr[0] = %x\n", ((long *)addr)[0]);
+		printf("daddr[1] = %x\n", ((long *)addr)[1]);
+		printf("daddr[2] = %x\n", ((long *)addr)[2]);
+# endif
+	    }
+
 	    if (ObjectFileLoader_Verbose == true) {
 		printf("value=%x section=%d type=%x sclass=%d\n", 
 			nl[0].n_value, nl[0].n_scnum, nl[0].n_type, nl[0].n_sclass);
-		printf("addr = %x\n", addr);
+		printf("vaddr = %x\n", addr);
 	    }
-
+# ifdef DOES_NOT_WORK
 	    address = __MKUINT( (int)addr );
+# else
+	    descriptor.vaddr = (unsigned) addr;
+	    descriptor.long2 = 0;
+	    descriptor.long3 = 0;
+	    address = __MKUINT( (int)(&descriptor) );
+# endif
 	}
+#endif /* dont USE_ENTRY */
     }
   }
-#endif
+#endif /* AIX_DL */
 
 #ifdef SUN_DL
   {
@@ -1693,18 +1761,25 @@
 #ifdef AIX_DL
   {
     extern char *__myName__;
-    char *ldname;
+    char *objName, *libPath;
     int *handle;
     extern errno;
 
     if (__isString(pathName)) {
-	if ( (handle = (int *) load(__stringVal(pathName), 0, 0)) == 0 ) {
+	objName = __stringVal(pathName);
+
+	if (__isString(@global(LibPath))) {
+	    libPath = __stringVal(@global(LibPath));
+	} else {
+	    libPath = (char *)0;
+	}
+	if ( (handle = (int *) load(objName, 0, libPath)) == 0 ) {
 	    if (ObjectFileLoader_Verbose == true) {
 		char *messages[64];
 		int i;
 
 		printf ("load file %s failed errno=%d\n", 
-				__stringVal(pathName), errno);
+				objName, errno);
 		switch (errno) {
 		    case ENOEXEC:
 			printf("   load messages:\n");
@@ -1718,7 +1793,7 @@
 	    RETURN ( nil );
 	}
 	if (ObjectFileLoader_Verbose == true) {
-	    printf("load %s handle = %x\n", __stringVal(pathName), handle);
+	    printf("load %s handle = %x\n", objName, handle);
 	}
 
 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (int)handle & 0xFFFF );
@@ -2825,6 +2900,6 @@
 !ObjectFileLoader  class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/ObjectFileLoader.st,v 1.106 1996-07-26 20:58:38 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/ObjectFileLoader.st,v 1.107 1996-07-29 14:32:28 cg Exp $'
 ! !
 ObjectFileLoader initialize!