mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-06 17:47:50 +02:00
444 lines
11 KiB
ObjectPascal
444 lines
11 KiB
ObjectPascal
Unit System;
|
|
|
|
interface
|
|
|
|
// Was needed to bootstrap with our old 2.1 fpc for BeOS
|
|
// to define real
|
|
{ $define VER2_0}
|
|
|
|
{$define FPC_IS_SYSTEM}
|
|
|
|
{$I sysunixh.inc}
|
|
|
|
|
|
type
|
|
THeapPointer = ^pointer;
|
|
var
|
|
heapstartpointer : THeapPointer;
|
|
heapstart : pointer;//external;//external name 'HEAP';
|
|
myheapsize : longint; //external;//external name 'HEAPSIZE';
|
|
myheaprealsize : longint;
|
|
heap_handle : longint;
|
|
implementation
|
|
|
|
procedure debugger(s : PAnsiChar); cdecl; external 'root' name 'debugger';
|
|
|
|
function disable_debugger(state : integer): integer; external 'root' name 'disable_debugger';
|
|
//begin
|
|
//end;
|
|
|
|
{ OS independant parts}
|
|
|
|
{$I system.inc}
|
|
|
|
{*****************************************************************************
|
|
System Dependent Exit code
|
|
*****************************************************************************}
|
|
procedure prthaltproc;external name '_haltproc';
|
|
|
|
procedure system_exit;
|
|
begin
|
|
asm
|
|
jmp prthaltproc
|
|
end;
|
|
End;
|
|
|
|
|
|
{ OS dependant parts }
|
|
|
|
{*****************************************************************************
|
|
Heap Management
|
|
*****************************************************************************}
|
|
|
|
(*var myheapstart:pointer;
|
|
myheapsize:longint;
|
|
myheaprealsize:longint;
|
|
heap_handle:longint;
|
|
zero:longint;
|
|
|
|
|
|
{ first address of heap }
|
|
function getheapstart:pointer;
|
|
begin
|
|
getheapstart:=myheapstart;
|
|
end;
|
|
|
|
{ current length of heap }
|
|
function getheapsize:longint;
|
|
begin
|
|
getheapsize:=myheapsize;
|
|
end;
|
|
*)
|
|
|
|
|
|
(*function getheapstart:pointer;
|
|
assembler;
|
|
asm
|
|
leal HEAP,%eax
|
|
end ['EAX'];
|
|
|
|
|
|
function getheapsize:longint;
|
|
assembler;
|
|
asm
|
|
movl intern_HEAPSIZE,%eax
|
|
end ['EAX'];*)
|
|
|
|
{ function to allocate size bytes more for the program }
|
|
{ must return the first address of new data space or nil if fail }
|
|
(*function Sbrk(size : longint):pointer;
|
|
var newsize,newrealsize:longint;
|
|
s : shortstring;
|
|
begin
|
|
WriteLn('SBRK');
|
|
Str(size, s);
|
|
WriteLn('size : ' + s);
|
|
if (myheapsize+size)<=myheaprealsize then
|
|
begin
|
|
Sbrk:=pointer(heapstart+myheapsize);
|
|
myheapsize:=myheapsize+size;
|
|
exit;
|
|
end;
|
|
newsize:=myheapsize+size;
|
|
newrealsize:=(newsize and $FFFFF000)+$1000;
|
|
case resize_area(heap_handle,newrealsize) of
|
|
B_OK :
|
|
begin
|
|
WriteLn('B_OK');
|
|
Sbrk:=pointer(heapstart+myheapsize);
|
|
myheapsize:=newsize;
|
|
myheaprealsize:=newrealsize;
|
|
exit;
|
|
end;
|
|
B_BAD_VALUE : WriteLn('B_BAD_VALUE');
|
|
B_NO_MEMORY : WriteLn('B_NO_MEMORY');
|
|
B_ERROR : WriteLn('B_ERROR');
|
|
else
|
|
begin
|
|
Sbrk:=pointer(heapstart+myheapsize);
|
|
myheapsize:=newsize;
|
|
myheaprealsize:=newrealsize;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
// Sbrk:=nil;
|
|
end;*)
|
|
|
|
function sys_resize_area (handle:cardinal; size:longint):longint; cdecl; external name 'sys_resize_area';
|
|
|
|
//function sbrk2 (size : longint):pointer; cdecl; external name 'sbrk';
|
|
|
|
{ function to allocate size bytes more for the program }
|
|
{ must return the first address of new data space or nil if fail }
|
|
//function Sbrk(size : longint):pointer;
|
|
//var newsize,newrealsize:longint;
|
|
// s : shortstring;
|
|
//begin
|
|
// sbrk := sbrk2(size);
|
|
(* sbrk := nil;
|
|
WriteLn('sbrk');
|
|
Str(size, s);
|
|
WriteLn('size : ' + s);
|
|
if (myheapsize+size)<=myheaprealsize then
|
|
begin
|
|
Sbrk:=heapstart+myheapsize;
|
|
myheapsize:=myheapsize+size;
|
|
exit;
|
|
end;
|
|
newsize:=myheapsize+size;
|
|
newrealsize:=(newsize and $FFFFF000)+$1000;
|
|
if sys_resize_area(heap_handle,newrealsize+$1000)=0 then
|
|
begin
|
|
WriteLn('sys_resize_area OK');
|
|
Str(longint(newrealsize), s);
|
|
WriteLn('newrealsize : $' + Hexstr(longint(newrealsize), 8));
|
|
Str(longint(heapstartpointer), s);
|
|
WriteLn('heapstart : $' + Hexstr(longint(heapstart), 8));
|
|
Str(myheapsize, s);
|
|
WriteLn('myheapsize : ' + s);
|
|
Str(myheapsize, s);
|
|
WriteLn('Total : ' + s);
|
|
WriteLn('Before fillchar');
|
|
WriteLn('sbrk : $' + Hexstr(longint(heapstart+myheapsize), 8));
|
|
Sbrk:=heapstart+myheapsize;
|
|
FillChar(sbrk^, size, #0);
|
|
WriteLn('EndFillChar');
|
|
WriteLn('sbrk : $' + Hexstr(longint(sbrk), 8));
|
|
// ReadLn(s);
|
|
myheapsize:=newsize;
|
|
Str({longint(heapstartpointer) +} myheapsize, s);
|
|
WriteLn('Total : ' + s);
|
|
myheaprealsize:=newrealsize;
|
|
exit;
|
|
end
|
|
else
|
|
begin
|
|
debugger('Bad resize_area');
|
|
WriteLn('Bad resize_area');
|
|
end;
|
|
Sbrk:=nil;
|
|
*)
|
|
//end;
|
|
|
|
{ $I text.inc}
|
|
|
|
{*****************************************************************************
|
|
UnTyped File Handling
|
|
*****************************************************************************}
|
|
|
|
|
|
{ $i file.inc}
|
|
|
|
{*****************************************************************************
|
|
Typed File Handling
|
|
*****************************************************************************}
|
|
|
|
{ $i typefile.inc}
|
|
|
|
{*****************************************************************************
|
|
Misc. System Dependent Functions
|
|
*****************************************************************************}
|
|
|
|
Function ParamCount: Longint;
|
|
var
|
|
s : shortstring;
|
|
Begin
|
|
ParamCount := 0;
|
|
Paramcount:=argc - 1;
|
|
End;
|
|
|
|
{ variable where full path and filename and executable is stored }
|
|
{ is setup by the startup of the system unit. }
|
|
var
|
|
execpathstr : shortstring;
|
|
|
|
{$ifdef FPC_USE_LIBC}
|
|
|
|
// private; use the macros, below
|
|
function _get_image_info(image : image_id; var info : image_info; size : size_t)
|
|
: status_t; cdecl; external 'root' name '_get_image_info';
|
|
|
|
function _get_next_image_info(team : team_id; var cookie : Longint; var info : image_info; size : size_t)
|
|
: status_t; cdecl; external 'root' name '_get_next_image_info';
|
|
|
|
function get_image_info(image : image_id; var info : image_info) : status_t;
|
|
begin
|
|
Result := _get_image_info(image, info, SizeOf(info));
|
|
end;
|
|
|
|
function get_next_image_info(team : team_id; var cookie : Longint; var info : image_info) : status_t;
|
|
begin
|
|
Result := _get_next_image_info(team, cookie, info, SizeOf(info));
|
|
end;
|
|
|
|
{$endif}
|
|
|
|
{ this routine sets up the paramstr(0) string at startup }
|
|
procedure setupexecname;
|
|
var
|
|
cookie: longint;
|
|
image : image_info;
|
|
index : byte;
|
|
s : shortstring;
|
|
begin
|
|
cookie:=0;
|
|
fillchar(image, sizeof(image_info), 0);
|
|
if get_next_image_info(0, cookie, image) = B_OK then
|
|
begin
|
|
execpathstr := strpas(@image.name);
|
|
end
|
|
else
|
|
execpathstr := '';
|
|
{ problem with Be 4.5 noted... path contains . character }
|
|
{ if file is directly executed in CWD }
|
|
index:=pos('/./',execpathstr);
|
|
if index <> 0 then
|
|
begin
|
|
{ remove the /. characters }
|
|
Delete(execpathstr,index, 2);
|
|
end;
|
|
end;
|
|
|
|
function paramstr(l: longint) : shortstring;
|
|
var
|
|
s: shortstring;
|
|
s1: shortstring;
|
|
begin
|
|
|
|
{ stricly conforming POSIX applications }
|
|
{ have the executing filename as argv[0] }
|
|
if l = 0 then
|
|
begin
|
|
paramstr := execpathstr;
|
|
end
|
|
else if (l > 0) and (l < argc) then
|
|
begin
|
|
paramstr:=strpas(argv[l]);
|
|
end
|
|
else
|
|
paramstr := '';
|
|
end;
|
|
|
|
Procedure Randomize;
|
|
Begin
|
|
randseed:=longint(Fptime(nil));
|
|
End;
|
|
|
|
function GetProcessID: SizeUInt;
|
|
begin
|
|
GetProcessID := SizeUInt (fpGetPID);
|
|
end;
|
|
|
|
{*****************************************************************************
|
|
SystemUnit Initialization
|
|
*****************************************************************************}
|
|
|
|
function reenable_signal(sig : longint) : boolean;
|
|
var
|
|
e : TSigSet;
|
|
i,j : byte;
|
|
olderrno: cint;
|
|
begin
|
|
fillchar(e,sizeof(e),#0);
|
|
{ set is 1 based PM }
|
|
dec(sig);
|
|
i:=sig mod (sizeof(cuLong) * 8);
|
|
j:=sig div (sizeof(cuLong) * 8);
|
|
e[j]:=1 shl i;
|
|
{ this routine is called from a signal handler, so must not change errno }
|
|
olderrno:=geterrno;
|
|
fpsigprocmask(SIG_UNBLOCK,@e,nil);
|
|
reenable_signal:=geterrno=0;
|
|
seterrno(olderrno);
|
|
end;
|
|
|
|
// signal handler is arch dependant due to processorexception to language
|
|
// exception translation
|
|
|
|
{$i sighnd.inc}
|
|
|
|
procedure InstallDefaultSignalHandler(signum: longint; out oldact: SigActionRec); public name '_FPC_INSTALLDEFAULTSIGHANDLER';
|
|
var
|
|
act: SigActionRec;
|
|
begin
|
|
{ Initialize the sigaction structure }
|
|
{ all flags and information set to zero }
|
|
FillChar(act, sizeof(SigActionRec),0);
|
|
{ initialize handler }
|
|
act.sa_handler := SigActionHandler(@SignalToRunError);
|
|
act.sa_flags:=SA_SIGINFO;
|
|
FpSigAction(signum,@act,@oldact);
|
|
end;
|
|
|
|
var
|
|
oldsigfpe: SigActionRec; public name '_FPC_OLDSIGFPE';
|
|
oldsigsegv: SigActionRec; public name '_FPC_OLDSIGSEGV';
|
|
oldsigbus: SigActionRec; public name '_FPC_OLDSIGBUS';
|
|
oldsigill: SigActionRec; public name '_FPC_OLDSIGILL';
|
|
|
|
Procedure InstallSignals;
|
|
begin
|
|
InstallDefaultSignalHandler(SIGFPE,oldsigfpe);
|
|
InstallDefaultSignalHandler(SIGSEGV,oldsigsegv);
|
|
InstallDefaultSignalHandler(SIGBUS,oldsigbus);
|
|
InstallDefaultSignalHandler(SIGILL,oldsigill);
|
|
end;
|
|
|
|
Procedure RestoreOldSignalHandlers;
|
|
begin
|
|
FpSigAction(SIGFPE,@oldsigfpe,nil);
|
|
FpSigAction(SIGSEGV,@oldsigsegv,nil);
|
|
FpSigAction(SIGBUS,@oldsigbus,nil);
|
|
FpSigAction(SIGILL,@oldsigill,nil);
|
|
end;
|
|
|
|
|
|
procedure SysInitStdIO;
|
|
begin
|
|
{ Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
|
|
displayed in and messagebox }
|
|
OpenStdIO(Input,fmInput,StdInputHandle);
|
|
OpenStdIO(Output,fmOutput,StdOutputHandle);
|
|
OpenStdIO(StdOut,fmOutput,StdOutputHandle);
|
|
OpenStdIO(StdErr,fmOutput,StdErrorHandle);
|
|
end;
|
|
|
|
function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
|
|
begin
|
|
result := stklen;
|
|
end;
|
|
|
|
var
|
|
s : shortstring;
|
|
begin
|
|
IsConsole := TRUE;
|
|
StackLength := CheckInitialStkLen(InitialStkLen);
|
|
StackBottom := Sptr - StackLength;
|
|
|
|
{ Set up signals handlers (may be needed by init code to test cpu features) }
|
|
InstallSignals;
|
|
|
|
{$ifdef cpui386}
|
|
fpc_cpucodeinit;
|
|
{$endif}
|
|
|
|
{ Setup heap }
|
|
myheapsize:=4096*1;// $ 20000;
|
|
myheaprealsize:=4096*1;// $ 20000;
|
|
heapstart:=nil;
|
|
heapstartpointer := nil;
|
|
heapstartpointer := Sbrk2(4096*1);
|
|
{$IFDEF FPC_USE_LIBC}
|
|
// heap_handle := create_area('fpcheap',heapstart,0,myheaprealsize,0,3);//!!
|
|
{$ELSE}
|
|
// debugger('tata'#0);
|
|
// heap_handle := create_area('fpcheap',longint(heapstartpointer),0,myheaprealsize,0,3);//!!
|
|
// case heap_handle of
|
|
// B_BAD_VALUE : WriteLn('B_BAD_VALUE');
|
|
// B_PAGE_SIZE : WriteLn('B_PAGE_SIZE');
|
|
// B_NO_MEMORY : WriteLn('B_NO_MEMORY');
|
|
// B_ERROR : WriteLn('B_ERROR');
|
|
// end;
|
|
|
|
FillChar(heapstartpointer^, myheaprealsize, #0);
|
|
// WriteLn('EndFillChar');
|
|
// WriteLn('P : $' + Hexstr(longint(heapstartpointer), 8));
|
|
// WriteLn('heapstart : $' + Hexstr(longint(heapstartpointer^), 8));
|
|
heapstart := heapstartpointer;
|
|
{$ENDIF}
|
|
// WriteLn('before InitHeap');
|
|
// case heap_handle of
|
|
// B_BAD_VALUE : WriteLn('B_BAD_VALUE');
|
|
// B_PAGE_SIZE : WriteLn('B_PAGE_SIZE');
|
|
// B_NO_MEMORY : WriteLn('B_NO_MEMORY');
|
|
// B_ERROR : WriteLn('B_ERROR');
|
|
// else
|
|
// begin
|
|
// WriteLn('ok');
|
|
// WriteLn('P : $' + Hexstr(longint(heapstartpointer), 8));
|
|
// WriteLn('heapstart : $' + Hexstr(longint(heapstartpointer^), 8));
|
|
// if heap_handle>0 then
|
|
// begin
|
|
InitHeap;
|
|
// end;
|
|
// end;
|
|
// end;
|
|
// WriteLn('after InitHeap');
|
|
// end else system_exit;
|
|
SysInitExceptions;
|
|
// WriteLn('after SysInitException');
|
|
|
|
initunicodestringmanager;
|
|
{ Setup IO }
|
|
SysInitStdIO;
|
|
{ Reset IO Error }
|
|
InOutRes:=0;
|
|
InitSystemThreads;
|
|
InitSystemDynLibs;
|
|
setupexecname;
|
|
{ restore original signal handlers in case this is a library }
|
|
if IsLibrary then
|
|
RestoreOldSignalHandlers;
|
|
end.
|