1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <mach.h> 5 #define EXTERN 6 #include "arm.h" 7 8 #define ODIRLEN 116 /* compatibility; used in _stat etc. */ 9 #define OERRLEN 64 /* compatibility; used in _stat etc. */ 10 11 char errbuf[ERRMAX]; 12 ulong nofunc; 13 14 #include "/sys/src/libc/9syscall/sys.h" 15 16 17 char* sysctab[] = 18 { 19 [SYSR1] "Running", 20 [_ERRSTR] "_errstr", 21 [BIND] "Bind", 22 [CHDIR] "Chdir", 23 [CLOSE] "Close", 24 [DUP] "Dup", 25 [ALARM] "Alarm", 26 [EXEC] "Exec", 27 [EXITS] "Exits", 28 [_FSESSION] "_Fsession", 29 [FAUTH] "Fauth", 30 [_FSTAT] "_fstat", 31 [SEGBRK] "Segbrk", 32 [MOUNT] "Mount", 33 [OPEN] "Open", 34 [_READ] "_Read", 35 [OSEEK] "Oseek", 36 [SLEEP] "Sleep", 37 [_STAT] "_Stat", 38 [RFORK] "Rfork", 39 [_WRITE] "_Write", 40 [PIPE] "Pipe", 41 [CREATE] "Create", 42 [FD2PATH] "Fd2path", 43 [BRK_] "Brk_", 44 [REMOVE] "Remove", 45 [_WSTAT] "_Wstat", 46 [_FWSTAT] "_Fwstat", 47 [NOTIFY] "Notify", 48 [NOTED] "Noted", 49 [SEGATTACH] "Segattach", 50 [SEGDETACH] "Segdetach", 51 [SEGFREE] "Segfree", 52 [SEGFLUSH] "Segflush", 53 [RENDEZVOUS] "Rendezvous", 54 [UNMOUNT] "Unmount", 55 [_WAIT] "_Wait", 56 [SEEK] "Seek", 57 [FVERSION] "Fversion", 58 [ERRSTR] "Errstr", 59 [STAT] "Stat", 60 [FSTAT] "Fstat", 61 [WSTAT] "Wstat", 62 [FWSTAT] "Fwstat", 63 [PREAD] "Pread", 64 [PWRITE] "Pwrite", 65 [AWAIT] "Await", 66 }; 67 68 void 69 sys1(void) 70 { 71 Bprint(bioout, "no system call %s\n", sysctab[reg.r[1]]); 72 exits(0); 73 } 74 75 void 76 sys_errstr(void) 77 { 78 ulong str; 79 80 str = getmem_w(reg.r[13]+4); 81 if(sysdbg) 82 itrace("errstr(0x%lux)", str); 83 84 memio(errbuf, str, OERRLEN, MemWrite); 85 strcpy(errbuf, "no error"); 86 reg.r[REGRET] = 0; 87 88 } 89 90 void 91 syserrstr(void) 92 { 93 ulong str; 94 int n; 95 96 str = getmem_w(reg.r[13]+4); 97 n = getmem_w(reg.r[13]+8); 98 if(sysdbg) 99 itrace("errstr(0x%lux, 0x%lux)", str, n); 100 101 if(n > strlen(errbuf)+1) 102 n = strlen(errbuf)+1; 103 memio(errbuf, str, n, MemWrite); 104 strcpy(errbuf, "no error"); 105 reg.r[REGRET] = n; 106 107 } 108 void 109 sysbind(void) 110 { 111 ulong pname, pold, flags; 112 char name[1024], old[1024]; 113 int n; 114 115 pname = getmem_w(reg.r[13]+4); 116 pold = getmem_w(reg.r[13]+8); 117 flags = getmem_w(reg.r[13]+12); 118 memio(name, pname, sizeof(name), MemReadstring); 119 memio(old, pold, sizeof(old), MemReadstring); 120 if(sysdbg) 121 itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, name, old, old, flags); 122 123 n = bind(name, old, flags); 124 if(n < 0) 125 errstr(errbuf, sizeof errbuf); 126 127 reg.r[REGRET] = n; 128 } 129 130 void 131 sysfd2path(void) 132 { 133 int n; 134 uint fd; 135 ulong str; 136 char buf[1024]; 137 138 fd = getmem_w(reg.r[13]+4); 139 str = getmem_w(reg.r[13]+8); 140 n = getmem_w(reg.r[13]+12); 141 if(sysdbg) 142 itrace("fd2path(0x%lux, 0x%lux, 0x%lux)", fd, str, n); 143 reg.r[1] = -1; 144 if(n > sizeof buf){ 145 strcpy(errbuf, "buffer too big"); 146 return; 147 } 148 n = fd2path(fd, buf, sizeof buf); 149 if(n < 0) 150 errstr(buf, sizeof buf); 151 else 152 memio(errbuf, str, n, MemWrite); 153 reg.r[REGRET] = n; 154 155 } 156 157 void 158 syschdir(void) 159 { 160 char file[1024]; 161 int n; 162 ulong name; 163 164 name = getmem_w(reg.r[13]+4); 165 memio(file, name, sizeof(file), MemReadstring); 166 if(sysdbg) 167 itrace("chdir(0x%lux='%s', 0x%lux)", name, file); 168 169 n = chdir(file); 170 if(n < 0) 171 errstr(errbuf, sizeof errbuf); 172 173 reg.r[REGRET] = n; 174 } 175 176 void 177 sysclose(void) 178 { 179 int n; 180 ulong fd; 181 182 fd = getmem_w(reg.r[13]+4); 183 if(sysdbg) 184 itrace("close(%d)", fd); 185 186 n = close(fd); 187 if(n < 0) 188 errstr(errbuf, sizeof errbuf); 189 reg.r[REGRET] = n; 190 } 191 192 void 193 sysdup(void) 194 { 195 int oldfd, newfd; 196 int n; 197 198 oldfd = getmem_w(reg.r[13]+4); 199 newfd = getmem_w(reg.r[13]+8); 200 if(sysdbg) 201 itrace("dup(%d, %d)", oldfd, newfd); 202 203 n = dup(oldfd, newfd); 204 if(n < 0) 205 errstr(errbuf, sizeof errbuf); 206 reg.r[REGRET] = n; 207 } 208 209 void 210 sysexits(void) 211 { 212 char buf[OERRLEN]; 213 ulong str; 214 215 str = getmem_w(reg.r[13]+4); 216 if(sysdbg) 217 itrace("exits(0x%lux)", str); 218 219 count = 1; 220 if(str != 0) { 221 memio(buf, str, sizeof buf, MemRead); 222 Bprint(bioout, "exits(%s)\n", buf); 223 } 224 else 225 Bprint(bioout, "exits(0)\n"); 226 } 227 228 void 229 sysopen(void) 230 { 231 char file[1024]; 232 int n; 233 ulong mode, name; 234 235 name = getmem_w(reg.r[13]+4); 236 mode = getmem_w(reg.r[13]+8); 237 memio(file, name, sizeof(file), MemReadstring); 238 239 n = open(file, mode); 240 if(n < 0) 241 errstr(errbuf, sizeof errbuf); 242 243 if(sysdbg) 244 itrace("open(0x%lux='%s', 0x%lux) = %d", name, file, mode, n); 245 246 reg.r[REGRET] = n; 247 }; 248 249 250 void 251 sysread(vlong offset) 252 { 253 int fd; 254 ulong size, a; 255 char *buf, *p; 256 int n, cnt, c; 257 258 fd = getmem_w(reg.r[13]+4); 259 a = getmem_w(reg.r[13]+8); 260 size = getmem_w(reg.r[13]+12); 261 262 buf = emalloc(size); 263 if(fd == 0) { 264 print("\nstdin>>"); 265 p = buf; 266 n = 0; 267 cnt = size; 268 while(cnt) { 269 c = Bgetc(bin); 270 if(c <= 0) 271 break; 272 *p++ = c; 273 n++; 274 cnt--; 275 if(c == '\n') 276 break; 277 } 278 } 279 else 280 n = pread(fd, buf, size, offset); 281 282 if(n < 0) 283 errstr(errbuf, sizeof errbuf); 284 else 285 memio(buf, a, n, MemWrite); 286 287 if(sysdbg) 288 itrace("read(%d, 0x%lux, %d, 0x%llx) = %d", fd, a, size, offset, n); 289 290 free(buf); 291 reg.r[REGRET] = n; 292 } 293 294 void 295 sys_read(void) 296 { 297 sysread(-1LL); 298 } 299 300 void 301 syspread(void) 302 { 303 sysread(getmem_v(reg.r[13]+16)); 304 } 305 306 void 307 sysseek(void) 308 { 309 int fd; 310 ulong mode; 311 ulong retp; 312 vlong v; 313 314 retp = getmem_w(reg.r[13]+4); 315 fd = getmem_w(reg.r[13]+8); 316 v = getmem_v(reg.r[13]+16); 317 mode = getmem_w(reg.r[13]+20); 318 if(sysdbg) 319 itrace("seek(%d, %lld, %d)", fd, v, mode); 320 321 v = seek(fd, v, mode); 322 if(v < 0) 323 errstr(errbuf, sizeof errbuf); 324 325 putmem_v(retp, v); 326 } 327 328 void 329 sysoseek(void) 330 { 331 int fd, n; 332 ulong off, mode; 333 334 fd = getmem_w(reg.r[13]+4); 335 off = getmem_w(reg.r[13]+8); 336 mode = getmem_w(reg.r[13]+12); 337 if(sysdbg) 338 itrace("seek(%d, %lud, %d)", fd, off, mode); 339 340 n = seek(fd, off, mode); 341 if(n < 0) 342 errstr(errbuf, sizeof errbuf); 343 344 reg.r[REGRET] = n; 345 } 346 347 void 348 syssleep(void) 349 { 350 ulong len; 351 int n; 352 353 len = getmem_w(reg.r[13]+4); 354 if(sysdbg) 355 itrace("sleep(%d)", len); 356 357 n = sleep(len); 358 if(n < 0) 359 errstr(errbuf, sizeof errbuf); 360 361 reg.r[REGRET] = n; 362 } 363 364 void 365 sys_stat(void) 366 { 367 char nambuf[1024]; 368 char buf[ODIRLEN]; 369 ulong edir, name; 370 extern int _stat(char*, char*); /* old system call */ 371 int n; 372 373 name = getmem_w(reg.r[13]+4); 374 edir = getmem_w(reg.r[13]+8); 375 memio(nambuf, name, sizeof(nambuf), MemReadstring); 376 if(sysdbg) 377 itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir); 378 379 n = _stat(nambuf, buf); 380 if(n < 0) 381 errstr(errbuf, sizeof errbuf); 382 else 383 memio(buf, edir, ODIRLEN, MemWrite); 384 385 reg.r[REGRET] = n; 386 } 387 388 void 389 sysstat(void) 390 { 391 char nambuf[1024]; 392 uchar buf[STATMAX]; 393 ulong edir, name; 394 int n; 395 396 name = getmem_w(reg.r[13]+4); 397 edir = getmem_w(reg.r[13]+8); 398 n = getmem_w(reg.r[13]+12); 399 memio(nambuf, name, sizeof(nambuf), MemReadstring); 400 if(sysdbg) 401 itrace("stat(0x%lux='%s', 0x%lux, 0x%lux)", name, nambuf, edir, n); 402 if(n > sizeof buf) 403 errstr(errbuf, sizeof errbuf); 404 else{ 405 n = stat(nambuf, buf, n); 406 if(n < 0) 407 errstr(errbuf, sizeof errbuf); 408 else 409 memio((char*)buf, edir, n, MemWrite); 410 } 411 reg.r[REGRET] = n; 412 } 413 414 void 415 sys_fstat(void) 416 { 417 char buf[ODIRLEN]; 418 extern int _fstat(int, char*); /* old system call */ 419 ulong edir; 420 int n, fd; 421 422 fd = getmem_w(reg.r[13]+4); 423 edir = getmem_w(reg.r[13]+8); 424 if(sysdbg) 425 itrace("fstat(%d, 0x%lux)", fd, edir); 426 427 n = _fstat(fd, buf); 428 if(n < 0) 429 errstr(errbuf, sizeof errbuf); 430 else 431 memio(buf, edir, ODIRLEN, MemWrite); 432 433 reg.r[REGRET] = n; 434 } 435 436 void 437 sysfstat(void) 438 { 439 uchar buf[STATMAX]; 440 ulong edir; 441 int n, fd; 442 443 fd = getmem_w(reg.r[13]+4); 444 edir = getmem_w(reg.r[13]+8); 445 n = getmem_w(reg.r[13]+12); 446 if(sysdbg) 447 itrace("fstat(%d, 0x%lux, 0x%lux)", fd, edir, n); 448 449 reg.r[REGRET] = -1; 450 if(n > sizeof buf){ 451 strcpy(errbuf, "stat buffer too big"); 452 return; 453 } 454 n = fstat(fd, buf, n); 455 if(n < 0) 456 errstr(errbuf, sizeof errbuf); 457 else 458 memio((char*)buf, edir, n, MemWrite); 459 reg.r[REGRET] = n; 460 } 461 462 void 463 syswrite(vlong offset) 464 { 465 int fd; 466 ulong size, a; 467 char *buf; 468 int n; 469 470 fd = getmem_w(reg.r[13]+4); 471 a = getmem_w(reg.r[13]+8); 472 size = getmem_w(reg.r[13]+12); 473 474 Bflush(bioout); 475 buf = memio(0, a, size, MemRead); 476 n = pwrite(fd, buf, size, offset); 477 if(n < 0) 478 errstr(errbuf, sizeof errbuf); 479 480 if(sysdbg) 481 itrace("write(%d, %lux, %d, 0x%llx) = %d", fd, a, size, offset, n); 482 483 free(buf); 484 485 reg.r[REGRET] = n; 486 } 487 488 void 489 sys_write(void) 490 { 491 syswrite(-1LL); 492 } 493 494 void 495 syspwrite(void) 496 { 497 syswrite(getmem_v(reg.r[13]+16)); 498 } 499 500 void 501 syspipe(void) 502 { 503 int n, p[2]; 504 ulong fd; 505 506 fd = getmem_w(reg.r[13]+4); 507 if(sysdbg) 508 itrace("pipe(%lux)", fd); 509 510 n = pipe(p); 511 if(n < 0) 512 errstr(errbuf, sizeof errbuf); 513 else { 514 putmem_w(fd, p[0]); 515 putmem_w(fd+4, p[1]); 516 } 517 reg.r[REGRET] = n; 518 } 519 520 void 521 syscreate(void) 522 { 523 char file[1024]; 524 int n; 525 ulong mode, name, perm; 526 527 name = getmem_w(reg.r[13]+4); 528 mode = getmem_w(reg.r[13]+8); 529 perm = getmem_w(reg.r[13]+12); 530 memio(file, name, sizeof(file), MemReadstring); 531 if(sysdbg) 532 itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm); 533 534 n = create(file, mode, perm); 535 if(n < 0) 536 errstr(errbuf, sizeof errbuf); 537 538 reg.r[REGRET] = n; 539 } 540 541 void 542 sysbrk_(void) 543 { 544 ulong addr, osize, nsize; 545 Segment *s; 546 547 addr = getmem_w(reg.r[13]+4); 548 if(sysdbg) 549 itrace("brk_(0x%lux)", addr); 550 551 reg.r[REGRET] = -1; 552 if(addr < memory.seg[Data].base+datasize) { 553 strcpy(errbuf, "address below segment"); 554 return; 555 } 556 if(addr > memory.seg[Stack].base) { 557 strcpy(errbuf, "segment too big"); 558 return; 559 } 560 s = &memory.seg[Bss]; 561 if(addr > s->end) { 562 osize = ((s->end-s->base)/BY2PG)*sizeof(uchar*); 563 addr = ((addr)+(BY2PG-1))&~(BY2PG-1); 564 s->end = addr; 565 nsize = ((s->end-s->base)/BY2PG)*sizeof(uchar*); 566 s->table = erealloc(s->table, osize, nsize); 567 } 568 569 reg.r[REGRET] = 0; 570 } 571 572 void 573 sysremove(void) 574 { 575 char nambuf[1024]; 576 ulong name; 577 int n; 578 579 name = getmem_w(reg.r[13]+4); 580 memio(nambuf, name, sizeof(nambuf), MemReadstring); 581 if(sysdbg) 582 itrace("remove(0x%lux='%s')", name, nambuf); 583 584 n = remove(nambuf); 585 if(n < 0) 586 errstr(errbuf, sizeof errbuf); 587 reg.r[REGRET] = n; 588 } 589 590 void 591 sysnotify(void) 592 { 593 nofunc = getmem_w(reg.r[13]+4); 594 if(sysdbg) 595 itrace("notify(0x%lux)\n", nofunc); 596 597 reg.r[REGRET] = 0; 598 } 599 600 void 601 sys_wait(void) 602 { 603 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 604 exits(0); 605 } 606 void 607 sysawait(void) 608 { 609 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 610 exits(0); 611 } 612 void 613 sysrfork(void) 614 { 615 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 616 exits(0); 617 } 618 void 619 syswstat(void) 620 { 621 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 622 exits(0); 623 } 624 void 625 sys_wstat(void) 626 { 627 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 628 exits(0); 629 } 630 void 631 sysfwstat(void) 632 { 633 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 634 exits(0); 635 } 636 void 637 sys_fwstat(void) 638 { 639 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 640 exits(0); 641 } 642 void 643 sysnoted(void) 644 { 645 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 646 exits(0); 647 } 648 void 649 syssegattach(void) 650 { 651 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 652 exits(0); 653 } 654 void 655 syssegdetach(void) 656 { 657 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 658 exits(0); 659 } 660 void 661 syssegfree(void) 662 { 663 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 664 exits(0); 665 } 666 void 667 syssegflush(void) 668 { 669 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 670 exits(0); 671 } 672 void 673 sysrendezvous(void) 674 { 675 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 676 exits(0); 677 } 678 void 679 sysunmount(void) 680 { 681 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 682 exits(0); 683 } 684 void 685 sysfork(void) 686 { 687 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 688 exits(0); 689 } 690 void 691 sysforkpgrp(void) 692 { 693 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 694 exits(0); 695 } 696 void 697 syssegbrk(void) 698 { 699 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 700 exits(0); 701 } 702 void 703 sysmount(void) 704 { 705 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 706 exits(0); 707 } 708 void 709 sysalarm(void) 710 { 711 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 712 exits(0); 713 } 714 void 715 sysexec(void) 716 { 717 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 718 exits(0); 719 } 720 void 721 sys_fsession(void) 722 { 723 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 724 exits(0); 725 } 726 void 727 sysfauth(void) 728 { 729 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 730 exits(0); 731 } 732 void 733 sysfversion(void) 734 { 735 Bprint(bioout, "No system call %s\n", sysctab[reg.r[REGARG]]); 736 exits(0); 737 } 738 739 void (*systab[])(void) = 740 { 741 [SYSR1] sys1, 742 [_ERRSTR] sys_errstr, 743 [BIND] sysbind, 744 [CHDIR] syschdir, 745 [CLOSE] sysclose, 746 [DUP] sysdup, 747 [ALARM] sysalarm, 748 [EXEC] sysexec, 749 [EXITS] sysexits, 750 [_FSESSION] sys_fsession, 751 [FAUTH] sysfauth, 752 [_FSTAT] sys_fstat, 753 [SEGBRK] syssegbrk, 754 [MOUNT] sysmount, 755 [OPEN] sysopen, 756 [_READ] sys_read, 757 [OSEEK] sysoseek, 758 [SLEEP] syssleep, 759 [_STAT] sys_stat, 760 [RFORK] sysrfork, 761 [_WRITE] sys_write, 762 [PIPE] syspipe, 763 [CREATE] syscreate, 764 [FD2PATH] sysfd2path, 765 [BRK_] sysbrk_, 766 [REMOVE] sysremove, 767 [_WSTAT] sys_wstat, 768 [_FWSTAT] sys_fwstat, 769 [NOTIFY] sysnotify, 770 [NOTED] sysnoted, 771 [SEGATTACH] syssegattach, 772 [SEGDETACH] syssegdetach, 773 [SEGFREE] syssegfree, 774 [SEGFLUSH] syssegflush, 775 [RENDEZVOUS] sysrendezvous, 776 [UNMOUNT] sysunmount, 777 [_WAIT] sys_wait, 778 [SEEK] sysseek, 779 [FVERSION] sysfversion, 780 [ERRSTR] syserrstr, 781 [STAT] sysstat, 782 [FSTAT] sysfstat, 783 [WSTAT] syswstat, 784 [FWSTAT] sysfwstat, 785 [PREAD] syspread, 786 [PWRITE] syspwrite, 787 [AWAIT] sysawait, 788 }; 789 790 void 791 Ssyscall(ulong) 792 { 793 int call; 794 795 call = reg.r[REGARG]; 796 if(call < 0 || call >= nelem(systab) || systab[call] == nil) { 797 Bprint(bioout, "bad system call %d (%#ux)\n", call, call); 798 dumpreg(); 799 Bflush(bioout); 800 return; 801 } 802 803 if(trace) 804 itrace("SWI\t%s", sysctab[call]); 805 (*systab[call])(); 806 Bflush(bioout); 807 } 808