nwpre now initializes bss, use linker generated symbol to get address of .text (for lineinfo)

git-svn-id: trunk@17269 -
This commit is contained in:
armin 2011-04-07 19:39:51 +00:00
parent 672d76e636
commit 03ca42d6e2
3 changed files with 87 additions and 90 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;