syscalls.inc 12 KB

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