/[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 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2006  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.72 2006/09/30 05:57:07 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            case ARCH_X86:
260                    debug("useremul__netbsd_setup(): X86: TODO\n");
261    
262                    break;
263    
264          default:          default:
265                  fatal("useremul__netbsd_setup(): unimplemented arch\n");                  fatal("useremul__netbsd_setup(): unimplemented arch\n");
266                  exit(1);                  exit(1);
# Line 255  void useremul__ultrix_setup(struct cpu * Line 290  void useremul__ultrix_setup(struct cpu *
290          /*  The userland stack:  */          /*  The userland stack:  */
291          cpu->cd.mips.gpr[MIPS_GPR_SP] = stack_top - stack_margin;          cpu->cd.mips.gpr[MIPS_GPR_SP] = stack_top - stack_margin;
292          add_symbol_name(&cpu->machine->symbol_context,          add_symbol_name(&cpu->machine->symbol_context,
293              stack_top - stacksize, stacksize, "userstack", 0);              stack_top - stacksize, stacksize, "userstack", 0, 0);
294    
295          /*  Stack contents:  (TODO: is this correct?)  */          /*  Stack contents:  (TODO: is this correct?)  */
296          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 369  static unsigned char *get_userland_strin
369   *  TODO: combine this with get_userland_string() in some way   *  TODO: combine this with get_userland_string() in some way
370   */   */
371  static unsigned char *get_userland_buf(struct cpu *cpu,  static unsigned char *get_userland_buf(struct cpu *cpu,
372          uint64_t baseaddr, int len)          uint64_t baseaddr, uint64_t len)
373  {  {
374          unsigned char *charbuf;          unsigned char *charbuf;
375          int i;          size_t i;
376    
377          charbuf = malloc(len);          charbuf = malloc(len);
378          if (charbuf == NULL) {          if (charbuf == NULL) {
379                  fprintf(stderr, "get_userland_buf(): out of memory (trying"                  fprintf(stderr, "get_userland_buf(): out of memory (trying"
380                      " to allocate %i bytes)\n", len);                      " to allocate %lli bytes)\n", (long long)len);
381                  exit(1);                  exit(1);
382          }          }
383    
# Line 375  void useremul_syscall(struct cpu *cpu, u Line 410  void useremul_syscall(struct cpu *cpu, u
410  }  }
411    
412    
413    /*****************************************************************************/
414    
415    
416    /*
417     *  useremul_exit():
418     */
419    int useremul_exit(struct cpu *cpu, uint64_t arg0)
420    {
421            debug("[ exit(%i) ]\n", (int)arg0);
422            cpu->running = 0;
423            cpu->machine->exit_without_entering_debugger = 1;
424            return 0;
425    }
426    
427    
428    /*
429     *  useremul_write():
430     */
431    int64_t useremul_write(struct cpu *cpu, int64_t *errnop,
432            uint64_t arg0, uint64_t arg1, uint64_t arg2)
433    {
434            int64_t res = 0;
435            *errnop = 0;
436            debug("[ write(%i,0x%llx,%lli) ]\n",
437                (int)arg0, (long long)arg1, (long long)arg2);
438            if (arg2 != 0) {
439                    unsigned char *cp = get_userland_buf(cpu, arg1, arg2);
440                    res = write(arg0, cp, arg2);
441                    if (res < 0)
442                            *errnop = errno;
443                    free(cp);
444            }
445            return res;
446    }
447    
448    
449    /*
450     *  useremul_break():
451     */
452    int64_t useremul_break(struct cpu *cpu, uint64_t arg0)
453    {
454            debug("[ break(0x%llx): TODO ]\n", (long long)arg0);
455    
456            /*  TODO  */
457            return 0;
458    }
459    
460    
461    /*
462     *  useremul_getpid():
463     */
464    int64_t useremul_getpid(struct cpu *cpu)
465    {
466            int64_t pid = getpid();
467            debug("[ getpid(): %lli ]\n", (long long)pid);
468            return pid;
469    }
470    
471    
472    /*
473     *  useremul_getuid():
474     */
475    int64_t useremul_getuid(struct cpu *cpu)
476    {
477            int64_t uid = getuid();
478            debug("[ getuid(): %lli ]\n", (long long)uid);
479            return uid;
480    }
481    
482    
483    /*
484     *  useremul_getegid():
485     */
486    int64_t useremul_getegid(struct cpu *cpu)
487    {
488            int64_t egid = getegid();
489            debug("[ getegid(): %lli ]\n", (long long)egid);
490            return egid;
491    }
492    
493    
494    /*
495     *  useremul_getgid():
496     */
497    int64_t useremul_getgid(struct cpu *cpu)
498    {
499            int64_t gid = getgid();
500            debug("[ getgid(): %lli ]\n", (long long)gid);
501            return gid;
502    }
503    
504    
505    /*
506     *  useremul_sync():
507     */
508    int useremul_sync(struct cpu *cpu)
509    {
510            debug("[ sync() ]\n");
511            sync();
512            return 0;
513    }
514    
515    
516    /*
517     *  useremul_readlink():
518     */
519    int64_t useremul_readlink(struct cpu *cpu, int64_t *errnop,
520            uint64_t arg0, uint64_t arg1, int64_t arg2)
521    {
522            int64_t res = 0;
523            unsigned char *charbuf = get_userland_string(cpu, arg0);
524            unsigned char *buf2;
525    
526            debug("[ readlink(\"%s\",0x%llx,%lli) ]\n",
527                charbuf, (long long)arg1, (long long)arg2);
528            if (arg2 == 0 || arg2 > 150000) {
529                    fprintf(stderr, "[ useremul_readlink(): TODO ]\n");
530                    exit(1);
531            }
532    
533            buf2 = malloc(arg2);
534            if (buf2 == NULL) {
535                    fprintf(stderr, "[ useremul_readlink(): out of memory ]\n");
536                    exit(1);
537            }
538            res = readlink((char *)charbuf, (char *)buf2, arg2);
539            buf2[arg2-1] = '\0';
540            if (res < 0)
541                    *errnop = errno;
542            else
543                    store_string(cpu, arg1, (char *)buf2);
544            free(buf2);
545            free(charbuf);
546            return res;
547    }
548    
549    
550    /*
551     *  useremul_getrusage():
552     */
553    int64_t useremul_getrusage(struct cpu *cpu, int64_t *errnop,
554            uint64_t arg0, uint64_t arg1)
555    {
556            int64_t res;
557            struct rusage rusage;
558            debug("[ getrusage(%i,0x%llx) ]\n", (int)arg0, (long long)arg1);
559            res = getrusage(arg0, &rusage);
560    
561            fatal("TODO: convert rusage into emulated memory!\n");
562            store_64bit_word(cpu, arg1 +  0, rusage.ru_utime.tv_sec);
563            store_64bit_word(cpu, arg1 +  8, rusage.ru_utime.tv_usec);
564            store_64bit_word(cpu, arg1 + 16, rusage.ru_stime.tv_sec);
565            store_64bit_word(cpu, arg1 + 24, rusage.ru_stime.tv_usec);
566    
567            return res;
568    }
569    
570    
571    /*
572     *  useremul_fstat():
573     */
574    int64_t useremul_fstat(struct cpu *cpu, int64_t *errnop,
575            int64_t arg0, uint64_t arg1)
576    {
577            int64_t res;
578            struct stat sb;
579            debug("[ fstat(%i,0x%llx) ]\n", (int)arg0, (long long)arg1);
580            res = fstat(arg0, &sb);
581            if (res < 0)
582                    *errnop = errno;
583            else {
584                    fatal("TODO: convert sb into emulated memory!\n");
585    
586    /*  NOTE: FreeBSD/alpha only  */
587    
588                    store_32bit_word(cpu, arg1 + 0, sb.st_dev);
589                    store_32bit_word(cpu, arg1 + 4, sb.st_ino);
590    /*              store_16bit_word(cpu, arg1 + 8, sb.st_mode);
591    */              store_16bit_word(cpu, arg1 + 10, sb.st_nlink);
592                    store_32bit_word(cpu, arg1 + 12, sb.st_uid);
593                    store_32bit_word(cpu, arg1 + 16, sb.st_gid);
594                    store_32bit_word(cpu, arg1 + 20, sb.st_rdev);
595    #if 0
596                    store_64bit_word(cpu, arg1 + 24, sb.st_atimespec.tv_sec);
597                    store_64bit_word(cpu, arg1 + 32, sb.st_atimespec.tv_nsec);
598                    store_64bit_word(cpu, arg1 + 40, sb.st_mtimespec.tv_sec);
599                    store_64bit_word(cpu, arg1 + 48, sb.st_mtimespec.tv_nsec);
600                    store_64bit_word(cpu, arg1 + 56, sb.st_ctimespec.tv_sec);
601                    store_64bit_word(cpu, arg1 + 64, sb.st_ctimespec.tv_nsec);
602    
603                    store_64bit_word(cpu, arg1 + 72, sb.st_size);
604                    store_64bit_word(cpu, arg1 + 80, sb.st_blocks);
605                    store_64bit_word(cpu, arg1 + 88, sb.st_blksize);
606                    store_64bit_word(cpu, arg1 + 92, sb.st_flags);
607                    store_64bit_word(cpu, arg1 + 96, sb.st_gen);
608    #endif
609            }
610            return res;
611    }
612    
613    
614    /*
615     *  useremul_mmap():
616     */
617    int64_t useremul_mmap(struct cpu *cpu, int64_t *errnop,
618            uint64_t arg0, int64_t arg1, int64_t arg2,
619            int64_t arg3, int64_t arg4, uint64_t arg5)
620    {
621            int64_t res = 0;
622    
623            /*  arg0..5: addr, len, prot, flags, fd, offset  */
624            debug("[ mmap(0x%llx,%lli,%i,%i,%i,%lli) ]\n",
625                (long long)arg0, (long long)arg1,
626                (int)arg2, (int)arg3, (int)arg4, (long long)arg5);
627    
628            if (arg4 != -1) {
629                    fatal("[ useremul_mmap(): fd != -1: TODO ]\n");
630                    cpu->running = 0;
631                    return 0;
632            }
633    
634            /*  Anonymous allocation.  */
635            if (arg0 != 0) {
636                    fatal("[ useremul_mmap(): addr != 0: TODO ]\n");
637                    cpu->running = 0;
638                    return 0;
639            }
640    
641            fatal("[ useremul_mmap(): TODO ]\n");
642    
643    res = 0x18000000ULL;
644    
645            return res;
646    }
647    
648    
649    /*****************************************************************************/
650    
651    
652  /*  /*
653   *  useremul__freebsd():   *  useremul__freebsd():
654   *   *
655   *  FreeBSD syscall emulation.   *  FreeBSD/Alpha syscall emulation.
656   *   *
657   *  TODO: How to make this work nicely with non-Alpha archs.   *  TODO: How to make this work nicely with non-Alpha archs.
658   */   */
659  static void useremul__freebsd(struct cpu *cpu, uint32_t code)  static void useremul__freebsd(struct cpu *cpu, uint32_t code)
660  {  {
 #if 0  
         unsigned char *cp;  
661          int nr;          int nr;
662          uint64_t arg0, arg1, arg2, arg3;          int64_t res = 0, err = 0;
663            uint64_t arg0, arg1, arg2, arg3, arg4, arg5;
664    
665          nr = cpu->cd.ppc.gpr[0];          nr = cpu->cd.alpha.r[ALPHA_V0];
666          arg0 = cpu->cd.ppc.gpr[3];          arg0 = cpu->cd.alpha.r[ALPHA_A0];
667          arg1 = cpu->cd.ppc.gpr[4];          arg1 = cpu->cd.alpha.r[ALPHA_A1];
668          arg2 = cpu->cd.ppc.gpr[5];          arg2 = cpu->cd.alpha.r[ALPHA_A2];
669          arg3 = cpu->cd.ppc.gpr[6];          arg3 = cpu->cd.alpha.r[ALPHA_A3];
670            arg4 = cpu->cd.alpha.r[ALPHA_A4];
671            arg5 = cpu->cd.alpha.r[ALPHA_A5];
672    
673            if (nr == 198) {
674                    /*  ___syscall  */
675                    nr = arg0;
676                    arg0 = arg1;
677                    arg1 = arg2;
678                    arg2 = arg3;
679                    arg3 = arg4;
680                    arg4 = arg5;
681                    /*  TODO: stack arguments  */
682            }
683    
684          switch (nr) {          switch (nr) {
685    
686          case LINUX_PPC_SYS_exit:          case 1: res = useremul_exit(cpu, arg0);
                 debug("[ exit(%i) ]\n", (int)arg0);  
                 cpu->running = 0;  
687                  break;                  break;
688    
689          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);  
690                  break;                  break;
691    
692          default:          case 17:res = useremul_break(cpu, arg0);
693                  fatal("useremul__linux(): syscall %i not yet implemented\n",                  break;
694                      nr);  
695            case 20:res = useremul_getpid(cpu);
696                    break;
697    
698            case 24:res = useremul_getuid(cpu);
699                    break;
700    
701            case 43:res = useremul_getegid(cpu);
702                    break;
703    
704            case 47:res = useremul_getgid(cpu);
705                    break;
706    
707            case 58:res = useremul_readlink(cpu, &err, arg0, arg1, arg2);
708                    break;
709    
710            case 73:/* munmap. TODO */
711                    res = 1;
712                    break;
713    
714            case 117:res = useremul_getrusage(cpu, &err, arg0, arg1);
715                    break;
716    
717            case 189:res = useremul_fstat(cpu, &err, arg0, arg1);
718                    break;
719    
720            case 197:res = useremul_mmap(cpu, &err, arg0, arg1, arg2, arg3,
721                        arg4, arg5);
722                    break;
723    
724            default:fatal("useremul__freebsd(): syscall %i not yet "
725                        "implemented\n", nr);
726                  cpu->running = 0;                  cpu->running = 0;
727          }          }
728  #endif  
729            if (err) {
730                    cpu->cd.alpha.r[ALPHA_A3] = 1;
731                    cpu->cd.alpha.r[ALPHA_V0] = err;
732            } else {
733                    cpu->cd.alpha.r[ALPHA_A3] = 0;
734                    cpu->cd.alpha.r[ALPHA_V0] = res;
735            }
736  }  }
737    
738    
# Line 429  static void useremul__freebsd(struct cpu Line 746  static void useremul__freebsd(struct cpu
746  static void useremul__linux(struct cpu *cpu, uint32_t code)  static void useremul__linux(struct cpu *cpu, uint32_t code)
747  {  {
748          int nr;          int nr;
749          unsigned char *cp;          int64_t res = 0, err = 0;
750          uint64_t arg0, arg1, arg2, arg3;          uint64_t arg0, arg1, arg2, arg3;
751    
752          if (code != 0) {          if (code != 0) {
# Line 446  static void useremul__linux(struct cpu * Line 763  static void useremul__linux(struct cpu *
763          switch (nr) {          switch (nr) {
764    
765          case LINUX_PPC_SYS_exit:          case LINUX_PPC_SYS_exit:
766                  debug("[ exit(%i) ]\n", (int)arg0);                  res = useremul_exit(cpu, arg0);
                 cpu->running = 0;  
767                  break;                  break;
768    
769          case LINUX_PPC_SYS_write:          case LINUX_PPC_SYS_write:
770                  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);  
771                  break;                  break;
772    
773          default:          default:
# Line 463  static void useremul__linux(struct cpu * Line 775  static void useremul__linux(struct cpu *
775                      nr);                      nr);
776                  cpu->running = 0;                  cpu->running = 0;
777          }          }
778    
779            /*  return res: TODO  */
780  }  }
781    
782    
# Line 476  static void useremul__netbsd(struct cpu Line 790  static void useremul__netbsd(struct cpu
790          int error_flag = 0, result_high_set = 0;          int error_flag = 0, result_high_set = 0;
791          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;
792          int sysnr = 0;          int sysnr = 0;
793          uint64_t error_code = 0;          int64_t error_code = 0;
794          uint64_t result_low = 0;          uint64_t result_low = 0;
795          uint64_t result_high = 0;          uint64_t result_high = 0;
796          struct timeval tv;          struct timeval tv;
# Line 530  static void useremul__netbsd(struct cpu Line 844  static void useremul__netbsd(struct cpu
844                  arg3 = cpu->cd.ppc.gpr[6];                  arg3 = cpu->cd.ppc.gpr[6];
845                  /*  TODO:  More arguments? Stack arguments?  */                  /*  TODO:  More arguments? Stack arguments?  */
846                  break;                  break;
847    
848            case ARCH_ARM:
849                    sysnr = code & 0xfffff;
850                    arg0 = cpu->cd.arm.r[0];
851                    arg1 = cpu->cd.arm.r[1];
852                    arg2 = cpu->cd.arm.r[2];
853                    arg3 = cpu->cd.arm.r[3];
854                    /*  TODO:  More arguments? Stack arguments?  */
855                    break;
856    
857            default:fatal("netbsd syscall for this arch: TODO\n");
858                    exit(1);
859          }          }
860    
861          /*          /*
862           *  NOTE: The following code should not be CPU arch dependant!           *  NOTE/TODO: The following code should not be CPU arch dependent!
          *  (TODO)  
863           */           */
864    
865          switch (sysnr) {          switch (sysnr) {
# Line 627  static void useremul__netbsd(struct cpu Line 952  static void useremul__netbsd(struct cpu
952                  break;                  break;
953    
954          case NETBSD_SYS_getuid:          case NETBSD_SYS_getuid:
955                  debug("[ getuid() ]\n");                  result_low = useremul_getuid(cpu);
                 result_low = getuid();  
956                  break;                  break;
957    
958          case NETBSD_SYS_geteuid:          case NETBSD_SYS_geteuid:
# Line 686  static void useremul__netbsd(struct cpu Line 1010  static void useremul__netbsd(struct cpu
1010                  break;                  break;
1011    
1012          case NETBSD_SYS_break:          case NETBSD_SYS_break:
1013                  debug("[ break(0x%llx): TODO ]\n", (long long)arg0);                  useremul_break(cpu, arg0);
                 /*  TODO  */  
1014                  break;                  break;
1015    
1016          case NETBSD_SYS_readlink:          case NETBSD_SYS_readlink:
1017                  charbuf = get_userland_string(cpu, arg0);                  result_low = useremul_readlink(cpu, &error_code,
1018                  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);  
1019                  break;                  break;
1020    
1021          case NETBSD_SYS_sync:          case NETBSD_SYS_sync:
1022                  debug("[ sync() ]\n");                  useremul_sync(cpu);
                 sync();  
1023                  break;                  break;
1024    
1025          case NETBSD_SYS_gettimeofday:          case NETBSD_SYS_gettimeofday:
# Line 906  static void useremul__netbsd(struct cpu Line 1214  static void useremul__netbsd(struct cpu
1214    
1215    
1216          switch (cpu->machine->arch) {          switch (cpu->machine->arch) {
1217            case ARCH_ARM:
1218                    /*  NetBSD/arm return values:  */
1219                    cpu->cd.arm.r[0] = result_low;
1220                    cpu->cd.arm.cpsr &= ~ARM_FLAG_C;
1221                    if (error_flag) {
1222                            cpu->cd.arm.cpsr |= ARM_FLAG_C;
1223                            cpu->cd.arm.r[0] = error_code;
1224                    }
1225                    if (result_high_set)
1226                            cpu->cd.arm.r[1] = result_high;
1227                    cpu->cd.arm.flags = cpu->cd.arm.cpsr >> 28;
1228                    break;
1229          case ARCH_MIPS:          case ARCH_MIPS:
1230                  /*                  /*
1231                   *  NetBSD/mips return values:                   *  NetBSD/mips return values:
# Line 947  static void useremul__ultrix(struct cpu Line 1267  static void useremul__ultrix(struct cpu
1267          int error_flag = 0, result_high_set = 0;          int error_flag = 0, result_high_set = 0;
1268          uint64_t arg0,arg1,arg2,arg3,stack0=0,stack1=0,stack2;          uint64_t arg0,arg1,arg2,arg3,stack0=0,stack1=0,stack2;
1269          int sysnr = 0;          int sysnr = 0;
1270          uint64_t error_code = 0;          int64_t error_code = 0;
1271          uint64_t result_low = 0;          uint64_t result_low = 0;
1272          uint64_t result_high = 0;          uint64_t result_high = 0;
1273          struct timeval tv;          struct timeval tv;
# Line 1068  static void useremul__ultrix(struct cpu Line 1388  static void useremul__ultrix(struct cpu
1388                  break;                  break;
1389    
1390          case ULTRIX_SYS_break:          case ULTRIX_SYS_break:
1391                  debug("[ break(0x%llx): TODO ]\n", (long long)arg0);                  useremul_break(cpu, arg0);
                 /*  TODO  */  
1392                  break;                  break;
1393    
1394          case ULTRIX_SYS_sync:          case ULTRIX_SYS_sync:
1395                  debug("[ sync() ]\n");                  useremul_sync(cpu);
                 sync();  
1396                  break;                  break;
1397    
1398          case ULTRIX_SYS_getuid:          case ULTRIX_SYS_getuid:
1399                  debug("[ getuid() ]\n");                  result_low = useremul_getuid(cpu);
                 result_low = getuid();  
1400                  break;                  break;
1401    
1402          case ULTRIX_SYS_getgid:          case ULTRIX_SYS_getgid:
# Line 1185  static void useremul__ultrix(struct cpu Line 1502  static void useremul__ultrix(struct cpu
1502                  break;                  break;
1503    
1504          case ULTRIX_SYS_fstat:          case ULTRIX_SYS_fstat:
1505                  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?  */  
                 }  
1506                  break;                  break;
1507    
1508          case ULTRIX_SYS_getpagesize:          case ULTRIX_SYS_getpagesize:
# Line 1424  static void add_useremul(char *name, int Line 1724  static void add_useremul(char *name, int
1724  void useremul_list_emuls(void)  void useremul_list_emuls(void)
1725  {  {
1726          struct syscall_emul *sep;          struct syscall_emul *sep;
1727          int iadd = 8;          int iadd = DEBUG_INDENTATION * 2;
1728    
1729          sep = first_syscall_emul;          sep = first_syscall_emul;
1730    
# Line 1462  void useremul_init(void) Line 1762  void useremul_init(void)
1762          add_useremul("Ultrix", ARCH_MIPS, "R3000",          add_useremul("Ultrix", ARCH_MIPS, "R3000",
1763              useremul__ultrix, useremul__ultrix_setup);              useremul__ultrix, useremul__ultrix_setup);
1764    
1765            add_useremul("NetBSD/sh", ARCH_SH, "SH4",
1766                useremul__netbsd, useremul__netbsd_setup);
1767    
1768          add_useremul("NetBSD/powerpc", ARCH_PPC, "PPC750",          add_useremul("NetBSD/powerpc", ARCH_PPC, "PPC750",
1769              useremul__netbsd, useremul__netbsd_setup);              useremul__netbsd, useremul__netbsd_setup);
1770    
1771          add_useremul("NetBSD/pmax", ARCH_MIPS, "R3000",          add_useremul("NetBSD/pmax", ARCH_MIPS, "R3000",
1772              useremul__netbsd, useremul__netbsd_setup);              useremul__netbsd, useremul__netbsd_setup);
1773    
1774            add_useremul("NetBSD/arm", ARCH_ARM, "SA1110",
1775                useremul__netbsd, useremul__netbsd_setup);
1776    
1777            add_useremul("NetBSD/amd64", ARCH_X86, "AMD64",
1778                useremul__netbsd, useremul__netbsd_setup);
1779    
1780            add_useremul("NetBSD/alpha", ARCH_ALPHA, "Alpha",
1781                useremul__netbsd, useremul__netbsd_setup);
1782    
1783          add_useremul("Linux/PPC64", ARCH_PPC, "PPC970",          add_useremul("Linux/PPC64", ARCH_PPC, "PPC970",
1784              useremul__linux, useremul__linux_setup);              useremul__linux, useremul__linux_setup);
1785    
1786          add_useremul("FreeBSD/Alpha", ARCH_ALPHA, "EV4",          add_useremul("FreeBSD/Alpha", ARCH_ALPHA, "Alpha",
1787              useremul__freebsd, useremul__freebsd_setup);              useremul__freebsd, useremul__freebsd_setup);
1788  }  }
1789    

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

  ViewVC Help
Powered by ViewVC 1.1.26