ObjectFileLoader.st
branchjv
changeset 4723 524785227024
parent 4651 0057186e74d6
parent 4635 d8c0804e23e3
equal deleted inserted replaced
4657:fceb50f108b6 4723:524785227024
   118 # ifndef dl_h
   118 # ifndef dl_h
   119 #  include <dl.h>
   119 #  include <dl.h>
   120 #  define dl_h
   120 #  define dl_h
   121 # endif
   121 # endif
   122 # include <errno.h>
   122 # include <errno.h>
   123 #endif
       
   124 
       
   125 #ifdef BEOS_DL
       
   126 # include <be/kernel/image.h>
       
   127 #endif
   123 #endif
   128 
   124 
   129 #ifdef WIN_DL
   125 #ifdef WIN_DL
   130 # undef INT
   126 # undef INT
   131 # undef UINT
   127 # undef UINT
   331 
   327 
   332     Verbose := false.
   328     Verbose := false.
   333     "/ Verbose := true.
   329     "/ Verbose := true.
   334 
   330 
   335     OperatingSystem isMSDOSlike ifTrue:[
   331     OperatingSystem isMSDOSlike ifTrue:[
   336 	"/ default setup for msc
       
   337 	ParserFlags useBorlandC ifTrue:[
   332 	ParserFlags useBorlandC ifTrue:[
       
   333 	    "/ default setup for bcc
   338 	    libDir := '..\lib\bc'.
   334 	    libDir := '..\lib\bc'.
   339 	    libDir asFilename exists ifFalse:[
   335 	    libDir asFilename exists ifFalse:[
   340 		libDir := '..\lib\lib\bc'.
   336 		libDir := '..\lib\lib\bc'.
   341 		libDir asFilename exists ifFalse:[
   337 		libDir asFilename exists ifFalse:[
   342 		    libDir := '..\lib'.
   338 		    libDir := '..\lib'.
   487 copyLibrariesWhenLoading
   483 copyLibrariesWhenLoading
   488     "under windows, a library file (dll) which has been loaded cannot be overwritten.
   484     "under windows, a library file (dll) which has been loaded cannot be overwritten.
   489      This makes it troublesome, to recompile a new lib while a smalltalk is being executed.
   485      This makes it troublesome, to recompile a new lib while a smalltalk is being executed.
   490      When CopyLibrariesWhenLoading is true, ddl files are copied to a tempdir before loading,
   486      When CopyLibrariesWhenLoading is true, ddl files are copied to a tempdir before loading,
   491      so that the original can still be recompiled.
   487      so that the original can still be recompiled.
   492      Makes loading a bit slower (due to copying and less sharing/caching of already loaded dlls),
   488      Makes loading a bit slower (due to the copying),
   493      so it is of by default and must be turned on explicitly during development."
   489      so it is off by default and must be turned on explicitly during development."
   494 
   490 
   495     ^ CopyLibrariesWhenLoading ? false
   491     ^ CopyLibrariesWhenLoading ? false
   496 
   492 
   497     "
   493     "
   498      self copyLibrariesWhenLoading
   494      self copyLibrariesWhenLoading
   499      self copyLibrariesWhenLoading:true
   495      self copyLibrariesWhenLoading:true
   500     "
   496     "
       
   497 
       
   498     "Modified (comment): / 22-07-2018 / 18:10:15 / Stefan Vogel"
   501 !
   499 !
   502 
   500 
   503 copyLibrariesWhenLoading:aBoolean
   501 copyLibrariesWhenLoading:aBoolean
   504     "under windows, a library file (dll) which has been loaded cannot be overwritten.
   502     "under windows, a library file (dll) which has been loaded cannot be overwritten.
   505      This makes it troublesome, to recompile a new lib while a smalltalk is being executed.
   503      This makes it troublesome, to recompile a new lib while a smalltalk is being executed.
   650     RETURN ( @symbol(coff));
   648     RETURN ( @symbol(coff));
   651 # endif
   649 # endif
   652 # if defined(WIN_DL)
   650 # if defined(WIN_DL)
   653     RETURN ( @symbol(dll));
   651     RETURN ( @symbol(dll));
   654 # endif
   652 # endif
   655 # if defined(BEOS_DL)
       
   656     RETURN ( @symbol(beobj));
       
   657 # endif
       
   658 # if defined(__VMS__)
   653 # if defined(__VMS__)
   659     RETURN ( @symbol(exe));
   654     RETURN ( @symbol(exe));
   660 # endif
   655 # endif
   661 # if defined(__osx__)
   656 # if defined(__osx__)
   662     RETURN ( @symbol(macho));
   657     RETURN ( @symbol(macho));
   695     ^ 'nm ' , file
   690     ^ 'nm ' , file
   696 
   691 
   697     "Modified: / 4.5.1998 / 12:18:47 / cg"
   692     "Modified: / 4.5.1998 / 12:18:47 / cg"
   698 !
   693 !
   699 
   694 
   700 objectFileExtension
   695 objectFileSuffix
   701     "return the fileName extension used for objects,
   696     "return the fileName extension used for objects,
   702      as generated by myself (output of cc).
   697      as generated by myself (output of cc).
   703      This is very machine specific."
   698      This is very machine specific."
   704 
   699 
   705     OperatingSystem isMSDOSlike ifTrue:[
   700     OperatingSystem isMSDOSlike ifTrue:[
   706 	"/ includes all of win32s, win95, winNT & os/2
   701 	"/ includes all of win32s, win95, winNT & os/2
   707 	^ '.obj'
   702 	^ 'obj'
   708     ].
   703     ].
   709     OperatingSystem isVMSlike ifTrue:[
   704     OperatingSystem isVMSlike ifTrue:[
   710 	^ '.obj'
   705 	^ 'obj'
   711     ].
   706     ].
   712 
   707 
   713     ^ '.o'
   708     ^ 'o'
   714 
   709 
   715     "
   710     "
   716      ObjectFileLoader objectFileExtension
   711      ObjectFileLoader objectFileExtension
   717     "
       
   718 
       
   719     "Modified: / 4.5.1998 / 12:17:34 / cg"
       
   720 !
       
   721 
       
   722 sharedLibraryExtension
       
   723     "return the fileName extension used for dynamic loadable objects,
       
   724      as generated by myself (output of linker).
       
   725      This is very machine specific."
       
   726 
       
   727     |suff|
       
   728 
       
   729     suff := self sharedLibrarySuffix.
       
   730     suff notNil ifTrue:[^ '.' , suff].
       
   731     ^ suff
       
   732 
       
   733     "
       
   734      ObjectFileLoader sharedLibraryExtension
       
   735     "
   712     "
   736 
   713 
   737     "Modified: / 4.5.1998 / 12:17:34 / cg"
   714     "Modified: / 4.5.1998 / 12:17:34 / cg"
   738 !
   715 !
   739 
   716 
   815     OperatingSystem isVMSlike ifTrue:[
   792     OperatingSystem isVMSlike ifTrue:[
   816 	^ #('exe')
   793 	^ #('exe')
   817     ].
   794     ].
   818 
   795 
   819     os := OperatingSystem getSystemType.
   796     os := OperatingSystem getSystemType.
   820     (os = 'linux') ifTrue:[
   797     (os == #linux) ifTrue:[
   821 	"/ are we really still supporting that old stuff?
   798 	"/ are we really still supporting that old stuff?
   822 	self loadableBinaryObjectFormat == #aout ifTrue:[
   799 	self loadableBinaryObjectFormat == #aout ifTrue:[
   823 	    ^ #('o' 'obj' 'a')
   800 	    ^ #('o' 'obj' 'a')
   824 	].
   801 	].
   825 	^ #('so')
   802 	^ #('so')
   834 
   811 
   835     "
   812     "
   836      ObjectFileLoader validBinaryExtensions
   813      ObjectFileLoader validBinaryExtensions
   837     "
   814     "
   838 
   815 
   839     "Modified: / 1.10.1998 / 12:46:03 / cg"
   816     "Modified: / 01-10-1998 / 12:46:03 / cg"
       
   817     "Modified: / 22-07-2018 / 16:14:54 / Stefan Vogel"
   840 ! !
   818 ! !
   841 
   819 
   842 !ObjectFileLoader class methodsFor:'dynamic object loading'!
   820 !ObjectFileLoader class methodsFor:'dynamic object loading'!
   843 
   821 
   844 loadCPlusPlusObjectFile:aFileName
   822 loadCPlusPlusObjectFile:aFileName
  1079     "Modified: 6.7.1997 / 12:34:48 / cg"
  1057     "Modified: 6.7.1997 / 12:34:48 / cg"
  1080 !
  1058 !
  1081 
  1059 
  1082 loadLibrary:aLibraryFileName
  1060 loadLibrary:aLibraryFileName
  1083     "load a library; search in some standard places and using
  1061     "load a library; search in some standard places and using
  1084      standard suffixes (i.e. no suffix should be given in the arg).
  1062      standard suffixes (i.e. suffix may be omitted from LibraryFileName).
  1085      Returns a handle or nil.
  1063      Returns a handle or raise an error.
  1086      Use this to attach C-libraries."
  1064      Use this to attach C-libraries."
  1087 
  1065 
  1088     |s suffixes handle libFilename libPath|
  1066     |suffix suffixes handle libFilename libPath|
  1089 
  1067 
  1090     Verbose ifTrue:[
  1068     Verbose ifTrue:[
  1091 	('loadLibrary:' , aLibraryFileName) errorPrintCR.
  1069 	('loadLibrary:' , aLibraryFileName) errorPrintCR.
  1092     ].
  1070     ].
  1093     libFilename := aLibraryFileName asFilename.
  1071     libFilename := aLibraryFileName asFilename.
  1094     (s := libFilename suffix) isEmpty ifTrue:[
  1072     (suffix := libFilename suffix) isEmpty ifTrue:[
  1095 	suffixes := self validBinaryExtensions
  1073 	suffixes := self validBinaryExtensions
  1096     ] ifFalse:[
  1074     ] ifFalse:[
  1097 	suffixes := Array with:s
  1075 	suffixes := Array with:suffix
  1098     ].
  1076     ].
  1099 
  1077 
  1100     "/ try each suffix ...
  1078     "/ try each suffix ...
  1101     suffixes do:[:aSuffix |
  1079     suffixes do:[:aSuffix |
  1102 	|fn f|
  1080 	|fn f|
  1109 
  1087 
  1110 	Verbose ifTrue:[
  1088 	Verbose ifTrue:[
  1111 	    ('loadLibrary try:' , fn asString) errorPrintCR.
  1089 	    ('loadLibrary try:' , fn asString) errorPrintCR.
  1112 	].
  1090 	].
  1113 
  1091 
  1114 	handle := self loadObjectFile:fn asString.
  1092 	handle := self loadObjectFile:fn.
  1115 	handle notNil ifTrue:[^ handle].
  1093 	handle notNil ifTrue:[
       
  1094 	    ^ handle
       
  1095 	].
  1116 
  1096 
  1117 	(libFilename isAbsolute
  1097 	(libFilename isAbsolute
  1118 	 or:[(aLibraryFileName startsWith:'./')
  1098 	 or:[(aLibraryFileName startsWith:'./')
  1119 	 or:[(aLibraryFileName startsWith:'../')]]) ifTrue:[
  1099 	 or:[(aLibraryFileName startsWith:'../')]]) ifTrue:[
  1120 	    "/ already tried...
  1100 	    "/ already tried...
  1126 	    libPath := self libPath.
  1106 	    libPath := self libPath.
  1127 	    libPath notEmptyOrNil ifTrue:[
  1107 	    libPath notEmptyOrNil ifTrue:[
  1128 		libPath asCollectionOfSubCollectionsSeparatedBy:$: do:[:eachSinglePath |
  1108 		libPath asCollectionOfSubCollectionsSeparatedBy:$: do:[:eachSinglePath |
  1129 		    f := eachSinglePath asFilename construct:fn.
  1109 		    f := eachSinglePath asFilename construct:fn.
  1130 		    f exists ifTrue:[
  1110 		    f exists ifTrue:[
  1131 			handle := self loadObjectFile:f pathName.
  1111 			handle := self loadObjectFile:f.
  1132 			handle notNil ifTrue:[^ handle].
  1112 			handle notNil ifTrue:[
       
  1113 			    ^ handle
       
  1114 			].
  1133 		    ]
  1115 		    ]
  1134 		]
  1116 		]
  1135 	    ].
  1117 	    ].
  1136 	]
  1118 	]
  1137     ].
  1119     ].
  1138 
  1120 
  1139     ^ nil
  1121    ObjectFileLoadError
  1140 
  1122 	raiseErrorString:('Cannot find or load dll/library: "%1"' bindWith:aLibraryFileName asString).
  1141     "
  1123 
       
  1124     "
       
  1125      ObjectFileLoader loadLibrary:'libc.so.6'
  1142      ObjectFileLoader loadLibrary:'libjpeg'
  1126      ObjectFileLoader loadLibrary:'libjpeg'
  1143      ObjectFileLoader loadLibrary:'odbc32'
  1127      ObjectFileLoader loadLibrary:'odbc32'
  1144     "
  1128     "
  1145 
  1129 
  1146     "Modified: / 04-05-1999 / 17:01:47 / cg"
  1130     "Modified: / 04-05-1999 / 17:01:47 / cg"
  1147     "Modified: / 20-09-2017 / 20:10:15 / stefan"
  1131     "Modified: / 20-09-2017 / 20:10:15 / stefan"
       
  1132     "Modified: / 22-07-2018 / 16:40:34 / Stefan Vogel"
  1148 !
  1133 !
  1149 
  1134 
  1150 loadMethodObjectFile:aFileName
  1135 loadMethodObjectFile:aFileName
  1151     "load an object file (.o-file) for a single method into the image;
  1136     "load an object file (.o-file) for a single method into the image;
  1152      This does a slightly different initialization.
  1137      This does a slightly different initialization.
  1169 
  1154 
  1170     initAddr := self getFunction:'__' , initName , '_Init' from:handle.
  1155     initAddr := self getFunction:'__' , initName , '_Init' from:handle.
  1171     initAddr isNil ifTrue:[
  1156     initAddr isNil ifTrue:[
  1172 	initAddr := self getFunction:'_' , initName , '_Init' from:handle.
  1157 	initAddr := self getFunction:'_' , initName , '_Init' from:handle.
  1173 	initAddr isNil ifTrue:[
  1158 	initAddr isNil ifTrue:[
  1174 	    (self getListOfUndefinedSymbolsFrom:handle) size > 0 ifTrue:[
  1159 	    (self getListOfUndefinedSymbolsFrom:handle) size ~~ 0 ifTrue:[
  1175 		self listUndefinedSymbolsIn:handle.
  1160 		self listUndefinedSymbolsIn:handle.
  1176 		'ObjectFileLoader [info]: undefined symbols in primitive code' errorPrintCR.
  1161 		'ObjectFileLoader [info]: undefined symbols in primitive code' errorPrintCR.
  1177 	    ] ifFalse:[
  1162 	    ] ifFalse:[
  1178 		('ObjectFileLoader [info]: ' , initName , '_Init() lookup failed') errorPrintCR
  1163 		('ObjectFileLoader [info]: ' , initName , '_Init() lookup failed') errorPrintCR
  1179 	    ].
  1164 	    ].
  1228     handle method:m.
  1213     handle method:m.
  1229     ^ handle
  1214     ^ handle
  1230 
  1215 
  1231     "Created: / 05-12-1995 / 20:59:46 / cg"
  1216     "Created: / 05-12-1995 / 20:59:46 / cg"
  1232     "Modified: / 15-11-2010 / 13:20:36 / cg"
  1217     "Modified: / 15-11-2010 / 13:20:36 / cg"
       
  1218     "Modified: / 01-03-2019 / 16:03:41 / Claus Gittinger"
  1233 !
  1219 !
  1234 
  1220 
  1235 loadObjectFile:aFileName
  1221 loadObjectFile:aFileName
  1236     "load an object file (.o-file) into the image;
  1222     "load an object file (.o-file) into the image;
  1237      the class name is not needed (multiple definitions may be in the file).
  1223      the class name is not needed (multiple definitions may be in the file).
  1238      This may be either a smalltalk object or a C-object file.
  1224      This may be either a smalltalk object or a C-object file.
  1239      The object files init function (if any) is called, and the module
  1225      The object file's init function (if any) is called, and the module
  1240      is unloaded if it returns failure (use lowLevel load, to load a file
  1226      is unloaded if it returns failure (use lowLevel load, to load a file
  1241      without automatic initialization).
  1227      without automatic initialization).
  1242      Return nil on error, an objectFile handle if ok."
  1228      Return nil on error, an objectFile handle if ok."
  1243 
  1229 
  1244     ^ self
  1230     ^ self
  1245 	loadObjectFile:aFileName
  1231 	loadObjectFile:aFileName
  1246 	invokeInitializeMethods:true
  1232 	invokeInitializeMethods:true
       
  1233 
       
  1234     "Modified (comment): / 10-04-2019 / 05:47:49 / Claus Gittinger"
       
  1235     "Modified: / 17-10-2019 / 13:46:10 / Stefan Vogel"
  1247 !
  1236 !
  1248 
  1237 
  1249 loadObjectFile:pathNameOrFilename invokeInitializeMethods:invokeInitializeMethods
  1238 loadObjectFile:pathNameOrFilename invokeInitializeMethods:invokeInitializeMethods
  1250     "load an object file (.dll or .so-file) into the image;
  1239     "load an object file (.dll or .so-file) into the image;
  1251      the class name is not needed (multiple definitions may be in the file).
  1240      the class name is not needed (multiple definitions may be in the file).
  1261     filename := pathNameOrFilename asFilename.
  1250     filename := pathNameOrFilename asFilename.
  1262     pathName := filename pathName.
  1251     pathName := filename pathName.
  1263 
  1252 
  1264     handle := self handleForDynamicObject:filename.
  1253     handle := self handleForDynamicObject:filename.
  1265     handle notNil ifTrue:[
  1254     handle notNil ifTrue:[
  1266 	"already loaded"
  1255         "already loaded"
  1267 	^ handle.
  1256         ^ handle.
  1268     ].
  1257     ].
  1269 
  1258 
  1270     handle := self loadDynamicObject:filename.
  1259     handle := self loadDynamicObject:filename.
  1271     handle isNil ifTrue:[
  1260     handle isNil ifTrue:[
  1272 	^ nil
  1261         ^ nil
  1273     ].
  1262     ].
  1274 
  1263 
  1275     didInit := false.
  1264     didInit := false.
  1276     isCModule := false.
  1265     isCModule := false.
  1277 
  1266 
  1278     "with dld, load may have worked, even if undefined symbols
  1267     "with dld, load may have worked, even if undefined symbols
  1279      are to be resolved. If that's the case, load all libraries ..."
  1268      are to be resolved. If that's the case, load all libraries ..."
  1280 
  1269 
  1281     ParserFlags searchedLibraries notEmptyOrNil ifTrue:[
  1270     ParserFlags searchedLibraries notEmptyOrNil ifTrue:[
  1282 	(self hasUndefinedSymbolsIn:handle) ifTrue:[
  1271         (self hasUndefinedSymbolsIn:handle) ifTrue:[
  1283 	    self initializeLoader.
  1272             self initializeLoader.
  1284 
  1273 
  1285 	    ParserFlags searchedLibraries do:[:libName |
  1274             ParserFlags searchedLibraries do:[:libName |
  1286 		(self hasUndefinedSymbolsIn:handle) ifTrue:[
  1275                 (self hasUndefinedSymbolsIn:handle) ifTrue:[
  1287 		    Logger info:'   ... trying  %1 to resolve undefined symbols ...' with:libName.
  1276                     Logger info:'   ... trying  %1 to resolve undefined symbols ...' with:libName.
  1288 		    dummyHandle := Array new:4.
  1277                     dummyHandle := Array new:4.
  1289 		    dummyHandle := self primLoadDynamicObject:libName into:dummyHandle.
  1278                     dummyHandle := self primLoadDynamicObject:libName into:dummyHandle.
  1290 "/                    dummyHandle isNil ifTrue:[
  1279 "/                    dummyHandle isNil ifTrue:[
  1291 "/                        Transcript showCR:'   ... load of library ' , libName , ' failed.'.
  1280 "/                        Transcript showCR:'   ... load of library ' , libName , ' failed.'.
  1292 "/                    ]
  1281 "/                    ]
  1293 		]
  1282                 ]
  1294 	    ].
  1283             ].
  1295 	    (self hasUndefinedSymbolsIn:handle) isNil ifTrue:[
  1284             (self hasUndefinedSymbolsIn:handle) isNil ifTrue:[
  1296 		Logger info:'still undefined symbols in %1.' with:pathName.
  1285                 Logger info:'still undefined symbols in %1.' with:pathName.
  1297 	    ].
  1286             ].
  1298 	]
  1287         ]
  1299     ].
  1288     ].
  1300 
  1289 
  1301     "
  1290     "
  1302      first, expect the classes-name to be the fileNames-baseName
  1291      first, expect the classes-name to be the fileNames-baseName
  1303      (if it's not, it may be a method or function module;
  1292      (if it's not, it may be a method or function module;
  1308 
  1297 
  1309     "look for explicit initDefinition (xxx_InitDefinition) function
  1298     "look for explicit initDefinition (xxx_InitDefinition) function
  1310      This is used in ST packaged classLib object files"
  1299      This is used in ST packaged classLib object files"
  1311 
  1300 
  1312     (initFunctionName startsWith:'lib') ifTrue:[
  1301     (initFunctionName startsWith:'lib') ifTrue:[
  1313 	definitionClassName := initFunctionName copyFrom:4.
  1302         definitionClassName := initFunctionName copyFrom:4.
  1314 	definitionClass := Smalltalk classNamed:definitionClassName.
  1303         definitionClass := Smalltalk classNamed:definitionClassName.
  1315     ].
  1304     ].
  1316     (definitionClass isNil or:[definitionClass isLoaded not]) ifTrue:[
  1305     (definitionClass isNil or:[definitionClass isLoaded not or:[definitionClass isObsolete]]) ifTrue:[
  1317 	"the project definition class has not been loaded yet.
  1306         "the project definition class has not been loaded yet.
  1318 	 initialize and load it"
  1307          initialize and load it"
  1319 
  1308 
  1320 	initDefinitionAddr := self findInitDefinitionFunction:initFunctionName in:handle.
  1309         initDefinitionAddr := self findInitDefinitionFunction:initFunctionName in:handle.
  1321 	initDefinitionAddr isNil ifTrue:[
  1310         initDefinitionAddr isNil ifTrue:[
  1322             Logger warning: 'no init definitions for: %1' with: pathName.
  1311             Logger warning: 'no init definitions for: %1' with: pathName.
  1323 	] ifFalse:[
  1312         ] ifFalse:[
  1324 	    Verbose ifTrue:[
  1313             Verbose ifTrue:[
  1325                 Logger info: 'calling initDefinition at: %1' with: (initDefinitionAddr printStringRadix:16).
  1314                 Logger info: 'calling initDefinition at: %1' with: (initDefinitionAddr printStringRadix:16).
  1326 	    ].
  1315             ].
  1327 	    info := self
  1316             info := self
  1328 			performModuleInitAt:initDefinitionAddr
  1317                         performModuleInitAt:initDefinitionAddr
  1329 			invokeInitializeMethods:false
  1318                         invokeInitializeMethods:false
  1330 			for:definitionClassName
  1319                         for:definitionClassName
  1331 			identifyAs:handle.
  1320                         identifyAs:handle.
  1332 	    status := info at:1.
  1321             status := info at:1.
  1333 	    status == #ok ifTrue:[
  1322             status == #ok ifTrue:[
  1334 		"/ now, we have only loaded and installed the projectDefinition class.
  1323                 "/ now, we have only loaded and installed the projectDefinition class.
  1335 		"/ (but no containing classes or extensions, yet).
  1324                 "/ (but no containing classes or extensions, yet).
  1336 		"/ let the projectDefinition load any prereqs
  1325                 "/ let the projectDefinition load any prereqs
  1337 	       definitionClassName notNil ifTrue:[
  1326                definitionClassName notNil ifTrue:[
  1338 		    definitionClass := Smalltalk classNamed:definitionClassName.
  1327                     definitionClass := Smalltalk classNamed:definitionClassName.
  1339 		    definitionClass notNil ifTrue:[
  1328                     definitionClass notNil ifTrue:[
  1340 "/                        "if projectDefinition denies loading, unload"
  1329                         [
  1341 "/                            self unloadDynamicObject:handle.
  1330                             definitionClass checkForLoad.   "/ raise exception if not supported on platform / not licensed
  1342 
  1331                         ] on:PackageLoadError do:[:ex|
  1343 			definitionClass
  1332                             self unloadObjectFileAndRemoveClasses:pathName.
  1344 			    checkForLoad;                           "/ raise exception if not supported on platform / not licensed
  1333                             ex reject.
  1345 			    initialize;
  1334                             ^ nil.
  1346 			    preLoadAction;
  1335                         ].
  1347 			    loadMandatoryPreRequisitesAsAutoloaded:false.
  1336                         definitionClass isObsolete ifTrue:[
  1348 		    ].
  1337                             "we come here when doing a filein and a (illegal) proceed from the PackageLoadError"
  1349 		].
  1338                             ^ nil.
  1350 	    ]
  1339                         ].
  1351 	].
  1340                         definitionClass
       
  1341                             initialize;
       
  1342                             preLoadAction;
       
  1343                             loadMandatoryPreRequisitesAsAutoloaded:false.
       
  1344                     ].
       
  1345                 ].
       
  1346             ]
       
  1347         ].
  1352     ].
  1348     ].
  1353     "look for explicit init (xxx_Init) function
  1349     "look for explicit init (xxx_Init) function
  1354      This is used in ST object files"
  1350      This is used in ST object files"
  1355 
  1351 
  1356     initAddr := self findInitFunction:initFunctionName in:handle.
  1352     initAddr := self findInitFunction:initFunctionName in:handle.
  1357     initAddr notNil ifTrue:[
  1353     initAddr notNil ifTrue:[
  1358 	Verbose ifTrue:[
  1354         Verbose ifTrue:[
  1359             Logger info: ' calling init at: %1' with: (initAddr printStringRadix:16).
  1355             Logger info: ' calling init at: %1' with: (initAddr printStringRadix:16).
  1360 	].
  1356         ].
  1361 	info := self
  1357         info := self
  1362 		    performModuleInitAt:initAddr
  1358                     performModuleInitAt:initAddr
  1363 		    invokeInitializeMethods:invokeInitializeMethods
  1359                     invokeInitializeMethods:invokeInitializeMethods
  1364 		    for:nil
  1360                     for:nil
  1365 		    identifyAs:handle.
  1361                     identifyAs:handle.
  1366 	status := info at:1.
  1362         status := info at:1.
  1367 	status == #ok ifTrue:[
  1363         status == #ok ifTrue:[
  1368 	    didInit := true.
  1364             didInit := true.
  1369 	    definitionClassName notNil ifTrue:[
  1365             definitionClassName notNil ifTrue:[
  1370 		definitionClass := Smalltalk classNamed:definitionClassName.
  1366                 definitionClass := Smalltalk classNamed:definitionClassName.
  1371 	    ]
  1367             ]
  1372 	]
  1368         ]
  1373     ] ifFalse:[
  1369     ] ifFalse:[
  1374 	"look for explicit C-init (xxx__Init) function
  1370         "look for explicit C-init (xxx__Init) function
  1375 	 This is used in C object files"
  1371          This is used in C object files"
  1376 
  1372 
  1377 	initAddr := self findFunction:initFunctionName suffix:'__Init' in:handle.
  1373         initAddr := self findFunction:initFunctionName suffix:'__Init' in:handle.
  1378 	initAddr notNil ifTrue:[
  1374         initAddr notNil ifTrue:[
  1379 	    isCModule := true.
  1375             isCModule := true.
  1380 
  1376 
  1381 	    OSSignalInterrupt handle:[:ex |
  1377             OSSignalInterrupt handle:[:ex |
  1382 		Logger error:'hard error in initFunction of class-module: %1' with:pathName.
  1378                 Logger error:'hard error in initFunction of class-module: %1' with:pathName.
  1383 		status := #initFailed.
  1379                 status := #initFailed.
  1384 	    ] do:[
  1380             ] do:[
  1385 		cRetVal := self
  1381                 cRetVal := self
  1386 		    saveCallInitFunctionAt:initAddr
  1382                     saveCallInitFunctionAt:initAddr
  1387 		    in:pathNameOrFilename
  1383                     in:pathNameOrFilename
  1388 		    specialInit:false
  1384                     specialInit:false
  1389 		    forceOld:true
  1385                     forceOld:true
  1390 		    interruptable:false
  1386                     interruptable:false
  1391 		    argument:0
  1387                     argument:0
  1392 		    identifyAs:handle
  1388                     identifyAs:handle
  1393 		    returnsObject:false.
  1389                     returnsObject:false.
  1394 		(cRetVal < 0) ifTrue:[
  1390                 (cRetVal < 0) ifTrue:[
  1395 		    Verbose ifTrue:[
  1391                     Verbose ifTrue:[
  1396                         Logger info: 'init function returns failure ... unload'.
  1392                         Logger info: 'init function returns failure ... unload'.
  1397 		    ].
  1393                     ].
  1398 		    status := #initFailed.
  1394                     status := #initFailed.
  1399 		] ifFalse:[
  1395                 ] ifFalse:[
  1400 		    didInit := true.
  1396                     didInit := true.
  1401 		]
  1397                 ]
  1402 	    ]
  1398             ]
  1403 	] ifFalse:[
  1399         ] ifFalse:[
  1404 	    status := #noInitFunction.
  1400             status := #noInitFunction.
  1405 
  1401 
  1406 	    "look for any init-function(s); call them all"
  1402             "look for any init-function(s); call them all"
  1407 	    Verbose ifTrue:[
  1403             Verbose ifTrue:[
  1408                 Logger info: 'no good init functions found; looking for candidates ...'.
  1404                 Logger info: 'no good init functions found; looking for candidates ...'.
  1409 	    ].
  1405             ].
  1410 	    initNames := self namesMatching:'*_Init' segment:'[tT?]' in:pathName.
  1406             initNames := self namesMatching:'*_Init' segment:'[tT?]' in:pathName.
  1411 	    initNames notNil ifTrue:[
  1407             initNames notNil ifTrue:[
  1412 		initNames do:[:aName |
  1408                 initNames do:[:aName |
  1413 		    initAddr := self getFunction:aName from:handle.
  1409                     initAddr := self getFunction:aName from:handle.
  1414 		    initAddr isNil ifTrue:[
  1410                     initAddr isNil ifTrue:[
  1415 			(aName startsWith:'_') ifTrue:[
  1411                         (aName startsWith:'_') ifTrue:[
  1416 			    initAddr := self getFunction:(aName copyFrom:2) from:handle.
  1412                             initAddr := self getFunction:(aName copyFrom:2) from:handle.
  1417 			].
  1413                         ].
  1418 		    ].
  1414                     ].
  1419 		    initAddr isNil ifTrue:[
  1415                     initAddr isNil ifTrue:[
  1420 			Transcript showCR:('no symbol: ',aName,' in ', pathName).
  1416                         Transcript showCR:('no symbol: ',aName,' in ', pathName).
  1421 		    ] ifFalse:[
  1417                     ] ifFalse:[
  1422 			Verbose ifTrue:[
  1418                         Verbose ifTrue:[
  1423                             Logger info: ' calling init at: %1' with: (initAddr printStringRadix:16)
  1419                             Logger info: ' calling init at: %1' with: (initAddr printStringRadix:16)
  1424 			].
  1420                         ].
  1425 			self
  1421                         self
  1426 			    performModuleInitAt:initAddr
  1422                             performModuleInitAt:initAddr
  1427 			    invokeInitializeMethods:invokeInitializeMethods
  1423                             invokeInitializeMethods:invokeInitializeMethods
  1428 			    for:nil
  1424                             for:nil
  1429 			    identifyAs:handle.
  1425                             identifyAs:handle.
  1430 			didInit := true.
  1426                         didInit := true.
  1431 		    ]
  1427                     ]
  1432 		].
  1428                 ].
  1433 	    ].
  1429             ].
  1434 	]
  1430         ]
  1435     ].
  1431     ].
  1436 
  1432 
  1437     (invokeInitializeMethods and:[didInit not]) ifTrue:[
  1433     (invokeInitializeMethods and:[didInit not]) ifTrue:[
  1438 	status == #noInitFunction ifTrue:[
  1434         status == #noInitFunction ifTrue:[
  1439 	    msg := 'no classLib init function found; assume load ok'
  1435             msg := 'no classLib init function found; assume load ok'
  1440 	] ifFalse:[
  1436         ] ifFalse:[
  1441 	    (status ~~ #registrationFailed
  1437             (status ~~ #registrationFailed
  1442 		and:[status ~~ #initFailed
  1438                 and:[status ~~ #initFailed
  1443 		and:[status ~~ #missingClass
  1439                 and:[status ~~ #missingClass
  1444 		and:[status ~~ #versionMismatch]]])
  1440                 and:[status ~~ #versionMismatch]]])
  1445 	    ifTrue:[
  1441             ifTrue:[
  1446 		self listUndefinedSymbolsIn:handle.
  1442                 self listUndefinedSymbolsIn:handle.
  1447 	    ].
  1443             ].
  1448 
  1444 
  1449 	    Verbose ifTrue:[
  1445             Verbose ifTrue:[
  1450                 Logger info: ': unloading, since init failed ...'.
  1446                 Logger info: ': unloading, since init failed ...'.
  1451 	    ].
  1447             ].
  1452 
  1448 
  1453 	    "/ give caller a chance to prevent unloading (to register later, when a prerequisite class comes)
  1449             "/ give caller a chance to prevent unloading (to register later, when a prerequisite class comes)
  1454 	    status == #missingClass ifTrue:[
  1450             status == #missingClass ifTrue:[
  1455 		doNotUnload := (SuperClassMissingErrorNotification query ? false).
  1451                 doNotUnload := (SuperClassMissingErrorNotification query ? false).
  1456 	    ] ifFalse:[
  1452             ] ifFalse:[
  1457 		status == #registrationFailed ifTrue:[
  1453                 status == #registrationFailed ifTrue:[
  1458 		    doNotUnload := (RegistrationFailedErrorNotification query ? false).
  1454                     doNotUnload := (RegistrationFailedErrorNotification query ? false).
  1459 		] ifFalse:[
  1455                 ] ifFalse:[
  1460 		    doNotUnload := false.
  1456                     doNotUnload := false.
  1461 		].
  1457                 ].
  1462 	    ].
  1458             ].
  1463 	    doNotUnload ifFalse:[
  1459             doNotUnload ifFalse:[
  1464 		self unloadDynamicObject:handle.
  1460                 self unloadDynamicObject:handle.
  1465 		Verbose ifTrue:[
  1461                 Verbose ifTrue:[
  1466                     Logger info: 'unloaded'.
  1462                     Logger info: 'unloaded'.
  1467 		].
  1463                 ].
  1468 		handle := nil.
  1464                 handle := nil.
  1469 	    ].
  1465             ].
  1470 
  1466 
  1471 	    status == #initFailed ifTrue:[
  1467             status == #initFailed ifTrue:[
  1472 		msg := 'module not loaded (init function signaled failure).'
  1468                 msg := 'module not loaded (init function signaled failure).'
  1473 	    ] ifFalse:[
  1469             ] ifFalse:[
  1474 		status == #missingClass ifTrue:[
  1470                 status == #missingClass ifTrue:[
  1475 		    msg := 'module not loaded (superclass missing: ' , (info at:2) , ').'
  1471                     msg := 'module not loaded (superclass missing: ' , (info at:2) , ').'
  1476 		] ifFalse:[
  1472                 ] ifFalse:[
  1477 		    status == #registrationFailed ifTrue:[
  1473                     status == #registrationFailed ifTrue:[
  1478 			msg :=  'module registration failed (incompatible object or missing superclass)'
  1474                         msg :=  'module registration failed (incompatible object or missing superclass)'
  1479 		    ] ifFalse:[
  1475                     ] ifFalse:[
  1480 			status == #versionMismatch ifTrue:[
  1476                         status == #versionMismatch ifTrue:[
  1481 			    msg :=  'module registration failed (class version mismatch ' , (info at:2) printString , ')'
  1477                             msg :=  'module registration failed (class version mismatch ' , (info at:2) printString , ')'
  1482 			] ifFalse:[
  1478                         ] ifFalse:[
  1483 			    (self namesMatching:'*__sepInitCode__*' segment:'[tT?]' in:pathName) notNil ifTrue:[
  1479                             (self namesMatching:'*__sepInitCode__*' segment:'[tT?]' in:pathName) notNil ifTrue:[
  1484 				msg := 'module not loaded (unknown error reason).'
  1480                                 msg := 'module not loaded (unknown error reason).'
  1485 			    ] ifFalse:[
  1481                             ] ifFalse:[
  1486 				msg := 'module not loaded (no _Init entry in object file ?).'
  1482                                 msg := 'module not loaded (no _Init entry in object file ?).'
  1487 			    ]
  1483                             ]
  1488 			]
  1484                         ]
  1489 		    ].
  1485                     ].
  1490 		].
  1486                 ].
  1491 	    ].
  1487             ].
  1492 	].
  1488         ].
  1493 	Verbose ifTrue:[
  1489         Verbose ifTrue:[
  1494 	    Logger debug:'%1: %2' with:pathNameOrFilename asFilename baseName with:msg.
  1490             Logger debug:'%1: %2' with:pathNameOrFilename asFilename baseName with:msg.
  1495 	].
  1491         ].
  1496     ].
  1492     ].
  1497 
  1493 
  1498     isCModule ifFalse:[
  1494     isCModule ifFalse:[
  1499 	Smalltalk flushCachedClasses.
  1495         Smalltalk flushCachedClasses.
  1500 	Class flushSubclassInfo.
  1496         Class flushSubclassInfo.
  1501 
  1497 
  1502 	(definitionClass notNil and:[definitionClass isLoaded]) ifTrue:[
  1498         (definitionClass notNil and:[definitionClass isLoaded and:[definitionClass isObsolete not]]) ifTrue:[
  1503             definitionClass checkForLoad.               "/ raise exception if not supported on platform / not licensed
  1499             [
       
  1500                 definitionClass checkForLoad.   "/ raise exception if not supported on platform / not licensed
       
  1501             ] on:PackageLoadError do:[:ex|
       
  1502                 self unloadObjectFileAndRemoveClasses:pathName.
       
  1503                 ex reject.
       
  1504                 ^ nil.
       
  1505             ].
  1504             Smalltalk changed: #aboutToLoadPackage with: definitionClass.
  1506             Smalltalk changed: #aboutToLoadPackage with: definitionClass.
  1505 	    definitionClass
  1507             definitionClass
  1506 		loadAllClassesAsAutoloaded:true;
  1508                 initialize;
  1507 		loadPreRequisitesAsAutoloaded:true;     "/ load non-mandatory prerequisites
  1509                 loadAllClassesAsAutoloaded:true;
  1508 		projectIsLoaded:true.                   "/ this performs the postLoadAction, too.
  1510                 loadPreRequisitesAsAutoloaded:true;     "/ load non-mandatory prerequisites
       
  1511                 projectIsLoaded:true.                   "/ this performs the postLoadAction, too.
  1509             Smalltalk changed: #packageLoaded with: definitionClass.
  1512             Smalltalk changed: #packageLoaded with: definitionClass.
  1510 	].
  1513         ].
  1511 	Smalltalk isInitialized ifTrue:[
  1514         Smalltalk isInitialized ifTrue:[
  1512 	    "really don't know, if and what has changed ...
  1515             "really don't know, if and what has changed ...
  1513 	     ... but assume, that new classes have been installed."
  1516              ... but assume, that new classes have been installed."
  1514 	    Smalltalk changed:#postLoad.
  1517             Smalltalk changed:#postLoad.
  1515 	].
  1518         ].
  1516     ].
  1519     ].
  1517     ^ handle
  1520     ^ handle
  1518 
  1521 
  1519     "Modified: / 15-11-2010 / 13:19:26 / cg"
  1522     "Modified: / 15-11-2010 / 13:19:26 / cg"
  1520     "Modified: / 20-09-2016 / 00:02:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1523     "Modified: / 20-09-2016 / 00:02:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1521     "Modified (comment): / 13-02-2017 / 20:27:55 / cg"
  1524     "Modified (comment): / 13-02-2017 / 20:27:55 / cg"
       
  1525     "Modified: / 17-10-2019 / 14:51:08 / Stefan Vogel"
  1522 !
  1526 !
  1523 
  1527 
  1524 unloadAllObsoleteObjectFiles
  1528 unloadAllObsoleteObjectFiles
  1525     "unload all dynamically loaded object files for which the classes/method
  1529     "unload all dynamically loaded object files for which the classes/method
  1526      has been already garbage collected."
  1530      has been already garbage collected."
  1538     "
  1542     "
  1539 
  1543 
  1540     "Modified: 5.12.1995 / 18:16:52 / cg"
  1544     "Modified: 5.12.1995 / 18:16:52 / cg"
  1541 !
  1545 !
  1542 
  1546 
  1543 unloadObjectFile:aFileName
  1547 unloadObjectFile:aFilename
  1544     "unload an object file (.o-file) from the image.
  1548     "unload an object file (.o-file) from the image.
  1545      DANGER ALERT: currently, you have to make sure that no references to
  1549      DANGER ALERT: currently, you have to make sure that no references to
  1546      objects of this module exist - in future versions, the system will keep
  1550      objects of this module exist - in future versions, the system will keep
  1547      track of these. For now, use at your own risk.
  1551      track of these. For now, use at your own risk.
  1548      (especially critical are blocks-functions)."
  1552      (especially critical are blocks-functions)."
  1549 
  1553 
  1550     |handle|
  1554     |handle|
  1551 
  1555 
  1552     LoadedObjects notNil ifTrue:[
  1556     handle := self handleForDynamicObject:aFilename.
  1553 	handle := LoadedObjects at:aFileName ifAbsent:nil
       
  1554     ].
       
  1555     handle isNil ifTrue:[
  1557     handle isNil ifTrue:[
  1556 	('ObjectFileLoader [info]: oops - file to be unloaded was not loaded dynamically (', aFileName , ')') infoPrintCR.
  1558 	Logger info:'oops - file to be unloaded was not loaded dynamically (%1)' with:aFilename.
  1557 	^ self
  1559 	^ self
  1558     ].
  1560     ].
  1559 
  1561 
  1560     "/ call the modules deInit-function and unload...
  1562     "/ call the modules deInit-function and unload...
  1561     self unloadDynamicObject:handle
  1563     self unloadDynamicObject:handle
  1562 
  1564 
  1563     "Modified: / 06-12-2006 / 18:19:13 / cg"
  1565     "Modified: / 06-12-2006 / 18:19:13 / cg"
  1564 !
  1566     "Modified: / 17-10-2019 / 13:35:52 / Stefan Vogel"
  1565 
  1567 !
  1566 unloadObjectFileAndRemoveClasses:aFileName
  1568 
       
  1569 unloadObjectFileAndRemoveClasses:aFilename
  1567     "unload an object file (.o-file) from the image and remove all
  1570     "unload an object file (.o-file) from the image and remove all
  1568      corresponding classes from the system.
  1571      corresponding classes from the system.
  1569      DANGER ALERT: currently, you have to make sure that no references to
  1572      DANGER ALERT: currently, you have to make sure that no references to
  1570      objects of this module exist - in future versions, the system will keep
  1573      objects of this module exist - in future versions, the system will keep
  1571      track of these. For now, use at your own risk.
  1574      track of these. For now, use at your own risk.
  1572      (especially critical are blocks-functions)."
  1575      (especially critical are blocks-functions)."
  1573 
  1576 
  1574     |handle|
  1577     |handle|
  1575 
  1578 
  1576     LoadedObjects notNil ifTrue:[
  1579     handle := self handleForDynamicObject:aFilename.
  1577 	handle := LoadedObjects at:aFileName ifAbsent:nil
       
  1578     ].
       
  1579     handle isNil ifTrue:[
  1580     handle isNil ifTrue:[
  1580 	('ObjectFileLoader [info]: oops - file to be unloaded was not loaded dynamically (', (aFileName ? 'unknown-file') , ')') infoPrintCR.
  1581 	Logger info:'oops - file to be unloaded was not loaded dynamically (%1)' with:aFilename.
  1581 	^ self
  1582 	^ self
  1582     ].
  1583     ].
  1583     handle isClassLibHandle ifFalse:[
  1584     handle isClassLibHandle ifFalse:[
  1584 	self error:'Module is not a classLib module. Proceed to unload anyway' mayProceed:true.
  1585 	self error:'Module is not a classLib module. Proceed to unload anyway' mayProceed:true.
  1585     ].
  1586     ].
  1595 
  1596 
  1596     "/ call the modules deInit-function and unload...
  1597     "/ call the modules deInit-function and unload...
  1597     self unloadDynamicObject:handle
  1598     self unloadDynamicObject:handle
  1598 
  1599 
  1599     "Modified: / 06-12-2006 / 18:19:19 / cg"
  1600     "Modified: / 06-12-2006 / 18:19:19 / cg"
       
  1601     "Modified: / 17-10-2019 / 13:38:01 / Stefan Vogel"
  1600 ! !
  1602 ! !
  1601 
  1603 
  1602 !ObjectFileLoader class methodsFor:'dynamic object queries'!
  1604 !ObjectFileLoader class methodsFor:'dynamic object queries'!
  1603 
  1605 
  1604 findFunction:functionName suffix:suffix in:handle
  1606 findFunction:functionName suffix:suffix in:handle
  1741      * don't know how to do it
  1743      * don't know how to do it
  1742      */
  1744      */
  1743 #endif
  1745 #endif
  1744 
  1746 
  1745 #ifdef WIN_DL
  1747 #ifdef WIN_DL
  1746     /*
       
  1747      * don't know how to do it
       
  1748      */
       
  1749 #endif
       
  1750 
       
  1751 #ifdef BEOS_DL
       
  1752     /*
  1748     /*
  1753      * don't know how to do it
  1749      * don't know how to do it
  1754      */
  1750      */
  1755 #endif
  1751 #endif
  1756 
  1752 
  1891 	}
  1887 	}
  1892     }
  1888     }
  1893   }
  1889   }
  1894 #endif
  1890 #endif
  1895 
  1891 
  1896 #ifdef BEOS_DL
       
  1897   {
       
  1898     void *h;
       
  1899     void *addr;
       
  1900     INT val;
       
  1901     void *handle;
       
  1902 
       
  1903     if (__bothSmallInteger(sysHandle1, sysHandle2)) {
       
  1904 # if __POINTER_SIZE__ == 8
       
  1905 	val = (_intVal(sysHandle2) << 32) + _intVal(sysHandle1);
       
  1906 # else
       
  1907 	val = (_intVal(sysHandle2) << 16) + _intVal(sysHandle1);
       
  1908 # endif
       
  1909 	handle = (void *)(val);
       
  1910 
       
  1911 	if (__isStringLike(aString)) {
       
  1912 	    if (@global(Verbose) == true)
       
  1913 		console_printf("get sym <%s> handle = %"_lx_"\n", __stringVal(aString), (INT)handle);
       
  1914 	    entry = NULL;
       
  1915 	    get_image_symbol((image_id) handle, (char *) __stringVal(aString), B_SYMBOL_TYPE_TEXT, &entry);
       
  1916 	    if (entry != NULL) {
       
  1917 		addr = (void *)entry;
       
  1918 		if (@global(Verbose) == true) {
       
  1919 		    console_printf("get_image_symbol %s ok; addr = %x\n", __stringVal(aString), addr);
       
  1920 		}
       
  1921 		address = __MKUINT( (INT)addr );
       
  1922 	    } else {
       
  1923 		if (@global(Verbose) == true) {
       
  1924 		    console_printf("get_image_symbol %s error\n", __stringVal(aString));
       
  1925 		}
       
  1926 	    }
       
  1927 	}
       
  1928     }
       
  1929   }
       
  1930 #endif
       
  1931 
  1892 
  1932 #ifdef DL1_6
  1893 #ifdef DL1_6
  1933   {
  1894   {
  1934     void *h;
  1895     void *h;
  1935     void *addr;
  1896     void *addr;
  2176 hasUndefinedSymbolsIn:handle
  2137 hasUndefinedSymbolsIn:handle
  2177     "return true, if a module has undefined symbols in it.
  2138     "return true, if a module has undefined symbols in it.
  2178      This is only possible if the system supports loading
  2139      This is only possible if the system supports loading
  2179      modules with undefined things in it - most do not"
  2140      modules with undefined things in it - most do not"
  2180 
  2141 
  2181     ^ (self getListOfUndefinedSymbolsFrom:handle) size > 0
  2142     ^ (self getListOfUndefinedSymbolsFrom:handle) size ~~ 0
  2182 
  2143 
  2183     "Modified: 25.4.1996 / 09:47:27 / cg"
  2144     "Modified: / 25-04-1996 / 09:47:27 / cg"
       
  2145     "Modified: / 01-03-2019 / 16:03:33 / Claus Gittinger"
  2184 !
  2146 !
  2185 
  2147 
  2186 initFunctionBasenameForFile:pathNameOrFilename
  2148 initFunctionBasenameForFile:pathNameOrFilename
  2187     "return the expected initFunction's name, given a fileName"
  2149     "return the expected initFunction's name, given a fileName"
  2188 
  2150 
  2261     "list undefined objects in a module on the transcript"
  2223     "list undefined objects in a module on the transcript"
  2262 
  2224 
  2263     |undefinedNames|
  2225     |undefinedNames|
  2264 
  2226 
  2265     undefinedNames := self getListOfUndefinedSymbolsFrom:handle.
  2227     undefinedNames := self getListOfUndefinedSymbolsFrom:handle.
  2266     undefinedNames size > 0 ifTrue:[
  2228     undefinedNames size ~~ 0 ifTrue:[
  2267 	Transcript showCR:'ObjectFileLoader [info]: undefined:'.
  2229 	Transcript showCR:'ObjectFileLoader [info]: undefined:'.
  2268 	undefinedNames do:[:aName |
  2230 	undefinedNames do:[:aName |
  2269 	    Transcript showCR:'    ' , aName
  2231 	    Transcript showCR:'    ' , aName
  2270 	]
  2232 	]
  2271     ].
  2233     ].
  2272 
  2234 
  2273     "Modified: 18.5.1996 / 15:43:45 / cg"
  2235     "Modified: / 18-05-1996 / 15:43:45 / cg"
       
  2236     "Modified: / 01-03-2019 / 16:03:37 / Claus Gittinger"
  2274 !
  2237 !
  2275 
  2238 
  2276 namesMatching:aPattern segment:segmentPattern in:aPathName
  2239 namesMatching:aPattern segment:segmentPattern in:aPathName
  2277     "search for entries which match a pattern.
  2240     "search for entries which match a pattern.
  2278      This is obsolete & rubbish - it will vanish soon"
  2241      This is obsolete & rubbish - it will vanish soon"
  2681     "Modified: 25.4.1996 / 09:46:27 / cg"
  2644     "Modified: 25.4.1996 / 09:46:27 / cg"
  2682 ! !
  2645 ! !
  2683 
  2646 
  2684 !ObjectFileLoader class methodsFor:'linking objects'!
  2647 !ObjectFileLoader class methodsFor:'linking objects'!
  2685 
  2648 
  2686 createLoadableObjectFor:baseFileName
  2649 createLoadableObjectFor:baseFilenameString
  2687     "given an oFile, arrange for it to be loadable.
  2650     "given an oFile, arrange for it to be loadable.
  2688      On ELF systems, this means that it has to be linked with the
  2651      On ELF systems, this means that it has to be linked with the
  2689      -shared option into a .so file;
  2652      -shared option into a .so file;
  2690      DLD based loaders (linux a.out) can directly load a .o file;
  2653      DLD based loaders (linux a.out) can directly load a .o file;
  2691      Other systems may require more ..."
  2654      Other systems may require more ..."
  2692 
  2655 
  2693     |osType oFileName soFileName expFileName librunExpFileName
  2656     |osType baseFilename oFileName soFileName expFileName librunExpFileName
  2694      needSharedObject ld ldArg expFile ok outfile output libDir libDirBasename
  2657      needSharedObject linker ld ldArg expFile ok outfile output libDir libDirBasename
  2695      errorMessage homeDir fmt|
  2658      errorMessage homeDir fmt|
  2696 
  2659 
  2697     osType := OperatingSystem getOSType.
  2660     osType := OperatingSystem getOSType.
       
  2661     baseFilename := baseFilenameString asFilename.
       
  2662 
       
  2663     linker := Filename possiblyQuotedPathname:(self linkCommand).
  2698 
  2664 
  2699     osType = #win32 ifTrue:[
  2665     osType = #win32 ifTrue:[
  2700         self activityNotification:'generating shared object'.
  2666 	self activityNotification:'generating shared object'.
  2701         ParserFlags linkArgs isNil ifTrue:[
  2667 	ParserFlags linkArgs isNil ifTrue:[
  2702             ld := self linkCommand , ' ' , baseFileName , '.obj'.
  2668 	    ld := linker , ' ' , (Filename possiblyQuotedPathname:(baseFilenameString,'.obj')).
  2703             ld := ld
  2669 	    ld := ld
  2704                , ' /NOPACK /NOLOGO /DEBUG /MACHINE:I386 /DLL'
  2670 	       , ' /NOPACK /NOLOGO /DEBUG /MACHINE:I386 /DLL'
  2705                , ' /OUT:' , baseFileName , '.dll '
  2671 	       , ' /OUT:' , (Filename possiblyQuotedPathname:(baseFilenameString,'.dll'))
  2706 "/               , ' /DEF:' , baseFileName , '.def'.
  2672 "/               , ' /DEF:' , baseFileName , '.def'.
  2707         ] ifFalse:[
  2673 	] ifFalse:[
  2708 "/            libDir := ParserFlags libDirectory.
  2674 "/            libDir := ParserFlags libDirectory.
  2709 "/            (libDir notNil and:[libDir asFilename exists]) ifFalse:[
  2675 "/            (libDir notNil and:[libDir asFilename exists]) ifFalse:[
  2710                 ParserFlags useBorlandC ifTrue:[
  2676 		ParserFlags useBorlandC ifTrue:[
  2711                     libDirBasename := 'lib\bc'
  2677 		    libDirBasename := 'lib\bc'
  2712                 ] ifFalse:[
  2678 		] ifFalse:[
  2713                     ParserFlags useVisualC ifTrue:[
  2679 		    ParserFlags useVisualC ifTrue:[
  2714                         libDirBasename := 'lib\vc'
  2680 			libDirBasename := 'lib\vc'
  2715                     ] ifFalse:[
  2681 		    ] ifFalse:[
  2716                         (ParserFlags useMingw32 or:[ParserFlags useMingw64]) ifTrue:[
  2682 			(ParserFlags useMingw32 or:[ParserFlags useMingw64]) ifTrue:[
  2717                             libDirBasename := 'lib\mingw'
  2683 			    libDirBasename := 'lib\mingw'
  2718                         ] ifFalse:[
  2684 			] ifFalse:[
  2719                             libDirBasename := 'lib\vc'
  2685 			    libDirBasename := 'lib\vc'
  2720                         ]
  2686 			]
  2721                     ]
  2687 		    ]
  2722                 ].
  2688 		].
  2723                 homeDir := Smalltalk packagePath detect:[:p | (p asFilename / 'stx' / libDirBasename) exists] ifNone:nil.
  2689 		homeDir := Smalltalk packagePath detect:[:p | (p asFilename / 'stx' / libDirBasename) exists] ifNone:nil.
  2724                 homeDir notNil ifTrue:[
  2690 		homeDir notNil ifTrue:[
  2725                     libDir := (homeDir asFilename / 'stx' / libDirBasename) pathName
  2691 		    libDir := (homeDir asFilename / 'stx' / libDirBasename) pathName
  2726                 ].
  2692 		].
  2727                 libDir isNil ifTrue:[
  2693 		libDir isNil ifTrue:[
  2728                     "/ some fallback
  2694 		    "/ some fallback
  2729                     libDir := #( '..'
  2695 		    libDir := #( '..'
  2730                                  '..\..'
  2696 				 '..\..'
  2731                                  '..\..\..'
  2697 				 '..\..\..'
  2732                                  '..\..\stx'
  2698 				 '..\..\stx'
  2733                                  '..\..\..\stx'
  2699 				 '..\..\..\stx'
  2734                                ) detect:[:p | (p asFilename / libDirBasename) exists] ifNone:nil.
  2700 			       ) detect:[:p | (p asFilename / libDirBasename) exists] ifNone:nil.
  2735 
  2701 
  2736                     libDir isNil ifTrue:[
  2702 		    libDir isNil ifTrue:[
  2737                         LastError := errorMessage := 'could not locate directory where .lib files are (',libDirBasename,')'.
  2703 			LastError := errorMessage := 'could not locate directory where .lib files are (',libDirBasename,')'.
  2738                         ObjectFileLoadError raiseRequestErrorString:errorMessage.
  2704 			ObjectFileLoadError raiseRequestErrorString:errorMessage.
  2739                         ^ nil
  2705 			^ nil
  2740                     ].
  2706 		    ].
  2741                 ].
  2707 		].
  2742 "/            ].
  2708 "/            ].
  2743 
  2709 
  2744             ParserFlags useBorlandC ifTrue:[
  2710 	    ParserFlags useBorlandC ifTrue:[
  2745                 ld := self linkCommand , ' ' , (ParserFlags linkArgs bindWith:baseFileName).
  2711 		ld := linker , ' ' , (ParserFlags linkArgs bindWith:baseFilenameString).
  2746                 ld := ld , ' c0d32.obj ' , baseFileName , '.obj '.
  2712 		ld := ld , ' c0d32.obj ' , (Filename possiblyQuotedPathname:(baseFilenameString , '.obj')).
  2747                 ld := ld , ',' , baseFileName , '.dll,,',libDir,'\librun.lib '.
  2713 		ld := ld , ',' , (Filename possiblyQuotedPathname:(baseFilenameString,'.dll')),',,',libDir,'\librun.lib'.
  2748                 ld := ld , (ParserFlags searchedLibraries asStringCollection asStringWith: $ ).
  2714 		ld := ld , ' ',(ParserFlags searchedLibraries asStringCollection asStringWith: $ ).
  2749                 ld := ld , ' ',libDir,'\cs32i.lib,,'.
  2715 		ld := ld , ' ',libDir,'\cs32i.lib,,'.
  2750             ] ifFalse:[
  2716 	    ] ifFalse:[
  2751                 ParserFlags useVisualC ifTrue:[
  2717 		ParserFlags useVisualC ifTrue:[
  2752                     "/ todo: fix for correct link libs
  2718 		    "/ todo: fix for correct link libs
  2753                     ld := self linkCommand , ' ' , (ParserFlags linkArgs bindWith:baseFileName).
  2719 		    ld := linker , ' ' , (ParserFlags linkArgs bindWith:baseFilenameString).
  2754                     ld := ld , ' c0d32.obj ' , baseFileName , '.obj '.
  2720 		    ld := ld , ' c0d32.obj ' , (Filename possiblyQuotedPathname:(baseFilenameString,'.obj')).
  2755                     ld := ld , ',' , baseFileName , '.dll,,',libDir,'\librun.lib '.
  2721 		    ld := ld , ',' , (Filename possiblyQuotedPathname:(baseFilenameString,'.dll')),',,',libDir,'\librun.lib'.
  2756                     ld := ld , (ParserFlags searchedLibraries asStringCollection asStringWith: $ ).
  2722 		    ld := ld , ' ',(ParserFlags searchedLibraries asStringCollection asStringWith: $ ).
  2757                     ld := ld , ' ',libDir,'\cs32i.lib,,'.
  2723 		    ld := ld , ' ',libDir,'\cs32i.lib,,'.
  2758                 ] ifFalse:[
  2724 		] ifFalse:[
  2759                     (ParserFlags useMingw64 or:[ParserFlags useMingw32]) ifTrue:[
  2725 		    (ParserFlags useMingw64 or:[ParserFlags useMingw32]) ifTrue:[
  2760                         ld := self linkCommand , ' ' , (ParserFlags linkArgs bindWith:baseFileName).
  2726 			ld := linker , ' ' , (ParserFlags linkArgs bindWith:baseFilenameString).
  2761                         ld := ld , ' -shared -o ',baseFileName,'.dll '.
  2727 			ld := ld , ' -shared -o ',(Filename possiblyQuotedPathname:(baseFilenameString,'.dll')).
  2762                         ld := ld , baseFileName,'.obj '.
  2728 			ld := ld , ' ',(Filename possiblyQuotedPathname:(baseFilenameString,'.obj')).
  2763                         ld := ld , libDir,'\librun.lib '.
  2729 			ld := ld , ' ',libDir,'\librun.lib'.
  2764                         ld := ld , (ParserFlags searchedLibraries asStringCollection asStringWith: $ ).
  2730 			ld := ld , ' ',(ParserFlags searchedLibraries asStringCollection asStringWith: $ ).
  2765                     ] ifFalse:[
  2731 		    ] ifFalse:[
  2766                         ObjectFileLoadError raiseRequestErrorString:'for dynamic objects, only borlandC is (currently) supported'.
  2732 			ObjectFileLoadError raiseRequestErrorString:'for dynamic objects, only borlandC is (currently) supported'.
  2767                         LastError := 'for dynamic objects, only borlandC is (currently) supported'.
  2733 			LastError := 'for dynamic objects, only borlandC is (currently) supported'.
  2768                         ^ nil
  2734 			^ nil
  2769                     ]
  2735 		    ]
  2770                 ]
  2736 		]
  2771             ]
  2737 	    ]
  2772         ].
  2738 	].
  2773 
  2739 
  2774         outfile := (baseFileName , '.out').
  2740 	outfile := (Filename possiblyQuotedPathname:(baseFilenameString , '.out')).
  2775         (Verbose or:[ STCCompilerInterface verbose ]) ifTrue:[
  2741 	(Verbose or:[ STCCompilerInterface verbose ]) ifTrue:[
  2776             Transcript showCR:('executing: ',ld).
  2742 	    Transcript showCR:('executing: ',ld).
  2777         ].
  2743 	].
  2778 
  2744 
  2779         ok := OperatingSystem executeCommand:(ld , ' >' , outfile, ' 2>&1') showWindow:false.
  2745 	ok := OperatingSystem executeCommand:(ld , ' >' , outfile, ' 2>&1') showWindow:false.
  2780         ok ifFalse:[
  2746 	ok ifFalse:[
  2781             output := (baseFileName , '.out') asFilename contentsOfEntireFile.
  2747 	    output := (baseFilenameString , '.out') asFilename contentsOfEntireFile.
  2782             Transcript showCR:'********************'.
  2748 	    Transcript showCR:'********************'.
  2783             Transcript showCR:'Failed linkCommand:'.
  2749 	    Transcript showCR:'Failed linkCommand:'.
  2784             Transcript showCR:ld.
  2750 	    Transcript showCR:ld.
  2785             Transcript showCR:'ParserFlags are:'.
  2751 	    Transcript showCR:'ParserFlags are:'.
  2786             Transcript showCR:ParserFlags.
  2752 	    Transcript showCR:ParserFlags.
  2787             Transcript showCR:'--------------------'.
  2753 	    Transcript showCR:'--------------------'.
  2788             Transcript showCR:output; endEntry.
  2754 	    Transcript showCR:output; endEntry.
  2789             Transcript showCR:'********************'.
  2755 	    Transcript showCR:'********************'.
  2790         ].
  2756 	].
  2791 
  2757 
  2792         #('.obj' '.out' '.tds' '.ilc' '.ild'
  2758 	#('obj' 'out' 'tds' 'ilc' 'ild'
  2793           '.ilf' '.ils' '.lib' '.map' '.def' '.o') do:[:eachSuffix|
  2759 	  'ilf' 'ils' 'lib' 'map' 'def' 'o') do:[:eachSuffix|
  2794             (baseFileName , eachSuffix) asFilename remove.
  2760 	    (baseFilename withSuffix:eachSuffix) removeFile.
  2795         ].
  2761 	].
  2796 
  2762 
  2797         ok ifFalse:[
  2763 	ok ifFalse:[
  2798             LastError := output.
  2764 	    LastError := output.
  2799             "/ ObjectFileLoadError raiseRequestErrorString:'link failed'.
  2765 	    "/ ObjectFileLoadError raiseRequestErrorString:'link failed'.
  2800             ^ nil
  2766 	    ^ nil
  2801         ].
  2767 	].
  2802         oFileName := (baseFileName , self sharedLibraryExtension) asFilename name.
  2768 	oFileName := (baseFilename withSuffix:self sharedLibrarySuffix) name.
  2803         ^ oFileName
  2769 	^ oFileName
  2804     ].
  2770     ].
  2805 
  2771 
  2806     "/ UNIX systems
  2772     "/ UNIX systems
  2807 
  2773 
  2808     ld := self linkCommand ? 'ld'.
  2774     ld := linker ? 'ld'.
  2809     needSharedObject := false.
  2775     needSharedObject := false.
  2810 
  2776 
  2811     fmt := self loadableBinaryObjectFormat.
  2777     fmt := self loadableBinaryObjectFormat.
  2812     (fmt == #elf
  2778     (fmt == #elf or:[ fmt == #macho ]) ifTrue:[
  2813     or:[ fmt == #macho ]) ifTrue:[
  2779 	"
  2814         "
  2780 	 link it to a shared object with 'ld -shared'
  2815          link it to a shared object with 'ld -shared'
  2781 	"
  2816         "
  2782 	needSharedObject := true.
  2817         needSharedObject := true.
  2783 	ld := linker ? 'cc'.
  2818         ld := self linkCommand ? 'cc'.
  2784 	ldArg := self linkSharedArgs.
  2819         ldArg := self linkSharedArgs.
  2785 	ldArg isNil ifTrue:[
  2820         ldArg isNil ifTrue:[
  2786 	    "/ some default
  2821             "/ some default
  2787 	    ExternalBytes sizeofPointer == 4 ifTrue:[
  2822             ExternalAddress pointerSize == 4 ifTrue:[
  2788 		ldArg := '-m32 -shared'.
  2823                 ldArg := '-m32 -shared'.
  2789 	    ] ifFalse:[
  2824             ] ifFalse:[
  2790 		ldArg := '--shared'.
  2825                 ldArg := '--shared'.
  2791 	    ]
  2826             ]
  2792 	]
  2827         ]
       
  2828     ].
  2793     ].
  2829 
  2794 
  2830     osType = #irix ifTrue:[
  2795     osType = #irix ifTrue:[
  2831         "
  2796 	"
  2832          link it to a shared object with 'ld -shared'
  2797 	 link it to a shared object with 'ld -shared'
  2833         "
  2798 	"
  2834         needSharedObject := true.
  2799 	needSharedObject := true.
  2835         ldArg := self linkSharedArgs ? '-shared'.
  2800 	ldArg := self linkSharedArgs ? '-shared'.
  2836     ].
  2801     ].
  2837 
  2802 
  2838     osType = #'sys5_4' ifTrue:[
  2803     osType = #'sys5_4' ifTrue:[
  2839         "
  2804 	"
  2840          link it to a shared object with 'ld -G'
  2805 	 link it to a shared object with 'ld -G'
  2841         "
  2806 	"
  2842         needSharedObject := true.
  2807 	needSharedObject := true.
  2843         ldArg := self linkSharedArgs ? '-G'.
  2808 	ldArg := self linkSharedArgs ? '-G'.
  2844     ].
  2809     ].
  2845 
  2810 
  2846     osType = #solaris ifTrue:[
  2811     osType = #solaris ifTrue:[
  2847         "
  2812 	"
  2848          link it to a shared object with 'ld -G -B dynamic'
  2813 	 link it to a shared object with 'ld -G -B dynamic'
  2849         "
  2814 	"
  2850         needSharedObject := true.
  2815 	needSharedObject := true.
  2851         ldArg := self linkSharedArgs ? '-G -Bdynamic'.
  2816 	ldArg := self linkSharedArgs ? '-G -Bdynamic'.
  2852     ].
  2817     ].
  2853 
  2818 
  2854     osType = #hpux ifTrue:[
  2819     osType = #hpux ifTrue:[
  2855         "
  2820 	"
  2856          link it to a shared object with 'ld -b -B immediate'
  2821 	 link it to a shared object with 'ld -b -B immediate'
  2857         "
  2822 	"
  2858         needSharedObject := true.
  2823 	needSharedObject := true.
  2859         ldArg := self linkSharedArgs ? '-b -B immediate'.
  2824 	ldArg := self linkSharedArgs ? '-b -B immediate'.
  2860     ].
  2825     ].
  2861 
  2826 
  2862     osType = #aix ifTrue:[
  2827     osType = #aix ifTrue:[
  2863         self activityNotification:'create export file'.
  2828 	self activityNotification:'create export file'.
  2864 
  2829 
  2865         "/ create an exports file.
  2830 	"/ create an exports file.
  2866         expFileName := './' , baseFileName , '.exp'.
  2831 	expFileName := './' , baseFilenameString , '.exp'.
  2867         [
  2832 	[
  2868             expFile := expFileName asFilename writeStream.
  2833 	    expFile := expFileName asFilename writeStream.
  2869             expFile nextPutAll:'#!! ./' , baseFileName , (self sharedLibraryExtension).
  2834 	    expFile nextPutAll:'#!! ./' , baseFilenameString , '.', self sharedLibrarySuffix.
  2870             expFile cr.
  2835 	    expFile cr.
  2871             expFile nextPutAll:'_' , baseFileName , '_Init'.
  2836 	    expFile nextPutAll:'_' , baseFilenameString , '_Init'.
  2872             expFile close.
  2837 	    expFile close.
  2873         ] on:FileStream openErrorSignal do:[:ex| "do nothing"].
  2838 	] on:OpenError do:[:ex| "do nothing"].
  2874 
  2839 
  2875         self activityNotification:'generating shared object'.
  2840 	self activityNotification:'generating shared object'.
  2876 
  2841 
  2877         "
  2842 	"
  2878          link it to a shared object with 'cc -bI:...librun.exp -bE -bMSRE'
  2843 	 link it to a shared object with 'cc -bI:...librun.exp -bE -bMSRE'
  2879         "
  2844 	"
  2880         needSharedObject := true.
  2845 	needSharedObject := true.
  2881         ld := 'cc'.
  2846 	ld := 'cc'.
  2882         librunExpFileName := Smalltalk getSystemFileName:'lib/librun_aix.exp'.
  2847 	librunExpFileName := Smalltalk getSystemFileName:'lib/librun_aix.exp'.
  2883         librunExpFileName isNil ifTrue:[
  2848 	librunExpFileName isNil ifTrue:[
  2884             LastError := 'missing exports file: ''lib/librun_aix.exp'' - cannot link'.
  2849 	    LastError := 'missing exports file: ''lib/librun_aix.exp'' - cannot link'.
  2885             ^ nil
  2850 	    ^ nil
  2886         ].
  2851 	].
  2887 
  2852 
  2888         ldArg := '-bI:' , librunExpFileName ,
  2853 	ldArg := '-bI:' , librunExpFileName ,
  2889                 ' -bE:' , baseFileName , '.exp' ,
  2854 		' -bE:' , baseFilenameString , '.exp' ,
  2890                 ' -bM:SRE -e _' , baseFileName , '_Init'.
  2855 		' -bM:SRE -e _' , baseFilenameString , '_Init'.
  2891     ].
  2856     ].
  2892 
  2857 
  2893     oFileName := baseFileName , self objectFileExtension.
  2858     oFileName := baseFilename withSuffix:self objectFileSuffix.
  2894     needSharedObject ifTrue:[
  2859     needSharedObject ifTrue:[
  2895         self activityNotification:'generating shared object'.
  2860 	self activityNotification:'generating shared object'.
  2896 
  2861 
  2897         soFileName := baseFileName , self sharedLibraryExtension.
  2862 	soFileName := baseFilename withSuffix:self sharedLibrarySuffix.
  2898         OperatingSystem removeFile:soFileName.
  2863 	soFileName removeFile.
  2899         ld := ld , ' ' , ldArg , ' ', (ParserFlags linkArgs ? '') ,
  2864 
  2900                  ' -o ' , soFileName , ' ' , oFileName , ' ',
  2865 	ld := ld , ' ' , ldArg , ' ', (ParserFlags linkArgs ? '') ,
  2901                  ((ParserFlags searchedLibraries  ? #()) asStringCollection asStringWith: $ ).
  2866 		 ' -o ' , soFileName name, ' ' , oFileName name , ' ',
  2902 
  2867 		 ((ParserFlags searchedLibraries  ? #()) asStringCollection asStringWith: $ ).
  2903         (Verbose or:[ STCCompilerInterface verbose ]) ifTrue:[
  2868 
  2904             Transcript showCR:('linking with: ',ld).
  2869 	(Verbose or:[ STCCompilerInterface verbose ]) ifTrue:[
  2905         ].
  2870 	    Transcript showCR:('linking with: ',ld).
  2906         ok := OperatingSystem executeCommand:(ld , ' >errorOutput 2>&1').
  2871 	].
  2907 
  2872 	ok := OperatingSystem executeCommand:(ld , ' >errorOutput 2>&1').
  2908         ok ifFalse:[
  2873 
  2909             output := 'errorOutput' asFilename contentsOfEntireFile.
  2874 	ok ifFalse:[
  2910             Transcript showCR:'********************'.
  2875 	    output := 'errorOutput' asFilename contentsOfEntireFile.
  2911             Transcript showCR:'linker command:'.
  2876 	    Transcript showCR:'********************'.
  2912             Transcript showCR:ld; endEntry.
  2877 	    Transcript showCR:'linker command:'.
  2913             Transcript showCR:'--------------------'.
  2878 	    Transcript showCR:ld; endEntry.
  2914             Transcript showCR:'linker error message:'.
  2879 	    Transcript showCR:'--------------------'.
  2915             Transcript showCR:output.
  2880 	    Transcript showCR:'linker error message:'.
  2916             Transcript showCR:'********************'.
  2881 	    Transcript showCR:output.
  2917         ].
  2882 	    Transcript showCR:'********************'.
  2918 
  2883 	].
  2919         OperatingSystem removeFile:oFileName.
  2884 
  2920         expFileName notNil ifTrue:[
  2885 	oFileName removeFile.
  2921             OperatingSystem removeFile:expFileName
  2886 	expFileName notNil ifTrue:[
  2922         ].
  2887 	    expFileName asFilename removeFile.
  2923         ^ soFileName.
  2888 	].
       
  2889 	^ soFileName name.
  2924     ].
  2890     ].
  2925 
  2891 
  2926     "
  2892     "
  2927      assume we can load an ordinary binary
  2893      assume we can load an ordinary binary
  2928     "
  2894     "
  2929     ^ oFileName
  2895     ^ oFileName
  2930 
  2896 
  2931     "Modified: / 29-07-2004 / 17:29:44 / stefan"
  2897     "Modified: / 29-07-2004 / 17:29:44 / stefan"
  2932     "Modified: / 25-02-2017 / 09:18:42 / cg"
  2898     "Modified: / 25-02-2017 / 09:18:42 / cg"
       
  2899     "Modified: / 28-03-2019 / 16:29:48 / Claus Gittinger"
       
  2900     "Modified (format): / 10-04-2019 / 06:18:38 / Claus Gittinger"
  2933 ! !
  2901 ! !
  2934 
  2902 
  2935 !ObjectFileLoader class methodsFor:'lowlevel object loading'!
  2903 !ObjectFileLoader class methodsFor:'lowlevel object loading'!
  2936 
  2904 
  2937 initializeLoader
  2905 initializeLoader
  2993             pathName := pathNameOrFilename asString.
  2961             pathName := pathNameOrFilename asString.
  2994         ].
  2962         ].
  2995     ].
  2963     ].
  2996 
  2964 
  2997     Verbose ifTrue:[
  2965     Verbose ifTrue:[
  2998 	('loadDynamic: ',pathNameOrFilename asString,' (',pathName asString,')...') errorPrintCR
  2966         ('loadDynamic: ',pathNameOrFilename asString,' (',pathName asString,')...') errorPrintCR
  2999     ].
  2967     ].
  3000     encodedPathName := OperatingSystem encodePath:pathName.
  2968     encodedPathName := OperatingSystem encodePath:pathName.
  3001 
  2969 
  3002     "/ already loaded ?
  2970     "/ already loaded ?
  3003     handle := self handleForDynamicObject:encodedPathName.
  2971     handle := self handleForDynamicObject:encodedPathName.
  3004     handle notNil ifTrue:[
  2972     handle notNil ifTrue:[
  3005 	Verbose ifTrue:[
  2973         Verbose ifTrue:[
  3006             ('... ' , pathName asString , ' already loaded.') errorPrintCR.
  2974             ('... ' , pathName asString , ' already loaded.') errorPrintCR.
  3007 	].
  2975         ].
  3008 	^ handle
  2976         ^ handle
  3009     ].
  2977     ].
  3010 
  2978 
  3011     Verbose ifTrue:[
  2979     Verbose ifTrue:[
  3012 	('initializeLoader...') errorPrintCR
  2980         ('initializeLoader...') errorPrintCR
  3013     ].
  2981     ].
  3014     self initializeLoader.
  2982     self initializeLoader.
  3015 
  2983 
  3016     "/
  2984     "/
  3017     "/ the 1st two entries are system dependent;
  2985     "/ the 1st two entries are system dependent;
  3021     buffer := Array new:4.
  2989     buffer := Array new:4.
  3022     buffer at:3 put:pathName.
  2990     buffer at:3 put:pathName.
  3023     buffer at:4 put:NextHandleID. NextHandleID := NextHandleID + 1.
  2991     buffer at:4 put:NextHandleID. NextHandleID := NextHandleID + 1.
  3024 
  2992 
  3025     Verbose ifTrue:[
  2993     Verbose ifTrue:[
  3026 	('primLoadDynamicObject...') errorPrintCR
  2994         ('primLoadDynamicObject...') errorPrintCR
  3027     ].
  2995     ].
  3028 
  2996 
  3029     buffer := self primLoadDynamicObject:encodedPathName into:buffer.
  2997     buffer := self primLoadDynamicObject:encodedPathName into:buffer.
  3030     Verbose ifTrue:[
  2998     Verbose ifTrue:[
  3031 	('done') errorPrintCR
  2999         ('done') errorPrintCR
  3032     ].
  3000     ].
  3033 
  3001 
  3034     buffer isNil ifTrue:[
  3002     buffer isNil ifTrue:[
  3035 	LastError == #notImplemented ifTrue:[
  3003         LastError == #notImplemented ifTrue:[
  3036 	    'ObjectFileLoader [warning]: no dynamic load facility present.' infoPrintCR.
  3004             'ObjectFileLoader [warning]: no dynamic load facility present.' infoPrintCR.
  3037 	] ifFalse:[
  3005         ] ifFalse:[
  3038 	    LastError == #linkError ifTrue:[
  3006             LastError == #linkError ifTrue:[
  3039 		LinkErrorMessage notNil ifTrue:[
  3007                 LinkErrorMessage notNil ifTrue:[
  3040 		    ('ObjectFileLoader [warning]: load error:' , LinkErrorMessage) infoPrintCR.
  3008                     ('ObjectFileLoader [warning]: load error:' , LinkErrorMessage) infoPrintCR.
  3041 		] ifFalse:[
  3009                 ] ifFalse:[
  3042 		    ('ObjectFileLoader [warning]: load error') infoPrintCR.
  3010                     ('ObjectFileLoader [warning]: load error') infoPrintCR.
  3043 		].
  3011                 ].
  3044 	    ].
  3012             ].
  3045 	].
  3013         ].
  3046         Logger warning: 'failed to load ''%1''' with: pathName.
  3014         Logger warning: 'failed to load ''%1''' with: pathName.
  3047 	^ nil
  3015         ^ nil
  3048     ].
  3016     ].
  3049 
  3017 
  3050     "
  3018     "
  3051      remember loaded object for later unloading
  3019      remember loaded object for later unloading
  3052     "
  3020     "
  3055     handle sysHandle2:(buffer at:2).
  3023     handle sysHandle2:(buffer at:2).
  3056     handle pathName:(buffer at:3).
  3024     handle pathName:(buffer at:3).
  3057     handle moduleID:(buffer at:4).
  3025     handle moduleID:(buffer at:4).
  3058 
  3026 
  3059     LoadedObjects isNil ifTrue:[
  3027     LoadedObjects isNil ifTrue:[
  3060 	LoadedObjects := Dictionary new.
  3028         LoadedObjects := Dictionary new.
  3061     ].
  3029     ].
  3062     LoadedObjects at:pathName put:handle.
  3030     LoadedObjects at:pathName put:handle.
  3063     "/ Smalltalk flushCachedClasses.
  3031     "/ Smalltalk flushCachedClasses.
  3064 
  3032 
  3065     Verbose ifTrue:[
  3033     Verbose ifTrue:[
  3066 	('loadDynamic ok; handle is: ' , handle printString) errorPrintCR.
  3034         ('loadDynamic ok; handle is: ' , handle printString) errorPrintCR.
  3067     ].
  3035     ].
  3068     "/ ObjectMemory garbageCollect.
  3036     "/ ObjectMemory garbageCollect.
  3069 
  3037 
  3070     ^ handle
  3038     ^ handle
  3071 
  3039 
  3177     HINSTANCE handle;
  3145     HINSTANCE handle;
  3178     int err;
  3146     int err;
  3179 
  3147 
  3180     if (__isStringLike(pathName)) {
  3148     if (__isStringLike(pathName)) {
  3181 	if (@global(Verbose) == true) {
  3149 	if (@global(Verbose) == true) {
  3182 	    console_fprintf(stderr, "ObjectFileLoader [info]: loading dll: %s...\n", __stringVal(pathName));
  3150 	    console_fprintf(__win32_stderr(), "ObjectFileLoader [info]: loading dll: %s...\n", __stringVal(pathName));
  3183 	    console_fflush(stderr);
  3151 	    console_fflush(__win32_stderr());
  3184 	}
  3152 	}
  3185 	//
  3153 	//
  3186 	// LOAD_WITH_ALTERED_SEARCH_PATH causes follow-up dlls to be looked up also
  3154 	// LOAD_WITH_ALTERED_SEARCH_PATH causes follow-up dlls to be looked up also
  3187 	// in the directory of the loaded library, if an absolute path to
  3155 	// in the directory of the loaded library, if an absolute path to
  3188 	// the library has been provided.
  3156 	// the library has been provided.
  3189 	// Note: this does not work for redirected library symbols, since they are
  3157 	// Note: this does not work for redirected library symbols, since they are
  3190 	//       resolved ad symbol lookup time and not at library load time
  3158 	//       resolved ad symbol lookup time and not at library load time
  3191 	//
  3159 	//
  3192 	handle = LoadLibraryEx(__stringVal(pathName), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  3160 	handle = LoadLibraryEx(__stringVal(pathName), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  3193 	if (@global(Verbose) == true) {
  3161 	if (@global(Verbose) == true) {
  3194 	    console_fprintf(stderr, "ObjectFileLoader [info]: handle: %"_lx_"\n", (INT)handle);
  3162 	    console_fprintf(__win32_stderr(), "ObjectFileLoader [info]: handle: %"_lx_"\n", (INT)handle);
  3195 	    console_fflush(stderr);
  3163 	    console_fflush(__win32_stderr());
  3196 	}
  3164 	}
  3197 	if (handle == NULL) {
  3165 	if (handle == NULL) {
  3198 	    char *msg;
  3166 	    char *msg;
  3199 
  3167 
  3200 	    err = GetLastError();
  3168 	    err = GetLastError();
  3201 	    if ((@global(ErrorPrinting) == true)
  3169 	    if ((@global(ErrorPrinting) == true)
  3202 	     || (@global(Verbose) == true)) {
  3170 	     || (@global(Verbose) == true)) {
  3203 		console_fprintf (stderr,
  3171 		console_fprintf (__win32_stderr(),
  3204 				 "ObjectFileLoader [warning]: LoadLibrary %s failed; error: %x\n",
  3172 				 "ObjectFileLoader [warning]: LoadLibrary %s failed; error: %x\n",
  3205 				 __stringVal(pathName), err);
  3173 				 __stringVal(pathName), err);
  3206 	    }
  3174 	    }
  3207 	    @global(LastError) = @symbol(loadError);;
  3175 	    @global(LastError) = @symbol(loadError);;
  3208 	    @global(LastErrorNumber) = __MKINT(__WIN32_ERR(err));
  3176 	    @global(LastErrorNumber) = __MKINT(__WIN32_ERR(err));
  3215 	    }
  3183 	    }
  3216 	    @global(LinkErrorMessage) = __MKSTRING(msg);
  3184 	    @global(LinkErrorMessage) = __MKSTRING(msg);
  3217 	    RETURN ( nil );
  3185 	    RETURN ( nil );
  3218 	}
  3186 	}
  3219 # if __POINTER_SIZE__ == 8
  3187 # if __POINTER_SIZE__ == 8
  3220 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (INT)handle & 0xFFFFFFFFL );
  3188 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (UINT)handle & 0xFFFFFFFFL );
  3221 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( ((INT)handle >> 32) & 0xFFFFFFFFL );
  3189 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( ((UINT)handle >> 32) & 0xFFFFFFFFL );
  3222 # else
  3190 # else
  3223 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (INT)handle & 0xFFFF );
  3191 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (UINT)handle & 0xFFFF );
  3224 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( ((INT)handle >> 16) & 0xFFFF );
  3192 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( ((UINT)handle >> 16) & 0xFFFF );
  3225 # endif
  3193 # endif
  3226 	RETURN ( anInfoBuffer );
  3194 	RETURN ( anInfoBuffer );
  3227     }
  3195     }
  3228     /*
  3196     /*
  3229      * Unlike POSIX.1-2001 dlopen(), Windows has no such handle that
  3197      * Unlike POSIX.1-2001 dlopen(), Windows has no such handle that
  3236      */
  3204      */
  3237     if (pathName == nil) {
  3205     if (pathName == nil) {
  3238 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( 0 );
  3206 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( 0 );
  3239 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( 0 );
  3207 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( 0 );
  3240 	RETURN ( anInfoBuffer );
  3208 	RETURN ( anInfoBuffer );
  3241     }
       
  3242     RETURN ( nil );
       
  3243   }
       
  3244 #endif
       
  3245 
       
  3246 #ifdef BEOS_DL
       
  3247   {
       
  3248     void *handle;
       
  3249     int err;
       
  3250 
       
  3251     if (__isStringLike(pathName)) {
       
  3252 	if (@global(Verbose) == true) {
       
  3253 	    console_fprintf(stderr, "ObjectFileLoader [info]: loading : %s...\n", __stringVal(pathName));
       
  3254 	    console_fflush(stderr);
       
  3255 	}
       
  3256 	handle = load_add_on(__stringVal(pathName));
       
  3257 	if (@global(Verbose) == true) {
       
  3258 	    console_fprintf(stderr, "ObjectFileLoader [info]: handle: %x\n", handle);
       
  3259 	    console_fflush(stderr);
       
  3260 	}
       
  3261 	if (handle == NULL) {
       
  3262 	    char *msg;
       
  3263 
       
  3264 	    @global(LastError) = @symbol(linkError);
       
  3265 	    @global(LinkErrorMessage) = __MKSTRING("unknown error");
       
  3266 	    RETURN ( nil );
       
  3267 	}
       
  3268 # if __POINTER_SIZE__ == 8
       
  3269 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (INT)handle & 0xFFFFFFFF );
       
  3270 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( ((INT)handle >> 32) & 0xFFFFFFFF );
       
  3271 # else
       
  3272 	__ArrayInstPtr(anInfoBuffer)->a_element[0] = __MKSMALLINT( (INT)handle & 0xFFFF );
       
  3273 	__ArrayInstPtr(anInfoBuffer)->a_element[1] = __MKSMALLINT( ((INT)handle >> 16) & 0xFFFF );
       
  3274 	RETURN ( anInfoBuffer );
       
  3275 # endif
       
  3276     }
  3209     }
  3277     RETURN ( nil );
  3210     RETURN ( nil );
  3278   }
  3211   }
  3279 #endif
  3212 #endif
  3280 
  3213 
  3559     }
  3492     }
  3560     RETURN (false);
  3493     RETURN (false);
  3561 #endif
  3494 #endif
  3562 
  3495 
  3563 #ifdef WIN_DL
  3496 #ifdef WIN_DL
  3564     INT val;
  3497 # if defined(__BORLANDC__)
  3565     HINSTANCE handle;
  3498     // FreeLibrary in Borland C calls exit, catches it with setjmp()
  3566     int err;
  3499     // but hangs after this.
  3567     jmp_buf exitJmpBuf;
  3500     if (@global(Verbose) == true) {
  3568 
  3501 	console_fprintf (__win32_stderr(),
       
  3502 			 "ObjectFileLoader [info]: FreeLibrary is not supported in Borland C\n");
       
  3503     }
       
  3504     RETURN (true);
       
  3505 # else // ! __BORLAND_C__
  3569     if (__bothSmallInteger(sysHandle1, sysHandle2)) {
  3506     if (__bothSmallInteger(sysHandle1, sysHandle2)) {
       
  3507 	UINT val;
       
  3508 	HINSTANCE handle;
       
  3509 	int err;
       
  3510 	jmp_buf exitJmpBuf;
       
  3511 
  3570 # if __POINTER_SIZE__ == 8
  3512 # if __POINTER_SIZE__ == 8
  3571 	val = (_intVal(sysHandle2) << 32) + _intVal(sysHandle1);
  3513 	val = ((UINT)_intVal(sysHandle2) << 32) + (UINT)_intVal(sysHandle1);
  3572 # else
  3514 # else
  3573 	val = (_intVal(sysHandle2) << 16) + _intVal(sysHandle1);
  3515 	val = ((UINT)_intVal(sysHandle2) << 16) + (UINT)_intVal(sysHandle1);
  3574 # endif
  3516 # endif
  3575 	handle = (HINSTANCE)(val);
  3517 	handle = (HINSTANCE)val;
  3576 
  3518 
  3577 	if (setjmp(exitJmpBuf)) {
  3519 	if (!setjmp(exitJmpBuf)) {
  3578 	    __setAtExitLongJmp(exitJmpBuf);
  3520 	    __setAtExitLongJmp(exitJmpBuf);
  3579 	    if (@global(Verbose) == true) {
  3521 	    if (@global(Verbose) == true) {
  3580 		console_fprintf (stderr,
  3522 		console_fprintf (__win32_stderr(),
  3581 				 "ObjectFileLoader [info]: FreeLibrary %s handle: %"_lx_"\n",
  3523 				 "ObjectFileLoader [info]: FreeLibrary handle: %"_lx_"\n",
  3582 				 __stringVal(sysHandle1), (INT)handle);
  3524 				 (INT)handle);
  3583 	    }
  3525 	    }
  3584 	    if (FreeLibrary(handle) != TRUE) {
  3526 	    if (FreeLibrary(handle) != TRUE) {
  3585 	       __setAtExitLongJmp(0);
  3527 		__setAtExitLongJmp(0);
  3586 		err = GetLastError();
  3528 		err = GetLastError();
  3587 		if (@global(Verbose) == true) {
  3529 		if (@global(Verbose) == true) {
  3588 		    console_fprintf (stderr,
  3530 		    console_fprintf (__win32_stderr(),
  3589 				     "ObjectFileLoader [warning]: FreeLibrary %s failed; error: %x\n",
  3531 				     "ObjectFileLoader [warning]: FreeLibrary failed; error: %x\n",
  3590 				     __stringVal(sysHandle1), err);
  3532 				     err);
  3591 		}
  3533 		}
  3592 		@global(LastErrorNumber) = __MKINT(__WIN32_ERR(err));
  3534 		@global(LastErrorNumber) = __MKINT(__WIN32_ERR(err));
  3593 		RETURN (false);
  3535 		RETURN (false);
  3594 	    }
  3536 	    } else {
  3595        } else {
  3537 		__setAtExitLongJmp(0);
  3596 	   __setAtExitLongJmp(0);
       
  3597 	   console_fprintf(stderr, "ObjectFileLoader [warning]: FreeLibrary called exit() - ignored\n");
       
  3598        }
       
  3599 	RETURN (true);
       
  3600     }
       
  3601     RETURN (false);
       
  3602 #endif
       
  3603 
       
  3604 #ifdef BEOS_DL
       
  3605     int val;
       
  3606     void *handle;
       
  3607     int ok, err;
       
  3608     jmp_buf exitJmpBuf;
       
  3609 
       
  3610     if (__bothSmallInteger(sysHandle1, sysHandle2)) {
       
  3611 	val = (_intVal(sysHandle2) << 16) + _intVal(sysHandle1);
       
  3612 	handle = (HINSTANCE)(val);
       
  3613 
       
  3614 	if (setjmp(exitJmpBuf)) {
       
  3615 	    __setAtExitLongJmp(exitJmpBuf);
       
  3616 	    ok = unload_add_on((image_id) handle);
       
  3617 	    __setAtExitLongJmp(0);
       
  3618 	    if (ok != 0) {
       
  3619 		@global(LastErrorNumber) = __MKSMALLINT(ok);
       
  3620 		RETURN (false);
       
  3621 	    }
  3538 	    }
  3622 	} else {
  3539 	} else {
       
  3540 	    // arrive here if FreeLibrary does exit
  3623 	    __setAtExitLongJmp(0);
  3541 	    __setAtExitLongJmp(0);
  3624 	    console_fprintf(stderr, "ObjectFileLoader [warning]: FreeLibrary called exit() - ignored\n");
  3542 	    console_fprintf(__win32_stderr(), "ObjectFileLoader [warning]: FreeLibrary called exit() - ignored\n");
  3625 	}
  3543 	}
  3626 	RETURN (true);
  3544 	RETURN (true);
  3627     }
  3545      }
  3628     RETURN (false);
  3546      RETURN (false);
  3629 #endif
  3547 # endif // !defined(__BORLAND_C__)
       
  3548 #endif // WIN_DL
  3630 
  3549 
  3631 #ifdef SYSV4_DL
  3550 #ifdef SYSV4_DL
  3632   {
  3551   {
  3633     void *h;
  3552     if (__bothSmallInteger(sysHandle1, sysHandle2)) {
  3634     INT val;
  3553 	void *handle;
  3635     OBJ low = sysHandle1, hi = sysHandle2;
  3554 	unsigned INT val;
  3636 
  3555 
  3637     if (__bothSmallInteger(low, hi)) {
       
  3638 #if __POINTER_SIZE__ == 8
  3556 #if __POINTER_SIZE__ == 8
  3639 	val = (__intVal(hi) << 32) + __intVal(low);
  3557 	val = ((unsigned INT)__intVal(sysHandle2) << 32) + (unsigned INT)__intVal(sysHandle1);
  3640 #else
  3558 #else
  3641 	val = (_intVal(hi) << 16) + _intVal(low);
  3559 	val = ((unsigned INT)_intVal(sysHandle2) << 16) + (unsigned INT)_intVal(sysHandle1);
  3642 #endif
  3560 #endif
  3643 	h = (void *)(val);
  3561 	handle = (void *)(val);
  3644 	if (@global(Verbose) == true)
  3562 	if (@global(Verbose) == true)
  3645 	    console_printf("close handle = %"_lx_"\n", (INT)h);
  3563 	    console_printf("close handle = %p\n", handle);
  3646 	if (dlclose(h) != 0) {
  3564 	if (dlclose(handle) != 0) {
  3647 	    console_fprintf(stderr, "dlclose failed with:<%s>\n", dlerror());
  3565 	    console_fprintf(stderr, "dlclose failed with:<%s>\n", dlerror());
  3648 	    RETURN (false);
  3566 	    RETURN (false);
  3649 	}
  3567 	}
  3650 	RETURN (true);
  3568 	RETURN (true);
  3651     }
  3569     }
  3714     console_fprintf(stderr, "ObjectFileLoader [warning]: Sorry, NeXTStep does not support selective unloading\n");
  3632     console_fprintf(stderr, "ObjectFileLoader [warning]: Sorry, NeXTStep does not support selective unloading\n");
  3715   }
  3633   }
  3716 #endif
  3634 #endif
  3717 %}.
  3635 %}.
  3718     ^ false
  3636     ^ false
       
  3637 
       
  3638     "Modified: / 13-02-2020 / 15:46:13 / Stefan Vogel"
  3719 !
  3639 !
  3720 
  3640 
  3721 unloadDynamicObject:handle
  3641 unloadDynamicObject:handle
  3722     "close an object-file (unmap from my address space)
  3642     "close an object-file (unmap from my address space)
  3723      and remove the entry from the remembered object file set.
  3643      and remove the entry from the remembered object file set.
  3724      This is a low-level entry, which does not care if there are
  3644      This is a low-level entry, which does not care if there are
  3725      still any code references (from blocks or methods) to this
  3645      still any code references (from blocks or methods) to this
  3726      module. Calling it for still living classes will definitely
  3646      module. Calling it for still living classes will definitely
  3727      lead to some fatal conditions to occur later."
  3647      lead to some fatal conditions to occur later."
  3728 
  3648 
  3729     |key fileName functionName deInitAddr m|
  3649     |key fileName functionName deInitAddr method|
  3730 
  3650 
  3731     Verbose ifTrue:[
  3651     Verbose ifTrue:[
  3732 	'unload module name=' errorPrint. handle pathName errorPrintCR.
  3652 	'unload module name=' errorPrint. handle pathName errorPrintCR.
  3733     ].
  3653     ].
  3734 
  3654 
  3822     "
  3742     "
  3823      for individual methods, we keep the methodObject,
  3743      for individual methods, we keep the methodObject,
  3824      but make it unexecutable. Its still visible in the browser.
  3744      but make it unexecutable. Its still visible in the browser.
  3825     "
  3745     "
  3826     handle isMethodHandle ifTrue:[
  3746     handle isMethodHandle ifTrue:[
  3827 	((m := handle method) notNil
  3747 	method := handle method.
  3828 	and:[m ~~ 0]) ifTrue:[
  3748 	(method  notNil and:[method ~~ 0]) ifTrue:[
  3829 	    m makeUnloaded.
  3749 	    method makeUnloaded.
  3830 	]
  3750 	].
       
  3751 	ObjectMemory flushCaches.
  3831     ].
  3752     ].
  3832 
  3753 
  3833     handle isClassLibHandle ifTrue:[
  3754     handle isClassLibHandle ifTrue:[
  3834 	Smalltalk flushCachedClasses.
  3755 	Smalltalk flushCachedClasses.
  3835 	Class flushSubclassInfo.
  3756 	Class flushSubclassInfo.
  3836     ].
       
  3837     handle isMethodHandle ifTrue:[
       
  3838 	ObjectMemory flushCaches.
       
  3839     ].
  3757     ].
  3840 
  3758 
  3841     handle moduleID:nil.
  3759     handle moduleID:nil.
  3842     handle sysHandle1:nil.
  3760     handle sysHandle1:nil.
  3843     handle sysHandle2:nil.
  3761     handle sysHandle2:nil.
  3870             ].
  3788             ].
  3871 
  3789 
  3872             "/ Old way: now obsolete and will wanish soon.
  3790             "/ Old way: now obsolete and will wanish soon.
  3873             binaryClassLibraryFilename exists ifFalse:[
  3791             binaryClassLibraryFilename exists ifFalse:[
  3874                 "/ mhmh - is this a good idea ? (temporary kludge)
  3792                 "/ mhmh - is this a good idea ? (temporary kludge)
  3875                 ExternalAddress pointerSize == 4 ifTrue:[
  3793                 ExternalBytes sizeofPointer == 4 ifTrue:[
  3876                     binaryClassLibraryFilename := dir / 'objbc' / shLibName.
  3794                     binaryClassLibraryFilename := dir / 'objbc' / shLibName.
  3877                     binaryClassLibraryFilename exists ifFalse:[
  3795                     binaryClassLibraryFilename exists ifFalse:[
  3878                         binaryClassLibraryFilename := dir / 'objvc' / shLibName.
  3796                         binaryClassLibraryFilename := dir / 'objvc' / shLibName.
  3879                                     binaryClassLibraryFilename exists ifFalse:[
  3797                                     binaryClassLibraryFilename exists ifFalse:[
  3880                                         binaryClassLibraryFilename := dir / 'objmingw' / shLibName.
  3798                                         binaryClassLibraryFilename := dir / 'objmingw' / shLibName.