fpc/rtl/netware/nwpre.pp
2023-07-27 19:04:03 +02:00

195 lines
6.3 KiB
ObjectPascal

(*
# $Id: nwpre.as,v 1.3 2003/03/25 18:17:54 armin Exp $
# This file is part of the Free Pascal run time library.
# Copyright (c) 1999-2011 by the Free Pascal development team
# Copyright (c) 2002-2011 Armin Diehl
#
# This is the (nwpre-like) startup code for netware (clib)
#
# 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.
#
#**********************************************************************
# This version initializes BSS
#
# Imported functions will not be known by the linker because only the
# generated object file will be included into the link process. The
# ppu will not be read. Therefore the file nwpre.imp containing the
# names of all imported functions needs to be created. This file
# will be used by the internal linker to import the needed functions.
#**********************************************************************
*)
{$IFNDEF FPC_DOTTEDUNITS}
unit nwpre;
{$ENDIF FPC_DOTTEDUNITS}
interface
implementation
procedure _SetupArgV_411 (startProc:pointer); cdecl; external 'clib' name '_SetupArgV_411';
procedure _nlm_main; external name '_nlm_main';
procedure FPC_NW_CHECKFUNCTION; external name 'FPC_NW_CHECKFUNCTION';
function _StartNLM (NLMHandle : longint;
initErrorScreenID : longint;
cmdLineP : PAnsiChar;
loadDirectoryPath : PAnsiChar;
uninitializedDataLength : longint;
NLMFileHandle : longint;
readRoutineP : pointer;
customDataOffset : longint;
customDataSize : longint;
NLMInformation : pointer;
userStartFunc : pointer) : longint; cdecl; external '!clib' name '_StartNLM';
function _TerminateNLM (NLMInformation : pointer;
threadID, status : longint) : longint; cdecl; external '!clib' name '_TerminateNLM';
procedure _Stop; cdecl; forward;
// This is the main program (not loader) Entry-Point that will be called by netware
// it sets up the argc and argv and calls _nlm_main (in system.pp)
procedure _pasStart; assembler; export; [alias:'_pasStart_'];
asm
pushl $_nlm_main
call _SetupArgV_411
addl $4,%esp
ret
// this is a hack to avoid that FPC_NW_CHECKFUNCTION will be
// eleminated by the linker (with smartlinking)
// TODO: change the internal linker to allow check and stop
call FPC_NW_CHECKFUNCTION
call _Stop
end;
// structure needed by clib
type kNLMInfoT =
packed record
Signature : array [0..3] of AnsiChar; // LONG 'NLMI'
Flavor : longint; // TRADINIONAL_FLAVOR = 0
Version : longint; // TRADINIONAL_VERSION = 0, LIBERTY_VERSION = 1
LongDoubleSize : longint; // gcc nwpre defines 12, watcom 8
wchar_tSize : longint;
end;
var
_kNLMInfo:kNLMInfoT = (Signature:'NLMI';Flavor:0;Version:1;LongDoubleSize:8;wChar_tSize:2);
// symbol is generated by the internal linker, when using ld in the future again,
// the link script for ld needs to be modified to include this symbol
bss : ptruint; external name '__bss_start__';
// fillchar
// netware kernel function
procedure CSetB(value:byte; var addr; count:longint); cdecl; external '!' name 'CSetB';
// this will be called by the loader, we pass the address of _pasStart_ and
// _kNLMInfo (needed by clib) and clib will call _pasStart within a newly
// created thread
function _Prelude (NLMHandle : longint;
initErrorScreenID : longint;
cmdLineP : PAnsiChar;
loadDirectoryPath : PAnsiChar;
uninitializedDataLength : longint;
NLMFileHandle : longint;
readRoutineP : pointer;
customDataOffset : longint;
customDataSize : longint) : longint; cdecl; export; [alias:'_Prelude'];
begin
// initialize BSS
CSetB(0,bss,uninitializedDataLength);
// let clib setup a thread and call pasStart in this new thread
_Prelude := _StartNLM (NLMHandle,
initErrorScreenID,
cmdLineP,
loadDirectoryPath,
uninitializedDataLength,
NLMFileHandle,
readRoutineP,
customDataOffset,
customDataSize,
@_kNLMInfo,
@_pasStart);
end;
(*
procedure _Prelude; assembler; export; [alias:'_Prelude'];
asm
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %esi
pushl %ebx
movl 0x14(%ebp),%edi
movl 0x18(%ebp),%esi
movl %esi, __uninitializedDataSize
movl 0x1c(%ebp),%ebx
movl 0x20(%ebp),%ecx
movl 0x28(%ebp),%eax
pushl $_pasStart
pushl $_kNLMInfo
pushl %eax
movl 0x24(%ebp),%edx // 1b7f6
pushl %edx
pushl %ecx
pushl %ebx
pushl %esi // uninitialized data size
pushl %edi
movl 0x10(%ebp),%edx
pushl %edx
movl 0xc(%ebp),%edx
pushl %edx
movl 0x8(%ebp),%edx
pushl %edx
call _StartNLM
test %eax,%eax
jne .Lx1
xorl %eax,%eax // dont know why this is needed ?
.Lx1:
lea 0xfffffff4(%ebp),%esp
popl %ebx
popl %esi
popl %edi
movl %ebp,%esp
popl %ebp
ret
end;
*)
//# the global stop-function
// fpc will generate an (unneeded) stack frame here, gcc does not
(*
procedure _Stop; cdecl; export; [alias:'_Stop'];
begin
_TerminateNLM (@_kNLMInfo,0,5);
end;
*)
procedure _Stop; cdecl; assembler; [alias:'_Stop'];
asm
pushl $0x5
pushl $0x0
movl _kNLMInfo,%edx
pushl %edx
call _TerminateNLM
addl $0x0c,%esp
ret
end;
end.