123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- (*
- # $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.
- #**********************************************************************
- *)
- unit nwpre;
- 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 : pchar;
- loadDirectoryPath : pchar;
- 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 char; // 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 : pchar;
- loadDirectoryPath : pchar;
- 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.
|