src/Emu/PPC64Linux/PPC64LinuxSyscallConv.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #include <pch.h>
00033 
00034 #include "Emu/PPC64Linux/PPC64LinuxSyscallConv.h"
00035 
00036 #include "Env/Env.h"
00037 #include "SysDeps/posix.h"
00038 
00039 #include "Emu/Utility/System/ProcessState.h"
00040 #include "Emu/Utility/System/Memory/MemorySystem.h"
00041 #include "Emu/Utility/System/Memory/MemoryUtility.h"
00042 #include "Emu/Utility/System/VirtualSystem.h"
00043 #include "Emu/Utility/System/Syscall/SyscallConstConv.h"
00044 #include "Emu/Utility/OpEmulationState.h"
00045 
00046 #include "Emu/PPC64Linux/PPC64LinuxSyscallID.h"
00047 
00048 #define SYSCALL_DEBUG
00049 
00050 using namespace std;
00051 using namespace Onikiri;
00052 using namespace Onikiri::EmulatorUtility;
00053 using namespace Onikiri::PPC64Linux;
00054 using namespace Onikiri::POSIX;
00055 
00056 
00057 PPC64LinuxSyscallConv::PPC64LinuxSyscallConv(ProcessState* processState) : Linux64SyscallConv(processState)
00058 {
00059 }
00060 
00061 PPC64LinuxSyscallConv::~PPC64LinuxSyscallConv()
00062 {
00063 }
00064 
00065 #ifdef SYSCALL_DEBUG
00066 #define SYSCALLNAME(name, argcnt, argtempl) {syscall_id_##name, #name, argcnt, argtempl}
00067 
00068 namespace {
00069 
00070 // x: int (hexadecimal)
00071 // n: int
00072 // p: pointer
00073 // s: string
00074 
00075 static struct {
00076     unsigned int syscallNo;
00077     const char* name;
00078     int argcnt;
00079     const char* argtempl;
00080 } syscallTable[] = {
00081     SYSCALLNAME(exit, 0, ""),
00082     SYSCALLNAME(read, 3, "npn"),
00083     SYSCALLNAME(write, 3, "npn"),
00084     SYSCALLNAME(readv, 3, "npn"),
00085     SYSCALLNAME(writev, 3, "npn"),
00086     SYSCALLNAME(open, 3, "sxx"),
00087     SYSCALLNAME(close, 1, "n"),
00088     SYSCALLNAME(stat, 2, "sp"),
00089     SYSCALLNAME(lstat, 2, "sp"),
00090     SYSCALLNAME(fstat, 2, "np"),
00091     //SYSCALLNAME(stat64, 2, "sp"),
00092     //SYSCALLNAME(lstat64, 2, "sp"),
00093     //SYSCALLNAME(fstat64, 2, "np"),
00094     SYSCALLNAME(lseek, 3, "nxn"),
00095     SYSCALLNAME(truncate, 2, "px"),
00096     SYSCALLNAME(ftruncate, 2, "nx"),
00097     SYSCALLNAME(fcntl, 3, "nnp"),
00098     SYSCALLNAME(chdir, 1, "p"),
00099     SYSCALLNAME(fchdir, 1, "n"),
00100     SYSCALLNAME(getcwd, 2, "px"),
00101     SYSCALLNAME(mkdir, 2, "sx"),
00102     SYSCALLNAME(rmdir, 1, "s"),
00103     SYSCALLNAME(readlink, 3, "spx"),
00104     SYSCALLNAME(unlink, 1, "s"),
00105     SYSCALLNAME(link, 2, "ss"),
00106     SYSCALLNAME(rename, 2, "ss"),
00107     SYSCALLNAME(mmap, 6, "pxxxnx"),
00108     SYSCALLNAME(mremap, 4, "pxxx"),
00109     SYSCALLNAME(munmap, 2, "px"),
00110     SYSCALLNAME(mprotect, 3, "pxx"),
00111     SYSCALLNAME(chmod, 2, "sx"),
00112     SYSCALLNAME(ioctl, 3, "xxx"),
00113     SYSCALLNAME(time, 1, "p"),
00114     SYSCALLNAME(times, 1, "p"),
00115     SYSCALLNAME(gettimeofday, 2, "pp"),
00116     //SYSCALLNAME(settimeofday, 2, "pp"),
00117 
00118     SYSCALLNAME(uname, 1, "p"),
00119     SYSCALLNAME(brk, 1, "p"),
00120 
00121     SYSCALLNAME(access, 2, "sx"),
00122 
00123     SYSCALLNAME(gettid, 0, ""),
00124     SYSCALLNAME(setuid, 1, "x"),
00125     SYSCALLNAME(getuid, 0, ""),
00126     //SYSCALLNAME(seteuid, 1, "x"),
00127     SYSCALLNAME(setgid, 1, "x"),
00128     SYSCALLNAME(getgid, 0, ""),
00129     //SYSCALLNAME(setegid, 1, "x"),
00130     SYSCALLNAME(geteuid, 0, ""),
00131     SYSCALLNAME(getegid, 0, ""),
00132     //SYSCALLNAME(setreuid, 2),
00133     //SYSCALLNAME(setregid, 2),
00134     SYSCALLNAME(getrusage, 2, "xp"),
00135     SYSCALLNAME(getrlimit, 2, "np"),
00136     SYSCALLNAME(setrlimit, 2, "np"),
00137     SYSCALLNAME(exit_group, 0, ""),
00138     SYSCALLNAME(dup, 1, "n"),
00139 
00140     SYSCALLNAME(rt_sigaction, 3, "xxx"),
00141     SYSCALLNAME(rt_sigprocmask, 3, "xxx"),
00142     SYSCALLNAME(kill, 2, "xx"),
00143     SYSCALLNAME(tgkill, 3, "xxx"),
00144 };
00145 #undef SYSCALLNAME
00146 
00147 } // namespace {
00148 #endif // #ifdef SYSCALL_DEBUG
00149 
00150 
00151 void PPC64LinuxSyscallConv::Execute(OpEmulationState* opState)
00152 {
00153 #ifdef SYSCALL_DEBUG 
00154     static std::ofstream log("syscall.log", std::ios_base::out | std::ios_base::trunc);
00155 
00156     log << dec << GetArg(0) << " ";
00157     for (size_t i = 0; i < sizeof(syscallTable)/sizeof(syscallTable[0]); i ++) {
00158         if (syscallTable[i].syscallNo == GetArg(0)) {
00159             log << syscallTable[i].name << "(";
00160             int argcnt = syscallTable[i].argcnt;
00161             const char *argtempl = syscallTable[i].argtempl;
00162             for (int j = 1; j <= argcnt; j ++) {
00163                 switch (argtempl[j-1]) {
00164                 case 's':
00165                     {
00166                         std::string s = StrCpyToHost( GetMemorySystem(), GetArg(j) );
00167                         log << "0x" << hex << GetArg(j) << dec;
00168                         log << "=\"" << s << "\"";
00169                     }
00170                     break;
00171                 case 'n':
00172                     log << dec << (s64)GetArg(j);
00173                     break;
00174                 case 'p':
00175                 case 'x':
00176                 default:
00177                     log << "0x" << hex << GetArg(j) << dec;
00178                     break;
00179                 }
00180                 if (j != argcnt)
00181                     log << ", ";
00182             }
00183             log << ")";
00184         }
00185     }
00186     log << flush;
00187 #endif // #ifdef SYSCALL_DEBUG
00188 
00189     opState->SetTakenPC( opState->GetPC()+4 );
00190     opState->SetTaken(true);
00191 
00192     SetResult(false, 0);
00193     switch (GetArg(0)) {
00194     case syscall_id_exit:
00195     case syscall_id_exit_group:
00196         syscall_exit(opState);
00197         break;
00198     case syscall_id_read:
00199         syscall_read(opState);
00200         break;
00201     case syscall_id_write:
00202         syscall_write(opState);
00203         break;
00204     case syscall_id_readv:
00205         syscall_readv(opState);
00206         break;
00207     case syscall_id_writev:
00208         syscall_writev(opState);
00209         break;
00210     case syscall_id_open:
00211         syscall_open(opState);
00212         break;
00213     case syscall_id_close:
00214         syscall_close(opState);
00215         break;
00216 
00217     case syscall_id_lseek:
00218         syscall_lseek(opState);
00219         break;
00220     case syscall_id_unlink:
00221         syscall_unlink(opState);
00222         break;
00223     case syscall_id_rename:
00224         syscall_rename(opState);
00225         break;
00226 
00227 
00228     case syscall_id_mmap:
00229         syscall_mmap(opState);
00230         break;
00231     case syscall_id_mremap:
00232         syscall_mremap(opState);
00233         break;
00234     case syscall_id_munmap:
00235         syscall_munmap(opState);
00236         break;
00237     //case syscall_id_mprotect:
00238     //  syscall_mprotect(opState);
00239     //  break;
00240     case syscall_id_uname:
00241         syscall_uname(opState);
00242         break;
00243     case syscall_id_fcntl:
00244         syscall_fcntl(opState);
00245         break;
00246     case syscall_id_brk:
00247         syscall_brk(opState);
00248         break;
00249     case syscall_id_getpid:
00250     case syscall_id_gettid:
00251         syscall_getpid(opState);
00252         break;
00253     ////case syscall_id_setuid:
00254     ////    syscall_setuid(opState);
00255     ////    break;
00256     case syscall_id_getuid:
00257         syscall_getuid(opState);
00258         break;
00259     case syscall_id_geteuid:
00260         syscall_geteuid(opState);
00261         break;
00262     case syscall_id_getgid:
00263         syscall_getgid(opState);
00264         break;
00265     case syscall_id_getegid:
00266         syscall_getegid(opState);
00267         break;
00268     //case syscall_id_setgid:
00269     //  syscall_setgid(opState);
00270     //  break;
00271     //case syscall_id_seteuid:
00272     //  syscall_seteuid(opState);
00273     //  break;
00274     //case syscall_id_setegid:
00275     //  syscall_setegid(opState);
00276     //  break;
00277     //case syscall_id_setregid:
00278     //  syscall_setregid(opState);
00279     //  break;
00280     //case syscall_id_setreuid:
00281     //  syscall_setreuid(opState);
00282     //  break;
00283     //case syscall_id_access:
00284     //  syscall_access(opState);
00285     //  break;
00286     case syscall_id_stat:
00287 //  case syscall_id_stat64:
00288         syscall_stat64(opState);
00289         break;
00290     case syscall_id_lstat:
00291 //  case syscall_id_lstat64:
00292         syscall_lstat64(opState);
00293         break;
00294     case syscall_id_fstat:
00295 //  case syscall_id_fstat64:
00296         syscall_fstat64(opState);
00297         break;
00298     case syscall_id_ioctl:
00299         syscall_ioctl(opState);
00300         break;
00301     //case syscall_id_readlink:
00302     //  syscall_readlink(opState);
00303     //  break;
00304     case syscall_id_time:
00305         syscall_time(opState);
00306         break;
00307     case syscall_id_times:
00308         syscall_times(opState);
00309         break;
00310     case syscall_id_gettimeofday:
00311         syscall_gettimeofday(opState);
00312         break;
00313 
00314     case syscall_id_dup:
00315         syscall_dup(opState);
00316         break;
00317     case syscall_id_truncate:
00318         syscall_truncate(opState);
00319         break;
00320     case syscall_id_ftruncate:
00321         syscall_ftruncate(opState);
00322         break;
00323 
00324     case syscall_id_kill:
00325         syscall_kill(opState);
00326         break;
00327     case syscall_id_tgkill:
00328         syscall_tgkill(opState);
00329         break;
00330 
00331 
00332     // signal functions
00333     case syscall_id_rt_sigaction:
00334     case syscall_id_rt_sigprocmask:
00335         syscall_ignore(opState);
00336         break;
00337 
00338     // gcc  stack ggp
00339     case syscall_id_getrlimit:
00340         syscall_ignore(opState);
00341         break;
00342     case syscall_id_setrlimit:
00343         syscall_ignore(opState);
00344         break;
00345 
00346     //case syscall_id_mkdir:
00347     //  syscall_mkdir(opState);
00348     //  break;
00349 
00350     // gcc タsgp
00351     case syscall_id_getrusage:
00352         syscall_ignore(opState);
00353         break;
00354 
00355     case syscall_id_getcwd:
00356         syscall_getcwd(opState);
00357         break;
00358     default:
00359         {
00360             stringstream ss;
00361             ss << "unknown syscall " << GetArg(0) << " called";
00362             THROW_RUNTIME_ERROR(ss.str().c_str());
00363         }
00364     }
00365 #ifdef SYSCALL_DEBUG
00366     if (GetResult(ErrorFlagIndex))
00367         log << " = error " << hex << GetResult(RetValueIndex) << std::endl;
00368     else
00369         log << " = " << hex << GetResult(RetValueIndex) << std::endl;
00370 #endif // #ifdef DEBUG
00371 }
00372 
00373 namespace {
00374     const int PPC64_CLK_TCK = 100;
00375 
00376     const int PPC64_MREMAP_MAYMOVE = 1;
00377     const int PPC64_MAP_NORESERVE = 0x00040;
00378     const int PPC64_MAP_ANONYMOUS = 0x20;
00379 }
00380 
00381 int PPC64LinuxSyscallConv::Get_MAP_ANONYMOUS()
00382 {
00383     return PPC64_MAP_ANONYMOUS;
00384 }
00385 
00386 int PPC64LinuxSyscallConv::Get_MREMAP_MAYMOVE()
00387 {
00388     return PPC64_MREMAP_MAYMOVE;
00389 }
00390 
00391 int PPC64LinuxSyscallConv::Get_CLK_TCK()
00392 {
00393     return PPC64_CLK_TCK;
00394 }
00395 
00396 u32 PPC64LinuxSyscallConv::OpenFlagTargetToHost(u32 flag)
00397 {
00398     static u32 host_open_flags[] =
00399     {
00400         POSIX_O_RDONLY, POSIX_O_WRONLY, POSIX_O_RDWR,
00401         POSIX_O_APPEND,
00402         POSIX_O_CREAT,
00403         POSIX_O_EXCL,
00404         //O_NOCTTY,
00405         //O_NONBLOCK,
00406         //O_SYNC,
00407         POSIX_O_TRUNC,
00408     };
00409     // see bits/fcntl.h
00410     static u32 ppc64_open_flags[] =
00411     {
00412         00, 01, 02, // O_RDONLY, O_WRONLY, O_RDWR,
00413         02000,  // O_APPEND
00414         00100,  // O_CREAT
00415         00200,  // O_EXCL
00416         //00400,    // O_NOCTTY
00417         //04000,    // O_NONBLOCK
00418         //010000,   // O_SYNC
00419         01000,  // O_TRUNC
00420     };
00421     static int open_flags_size = sizeof(host_open_flags)/sizeof(host_open_flags[0]);
00422 
00423     SyscallConstConvBitwise conv(
00424         host_open_flags,
00425         ppc64_open_flags, 
00426         open_flags_size);
00427 
00428     return conv.TargetToHost(flag);
00429 }

Onikiri2に対してTue Jun 18 14:34:19 2013に生成されました。  doxygen 1.4.7