system.pp 12 KB

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