syscalls.inc 12 KB

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