Quellcode durchsuchen

generic SolarisA2 files, works now

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7116 8c9fc860-2736-0410-a75d-ab315db34111
eth.guenter vor 8 Jahren
Ursprung
Commit
ab70c9437a

+ 113 - 329
source/Generic.Solaris.I386.Glue.Mod

@@ -6,9 +6,10 @@ MODULE Glue;
 IMPORT SYSTEM, Trace;
 
 CONST 
-	base* = 08050000H;
+(*	base* = 08050000H;		for true elf core *)
+	base* = 08070000H;	(*  used by A2Loader,  see 'A2Loader.elf  -h' *)
 	debug* = {};
-	NL = 0AXl
+	NL = 0AX;
 VAR
 	last-: RECORD END; (* empty variable linked to end of kernel *)
 	
@@ -29,6 +30,10 @@ VAR
 	argv-: ADDRESS;
 	environ-: ADDRESS;
 
+
+(*? the relocation of "dlsym/dlopen" doesn't work	*)
+(*==================
+	
 	PROCEDURE {INITIAL, NOPAF} EntryPoint;
 	CODE
 		; ELF header
@@ -49,6 +54,16 @@ VAR
 
 	elfheadersize:
 
+		; interpreter header, must precede any loadable segment!! 
+		DD 3
+		DD interpretername; interpreter name offset
+		DD interpretername + base; interpreter name 
+		DD interpretername + base; interpreter name
+		DD interpretername_end - interpretername ; interpreter name length
+		DD interpretername_end - interpretername ; interpreter name length
+		DD 4H
+		DD 1H
+
 		; program header
 		DD 1
 		DD 0
@@ -59,16 +74,6 @@ VAR
 		DD 07
 		DD 1000H; alignment
 		
-		; interpreter header
-		DD 3
-		DD interpretername; interpreter name offset
-		DD interpretername + base; interpreter name 
-		DD interpretername + base; interpreter name
-		DD interpretername_end - interpretername ; interpreter name length
-		DD interpretername_end - interpretername ; interpreter name length
-		DD 4H
-		DD 1H
-
 		; dynamic header
 		DD 02H
 		DD dynamicsection 
@@ -79,39 +84,58 @@ VAR
 		DD 06H
 		DD 04H
 
-	dynamicsection:
-		DD 05H, base + stringtable
-		DD 06H, symboltablebegin + base
-		DD 07H, dlsymrelocation + base
-		DD 08H, dlsymrelocation_end-dlsymrelocation ; size (relocationtable)
-		DD 09H, 0CH
-		DD 0AH, stringtable_end - stringtable; size (stringtable)
-		DD 0BH, 10H
+	dynamicsection: 			; manantory in solaris: 0, 4-11, 17-19
+		DD 04H, hashtable + base								;DT_HASH
+		DD 05H, stringtable + base							;DT_STRTAB
+		DD 06H, symboltable + base							;DT_SYMTAB
+		DD 07H, relocationtable + base						;DT_RELA
+		DD 08H, relocationtable_end - relocationtable	;DT_RELASZ, size of relocationtable
+		DD 09H, 0CH													;DT_RELAENT, size of relocation entry
+		DD 0AH, stringtable_end - stringtable				;DT_STRSZ, size of stringtable
+		DD 0BH, 10H													;DT_SYMENT, size of symboltable entry
 		
-		DD 01H, libname - stringtable; position of libname
-		DD 0H, 0H ; sentinel
+		DD 11H, relocationtable + base						;DT_REL
+		DD 12H, relocationtable_end - relocationtable	;DT_RELSZ
+		DD 13H, 0CH													;DT_RELENT
+		
+		DD 01H, libdl - stringtable						;DT_NEEDED, pos. of libdl
+		DD 01H, libc - stringtable						;DT_NEEDED, pos. of libc
+		DD 0H, 0H 	;sentinel
 	dynamicsection_end:		
 		
-	dlsymrelocation:
+	relocationtable:
 		DD @dlsym
-		DB 01H
-		DB 01H, 00H, 00H; index of the symbol
+		DB 01H				;relocation type
+		DB 01H, 00H, 00H	;index of the symbol
+		DD 0H
+		DD @dlopen
+		DB 01H				;relocation type
+		DB 01H, 00H, 00H	;index of the symbol
 		DD 0H
-	dlsymrelocation_end:
+	relocationtable_end:
 
 	stringtable:
 		DB 0H ; sentinel
-
-	libname:
-		DB 'libdl.so.1', 0
-		
+	libdl:
+		DB '/lib/libdl.so.1', 0
+	libc:
+		DB '/lib/libc.so.1', 0
 	dlsymname:
 		DB 'dlsym', 0
-		
+	dlopenname:
+		DB 'dlopen', 0
 	stringtable_end:
 		
 		ALIGN 4
-	symboltablebegin:
+	hashtable:
+		DD 2		; nbucket
+		DD 2		; nchain
+		DD 1		; bucket[0]
+		DD 2		; bucket[1]
+		DD 1		; chain[0]
+		DD 2		; chain[1]
+		
+	symboltable:
 		DD	0
 		DD	0
 		DD	0
@@ -119,13 +143,21 @@ VAR
 		DB	0
 		DW 0
 		
-		; dlsym symbol
-		DD dlsymname - stringtable; position of dlsymname
-		DD	0
-		DD	0
-		DB	12H ; info: global + function
-		DB 0
-		DW	0
+		;dlsym symbol
+		DD dlsymname - stringtable	; st_name, position of dlsymname
+		DD	0									; st_value
+		DD	0									; st_size
+		DB	12H 								; st_info, global + function
+		DB 0									; st_other
+		DW 0									; st_shndx: default
+
+		;dlopen symbol
+		DD dlopenname - stringtable	; st_name, position of dlopenname
+		DD	0									; st_value
+		DD	0									; st_size
+		DB	12H 								; st_info, global + function
+		DB 0									; st_other
+		DW 0									; st_shndx: default
 
 	interpretername:
 		DB '/lib/ld.so.1', 0
@@ -134,9 +166,23 @@ VAR
 		ALIGN 4
 
 	entry:
-	END EntryPoint;
+	END EntryPoint;			======*)
 
-	
+
+	PROCEDURE {INITIAL, NOPAF} EntryPoint;		(* header needed by A2Loader *)
+	CODE
+		DB 'Solaris32G.core', 0
+		DD 0
+		DD 0
+		DD 0
+		DD 0
+		DD base
+		DD @Init0
+		DD @dlopen
+		DD @dlsym
+		DD @argc
+		DD @argv
+	END EntryPoint;		
 	
  	PROCEDURE Char ( c: CHAR );
 	VAR r: LONGINT;
@@ -144,7 +190,6 @@ VAR
 		r := write( 1, ADDRESSOF( c ), 1 );
 	END Char;
 
- 
  	PROCEDURE Dlsym*( handle: ADDRESS; CONST name: ARRAY OF CHAR; adr: ADDRESS );
 	VAR val: ADDRESS;
 	BEGIN
@@ -155,6 +200,7 @@ VAR
 	
 	PROCEDURE Init;
 	VAR i: LONGINT;
+		libdl: ADDRESS;
 	BEGIN
 		baseAdr := ADDRESSOF( EntryPoint );
 		endAdr := ADDRESSOF( last );
@@ -164,17 +210,18 @@ VAR
 		
 		stackBottom := ADDRESSOF( i ) + 2*SIZEOF( ADDRESS );
 
-		Dlsym( 0, "dlopen" , ADDRESSOF ( dlopen ) );
-		Dlsym( 0, "dlclose", ADDRESSOF ( dlclose ) );
-		
-		libc := dlopen( ADDRESSOF( "libc.so.1" ), 2 );
+	(*	Dlsym( 0, "dlopen" , ADDRESSOF ( dlopen ) );	*)
+		libdl := dlopen( ADDRESSOF( "/lib/libdl.so.1" ), 2 );
+		Dlsym( libdl, "dlclose", ADDRESSOF ( dlclose ) );
+		libc := dlopen( ADDRESSOF( "/lib/libc.so.1" ), 2 );	
 		Dlsym( libc, "write", ADDRESSOF ( write ) );
 		Dlsym( libc, "exit", ADDRESSOF ( exit ) );
 	END Init;
 	
 	PROCEDURE {INITIAL, NOPAF} Init0;
 	BEGIN
-		(*initial stack layout:
+	(*? same layout in Solaris ?? *)
+	(*	(*initial stack layout:
 			argc at esp
 			argv at esp+4
 			0 at esp+4+argc*4
@@ -190,10 +237,8 @@ VAR
 			SHL EAX, 2
 			ADD EAX, ESP
 			MOV environ, EAX
-		END;	
+		END;	*)
 		Init;
-		Char( 'A' ); Char( NL );
-		exit( 0 )
 	END Init0;
 	
 	PROCEDURE Initialize*;
@@ -205,297 +250,36 @@ VAR
 END Glue.
 
 
-Simple elf for Solaris:
-==============
+
+
+ Building the SolarisA2 Generic elf binary:
 
 Compiler.Compile -p=Linux32G
 		Runtime.Mod Trace.Mod 
 		Generic.Solaris.I386.Glue.Mod  Generic.Solaris.I386.Unix.Mod  Generic.Unix.I386.Machine.Mod	
-		Heaps.Mod  Generic.Modules.Mod  Generic.Unix.Objects.Mod  Unix.Kernel.Mod
-		KernelLog.Mod  Streams.Mod	Commands.Mod	TrapWriters.Mod  Generic.Reflection.Mod	
+		Heaps.Mod  Generic.Modules.Mod  Generic.Solaris.Objects.Mod  Unix.Kernel.Mod
+		KernelLog.Mod  Streams.Mod  Pipes.Mod  Commands.Mod  TrapWriters.Mod  Generic.Reflection.Mod	
 		Unix.StdIO.Mod  Generic.Unix.Traps.Mod  UTF8Strings.Mod  Files.Mod  Unix.UnixFiles.Mod
 		RelativeFileSystem.Mod  StringPool.Mod  BitSets.Mod  ObjectFile.Mod  
 		I386.Reals.Mod  Unix.Clock.Mod  Dates.Mod  Strings.Mod  Diagnostics.Mod 
-		GenericLinker.Mod  GenericLoader.Mod  Unix.BootConsole.Mod
+		GenericLinker.Mod  GenericLoader.Mod  Unix.BootConsole.Mod 
+		
+		SolarisELF.Mod 
 		~
 		
-StaticLinker.Link --fileFormat=Raw --fileName=simple_elf --extension=.GofU --displacement=08050000H
+		
+	(* the correct displacement is shown by  'A2Loader.elf  -h'  *)
+StaticLinker.Link 
+	--fileFormat=Raw --fileName=Solaris32G.core --extension=.GofU --displacement=08070000H
 		Runtime Trace Glue 
 		Unix  Machine  Heaps Modules  Objects  Kernel  KernelLog 
-		Streams  Commands  StdIO  TrapWriters  Traps 
+		Streams  Pipes  Commands  StdIO  TrapWriters  Traps 
 		Files  UnixFiles  Clock  Dates  Reals  Strings  Diagnostics 
-		BitSets  StringPool  ObjectFile  GenericLinker  Reflection  GenericLoader
+		BitSets  StringPool  GenericLinker  Reflection  GenericLoader
 		BootConsole
 		~
 
-
-Simple elf for Linux:
-=============
-
-SystemTools.DoCommands
-	Compiler.Compile -p=Linux32G
-		Runtime.Mod Trace.Mod Generic.Linux.I386.Glue.Mod Generic.Linux.I386.Unix.Mod Generic.Unix.I386.Machine.Mod Heaps.Mod  Generic.Modules.Mod 
-		Generic.Unix.Objects.Mod 
-		Unix.Kernel.Mod KernelLog.Mod Plugins.Mod Streams.Mod 
-		Pipes.Mod Commands.Mod I386.Reals.Mod Generic.Reflection.Mod TrapWriters.Mod CRC.Mod SystemVersion.Mod 
-		Unix.StdIO.Mod Generic.Unix.Traps.Mod Locks.Mod Unix.Clock.Mod Disks.Mod Files.Mod Dates.Mod Strings.Mod 
-		UTF8Strings.Mod FileTrapWriter.Mod Caches.Mod DiskVolumes.Mod OldDiskVolumes.Mod RAMVolumes.Mod 
-		DiskFS.Mod OldDiskFS.Mod OberonFS.Mod FATVolumes.Mod FATFiles.Mod ISO9660Volumes.Mod 
-		ISO9660Files.Mod Unix.UnixFiles.Mod RelativeFileSystem.Mod BitSets.Mod StringPool.Mod DIagnostics.Mod 
-		ObjectFile.Mod GenericLinker.Mod GenericLoader.Mod Unix.BootConsole.Mod 
-		~
-
-	StaticLinker.Link --fileFormat=Raw --fileName=simple_elf --extension=.GofU --displacement=08048000H
-		Runtime Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog 
-		Streams Commands StdIO TrapWriters Traps 
-		Files UnixFiles Clock Dates Reals Strings Diagnostics 
-		BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  
-		BootConsole 
-		 ~
-
-	FSTools.CloseFiles simple_elf ~
-~ 
-
-MODULE Test;
-
-IMPORT StdIO, Commands, Streams, Modules;
-
-PROCEDURE Execute(context: Commands.Context);
-VAR str, msg: ARRAY 256 OF CHAR;  res: LONGINT;
-BEGIN
-	IF ~context.arg.GetString(str) THEN RETURN END;
-	IF ~context.arg.GetString(str) THEN 
-		context.out.String("no command"); context.out.Ln;
-		RETURN
-	END;
-	Commands.Activate(str, context, {Commands.Wait}, res, msg);
-END Execute;
-
-BEGIN
-	Execute(StdIO.env);
-	Modules.Shutdown(1);
-END Test.
-
-
-#	Release.Build --path="../obg/"  WinAosNewObjectFile ~
-#	StaticLinker.Link --fileFormat=PE32 --fileName=A2.exe --extension=GofW --displacement=401000H --path="../obg/" 
-
-Runtime Trace Kernel32 Machine Heaps Modules Objects Kernel KernelLog 
-Streams Commands FIles WinFS Clock Dates Reals Strings Diagnostics 
-BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  BootConsole ~
-
-FoxGenericObjectFile.Show Machine.GofU ~
-
-
-# LinuxAos
-# Wednesday, September 7, 2016  18:54:57
-# This file has been automatically generated using Release.Mod.
-# Red colors indicate that a module imports SYSTEM.
-SystemTools.DoCommands
-SystemTools.Timer start ~
-Compiler.Compile  -b=AMD --objectFileExtension=.Obj --symbolFileExtension=.Obj --destPath=NewAos/
-Runtime.Mod Trace.Mod Unix.Glue.Mod Linux.I386.Unix.Mod Unix.I386.Machine.Mod 
-Unix.Heaps.Mod Modules.Mod Unix.Objects.Mod Unix.Kernel.Mod KernelLog.Mod Plugins.Mod Streams.Mod 
-Pipes.Mod Commands.Mod I386.Reals.Mod Reflection.Mod TrapWriters.Mod CRC.Mod SystemVersion.Mod 
-Unix.StdIO.Mod Unix.Traps.Mod Locks.Mod Unix.Clock.Mod Disks.Mod Files.Mod Dates.Mod Strings.Mod 
-UTF8Strings.Mod FileTrapWriter.Mod Caches.Mod DiskVolumes.Mod OldDiskVolumes.Mod RAMVolumes.Mod 
-DiskFS.Mod OldDiskFS.Mod OberonFS.Mod FATVolumes.Mod FATFiles.Mod ISO9660Volumes.Mod 
-ISO9660Files.Mod Unix.UnixFiles.Mod RelativeFileSystem.Mod Loader.Mod Unix.BootConsole.Mod
-
-Compiler.Compile -p=Linux32G
-Displays.Mod Inputs.Mod Options.Mod Events.Mod EventsUtils.Mod EventsKernelLog.Mod 
-EventsFileLog.Mod EventsMemoryLog.Mod DynamicStrings.Mod XMLObjects.Mod XML.Mod XMLScanner.Mod 
-XMLParser.Mod Configuration.Mod FileHandlers.Mod BootShell.Mod I386.Network.Mod ActiveTimers.Mod 
-Unix.IP.Mod Unix.Sockets.Mod Unix.TCP.Mod Unix.UDP.Mod Unix.DNS.Mod Serials.Mod SoundDevices.Mod 
-Joysticks.Mod TVDriver.Mod VirtualDisks.Mod DisplayNull.Mod Unix.V24.Mod Unix.OpenAL.Mod 
-OpenALSound.Mod StringPool.Mod Diagnostics.Mod Debugging.Mod BitSets.Mod ObjectFile.Mod 
-GenericLinker.Mod StaticLinker.Mod FoxBasic.Mod FoxProgTools.Mod FoxScanner.Mod FoxCSharpScanner.Mod 
-FoxSyntaxTree.Mod FoxGlobal.Mod FoxActiveCells.Mod FoxHardware.Mod FoxFormats.Mod FoxPrintout.Mod 
-FoxParser.Mod FoxCSharpParser.Mod FoxSemanticChecker.Mod FoxBackend.Mod FoxSections.Mod 
-FoxFrontend.Mod FoxOberonFrontend.Mod FoxCSharpFrontend.Mod FoxCompiler.Mod FoxFingerPrinter.Mod 
-FoxInterfaceComparison.Mod FoxTextualSymbolFile.Mod FoxBinarySymbolFile.Mod FoxBinaryCode.Mod 
-FoxIntermediateCode.Mod FoxIntermediateBackend.Mod FoxCodeGenerators.Mod FoxBinaryObjectFile.Mod 
-FoxGenericObjectFile.Mod FoxAMD64InstructionSet.Mod FoxAMD64Assembler.Mod FoxAMDBackend.Mod FoxAssembler.Mod 
-FoxIntermediateAssembler.Mod FoxDisassembler.Mod FoxARMInstructionSet.Mod FoxARMAssembler.Mod FoxARMBackend.Mod 
-FoxMinosObjectFile.Mod FoxIntermediateParser.Mod FoxIntermediateObjectFile.Mod FoxIntermediateLinker.Mod 
-FoxTRMInstructionSet.Mod FoxTRMAssembler.Mod FoxTRMBackend.Mod FoxInterpreterBackend.Mod 
-FoxTranspilerBackend.Mod FoxDocumentationScanner.Mod FoxDocumentationTree.Mod FoxDocumentationPrinter.Mod 
-FoxDocumentationHtml.Mod FoxDocumentationParser.Mod FoxDocumentationBackend.Mod FoxProfiler.Mod 
-XMM.I386.Math.Mod XMM.I386.MathL.Mod FoxArrayBase.Mod I386.FoxArrayBaseOptimized.Mod Errors.Mod 
-Unix.ProcessInfo0.Mod ProcessInfo.Mod SystemTools.Mod Reboot.Mod XMM.I386.Math.Mod XMM.I386.MathL.Mod 
-Random.Mod Drand48.Mod SerialsVirtual.Mod Autostart.Mod FSTools.Mod UpTime.Mod CLUTs.Mod 
-I386.Raster.Mod Localization.Mod Archives.Mod WMRectangles.Mod WMEvents.Mod Repositories.Mod 
-FP1616.Mod Texts.Mod UndoManager.Mod CRC.Mod Inflate.Mod Unzip.Mod ZipFS.Mod Codecs.Mod 
-UnicodeProperties.Mod ContextualDependency.Mod UnicodeBidirectionality.Mod I386.WMRasterScale.Mod 
-WMGraphics.Mod TextUtilities.Mod Types.Mod Models.Mod WMProperties.Mod WMMessages.Mod 
-WMWindowManager.Mod WMGraphicUtilities.Mod WMDropTarget.Mod WMComponents.Mod KernelLogger.Mod 
-CompilerInterface.Mod FoxTextCompiler.Mod PCDebug.Mod PCM.Mod PCS.Mod PCT.Mod PCBT.Mod PCLIR.Mod PCO.Mod 
-PCG386.Mod PCC.Mod PCV.Mod PCArrays.Mod PCB.Mod PCP.Mod PCA386.Mod PCOM.Mod PCOF.Mod PCOFPE.Mod 
-PC.Mod PCOARM.Mod PCARMCP.Mod PCARMRegisters.Mod PCAARM.Mod PCGARM.Mod ASMAMD64.Mod 
-PCAAMD64.Mod PCGAMD64.Mod WhitespaceRemover.Mod HostClipboard.Mod Tar.Mod Zlib.Mod ZlibBuffers.Mod 
-ZlibDeflate.Mod ZlibInflate.Mod ZlibWriters.Mod ZlibReaders.Mod Zip.Mod ZipTool.Mod BIT.Mod 
-PNGDecoder.Mod BMPCodec.Mod GIFCodec.Mod JPEGDecoder.Mod AnimationCodec.Mod PartitionsLib.Mod 
-FATScavenger.Mod Partitions.Mod DiskTests.Mod DiskBenchmark.Mod PartitionEditorTable.Mod 
-FTPClient.Mod XYModem.Mod Shell.Mod ShellSerial.Mod Installer.Mod CryptoBigNumbers.Mod 
-CryptoBase64.Mod CryptoUtils.Mod CryptoCiphers.Mod CryptoARC4.Mod CryptoDES.Mod CryptoDES3.Mod 
-CryptoHashes.Mod CryptoMD5.Mod CryptoSHA1.Mod CryptoSHA256.Mod CryptoKeccakF1600.Mod 
-CryptoKeccakSponge.Mod CryptoSHA3.Mod CryptoCSPRNG.Mod CryptoPrimes.Mod CryptoDSA.Mod 
-CryptoDiffieHellman.Mod CryptoAES.Mod CryptoBlowfish.Mod CryptoTwofish.Mod CryptoCAST.Mod CryptoHMAC.Mod 
-CryptoIDEA.Mod CryptoRSA.Mod Checksum.Mod Fido.Mod I386.CPUID.Mod A2Sequencers.Mod PictImages.Mod 
-V24Tracer.Mod XMLGeneratorSchema.Mod CSS2.Mod CSS2Scanner.Mod CSS2Parser.Mod RAWPrinter.Mod LPR.Mod 
-ASN1.Mod PKCS1.Mod X509.Mod TLS.Mod TCPServices.Mod TestServer.Mod TCPTools.Mod 
-Win32.Performance.Mod Bin2Hex.Mod BinToCode.Mod Base64.Mod DisplayGTF.Mod GZip.Mod ShellCommands.Mod 
-Telnet.Mod TFClasses.Mod Mail.Mod SMTPClient.Mod TFLog.Mod WebHTTP.Mod WebHTTPClient.Mod 
-WebHTTPTools.Mod WebHTTPServer.Mod WebHTTPServerTools.Mod WebSSMPPlugin.Mod 
-WebHTTPServerStatistics.Mod POP3Client.Mod RFC865Client.Mod QuoteServer.Mod FTPFS.Mod XModem.Mod SearchTools.Mod 
-DiffLib.Mod TextConverter.Mod TaskScheduler.Mod FTP.Mod DES.Mod VNCServer.Mod WAVCodec.Mod 
-MP3Decoder.Mod I386.IDCT.Mod AVI.Mod DivXTypes.Mod I386.DivXHelper.Mod I386.DivXDecoder.Mod 
-MPEGTables.Mod I386.MPEGUtilities.Mod MPEGVideoDecoder.Mod JPEG2000DecoderUtil.Mod 
-JPEG2000DecoderCS.Mod JPEG2000Decoder.Mod MD5.Mod HTTPSupport.Mod HTTPSession.Mod DynamicWebpage.Mod 
-DynamicWebpagePlugin.Mod PrevalenceSystem.Mod WMDropTarget.Mod GenericSort.Mod WebStd.Mod WebComplex.Mod 
-WMCharCodes.Mod HTMLScanner.Mod HTMLParser.Mod NewHTTPClient.Mod UnihanParser.Mod CSV.Mod 
-ColorModels.Mod WMDefaultWindows.Mod WMDefaultFont.Mod WMFontManager.Mod WMOberonFonts.Mod 
-WMCCGFonts.Mod WMBitmapFont.Mod OpenTypeInt.Mod OpenTypeScan.Mod OpenType.Mod OpenTypeFonts.Mod 
-WMOTFonts.Mod WindowManager.Mod Generic.Unix.X11.Mod Unix.X11Api.Mod Unix.XDisplay.Mod Unix.Beep.Mod 
-Unix.KbdMouse.Mod Unix.Clipboard.Mod Attributes.Mod WMStandardComponents.Mod WMProgressComponents.Mod 
-WMShapes.Mod WMFigures.Mod WMScrollableComponents.Mod WMPieMenu.Mod WMPopups.Mod 
-PositionDebugging.Mod SyntaxHighlighter.Mod WMTextView.Mod WMInputMethods.Mod WMEditors.Mod 
-WMSearchComponents.Mod WMMacros.Mod WMGrids.Mod WMStringGrids.Mod WMTrees.Mod WMMixer.Mod 
-WMTabComponents.Mod WMColorComponents.Mod WMAnimations.Mod WMDropDownLists.Mod WMRestorable.Mod 
-WMApplications.Mod WMDialogs.Mod WMDocumentEditor.Mod WMErrors.Mod WMOSD.Mod WMArchives.Mod 
-WMCharMap.Mod WMUnicodeMarkerTool.Mod Unix.DisplayRefresher.Mod ModuleParser.Mod ModuleTrees.Mod 
-WMXMLTree.Mod WMDiagnostics.Mod PETTrees.Mod PETModuleTree.Mod PETXMLTree.Mod PET.Mod 
-WMArabicIME.Mod WMArmenianIME.Mod WMHebrewIME.Mod WMPinyinIME.Mod WMRussianIME.Mod 
-WMUkrainianIME.Mod WMEthiopicIME.Mod WMUnicodeIME.Mod WMInputMethodTool.Mod WMUtilities.Mod 
-WMTrapWriter.Mod FoxA2Interface.Mod WMMenus.Mod WMDiagramComponents.Mod MainMenu.Mod StartMenu.Mod 
-HotKeys.Mod WMNavigate.Mod WMNavigator.Mod WMDesktops.Mod Notepad.Mod WMSystemComponents.Mod 
-WMFileManager.Mod WMSearchTool.Mod WMFTPClient.Mod SkinLanguage.Mod FNHistories.Mod SkinEngine.Mod 
-WMProcessInfo.Mod WMObjectTracker.Mod WMKernelLog.Mod WMEventLog.Mod WMPartitionsComponents.Mod 
-WMPartitions.Mod PartitionEditorComponents.Mod PartitionEditor.Mod MultiLogger.Mod MemoryReader.Mod 
-Decoder.Mod I386Decoder.Mod ARMDecoder.Mod AMD64Decoder.Mod WMTextTool.Mod WMPerfMonPlugins.Mod 
-WMPerfMonAlerts.Mod WMPerfMonAlertsUtils.Mod Unix.WMPerfMonPluginCpu.Mod 
- WMPerfMonPluginProcesses.Mod WMPerfMonPluginSerials.Mod WMPerfMonPluginNetwork.Mod 
-WMPerfMonPluginDisks.Mod WMPerfMonPluginPerfMon.Mod WMPerfMonPluginEvents.Mod WMPerfMonPluginMessages.Mod 
-WMPerfMonComponents.Mod WMPerfMonTabSystem.Mod WMPerfMonTabAlerts.Mod WMPerfMon.Mod WMClock.Mod 
-WMCalendar.Mod WMV24Component.Mod WMShell.Mod SSHGlobals.Mod SSHKeys.Mod SSHTransport.Mod 
-SSHAuthorize.Mod SSH.Mod SSHClient.Mod TFStringPool.Mod BimboScanner.Mod TFTypeSys.Mod TFDumpTS.Mod 
-TFScopeTools.Mod TFCheck.Mod TFAOParser.Mod TFModuleTrees.Mod TFPET.Mod TFClasses.Mod 
-TFDocGenerator.Mod TFXRef.Mod CharacterLineup.Mod WMDesktopIcons.Mod WMTextStyleTool.Mod WMVNCView.Mod 
-VNC.Mod WMVT100.Mod SkinEditor.Mod Looks.Mod WMSkinLoader.Mod WMBackdropLoader.Mod 
-WMInspectionComponents.Mod WMInspector.Mod WMRepositories.Mod WMBuilder.Mod WMBuilderTransformer.Mod 
-CyberbitNetInstall.Mod WMDiff.Mod WMTaskScheduler.Mod IMAPUtilities.Mod IMAP.Mod IMAPClient.Mod RMSMTP.Mod 
-IMAPGUI.Mod WMPerfMonPluginHTTPServer.Mod WMPerfMonPluginQuoteServer.Mod 
-WMPerfMonPluginVNCServer.Mod WMPerfMonPluginExample.Mod WMModuleState.Mod WMKeyCode.Mod WMPicView.Mod 
-ComponentViewer.Mod WMScreenShot.Mod WMBackdrop.Mod WMInstaller.Mod HotKeysCommands.Mod 
-I386.VMWareTools.Mod SynergyClient.Mod I386.WMTransitions.Mod MediaPlayer.Mod Presentation.Mod 
-MP3Player.Mod WMPlayer.Mod WAVRecorder.Mod OGGUtilities.Mod OGGVorbisPlayer.Mod WMOGGPlayer.Mod 
-DTPData.Mod DTPUtilities.Mod DTPView.Mod DTPEditor.Mod DTPText.Mod DTPRect.Mod DTPImage.Mod 
-GfxMatrix.Mod GfxImages.Mod GfxPaths.Mod GfxRegions.Mod GfxFonts.Mod Gfx.Mod GfxRaster.Mod 
-GfxBuffer.Mod WMGraphicsGfx.Mod CSS2Properties.Mod XMLComponents.Mod XMLStyle.Mod XMLLoader.Mod 
-SVGUtilities.Mod SVGColors.Mod SVGMatrix.Mod SVG.Mod SVGGradients.Mod SVGFilters.Mod SVGRenderer.Mod 
-SVGLoader.Mod SVGDecoder.Mod WebBrowserComponents.Mod XMLTransformer.Mod HTMLTransformer.Mod 
-WebBrowserPanel.Mod WebBrowser.Mod MailStorage.Mod BimboMail.Mod DebugLog.Mod WMJoysticks.Mod 
-WMTetris.Mod VNCTetrisServer.Mod Bimso.Mod WMScribble.Mod SortDemo.Mod FractalDemo.Mod WMBunny.Mod 
-TuringCoatWnd.Mod W3dVectors.Mod W3dMatrix.Mod W3dGeometry.Mod W3dAbstractWorld.Mod 
-W3dObjectGenerator.Mod W3dRasterizer.Mod W3dWorld.Mod W3dExplorer.Mod W3dMenu.Mod CATServer.Mod 
-W3dClusterWatch.Mod WMSlideshow.Mod Snow.Mod MenuEdit.Mod PresentViewer.Mod TestSuite.Mod PCTest.Mod 
-Versioning.Mod FoxTest.Mod TestFiles.Mod BenchTCP.Mod TestDates.Mod TestStrings.Mod BenchXML.Mod 
-BenchSyntaxHighlighter.Mod CryptoTestBigNumbers.Mod CryptoTestCiphers.Mod CryptoTestDH.Mod CryptoTestDSA.Mod 
-CryptoTestHMAC.Mod CryptoTestHashes.Mod CryptoTestRSA.Mod BeepTest.Mod JoysticksTest.Mod TestMenu.Mod 
-PieTest.Mod TestTrees.Mod TestComponentDragDrop.Mod ComponentInfo.Mod TestComponents.Mod 
-TestXMLPlugins.Mod HelloWorld.Mod HelloWorld1.Mod HelloWorld2.Mod HelloWorld3.Mod Example1.Mod 
-Example2.Mod Example3.Mod Example4.Mod Example5.Mod Example6.Mod Example7.Mod Example8.Mod 
-ExampleTextWriter.Mod JavaLocks.Mod WebAccounts.Mod WebForum.Mod ExerciseGroups.Mod IsoImages.Mod 
-ReleaseThreadPool.Mod Release.Mod PETReleaseTree.Mod Linker0.Mod Linker1.Mod Linker.Mod 
-Unix.BootLinkerHeaps.Mod Unix.BootLinkerModules.Mod Unix.BootLinkerLoader.Mod Unix.BootLinker.Mod 
-BootManager.Mod EFI.Mod I386.EFIMachine.Mod EFIBlockIO.Mod EFIDiskIO.Mod EFIFileProtocol.Mod 
-EFISimpleFS.Mod EFILoadedImage.Mod EFIGraphicsOutput.Mod EFITrace.Mod EFILib.Mod EFITest.Mod 
-EFIGraphicalConsole.Mod EFIA2Loader.Mod Sage.UDPChatBase.Mod Sage.UDPChatServer.Mod Sage.UDPChatClient.Mod 
-CyrillicUtilities.Mod YMF754Util.Mod SambaClient.Mod SambaServer.Mod srBase.Mod srRayEngine.Mod srMath.Mod 
-I386.srE.Mod srGL.Mod srHex.Mod srImage.Mod srVoxel.Mod srVoxel2.Mod srVoxel3.Mod srVolShader.Mod 
-srVoxel4.Mod srVoxel5.Mod srM2Space.Mod srM3Space.Mod srM5Space.Mod srM6Space.Mod 
-srRastermovie.Mod srTexVox.Mod srThermoCell.Mod srTree.Mod sr3DTexture.Mod srLifeVox.Mod srRotaVox.Mod 
-srvoxels.Mod srRender.Mod MenuPages.Mod WMOverlay.Mod PrettyPrint.Mod NbrInt8.Mod NbrInt16.Mod 
-NbrInt32.Mod I386.NbrInt64.Mod NbrInt.Mod NbrRat.Mod I386.NbrRe32.Mod I386.NbrRe64.Mod NbrRe.Mod 
-NbrCplx.Mod NbrStrings.Mod WPM.Mod AlmSmtpReceiver.Mod WMFontCCGConverter.Mod WebCGI.Mod 
-RegisterRFW.Mod WebBimbodot.Mod TFWebForum.Mod PDF.Mod AFM.Mod PDFExample.Mod Visualizer.Mod 
-ReleaseVisualizerScanner.Mod ReleaseVisualizer.Mod OdUtil.Mod OdXml.Mod OdCond.Mod OdAuthBase.Mod OdAuth.Mod 
-OdClient.Mod OdVCSBase.Mod SVNArgument.Mod SVNOutput.Mod SVNUtil.Mod Oberon.Kernel.Mod 
-Oberon.Modules.Mod Oberon.FileDir.Mod Oberon.Files.Mod Oberon.Disks.Mod Oberon.Objects.Mod 
-OberonInput.Mod OberonDisplay.Mod Oberon.Display.Mod Oberon.Input.Mod Oberon.Viewers.Mod 
-Oberon.Fonts.Mod Oberon.Mod Oberon.Texts.Mod Oberon.Oberon.Mod Oberon.MenuViewers.Mod 
-Oberon.TextFrames.Mod Oberon.System.Mod Oberon.In.Mod Oberon.Out.Mod Oberon.Dates.Mod Oberon.Strings.Mod 
-I386.Oberon.Bitmaps.Mod Oberon.Pictures.Mod Oberon.RandomNumbers.Mod Oberon.V24.Mod Unix.Oberon.Printer.Mod 
-Oberon.OPM.Mod Oberon.OPS.Mod Oberon.OPT.Mod Oberon.OPB.Mod Oberon.OPA.Mod Oberon.OPP.Mod 
-Oberon.OPO.Mod Oberon.OPL.Mod Oberon.OPC.Mod Oberon.OPV.Mod Oberon.Compiler.Mod Oberon.OPAData.Mod 
-Oberon.Edit.Mod Oberon.Styles.Mod Oberon.ScriptFrames.Mod Oberon.Script.Mod Oberon.Partitions.Mod 
-Oberon.Browser.Mod Oberon.FATFiles.Mod Oberon.DOS.Mod Oberon.Hello.Mod Oberon.PSPrinter.Mod 
-Oberon.HPLaserPrinter.Mod Oberon.HPPCL.Mod Unix.Oberon.UnixPrinter.Mod Unix.Oberon.NetSystem.Mod 
-Oberon.HelloServer.Mod Oberon.Terminals.Mod Oberon.TerminalFrames.Mod Oberon.Telnet.Mod 
-Oberon.TextMail.Mod Oberon.FTP.Mod Oberon.XYplane.Mod Oberon.IFS.Mod Oberon.ET.Mod Oberon.Menu.Mod 
-Oberon.Decoder.Mod Oberon.V24Log.Mod Oberon.SysLog.Mod Oberon.ZlibWriters.Mod Oberon.ZlibReaders.Mod 
-Oberon.Zip.Mod Oberon.ZipTool.Mod Oberon.GZWriters.Mod Oberon.GZReaders.Mod Oberon.GZip.Mod 
-Oberon.TGZ.Mod Oberon.PCARMDecoder.Mod Oberon.Aos.Mod Oberon.OFSTools.Mod Oberon.CleanupFiles.Mod 
-Oberon.FATTools.Mod Oberon.Colors.Mod Oberon.Display3.Mod Oberon.Effects.Mod Oberon.Printer3.Mod 
-Oberon.Attributes.Mod Oberon.Links.Mod Oberon.Gadgets.Mod Oberon.BasicGadgets.Mod Oberon.TextFields.Mod 
-Oberon.ListRiders.Mod Oberon.ListModels.Mod Oberon.ListDags.Mod Oberon.ListGadgets.Mod Oberon.Lists.Mod 
-Oberon.Panels.Mod Unix.Oberon.TextGadgets0.Mod Unix.Oberon.TextGadgets.Mod Oberon.BasicFigures.Mod 
-Unix.Oberon.Scrollbars.Mod Unix.Oberon.TextSBControl.Mod Oberon.Directories.Mod Oberon.Clocks.Mod 
-Oberon.Organizers.Mod Oberon.Complex.Mod Oberon.SetGadgets.Mod Oberon.TimeStamps.Mod Oberon.Gages.Mod 
-Oberon.AudioGadgets.Mod Oberon.ProgressMeters.Mod Oberon.Sisiphus.Mod Oberon.Documents.Mod Oberon.Views.Mod 
-Oberon.Desktops.Mod Unix.Oberon.TextDocs.Mod Oberon.PanelDocs.Mod Oberon.Icons.Mod 
-Oberon.ColorTools.Mod Oberon.NamePlates.Mod Oberon.Navigators.Mod Oberon.NoteBooks.Mod Oberon.Finder.Mod 
-Oberon.GadgetsIn.Mod Oberon.GadgetsOut.Mod Oberon.ScrollViews.Mod Oberon.RefGadgets.Mod 
-Oberon.Columbus.Mod Oberon.ObjExplorer.Mod Oberon.Compress.Mod Oberon.CompressCrypt.Mod 
-Oberon.AsciiCoder.Mod Oberon.Base64.Mod Oberon.UUDecoder.Mod Oberon.BinHex.Mod Oberon.Rot13.Mod 
-Oberon.Tar.Mod Oberon.QuotedPrintable.Mod Oberon.Builder.Mod Oberon.Watson0.Mod Oberon.Watson.Mod 
-Oberon.EditTools.Mod Oberon.Outlines.Mod Oberon.OFormatterIO.Mod Oberon.OFormatter.Mod 
-Oberon.StyleGadgets.Mod Oberon.ScriptGadgets.Mod Oberon.Rembrandt0.Mod Oberon.Rembrandt.Mod 
-Oberon.RembrandtDocs.Mod Oberon.RembrandtTools.Mod Oberon.ErrorGadgets.Mod Oberon.PC.Mod 
-Unix.Oberon.Clipboard.Mod Oberon.JPEG.Mod Oberon.GIF.Mod Oberon.XBM.Mod Oberon.BMP.Mod Oberon.ICO.Mod 
-Oberon.PCX.Mod Oberon.TGA.Mod Oberon.IFF.Mod Oberon.ColorModels.Mod Oberon.XPM.Mod Oberon.PPM.Mod 
-Oberon.PSD.Mod Oberon.Images.Mod Oberon.ImageGadgets.Mod Oberon.ImageDocs.Mod 
-Oberon.PictImages.Mod Oberon.BMPImages.Mod Oberon.JPEGImages.Mod Oberon.GIFImages.Mod 
-Oberon.PSDImages.Mod Oberon.ColorGadgets.Mod Oberon.PCXImages.Mod Oberon.ColorWells.Mod 
-Oberon.Streams.Mod Oberon.TextStreams.Mod Oberon.BTrees.Mod Oberon.MIME.Mod Oberon.HyperDocs.Mod 
-Oberon.NetTools.Mod Oberon.PasswordFields.Mod Oberon.HyperDocTools.Mod Oberon.Mail.Mod 
-Oberon.FTPDocs.Mod Oberon.Finger.Mod Oberon.News.Mod Oberon.Gopher.Mod Oberon.TerminalGadgets.Mod 
-Oberon.TelnetGadgets.Mod Oberon.HTTPDocs0.Mod Oberon.HTMLDocs.Mod Oberon.HTTPDocs.Mod Oberon.HTMLForms.Mod 
-Oberon.HTMLImages.Mod Oberon.HTMLTables.Mod Oberon.ZipDocs.Mod Oberon.Packages.Mod Oberon.PlugIns.Mod 
-Oberon.HTMLPlugIns.Mod Oberon.Copyright.Mod Oberon.FileDisks.Mod Oberon.OTInt.Mod Oberon.OTScan.Mod 
-Oberon.OType.Mod Oberon.OTFonts.Mod Oberon.GfxMatrix.Mod Oberon.GfxImages.Mod Oberon.GfxPaths.Mod 
-Oberon.GfxRegions.Mod Oberon.GfxFonts0.Mod Oberon.GfxFonts.Mod Oberon.Gfx.Mod Oberon.GfxRaster.Mod 
-Oberon.GfxPrinter.Mod Oberon.GfxBuffer.Mod Oberon.GfxDisplay.Mod Oberon.GfxPS.Mod Oberon.GfxOType.Mod 
-Oberon.GfxPKFonts.Mod Oberon.GfxTest.Mod Oberon.GfxDemo.Mod Oberon.Leonardo.Mod Oberon.LeoFrames.Mod 
-Oberon.LeoTools.Mod Oberon.LeoDocs.Mod Oberon.LeoPanels.Mod Oberon.LeoLists.Mod Oberon.LeoPens.Mod 
-Oberon.LeoOutliners.Mod Oberon.LeoPenEditors.Mod Oberon.LeoPaths.Mod Oberon.LeoPathEditors.Mod 
-Oberon.LeoSplines.Mod Oberon.LeoSplineEditors.Mod Oberon.LeoCaptions.Mod Oberon.LeoCaptionEditors.Mod 
-Oberon.LeoBasic.Mod Oberon.LeoBasicEditors.Mod Oberon.LeoImages.Mod Oberon.LeoImageEditors.Mod 
-Oberon.LeoDraw.Mod Oberon.Scheme.Mod Oberon.SchemeOps.Mod Oberon.Vinci.Mod Oberon.VinciGadgets.Mod 
-Oberon.VinciDocs.Mod Oberon.VinciShapes.Mod Oberon.VinciPens.Mod Oberon.VinciEditors.Mod 
-Oberon.TextPopups.Mod Oberon.V24Gadgets.Mod Oberon.Hex.Mod Oberon.Conversions.Mod Oberon.HPCalc.Mod 
-Oberon.EditKeys.Mod Oberon.Find.Mod Oberon.TeXTools.Mod Oberon.SaveScreen.Mod Oberon.SaveTiles.Mod 
-Oberon.SaveParticles.Mod Oberon.SaveDecay.Mod Oberon.SaveSisyphus.Mod Oberon.SaveSwarm.Mod 
-Oberon.SavePoints.Mod Oberon.MakePoints.Mod Oberon.SaveLife.Mod Oberon.SaveArt.Mod Oberon.DayTime.Mod 
-Oberon.Backdrops.Mod Oberon.LayoutPanels0.Mod Oberon.LayoutPanels.Mod Oberon.Layouts.Mod 
-Oberon.LayLaS.Mod Oberon.LayLa.Mod Oberon.LayLa2S.Mod Oberon.LayLa2.Mod Oberon.LayLaDemo.Mod 
-Oberon.Books0.Mod Oberon.Books.Mod Oberon.BooksHelp.Mod Oberon.BookDocs.Mod Oberon.BookCompiler.Mod 
-Oberon.Sets.Mod Oberon.CRS.Mod Oberon.CRT.Mod Oberon.CRA.Mod Oberon.CRX.Mod Oberon.CRP.Mod 
-Oberon.Coco.Mod Oberon.FontEditor.Mod Oberon.ASCIITab.Mod Oberon.Magnifier.Mod Oberon.Cards.Mod 
-Oberon.Solitaire.Mod Oberon.Spider.Mod Oberon.Freecell.Mod Oberon.MineSweeper.Mod Oberon.Sokoban.Mod 
-Oberon.Scramble.Mod Oberon.Shanghai.Mod Oberon.Tetris.Mod Oberon.Asteroids.Mod Oberon.HTML.Mod 
-Oberon.WTS.Mod Oberon.WTSFold.Mod Oberon.WTSPict.Mod Oberon.WTSStamp.Mod Oberon.WTSDraw.Mod 
-Oberon.CUSM.Mod Oberon.DiffGadgets.Mod Oberon.Diff.Mod Oberon.Sort.Mod Oberon.RXA.Mod Oberon.RX.Mod 
-Oberon.PictConverters.Mod Oberon.PS.Mod Oberon.Histogram.Mod Oberon.MultiMail.Mod Oberon.Calc.Mod 
-Oberon.Calculator.Mod Oberon.CalculatorGadgets.Mod Oberon.DBF.Mod Oberon.DBFDump.Mod Oberon.Swarm.Mod 
-Oberon.DVIFiles.Mod Oberon.DVIViewers.Mod Oberon.DVIDocs.Mod Oberon.ColorSystem.Mod Oberon.PhonePad.Mod 
-Oberon.Plotter.Mod Oberon.Plot.Mod Oberon.Lissajous.Mod Oberon.Graphs.Mod Oberon.Diagrams.Mod 
-Oberon.Simulator.Mod Oberon.Popups.Mod Oberon.BartSimpson.Mod Oberon.Cups.Mod Oberon.Examples.Mod 
-Oberon.Examples1.Mod Oberon.OpenDemo.Mod Oberon.OpenDemo2.Mod Oberon.ExampleOberon.Mod 
-Oberon.Suitcases.Mod Oberon.Skeleton.Mod Oberon.ViewSkeleton.Mod Oberon.ColorDriver.Mod 
-Oberon.DocumentSkeleton.Mod Oberon.Portraits.Mod Oberon.Reminders.Mod Oberon.TaskExample.Mod 
-Oberon.TCPExample.Mod 
-~
-SystemTools.Show Time elapsed: ~ SystemTools.Ln ~
-SystemTools.Timer elapsed ~ SystemTools.Ln ~
-~
+ 
+ Build 'Solaris32G.elf' by concatenating 'A2Loader.elf' (C) and 'Solaris32G.core' (Oberon).	
+ 
+ SolarisELF.Build Solaris32G.elf ~

+ 57 - 74
source/Generic.Solaris.I386.Unix.Mod

@@ -16,7 +16,7 @@ IMPORT S := SYSTEM, Glue, Trace;
 
 
 CONST
-	Version* = "SolarisG32";
+	Version* = "Solaris";
 
 	libcname* = "libc.so.1";
 	libmname* = "libm.so.1";
@@ -124,8 +124,6 @@ CONST
 	SIGJVM1		= 39;		(* reserved signal for Java Virtual Machine *)
 	SIGJVM2		= 40;		(* reserved signal for Java Virtual Machine *)
 	
-	T_SIGRESUME = SIGUSR1;
-	T_SIGSUSPEND = SIGUSR2; 
 	
 	SIG_BLOCK = 1;
 	SIG_UNBLOCK=2;
@@ -397,10 +395,9 @@ TYPE
 	
 VAR
 	suspend_mutex: MutexDesc;
+	handler_done: BOOLEAN;
 	mainthread: Thread_t;
-	suspend_done: LONGINT;
-	resume_done: LONGINT;
-	sasuspend, saresume: Sigaction;
+	sasuspend: Sigaction;
 	
 	argc-: LONGINT;  argv-: ADDRESS;  environ: ADDRESS;
 	
@@ -430,11 +427,11 @@ VAR
 	pthread_cond_wait		: PROCEDURE {C} ( cond: ADDRESS; mutex: ADDRESS ): WORD;
 	pthread_cond_signal		: PROCEDURE {C} ( cond: ADDRESS ): WORD; 
 	
-	pthread_create	: PROCEDURE {C} ( newthread: ADDRESS; attr: ADDRESS; start_routine: PROCEDURE {C} (arg: PROCEDURE):ADDRESS; arg:PROCEDURE): WORD;
+	pthread_create	: PROCEDURE {C} ( newthread: ADDRESS; attr: ADDRESS; start_routine: PROCEDURE {C} (arg: PROCEDURE):ADDRESS; arg:PROCEDURE): Thread_t;
 	pthread_exit		: PROCEDURE {C} ( thr: ADDRESS );
-	pthread_detach	: PROCEDURE {C} ( thr: ADDRESS );
-	pthread_kill		: PROCEDURE {C} ( thr: ADDRESS; sigid: LONGINT ): LONGINT;
-	pthread_cancel	: PROCEDURE {C} ( thr: ADDRESS );
+	pthread_detach	: PROCEDURE {C} ( thr: Thread_t );
+	pthread_kill		: PROCEDURE {C} ( thr: Thread_t; sigid: LONGINT ): LONGINT;
+	pthread_cancel	: PROCEDURE {C} ( thr: Thread_t );
 	pthread_self		: PROCEDURE {C} ( ): Thread_t;
 	
 	pthread_attr_init: PROCEDURE {C} ( attr: ADDRESS );
@@ -442,14 +439,16 @@ VAR
 	pthread_attr_setdetachstate: PROCEDURE {C} ( attr: ADDRESS; set: WORD );
 	pthread_attr_setstacksize: PROCEDURE {C} ( attr: ADDRESS; stackSize: SIZE );
 	
-
-
 	sched_get_priority_max		: PROCEDURE {C} ( policy: LONGINT ): LONGINT;
 	sched_get_priority_min		: PROCEDURE {C} ( policy: LONGINT ): LONGINT;
 	pthread_setschedparam		: PROCEDURE {C} ( thread: Thread_t; policy: LONGINT; param: ADDRESS ): WORD;
 	pthread_getschedparam		: PROCEDURE {C} ( thread: Thread_t; policy: LONGINT; param: ADDRESS ): WORD;
 	pthread_setcancelstate		: PROCEDURE {C} ( state: LONGINT; oldstate: ADDRESS ): LONGINT;
 	pthread_setcanceltype		: PROCEDURE {C} ( type: LONGINT; oldtype: ADDRESS ): LONGINT;
+	
+	thr_suspend		: PROCEDURE {C} ( thread: Thread_t ): LONGINT;
+	thr_continue		: PROCEDURE {C} ( thread: Thread_t ): LONGINT;
+	
 	sigaction			: PROCEDURE {C} ( signum: LONGINT; CONST act, oldact: ADDRESS ): LONGINT;
 	sigemptyset		: PROCEDURE {C} ( set: ADDRESS );
 	sigfillset			: PROCEDURE {C} ( set: ADDRESS ): LONGINT;
@@ -548,7 +547,7 @@ VAR
 		cont.mc.r_sp := sp;	
 	END ModifyContext;
 	
-	PROCEDURE CopyContext*(CONST from: McontextDesc; VAR to: McontextDesc);
+	PROCEDURE CopyContext*( CONST from: McontextDesc; VAR to: McontextDesc );
 	BEGIN
 		S.MOVE( ADDRESSOF( from ), ADDRESSOF( to ), SIZEOF( McontextDesc ) );
 	END CopyContext;
@@ -574,12 +573,21 @@ VAR
 
 	(*------------------------------------------------------------------------------------------------------*)
 	
-	PROCEDURE {C} SigHandler  ( sig: LONGINT; scp: ADDRESS; ucp: ADDRESS ); (* reversed arguments !! *)
+	VAR suspendHandler*: PROCEDURE( c: Ucontext );
+	
+	PROCEDURE {C} SigHandler( sig: LONGINT; scp: ADDRESS; ucp: Ucontext ); (* reversed arguments !! *)
+	VAR r: LONGINT;  thr: Thread_t;
 	BEGIN
-		IF trap # NIL THEN 
-			trap( sig, scp, ucp, 0 )
+		IF sig = SIGUSR1 THEN
+			suspendHandler( ucp );
+			thr := pthread_self( );
+			r := thr_suspend( thr )
+		ELSIF sig = SIGUSR2 THEN
+			suspendHandler( ucp );
+		ELSIF trap # NIL THEN 
+			trap( sig, scp, ucp, 0 );
 		ELSE
-			TRACE( sig, scp, ucp )
+			Trace.String( "Unix.SigHandler: sig = " ); Trace.Int( sig, 0 ); Trace.Ln;  exit( -1 );
 		END;
 	END SigHandler;
 	
@@ -614,6 +622,8 @@ VAR
 		FOR i := 1 TO 15 DO
 			IF i # 9 THEN InstallHandler( i ) END;
 		END;
+		InstallHandler( SIGUSR1 );
+		InstallHandler( SIGUSR2 );
 	END InitSignalHandler;
 	
 	(*-------------------------------------------------------------------------------------------------------------*)
@@ -627,66 +637,38 @@ VAR
 		mainthread := pthread_self();
 		high := sched_get_priority_max( SCHED_OTHER );
 		low := sched_get_priority_min( SCHED_OTHER );
-	    
-		param.sched_priority := high;
-		IF pthread_setschedparam( mainthread, SCHED_OTHER, ADDRESSOF( param ) ) # 0 THEN
-			Perror("ThrInitialize: setparam");
-		END;
-		
-	    sigemptyset( ADDRESSOF( sasuspend.sa_mask ) );
-	    sigaddset(  ADDRESSOF( sasuspend.sa_mask ), T_SIGRESUME );
-	    sasuspend.sa_flags := SA_SIGINFO +  SA_NODEFER;;
-	    sasuspend.sa_handler := suspend_handler;
-	    ASSERT(sigaction( T_SIGSUSPEND, ADDRESSOF( sasuspend ), NIL ) = 0);
-
-	    sigemptyset( ADDRESS OF saresume.sa_mask );
-	    saresume.sa_flags := 0;
-	    saresume.sa_handler := resume_handler;
-	    ASSERT(sigaction( T_SIGRESUME, ADDRESSOF( saresume ), NIL ) = 0);
-
-	    RETURN TRUE;
+	 
+		RETURN TRUE;
 	END ThrInitialize;
 	
-	
-	PROCEDURE {C} resume_handler( sig: LONGINT );
-	BEGIN
-	END resume_handler;
 
+	
 	PROCEDURE ThrResume*( thr: Thread_t );
-	VAR n, r: LONGINT; 
+	VAR r: LONGINT;
 	BEGIN
-	    r := pthread_mutex_lock( ADDRESSOF( suspend_mutex ) );
-	    resume_done := 0; n := 1;
-	    r := pthread_kill( thr, T_SIGRESUME ); 
-	    
-	    WHILE (resume_done # 1) & (n < 50) DO  ThrSleep( 1 ); INC( n )  END; 
-	    r := pthread_mutex_unlock( ADDRESSOF( suspend_mutex ) );
-	END ThrResume;
+		r := thr_continue( thr )
+	END ThrResume;	
 
-	VAR suspendHandler*: PROCEDURE( c: Ucontext );
-
-	PROCEDURE {C} suspend_handler( sig: LONGINT; scp: ADDRESS; ucp: ADDRESS );
-	VAR block: Sigset; r: LONGINT;
-	BEGIN
-		IF suspendHandler # NIL THEN  suspendHandler( S.VAL( Ucontext, ucp ) ) END;
-		r := sigfillset( ADDRESSOF( block ) );
-		sigdelset(  ADDRESSOF( block ), T_SIGRESUME );
-		suspend_done := 1;
-		r := sigsuspend(  ADDRESSOF( block ) ); (* await T_SIGRESUME *)
-		resume_done := 1;
-	END suspend_handler;
-
-	PROCEDURE ThrSuspend*( thr: Thread_t );
+	
+	PROCEDURE ThrSuspend*( thr: Thread_t; saveContext: BOOLEAN );
 	VAR r: LONGINT;
 	BEGIN
-	    r := pthread_mutex_lock( ADDRESSOF( suspend_mutex ) );
-	    suspend_done := 0;
-	    r := pthread_kill( thr, T_SIGSUSPEND );
-	    WHILE (suspend_done # 1) DO  ThrSleep( 1 )  END;
-	    r := pthread_mutex_unlock( ADDRESSOF( suspend_mutex ) );
-	END ThrSuspend;
-
+		IF saveContext THEN
+			r := pthread_kill( thr, SIGUSR1 );	
+			(*	not working in Solaris when the thread is stalled 
+				in a mutex.
+				handler gets arrived but has bad side effects, 
+				yields traps and locks the system *)
+		ELSE
+			r := thr_suspend( thr )
+		END
+	END ThrSuspend;	
 
+	PROCEDURE GetThreadContext*( thr: Thread_t );
+	VAR r: LONGINT;
+	BEGIN
+		r := pthread_kill( thr, SIGUSR2 );	
+	END GetThreadContext;
 	
 	
 	PROCEDURE SetSigaltstack;
@@ -722,7 +704,8 @@ VAR
 		sigdelset( ADDRESSOF( new ), SIGBUS );
 		sigdelset( ADDRESSOF( new ), SIGSEGV );
 		sigdelset( ADDRESSOF( new ), SIGTERM );
-		sigdelset( ADDRESSOF( new ), T_SIGSUSPEND );
+		sigdelset( ADDRESSOF( new ), SIGUSR1 );	
+		sigdelset( ADDRESSOF( new ), SIGUSR2 );	
 		r := pthread_sigmask( SIG_SETMASK, ADDRESSOF( new ), ADDRESSOF( old ) );
 		r := pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NIL );
 		r := pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NIL );
@@ -796,11 +779,11 @@ VAR
 		param: Sched_param;
 		policy, r: LONGINT;
 	BEGIN
-		r := pthread_getschedparam( thr, ADDRESSOF( policy ), ADDRESSOF( param ) );
+	(*	r := pthread_getschedparam( thr, ADDRESSOF( policy ), ADDRESSOF( param ) );
 		param.sched_priority := prio;
 		IF pthread_setschedparam( thr, SCHED_OTHER, ADDRESSOF( param ) ) # 0 THEN
 			Perror( "pthread_setschedparam" );
-		END
+		END	*)
 	END ThrSetPriority;
 
 	PROCEDURE ThrGetPriority*( thr: Thread_t ):LONGINT;
@@ -887,7 +870,6 @@ VAR
 	PROCEDURE {C} X11ErrorHandler( d: ADDRESS; err: ADDRESS ): WORD;
 	VAR res: LONGINT;
 	BEGIN
-		TRACE( d, err );
 		IF oberonXErrorHandler # NIL THEN 
 			res := oberonXErrorHandler( d, err );
 		END;
@@ -897,7 +879,6 @@ VAR
 	PROCEDURE {C} X11IOErrorHandler( d: ADDRESS ): WORD;
 	VAR res: LONGINT;
 	BEGIN
-		TRACE( d );
 		IF oberonXIOErrorHandler # NIL THEN
 			res := oberonXIOErrorHandler( d );
 		END;
@@ -925,7 +906,6 @@ VAR
 		IF val = 0 THEN
 			Trace.String( "Unix.Dlsym:  entry '" );  Trace.String( sym );  Trace.String( "' not found" );
 			Trace.Ln;
-			exit( 0 )
 		END
 	END Dlsym;
 
@@ -1051,6 +1031,9 @@ VAR
 		Dlsym( libp, "pthread_attr_setstacksize", ADDRESSOF( pthread_attr_setstacksize ) );
 		Dlsym( libp, "pthread_self", ADDRESSOF( pthread_self ) );
 		
+		Dlsym( libc, "thr_suspend", ADDRESSOF( thr_suspend ) );
+		Dlsym( libc, "thr_continue", ADDRESSOF( thr_continue ) );
+		
 		Dlsym( libc, "posix_spawnp",	ADDRESSOF( posix_spawnp ) );
 		Dlsym( libc, "posix_spawn",	ADDRESSOF( posix_spawn ) );
 

+ 818 - 0
source/Generic.Solaris.Objects.Mod

@@ -0,0 +1,818 @@
+(* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
+
+MODULE Objects;   (** AUTHOR "pjm, G.F."; PURPOSE "Active object runtime support"; *)
+
+
+IMPORT S := SYSTEM, Trace, Glue, Unix, Machine, Heaps, Modules;
+
+CONST
+
+	(*! Process flags, meaningless in Unix ports !!! *)
+	PleaseHalt* = 10;		(* Process requested to Halt itself soon *)
+	Unbreakable*= 11;		(* FINALLY shall not catch HALT exception (PleaseHalt is also set) *)
+	SelfTermination*=12;	(* Indicates the process has requested to terminate ifself (PleaseHalt is also set) *)
+	Preempted* = 27;		(* Has been preempted. *)
+	Resistant* = 28;		(* Can only be destroyed by itself *)
+
+
+	MinPriority*	= Unix.ThreadLow;
+	Low*			= Unix.ThreadLow + 1;
+	Normal*		= Unix.ThreadNormal;
+	High*			= Unix.ThreadHigh - 2;
+	GCPriority*	= Unix.ThreadHigh - 1;
+	Realtime*	= Unix.ThreadHigh;
+
+	(* Process flag defined by compiler in OPC.CallRecBody *)
+	Restart* = 0;	(* Restart/Destroy process on exception *)
+
+	(* Process modes (in UnixAos Running means Running or Ready!) *)
+	Unknown* = 0;  Ready* = 1;  Running* = 2;  AwaitingLock* = 3;
+	AwaitingCond* = 4;  AwaitingEvent* = 5;  Terminated* = 6;  Locked = 7;
+
+	Second* = 1000;	(* frequency of ticks increments in Hz *)
+
+	DefaultStacksize = 128*1024;
+	
+	AddrSize = SIZEOF( ADDRESS )
+
+
+VAR
+	(* timer *)
+	timerActivity		: TimerActivity;
+	clock				: Clock;
+	timers				: Timer;  
+	timerListMutex	: Unix.Mutex_t;
+	
+	(* processes *)
+	root-	: Process;	(*!  Anchor of all instantiated threads in system *)
+	stacksize: LONGINT;		(* stack size of active objects, adjustable via boot parameter *)
+	
+	processList		: Unix.Mutex_t;
+	createProcess	: Unix.Mutex_t;
+	startProcess		: Unix.Mutex_t;
+	lockMutex		: Unix.Mutex_t;
+	childrunning		: Unix.Condition_t;
+		
+	newProcess: Process;
+	nextPID: LONGINT;
+	
+	finalizerCaller	: FinalizerCaller;
+	
+	
+
+TYPE
+
+	LockT= POINTER TO RECORD
+		mtx, enter: ADDRESS;
+	END;
+
+	CpuCyclesArray* = ARRAY Machine.MaxCPU OF HUGEINT;
+
+	ProtectedObject = POINTER TO RECORD END;
+
+	ObjectHeader = Heaps.ProtRecBlock;
+
+	ProcessQueue = Heaps.ProcessQueue;
+
+	EventHandler* = PROCEDURE  {DELEGATE};
+
+
+
+	Timer* =  OBJECT
+	VAR
+		next: Timer;
+		trigger: LONGINT;
+		handler: EventHandler
+	END Timer;
+			
+	TimerActivity = OBJECT		
+	VAR 
+		t, r: Timer;  h: EventHandler;  restart: BOOLEAN;
+		
+		PROCEDURE UpdateTicks;
+		BEGIN {EXCLUSIVE}
+			Machine.UpdateTicks
+		END UpdateTicks;
+		
+		PROCEDURE Restart;
+		BEGIN {EXCLUSIVE}
+			restart := TRUE
+		END Restart;
+		
+	BEGIN {ACTIVE, SAFE, PRIORITY(High)}
+		restart := FALSE;
+		LOOP
+			t := timers;
+			IF t # NIL THEN				
+				h := NIL;  r := NIL;
+				BEGIN {EXCLUSIVE}
+					AWAIT( (Machine.ticks >= t.trigger) OR restart );  restart := FALSE;
+					IF Machine.ticks >= t.trigger THEN
+						h := t.handler;  r := t
+					END
+				END;
+				IF r # NIL THEN  Remove( r )  END;
+				IF h # NIL THEN  (* not canceled *) h END
+			ELSE				
+				BEGIN{EXCLUSIVE}
+					AWAIT( restart );  restart := FALSE;
+				END
+			END
+		END
+	END TimerActivity;
+	
+	Clock* = OBJECT
+	VAR i: LONGINT;
+	BEGIN{ACTIVE}
+		LOOP
+			Unix.ThrSleep( 10 ); 
+			timerActivity.UpdateTicks
+		END;
+	END Clock;
+
+
+
+	FinalizedCollection* = OBJECT (* base type for collection, extended in Kernel.Mod *)
+		PROCEDURE RemoveAll*(obj: ANY); (** abstract *)
+		BEGIN HALT(301) END RemoveAll;
+	END FinalizedCollection;
+
+	FinalizerNode* = POINTER TO RECORD (Heaps.FinalizerNode)
+		c*: FinalizedCollection (* base type for collection containing object *)
+	END;
+
+		
+	FinalizerCaller = OBJECT	(* separate active object that calls finalizers *)
+	VAR 
+		n: Heaps.FinalizerNode;  start: BOOLEAN;
+	
+		PROCEDURE Activate;
+		BEGIN {EXCLUSIVE}
+			start := TRUE
+		END Activate;
+		
+	BEGIN {ACTIVE, SAFE, PRIORITY(High)}
+		start := FALSE;
+		LOOP 
+			BEGIN {EXCLUSIVE} AWAIT( start ) END;
+			start := FALSE;
+			LOOP
+				n := Heaps.GetFinalizer();
+				IF n = NIL THEN EXIT END;
+				IF n IS FinalizerNode THEN
+					n(FinalizerNode).c.RemoveAll(n.objStrong)	(* remove it if it is not removed yet *)
+				END;
+				IF n.finalizer # NIL THEN
+					n.finalizer(n.objStrong)	(* may acquire locks *)
+				END;
+			END;
+			Machine.ReleaseGC( )
+		END
+	END FinalizerCaller;
+	
+
+
+	Body = PROCEDURE ( self: ProtectedObject );
+	Condition = PROCEDURE ( slink: ADDRESS ): BOOLEAN;
+	
+	Process* = OBJECT (Heaps.ProcessLink)
+	VAR
+		threadId-			: Unix.Thread_t;
+		nextProcess-	: Process;	(* next in list of all processes *)
+		stackBottom	-	: ADDRESS;
+		id-				: LONGINT;
+		body			: Body;
+		mode-		: LONGINT;
+		flags-			: SET;
+		priority-		: LONGINT;	(* only effective if Aos is running SUID root *)
+		succ			: Process;   		  	(* in ProcessQueue *)
+		obj-			: ProtectedObject;	(* associated active object *)
+		condition-	: Condition;   			(* awaited process' condition *)
+		condFP-		: ADDRESS;			(* awaited process' condition's context *)
+		continue		: Unix.Condition_t;	(* gets signaled when condition yields true *)
+		waitingOn-	: ProtectedObject;
+		procID-		: LONGINT;				(* processor ID where running, not used in UnixAos *)
+		state-			: Machine.State;		(*! not used in UnixAos! *)
+		context		: Unix.McontextDesc;
+		contsp			: ADDRESS;
+		state0	: ARRAY 2048 OF CHAR;		(* thread state at body start, used for restart after trap *)
+					
+				
+		PROCEDURE FindRoots*;
+		VAR sp, ptr, bp, n, a0, a1, adr: ADDRESS; desc: Modules.ProcedureDescPointer; i: LONGINT; p {UNTRACED}: ANY;
+			me: Process;
+		BEGIN
+			IF mode # Terminated THEN
+				
+				IF SELF = CurrentProcess() THEN
+					context.r_sp := Machine.CurrentSP();
+					context.r_bp := Machine.CurrentBP();
+				END;
+				sp := context.r_sp; bp := context.r_bp; 
+				
+				Heaps.Candidate( context.r_di );  Heaps.Candidate( context.r_si );
+				Heaps.Candidate( context.r_bx ); Heaps.Candidate( context.r_dx );
+				Heaps.Candidate( context.r_cx ); Heaps.Candidate( context.r_ax) ;
+				IF (stackBottom # 0) & (sp # 0) & (sp <= stackBottom) THEN
+					Heaps.RegisterCandidates( sp, stackBottom - sp );
+				END;
+			END;
+			Heaps.Mark( nextProcess ) 
+		END FindRoots;
+				
+		PROCEDURE Cancel;
+		VAR pt, t: Process;  kt: Unix.Thread_t;
+		BEGIN
+			IF SELF = CurrentProcess() THEN  Exit
+			ELSE
+				Machine.Acquire( Machine.X11 );  (* let the thread to be killed first finish its last I/O, if any *)
+				Unix.MtxLock( processList );
+					pt := NIL; t := root;  kt := 0;
+					WHILE (t # NIL ) & (t # SELF) DO  pt := t;  t := t.nextProcess  END;
+					IF t = SELF THEN
+						kt := threadId;
+						IF pt = NIL THEN  root := t.nextProcess  ELSE  pt.nextProcess := t.nextProcess  END;
+					END;
+				Unix.MtxUnlock( processList );
+				IF kt # 0 THEN  Unix.ThrKill( kt )  END;
+				Machine.Release( Machine.X11 );
+			END
+		END Cancel;
+
+		PROCEDURE GetPriority( ): LONGINT;
+		BEGIN
+			RETURN Unix.ThrGetPriority( threadId ) 
+		END GetPriority;
+
+		PROCEDURE SetPriority( prio: LONGINT );
+		VAR pr: LONGINT;
+		BEGIN
+			pr := max( Machine.prioLow, min( prio, Machine.prioHigh ) );
+			Unix.ThrSetPriority( threadId, pr );	(* works only if SUID root *)
+			priority := GetPriority( )	
+		END SetPriority;
+				
+				
+		PROCEDURE & Initialize( obj: ProtectedObject;  bodyProc: Body;  prio: LONGINT; fl: SET; stacksize: LONGINT);
+		VAR  thr: Unix.Thread_t;
+		BEGIN
+			SELF.obj := obj;  condition := NIL;  continue := Unix.ConInit(0);
+			flags := fl;
+			priority := prio;
+			nextProcess := NIL;
+			IF root # NIL THEN
+				newProcess := SELF;
+				ASSERT( bodyProc # NIL );
+				body := bodyProc;  
+				Unix.MtxLock( startProcess );
+				thr := Unix.ThrStart( BodyStarter, stacksize );
+				Unix.ConWait( childrunning, startProcess );
+				Unix.MtxUnlock( startProcess );
+				RegisterFinalizer( SELF, FinalizeProcess );
+			ELSE 
+				(* first process *)
+				stackBottom := Glue.stackBottom;  
+				threadId := Unix.ThrThis(0);
+				id := 0;  nextPID := 1;
+				root := SELF;
+				mode := Running;
+			END;
+		END Initialize;
+				
+	END Process;
+
+	GCStatusExt = OBJECT (Heaps.GCStatus)
+	
+		PROCEDURE SetgcOngoing( value: BOOLEAN );
+		VAR p: Heaps.ProcessLink; cur, r: Process; res: LONGINT; num: LONGINT; time: LONGINT;
+			
+		BEGIN 
+			IF value THEN
+				IF Machine.AcquireGC( ) THEN
+				(*	Trace.StringLn( "[GC" );		*)		
+					Machine.Acquire( Machine.X11 );	
+					Machine.Acquire( Machine.Heaps );
+					SuspendActivities;
+					
+					Heaps.CollectGarbage( Modules.root );
+					
+					Machine.Release( Machine.Heaps );
+					Machine.Release( Machine.X11 );
+					ResumeActivities;
+					finalizerCaller.Activate;
+				(*	Trace.StringLn( "GC]" )		*)
+			(*	ELSE
+					Trace.StringLn( "-GC-" )	*)
+				END
+			END;	
+		END SetgcOngoing;
+	
+	END GCStatusExt;
+
+
+	
+	PROCEDURE BodyStarter;
+	VAR p{UNTRACED}: Process;  res: LONGINT; prevBP: ADDRESS; i: LONGINT;
+	BEGIN
+		Unix.MtxLock( startProcess );
+			p := newProcess;  newProcess := NIL;
+			p.threadId := Unix.ThrThis(0);  
+			p.id := nextPID;  INC( nextPID );
+			p.stackBottom := Machine.CurrentBP( );
+			S.GET( p.stackBottom, prevBP );
+			S.PUT( prevBP, S.VAL( ADDRESS, 0 ) );	(* for terminating Reflection.StackTraceBack *)
+			Unix.MtxLock( processList );
+				p.nextProcess := root;  root := p;
+			Unix.MtxUnlock( processList );
+			Unix.ConSignal( childrunning );
+		Unix.MtxUnlock( startProcess );
+
+		p.SetPriority( p.priority );
+
+		IF Restart IN p.flags THEN
+			res := Unix.sigsetjmp( ADDRESSOF( p.state0[0] ), 1 );
+		END;
+
+		p.mode := Running;
+		p.body( p.obj );
+		p.mode := Terminated;
+		Exit
+	END BodyStarter;
+
+
+
+
+	(*---------------------   create,  lock,  await,  unlock   -------------------------*)
+	
+	
+	(* initialize the ObjectHeader, requires lockMutex temporarily *)
+	PROCEDURE InitProtHeader( hdr: ObjectHeader);
+	VAR lock: LockT;
+	BEGIN
+		(* we cannot hold the lockMute here because allocation can trigger the GC that requires the lock when activating the finalizers *)
+		NEW(lock);
+		Unix.MtxLock(lockMutex);
+		IF hdr.lock = NIL THEN
+			hdr.lock := lock;
+			lock.mtx := Unix.MtxInit( 0 );  lock.enter := Unix.ConInit( 0 );  hdr.lockedBy := NIL; 
+		END;
+		Unix.MtxUnlock(lockMutex);
+	END InitProtHeader;
+	
+	
+	PROCEDURE CreateProcess*( body: Body;  priority: LONGINT;  flags: SET;  obj: ProtectedObject );
+	VAR p: Process;  hdr: ObjectHeader;
+	BEGIN
+		Unix.MtxLock( createProcess );
+		S.GET( S.VAL( ADDRESS, obj ) + Heaps.HeapBlockOffset, hdr );  
+		InitProtHeader( hdr );
+		IF priority = 0 THEN  priority := Normal  END;
+		NEW( p, obj, body, priority, flags, stacksize ) ;	(* execute BodyStarter as new (posix or solaris) thread *)
+		Unix.MtxUnlock( createProcess );
+		RegisterFinalizer( obj, FinalizeActiveObj )
+	END CreateProcess;
+
+	PROCEDURE Lock*( obj: ProtectedObject;  exclusive: BOOLEAN );
+	VAR hdr: ObjectHeader;  p: Process; lock: LockT;
+	BEGIN
+		ASSERT( exclusive );   (* shared not implemented yet *)
+		S.GET( S.VAL( ADDRESS, obj ) + Heaps.HeapBlockOffset, hdr );
+		p := CurrentProcess();
+		p.mode := AwaitingLock;
+
+		(*! we might want to replace the lock mutex by a lock free construct *)
+		IF hdr.lock = NIL THEN  InitProtHeader( hdr )  END;		
+		lock := S.VAL(LockT, hdr.lock);
+		p.mode := Locked;
+		Unix.MtxLock( lock.mtx );
+		WHILE hdr.lockedBy # NIL DO
+			(* wait until threads with complied AWAIT conditions have left the monitor *)
+			p.mode := AwaitingLock;
+			Unix.ConWait( lock.enter, lock.mtx );
+		END;
+		p.mode := Running;  hdr.lockedBy := p;  p.waitingOn := NIL
+	END Lock;
+
+	PROCEDURE Await*( cond: Condition;  slink: ADDRESS;  obj: ProtectedObject;  flags: SET );
+	VAR hdr: ObjectHeader;  p, c: Process; lock: LockT;  sp: ADDRESS;
+	BEGIN
+		IF 1 IN flags THEN  (* compiler did not generate IF *)
+			IF cond( slink ) THEN  (* condition already true *)  RETURN  END
+		END;
+		S.GET( S.VAL( ADDRESS, obj ) + Heaps.HeapBlockOffset, hdr );  c := NIL;
+		lock := S.VAL(LockT, hdr.lock);
+		IF hdr.awaitingCond.head # NIL THEN  c := FindCondition( hdr.awaitingCond )  END;
+		
+		p := CurrentProcess();  p.succ := NIL;  p.condition := cond;  p.condFP := slink;   
+		p.waitingOn := obj;  p.mode := AwaitingCond;
+		
+		Put( hdr.awaitingCond, p );
+		hdr.lockedBy := c;
+		IF c # NIL THEN  Unix.ConSignal( c.continue )  ELSE  Unix.ConSignal( lock.enter )  END;
+		sp := Machine.CurrentSP( );
+		IF p.contsp # sp THEN
+			p.contsp := sp;
+			Unix.GetThreadContext( p.threadId )
+		END;
+		Unix.ConWait( p.continue, lock.mtx );   
+		
+		p.mode := Running;  hdr.lockedBy := p;  p.waitingOn := NIL
+	END Await;
+
+	PROCEDURE Unlock*( obj: ProtectedObject;  dummy: BOOLEAN );
+	VAR hdr: ObjectHeader;  c: Process; lock: LockT;
+	BEGIN
+		S.GET( S.VAL( ADDRESS, obj ) + Heaps.HeapBlockOffset, hdr );  c := NIL;
+		lock := S.VAL(LockT,hdr.lock);
+		IF hdr.awaitingCond.head # NIL THEN  c := FindCondition( hdr.awaitingCond )  END;
+		
+		hdr.lockedBy := c;
+		IF c # NIL THEN  Unix.ConSignal( c.continue )  ELSE  Unix.ConSignal( lock.enter )  END;
+		Unix.MtxUnlock( lock.mtx );
+	END Unlock;
+	
+	
+	
+	PROCEDURE FindCondition( VAR q: ProcessQueue ): Process;
+	VAR first, cand: Process;
+	BEGIN
+		Get( q, first );
+		IF first.condition( first.condFP ) THEN  RETURN first  ELSE  Put( q, first )  END;
+		WHILE q.head # first DO
+			Get( q, cand );
+			IF cand.condition( cand.condFP ) THEN  RETURN cand  ELSE  Put( q, cand )  END;
+		END;
+		RETURN NIL
+	END FindCondition;
+
+	PROCEDURE Get( VAR queue: ProcessQueue;  VAR new: Process );
+	VAR t: Process;
+	BEGIN
+		t := queue.head(Process);
+		IF t # NIL THEN
+			IF t = queue.tail THEN  queue.head := NIL;  queue.tail := NIL
+			ELSE  queue.head := t.succ;  t.succ := NIL
+			END
+		END;
+		new := t
+	END Get;
+
+	PROCEDURE Put( VAR queue: ProcessQueue;  t: Process );
+	BEGIN
+		IF queue.head = NIL THEN  queue.head := t  ELSE  queue.tail(Process).succ := t  END;
+		queue.tail := t
+	END Put;
+	
+	
+	
+	(*-------------------------------------------------------------------------*)
+	
+	PROCEDURE Terminate*;
+	BEGIN
+		Exit
+	END Terminate;
+
+	PROCEDURE TerminateThis*( p: Process; unbreakable: BOOLEAN );
+	BEGIN
+		p.mode := Terminated;
+		p.Cancel
+	END TerminateThis;
+	
+	PROCEDURE SetPriority*( pri: LONGINT );		(* Set the current process' priority. *)
+	VAR me: Process;
+	BEGIN
+		me := CurrentProcess();
+		me.SetPriority( pri )
+	END SetPriority;
+
+	PROCEDURE Sleep*( ms: LONGINT );
+	BEGIN
+		Unix.ThrSleep( ms )
+	END Sleep;
+
+	PROCEDURE Yield*;	(* Relinquish control. *)
+	BEGIN
+		Unix.ThrYield(0);
+	END Yield;
+	
+	(* Return current process. (DEPRECATED, use ActiveObject) *)
+	PROCEDURE CurrentProcess*( ): Process;	
+	VAR me: Unix.Thread_t;  p: Process;
+	BEGIN
+		me := Unix.ThrThis(0);
+		Unix.MtxLock( processList );
+		p := root;
+		WHILE (p # NIL) & (p.threadId # me) DO  p := p.nextProcess  END;
+		Unix.MtxUnlock( processList );
+		RETURN p
+	END CurrentProcess;
+
+	
+	(* Return the active object currently executing. *)
+	PROCEDURE ActiveObject*( ): ANY;		
+	VAR p: Process;
+	BEGIN
+		p := CurrentProcess();
+		RETURN p.obj 
+	END ActiveObject;
+	
+	
+	(* Return stack bottom of process. For compatibility WinAos/UnixAos/NativeAos  *)
+	PROCEDURE GetStackBottom*(p: Process): ADDRESS;
+	BEGIN
+		RETURN p.stackBottom
+	END GetStackBottom;
+
+
+	PROCEDURE GetProcessID*( ): LONGINT;
+	VAR p: Process;
+	BEGIN
+		p := CurrentProcess();
+		RETURN p.id;
+	END GetProcessID;
+
+	
+	PROCEDURE GetCpuCycles*( process : Process; VAR cpuCycles: CpuCyclesArray; all: BOOLEAN );
+	VAR i: LONGINT;
+	BEGIN
+		ASSERT( process # NIL );
+		FOR i := 0 TO Machine.MaxCPU-1 DO  cpuCycles[i] := 0  END;
+	END GetCpuCycles;
+	
+	
+	
+	(*-----------------------------------------------------------------------*)
+	
+	
+	PROCEDURE min( a, b: LONGINT ): LONGINT;
+	BEGIN
+		IF a <= b THEN  RETURN a  ELSE  RETURN b  END
+	END min;
+
+	PROCEDURE max( a, b: LONGINT ): LONGINT;
+	BEGIN
+		IF a >= b THEN  RETURN a  ELSE  RETURN b  END
+	END max;
+	
+	
+	PROCEDURE RegisterFinalizer( obj: ANY;  fin: Heaps.Finalizer );
+	VAR n: Heaps.FinalizerNode;
+	BEGIN
+		NEW( n ); n.finalizer := fin;  Heaps.AddFinalizer( obj, n );
+	END RegisterFinalizer;
+
+
+	PROCEDURE FinalizeActiveObj( obj: ANY );
+	VAR p: Process;
+	BEGIN
+		Unix.MtxLock( processList );
+			p := root;
+			WHILE (p # NIL) & (p.obj # obj) DO p := p.nextProcess  END;
+		Unix.MtxUnlock( processList );
+		IF (p # NIL) & (p.obj = obj) THEN
+			p.mode := Terminated;
+			Unix.ConDestroy( p.continue );  p.continue := 0;
+			FinalizeProtObject( obj );
+			p.Cancel
+		END;
+	END FinalizeActiveObj;
+
+	PROCEDURE FinalizeProtObject( obj: ANY );
+	VAR hdr: ObjectHeader; lock: LockT;
+	BEGIN
+		S.GET( S.VAL( ADDRESS, obj ) + Heaps.HeapBlockOffset, hdr );
+		IF hdr.lock # NIL THEN
+			lock := S.VAL(LockT, hdr.lock);
+			Unix.MtxDestroy( lock.mtx );  lock.mtx := 0
+		END
+	END FinalizeProtObject;
+
+
+	PROCEDURE FinalizeProcess( obj: ANY );
+	VAR p: Process;
+	BEGIN
+		p := obj(Process);
+		IF p.continue # 0 THEN
+			Unix.ConDestroy( p.continue );  p.continue := 0
+		END
+	END FinalizeProcess;
+	
+	(* Terminate calling thread. *)
+	PROCEDURE Exit;
+	VAR prev, p, me: Process;
+	BEGIN
+		me := CurrentProcess();
+		me.mode := Terminated;
+		Unix.MtxLock( processList );
+			prev := NIL;  p := root;
+			WHILE (p # NIL ) & (p # me) DO  prev := p;  p := p.nextProcess  END;
+			IF p = me THEN
+				IF prev = NIL THEN  root := p.nextProcess  ELSE  prev.nextProcess := p.nextProcess  END;
+			END;
+		Unix.MtxUnlock( processList );
+		Unix.ThrExit(0);
+	END Exit;
+
+	PROCEDURE ExitTrap*;
+	VAR p: Process;
+	BEGIN
+		p := CurrentProcess();
+		(* restart the object body if it was given the SAFE flag *)
+		IF Restart IN p.flags THEN
+			Unix.siglongjmp( ADDRESSOF( p.state0[0] ), 1 )
+		END;
+		Exit
+	END ExitTrap;
+
+
+
+
+	(*---------------------------- Timer --------------------------------*)
+
+
+	PROCEDURE Remove( t: Timer );  (* remove timer from list of active timers *)
+	VAR p, x: Timer;
+	BEGIN
+		Unix.MtxLock( timerListMutex ); 
+		t.trigger := 0;  t.handler := NIL;
+		IF timers # NIL THEN
+			IF t = timers THEN  
+				timers := t.next
+			ELSE
+				p := timers;  x := p.next;
+				WHILE (x # NIL) & (x # t)  DO  p := x;  x := p.next  END;
+				IF x = t THEN  p.next := t.next  END
+			END;
+			t.next := NIL
+		END;
+		Unix.MtxUnlock( timerListMutex )
+	END Remove;
+	
+	PROCEDURE Insert( t: Timer );
+	VAR  p, x: Timer;
+	BEGIN
+		Unix.MtxLock( timerListMutex ); 
+		p := NIL;  x := timers;
+		WHILE (x # NIL) & (x.trigger < t.trigger)  DO  p := x;  x := p.next  END;
+		t.next := x;
+		IF p = NIL THEN  timers := t  ELSE   p.next := t  END;
+		Unix.MtxUnlock( timerListMutex )
+	END Insert;
+
+	PROCEDURE SetTimeout*( t: Timer;  h: EventHandler;  ms: LONGINT );
+	BEGIN
+		ASSERT( ( t # NIL) & ( h # NIL) );
+		Remove( t );  
+		IF ms < 1 THEN ms := 1 END;
+		t.trigger := Machine.ticks + ms;  t.handler := h;
+		Insert( t );
+		timerActivity.Restart
+	END SetTimeout;
+
+	PROCEDURE SetTimeoutAt*( t: Timer;  h: EventHandler;  ms: LONGINT );
+	BEGIN
+		ASSERT( (t # NIL) & (h # NIL) );
+		Remove( t );
+		t.trigger := ms;  t.handler := h;
+		Insert( t );
+		timerActivity.Restart
+	END SetTimeoutAt;
+
+	PROCEDURE CancelTimeout*( t: Timer );
+	BEGIN
+		Remove( t )
+	END CancelTimeout;
+
+
+
+	(*--------------------  Garbage Collection  ------------------------------------*)
+
+	
+	PROCEDURE GetContext( ctxt: Unix.Ucontext );
+	VAR t: Process; bp: ADDRESS;
+	BEGIN
+		t := CurrentProcess();
+		Unix.CopyContext( ctxt.mc, t.context );
+	END GetContext;
+	
+	PROCEDURE SuspendActivities;
+	VAR t,me: Process;  res: LONGINT;
+	BEGIN
+		me := CurrentProcess();
+		t := root;
+				
+		WHILE t # NIL DO
+			IF t # me THEN  
+			(*	Trace.String( "suspend " ); Trace.Hex( t.id, 2 );  Trace.Ln;		*)
+				IF t.mode = Running THEN
+					t.contsp := 0;
+					Unix.ThrSuspend( t.threadId, TRUE );
+				ELSE
+					Unix.ThrSuspend( t.threadId, FALSE )
+				END
+			END;
+			t := t.nextProcess
+		END;
+	END SuspendActivities;
+
+	PROCEDURE ResumeActivities;
+	VAR t, me: Process;  
+	BEGIN
+		me := CurrentProcess();
+		t := root;
+		WHILE t # NIL DO
+			IF (t # me) THEN  
+			(*	Trace.String( "resume " ); Trace.Hex( t.id, 2 ); Trace.Ln;	*)
+				Unix.ThrResume( t.threadId );
+			END;
+			t := t.nextProcess
+		END;
+	END ResumeActivities;
+	
+
+	
+	(*!	GCLoop gets called as last procedure in BootConsole (main thread). 
+		The stack of the main thread is not limited by the  boot parameter 'StackSize' !!
+	*)
+	
+	PROCEDURE GCLoop*;	(* Timer and GC activity *)
+	BEGIN
+		LOOP  Unix.ThrSleep( 10 )  END;	  (* in Solaris the main thread must not terminate !! *)
+	(*	RETURN;	*)
+	END GCLoop;		
+	
+	
+	
+	PROCEDURE CurrentProcessTime*(): HUGEINT;
+	BEGIN
+		RETURN  Machine.GetTimer()
+	END CurrentProcessTime;
+	
+	PROCEDURE TimerFrequency*(): HUGEINT;
+	BEGIN
+		RETURN Machine.mhz * 1000000
+	END TimerFrequency;
+
+	
+	(*----------------------------- initialization ----------------------------------*)
+	
+	PROCEDURE StartTimerActivity;
+	BEGIN
+		timerListMutex := Unix.MtxInit(0);  timers := NIL;  
+		NEW( timerActivity );
+	END StartTimerActivity;
+
+
+	PROCEDURE GetStacksize;
+	VAR str: ARRAY  32 OF  CHAR;  i: LONGINT;
+	BEGIN
+		Machine.GetConfig( "StackSize", str );
+		IF str = "" THEN  stacksize := DefaultStacksize
+		ELSE
+			i := 0;  stacksize := Machine.StrToInt( i, str );
+			stacksize := stacksize * 1024;
+		END;
+		IF Glue.debug # {} THEN
+			Trace.String( "Stacksize of active objects = " );
+			Trace.Int( stacksize DIV 1024, 0 );  Trace.StringLn( "K"  )
+		END;
+	END GetStacksize;
+
+	
+	PROCEDURE Convert;
+	VAR p: Process;
+	BEGIN
+		(* make current thread the first active object  *)
+		NEW( p, NIL, NIL, 0, {}, 0 );
+	END Convert;
+
+	PROCEDURE Init;
+	BEGIN
+		Unix.suspendHandler := GetContext;
+		
+		createProcess := Unix.MtxInit( 0 );  processList := Unix.MtxInit( 0 );
+		startProcess := Unix.MtxInit(0);  childrunning := Unix.ConInit(0); 
+		lockMutex := Unix.MtxInit(0);
+											
+		GetStacksize;  
+		Convert;
+		NEW( clock );  StartTimerActivity;
+		
+		NEW( finalizerCaller );
+		
+		Heaps.gcStatus := GCStatusFactory()
+	END Init;
+
+
+	PROCEDURE GCStatusFactory(): Heaps.GCStatus;
+	VAR gcStatusExt : GCStatusExt;
+	BEGIN
+		ASSERT( Heaps.gcStatus = NIL );
+		NEW( gcStatusExt );
+		RETURN gcStatusExt
+	END GCStatusFactory;
+
+BEGIN
+	Init;
+END Objects.
+

BIN
source/Generic.SolarisA2.Tool


+ 70 - 0
source/SolarisELF.Mod

@@ -0,0 +1,70 @@
+MODULE SolarisELF;
+
+IMPORT Files, Commands, Streams, Strings;
+
+CONST 
+	HeaderPart = "A2Loader.elf";
+	CorePart = "Solaris32G.core";
+	Offset = 10*1024;
+
+	
+	PROCEDURE NewFile( CONST name: ARRAY OF CHAR; log: Streams.Writer ): Files.File;
+	VAR
+		name2: ARRAY 128 OF CHAR;  res: LONGINT;
+	BEGIN
+		IF Files.Old( name ) # NIL THEN
+			COPY( name, name2);  Strings.Append( name2, ".Bak" );
+			Files.Rename( name, name2, res );
+			log.String( "Backup created in " ); log.String( name2 );  log.Ln
+		END;
+		RETURN Files.New( name )
+	END NewFile;
+	
+	PROCEDURE Build*( cc: Commands.Context );
+	VAR in1, in2, fout: Files.File;  r: Files.Reader; w: Files.Writer;
+		outname: ARRAY 64 OF CHAR;
+		size, i: SIZE; c: CHAR;
+	BEGIN
+		in1 := Files.Old( HeaderPart );
+		IF in1 = NIL THEN
+			cc.error.String( HeaderPart );  cc.error.String( " not found" ); cc.error.Ln;
+			cc.error.Update;
+			RETURN
+		END;
+		in2 := Files.Old( CorePart );
+		IF in2 = NIL THEN
+			cc.error.String( CorePart );  cc.error.String( " not found" ); cc.error.Ln;
+			cc.error.Update;
+			RETURN
+		END;
+		
+		IF cc.arg.GetString( outname ) THEN
+			size := in1.Length();  Files.OpenReader( r, in1, 0 );
+			fout := NewFile( outname, cc.out );  Files.OpenWriter( w, fout, 0 );
+			FOR i := 1 TO size DO
+				r.Char( c ); w.Char( c )
+			END;
+			
+			FOR i := 1 TO Offset - size DO  w.Char( '=' )  END;
+			
+			size := in2.Length();  Files.OpenReader( r, in2, 0 );
+			FOR i := 1 TO size DO
+				r.Char( c ); w.Char( c )
+			END;
+			
+			w.Update;  Files.Register( fout );
+			
+			cc.out.String( outname );  cc.out.String( " created" ); cc.out.Ln;
+		ELSE
+			cc.error.String( "fileneme missing" );  cc.error.Ln
+		END;
+		cc.error.Update;
+		cc.out.Update
+	END Build;
+
+END SolarisELF.
+
+   SystemTools.Free  SolarisELF ~
+   
+   SolarisELF.Build  Solaris32G.elf ~
+