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

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

  ViewVC Help
Powered by ViewVC 1.1.26