1224 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 |
1225 without automatic initialization). |
1227 without automatic initialization). |
1226 Returns nil on error, or the objectFile's handle if ok." |
1228 Returns nil on error, or the objectFile's handle if ok." |
1227 |
1229 |
1228 |filename pathName handle initAddr initDefinitionAddr initFunctionName initNames didInit info status |
1230 |filename pathName handle initAddr initDefinitionAddr initFunctionName initNames didInit info status |
1229 dummyHandle msg isCModule doNotUnload definitionClassName definitionClass| |
1231 dummyHandle msg isCModule doNotUnload definitionClassName definitionClass cRetVal| |
1230 |
1232 |
1231 filename := pathNameOrFilename asFilename. |
1233 filename := pathNameOrFilename asFilename. |
1232 pathName := filename pathName. |
1234 pathName := filename pathName. |
1233 |
1235 |
1234 handle := self handleForDynamicObject:filename. |
1236 handle := self handleForDynamicObject:filename. |
1235 handle notNil ifTrue:[ |
1237 handle notNil ifTrue:[ |
1236 "already loaded" |
1238 "already loaded" |
1237 ^ handle. |
1239 ^ handle. |
1238 ]. |
1240 ]. |
1239 |
1241 |
1240 handle := self loadDynamicObject:filename. |
1242 handle := self loadDynamicObject:filename. |
1241 handle isNil ifTrue:[ |
1243 handle isNil ifTrue:[ |
1242 ^ nil |
1244 ^ nil |
1243 ]. |
1245 ]. |
1244 |
1246 |
1245 didInit := false. |
1247 didInit := false. |
1246 isCModule := false. |
1248 isCModule := false. |
1247 |
1249 |
1248 "with dld, load may have worked, even if undefined symbols |
1250 "with dld, load may have worked, even if undefined symbols |
1249 are to be resolved. If that's the case, load all libraries ..." |
1251 are to be resolved. If that's the case, load all libraries ..." |
1250 |
1252 |
1251 ParserFlags searchedLibraries notNil ifTrue:[ |
1253 ParserFlags searchedLibraries notNil ifTrue:[ |
1252 (self hasUndefinedSymbolsIn:handle) ifTrue:[ |
1254 (self hasUndefinedSymbolsIn:handle) ifTrue:[ |
1253 self initializeLoader. |
1255 self initializeLoader. |
1254 |
1256 |
1255 ParserFlags searchedLibraries do:[:libName | |
1257 ParserFlags searchedLibraries do:[:libName | |
1256 (self hasUndefinedSymbolsIn:handle) ifTrue:[ |
1258 (self hasUndefinedSymbolsIn:handle) ifTrue:[ |
1257 Transcript showCR:' ... trying ' , libName , ' to resolve undefined symbols ...'. |
1259 Transcript showCR:' ... trying ' , libName , ' to resolve undefined symbols ...'. |
1258 dummyHandle := Array new:4. |
1260 dummyHandle := Array new:4. |
1259 dummyHandle := self primLoadDynamicObject:libName into:dummyHandle. |
1261 dummyHandle := self primLoadDynamicObject:libName into:dummyHandle. |
1260 "/ dummyHandle isNil ifTrue:[ |
1262 "/ dummyHandle isNil ifTrue:[ |
1261 "/ Transcript showCR:' ... load of library ' , libName , ' failed.'. |
1263 "/ Transcript showCR:' ... load of library ' , libName , ' failed.'. |
1262 "/ ] |
1264 "/ ] |
1263 ] |
1265 ] |
1264 ]. |
1266 ]. |
1265 (self hasUndefinedSymbolsIn:handle) isNil ifTrue:[ |
1267 (self hasUndefinedSymbolsIn:handle) isNil ifTrue:[ |
1266 Transcript showCR:('ObjectFileLoader [info]: still undefined symbols in ', pathName,'.'). |
1268 Transcript showCR:('ObjectFileLoader [info]: still undefined symbols in ', pathName,'.'). |
1267 ]. |
1269 ]. |
1268 ] |
1270 ] |
1269 ]. |
1271 ]. |
1270 |
1272 |
1271 " |
1273 " |
1272 first, expect the classes-name to be the fileNames-baseName |
1274 first, expect the classes-name to be the fileNames-baseName |
1273 (if its not, it may be a method or function module; |
1275 (if its not, it may be a method or function module; |
1278 |
1280 |
1279 "look for explicit initDefinition (xxx_InitDefinition) function |
1281 "look for explicit initDefinition (xxx_InitDefinition) function |
1280 This is used in ST packaged classLib object files" |
1282 This is used in ST packaged classLib object files" |
1281 |
1283 |
1282 (initFunctionName startsWith:'lib') ifTrue:[ |
1284 (initFunctionName startsWith:'lib') ifTrue:[ |
1283 definitionClassName := initFunctionName copyFrom:4. |
1285 definitionClassName := initFunctionName copyFrom:4. |
1284 definitionClass := Smalltalk classNamed:definitionClassName. |
1286 definitionClass := Smalltalk classNamed:definitionClassName. |
1285 ]. |
1287 ]. |
1286 (definitionClass isNil or:[definitionClass isLoaded not]) ifTrue:[ |
1288 (definitionClass isNil or:[definitionClass isLoaded not]) ifTrue:[ |
1287 "the project definition class has not been loaded yet. |
1289 "the project definition class has not been loaded yet. |
1288 initialize and load it" |
1290 initialize and load it" |
1289 |
1291 |
1290 initDefinitionAddr := self findInitDefinitionFunction:initFunctionName in:handle. |
1292 initDefinitionAddr := self findInitDefinitionFunction:initFunctionName in:handle. |
1291 initDefinitionAddr isNil ifTrue:[ |
1293 initDefinitionAddr isNil ifTrue:[ |
1292 ('WARNING: no init definitions for: ' , pathName) errorPrintCR. |
1294 ('WARNING: no init definitions for: ' , pathName) errorPrintCR. |
1293 ] ifFalse:[ |
1295 ] ifFalse:[ |
1294 Verbose ifTrue:[ |
1296 Verbose ifTrue:[ |
1295 ('calling initDefinition at:' , (initDefinitionAddr printStringRadix:16)) errorPrintCR. |
1297 ('calling initDefinition at:' , (initDefinitionAddr printStringRadix:16)) errorPrintCR. |
1296 ]. |
1298 ]. |
1297 info := self |
1299 info := self |
1298 performModuleInitAt:initDefinitionAddr |
1300 performModuleInitAt:initDefinitionAddr |
1299 invokeInitializeMethods:false |
1301 invokeInitializeMethods:false |
1300 for:definitionClassName |
1302 for:definitionClassName |
1301 identifyAs:handle. |
1303 identifyAs:handle. |
1302 status := info at:1. |
1304 status := info at:1. |
1303 status == #ok ifTrue:[ |
1305 status == #ok ifTrue:[ |
1304 "/ now, we have only loaded and installed the projectDefinition class. |
1306 "/ now, we have only loaded and installed the projectDefinition class. |
1305 "/ (but no containing classes or extensions, yet). |
1307 "/ (but no containing classes or extensions, yet). |
1306 "/ let the projectDefinition load any prereqs |
1308 "/ let the projectDefinition load any prereqs |
1307 definitionClassName notNil ifTrue:[ |
1309 definitionClassName notNil ifTrue:[ |
1308 definitionClass := Smalltalk classNamed:definitionClassName. |
1310 definitionClass := Smalltalk classNamed:definitionClassName. |
1309 definitionClass notNil ifTrue:[ |
1311 definitionClass notNil ifTrue:[ |
1310 definitionClass |
1312 definitionClass |
1311 initialize; |
1313 initialize; |
1312 loadMandatoryPreRequisitesAsAutoloaded:false. |
1314 loadMandatoryPreRequisitesAsAutoloaded:false. |
1313 ]. |
1315 ]. |
1314 ]. |
1316 ]. |
1315 ] |
1317 ] |
1316 ]. |
1318 ]. |
1317 ]. |
1319 ]. |
1318 "look for explicit init (xxx_Init) function |
1320 "look for explicit init (xxx_Init) function |
1319 This is used in ST object files" |
1321 This is used in ST object files" |
1320 |
1322 |
1321 initAddr := self findInitFunction:initFunctionName in:handle. |
1323 initAddr := self findInitFunction:initFunctionName in:handle. |
1322 initAddr notNil ifTrue:[ |
1324 initAddr notNil ifTrue:[ |
1323 Verbose ifTrue:[ |
1325 Verbose ifTrue:[ |
1324 ('calling init at:' , (initAddr printStringRadix:16)) errorPrintCR. |
1326 ('calling init at:' , (initAddr printStringRadix:16)) errorPrintCR. |
1325 ]. |
1327 ]. |
1326 info := self |
1328 info := self |
1327 performModuleInitAt:initAddr |
1329 performModuleInitAt:initAddr |
1328 invokeInitializeMethods:invokeInitializeMethods |
1330 invokeInitializeMethods:invokeInitializeMethods |
1329 for:nil |
1331 for:nil |
1330 identifyAs:handle. |
1332 identifyAs:handle. |
1331 status := info at:1. |
1333 status := info at:1. |
1332 status == #ok ifTrue:[ |
1334 status == #ok ifTrue:[ |
1333 didInit := true. |
1335 didInit := true. |
1334 definitionClassName notNil ifTrue:[ |
1336 definitionClassName notNil ifTrue:[ |
1335 definitionClass := Smalltalk classNamed:definitionClassName. |
1337 definitionClass := Smalltalk classNamed:definitionClassName. |
1336 ] |
1338 ] |
1337 ] |
1339 ] |
1338 ] ifFalse:[ |
1340 ] ifFalse:[ |
1339 "look for explicit C-init (xxx__Init) function |
1341 "look for explicit C-init (xxx__Init) function |
1340 This is used in C object files" |
1342 This is used in C object files" |
1341 |
1343 |
1342 initAddr := self findFunction:initFunctionName suffix:'__Init' in:handle. |
1344 initAddr := self findFunction:initFunctionName suffix:'__Init' in:handle. |
1343 initAddr notNil ifTrue:[ |
1345 initAddr notNil ifTrue:[ |
1344 isCModule := true. |
1346 isCModule := true. |
1345 |
1347 |
1346 OSSignalInterrupt handle:[:ex | |
1348 OSSignalInterrupt handle:[:ex | |
1347 ('ObjectFileLoader [warning]: hard error in initFunction of class-module: ' , pathName) errorPrintCR. |
1349 ('ObjectFileLoader [warning]: hard error in initFunction of class-module: ' , pathName) errorPrintCR. |
1348 status := #initFailed. |
1350 status := #initFailed. |
1349 ] do:[ |
1351 ] do:[ |
1350 (self |
1352 cRetVal := self |
1351 saveCallInitFunctionAt:initAddr |
1353 saveCallInitFunctionAt:initAddr |
1352 in:pathNameOrFilename |
1354 in:pathNameOrFilename |
1353 specialInit:false |
1355 specialInit:false |
1354 forceOld:true |
1356 forceOld:true |
1355 interruptable:false |
1357 interruptable:false |
1356 argument:0 |
1358 argument:0 |
1357 identifyAs:handle |
1359 identifyAs:handle |
1358 returnsObject:false) < 0 |
1360 returnsObject:false. |
1359 ifTrue:[ |
1361 (cRetVal < 0) ifTrue:[ |
1360 Verbose ifTrue:[ |
1362 Verbose ifTrue:[ |
1361 'init function return failure ... unload' errorPrintCR. |
1363 'init function return failure ... unload' errorPrintCR. |
1362 ]. |
1364 ]. |
1363 status := #initFailed. |
1365 status := #initFailed. |
1364 ] ifFalse:[ |
1366 ] ifFalse:[ |
1365 didInit := true. |
1367 didInit := true. |
1366 ] |
1368 ] |
1367 ] |
1369 ] |
1368 ] ifFalse:[ |
1370 ] ifFalse:[ |
1369 status := #noInitFunction. |
1371 status := #noInitFunction. |
1370 |
1372 |
1371 "look for any init-function(s); call them all" |
1373 "look for any init-function(s); call them all" |
1372 Verbose ifTrue:[ |
1374 Verbose ifTrue:[ |
1373 'no good init functions found; looking for candidates ...' errorPrintCR. |
1375 'no good init functions found; looking for candidates ...' errorPrintCR. |
1374 ]. |
1376 ]. |
1375 initNames := self namesMatching:'*_Init' segment:'[tT?]' in:pathName. |
1377 initNames := self namesMatching:'*_Init' segment:'[tT?]' in:pathName. |
1376 initNames notNil ifTrue:[ |
1378 initNames notNil ifTrue:[ |
1377 initNames do:[:aName | |
1379 initNames do:[:aName | |
1378 initAddr := self getFunction:aName from:handle. |
1380 initAddr := self getFunction:aName from:handle. |
1379 initAddr isNil ifTrue:[ |
1381 initAddr isNil ifTrue:[ |
1380 (aName startsWith:'_') ifTrue:[ |
1382 (aName startsWith:'_') ifTrue:[ |
1381 initAddr := self getFunction:(aName copyFrom:2) from:handle. |
1383 initAddr := self getFunction:(aName copyFrom:2) from:handle. |
1382 ]. |
1384 ]. |
1383 ]. |
1385 ]. |
1384 initAddr isNil ifTrue:[ |
1386 initAddr isNil ifTrue:[ |
1385 Transcript showCR:('no symbol: ',aName,' in ', pathName). |
1387 Transcript showCR:('no symbol: ',aName,' in ', pathName). |
1386 ] ifFalse:[ |
1388 ] ifFalse:[ |
1387 Verbose ifTrue:[ |
1389 Verbose ifTrue:[ |
1388 ('calling init at:' , (initAddr printStringRadix:16)) errorPrintCR |
1390 ('calling init at:' , (initAddr printStringRadix:16)) errorPrintCR |
1389 ]. |
1391 ]. |
1390 self |
1392 self |
1391 performModuleInitAt:initAddr |
1393 performModuleInitAt:initAddr |
1392 invokeInitializeMethods:invokeInitializeMethods |
1394 invokeInitializeMethods:invokeInitializeMethods |
1393 for:nil |
1395 for:nil |
1394 identifyAs:handle. |
1396 identifyAs:handle. |
1395 didInit := true. |
1397 didInit := true. |
1396 ] |
1398 ] |
1397 ]. |
1399 ]. |
1398 ]. |
1400 ]. |
1399 ] |
1401 ] |
1400 ]. |
1402 ]. |
1401 |
1403 |
1402 (invokeInitializeMethods and:[didInit not]) ifTrue:[ |
1404 (invokeInitializeMethods and:[didInit not]) ifTrue:[ |
1403 status == #noInitFunction ifTrue:[ |
1405 status == #noInitFunction ifTrue:[ |
1404 msg := 'no classLib init function found; assume load ok' |
1406 msg := 'no classLib init function found; assume load ok' |
1405 ] ifFalse:[ |
1407 ] ifFalse:[ |
1406 (status ~~ #registrationFailed |
1408 (status ~~ #registrationFailed |
1407 and:[status ~~ #initFailed |
1409 and:[status ~~ #initFailed |
1408 and:[status ~~ #missingClass |
1410 and:[status ~~ #missingClass |
1409 and:[status ~~ #versionMismatch]]]) |
1411 and:[status ~~ #versionMismatch]]]) |
1410 ifTrue:[ |
1412 ifTrue:[ |
1411 self listUndefinedSymbolsIn:handle. |
1413 self listUndefinedSymbolsIn:handle. |
1412 ]. |
1414 ]. |
1413 |
1415 |
1414 Verbose ifTrue:[ |
1416 Verbose ifTrue:[ |
1415 'unloading, since init failed ...' errorPrintCR. |
1417 'unloading, since init failed ...' errorPrintCR. |
1416 ]. |
1418 ]. |
1417 |
1419 |
1418 "/ give caller a chance to prevent unloading (to register later, when a prerequisite class comes) |
1420 "/ give caller a chance to prevent unloading (to register later, when a prerequisite class comes) |
1419 status == #missingClass ifTrue:[ |
1421 status == #missingClass ifTrue:[ |
1420 self breakPoint:#sv. |
1422 self breakPoint:#sv. |
1421 doNotUnload := (SuperClassMissingErrorNotification query ? false). |
1423 doNotUnload := (SuperClassMissingErrorNotification query ? false). |
1422 ] ifFalse:[ |
1424 ] ifFalse:[ |
1423 status == #registrationFailed ifTrue:[ |
1425 status == #registrationFailed ifTrue:[ |
1424 self breakPoint:#sv. |
1426 self breakPoint:#sv. |
1425 doNotUnload := (RegistrationFailedErrorNotification query ? false). |
1427 doNotUnload := (RegistrationFailedErrorNotification query ? false). |
1426 ] ifFalse:[ |
1428 ] ifFalse:[ |
1427 doNotUnload := false. |
1429 doNotUnload := false. |
1428 ]. |
1430 ]. |
1429 ]. |
1431 ]. |
1430 doNotUnload ifFalse:[ |
1432 doNotUnload ifFalse:[ |
1431 self unloadDynamicObject:handle. |
1433 self unloadDynamicObject:handle. |
1432 Verbose ifTrue:[ |
1434 Verbose ifTrue:[ |
1433 'unloaded.' errorPrintCR. |
1435 'unloaded.' errorPrintCR. |
1434 ]. |
1436 ]. |
1435 handle := nil. |
1437 handle := nil. |
1436 ]. |
1438 ]. |
1437 |
1439 |
1438 status == #initFailed ifTrue:[ |
1440 status == #initFailed ifTrue:[ |
1439 msg := 'module not loaded (init function signaled failure).' |
1441 msg := 'module not loaded (init function signaled failure).' |
1440 ] ifFalse:[ |
1442 ] ifFalse:[ |
1441 status == #missingClass ifTrue:[ |
1443 status == #missingClass ifTrue:[ |
1442 msg := 'module not loaded (superclass missing: ' , (info at:2) , ').' |
1444 msg := 'module not loaded (superclass missing: ' , (info at:2) , ').' |
1443 ] ifFalse:[ |
1445 ] ifFalse:[ |
1444 status == #registrationFailed ifTrue:[ |
1446 status == #registrationFailed ifTrue:[ |
1445 msg := 'module registration failed (incompatible object or missing superclass)' |
1447 msg := 'module registration failed (incompatible object or missing superclass)' |
1446 ] ifFalse:[ |
1448 ] ifFalse:[ |
1447 status == #versionMismatch ifTrue:[ |
1449 status == #versionMismatch ifTrue:[ |
1448 msg := 'module registration failed (class version mismatch ' , (info at:2) printString , ')' |
1450 msg := 'module registration failed (class version mismatch ' , (info at:2) printString , ')' |
1449 ] ifFalse:[ |
1451 ] ifFalse:[ |
1450 (self namesMatching:'*__sepInitCode__*' segment:'[tT?]' in:pathName) notNil ifTrue:[ |
1452 (self namesMatching:'*__sepInitCode__*' segment:'[tT?]' in:pathName) notNil ifTrue:[ |
1451 msg := 'module not loaded (unknown error reason).' |
1453 msg := 'module not loaded (unknown error reason).' |
1452 ] ifFalse:[ |
1454 ] ifFalse:[ |
1453 msg := 'module not loaded (no _Init entry in object file ?).' |
1455 msg := 'module not loaded (no _Init entry in object file ?).' |
1454 ] |
1456 ] |
1455 ] |
1457 ] |
1456 ]. |
1458 ]. |
1457 ]. |
1459 ]. |
1458 ]. |
1460 ]. |
1459 ]. |
1461 ]. |
1460 msg := 'ObjectFileLoader [info]: <1p>: <2p>' expandMacrosWith:pathNameOrFilename asFilename baseName with:msg. |
1462 msg := 'ObjectFileLoader [info]: <1p>: <2p>' expandMacrosWith:pathNameOrFilename asFilename baseName with:msg. |
1461 Smalltalk isStandAloneApp ifTrue:[ |
1463 Smalltalk isStandAloneApp ifTrue:[ |
1462 msg errorPrintCR |
1464 msg errorPrintCR |
1463 ] ifFalse:[ |
1465 ] ifFalse:[ |
1464 Transcript showCR:msg |
1466 Transcript showCR:msg |
1465 ]. |
1467 ]. |
1466 ]. |
1468 ]. |
1467 |
1469 |
1468 isCModule ifFalse:[ |
1470 isCModule ifFalse:[ |
1469 Smalltalk flushCachedClasses. |
1471 Smalltalk flushCachedClasses. |
1470 Class flushSubclassInfo. |
1472 Class flushSubclassInfo. |
1471 |
1473 |
1472 (definitionClass notNil and:[definitionClass isLoaded]) ifTrue:[ |
1474 (definitionClass notNil and:[definitionClass isLoaded]) ifTrue:[ |
1473 definitionClass supportedOnPlatform ifTrue:[ |
1475 definitionClass supportedOnPlatform ifTrue:[ |
1474 definitionClass loadAllClassesAsAutoloaded:true. |
1476 definitionClass loadAllClassesAsAutoloaded:true. |
1475 "/ load non-mandatory prerequisites |
1477 "/ load non-mandatory prerequisites |
1476 definitionClass loadPreRequisitesAsAutoloaded:true. |
1478 definitionClass loadPreRequisitesAsAutoloaded:true. |
1477 definitionClass projectIsLoaded:true. |
1479 definitionClass projectIsLoaded:true. |
1478 ]. |
1480 ]. |
1479 ]. |
1481 ]. |
1480 Smalltalk isInitialized ifTrue:[ |
1482 Smalltalk isInitialized ifTrue:[ |
1481 "really don't know, if and what has changed ... |
1483 "really don't know, if and what has changed ... |
1482 ... but assume, that new classes have been installed." |
1484 ... but assume, that new classes have been installed." |
1483 Smalltalk changed:#postLoad. |
1485 Smalltalk changed:#postLoad. |
1484 ]. |
1486 ]. |
1485 ]. |
1487 ]. |
1486 ^ handle |
1488 ^ handle |
1487 |
1489 |
1488 "Modified: / 15-11-2010 / 13:19:26 / cg" |
1490 "Modified: / 15-11-2010 / 13:19:26 / cg" |
1489 ! |
1491 ! |