From 03ca42d6e240aedbe55eaa5abaef2e62c0b3e4b0 Mon Sep 17 00:00:00 2001 From: armin Date: Thu, 7 Apr 2011 19:39:51 +0000 Subject: [PATCH] nwpre now initializes bss, use linker generated symbol to get address of .text (for lineinfo) git-svn-id: trunk@17269 - --- rtl/netware/nwpre.imp | 3 +- rtl/netware/nwpre.pp | 159 +++++++++++++++++++++--------------------- rtl/netware/system.pp | 15 ++-- 3 files changed, 87 insertions(+), 90 deletions(-) diff --git a/rtl/netware/nwpre.imp b/rtl/netware/nwpre.imp index feac7584cc..8a3bc8b6d7 100644 --- a/rtl/netware/nwpre.imp +++ b/rtl/netware/nwpre.imp @@ -1,5 +1,6 @@ #imports needed by nwpre, will be used by the -#internal linker, ad 20 mar 2011 +#internal linker, ad 7 apr 2011 _SetupArgV_411 _TerminateNLM _StartNLM + CSetB diff --git a/rtl/netware/nwpre.pp b/rtl/netware/nwpre.pp index 3d48084c43..967f46e21c 100644 --- a/rtl/netware/nwpre.pp +++ b/rtl/netware/nwpre.pp @@ -4,8 +4,8 @@ # 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 -# +# This is the (nwpre-like) startup code for netware (clib) +# # See the file COPYING.FPC, included in this distribution, # for details about the copyright. # @@ -14,6 +14,14 @@ # 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; @@ -22,15 +30,10 @@ interface implementation -// .file "nwpre.as" -// .text - 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'; -//procedure _StartNLM; external name '_StartNLM'; - function _StartNLM (NLMHandle : longint; initErrorScreenID : longint; cmdLineP : pchar; @@ -44,13 +47,14 @@ function _StartNLM (NLMHandle : longint; userStartFunc : pointer) : longint; cdecl; external '!clib' name '_StartNLM'; -procedure _TerminateNLM; cdecl; external '!clib' name '_TerminateNLM'; +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 _Stop; forward; procedure _pasStart; assembler; export; [alias:'_pasStart_']; asm @@ -60,39 +64,67 @@ asm 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; -//.data -//# argc is defined in the novell nwpre, i assume it is not needed -//#_argc: -//# .long 0 // 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 + 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; -// .globl _kNLMInfo # will be used as data start -var _kNLMInfo:kNLMInfoT = (Signature:'NLMI';Flavor:0;Version:1;LongDoubleSize:8;wChar_tSize:2); -// .ascii "NLMI" -// .long 0,1,8,2 -// -//.data -// __uninitializedDataSize: .long -var __uninitializedDataSize:longint; +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 netware is doing the work -// -// .globl _Prelude +// _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 @@ -134,58 +166,27 @@ asm popl %ebp ret end; +*) -//# //# the global stop-function -//# -// .globl _Stop -procedure _Stop; assembler; [alias:'_Stop']; + +// 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 // TERMINATE_BY_UNLOAD=0, TERMINATE_BY_EXTERNAL_THREAD=0 + pushl $0x5 pushl $0x0 - movl _kNLMInfo,%edx - pushl %edx - call _TerminateNLM - addl $0x0c,%esp - ret + movl _kNLMInfo,%edx + pushl %edx + call _TerminateNLM + addl $0x0c,%esp + ret end; - -//.text -procedure __getTextStart; assembler; export; [alias:'__getTextStart']; -asm -//__getTextStart: -// movl $.text,%eax - movl $_pasStart,%eax // should be the start in .text, dont know how to access .text in the internal assembler - ret -end; - -procedure _DataStart; external name '.data'; - -procedure __getDataStart; assembler; export; [alias:'_getDataStart']; -asm -//__getDataStart: -// movl $.data,%eax - movl $_kNLMInfo, %eax - ret -end; - - -procedure __getBssStart; assembler; export; [alias:'__getBssStart']; -asm -//__getBssStart: -// movl $.bss,%eax - movl $__uninitializedDataSize,%eax - ret -end; - -//.text -procedure __getUninitializedDataSize; assembler; export; [alias:'__getUninitializedDataSize']; -asm -//__getUninitializedDataSize: - movl __uninitializedDataSize, %eax - ret -end; - - end. diff --git a/rtl/netware/system.pp b/rtl/netware/system.pp index bfee327418..2a45147f68 100644 --- a/rtl/netware/system.pp +++ b/rtl/netware/system.pp @@ -1,6 +1,7 @@ { This file is part of the Free Pascal run time library. Copyright (c) 1999-2000 by the Free Pascal development team. + Copyright (c) 2001-2011 by Armin Diehl. See the file COPYING.FPC, included in this distribution, for details about the copyright. @@ -69,7 +70,6 @@ VAR ArgV : ppchar; NetwareCheckFunction : TNWCheckFunction; NetwareMainThreadGroupID: longint; - NetwareCodeStartAddress : dword; NetwareUnloadProc : pointer = nil; {like exitProc but for nlm unload only} CONST @@ -116,26 +116,21 @@ procedure fpc_do_exit;external name 'FPC_DO_EXIT'; Startup *****************************************************************************} - function __GetBssStart : pointer; external name '__getBssStart'; - function __getUninitializedDataSize : longint; external name '__getUninitializedDataSize'; - //function __getDataStart : longint; external name '__getDataStart'; - function __GetTextStart : longint; external name '__getTextStart'; PROCEDURE nlm_main (_ArgC : LONGINT; _ArgV : ppchar); CDECL; [public,alias: '_nlm_main']; BEGIN - // Initialize BSS - if __getUninitializedDataSize > 0 then - fillchar (__getBssStart^,__getUninitializedDataSize,0); - NetwareCodeStartAddress := __GetTextStart; + // Initialize of BSS now done in nwpre ArgC := _ArgC; ArgV := _ArgV; fpc_threadvar_relocate_proc := nil; PASCALMAIN; END; +var dottext : ptruint; external name '__text_start__'; + function NWGetCodeStart : pointer; // needed for lineinfo begin - NWGetCodeStart := pointer(NetwareCodeStartAddress); + NWGetCodeStart := @dottext; end;