system.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. Unit System;
  2. interface
  3. // Was needed to bootstrap with our old 2.1 fpc for BeOS
  4. // to define real
  5. { $define VER2_0}
  6. {$define FPC_IS_SYSTEM}
  7. {$I sysunixh.inc}
  8. type
  9. THeapPointer = ^pointer;
  10. var
  11. heapstartpointer : THeapPointer;
  12. heapstart : pointer;//external;//external name 'HEAP';
  13. myheapsize : longint; //external;//external name 'HEAPSIZE';
  14. myheaprealsize : longint;
  15. heap_handle : longint;
  16. implementation
  17. procedure debugger(s : PChar); cdecl; external 'root' name 'debugger';
  18. function disable_debugger(state : integer): integer; cdecl; external 'root' name 'disable_debugger';
  19. //begin
  20. //end;
  21. { OS independant parts}
  22. {$I system.inc}
  23. {*****************************************************************************
  24. System Dependent Exit code
  25. *****************************************************************************}
  26. {$ifdef i386}
  27. procedure prthaltproc;external name '_haltproc';
  28. procedure system_exit;
  29. begin
  30. asm
  31. jmp prthaltproc
  32. end;
  33. End;
  34. {$else i386}
  35. procedure haltproc(exitcode: longint); cdecl; external name '_haltproc';
  36. procedure system_exit;
  37. begin
  38. haltproc(ExitCode);
  39. end;
  40. {$endif i386}
  41. { OS dependant parts }
  42. {*****************************************************************************
  43. Heap Management
  44. *****************************************************************************}
  45. (*var myheapstart:pointer;
  46. myheapsize:longint;
  47. myheaprealsize:longint;
  48. heap_handle:longint;
  49. zero:longint;
  50. { first address of heap }
  51. function getheapstart:pointer;
  52. begin
  53. getheapstart:=myheapstart;
  54. end;
  55. { current length of heap }
  56. function getheapsize:longint;
  57. begin
  58. getheapsize:=myheapsize;
  59. end;
  60. *)
  61. (*function getheapstart:pointer;
  62. assembler;
  63. asm
  64. leal HEAP,%eax
  65. end ['EAX'];
  66. function getheapsize:longint;
  67. assembler;
  68. asm
  69. movl intern_HEAPSIZE,%eax
  70. end ['EAX'];*)
  71. { function to allocate size bytes more for the program }
  72. { must return the first address of new data space or nil if fail }
  73. (*function Sbrk(size : longint):pointer;
  74. var newsize,newrealsize:longint;
  75. s : string;
  76. begin
  77. WriteLn('SBRK');
  78. Str(size, s);
  79. WriteLn('size : ' + s);
  80. if (myheapsize+size)<=myheaprealsize then
  81. begin
  82. Sbrk:=pointer(heapstart+myheapsize);
  83. myheapsize:=myheapsize+size;
  84. exit;
  85. end;
  86. newsize:=myheapsize+size;
  87. newrealsize:=(newsize and $FFFFF000)+$1000;
  88. case resize_area(heap_handle,newrealsize) of
  89. B_OK :
  90. begin
  91. WriteLn('B_OK');
  92. Sbrk:=pointer(heapstart+myheapsize);
  93. myheapsize:=newsize;
  94. myheaprealsize:=newrealsize;
  95. exit;
  96. end;
  97. B_BAD_VALUE : WriteLn('B_BAD_VALUE');
  98. B_NO_MEMORY : WriteLn('B_NO_MEMORY');
  99. B_ERROR : WriteLn('B_ERROR');
  100. else
  101. begin
  102. Sbrk:=pointer(heapstart+myheapsize);
  103. myheapsize:=newsize;
  104. myheaprealsize:=newrealsize;
  105. exit;
  106. end;
  107. end;
  108. // Sbrk:=nil;
  109. end;*)
  110. function sys_resize_area (handle:cardinal; size:longint):longint; cdecl; external name 'sys_resize_area';
  111. //function sbrk2 (size : longint):pointer; cdecl; external name 'sbrk';
  112. { function to allocate size bytes more for the program }
  113. { must return the first address of new data space or nil if fail }
  114. //function Sbrk(size : longint):pointer;
  115. //var newsize,newrealsize:longint;
  116. // s : string;
  117. //begin
  118. // sbrk := sbrk2(size);
  119. (* sbrk := nil;
  120. WriteLn('sbrk');
  121. Str(size, s);
  122. WriteLn('size : ' + s);
  123. if (myheapsize+size)<=myheaprealsize then
  124. begin
  125. Sbrk:=heapstart+myheapsize;
  126. myheapsize:=myheapsize+size;
  127. exit;
  128. end;
  129. newsize:=myheapsize+size;
  130. newrealsize:=(newsize and $FFFFF000)+$1000;
  131. if sys_resize_area(heap_handle,newrealsize+$1000)=0 then
  132. begin
  133. WriteLn('sys_resize_area OK');
  134. Str(longint(newrealsize), s);
  135. WriteLn('newrealsize : $' + Hexstr(longint(newrealsize), 8));
  136. Str(longint(heapstartpointer), s);
  137. WriteLn('heapstart : $' + Hexstr(longint(heapstart), 8));
  138. Str(myheapsize, s);
  139. WriteLn('myheapsize : ' + s);
  140. Str(myheapsize, s);
  141. WriteLn('Total : ' + s);
  142. WriteLn('Before fillchar');
  143. WriteLn('sbrk : $' + Hexstr(longint(heapstart+myheapsize), 8));
  144. Sbrk:=heapstart+myheapsize;
  145. FillChar(sbrk^, size, #0);
  146. WriteLn('EndFillChar');
  147. WriteLn('sbrk : $' + Hexstr(longint(sbrk), 8));
  148. // ReadLn(s);
  149. myheapsize:=newsize;
  150. Str({longint(heapstartpointer) +} myheapsize, s);
  151. WriteLn('Total : ' + s);
  152. myheaprealsize:=newrealsize;
  153. exit;
  154. end
  155. else
  156. begin
  157. debugger('Bad resize_area');
  158. WriteLn('Bad resize_area');
  159. end;
  160. Sbrk:=nil;
  161. *)
  162. //end;
  163. { $I text.inc}
  164. {*****************************************************************************
  165. UnTyped File Handling
  166. *****************************************************************************}
  167. { $i file.inc}
  168. {*****************************************************************************
  169. Typed File Handling
  170. *****************************************************************************}
  171. { $i typefile.inc}
  172. {*****************************************************************************
  173. Misc. System Dependent Functions
  174. *****************************************************************************}
  175. Function ParamCount: Longint;
  176. var
  177. s : string;
  178. Begin
  179. ParamCount := 0;
  180. Paramcount:=argc - 1;
  181. End;
  182. { variable where full path and filename and executable is stored }
  183. { is setup by the startup of the system unit. }
  184. var
  185. execpathstr : shortstring;
  186. {$ifdef FPC_USE_LIBC}
  187. // private; use the macros, below
  188. function _get_image_info(image : image_id; var info : image_info; size : size_t)
  189. : status_t; cdecl; external 'root' name '_get_image_info';
  190. function _get_next_image_info(team : team_id; var cookie : Longint; var info : image_info; size : size_t)
  191. : status_t; cdecl; external 'root' name '_get_next_image_info';
  192. function get_image_info(image : image_id; var info : image_info) : status_t;
  193. begin
  194. Result := _get_image_info(image, info, SizeOf(info));
  195. end;
  196. function get_next_image_info(team : team_id; var cookie : Longint; var info : image_info) : status_t;
  197. begin
  198. Result := _get_next_image_info(team, cookie, info, SizeOf(info));
  199. end;
  200. {$endif}
  201. { this routine sets up the paramstr(0) string at startup }
  202. procedure setupexecname;
  203. var
  204. cookie: longint;
  205. image : image_info;
  206. index : byte;
  207. s : string;
  208. begin
  209. cookie:=0;
  210. fillchar(image, sizeof(image_info), 0);
  211. if get_next_image_info(0, cookie, image) = B_OK then
  212. begin
  213. execpathstr := strpas(@image.name);
  214. end
  215. else
  216. execpathstr := '';
  217. { problem with Be 4.5 noted... path contains . character }
  218. { if file is directly executed in CWD }
  219. index:=pos('/./',execpathstr);
  220. if index <> 0 then
  221. begin
  222. { remove the /. characters }
  223. Delete(execpathstr,index, 2);
  224. end;
  225. end;
  226. function paramstr(l: longint) : string;
  227. var
  228. s: string;
  229. s1: string;
  230. begin
  231. { stricly conforming POSIX applications }
  232. { have the executing filename as argv[0] }
  233. if l = 0 then
  234. begin
  235. paramstr := execpathstr;
  236. end
  237. else if (l < argc) then
  238. begin
  239. paramstr:=strpas(argv[l]);
  240. end
  241. else
  242. paramstr := '';
  243. end;
  244. Procedure Randomize;
  245. Begin
  246. randseed:=longint(Fptime(nil));
  247. End;
  248. function GetProcessID: SizeUInt;
  249. begin
  250. GetProcessID := SizeUInt (fpGetPID);
  251. end;
  252. {*****************************************************************************
  253. SystemUnit Initialization
  254. *****************************************************************************}
  255. function reenable_signal(sig : longint) : boolean;
  256. var
  257. e : TSigSet;
  258. i,j : byte;
  259. olderrno: cint;
  260. begin
  261. fillchar(e,sizeof(e),#0);
  262. { set is 1 based PM }
  263. dec(sig);
  264. i:=sig mod (sizeof(cuLong) * 8);
  265. j:=sig div (sizeof(cuLong) * 8);
  266. e[j]:=1 shl i;
  267. { this routine is called from a signal handler, so must not change errno }
  268. olderrno:=geterrno;
  269. fpsigprocmask(SIG_UNBLOCK,@e,nil);
  270. reenable_signal:=geterrno=0;
  271. seterrno(olderrno);
  272. end;
  273. // signal handler is arch dependant due to processorexception to language
  274. // exception translation
  275. {$i sighnd.inc}
  276. //void set_signal_stack(void *ptr, size_t size);
  277. //int sigaltstack(const stack_t *ss, stack_t *oss);
  278. procedure set_signal_stack(ptr : pointer; size : size_t); cdecl; external 'root' name 'set_signal_stack';
  279. function sigaltstack(const stack : pstack_t; oldStack : pstack_t) : integer; cdecl; external 'root' name 'sigaltstack';
  280. type
  281. {$PACKRECORDS C}
  282. TAlternateSignalStack = record
  283. case Integer of
  284. 0 : (buffer : array[0..(SIGSTKSZ * 4)-1] of Char);
  285. 1 : (ld : clonglong);
  286. 2 : (l : integer);
  287. 3 : (p : pointer);
  288. end;
  289. var
  290. alternate_signal_stack : TAlternateSignalStack;
  291. procedure InstallDefaultSignalHandler(signum: longint; out oldact: SigActionRec); public name '_FPC_INSTALLDEFAULTSIGHANDLER';
  292. var
  293. r : integer;
  294. st : stack_t;
  295. act : SigActionRec;
  296. begin
  297. st.ss_flags := 0;
  298. st.ss_sp := @alternate_signal_stack.buffer;
  299. st.ss_size := SizeOf(alternate_signal_stack.buffer);
  300. r := sigaltstack(@st, nil);
  301. if (r <> 0) then
  302. begin
  303. debugger('sigaltstack error');
  304. end;
  305. { Initialize the sigaction structure }
  306. { all flags and information set to zero }
  307. FillChar(act, sizeof(SigActionRec), #0);
  308. { initialize handler }
  309. act.sa_mask[0] := 0;
  310. act.sa_handler := SigActionHandler(@SignalToRunError);
  311. act.sa_flags := SA_ONSTACK;
  312. FpSigAction(signum,@act,@oldact);
  313. end;
  314. var
  315. oldsigfpe: SigActionRec; public name '_FPC_OLDSIGFPE';
  316. oldsigsegv: SigActionRec; public name '_FPC_OLDSIGSEGV';
  317. oldsigbus: SigActionRec; public name '_FPC_OLDSIGBUS';
  318. oldsigill: SigActionRec; public name '_FPC_OLDSIGILL';
  319. Procedure InstallSignals;
  320. begin
  321. InstallDefaultSignalHandler(SIGFPE,oldsigfpe);
  322. InstallDefaultSignalHandler(SIGSEGV,oldsigsegv);
  323. InstallDefaultSignalHandler(SIGBUS,oldsigbus);
  324. InstallDefaultSignalHandler(SIGILL,oldsigill);
  325. end;
  326. Procedure RestoreOldSignalHandlers;
  327. begin
  328. FpSigAction(SIGFPE,@oldsigfpe,nil);
  329. FpSigAction(SIGSEGV,@oldsigsegv,nil);
  330. FpSigAction(SIGBUS,@oldsigbus,nil);
  331. FpSigAction(SIGILL,@oldsigill,nil);
  332. end;
  333. procedure SysInitStdIO;
  334. begin
  335. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  336. displayed in and messagebox }
  337. OpenStdIO(Input,fmInput,StdInputHandle);
  338. OpenStdIO(Output,fmOutput,StdOutputHandle);
  339. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  340. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  341. end;
  342. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  343. begin
  344. result := stklen;
  345. end;
  346. var
  347. s : string;
  348. begin
  349. IsConsole := TRUE;
  350. StackLength := CheckInitialStkLen(InitialStkLen);
  351. StackBottom := Sptr - StackLength;
  352. ReturnNilIfGrowHeapFails := False;
  353. { Set up signals handlers }
  354. InstallSignals;
  355. {$ifdef cpui386}
  356. fpc_cpucodeinit;
  357. {$endif}
  358. { Setup heap }
  359. myheapsize:=4096*100;// $ 20000;
  360. myheaprealsize:=4096*100;// $ 20000;
  361. heapstart:=nil;
  362. heapstartpointer := nil;
  363. // heapstartpointer := Sbrk2(4096*1);
  364. heapstartpointer := SysOSAlloc(4096*100);
  365. {$IFDEF FPC_USE_LIBC}
  366. // heap_handle := create_area('fpcheap',heapstart,0,myheaprealsize,0,3);//!!
  367. {$ELSE}
  368. // debugger('tata'#0);
  369. // heap_handle := create_area('fpcheap',longint(heapstartpointer),0,myheaprealsize,0,3);//!!
  370. // case heap_handle of
  371. // B_BAD_VALUE : WriteLn('B_BAD_VALUE');
  372. // B_PAGE_SIZE : WriteLn('B_PAGE_SIZE');
  373. // B_NO_MEMORY : WriteLn('B_NO_MEMORY');
  374. // B_ERROR : WriteLn('B_ERROR');
  375. // end;
  376. FillChar(heapstartpointer^, myheaprealsize, #0);
  377. // WriteLn('EndFillChar');
  378. // WriteLn('P : $' + Hexstr(longint(heapstartpointer), 8));
  379. // WriteLn('heapstart : $' + Hexstr(longint(heapstartpointer^), 8));
  380. heapstart := heapstartpointer;
  381. {$ENDIF}
  382. // WriteLn('before InitHeap');
  383. // case heap_handle of
  384. // B_BAD_VALUE : WriteLn('B_BAD_VALUE');
  385. // B_PAGE_SIZE : WriteLn('B_PAGE_SIZE');
  386. // B_NO_MEMORY : WriteLn('B_NO_MEMORY');
  387. // B_ERROR : WriteLn('B_ERROR');
  388. // else
  389. // begin
  390. // WriteLn('ok');
  391. // WriteLn('P : $' + Hexstr(longint(heapstartpointer), 8));
  392. // WriteLn('heapstart : $' + Hexstr(longint(heapstartpointer^), 8));
  393. // if heap_handle>0 then
  394. // begin
  395. InitHeap;
  396. // end;
  397. // end;
  398. // end;
  399. // WriteLn('after InitHeap');
  400. // end else system_exit;
  401. SysInitExceptions;
  402. // WriteLn('after SysInitException');
  403. initunicodestringmanager;
  404. { Setup IO }
  405. SysInitStdIO;
  406. { Reset IO Error }
  407. InOutRes:=0;
  408. InitSystemThreads;
  409. InitSystemDynLibs;
  410. setupexecname;
  411. { restore original signal handlers in case this is a library }
  412. if IsLibrary then
  413. RestoreOldSignalHandlers;
  414. end.