/[gxemul]/trunk/src/useremul.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/useremul.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: useremul.c,v 1.45 2005/03/23 08:45:51 debug Exp $   *  $Id: useremul.c,v 1.74 2007/02/10 14:04:51 debug Exp $
29   *   *
30   *  Userland (syscall) emulation.   *  Userland (syscall) emulation.
31   *   *
32   *  TODO:   *  TODO:
33   *   *
34   *      NetBSD/pmax:   *      environment passing for most emulation modes
35   *              environment passing   *
36   *              more syscalls   *      implement more syscalls
37   *   *
38   *      32-bit vs 64-bit problems? MIPS n32, o32, n64?   *      32-bit vs 64-bit problems? MIPS n32, o32, n64?
39   *   *
40   *      Dynamic ELFs?   *      Dynamic ELFs?
41   *   *
42   *      Try to prefix "/emul/mips/" or similar to all filenames,   *      Try to prefix "/emul/mips/" or similar to all filenames,
43   *              and only if that fails, try the given filename   *              and only if that fails, try the given filename.
44     *              Read this setting from an environment variable, and only
45     *              if there is none, fall back to hardcoded string.
46   *   *
47   *      Automagic errno translation?   *      Automagic errno translation!
48   *   *
49   *      Memory allocation? mmap etc.   *      Memory allocation? mmap, munmap, mprotect, etc.
50     *              mprotect = unmap in dyntrans...
51   *   *
52   *      File descriptor (0,1,2) assumptions?   *      File descriptor (0,1,2) assumptions? Find and fix these?
53   *   *
54   *   *
55   *  This module needs more cleanup.   *  This module needs more cleanup.
56   *  -------------------------------   *  -------------------------------
57   *   *
58   *   *
59   *  NOTE:  This module (useremul.c) is just a quick hack to see if   *  NOTE:  This module (useremul.c) is just a quick hack so far, to see if
60   *         userland emulation works at all.   *         userland emulation works at all. It only works for Hello World-
61     *         style programs compiled for FreeBSD/alpha or NetBSD/mips.
62   */   */
63    
64  #include <errno.h>  #include <errno.h>
# Line 67  Line 71 
71  #include <sys/time.h>  #include <sys/time.h>
72  #include <sys/stat.h>  #include <sys/stat.h>
73  #include <sys/socket.h>  #include <sys/socket.h>
74    #include <sys/resource.h>
75  #include <time.h>  #include <time.h>
76    
77  #include "cpu.h"  #include "cpu.h"
# Line 132  void useremul__freebsd_setup(struct cpu Line 137  void useremul__freebsd_setup(struct cpu
137  {  {
138          debug("useremul__freebsd_setup(): TODO\n");          debug("useremul__freebsd_setup(): TODO\n");
139    
140          if (cpu->machine->arch != ARCH_ALPHA) {          switch (cpu->machine->arch) {
141            case ARCH_ALPHA:
142                    /*  According to FreeBSD's /usr/src/lib/csu/alpha/crt1.c:  */
143                    /*  a0 = char **ap                                         */
144                    /*  a1 = void (*cleanup)(void)          from shared loader */
145                    /*  a2 = struct Struct_Obj_Entry *obj   from shared loader */
146                    /*  a3 = struct ps_strings *ps_strings                     */
147                    cpu->cd.alpha.r[ALPHA_A0] = 0;
148                    cpu->cd.alpha.r[ALPHA_A1] = 0;
149                    cpu->cd.alpha.r[ALPHA_A2] = 0;
150                    cpu->cd.alpha.r[ALPHA_A3] = 0;
151    
152                    /*  What is a good stack pointer? TODO  */
153                    cpu->cd.alpha.r[ALPHA_SP] = 0x120000000ULL +
154                        1048576 * cpu->machine->physical_ram_in_mb - 1024;
155                    break;
156            default:
157                  fatal("non-Alpha not yet implemented for freebsd emul.\n");                  fatal("non-Alpha not yet implemented for freebsd emul.\n");
158                  exit(1);                  exit(1);
159          }          }
   
         /*  What is a good stack pointer? TODO  */  
         /*  cpu->cd.alpha.gpr[...] = ...  */  
160  }  }
161    
162    
# Line 186  void useremul__netbsd_setup(struct cpu * Line 204  void useremul__netbsd_setup(struct cpu *
204                  /*  The userland stack:  */                  /*  The userland stack:  */
205                  cpu->cd.mips.gpr[MIPS_GPR_SP] = stack_top - stack_margin;                  cpu->cd.mips.gpr[MIPS_GPR_SP] = stack_top - stack_margin;
206                  add_symbol_name(&cpu->machine->symbol_context,                  add_symbol_name(&cpu->machine->symbol_context,
207                      stack_top - stacksize, stacksize, "userstack", 0);                      stack_top - stacksize, stacksize, "userstack", 0, 0);
208    
209                  /*  Stack contents:  (TODO: is this correct?)  */                  /*  Stack contents:  (TODO: is this correct?)  */
210                  store_32bit_word(cpu, stack_top - stack_margin, argc);                  store_32bit_word(cpu, stack_top - stack_margin, argc);
# Line 218  void useremul__netbsd_setup(struct cpu * Line 236  void useremul__netbsd_setup(struct cpu *
236                  }                  }
237                  break;                  break;
238    
239            case ARCH_ALPHA:
240                    debug("useremul__netbsd_setup(): ALPHA: TODO\n");
241                    break;
242    
243            case ARCH_ARM:
244                    debug("useremul__netbsd_setup(): ARM: TODO\n");
245                    break;
246    
247          case ARCH_PPC:          case ARCH_PPC:
248                  debug("useremul__netbsd_setup(): TODO\n");                  debug("useremul__netbsd_setup(): PPC: TODO\n");
249    
250                  /*  What is a good stack pointer? TODO  */                  /*  What is a good stack pointer? TODO  */
251                  cpu->cd.ppc.gpr[1] = 0x7ffff000ULL;                  cpu->cd.ppc.gpr[1] = 0x7ffff000ULL;
252    
253                  break;                  break;
254    
255            case ARCH_SH:
256                    debug("useremul__netbsd_setup(): SH: TODO\n");
257                    break;
258    
259          default:          default:
260                  fatal("useremul__netbsd_setup(): unimplemented arch\n");                  fatal("useremul__netbsd_setup(): unimplemented arch\n");
261                  exit(1);                  exit(1);
# Line 255  void useremul__ultrix_setup(struct cpu * Line 285  void useremul__ultrix_setup(struct cpu *
285          /*  The userland stack:  */          /*  The userland stack:  */
286          cpu->cd.mips.gpr[MIPS_GPR_SP] = stack_top - stack_margin;          cpu->cd.mips.gpr[MIPS_GPR_SP] = stack_top - stack_margin;
287          add_symbol_name(&cpu->machine->symbol_context,          add_symbol_name(&cpu->machine->symbol_context,
288              stack_top - stacksize, stacksize, "userstack", 0);              stack_top - stacksize, stacksize, "userstack", 0, 0);
289    
290          /*  Stack contents:  (TODO: is this correct?)  */          /*  Stack contents:  (TODO: is this correct?)  */
291          store_32bit_word(cpu, stack_top - stack_margin, argc);          store_32bit_word(cpu, stack_top - stack_margin, argc);
# Line 334  static unsigned char *get_userland_strin Line 364  static unsigned char *get_userland_strin
364   *  TODO: combine this with get_userland_string() in some way   *  TODO: combine this with get_userland_string() in some way
365   */   */
366  static unsigned char *get_userland_buf(struct cpu *cpu,  static unsigned char *get_userland_buf(struct cpu *cpu,
367          uint64_t baseaddr, int len)          uint64_t baseaddr, uint64_t len)
368  {  {
369          unsigned char *charbuf;          unsigned char *charbuf;
370          int i;          size_t i;
371    
372          charbuf = malloc(len);          charbuf = malloc(len);
373          if (charbuf == NULL) {          if (charbuf == NULL) {
374                  fprintf(stderr, "get_userland_buf(): out of memory (trying"                  fprintf(stderr, "get_userland_buf(): out of memory (trying"
375                      " to allocate %i bytes)\n", len);                      " to allocate %lli bytes)\n", (long long)len);
376                  exit(1);                  exit(1);
377          }          }
378    
# Line 375  void useremul_syscall(struct cpu *cpu, u Line 405  void useremul_syscall(struct cpu *cpu, u
405  }  }
406    
407    
408    /*****************************************************************************/
409    
410    
411    /*
412     *  useremul_exit():
413     */
414    int useremul_exit(struct cpu *cpu, uint64_t arg0)
415    {
416            debug("[ exit(%i) ]\n", (int)arg0);
417            cpu->running = 0;
418            cpu->machine->exit_without_entering_debugger = 1;
419            return 0;
420    }
421    
422    
423    /*
424     *  useremul_write():
425     */
426    int64_t useremul_write(struct cpu *cpu, int64_t *errnop,
427            uint64_t arg0, uint64_t arg1, uint64_t arg2)
428    {
429            int64_t res = 0;
430            *errnop = 0;
431            debug("[ write(%i,0x%llx,%lli) ]\n",
432                (int)arg0, (long long)arg1, (long long)arg2);
433            if (arg2 != 0) {
434                    unsigned char *cp = get_userland_buf(cpu, arg1, arg2);
435                    res = write(arg0, cp, arg2);
436                    if (res < 0)
437                            *errnop = errno;
438                    free(cp);
439            }
440            return res;
441    }
442    
443    
444    /*
445     *  useremul_break():
446     */
447    int64_t useremul_break(struct cpu *cpu, uint64_t arg0)
448    {
449            debug("[ break(0x%llx): TODO ]\n", (long long)arg0);
450    
451            /*  TODO  */
452            return 0;
453    }
454    
455    
456    /*
457     *  useremul_getpid():
458     */
459    int64_t useremul_getpid(struct cpu *cpu)
460    {
461            int64_t pid = getpid();
462            debug("[ getpid(): %lli ]\n", (long long)pid);
463            return pid;
464    }
465    
466    
467    /*
468     *  useremul_getuid():
469     */
470    int64_t useremul_getuid(struct cpu *cpu)
471    {
472            int64_t uid = getuid();
473            debug("[ getuid(): %lli ]\n", (long long)uid);
474            return uid;
475    }
476    
477    
478    /*
479     *  useremul_getegid():
480     */
481    int64_t useremul_getegid(struct cpu *cpu)
482    {
483            int64_t egid = getegid();
484            debug("[ getegid(): %lli ]\n", (long long)egid);
485            return egid;
486    }
487    
488    
489    /*
490     *  useremul_getgid():
491     */
492    int64_t useremul_getgid(struct cpu *cpu)
493    {
494            int64_t gid = getgid();
495            debug("[ getgid(): %lli ]\n", (long long)gid);
496            return gid;
497    }
498    
499    
500    /*
501     *  useremul_sync():
502     */
503    int useremul_sync(struct cpu *cpu)
504    {
505            debug("[ sync() ]\n");
506            sync();
507            return 0;
508    }
509    
510    
511    /*
512     *  useremul_readlink():
513     */
514    int64_t useremul_readlink(struct cpu *cpu, int64_t *errnop,
515            uint64_t arg0, uint64_t arg1, int64_t arg2)
516    {
517            int64_t res = 0;
518            unsigned char *charbuf = get_userland_string(cpu, arg0);
519            unsigned char *buf2;
520    
521            debug("[ readlink(\"%s\",0x%llx,%lli) ]\n",
522                charbuf, (long long)arg1, (long long)arg2);
523            if (arg2 == 0 || arg2 > 150000) {
524                    fprintf(stderr, "[ useremul_readlink(): TODO ]\n");
525                    exit(1);
526            }
527    
528            buf2 = malloc(arg2);
529            if (buf2 == NULL) {
530                    fprintf(stderr, "[ useremul_readlink(): out of memory ]\n");
531                    exit(1);
532            }
533            res = readlink((char *)charbuf, (char *)buf2, arg2);
534            buf2[arg2-1] = '\0';
535            if (res < 0)
536                    *errnop = errno;
537            else
538                    store_string(cpu, arg1, (char *)buf2);
539            free(buf2);
540            free(charbuf);
541            return res;
542    }
543    
544    
545    /*
546     *  useremul_getrusage():
547     */
548    int64_t useremul_getrusage(struct cpu *cpu, int64_t *errnop,
549            uint64_t arg0, uint64_t arg1)
550    {
551            int64_t res;
552            struct rusage rusage;
553            debug("[ getrusage(%i,0x%llx) ]\n", (int)arg0, (long long)arg1);
554            res = getrusage(arg0, &rusage);
555    
556            fatal("TODO: convert rusage into emulated memory!\n");
557            store_64bit_word(cpu, arg1 +  0, rusage.ru_utime.tv_sec);
558            store_64bit_word(cpu, arg1 +  8, rusage.ru_utime.tv_usec);
559            store_64bit_word(cpu, arg1 + 16, rusage.ru_stime.tv_sec);
560            store_64bit_word(cpu, arg1 + 24, rusage.ru_stime.tv_usec);
561    
562            return res;
563    }
564    
565    
566    /*
567     *  useremul_fstat():
568     */
569    int64_t useremul_fstat(struct cpu *cpu, int64_t *errnop,
570            int64_t arg0, uint64_t arg1)
571    {
572            int64_t res;
573            struct stat sb;
574            debug("[ fstat(%i,0x%llx) ]\n", (int)arg0, (long long)arg1);
575            res = fstat(arg0, &sb);
576            if (res < 0)
577                    *errnop = errno;
578            else {
579                    fatal("TODO: convert sb into emulated memory!\n");
580    
581    /*  NOTE: FreeBSD/alpha only  */
582    
583                    store_32bit_word(cpu, arg1 + 0, sb.st_dev);
584                    store_32bit_word(cpu, arg1 + 4, sb.st_ino);
585    /*              store_16bit_word(cpu, arg1 + 8, sb.st_mode);
586    */              store_16bit_word(cpu, arg1 + 10, sb.st_nlink);
587                    store_32bit_word(cpu, arg1 + 12, sb.st_uid);
588                    store_32bit_word(cpu, arg1 + 16, sb.st_gid);
589                    store_32bit_word(cpu, arg1 + 20, sb.st_rdev);
590    #if 0
591                    store_64bit_word(cpu, arg1 + 24, sb.st_atimespec.tv_sec);
592                    store_64bit_word(cpu, arg1 + 32, sb.st_atimespec.tv_nsec);
593                    store_64bit_word(cpu, arg1 + 40, sb.st_mtimespec.tv_sec);
594                    store_64bit_word(cpu, arg1 + 48, sb.st_mtimespec.tv_nsec);
595                    store_64bit_word(cpu, arg1 + 56, sb.st_ctimespec.tv_sec);
596                    store_64bit_word(cpu, arg1 + 64, sb.st_ctimespec.tv_nsec);
597    
598                    store_64bit_word(cpu, arg1 + 72, sb.st_size);
599                    store_64bit_word(cpu, arg1 + 80, sb.st_blocks);
600                    store_64bit_word(cpu, arg1 + 88, sb.st_blksize);
601                    store_64bit_word(cpu, arg1 + 92, sb.st_flags);
602                    store_64bit_word(cpu, arg1 + 96, sb.st_gen);
603    #endif
604            }
605            return res;
606    }
607    
608    
609    /*
610     *  useremul_mmap():
611     */
612    int64_t useremul_mmap(struct cpu *cpu, int64_t *errnop,
613            uint64_t arg0, int64_t arg1, int64_t arg2,
614            int64_t arg3, int64_t arg4, uint64_t arg5)
615    {
616            int64_t res = 0;
617    
618            /*  arg0..5: addr, len, prot, flags, fd, offset  */
619            debug("[ mmap(0x%llx,%lli,%i,%i,%i,%lli) ]\n",
620                (long long)arg0, (long long)arg1,
621                (int)arg2, (int)arg3, (int)arg4, (long long)arg5);
622    
623            if (arg4 != -1) {
624                    fatal("[ useremul_mmap(): fd != -1: TODO ]\n");
625                    cpu->running = 0;
626                    return 0;
627            }
628    
629            /*  Anonymous allocation.  */
630            if (arg0 != 0) {
631                    fatal("[ useremul_mmap(): addr != 0: TODO ]\n");
632                    cpu->running = 0;
633                    return 0;
634            }
635    
636            fatal("[ useremul_mmap(): TODO ]\n");
637    
638    res = 0x18000000ULL;
639    
640            return res;
641    }
642    
643    
644    /*****************************************************************************/
645    
646    
647  /*  /*
648   *  useremul__freebsd():   *  useremul__freebsd():
649   *   *
650   *  FreeBSD syscall emulation.   *  FreeBSD/Alpha syscall emulation.
651   *   *
652   *  TODO: How to make this work nicely with non-Alpha archs.   *  TODO: How to make this work nicely with non-Alpha archs.
653   */   */
654  static void useremul__freebsd(struct cpu *cpu, uint32_t code)  static void useremul__freebsd(struct cpu *cpu, uint32_t code)
655  {  {
 #if 0  
         unsigned char *cp;  
656          int nr;          int nr;
657          uint64_t arg0, arg1, arg2, arg3;          int64_t res = 0, err = 0;
658            uint64_t arg0, arg1, arg2, arg3, arg4, arg5;
659    
660          nr = cpu->cd.ppc.gpr[0];          nr = cpu->cd.alpha.r[ALPHA_V0];
661          arg0 = cpu->cd.ppc.gpr[3];          arg0 = cpu->cd.alpha.r[ALPHA_A0];
662          arg1 = cpu->cd.ppc.gpr[4];          arg1 = cpu->cd.alpha.r[ALPHA_A1];
663          arg2 = cpu->cd.ppc.gpr[5];          arg2 = cpu->cd.alpha.r[ALPHA_A2];
664          arg3 = cpu->cd.ppc.gpr[6];          arg3 = cpu->cd.alpha.r[ALPHA_A3];
665            arg4 = cpu->cd.alpha.r[ALPHA_A4];
666            arg5 = cpu->cd.alpha.r[ALPHA_A5];
667    
668            if (nr == 198) {
669                    /*  ___syscall  */
670                    nr = arg0;
671                    arg0 = arg1;
672                    arg1 = arg2;
673                    arg2 = arg3;
674                    arg3 = arg4;
675                    arg4 = arg5;
676                    /*  TODO: stack arguments  */
677            }
678    
679          switch (nr) {          switch (nr) {
680    
681          case LINUX_PPC_SYS_exit:          case 1: res = useremul_exit(cpu, arg0);
                 debug("[ exit(%i) ]\n", (int)arg0);  
                 cpu->running = 0;  
682                  break;                  break;
683    
684          case LINUX_PPC_SYS_write:          case 4: res = useremul_write(cpu, &err, arg0, arg1, arg2);
                 debug("[ write(%i,0x%llx,%lli) ]\n",  
                     (int)arg0, (long long)arg1, (long long)arg2);  
                 cp = get_userland_buf(cpu, arg1, arg2);  
                 write(arg0, cp, arg2);  
                 free(cp);  
685                  break;                  break;
686    
687          default:          case 17:res = useremul_break(cpu, arg0);
688                  fatal("useremul__linux(): syscall %i not yet implemented\n",                  break;
689                      nr);  
690            case 20:res = useremul_getpid(cpu);
691                    break;
692    
693            case 24:res = useremul_getuid(cpu);
694                    break;
695    
696            case 43:res = useremul_getegid(cpu);
697                    break;
698    
699            case 47:res = useremul_getgid(cpu);
700                    break;
701    
702            case 58:res = useremul_readlink(cpu, &err, arg0, arg1, arg2);
703                    break;
704    
705            case 73:/* munmap. TODO */
706                    res = 1;
707                    break;
708    
709            case 117:res = useremul_getrusage(cpu, &err, arg0, arg1);
710                    break;
711    
712            case 189:res = useremul_fstat(cpu, &err, arg0, arg1);
713                    break;
714    
715            case 197:res = useremul_mmap(cpu, &err, arg0, arg1, arg2, arg3,
716                        arg4, arg5);
717                    break;
718    
719            default:fatal("useremul__freebsd(): syscall %i not yet "
720                        "implemented\n", nr);
721                  cpu->running = 0;                  cpu->running = 0;
722          }          }
723  #endif  
724            if (err) {
725                    cpu->cd.alpha.r[ALPHA_A3] = 1;
726                    cpu->cd.alpha.r[ALPHA_V0] = err;
727            } else {
728                    cpu->cd.alpha.r[ALPHA_A3] = 0;
729                    cpu->cd.alpha.r[ALPHA_V0] = res;
730            }
731  }  }
732    
733    
# Line 429  static void useremul__freebsd(struct cpu Line 741  static void useremul__freebsd(struct cpu
741  static void useremul__linux(struct cpu *cpu, uint32_t code)  static void useremul__linux(struct cpu *cpu, uint32_t code)
742  {  {
743          int nr;          int nr;
744          unsigned char *cp;          int64_t res = 0, err = 0;
745          uint64_t arg0, arg1, arg2, arg3;          uint64_t arg0, arg1, arg2, arg3;
746    
747          if (code != 0) {          if (code != 0) {
# Line 446  static void useremul__linux(struct cpu * Line 758  static void useremul__linux(struct cpu *
758          switch (nr) {          switch (nr) {
759    
760          case LINUX_PPC_SYS_exit:          case LINUX_PPC_SYS_exit:
761                  debug("[ exit(%i) ]\n", (int)arg0);                  res = useremul_exit(cpu, arg0);
                 cpu->running = 0;  
762                  break;                  break;
763    
764          case LINUX_PPC_SYS_write:          case LINUX_PPC_SYS_write:
765                  debug("[ write(%i,0x%llx,%lli) ]\n",                  res = useremul_write(cpu, &err, arg0, arg1, arg2);
                     (int)arg0, (long long)arg1, (long long)arg2);  
                 cp = get_userland_buf(cpu, arg1, arg2);  
                 write(arg0, cp, arg2);  
                 free(cp);  
766                  break;                  break;
767    
768          default:          default:
# Line 463  static void useremul__linux(struct cpu * Line 770  static void useremul__linux(struct cpu *
770                      nr);                      nr);
771                  cpu->running = 0;                  cpu->running = 0;
772          }          }
773    
774            /*  return res: TODO  */
775  }  }
776    
777    
# Line 476  static void useremul__netbsd(struct cpu Line 785  static void useremul__netbsd(struct cpu
785          int error_flag = 0, result_high_set = 0;          int error_flag = 0, result_high_set = 0;
786          uint64_t arg0=0,arg1=0,arg2=0,arg3=0,stack0=0,stack1=0,stack2=0;          uint64_t arg0=0,arg1=0,arg2=0,arg3=0,stack0=0,stack1=0,stack2=0;
787          int sysnr = 0;          int sysnr = 0;
788          uint64_t error_code = 0;          int64_t error_code = 0;
789          uint64_t result_low = 0;          uint64_t result_low = 0;
790          uint64_t result_high = 0;          uint64_t result_high = 0;
791          struct timeval tv;          struct timeval tv;
# Line 530  static void useremul__netbsd(struct cpu Line 839  static void useremul__netbsd(struct cpu
839                  arg3 = cpu->cd.ppc.gpr[6];                  arg3 = cpu->cd.ppc.gpr[6];
840                  /*  TODO:  More arguments? Stack arguments?  */                  /*  TODO:  More arguments? Stack arguments?  */
841                  break;                  break;
842    
843            case ARCH_ARM:
844                    sysnr = code & 0xfffff;
845                    arg0 = cpu->cd.arm.r[0];
846                    arg1 = cpu->cd.arm.r[1];
847                    arg2 = cpu->cd.arm.r[2];
848                    arg3 = cpu->cd.arm.r[3];
849                    /*  TODO:  More arguments? Stack arguments?  */
850                    break;
851    
852            default:fatal("netbsd syscall for this arch: TODO\n");
853                    exit(1);
854          }          }
855    
856          /*          /*
857           *  NOTE: The following code should not be CPU arch dependant!           *  NOTE/TODO: The following code should not be CPU arch dependent!
          *  (TODO)  
858           */           */
859    
860          switch (sysnr) {          switch (sysnr) {
# Line 627  static void useremul__netbsd(struct cpu Line 947  static void useremul__netbsd(struct cpu
947                  break;                  break;
948    
949          case NETBSD_SYS_getuid:          case NETBSD_SYS_getuid:
950                  debug("[ getuid() ]\n");                  result_low = useremul_getuid(cpu);
                 result_low = getuid();  
951                  break;                  break;
952    
953          case NETBSD_SYS_geteuid:          case NETBSD_SYS_geteuid:
# Line 686  static void useremul__netbsd(struct cpu Line 1005  static void useremul__netbsd(struct cpu
1005                  break;                  break;
1006    
1007          case NETBSD_SYS_break:          case NETBSD_SYS_break:
1008                  debug("[ break(0x%llx): TODO ]\n", (long long)arg0);                  useremul_break(cpu, arg0);
                 /*  TODO  */  
1009                  break;                  break;
1010    
1011          case NETBSD_SYS_readlink:          case NETBSD_SYS_readlink:
1012                  charbuf = get_userland_string(cpu, arg0);                  result_low = useremul_readlink(cpu, &error_code,
1013                  debug("[ readlink(\"%s\",0x%lli,%lli) ]\n",                      arg0, arg1, arg2);
                     charbuf, (long long)arg1, (long long)arg2);  
                 if (arg2 != 0 && arg2 < 50000) {  
                         unsigned char *buf2 = malloc(arg2);  
                         buf2[arg2-1] = '\0';  
                         result_low = readlink((char *)charbuf,  
                             (char *)buf2, arg2 - 1);  
                         if ((int64_t)result_low < 0) {  
                                 error_flag = 1;  
                                 error_code = errno;  
                         } else  
                                 store_string(cpu, arg1, (char *)buf2);  
                         free(buf2);  
                 }  
                 free(charbuf);  
1014                  break;                  break;
1015    
1016          case NETBSD_SYS_sync:          case NETBSD_SYS_sync:
1017                  debug("[ sync() ]\n");                  useremul_sync(cpu);
                 sync();  
1018                  break;                  break;
1019    
1020          case NETBSD_SYS_gettimeofday:          case NETBSD_SYS_gettimeofday:
# Line 906  static void useremul__netbsd(struct cpu Line 1209  static void useremul__netbsd(struct cpu
1209    
1210    
1211          switch (cpu->machine->arch) {          switch (cpu->machine->arch) {
1212            case ARCH_ARM:
1213                    /*  NetBSD/arm return values:  */
1214                    cpu->cd.arm.r[0] = result_low;
1215                    cpu->cd.arm.cpsr &= ~ARM_FLAG_C;
1216                    if (error_flag) {
1217                            cpu->cd.arm.cpsr |= ARM_FLAG_C;
1218                            cpu->cd.arm.r[0] = error_code;
1219                    }
1220                    if (result_high_set)
1221                            cpu->cd.arm.r[1] = result_high;
1222                    cpu->cd.arm.flags = cpu->cd.arm.cpsr >> 28;
1223                    break;
1224          case ARCH_MIPS:          case ARCH_MIPS:
1225                  /*                  /*
1226                   *  NetBSD/mips return values:                   *  NetBSD/mips return values:
# Line 947  static void useremul__ultrix(struct cpu Line 1262  static void useremul__ultrix(struct cpu
1262          int error_flag = 0, result_high_set = 0;          int error_flag = 0, result_high_set = 0;
1263          uint64_t arg0,arg1,arg2,arg3,stack0=0,stack1=0,stack2;          uint64_t arg0,arg1,arg2,arg3,stack0=0,stack1=0,stack2;
1264          int sysnr = 0;          int sysnr = 0;
1265          uint64_t error_code = 0;          int64_t error_code = 0;
1266          uint64_t result_low = 0;          uint64_t result_low = 0;
1267          uint64_t result_high = 0;          uint64_t result_high = 0;
1268          struct timeval tv;          struct timeval tv;
# Line 1068  static void useremul__ultrix(struct cpu Line 1383  static void useremul__ultrix(struct cpu
1383                  break;                  break;
1384    
1385          case ULTRIX_SYS_break:          case ULTRIX_SYS_break:
1386                  debug("[ break(0x%llx): TODO ]\n", (long long)arg0);                  useremul_break(cpu, arg0);
                 /*  TODO  */  
1387                  break;                  break;
1388    
1389          case ULTRIX_SYS_sync:          case ULTRIX_SYS_sync:
1390                  debug("[ sync() ]\n");                  useremul_sync(cpu);
                 sync();  
1391                  break;                  break;
1392    
1393          case ULTRIX_SYS_getuid:          case ULTRIX_SYS_getuid:
1394                  debug("[ getuid() ]\n");                  result_low = useremul_getuid(cpu);
                 result_low = getuid();  
1395                  break;                  break;
1396    
1397          case ULTRIX_SYS_getgid:          case ULTRIX_SYS_getgid:
# Line 1185  static void useremul__ultrix(struct cpu Line 1497  static void useremul__ultrix(struct cpu
1497                  break;                  break;
1498    
1499          case ULTRIX_SYS_fstat:          case ULTRIX_SYS_fstat:
1500                  debug("[ fstat(%i, 0x%llx): TODO ]\n",                  result_low = useremul_fstat(cpu, &error_code, arg0, arg1);
                     (int)arg0, (long long)arg1);  
   
                 if (arg1 != 0) {  
                         struct stat st;  
                         result_low = fstat(arg0, &st);  
                         if ((int64_t)result_low < 0) {  
                                 error_flag = 1;  
                                 error_code = errno;  
                         } else {  
                                 /*  Fill in the Ultrix stat struct at arg1:  */  
   
                                 /*  TODO  */  
                         }  
                 } else {  
                         error_flag = 1;  
                         error_code = 1111;      /*  TODO: ultrix ENOMEM?  */  
                 }  
1501                  break;                  break;
1502    
1503          case ULTRIX_SYS_getpagesize:          case ULTRIX_SYS_getpagesize:
# Line 1424  static void add_useremul(char *name, int Line 1719  static void add_useremul(char *name, int
1719  void useremul_list_emuls(void)  void useremul_list_emuls(void)
1720  {  {
1721          struct syscall_emul *sep;          struct syscall_emul *sep;
1722          int iadd = 8;          int iadd = DEBUG_INDENTATION * 2;
1723    
1724          sep = first_syscall_emul;          sep = first_syscall_emul;
1725    
# Line 1462  void useremul_init(void) Line 1757  void useremul_init(void)
1757          add_useremul("Ultrix", ARCH_MIPS, "R3000",          add_useremul("Ultrix", ARCH_MIPS, "R3000",
1758              useremul__ultrix, useremul__ultrix_setup);              useremul__ultrix, useremul__ultrix_setup);
1759    
1760            add_useremul("NetBSD/sh", ARCH_SH, "SH4",
1761                useremul__netbsd, useremul__netbsd_setup);
1762    
1763          add_useremul("NetBSD/powerpc", ARCH_PPC, "PPC750",          add_useremul("NetBSD/powerpc", ARCH_PPC, "PPC750",
1764              useremul__netbsd, useremul__netbsd_setup);              useremul__netbsd, useremul__netbsd_setup);
1765    
1766          add_useremul("NetBSD/pmax", ARCH_MIPS, "R3000",          add_useremul("NetBSD/pmax", ARCH_MIPS, "R3000",
1767              useremul__netbsd, useremul__netbsd_setup);              useremul__netbsd, useremul__netbsd_setup);
1768    
1769            add_useremul("NetBSD/arm", ARCH_ARM, "SA1110",
1770                useremul__netbsd, useremul__netbsd_setup);
1771    
1772            add_useremul("NetBSD/alpha", ARCH_ALPHA, "Alpha",
1773                useremul__netbsd, useremul__netbsd_setup);
1774    
1775          add_useremul("Linux/PPC64", ARCH_PPC, "PPC970",          add_useremul("Linux/PPC64", ARCH_PPC, "PPC970",
1776              useremul__linux, useremul__linux_setup);              useremul__linux, useremul__linux_setup);
1777    
1778          add_useremul("FreeBSD/Alpha", ARCH_ALPHA, "EV4",          add_useremul("FreeBSD/Alpha", ARCH_ALPHA, "Alpha",
1779              useremul__freebsd, useremul__freebsd_setup);              useremul__freebsd, useremul__freebsd_setup);
1780  }  }
1781    

Legend:
Removed from v.2  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26