fpc/rtl/palmos/si_prc.pp

124 lines
2.9 KiB
ObjectPascal

{
This file is part of the Free Pascal run time library.
Copyright (c) 2017 by the Free Pascal development team
System Entry point for PalmOS, Pascal only programs
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{$SMARTLINK OFF}
unit si_prc;
interface
implementation
{$i palmos.inc}
var
appInfo: SysAppInfoPtr; public name '__appInfo';
StkLen: LongInt; external name '__stklen';
sysinit_jmpbuf: jmp_buf;
ExitCode: LongInt;
var
{ this is declared by the PalmOS linker script }
data_start: pbyte; external name 'data_start';
procedure PascalMain; external name 'PASCALMAIN';
procedure FPCRelocateData; forward;
{ this function must be the first in this unit which contains code }
function _FPC_proc_start: longint; cdecl; public name '_start';
var
locAppInfo: SysAppInfoPtr;
prevGlobals: Pointer;
globalsPtr: Pointer;
begin
_FPC_proc_start:=0;
if SysAppStartup(locAppInfo, prevGlobals, globalsPtr) <> 0 then
begin
SndPlaySystemSound(sndError);
exit(-1);
end;
if (locAppInfo^.launchFlags and sysAppLaunchFlagNewGlobals) > 0 then
FPCRelocateData;
{ we don't support anything but normal startup now }
{ FIXME: figure it out how various startup commands can }
{ coexist with the normal system unit infrastructure (KB) }
if locAppInfo^.cmd = sysAppLaunchCmdNormalLaunch then
begin
if setjmp(sysinit_jmpbuf) = 0 then
begin
appInfo:=locAppInfo;
PascalMain;
end;
_FPC_proc_start:=ExitCode;
end;
SysAppExit(locAppInfo, prevGlobals, globalsPtr);
end;
procedure _FPC_proc_halt(_ExitCode: longint); cdecl; public name '_haltproc';
begin
ExitCode:=_ExitCode;
longjmp(sysinit_jmpbuf,1);
end;
{ data segment relocation magic, ported to Pascal from prc-tools C version }
type
PReloc = ^TReloc;
TReloc = record
case boolean of
true: ( next: smallint; addend: word );
false: ( value: dword );
end;
procedure RelocateChain(offset: smallint; base: pointer);
var
data_res: pbyte;
site: PReloc;
begin
data_res:=@data_start;
while offset >= 0 do
begin
site:=PReloc(data_res + offset);
offset:=site^.next;
site^.next:=0;
site^.value:=site^.value + PtrUInt(base);
end;
end;
procedure FPCRelocateData;
var
relocH: MemHandle;
chain: psmallint;
const
rloc_id = $726c6f63; // 'rloc'
begin
relocH:=DmGet1Resource(rloc_id, 0);
if relocH <> nil then
begin
chain:=MemHandleLock(relocH);
RelocateChain(chain^, @data_start);
Inc(chain);
RelocateChain(chain^, @_FPC_proc_start);
Inc(chain);
MemHandleUnlock(relocH);
DmReleaseResource(relocH);
end;
end;
end.