system.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2005 by Florian Klaempfl and Pavel Ozerski
  4. member of the Free Pascal development team.
  5. FPC Pascal system unit for the Win32 API.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit System;
  13. interface
  14. {$ifdef SYSTEMDEBUG}
  15. {$define SYSTEMEXCEPTIONDEBUG}
  16. {$endif SYSTEMDEBUG}
  17. {$define FPC_HAS_INDIRECT_MAIN_INFORMATION}
  18. {$ifdef cpui386}
  19. {$define Set_i386_Exception_handler}
  20. {$endif cpui386}
  21. {$define DISABLE_NO_THREAD_MANAGER}
  22. {$define HAS_WIDESTRINGMANAGER}
  23. { include system-independent routine headers }
  24. {$I systemh.inc}
  25. const
  26. LineEnding = #13#10;
  27. LFNSupport = true;
  28. DirectorySeparator = '\';
  29. DriveSeparator = ':';
  30. ExtensionSeparator = '.';
  31. PathSeparator = ';';
  32. AllowDirectorySeparators : set of char = ['\','/'];
  33. AllowDriveSeparators : set of char = [':'];
  34. { FileNameCaseSensitive is defined separately below!!! }
  35. maxExitCode = 65535;
  36. MaxPathLen = 260;
  37. AllFilesMask = '*';
  38. type
  39. PEXCEPTION_FRAME = ^TEXCEPTION_FRAME;
  40. TEXCEPTION_FRAME = record
  41. next : PEXCEPTION_FRAME;
  42. handler : pointer;
  43. end;
  44. const
  45. { Default filehandles }
  46. UnusedHandle : THandle = THandle(-1);
  47. StdInputHandle : THandle = 0;
  48. StdOutputHandle : THandle = 0;
  49. StdErrorHandle : THandle = 0;
  50. FileNameCaseSensitive : boolean = true;
  51. CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
  52. sLineBreak = LineEnding;
  53. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  54. System_exception_frame : PEXCEPTION_FRAME =nil;
  55. type
  56. TStartupInfo=packed record
  57. cb : longint;
  58. lpReserved : Pointer;
  59. lpDesktop : Pointer;
  60. lpTitle : Pointer;
  61. dwX : longint;
  62. dwY : longint;
  63. dwXSize : longint;
  64. dwYSize : longint;
  65. dwXCountChars : longint;
  66. dwYCountChars : longint;
  67. dwFillAttribute : longint;
  68. dwFlags : longint;
  69. wShowWindow : Word;
  70. cbReserved2 : Word;
  71. lpReserved2 : Pointer;
  72. hStdInput : longint;
  73. hStdOutput : longint;
  74. hStdError : longint;
  75. end;
  76. var
  77. { C compatible arguments }
  78. argc : longint; public name 'operatingsystem_parameter_argc';
  79. argv : ppchar; public name 'operatingsystem_parameter_argv';
  80. { Win32 Info }
  81. startupinfo : tstartupinfo;
  82. MainInstance,
  83. cmdshow : longint;
  84. DLLreason : dword; public name 'operatingsystem_dllreason';
  85. DLLparam : PtrInt; public name 'operatingsystem_dllparam';
  86. StartupConsoleMode : DWORD;
  87. const
  88. hprevinst: longint=0;
  89. type
  90. TDLL_Entry_Hook = procedure (dllparam : PtrInt);
  91. const
  92. Dll_Process_Detach_Hook : TDLL_Entry_Hook = nil;
  93. Dll_Thread_Attach_Hook : TDLL_Entry_Hook = nil;
  94. Dll_Thread_Detach_Hook : TDLL_Entry_Hook = nil;
  95. Const
  96. { it can be discussed whether fmShareDenyNone means read and write or read, write and delete, see
  97. also http://bugs.freepascal.org/view.php?id=8898, this allows users to configure the used
  98. value
  99. }
  100. fmShareDenyNoneFlags : DWord = 3;
  101. implementation
  102. var
  103. SysInstance : Longint;public name '_FPC_SysInstance';
  104. InitFinalTable : record end; external name 'INITFINAL';
  105. ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES';
  106. procedure PascalMain;stdcall;external name 'PASCALMAIN';
  107. procedure asm_exit;stdcall;external name 'asm_exit';
  108. const
  109. EntryInformation : TEntryInformation = (
  110. InitFinalTable : @InitFinalTable;
  111. ThreadvarTablesTable : @ThreadvarTablesTable;
  112. asm_exit : @asm_exit;
  113. PascalMain : @PascalMain;
  114. valgrind_used : false;
  115. );
  116. { include system independent routines }
  117. {$I system.inc}
  118. { include code common with win64 }
  119. {$I syswin.inc}
  120. {*****************************************************************************
  121. System Dependent Exit code
  122. *****************************************************************************}
  123. procedure install_exception_handlers;forward;
  124. procedure remove_exception_handlers;forward;
  125. Procedure system_exit;
  126. begin
  127. if IsLibrary then
  128. begin
  129. { If exiting from DLL_PROCESS_ATTACH/DETACH, unwind to DllMain context. }
  130. if DllInitState in [DLL_PROCESS_ATTACH,DLL_PROCESS_DETACH] then
  131. LongJmp(DLLBuf,1)
  132. else
  133. { Abnormal termination, Halt has been called from DLL function,
  134. put down the entire process (DLL_PROCESS_DETACH will still
  135. occur). At this point RTL has been already finalized in InternalExit
  136. and shouldn't be finalized another time in DLL_PROCESS_DETACH.
  137. Indicate this by resetting MainThreadIdWin32. }
  138. MainThreadIDWin32:=0;
  139. end;
  140. if not IsConsole then
  141. begin
  142. Close(stderr);
  143. Close(stdout);
  144. Close(erroutput);
  145. Close(Input);
  146. Close(Output);
  147. { what about Input and Output ?? PM }
  148. { now handled, FPK }
  149. end;
  150. if not IsLibrary then
  151. remove_exception_handlers;
  152. { do cleanup required by the startup code }
  153. EntryInformation.asm_exit();
  154. { call exitprocess, with cleanup as required }
  155. ExitProcess(exitcode);
  156. end;
  157. var
  158. { value of the stack segment
  159. to check if the call stack can be written on exceptions }
  160. _SS : Cardinal;
  161. procedure Exe_entry(const info : TEntryInformation);[public,alias:'_FPC_EXE_Entry'];
  162. var
  163. ST : pointer;
  164. begin
  165. EntryInformation:=info;
  166. IsLibrary:=false;
  167. { install the handlers for exe only ?
  168. or should we install them for DLL also ? (PM) }
  169. install_exception_handlers;
  170. { This strange construction is needed to solve the _SS problem
  171. with a smartlinked syswin32 (PFV) }
  172. asm
  173. { allocate space for an exception frame }
  174. pushl $0
  175. pushl %fs:(0)
  176. { movl %esp,%fs:(0)
  177. but don't insert it as it doesn't
  178. point to anything yet
  179. this will be used in signals unit }
  180. movl %esp,%eax
  181. movl %eax,System_exception_frame
  182. pushl %ebp
  183. movl %esp,%eax
  184. movl %eax,st
  185. end;
  186. StackTop:=st;
  187. asm
  188. xorl %eax,%eax
  189. movw %ss,%ax
  190. movl %eax,_SS
  191. xorl %ebp,%ebp
  192. end;
  193. EntryInformation.PascalMain();
  194. asm
  195. popl %ebp
  196. end;
  197. { if we pass here there was no error ! }
  198. system_exit;
  199. end;
  200. function is_prefetch(p : pointer) : boolean;
  201. var
  202. a : array[0..15] of byte;
  203. doagain : boolean;
  204. instrlo,instrhi,opcode : byte;
  205. i : longint;
  206. begin
  207. result:=false;
  208. { read memory savely without causing another exeception }
  209. if not(ReadProcessMemory(GetCurrentProcess,p,@a,sizeof(a),nil)) then
  210. exit;
  211. i:=0;
  212. doagain:=true;
  213. while doagain and (i<15) do
  214. begin
  215. opcode:=a[i];
  216. instrlo:=opcode and $f;
  217. instrhi:=opcode and $f0;
  218. case instrhi of
  219. { prefix? }
  220. $20,$30:
  221. doagain:=(instrlo and 7)=6;
  222. $60:
  223. doagain:=(instrlo and $c)=4;
  224. $f0:
  225. doagain:=instrlo in [0,2,3];
  226. $0:
  227. begin
  228. result:=(instrlo=$f) and (a[i+1] in [$d,$18]);
  229. exit;
  230. end;
  231. else
  232. doagain:=false;
  233. end;
  234. inc(i);
  235. end;
  236. end;
  237. //
  238. // Hardware exception handling
  239. //
  240. {$ifdef Set_i386_Exception_handler}
  241. type
  242. PFloatingSaveArea = ^TFloatingSaveArea;
  243. TFloatingSaveArea = packed record
  244. ControlWord : Cardinal;
  245. StatusWord : Cardinal;
  246. TagWord : Cardinal;
  247. ErrorOffset : Cardinal;
  248. ErrorSelector : Cardinal;
  249. DataOffset : Cardinal;
  250. DataSelector : Cardinal;
  251. RegisterArea : array[0..79] of Byte;
  252. Cr0NpxState : Cardinal;
  253. end;
  254. PContext = ^TContext;
  255. TContext = packed record
  256. //
  257. // The flags values within this flag control the contents of
  258. // a CONTEXT record.
  259. //
  260. ContextFlags : Cardinal;
  261. //
  262. // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
  263. // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
  264. // included in CONTEXT_FULL.
  265. //
  266. Dr0, Dr1, Dr2,
  267. Dr3, Dr6, Dr7 : Cardinal;
  268. //
  269. // This section is specified/returned if the
  270. // ContextFlags word contains the flag CONTEXT_FLOATING_POINT.
  271. //
  272. FloatSave : TFloatingSaveArea;
  273. //
  274. // This section is specified/returned if the
  275. // ContextFlags word contains the flag CONTEXT_SEGMENTS.
  276. //
  277. SegGs, SegFs,
  278. SegEs, SegDs : Cardinal;
  279. //
  280. // This section is specified/returned if the
  281. // ContextFlags word contains the flag CONTEXT_INTEGER.
  282. //
  283. Edi, Esi, Ebx,
  284. Edx, Ecx, Eax : Cardinal;
  285. //
  286. // This section is specified/returned if the
  287. // ContextFlags word contains the flag CONTEXT_CONTROL.
  288. //
  289. Ebp : Cardinal;
  290. Eip : Cardinal;
  291. SegCs : Cardinal;
  292. EFlags, Esp, SegSs : Cardinal;
  293. //
  294. // This section is specified/returned if the ContextFlags word
  295. // contains the flag CONTEXT_EXTENDED_REGISTERS.
  296. // The format and contexts are processor specific
  297. //
  298. ExtendedRegisters : array[0..MAXIMUM_SUPPORTED_EXTENSION-1] of Byte;
  299. end;
  300. PExceptionPointers = ^TExceptionPointers;
  301. TExceptionPointers = packed record
  302. ExceptionRecord : PExceptionRecord;
  303. ContextRecord : PContext;
  304. end;
  305. { type of functions that should be used for exception handling }
  306. TTopLevelExceptionFilter = function (excep : PExceptionPointers) : Longint;stdcall;
  307. function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : TTopLevelExceptionFilter) : TTopLevelExceptionFilter;
  308. stdcall;external 'kernel32' name 'SetUnhandledExceptionFilter';
  309. const
  310. MaxExceptionLevel = 16;
  311. exceptLevel : Byte = 0;
  312. var
  313. exceptEip : array[0..MaxExceptionLevel-1] of Longint;
  314. exceptError : array[0..MaxExceptionLevel-1] of Byte;
  315. resetFPU : array[0..MaxExceptionLevel-1] of Boolean;
  316. {$ifdef SYSTEMEXCEPTIONDEBUG}
  317. procedure DebugHandleErrorAddrFrame(error : longint; addr, frame : pointer);
  318. begin
  319. if IsConsole then
  320. begin
  321. write(stderr,'HandleErrorAddrFrame(error=',error);
  322. write(stderr,',addr=',hexstr(ptruint(addr),8));
  323. writeln(stderr,',frame=',hexstr(ptruint(frame),8),')');
  324. end;
  325. HandleErrorAddrFrame(error,addr,frame);
  326. end;
  327. {$endif SYSTEMEXCEPTIONDEBUG}
  328. procedure JumpToHandleErrorFrame;
  329. var
  330. eip, ebp, error : Longint;
  331. begin
  332. // save ebp
  333. asm
  334. movl (%ebp),%eax
  335. movl %eax,ebp
  336. end;
  337. if (exceptLevel > 0) then
  338. dec(exceptLevel);
  339. eip:=exceptEip[exceptLevel];
  340. error:=exceptError[exceptLevel];
  341. {$ifdef SYSTEMEXCEPTIONDEBUG}
  342. if IsConsole then
  343. writeln(stderr,'In JumpToHandleErrorFrame error=',error);
  344. {$endif SYSTEMEXCEPTIONDEBUG}
  345. if resetFPU[exceptLevel] then
  346. SysResetFPU;
  347. { build a fake stack }
  348. asm
  349. movl ebp,%ecx
  350. movl eip,%edx
  351. movl error,%eax
  352. pushl eip
  353. movl ebp,%ebp // Change frame pointer
  354. {$ifdef SYSTEMEXCEPTIONDEBUG}
  355. jmpl DebugHandleErrorAddrFrame
  356. {$else not SYSTEMEXCEPTIONDEBUG}
  357. jmpl HandleErrorAddrFrame
  358. {$endif SYSTEMEXCEPTIONDEBUG}
  359. end;
  360. end;
  361. function syswin32_i386_exception_handler(excep : PExceptionPointers) : Longint;stdcall;
  362. var
  363. res: longint;
  364. err: byte;
  365. must_reset_fpu: boolean;
  366. begin
  367. res := EXCEPTION_CONTINUE_SEARCH;
  368. if excep^.ContextRecord^.SegSs=_SS then begin
  369. err := 0;
  370. must_reset_fpu := true;
  371. {$ifdef SYSTEMEXCEPTIONDEBUG}
  372. if IsConsole then Writeln(stderr,'Exception ',
  373. hexstr(excep^.ExceptionRecord^.ExceptionCode, 8));
  374. {$endif SYSTEMEXCEPTIONDEBUG}
  375. case excep^.ExceptionRecord^.ExceptionCode of
  376. STATUS_INTEGER_DIVIDE_BY_ZERO,
  377. STATUS_FLOAT_DIVIDE_BY_ZERO :
  378. err := 200;
  379. STATUS_ARRAY_BOUNDS_EXCEEDED :
  380. begin
  381. err := 201;
  382. must_reset_fpu := false;
  383. end;
  384. STATUS_STACK_OVERFLOW :
  385. begin
  386. err := 202;
  387. must_reset_fpu := false;
  388. end;
  389. STATUS_FLOAT_OVERFLOW :
  390. err := 205;
  391. STATUS_FLOAT_DENORMAL_OPERAND,
  392. STATUS_FLOAT_UNDERFLOW :
  393. err := 206;
  394. {excep^.ContextRecord^.FloatSave.StatusWord := excep^.ContextRecord^.FloatSave.StatusWord and $ffffff00;}
  395. STATUS_FLOAT_INEXACT_RESULT,
  396. STATUS_FLOAT_INVALID_OPERATION,
  397. STATUS_FLOAT_STACK_CHECK :
  398. err := 207;
  399. STATUS_INTEGER_OVERFLOW :
  400. begin
  401. err := 215;
  402. must_reset_fpu := false;
  403. end;
  404. STATUS_ILLEGAL_INSTRUCTION:
  405. { if we're testing sse support, simply set the flag and continue }
  406. if sse_check then
  407. begin
  408. os_supports_sse:=false;
  409. { skip the offending movaps %xmm7, %xmm6 instruction }
  410. inc(excep^.ContextRecord^.Eip,3);
  411. excep^.ExceptionRecord^.ExceptionCode := 0;
  412. res:=EXCEPTION_CONTINUE_EXECUTION;
  413. end
  414. else
  415. err := 216;
  416. STATUS_ACCESS_VIOLATION:
  417. { Athlon prefetch bug? }
  418. if is_prefetch(pointer(excep^.ContextRecord^.Eip)) then
  419. begin
  420. { if yes, then retry }
  421. excep^.ExceptionRecord^.ExceptionCode := 0;
  422. res:=EXCEPTION_CONTINUE_EXECUTION;
  423. end
  424. else
  425. err := 216;
  426. STATUS_CONTROL_C_EXIT:
  427. err := 217;
  428. STATUS_PRIVILEGED_INSTRUCTION:
  429. begin
  430. err := 218;
  431. must_reset_fpu := false;
  432. end;
  433. else
  434. begin
  435. if ((excep^.ExceptionRecord^.ExceptionCode and SEVERITY_ERROR) = SEVERITY_ERROR) then
  436. err := 217
  437. else
  438. err := 255;
  439. end;
  440. end;
  441. if (err <> 0) and (exceptLevel < MaxExceptionLevel) then begin
  442. exceptEip[exceptLevel] := excep^.ContextRecord^.Eip;
  443. exceptError[exceptLevel] := err;
  444. resetFPU[exceptLevel] := must_reset_fpu;
  445. inc(exceptLevel);
  446. excep^.ContextRecord^.Eip := Longint(@JumpToHandleErrorFrame);
  447. excep^.ExceptionRecord^.ExceptionCode := 0;
  448. res := EXCEPTION_CONTINUE_EXECUTION;
  449. {$ifdef SYSTEMEXCEPTIONDEBUG}
  450. if IsConsole then begin
  451. writeln(stderr,'Exception Continue Exception set at ',
  452. hexstr(exceptEip[exceptLevel],8));
  453. writeln(stderr,'Eip changed to ',
  454. hexstr(longint(@JumpToHandleErrorFrame),8), ' error=', err);
  455. end;
  456. {$endif SYSTEMEXCEPTIONDEBUG}
  457. end;
  458. end;
  459. syswin32_i386_exception_handler := res;
  460. end;
  461. procedure install_exception_handlers;
  462. {$ifdef SYSTEMEXCEPTIONDEBUG}
  463. var
  464. oldexceptaddr,
  465. newexceptaddr : Longint;
  466. {$endif SYSTEMEXCEPTIONDEBUG}
  467. begin
  468. {$ifdef SYSTEMEXCEPTIONDEBUG}
  469. asm
  470. movl $0,%eax
  471. movl %fs:(%eax),%eax
  472. movl %eax,oldexceptaddr
  473. end;
  474. {$endif SYSTEMEXCEPTIONDEBUG}
  475. SetUnhandledExceptionFilter(@syswin32_i386_exception_handler);
  476. {$ifdef SYSTEMEXCEPTIONDEBUG}
  477. asm
  478. movl $0,%eax
  479. movl %fs:(%eax),%eax
  480. movl %eax,newexceptaddr
  481. end;
  482. if IsConsole then
  483. writeln(stderr,'Old exception ',hexstr(oldexceptaddr,8),
  484. ' new exception ',hexstr(newexceptaddr,8));
  485. {$endif SYSTEMEXCEPTIONDEBUG}
  486. end;
  487. procedure remove_exception_handlers;
  488. begin
  489. SetUnhandledExceptionFilter(nil);
  490. end;
  491. {$else not cpui386 (Processor specific !!)}
  492. procedure install_exception_handlers;
  493. begin
  494. end;
  495. procedure remove_exception_handlers;
  496. begin
  497. end;
  498. {$endif Set_i386_Exception_handler}
  499. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  500. type
  501. tdosheader = packed record
  502. e_magic : word;
  503. e_cblp : word;
  504. e_cp : word;
  505. e_crlc : word;
  506. e_cparhdr : word;
  507. e_minalloc : word;
  508. e_maxalloc : word;
  509. e_ss : word;
  510. e_sp : word;
  511. e_csum : word;
  512. e_ip : word;
  513. e_cs : word;
  514. e_lfarlc : word;
  515. e_ovno : word;
  516. e_res : array[0..3] of word;
  517. e_oemid : word;
  518. e_oeminfo : word;
  519. e_res2 : array[0..9] of word;
  520. e_lfanew : longint;
  521. end;
  522. tpeheader = packed record
  523. PEMagic : longint;
  524. Machine : word;
  525. NumberOfSections : word;
  526. TimeDateStamp : longint;
  527. PointerToSymbolTable : longint;
  528. NumberOfSymbols : longint;
  529. SizeOfOptionalHeader : word;
  530. Characteristics : word;
  531. Magic : word;
  532. MajorLinkerVersion : byte;
  533. MinorLinkerVersion : byte;
  534. SizeOfCode : longint;
  535. SizeOfInitializedData : longint;
  536. SizeOfUninitializedData : longint;
  537. AddressOfEntryPoint : longint;
  538. BaseOfCode : longint;
  539. BaseOfData : longint;
  540. ImageBase : longint;
  541. SectionAlignment : longint;
  542. FileAlignment : longint;
  543. MajorOperatingSystemVersion : word;
  544. MinorOperatingSystemVersion : word;
  545. MajorImageVersion : word;
  546. MinorImageVersion : word;
  547. MajorSubsystemVersion : word;
  548. MinorSubsystemVersion : word;
  549. Reserved1 : longint;
  550. SizeOfImage : longint;
  551. SizeOfHeaders : longint;
  552. CheckSum : longint;
  553. Subsystem : word;
  554. DllCharacteristics : word;
  555. SizeOfStackReserve : longint;
  556. SizeOfStackCommit : longint;
  557. SizeOfHeapReserve : longint;
  558. SizeOfHeapCommit : longint;
  559. LoaderFlags : longint;
  560. NumberOfRvaAndSizes : longint;
  561. DataDirectory : array[1..$80] of byte;
  562. end;
  563. begin
  564. if (SysInstance=0) and not IsLibrary then
  565. SysInstance:=getmodulehandle(nil);
  566. if (SysInstance=0) then
  567. result:=stklen
  568. else
  569. result:=tpeheader((pointer(SysInstance)+(tdosheader(pointer(SysInstance)^).e_lfanew))^).SizeOfStackReserve;
  570. end;
  571. begin
  572. { get some helpful informations }
  573. GetStartupInfo(@startupinfo);
  574. { some misc Win32 stuff }
  575. if not IsLibrary then
  576. SysInstance:=getmodulehandle(nil);
  577. MainInstance:=SysInstance;
  578. { pass dummy value }
  579. StackLength := CheckInitialStkLen($1000000);
  580. StackBottom := StackTop - StackLength;
  581. cmdshow:=startupinfo.wshowwindow;
  582. { Setup heap and threading, these may be already initialized from TLS callback }
  583. if not Assigned(CurrentTM.BeginThread) then
  584. begin
  585. InitHeap;
  586. InitSystemThreads;
  587. end;
  588. SysInitExceptions;
  589. { setup fastmove stuff }
  590. fpc_cpucodeinit;
  591. initwidestringmanager;
  592. initunicodestringmanager;
  593. InitWin32Widestrings;
  594. SysInitStdIO;
  595. { Arguments }
  596. setup_arguments;
  597. { Reset IO Error }
  598. InOutRes:=0;
  599. ProcessID := GetCurrentProcessID;
  600. { Reset internal error variable }
  601. errno:=0;
  602. initvariantmanager;
  603. DispCallByIDProc:=@DoDispCallByIDError;
  604. end.