syscalls.inc 13 KB

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