syscalls.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  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. {No debugging for syslinux include !}
  13. {$IFDEF SYS_LINUX}
  14. {$UNDEF SYSCALL_DEBUG}
  15. {$ENDIF SYS_LINUX}
  16. {*****************************************************************************
  17. --- Main:The System Call Self ---
  18. *****************************************************************************}
  19. Procedure Do_SysCall( callnr:longint;var regs : SysCallregs );assembler;
  20. {
  21. This function puts the registers in place, does the call, and then
  22. copies back the registers as they are after the SysCall.
  23. }
  24. {$ifdef i386}
  25. {$ASMMODE ATT}
  26. {$define fpc_syscall_ok}
  27. asm
  28. { load the registers... }
  29. movl 12(%ebp),%eax
  30. movl 4(%eax),%ebx
  31. movl 8(%eax),%ecx
  32. movl 12(%eax),%edx
  33. movl 16(%eax),%esi
  34. movl 20(%eax),%edi
  35. { set the call number }
  36. movl 8(%ebp),%eax
  37. { Go ! }
  38. int $0x80
  39. { Put back the registers... }
  40. pushl %eax
  41. movl 12(%ebp),%eax
  42. movl %edi,20(%eax)
  43. movl %esi,16(%eax)
  44. movl %edx,12(%eax)
  45. movl %ecx,8(%eax)
  46. movl %ebx,4(%eax)
  47. popl %ebx
  48. movl %ebx,(%eax)
  49. end;
  50. {$ASMMODE DEFAULT}
  51. {$endif i386}
  52. {$ifdef m68k}
  53. {$define fpc_syscall_ok}
  54. asm
  55. { load the registers... }
  56. move.l 12(a6),a0
  57. move.l 4(a0),d1
  58. move.l 8(a0),d2
  59. move.l 12(a0),d3
  60. move.l 16(a0),d4
  61. move.l 20(a0),d5
  62. { set the call number }
  63. move.l 8(a6),d0
  64. { Go ! }
  65. trap #0
  66. { Put back the registers... }
  67. move.l d0,-(sp)
  68. move.l 12(a6),a0
  69. move.l d5,20(a0)
  70. move.l d4,16(a0)
  71. move.l d3,12(a0)
  72. move.l d2,8(a0)
  73. move.l d1,4(a0)
  74. move.l (sp)+,d1
  75. move.l d1,(a0)
  76. end;
  77. {$endif m68k}
  78. {$ifdef powerpc}
  79. {$define fpc_syscall_ok}
  80. var
  81. tmp: pointer;
  82. asm
  83. { load the registers... }
  84. lwz r5, 8(r4)
  85. lwz r6, 12(r4)
  86. lwz r7, 16(r4)
  87. mr r0, r3
  88. lwz r3, 0(r4)
  89. stw r4, tmp
  90. lwz r4, 4(r4)
  91. { Go ! }
  92. sc
  93. { Put back the registers... }
  94. lwz r0, tmp
  95. stw r3, 0(r0)
  96. stw r4, 4(r0)
  97. stw r5, 8(r0)
  98. stw r6, 12(r0)
  99. stw r7, 16(r0)
  100. end;
  101. {$endif powerpc}
  102. {$ifndef fpc_syscall_ok}
  103. {$error Cannot decide which processor you have!}
  104. asm
  105. end;
  106. {$endif not fpc_syscall_ok}
  107. {$IFDEF SYSCALL_DEBUG}
  108. Const
  109. DoSysCallDebug : Boolean = False;
  110. var
  111. LastCnt,
  112. LastEax,
  113. LastCall : longint;
  114. DebugTxt : string[20];
  115. {$ENDIF}
  116. Function SysCall( callnr:longint;var regs : SysCallregs ):longint;
  117. {
  118. This function serves as an interface to do_SysCall.
  119. If the SysCall returned a negative number, it returns -1, and puts the
  120. SysCall result in errno. Otherwise, it returns the SysCall return value
  121. }
  122. begin
  123. do_SysCall(callnr,regs);
  124. if regs.reg1<0 then
  125. begin
  126. {$IFDEF SYSCALL_DEBUG}
  127. If DoSysCallDebug then
  128. debugtxt:=' syscall error: ';
  129. {$endif}
  130. ErrNo:=-regs.reg1;
  131. SysCall:=-1;
  132. end
  133. else
  134. begin
  135. {$IFDEF SYSCALL_DEBUG}
  136. if DoSysCallDebug then
  137. debugtxt:=' syscall returned: ';
  138. {$endif}
  139. SysCall:=regs.reg1;
  140. errno:=0
  141. end;
  142. {$IFDEF SYSCALL_DEBUG}
  143. if DoSysCallDebug then
  144. begin
  145. inc(lastcnt);
  146. if (callnr<>lastcall) or (regs.reg1<>lasteax) then
  147. begin
  148. if lastcnt>1 then
  149. writeln(sys_nr_txt[lastcall],debugtxt,lasteax,' (',lastcnt,'x)');
  150. lastcall:=callnr;
  151. lasteax:=regs.reg1;
  152. lastcnt:=0;
  153. writeln(sys_nr_txt[lastcall],debugtxt,lasteax);
  154. end;
  155. end;
  156. {$endif}
  157. end;
  158. Function Sys_Time:longint;
  159. var
  160. regs : SysCallregs;
  161. begin
  162. regs.reg2:=0;
  163. Sys_Time:=SysCall(SysCall_nr_time,regs);
  164. end;
  165. {*****************************************************************************
  166. --- File:File handling related calls ---
  167. *****************************************************************************}
  168. Function Sys_Open(f:pchar;flags:longint;mode:integer):longint;
  169. var
  170. regs : SysCallregs;
  171. Begin
  172. regs.reg2:=longint(f);
  173. regs.reg3:=flags;
  174. regs.reg4:=mode;
  175. Sys_Open:=SysCall(SysCall_nr_open,regs);
  176. End;
  177. Function Sys_Close(f:longint):longint;
  178. var
  179. regs : SysCallregs;
  180. begin
  181. regs.reg2:=f;
  182. Sys_Close:=SysCall(SysCall_nr_close,regs);
  183. end;
  184. Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint;
  185. var
  186. regs : SysCallregs;
  187. begin
  188. regs.reg2:=f;
  189. regs.reg3:=off;
  190. regs.reg4:=Whence;
  191. Sys_lseek:=SysCall(SysCall_nr_lseek,regs);
  192. end;
  193. Function Sys_Read(f:longint;buffer:pchar;count:longint):longint;
  194. var
  195. regs : SysCallregs;
  196. begin
  197. regs.reg2:=f;
  198. regs.reg3:=longint(buffer);
  199. regs.reg4:=count;
  200. Sys_Read:=SysCall(SysCall_nr_read,regs);
  201. end;
  202. Function Sys_Write(f:longint;buffer:pchar;count:longint):longint;
  203. var
  204. regs : SysCallregs;
  205. begin
  206. regs.reg2:=f;
  207. regs.reg3:=longint(buffer);
  208. regs.reg4:=count;
  209. Sys_Write:=SysCall(SysCall_nr_write,regs);
  210. end;
  211. Function Sys_Unlink(Filename:pchar):longint;
  212. var
  213. regs : SysCallregs;
  214. begin
  215. regs.reg2:=longint(filename);
  216. Sys_Unlink:=SysCall(SysCall_nr_unlink,regs);
  217. end;
  218. Function Sys_fstat(fd : longint;var Info:stat):Longint;
  219. var
  220. regs : SysCallregs;
  221. begin
  222. regs.reg2:=fd;
  223. regs.reg3:=longint(@Info);
  224. Sys_fStat:=SysCall(SysCall_nr_fstat,regs);
  225. end;
  226. Function Sys_Rename(Oldname,Newname:pchar):longint;
  227. var
  228. regs : SysCallregs;
  229. begin
  230. regs.reg2:=longint(oldname);
  231. regs.reg3:=longint(newname);
  232. Sys_Rename:=SysCall(SysCall_nr_rename,regs);
  233. end;
  234. Function Sys_Stat(Filename:pchar;var Buffer: stat):longint;
  235. {
  236. We need this for getcwd
  237. }
  238. var
  239. regs : SysCallregs;
  240. begin
  241. regs.reg2:=longint(filename);
  242. regs.reg3:=longint(@buffer);
  243. Sys_Stat:=SysCall(SysCall_nr_stat,regs);
  244. end;
  245. Function Sys_Symlink(oldname,newname:pchar):longint;
  246. {
  247. We need this for erase
  248. }
  249. var
  250. regs : SysCallregs;
  251. begin
  252. regs.reg2:=longint(oldname);
  253. regs.reg3:=longint(newname);
  254. Sys_symlink:=SysCall(SysCall_nr_symlink,regs);
  255. end;
  256. Function Sys_ReadLink(name,linkname:pchar;maxlen:longint):longint;
  257. var
  258. regs : SysCallRegs;
  259. begin
  260. regs.reg2:=longint(name);
  261. regs.reg3:=longint(linkname);
  262. regs.reg4:=maxlen;
  263. Sys_ReadLink:=SysCall(Syscall_nr_readlink,regs);
  264. end;
  265. {*****************************************************************************
  266. --- Directory:Directory related calls ---
  267. *****************************************************************************}
  268. Function Sys_Chdir(Filename:pchar):longint;
  269. var
  270. regs : SysCallregs;
  271. begin
  272. regs.reg2:=longint(filename);
  273. Sys_ChDir:=SysCall(SysCall_nr_chdir,regs);
  274. end;
  275. Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
  276. var
  277. regs : SysCallregs;
  278. begin
  279. regs.reg2:=longint(filename);
  280. regs.reg3:=mode;
  281. Sys_MkDir:=SysCall(SysCall_nr_mkdir,regs);
  282. end;
  283. Function Sys_Rmdir(Filename:pchar):longint;
  284. var
  285. regs : SysCallregs;
  286. begin
  287. regs.reg2:=longint(filename);
  288. Sys_Rmdir:=SysCall(SysCall_nr_rmdir,regs);
  289. end;
  290. { we need this for getcwd }
  291. Function OpenDir(f:pchar):pdir;
  292. var
  293. fd:integer;
  294. st:stat;
  295. ptr:pdir;
  296. begin
  297. opendir:=nil;
  298. if sys_stat(f,st)<0 then
  299. exit;
  300. { Is it a dir ? }
  301. if not((st.mode and $f000)=$4000)then
  302. begin
  303. errno:=sys_enotdir;
  304. exit
  305. end;
  306. { Open it}
  307. fd:=sys_open(f,OPEN_RDONLY,438);
  308. if fd<0 then
  309. exit;
  310. new(ptr);
  311. if ptr=nil then
  312. exit;
  313. new(ptr^.buf);
  314. if ptr^.buf=nil then
  315. exit;
  316. ptr^.fd:=fd;
  317. ptr^.loc:=0;
  318. ptr^.size:=0;
  319. ptr^.dd_max:=sizeof(ptr^.buf^);
  320. opendir:=ptr;
  321. end;
  322. function CloseDir(p:pdir):integer;
  323. begin
  324. closedir:=sys_close(p^.fd);
  325. dispose(p^.buf);
  326. dispose(p);
  327. end;
  328. Function Sys_ReadDir(p:pdir):pdirent;
  329. var
  330. regs :SysCallregs;
  331. dummy:longint;
  332. begin
  333. regs.reg3:=longint(p^.buf);
  334. regs.reg2:=p^.fd;
  335. regs.reg4:=1;
  336. dummy:=SysCall(SysCall_nr_readdir,regs);
  337. { the readdir system call returns the number of bytes written }
  338. if dummy=0 then
  339. sys_readdir:=nil
  340. else
  341. sys_readdir:=p^.buf
  342. end;
  343. {*****************************************************************************
  344. --- Process:Process & program handling - related calls ---
  345. *****************************************************************************}
  346. Function Sys_GetPid:LongInt;
  347. var
  348. regs : SysCallregs;
  349. begin
  350. Sys_GetPid:=SysCall(SysCall_nr_getpid,regs);
  351. end;
  352. Procedure Sys_Exit(ExitCode:Integer);
  353. var
  354. regs : SysCallregs;
  355. begin
  356. regs.reg2:=exitcode;
  357. SysCall(SysCall_nr_exit,regs)
  358. end;
  359. Procedure SigAction(Signum:longint;Act,OldAct:PSigActionRec );
  360. {
  361. Change action of process upon receipt of a signal.
  362. Signum specifies the signal (all except SigKill and SigStop).
  363. If Act is non-nil, it is used to specify the new action.
  364. If OldAct is non-nil the previous action is saved there.
  365. }
  366. Var
  367. sr : Syscallregs;
  368. begin
  369. sr.reg2:=Signum;
  370. sr.reg3:=Longint(act);
  371. sr.reg4:=Longint(oldact);
  372. SysCall(Syscall_nr_sigaction,sr);
  373. end;
  374. function Sys_FTruncate(Handle,Pos:longint):longint; //moved from sysunix.inc Do_Truncate
  375. var
  376. sr : syscallregs;
  377. begin
  378. sr.reg2:=Handle;
  379. sr.reg3:=Pos;
  380. Sys_FTruncate:=syscall(syscall_nr_ftruncate,sr);
  381. end;
  382. Function Sys_mmap(adr,len,prot,flags,fdes,off:longint):longint; // moved from sysunix.inc, used in sbrk
  383. type
  384. tmmapargs=packed record
  385. address : longint;
  386. size : longint;
  387. prot : longint;
  388. flags : longint;
  389. fd : longint;
  390. offset : longint;
  391. end;
  392. var
  393. t : syscallregs;
  394. mmapargs : tmmapargs;
  395. begin
  396. mmapargs.address:=adr;
  397. mmapargs.size:=len;
  398. mmapargs.prot:=prot;
  399. mmapargs.flags:=flags;
  400. mmapargs.fd:=fdes;
  401. mmapargs.offset:=off;
  402. t.reg2:=longint(@mmapargs);
  403. Sys_mmap:=syscall(syscall_nr_mmap,t);
  404. end;
  405. Function Sys_munmap(adr,len:longint):longint; // moved from sysunix.inc, used in sbrk
  406. var
  407. t : syscallregs;
  408. begin
  409. t.reg2:=adr;
  410. t.reg3:=len;
  411. Sys_munmap:=syscall(syscall_nr_munmap,t);
  412. end;
  413. function Clone(func:TCloneFunc;sp:pointer;flags:longint;args:pointer):longint;
  414. begin
  415. if (pointer(func)=nil) or (sp=nil) then
  416. exit(-1); // give an error result
  417. {$ifdef i386}
  418. asm
  419. { Insert the argument onto the new stack. }
  420. movl sp,%ecx
  421. subl $8,%ecx
  422. movl args,%eax
  423. movl %eax,4(%ecx)
  424. { Save the function pointer as the zeroth argument.
  425. It will be popped off in the child in the ebx frobbing below. }
  426. movl func,%eax
  427. movl %eax,0(%ecx)
  428. { Do the system call }
  429. pushl %ebx
  430. movl flags,%ebx
  431. movl SysCall_nr_clone,%eax
  432. int $0x80
  433. popl %ebx
  434. test %eax,%eax
  435. jnz .Lclone_end
  436. { We're in the new thread }
  437. subl %ebp,%ebp { terminate the stack frame }
  438. call *%ebx
  439. { exit process }
  440. movl %eax,%ebx
  441. movl $1,%eax
  442. int $0x80
  443. .Lclone_end:
  444. movl %eax,__RESULT
  445. end;
  446. {$endif i386}
  447. {$ifdef m68k}
  448. { No yet translated, my m68k assembler is too weak for such things PM }
  449. (*
  450. asm
  451. { Insert the argument onto the new stack. }
  452. movl sp,%ecx
  453. subl $8,%ecx
  454. movl args,%eax
  455. movl %eax,4(%ecx)
  456. { Save the function pointer as the zeroth argument.
  457. It will be popped off in the child in the ebx frobbing below. }
  458. movl func,%eax
  459. movl %eax,0(%ecx)
  460. { Do the system call }
  461. pushl %ebx
  462. movl flags,%ebx
  463. movl SysCall_nr_clone,%eax
  464. int $0x80
  465. popl %ebx
  466. test %eax,%eax
  467. jnz .Lclone_end
  468. { We're in the new thread }
  469. subl %ebp,%ebp { terminate the stack frame }
  470. call *%ebx
  471. { exit process }
  472. movl %eax,%ebx
  473. movl $1,%eax
  474. int $0x80
  475. .Lclone_end:
  476. movl %eax,__RESULT
  477. end;
  478. *)
  479. {$endif m68k}
  480. end;
  481. {
  482. Interface to Unix ioctl call.
  483. Performs various operations on the filedescriptor Handle.
  484. Ndx describes the operation to perform.
  485. Data points to data needed for the Ndx function. The structure of this
  486. data is function-dependent.
  487. }
  488. Function Sys_IOCtl(Handle,Ndx: Longint;Data: Pointer):LongInt; // This was missing here, instead hardcode in Do_IsDevice
  489. var
  490. sr: SysCallRegs;
  491. begin
  492. sr.reg2:=Handle;
  493. sr.reg3:=Ndx;
  494. sr.reg4:=Longint(Data);
  495. Sys_IOCtl:=SysCall(Syscall_nr_ioctl,sr);
  496. end;
  497. {
  498. $Log$
  499. Revision 1.8 2002-08-19 18:24:05 jonas
  500. + ppc support for do_syscall
  501. Revision 1.7 2002/07/29 21:28:17 florian
  502. * several fixes to get further with linux/ppc system unit compilation
  503. Revision 1.6 2002/07/28 20:43:48 florian
  504. * several fixes for linux/powerpc
  505. * several fixes to MT
  506. Revision 1.5 2001/10/14 13:33:20 peter
  507. * start of thread support for linux
  508. Revision 1.4 2001/06/02 00:31:30 peter
  509. * merge unix updates from the 1.0 branch, mostly related to the
  510. solaris target
  511. }