Ver código fonte

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 8 anos atrás
pai
commit
ab70c9437a

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

@@ -6,9 +6,10 @@ MODULE Glue;
 IMPORT SYSTEM, Trace;
 IMPORT SYSTEM, Trace;
 
 
 CONST 
 CONST 
-	base* = 08050000H;
+(*	base* = 08050000H;		for true elf core *)
+	base* = 08070000H;	(*  used by A2Loader,  see 'A2Loader.elf  -h' *)
 	debug* = {};
 	debug* = {};
-	NL = 0AXl
+	NL = 0AX;
 VAR
 VAR
 	last-: RECORD END; (* empty variable linked to end of kernel *)
 	last-: RECORD END; (* empty variable linked to end of kernel *)
 	
 	
@@ -29,6 +30,10 @@ VAR
 	argv-: ADDRESS;
 	argv-: ADDRESS;
 	environ-: ADDRESS;
 	environ-: ADDRESS;
 
 
+
+(*? the relocation of "dlsym/dlopen" doesn't work	*)
+(*==================
+	
 	PROCEDURE {INITIAL, NOPAF} EntryPoint;
 	PROCEDURE {INITIAL, NOPAF} EntryPoint;
 	CODE
 	CODE
 		; ELF header
 		; ELF header
@@ -49,6 +54,16 @@ VAR
 
 
 	elfheadersize:
 	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
 		; program header
 		DD 1
 		DD 1
 		DD 0
 		DD 0
@@ -59,16 +74,6 @@ VAR
 		DD 07
 		DD 07
 		DD 1000H; alignment
 		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
 		; dynamic header
 		DD 02H
 		DD 02H
 		DD dynamicsection 
 		DD dynamicsection 
@@ -79,39 +84,58 @@ VAR
 		DD 06H
 		DD 06H
 		DD 04H
 		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:		
 	dynamicsection_end:		
 		
 		
-	dlsymrelocation:
+	relocationtable:
 		DD @dlsym
 		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
 		DD 0H
-	dlsymrelocation_end:
+	relocationtable_end:
 
 
 	stringtable:
 	stringtable:
 		DB 0H ; sentinel
 		DB 0H ; sentinel
-
-	libname:
-		DB 'libdl.so.1', 0
-		
+	libdl:
+		DB '/lib/libdl.so.1', 0
+	libc:
+		DB '/lib/libc.so.1', 0
 	dlsymname:
 	dlsymname:
 		DB 'dlsym', 0
 		DB 'dlsym', 0
-		
+	dlopenname:
+		DB 'dlopen', 0
 	stringtable_end:
 	stringtable_end:
 		
 		
 		ALIGN 4
 		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
 		DD	0
 		DD	0
 		DD	0
@@ -119,13 +143,21 @@ VAR
 		DB	0
 		DB	0
 		DW 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:
 	interpretername:
 		DB '/lib/ld.so.1', 0
 		DB '/lib/ld.so.1', 0
@@ -134,9 +166,23 @@ VAR
 		ALIGN 4
 		ALIGN 4
 
 
 	entry:
 	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 );
  	PROCEDURE Char ( c: CHAR );
 	VAR r: LONGINT;
 	VAR r: LONGINT;
@@ -144,7 +190,6 @@ VAR
 		r := write( 1, ADDRESSOF( c ), 1 );
 		r := write( 1, ADDRESSOF( c ), 1 );
 	END Char;
 	END Char;
 
 
- 
  	PROCEDURE Dlsym*( handle: ADDRESS; CONST name: ARRAY OF CHAR; adr: ADDRESS );
  	PROCEDURE Dlsym*( handle: ADDRESS; CONST name: ARRAY OF CHAR; adr: ADDRESS );
 	VAR val: ADDRESS;
 	VAR val: ADDRESS;
 	BEGIN
 	BEGIN
@@ -155,6 +200,7 @@ VAR
 	
 	
 	PROCEDURE Init;
 	PROCEDURE Init;
 	VAR i: LONGINT;
 	VAR i: LONGINT;
+		libdl: ADDRESS;
 	BEGIN
 	BEGIN
 		baseAdr := ADDRESSOF( EntryPoint );
 		baseAdr := ADDRESSOF( EntryPoint );
 		endAdr := ADDRESSOF( last );
 		endAdr := ADDRESSOF( last );
@@ -164,17 +210,18 @@ VAR
 		
 		
 		stackBottom := ADDRESSOF( i ) + 2*SIZEOF( ADDRESS );
 		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, "write", ADDRESSOF ( write ) );
 		Dlsym( libc, "exit", ADDRESSOF ( exit ) );
 		Dlsym( libc, "exit", ADDRESSOF ( exit ) );
 	END Init;
 	END Init;
 	
 	
 	PROCEDURE {INITIAL, NOPAF} Init0;
 	PROCEDURE {INITIAL, NOPAF} Init0;
 	BEGIN
 	BEGIN
