src/Emu/Utility/System/Syscall/Linux64SyscallConv.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 #include <time.h>
00034 
00035 #include "Emu/Utility/System/Syscall/Linux64SyscallConv.h"
00036 
00037 #include "Interface/SystemIF.h"
00038 #include "Env/Env.h"
00039 #include "SysDeps/posix.h"
00040 #include "SysDeps/Endian.h"
00041 
00042 #include "Emu/Utility/System/ProcessState.h"
00043 #include "Emu/Utility/System/Memory/MemorySystem.h"
00044 #include "Emu/Utility/System/Memory/MemoryUtility.h"
00045 #include "Emu/Utility/System/VirtualSystem.h"
00046 #include "Emu/Utility/System/Syscall/SyscallConstConv.h"
00047 #include "Emu/Utility/OpEmulationState.h"
00048 
00049 //#define SYSCALL_DEBUG
00050 
00051 using namespace std;
00052 using namespace boost;
00053 using namespace Onikiri;
00054 using namespace Onikiri::EmulatorUtility;
00055 using namespace Onikiri::POSIX;
00056 
00057 
00058 
00059 // Linux64SyscallConv
00060 Linux64SyscallConv::Linux64SyscallConv(ProcessState* processState)
00061     : m_processState(processState)
00062 {
00063     m_args.resize(MaxArgCount);
00064     m_results.resize(MaxResultCount);
00065 }
00066 
00067 Linux64SyscallConv::~Linux64SyscallConv()
00068 {
00069 }
00070 
00071 void Linux64SyscallConv::SetArg(int index, u64 value)
00072 {
00073     m_args.at(index) = value;
00074 }
00075 
00076 u64 Linux64SyscallConv::GetResult(int index)
00077 {
00078     return m_results.at(index);
00079 }
00080 
00081 void Linux64SyscallConv::SetResult(bool success, u64 result)
00082 {
00083     m_results[RetValueIndex] = result;
00084     m_results[ErrorFlagIndex] = success ? 0 : 1;    // error flag
00085 }
00086 
00087 void Linux64SyscallConv::SetSystem(SystemIF* system)
00088 {
00089     m_simulatorSystem = system;
00090 }
00091 
00092 
00093 //
00094 // タ
00095 //
00096 
00097 
00098 namespace {
00099     struct linux64_stat64
00100     {
00101         u64 linux64_stdev;
00102         u64 linux64_stino;      
00103         u64 linux64_strdev;
00104         s64 linux64_stsize;
00105         u64 linux64_stblocks;
00106         u32 linux64_stmode;
00107         u32 linux64_stuid;
00108         u32 linux64_stgid;
00109         u32 linux64_stblksize;
00110         u32 linux64_stnlink;
00111         s32 pad0;
00112         s64 linux64_statime;
00113         s64 pad1;
00114         s64 linux64_stmtime;
00115         s64 pad2;
00116         s64 linux64_stctime;
00117         s64 pad3;
00118         s64 unused[3];
00119     };
00120 
00121     struct linux64_iovec
00122     {
00123         u64 linux64_iov_base;
00124         u64 linux64_iov_len;
00125     };
00126 
00127     struct linux64_tms
00128     {
00129         s64 linux64_tms_utime;
00130         s64 linux64_tms_stime;
00131         s64 linux64_tms_cutime;
00132         s64 linux64_tms_cstime;
00133     };
00134 
00135     struct linux64_timeval {
00136         s64 linux64_tv_sec;
00137         s64 linux64_tv_usec;
00138     };
00139 
00140     typedef s64 linux64_time_t;
00141 
00142     //const int LINUX_F_DUPFD = 0;
00143     const int LINUX_F_GETFD = 1;
00144     const int LINUX_F_SETFD = 2;
00145 
00146     const int LINUX_F_OK = 0;
00147     const int LINUX_X_OK = 0;
00148     const int LINUX_W_OK = 2;
00149     const int LINUX_R_OK = 4;
00150 
00151     const int LINUX_SEEK_SET = 0;
00152     const int LINUX_SEEK_CUR = 1;
00153     const int LINUX_SEEK_END = 2;
00154 }
00155 
00156 
00157 
00158 void Linux64SyscallConv::syscall_ignore(OpEmulationState* opState)
00159 {
00160     m_results[RetValueIndex] = (u64)0;
00161     m_results[ErrorFlagIndex] = (u64)0;
00162 }
00163 
00164 void Linux64SyscallConv::syscall_exit(OpEmulationState* opState)
00165 {
00166     opState->SetTakenPC(0);
00167     opState->SetTaken(true);
00168 
00169     m_simulatorSystem->NotifyProcessTermination(opState->GetPID());
00170 }
00171 
00172 void Linux64SyscallConv::syscall_getuid(OpEmulationState* opState)
00173 {
00174     SetResult(true, (u64)posix_getuid());
00175 }
00176 
00177 void Linux64SyscallConv::syscall_geteuid(OpEmulationState* opState)
00178 {
00179     SetResult(true, (u64)posix_geteuid());
00180 }
00181 
00182 void Linux64SyscallConv::syscall_getgid(OpEmulationState* opState)
00183 {
00184     SetResult(true, (u64)posix_getgid());
00185 }
00186 
00187 void Linux64SyscallConv::syscall_getegid(OpEmulationState* opState)
00188 {
00189     SetResult(true, (u64)posix_getegid());
00190 }
00191 
00192 void Linux64SyscallConv::syscall_brk(OpEmulationState* opState)
00193 {
00194     if (m_args[1] == 0) {
00195         SetResult(true, GetMemorySystem()->Brk(0));
00196         return;
00197     }
00198 
00199     if (GetMemorySystem()->Brk(m_args[1]) == (u64)-1) {
00200         SetResult(false, ENOMEM);
00201     }
00202     else {
00203         // Linux brkVXeR[CVbreak
00204         SetResult(true, GetMemorySystem()->Brk(0));
00205     }
00206 }
00207 
00208 void Linux64SyscallConv::syscall_mmap(OpEmulationState* opState)
00209 {
00210     u64 result;
00211     if (!(m_args[4] & Get_MAP_ANONYMOUS())) {
00212         result = (u64)-1;
00213     }
00214     else {
00215         result = GetMemorySystem()->MMap(m_args[1], m_args[2]);
00216     }
00217 
00218     if (result == (u64)-1)
00219         SetResult(false, ENOMEM);   // <TODO> errno
00220     else
00221         SetResult(true, result);
00222 }
00223 void Linux64SyscallConv::syscall_mremap(OpEmulationState* opState)
00224 {
00225     u64 result = GetMemorySystem()->MRemap(m_args[1], m_args[2], m_args[3], (m_args[4] & Get_MREMAP_MAYMOVE()) != 0);
00226     if (result == (u64)-1)
00227         SetResult(false, ENOMEM);
00228     else
00229         SetResult(true, result);
00230 }
00231 void Linux64SyscallConv::syscall_munmap(OpEmulationState* opState)
00232 {
00233     int result = GetMemorySystem()->MUnmap(m_args[1], m_args[2]);
00234     if (result == -1)
00235         SetResult(false, EINVAL);
00236     else
00237         SetResult(true, (u64)result);
00238 }
00239 void Linux64SyscallConv::syscall_mprotect(OpEmulationState* opState)
00240 {
00241     SetResult(true, (u64)0);
00242 }
00243 
00244 void Linux64SyscallConv::syscall_uname(OpEmulationState* opState)
00245 {
00246     // linux
00247     struct utsname_linux
00248     {
00249         char sysname[65];
00250         char nodename[65];
00251         char release[65];
00252         char version[65];
00253         char machine[65];
00254     } utsname;
00255 
00256     memset(&utsname, 0, sizeof(utsname));
00257     strcpy(utsname.release, "2.6.23");
00258 
00259     GetMemorySystem()->MemCopyToTarget(m_args[1], &utsname, sizeof(utsname));
00260 
00261     SetResult(true, 0);
00262 }
00263 
00264 
00265 
00266 void Linux64SyscallConv::syscall_getpid(OpEmulationState* opState)
00267 {
00268     SetResult(true, (u64)posix_getpid());
00269 }
00270 
00271 void Linux64SyscallConv::syscall_kill(OpEmulationState* opState)
00272 {
00273     kill_helper(opState, (int)m_args[1], (int)m_args[2]);
00274 }
00275 
00276 void Linux64SyscallConv::syscall_tgkill(OpEmulationState* opState)
00277 {
00278     ASSERT(m_args[1] == m_args[2]);
00279     kill_helper(opState, (int)m_args[1], (int)m_args[3]);
00280 }
00281 
00282 void Linux64SyscallConv::kill_helper(OpEmulationState* opState, int arg_pid, int arg_sig)
00283 {
00284     if (arg_pid == posix_getpid()) {
00285         if (arg_sig == 6)   // SIGABRT
00286             g_env.Print("target program aborted.\n");
00287         else
00288             g_env.Print("signaling with kill not implemented yet.\n");
00289     }
00290     else {
00291         g_env.Print("target program attempted to kill another process.\n");
00292     }
00293 
00294     syscall_exit(opState);
00295 }
00296 
00297 void Linux64SyscallConv::syscall_getcwd(OpEmulationState* opState)
00298 {
00299     int bufSize = (int)m_args[2];
00300 
00301     TargetBuffer buf(GetMemorySystem(), m_args[1], bufSize+1);
00302     void *result = GetVirtualSystem()->GetCWD(static_cast<char*>(buf.Get()), bufSize);
00303     if (result == NULL) {
00304         SetResult(false, GetVirtualSystem()->GetErrno());
00305     }
00306     else {
00307         SetResult(true, m_args[1]);
00308     }
00309 }
00310 
00311 void Linux64SyscallConv::syscall_open(OpEmulationState* opState)
00312 {
00313     std::string fileName = StrCpyToHost( GetMemorySystem(), m_args[1] );
00314     int result = GetVirtualSystem()->Open( 
00315         fileName.c_str(), 
00316         (int)OpenFlagTargetToHost( static_cast<u32>(m_args[2]) ) 
00317     );
00318 
00319     if (result == -1)
00320         SetResult(false, GetVirtualSystem()->GetErrno());
00321     else
00322         SetResult(true, result);
00323 }
00324 
00325 void Linux64SyscallConv::syscall_close(OpEmulationState* opState)
00326 {
00327     int result = GetVirtualSystem()->Close((int)m_args[1]);
00328     if (result == -1)
00329         SetResult(false, GetVirtualSystem()->GetErrno());
00330     else
00331         SetResult(true, result);
00332 }
00333 
00334 void Linux64SyscallConv::syscall_dup(OpEmulationState* opState)
00335 {
00336     int result = GetVirtualSystem()->Dup((int)m_args[1]);
00337     if (result == -1)
00338         SetResult(false, GetVirtualSystem()->GetErrno());
00339     else
00340         SetResult(true, result);
00341 }
00342 
00343 void Linux64SyscallConv::syscall_read(OpEmulationState* opState)
00344 {
00345     unsigned int bufSize = (unsigned int)m_args[3];
00346     TargetBuffer buf(GetMemorySystem(), m_args[2], bufSize);
00347     int result = GetVirtualSystem()->Read((int)m_args[1], buf.Get(),    bufSize);
00348     if (result == -1) {
00349         SetResult(false, GetVirtualSystem()->GetErrno());
00350     }
00351     else {
00352         m_simulatorSystem->NotifySyscallReadFileToMemory(Addr(opState->GetPID(), opState->GetTID(), m_args[2]), bufSize);
00353         SetResult(true, result);
00354     }
00355 }
00356 
00357 void Linux64SyscallConv::syscall_write(OpEmulationState* opState)
00358 {
00359     unsigned int bufSize = (unsigned int)m_args[3];
00360     TargetBuffer buf(GetMemorySystem(), m_args[2], bufSize);
00361     int result = GetVirtualSystem()->Write((int)m_args[1], buf.Get(), bufSize);
00362     if (result == -1) {
00363         SetResult(false, GetVirtualSystem()->GetErrno());
00364     }
00365     else {
00366         m_simulatorSystem->NotifySyscallWriteFileFromMemory(Addr(opState->GetPID(), opState->GetTID(), m_args[2]), bufSize);
00367         SetResult(true, result);
00368     }
00369 }
00370 
00371 
00372 void Linux64SyscallConv::syscall_readv(OpEmulationState* opState)
00373 {
00374     int iovcnt = (int)m_args[3];
00375     s64 result = 0;
00376     const TargetBuffer iovecBuf(GetMemorySystem(), m_args[2], iovcnt*sizeof(linux64_iovec), true);
00377     const linux64_iovec* iovec = static_cast<const linux64_iovec*>(iovecBuf.Get());
00378 
00379     for (int i = 0; i < iovcnt; i ++) {
00380         u64 iov_base = EndianSpecifiedToHost(iovec->linux64_iov_base, GetMemorySystem()->IsBigEndian());
00381         u64 iov_len = EndianSpecifiedToHost(iovec->linux64_iov_len, GetMemorySystem()->IsBigEndian());
00382 
00383         TargetBuffer buf(GetMemorySystem(), iov_base, (size_t)iov_len);
00384         int bytesRead = GetVirtualSystem()->Read((int)m_args[1], buf.Get(), (unsigned int)iov_len);
00385 
00386         if (result == -1 || bytesRead == -1 || (u64)bytesRead != iov_len) {
00387             SetResult(false, GetVirtualSystem()->GetErrno());
00388             result = -1;
00389             break;
00390         }
00391         else {
00392             m_simulatorSystem->NotifySyscallReadFileToMemory(Addr(opState->GetPID(), opState->GetTID(), iov_base), iov_len);
00393             result += iov_len;
00394         }
00395         iovec++;
00396     }
00397     SetResult(true, result);
00398 }
00399 
00400 void Linux64SyscallConv::syscall_writev(OpEmulationState* opState)
00401 {
00402     int iovcnt = (int)m_args[3];
00403     s64 result = 0;
00404     const TargetBuffer iovecBuf(GetMemorySystem(), m_args[2], iovcnt*sizeof(linux64_iovec), true);
00405     const linux64_iovec* iovec = static_cast<const linux64_iovec*>(iovecBuf.Get());
00406 
00407     for (int i = 0; i < iovcnt; i ++) {
00408         u64 iov_base = EndianSpecifiedToHost(iovec->linux64_iov_base, GetMemorySystem()->IsBigEndian());
00409         u64 iov_len = EndianSpecifiedToHost(iovec->linux64_iov_len, GetMemorySystem()->IsBigEndian());
00410 
00411         TargetBuffer buf(GetMemorySystem(), iov_base, (size_t)iov_len);
00412         int bytesWritten = GetVirtualSystem()->Write((int)m_args[1], buf.Get(), (unsigned int)iov_len);
00413 
00414         if (result == -1 || bytesWritten == -1 || (u64)bytesWritten != iov_len) {
00415             SetResult(false, GetVirtualSystem()->GetErrno());
00416             result = -1;
00417             break;
00418         }
00419         else {
00420             m_simulatorSystem->NotifySyscallWriteFileFromMemory(Addr(opState->GetPID(), opState->GetTID(), iov_base), iov_len);
00421             result += iov_len;
00422         }
00423         iovec++;
00424     }
00425     SetResult(true, result);
00426 }
00427 
00428 void Linux64SyscallConv::syscall_lseek(OpEmulationState* opState)
00429 {
00430     s64 result = GetVirtualSystem()->LSeek((int)m_args[1], m_args[2], (int)SeekWhenceTargetToHost((u32)m_args[3]));
00431     if (result == -1)
00432         SetResult(false, GetVirtualSystem()->GetErrno());
00433     else
00434         SetResult(true, (u64)result);
00435 }
00436 
00437 void Linux64SyscallConv::syscall_fstat64(OpEmulationState* opState)
00438 {
00439     HostStat st;
00440     int result = GetVirtualSystem()->FStat((int)m_args[1], &st);
00441     if (result == -1) {
00442         SetResult(false, GetVirtualSystem()->GetErrno());
00443     }
00444     else {
00445 #ifdef HOST_IS_WINDOWS
00446         /*
00447         st.st_rdev  Windows  st.st_dev A
00448         (http://msdn.microsoft.com/ja-jp/library/14h5k7ff.aspx)
00449         Linux t@ClB
00450         Wo 0x8801 HivoTj
00451          st_rdev タspXAzXgogp
00452          0x8801 B
00453         i mcf  if(st.st_rdev >> 4)  Copyright A
00454         lタspXj
00455         */
00456         if(GetVirtualSystem()->GetDelayUnlinker()->GetMapPath((int)m_args[1]) == "HostIO"){
00457             st.st_rdev = 0x8801;
00458         }
00459 #endif
00460         write_stat64((u64)m_args[2], st);
00461         SetResult(true, result);
00462     }
00463 }
00464 
00465 void Linux64SyscallConv::syscall_stat64(OpEmulationState* opState)
00466 {
00467     HostStat st;
00468     string path = StrCpyToHost( GetMemorySystem(), m_args[1] );
00469     int result = GetVirtualSystem()->Stat(path.c_str(), &st);
00470     if (result == -1) {
00471         SetResult(false, GetVirtualSystem()->GetErrno());
00472     }
00473     else {
00474         write_stat64((u64)m_args[2], st);
00475         SetResult(true, result);
00476     }
00477 }
00478 
00479 void Linux64SyscallConv::syscall_lstat64(OpEmulationState* opState)
00480 {
00481     HostStat st;
00482     string path = StrCpyToHost( GetMemorySystem(), m_args[1] );
00483     int result = GetVirtualSystem()->LStat(path.c_str(), &st);
00484     if (result == -1) {
00485         SetResult(false, GetVirtualSystem()->GetErrno());
00486     }
00487     else {
00488         write_stat64((u64)m_args[2], st);
00489         SetResult(true, result);
00490     }
00491 }
00492 
00493 void Linux64SyscallConv::syscall_fcntl(OpEmulationState* opState)
00494 {
00495     int cmd = (int)m_args[2];
00496     switch (cmd) {
00497     case LINUX_F_GETFD:
00498     case LINUX_F_SETFD:
00499         SetResult(true, 0);
00500         break;
00501     default:
00502         THROW_RUNTIME_ERROR("syscall_fcntl : unknown cmd");
00503     }
00504 }
00505 
00506 void Linux64SyscallConv::syscall_mkdir(OpEmulationState* opState)
00507 {
00508     string path = StrCpyToHost( GetMemorySystem(), m_args[1] );
00509     int result = GetVirtualSystem()->MkDir(path.c_str(), (int)m_args[2]);
00510     if (result == -1) {
00511         SetResult(false, GetVirtualSystem()->GetErrno());
00512     }
00513     else {
00514         SetResult(true, result);
00515     }
00516 }
00517 
00518 void Linux64SyscallConv::syscall_access(OpEmulationState* opState)
00519 {
00520     string path = StrCpyToHost( GetMemorySystem(), m_args[1] );
00521     int result = GetVirtualSystem()->Access( path.c_str(), (int)AccessModeTargetToHost((u32)m_args[2]) );
00522     if (result == -1)
00523         SetResult(false, GetVirtualSystem()->GetErrno());
00524     else
00525         SetResult(true, result);
00526 }
00527 
00528 void Linux64SyscallConv::syscall_unlink(OpEmulationState* opState)
00529 {
00530     string path = StrCpyToHost( GetMemorySystem(), m_args[1] );
00531     int result = GetVirtualSystem()->Unlink( path.c_str() );
00532     if (result == -1)
00533         SetResult(false, GetVirtualSystem()->GetErrno());
00534     else
00535         SetResult(true, result);
00536 }
00537 
00538 void Linux64SyscallConv::syscall_rename(OpEmulationState* opState)
00539 {
00540     string oldpath = StrCpyToHost( GetMemorySystem(), m_args[1] );
00541     string newpath = StrCpyToHost( GetMemorySystem(), m_args[2] );
00542 
00543     int result = GetVirtualSystem()->Rename( oldpath.c_str(), newpath.c_str() );
00544     if (result == -1)
00545         SetResult(false, GetVirtualSystem()->GetErrno());
00546     else
00547         SetResult(true, result);
00548 }
00549 
00550 void Linux64SyscallConv::syscall_truncate(OpEmulationState* opState)
00551 {
00552     string path = StrCpyToHost( GetMemorySystem(), m_args[1] );
00553     int result = GetVirtualSystem()->Truncate( path.c_str(), (s64)m_args[2] );
00554     if (result == -1)
00555         SetResult(false, GetVirtualSystem()->GetErrno());
00556     else
00557         SetResult(true, result);
00558 }
00559 
00560 void Linux64SyscallConv::syscall_ftruncate(OpEmulationState* opState)
00561 {
00562     int result = GetVirtualSystem()->FTruncate( (int)m_args[1], (s64)m_args[2] );
00563     if (result == -1)
00564         SetResult(false, GetVirtualSystem()->GetErrno());
00565     else
00566         SetResult(true, result);
00567 }
00568 
00569 void Linux64SyscallConv::syscall_time(OpEmulationState* opState)
00570 {
00571     s64 result = GetVirtualSystem()->GetTime();
00572     if (m_args[1] != 0) {
00573         TargetBuffer buf(GetMemorySystem(), m_args[1], sizeof(linux64_time_t));
00574         linux64_time_t* ptime = static_cast<linux64_time_t*>(buf.Get());
00575         *ptime = EndianHostToSpecified(result, GetMemorySystem()->IsBigEndian());
00576     }
00577     SetResult(true, result);
00578 }
00579 
00580 void Linux64SyscallConv::syscall_times(OpEmulationState* opState)
00581 {
00582     TargetBuffer buf(GetMemorySystem(), m_args[1], sizeof(linux64_tms));
00583     linux64_tms* tms_buf = static_cast<linux64_tms*>(buf.Get());
00584 
00585     s64 clk = GetVirtualSystem()->GetClock();
00586     u64 result = (u64)((double)clk / CLOCKS_PER_SEC * Get_CLK_TCK());
00587     tms_buf->linux64_tms_utime = EndianHostToSpecified(result, GetMemorySystem()->IsBigEndian());
00588     tms_buf->linux64_tms_stime = 0;
00589     tms_buf->linux64_tms_cutime = 0;
00590     tms_buf->linux64_tms_cstime = 0;
00591 
00592     SetResult(true, result);
00593 }
00594 
00595 void Linux64SyscallConv::syscall_gettimeofday(OpEmulationState* opState)
00596 {
00597     if (m_args[2] != 0) {
00598         // timezone obsoleteT|[g
00599         SetResult(false, EINVAL);
00600         return;
00601     }
00602     TargetBuffer buf(GetMemorySystem(), m_args[1], sizeof(linux64_timeval));
00603     linux64_timeval* tv_buf = static_cast<linux64_timeval*>(buf.Get());
00604 
00605     s64 t = GetVirtualSystem()->GetTime();
00606     tv_buf->linux64_tv_sec = EndianHostToSpecified((u64)t, GetMemorySystem()->IsBigEndian());
00607     tv_buf->linux64_tv_usec = EndianHostToSpecified((u64)t * 1000 * 1000, GetMemorySystem()->IsBigEndian());
00608 
00609     SetResult(true, 0);
00610 }
00611 
00612 void Linux64SyscallConv::syscall_ioctl(OpEmulationState* opState)
00613 {
00614     const int LINUX_TCGETS = 0x402c7413;
00615 
00616     // LINUX_TCGETSCisatty
00617     // isatty CG[
00618     if ((int)m_args[2] == LINUX_TCGETS) {
00619         const int ERRNO_ENOTTY = 25;
00620         // t@C
00621         // TTY(success)CglibcTTYfoCXreadlinko (ttyname)
00622         if (false) {
00623             SetResult(true, 0);
00624         }
00625         else {
00626             SetResult(false, ERRNO_ENOTTY);
00627         }
00628     }
00629     else {
00630         SetResult(false, EINVAL);
00631     }
00632 }
00633 
00634 u32 Linux64SyscallConv::SeekWhenceTargetToHost(u32 flag)
00635 {
00636     static u32 host_whence[] =
00637     {
00638         POSIX_SEEK_SET,
00639         POSIX_SEEK_CUR,
00640         POSIX_SEEK_END
00641     };
00642     static u32 linux_whence[] =
00643     {
00644         LINUX_SEEK_SET,
00645         LINUX_SEEK_CUR,
00646         LINUX_SEEK_END
00647     };
00648     static int whence_size = sizeof(host_whence)/sizeof(host_whence[0]);
00649     SyscallConstConvEnum conv(
00650         host_whence,
00651         linux_whence, 
00652         whence_size);
00653 
00654     return conv.TargetToHost(flag);
00655 }
00656 
00657 
00658 u32 Linux64SyscallConv::AccessModeTargetToHost(u32 flag)
00659 {
00660     static u32 host_access_mode[] =
00661     {
00662         POSIX_F_OK,
00663         POSIX_X_OK,
00664         POSIX_W_OK,
00665         POSIX_R_OK
00666     };
00667     static u32 linux_access_mode[] =
00668     {
00669         LINUX_F_OK,
00670         LINUX_X_OK,
00671         LINUX_W_OK,
00672         LINUX_R_OK
00673     };
00674     static int access_mode_size = sizeof(host_access_mode)/sizeof(host_access_mode[0]);
00675     SyscallConstConvBitwise conv(
00676         host_access_mode,
00677         linux_access_mode, 
00678         access_mode_size);
00679 
00680     return conv.TargetToHost(flag);
00681 }
00682 
00683 
00684 void Linux64SyscallConv::write_stat64(u64 dest, const HostStat &src)
00685 {
00686     static u32 host_st_mode[] =
00687     {
00688         POSIX_S_IFDIR,
00689         POSIX_S_IFCHR,
00690         POSIX_S_IFREG,
00691         POSIX_S_IFIFO,
00692     };
00693     static u32 linux64_st_mode[] =
00694     {
00695         0040000, // _S_IFDIR
00696         0020000, // _S_IFCHR
00697         0100000, // _S_IFREG
00698         0010000, // _S_IFIFO
00699     };
00700     static int st_mode_size = sizeof(host_st_mode)/sizeof(host_st_mode[0]);
00701     SyscallConstConvBitwise conv(
00702         host_st_mode,
00703         linux64_st_mode, 
00704         st_mode_size);
00705 
00706     TargetBuffer buf(GetMemorySystem(), dest, sizeof(linux64_stat64));
00707     linux64_stat64* t_buf = static_cast<linux64_stat64*>(buf.Get());
00708     memset(t_buf, 0, sizeof(linux64_stat64));
00709 
00710     t_buf->linux64_stdev = src.st_dev;
00711     t_buf->linux64_stino = src.st_ino;
00712     t_buf->linux64_strdev = src.st_rdev;
00713     t_buf->linux64_stsize = src.st_size;
00714     t_buf->linux64_stuid = src.st_uid;
00715     t_buf->linux64_stgid = src.st_gid;
00716     t_buf->linux64_stnlink = src.st_nlink;
00717     t_buf->linux64_statime = src.st_atime;
00718     t_buf->linux64_stmtime = src.st_mtime;
00719     t_buf->linux64_stctime = src.st_ctime;
00720 
00721     // st_blksize : It@CEVXeIO s"D"ubNETCY
00722     //              CentOS4 32768
00723     // st_blocks  : t@C512B 
00724     //              CentOS4 8 H
00725 
00726 #if defined(HOST_IS_WINDOWS) || defined(HOST_IS_CYGWIN)
00727     static const int BLOCK_UNIT = 512*8;
00728     t_buf->linux64_stmode    = conv.HostToTarget(src.st_mode);
00729     t_buf->linux64_stblocks  = (src.st_size+BLOCK_UNIT-1)/BLOCK_UNIT*8;
00730     t_buf->linux64_stblksize = 32768;
00731 #else
00732     t_buf->linux64_stblocks = src.st_blocks;
00733     t_buf->linux64_stmode = src.st_mode;
00734     t_buf->linux64_stblksize = src.st_blksize;
00735 #endif
00736 
00737     // hoststat(src)vftargetstatvfTCYCUtargetstatGfBA
00738     bool bigEndian = GetMemorySystem()->IsBigEndian();
00739     EndianHostToSpecifiedInPlace(t_buf->linux64_stdev, bigEndian);
00740     EndianHostToSpecifiedInPlace(t_buf->linux64_stino, bigEndian);
00741     EndianHostToSpecifiedInPlace(t_buf->linux64_strdev, bigEndian);
00742     EndianHostToSpecifiedInPlace(t_buf->linux64_stsize, bigEndian);
00743     EndianHostToSpecifiedInPlace(t_buf->linux64_stuid, bigEndian);
00744     EndianHostToSpecifiedInPlace(t_buf->linux64_stgid, bigEndian);
00745     EndianHostToSpecifiedInPlace(t_buf->linux64_stnlink, bigEndian);
00746     EndianHostToSpecifiedInPlace(t_buf->linux64_statime, bigEndian);
00747     EndianHostToSpecifiedInPlace(t_buf->linux64_stmtime, bigEndian);
00748     EndianHostToSpecifiedInPlace(t_buf->linux64_stctime, bigEndian);
00749     EndianHostToSpecifiedInPlace(t_buf->linux64_stmode, bigEndian);
00750     EndianHostToSpecifiedInPlace(t_buf->linux64_stblocks, bigEndian);
00751     EndianHostToSpecifiedInPlace(t_buf->linux64_stblksize, bigEndian);
00752 }
00753 

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