2
0

nwpre.pp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. (*
  2. # $Id: nwpre.as,v 1.3 2003/03/25 18:17:54 armin Exp $
  3. # This file is part of the Free Pascal run time library.
  4. # Copyright (c) 1999-2011 by the Free Pascal development team
  5. # Copyright (c) 2002-2011 Armin Diehl
  6. #
  7. # This is the (nwpre-like) startup code for netware (clib)
  8. #
  9. # See the file COPYING.FPC, included in this distribution,
  10. # for details about the copyright.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. #
  16. #**********************************************************************
  17. # This version initializes BSS
  18. #
  19. # Imported functions will not be known by the linker because only the
  20. # generated object file will be included into the link process. The
  21. # ppu will not be read. Therefore the file nwpre.imp containing the
  22. # names of all imported functions needs to be created. This file
  23. # will be used by the internal linker to import the needed functions.
  24. #**********************************************************************
  25. *)
  26. {$IFNDEF FPC_DOTTEDUNITS}
  27. unit nwpre;
  28. {$ENDIF FPC_DOTTEDUNITS}
  29. interface
  30. implementation
  31. procedure _SetupArgV_411 (startProc:pointer); cdecl; external 'clib' name '_SetupArgV_411';
  32. procedure _nlm_main; external name '_nlm_main';
  33. procedure FPC_NW_CHECKFUNCTION; external name 'FPC_NW_CHECKFUNCTION';
  34. function _StartNLM (NLMHandle : longint;
  35. initErrorScreenID : longint;
  36. cmdLineP : PAnsiChar;
  37. loadDirectoryPath : PAnsiChar;
  38. uninitializedDataLength : longint;
  39. NLMFileHandle : longint;
  40. readRoutineP : pointer;
  41. customDataOffset : longint;
  42. customDataSize : longint;
  43. NLMInformation : pointer;
  44. userStartFunc : pointer) : longint; cdecl; external '!clib' name '_StartNLM';
  45. function _TerminateNLM (NLMInformation : pointer;
  46. threadID, status : longint) : longint; cdecl; external '!clib' name '_TerminateNLM';
  47. procedure _Stop; cdecl; forward;
  48. // This is the main program (not loader) Entry-Point that will be called by netware
  49. // it sets up the argc and argv and calls _nlm_main (in system.pp)
  50. procedure _pasStart; assembler; export; [alias:'_pasStart_'];
  51. asm
  52. pushl $_nlm_main
  53. call _SetupArgV_411
  54. addl $4,%esp
  55. ret
  56. // this is a hack to avoid that FPC_NW_CHECKFUNCTION will be
  57. // eleminated by the linker (with smartlinking)
  58. // TODO: change the internal linker to allow check and stop
  59. call FPC_NW_CHECKFUNCTION
  60. call _Stop
  61. end;
  62. // structure needed by clib
  63. type kNLMInfoT =
  64. packed record
  65. Signature : array [0..3] of AnsiChar; // LONG 'NLMI'
  66. Flavor : longint; // TRADINIONAL_FLAVOR = 0
  67. Version : longint; // TRADINIONAL_VERSION = 0, LIBERTY_VERSION = 1
  68. LongDoubleSize : longint; // gcc nwpre defines 12, watcom 8
  69. wchar_tSize : longint;
  70. end;
  71. var
  72. _kNLMInfo:kNLMInfoT = (Signature:'NLMI';Flavor:0;Version:1;LongDoubleSize:8;wChar_tSize:2);
  73. // symbol is generated by the internal linker, when using ld in the future again,
  74. // the link script for ld needs to be modified to include this symbol
  75. bss : ptruint; external name '__bss_start__';
  76. // fillchar
  77. // netware kernel function
  78. procedure CSetB(value:byte; var addr; count:longint); cdecl; external '!' name 'CSetB';
  79. // this will be called by the loader, we pass the address of _pasStart_ and
  80. // _kNLMInfo (needed by clib) and clib will call _pasStart within a newly
  81. // created thread
  82. function _Prelude (NLMHandle : longint;
  83. initErrorScreenID : longint;
  84. cmdLineP : PAnsiChar;
  85. loadDirectoryPath : PAnsiChar;
  86. uninitializedDataLength : longint;
  87. NLMFileHandle : longint;
  88. readRoutineP : pointer;
  89. customDataOffset : longint;
  90. customDataSize : longint) : longint; cdecl; export; [alias:'_Prelude'];
  91. begin
  92. // initialize BSS
  93. CSetB(0,bss,uninitializedDataLength);
  94. // let clib setup a thread and call pasStart in this new thread
  95. _Prelude := _StartNLM (NLMHandle,
  96. initErrorScreenID,
  97. cmdLineP,
  98. loadDirectoryPath,
  99. uninitializedDataLength,
  100. NLMFileHandle,
  101. readRoutineP,
  102. customDataOffset,
  103. customDataSize,
  104. @_kNLMInfo,
  105. @_pasStart);
  106. end;
  107. (*
  108. procedure _Prelude; assembler; export; [alias:'_Prelude'];
  109. asm
  110. pushl %ebp
  111. movl %esp,%ebp
  112. pushl %edi
  113. pushl %esi
  114. pushl %ebx
  115. movl 0x14(%ebp),%edi
  116. movl 0x18(%ebp),%esi
  117. movl %esi, __uninitializedDataSize
  118. movl 0x1c(%ebp),%ebx
  119. movl 0x20(%ebp),%ecx
  120. movl 0x28(%ebp),%eax
  121. pushl $_pasStart
  122. pushl $_kNLMInfo
  123. pushl %eax
  124. movl 0x24(%ebp),%edx // 1b7f6
  125. pushl %edx
  126. pushl %ecx
  127. pushl %ebx
  128. pushl %esi // uninitialized data size
  129. pushl %edi
  130. movl 0x10(%ebp),%edx
  131. pushl %edx
  132. movl 0xc(%ebp),%edx
  133. pushl %edx
  134. movl 0x8(%ebp),%edx
  135. pushl %edx
  136. call _StartNLM
  137. test %eax,%eax
  138. jne .Lx1
  139. xorl %eax,%eax // dont know why this is needed ?
  140. .Lx1:
  141. lea 0xfffffff4(%ebp),%esp
  142. popl %ebx
  143. popl %esi
  144. popl %edi
  145. movl %ebp,%esp
  146. popl %ebp
  147. ret
  148. end;
  149. *)
  150. //# the global stop-function
  151. // fpc will generate an (unneeded) stack frame here, gcc does not
  152. (*
  153. procedure _Stop; cdecl; export; [alias:'_Stop'];
  154. begin
  155. _TerminateNLM (@_kNLMInfo,0,5);
  156. end;
  157. *)
  158. procedure _Stop; cdecl; assembler; [alias:'_Stop'];
  159. asm
  160. pushl $0x5
  161. pushl $0x0
  162. movl _kNLMInfo,%edx
  163. pushl %edx
  164. call _TerminateNLM
  165. addl $0x0c,%esp
  166. ret
  167. end;
  168. end.