-		(*initial stack layout:
+	(*? same layout in Solaris ?? *)
+	(*	(*initial stack layout:
 			argc at esp
 			argc at esp
 			argv at esp+4
 			argv at esp+4
 			0 at esp+4+argc*4
 			0 at esp+4+argc*4
@@ -190,10 +237,8 @@ VAR
 			SHL EAX, 2
 			SHL EAX, 2
 			ADD EAX, ESP
 			ADD EAX, ESP
 			MOV environ, EAX
 			MOV environ, EAX
-		END;	
+		END;	*)
 		Init;
 		Init;
-		Char( 'A' ); Char( NL );
-		exit( 0 )
 	END Init0;
 	END Init0;
 	
 	
 	PROCEDURE Initialize*;
 	PROCEDURE Initialize*;
@@ -205,297 +250,36 @@ VAR
 END Glue.
 END Glue.
 
 
 
 
-Simple elf for Solaris:
-==============
+
+
+ Building the SolarisA2 Generic elf binary:
 
 
 Compiler.Compile -p=Linux32G
 Compiler.Compile -p=Linux32G
 		Runtime.Mod Trace.Mod 
 		Runtime.Mod Trace.Mod 
 		Generic.Solaris.I386.Glue.Mod  Generic.Solaris.I386.Unix.Mod  Generic.Unix.I386.Machine.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
 		Unix.StdIO.Mod  Generic.Unix.Traps.Mod  UTF8Strings.Mod  Files.Mod  Unix.UnixFiles.Mod
 		RelativeFileSystem.Mod  StringPool.Mod  BitSets.Mod  ObjectFile.Mod  
 		RelativeFileSystem.Mod  StringPool.Mod  BitSets.Mod  ObjectFile.Mod  
 		I386.Reals.Mod  Unix.Clock.Mod  Dates.Mod  Strings.Mod  Diagnostics.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 
 		Runtime Trace Glue 
 		Unix  Machine  Heaps Modules  Objects  Kernel  KernelLog 
 		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 
 		Files  UnixFiles  Clock  Dates  Reals  Strings  Diagnostics 
-		BitSets  StringPool  ObjectFile  GenericLinker  Reflection  GenericLoader
+		BitSets  StringPool  GenericLinker  Reflection  GenericLoader
 		BootConsole
 		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
 CONST
-	Version* = "SolarisG32";
+	Version* = "Solaris";
 
 
 	libcname* = "libc.so.1";
 	libcname* = "libc.so.1";
 	libmname* = "libm.so.1";
 	libmname* = "libm.so.1";
@@ -124,8 +124,6 @@ CONST
 	SIGJVM1		= 39;		(* reserved signal for Java Virtual Machine *)
 	SIGJVM1		= 39;		(* reserved signal for Java Virtual Machine *)
 	SIGJVM2		= 40;		(* reserved signal for Java Virtual Machine *)
 	SIGJVM2		= 40;		(* reserved signal for Java Virtual Machine *)
 	
 	
-	T_SIGRESUME = SIGUSR1;
-	T_SIGSUSPEND = SIGUSR2; 
 	
 	
 	SIG_BLOCK = 1;
 	SIG_BLOCK = 1;
 	SIG_UNBLOCK=2;
 	SIG_UNBLOCK=2;
@@ -397,10 +395,9 @@ TYPE
 	
 	
 VAR
 VAR
 	suspend_mutex: MutexDesc;
 	suspend_mutex: MutexDesc;
+	handler_done: BOOLEAN;
 	mainthread: Thread_t;
 	mainthread: Thread_t;
-	suspend_done: LONGINT;
-	resume_done: LONGINT;
-	sasuspend, saresume: Sigaction;
+	sasuspend: Sigaction;
 	
 	
 	argc-: LONGINT;  argv-: ADDRESS;  environ: ADDRESS;
 	argc-: LONGINT;  argv-: ADDRESS;  environ: ADDRESS;
 	
 	
@@ -430,11 +427,11 @@ VAR
 	pthread_cond_wait		: PROCEDURE {C} ( cond: ADDRESS; mutex: ADDRESS ): WORD;
 	pthread_cond_wait		: PROCEDURE {C} ( cond: ADDRESS; mutex: ADDRESS ): WORD;
 	pthread_cond_signal		: PROCEDURE {C} ( cond: 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_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_self		: PROCEDURE {C} ( ): Thread_t;
 	
 	
 	pthread_attr_init: PROCEDURE {C} ( attr: ADDRESS );
 	pthread_attr_init: PROCEDURE {C} ( attr: ADDRESS );
@@ -442,14 +439,16 @@ VAR
 	pthread_attr_setdetachstate: PROCEDURE {C} ( attr: ADDRESS; set: WORD );
 	pthread_attr_setdetachstate: PROCEDURE {C} ( attr: ADDRESS; set: WORD );
 	pthread_attr_setstacksize: PROCEDURE {C} ( attr: ADDRESS; stackSize: SIZE );
 	pthread_attr_setstacksize: PROCEDURE {C} ( attr: ADDRESS; stackSize: SIZE );
 	
 	
-
-
 	sched_get_priority_max		: PROCEDURE {C} ( policy: LONGINT ): LONGINT;
 	sched_get_priority_max		: PROCEDURE {C} ( policy: LONGINT ): LONGINT;
 	sched_get_priority_min		: 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_setschedparam		: PROCEDURE {C} ( thread: Thread_t; policy: LONGINT; param: ADDRESS ): WORD;
 	pthread_getschedparam		: 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_setcancelstate		: PROCEDURE {C} ( state: LONGINT; oldstate: ADDRESS ): LONGINT;
 	pthread_setcanceltype		: PROCEDURE {C} ( type: LONGINT; oldtype: 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;
 	sigaction			: PROCEDURE {C} ( signum: LONGINT; CONST act, oldact: ADDRESS ): LONGINT;
 	sigemptyset		: PROCEDURE {C} ( set: ADDRESS );
 	sigemptyset		: PROCEDURE {C} ( set: ADDRESS );
 	sigfillset			: PROCEDURE {C} ( set: ADDRESS ): LONGINT;
 	sigfillset			: PROCEDURE {C} ( set: ADDRESS ): LONGINT;
@@ -548,7 +547,7 @@ VAR
 		cont.mc.r_sp := sp;	
 		cont.mc.r_sp := sp;	
 	END ModifyContext;
 	END ModifyContext;
 	
 	
-	PROCEDURE CopyContext*(CONST from: McontextDesc; VAR to: McontextDesc);
+	PROCEDURE CopyContext*( CONST from: McontextDesc; VAR to: McontextDesc );
 	BEGIN
 	BEGIN
 		S.MOVE( ADDRESSOF( from ), ADDRESSOF( to ), SIZEOF( McontextDesc ) );
 		S.MOVE( ADDRESSOF( from ), ADDRESSOF( to ), SIZEOF( McontextDesc ) );
 	END CopyContext;
 	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
 	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
 		ELSE
-			TRACE( sig, scp, ucp )
+			Trace.String( "Unix.SigHandler: sig = " ); Trace.Int( sig, 0 ); Trace.Ln;  exit( -1 );
 		END;
 		END;
 	END SigHandler;
 	END SigHandler;
 	
 	
@@ -614,6 +622,8 @@ VAR
 		FOR i := 1 TO 15 DO
 		FOR i := 1 TO 15 DO
 			IF i # 9 THEN InstallHandler( i ) END;
 			IF i # 9 THEN InstallHandler( i ) END;
 		END;
 		END;
+		InstallHandler( SIGUSR1 );
+		InstallHandler( SIGUSR2 );
 	END InitSignalHandler;
 	END InitSignalHandler;
 	
 	
 	(*-------------------------------------------------------------------------------------------------------------*)
 	(*-------------------------------------------------------------------------------------------------------------*)
@@ -627,66 +637,38 @@ VAR
 		mainthread := pthread_self();
 		mainthread := pthread_self();
 		high := sched_get_priority_max( SCHED_OTHER );
 		high := sched_get_priority_max( SCHED_OTHER );
 		low := sched_get_priority_min( 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;
 	END ThrInitialize;
 	
 	
-	
-	PROCEDURE {C} resume_handler( sig: LONGINT );
-	BEGIN
-	END resume_handler;
 
 
+	
 	PROCEDURE ThrResume*( thr: Thread_t );
 	PROCEDURE ThrResume*( thr: Thread_t );
-	VAR n, r: LONGINT; 
+	VAR r: LONGINT;
 	BEGIN
 	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;
 	VAR r: LONGINT;
 	BEGIN
 	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;
 	PROCEDURE SetSigaltstack;
@@ -722,7 +704,8 @@ VAR
 		sigdelset( ADDRESSOF( new ), SIGBUS );
 		sigdelset( ADDRESSOF( new ), SIGBUS );
 		sigdelset( ADDRESSOF( new ), SIGSEGV );
 		sigdelset( ADDRESSOF( new ), SIGSEGV );
 		sigdelset( ADDRESSOF( new ), SIGTERM );
 		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_sigmask( SIG_SETMASK, ADDRESSOF( new ), ADDRESSOF( old ) );
 		r := pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NIL );
 		r := pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NIL );
 		r := pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NIL );
 		r := pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NIL );
@@ -796,11 +779,11 @@ VAR
 		param: Sched_param;
 		param: Sched_param;
 		policy, r: LONGINT;
 		policy, r: LONGINT;
 	BEGIN
 	BEGIN
-		r := pthread_getschedparam( thr, ADDRESSOF( policy ), ADDRESSOF( param ) );
+	(*	r := pthread_getschedparam( thr, ADDRESSOF( policy ), ADDRESSOF( param ) );
 		param.sched_priority := prio;
 		param.sched_priority := prio;
 		IF pthread_setschedparam( thr, SCHED_OTHER, ADDRESSOF( param ) ) # 0 THEN
 		IF pthread_setschedparam( thr, SCHED_OTHER, ADDRESSOF( param ) ) # 0 THEN
 			Perror( "pthread_setschedparam" );
 			Perror( "pthread_setschedparam" );
-		END
+		END	*)
 	END ThrSetPriority;
 	END ThrSetPriority;
 
 
 	PROCEDURE ThrGetPriority*( thr: Thread_t ):LONGINT;
 	PROCEDURE ThrGetPriority*( thr: Thread_t ):LONGINT;
@@ -887,7 +870,6 @@ VAR
 	PROCEDURE {C} X11ErrorHandler( d: ADDRESS; err: ADDRESS ): WORD;
 	PROCEDURE {C} X11ErrorHandler( d: ADDRESS; err: ADDRESS ): WORD;
 	VAR res: LONGINT;
 	VAR res: LONGINT;
 	BEGIN
 	BEGIN
-		TRACE( d, err );
 		IF oberonXErrorHandler # NIL THEN 
 		IF oberonXErrorHandler # NIL THEN 
 			res := oberonXErrorHandler( d, err );
 			res := oberonXErrorHandler( d, err );
 		END;
 		END;
@@ -897,7 +879,6 @@ VAR
 	PROCEDURE {C} X11IOErrorHandler( d: ADDRESS ): WORD;
 	PROCEDURE {C} X11IOErrorHandler( d: ADDRESS ): WORD;
 	VAR res: LONGINT;
 	VAR res: LONGINT;
 	BEGIN
 	BEGIN
-		TRACE( d );
 		IF oberonXIOErrorHandler # NIL THEN
 		IF oberonXIOErrorHandler # NIL THEN
 			res := oberonXIOErrorHandler( d );
 			res := oberonXIOErrorHandler( d );
 		END;
 		END;
@@ -925,7 +906,6 @@ VAR
 		IF val = 0 THEN
 		IF val = 0 THEN
 			Trace.String( "Unix.Dlsym:  entry '" );  Trace.String( sym );  Trace.String( "' not found" );
 			Trace.String( "Unix.Dlsym:  entry '" );  Trace.String( sym );  Trace.String( "' not found" );
 			Trace.Ln;
 			Trace.Ln;
-			exit( 0 )
 		END
 		END
 	END Dlsym;
 	END Dlsym;
 
 
@@ -1051,6 +1031,9 @@ VAR
 		Dlsym( libp, "pthread_attr_setstacksize", ADDRESSOF( pthread_attr_setstacksize ) );
 		Dlsym( libp, "pthread_attr_setstacksize", ADDRESSOF( pthread_attr_setstacksize ) );
 		Dlsym( libp, "pthread_self", ADDRESSOF( pthread_self ) );
 		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_spawnp",	ADDRESSOF( posix_spawnp ) );
 		Dlsym( libc, "posix_spawn",	ADDRESSOF( posix_spawn ) );
 		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 ~
+