From: <mic...@us...> - 2007-04-21 19:45:02
|
Revision: 79 http://svn.sourceforge.net/pearcolator/?rev=79&view=rev Author: michael_baer Date: 2007-04-21 12:44:59 -0700 (Sat, 21 Apr 2007) Log Message: ----------- - Added ABI support for ARM linux: legacy ABI and ARM EABI - Fixed bug in system call interface - fixed ARM decoder bugs Modified Paths: -------------- src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxSyscallArgumentIterator.java src/org/binarytranslator/generic/execution/InterpreterController.java src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java Added Paths: ----------- src/org/binarytranslator/arch/arm/os/process/linux/abi/ src/org/binarytranslator/arch/arm/os/process/linux/abi/EABI.java src/org/binarytranslator/arch/arm/os/process/linux/abi/Legacy.java Removed Paths: ------------- src/org/binarytranslator/arch/arm/os/process/linux/ARM_SyscallArgumentIterator.java Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Disassembler.java 2007-04-21 19:44:59 UTC (rev 79) @@ -317,7 +317,7 @@ String registers = ""; - for (int i = 0; i < 15; i++) + for (int i = 0; i <= 15; i++) if (instr.transferRegister(i)) registers += ", r" + i; Modified: src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java =================================================================== --- src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/arch/arm/decoder/ARM_Interpreter.java 2007-04-21 19:44:59 UTC (rev 79) @@ -691,7 +691,7 @@ transferPC = transferRegister(15); int regCount = 0; - for (int i = 0; i < 14; i++) + for (int i = 0; i <= 14; i++) if (transferRegister(i)) { registersToTransfer[regCount++] = i; } @@ -756,7 +756,7 @@ //also transfer the program counter, if requested so if (transferPC) { nextAddress += 4; - ps.memory.store32(nextAddress, regs.get(15)); + ps.memory.store32(nextAddress, regs.get(15) + 8); } } Modified: src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java =================================================================== --- src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/arch/arm/os/abi/linux/ARM_LinuxSystemCalls.java 2007-04-21 19:44:59 UTC (rev 79) @@ -7,6 +7,26 @@ public ARM_LinuxSystemCalls(LinuxSystemCallGenerator src) { super(src); + + systemCallTable[1] = new LinuxSystemCalls.SysExit(); + systemCallTable[3] = new LinuxSystemCalls.SysRead(); + systemCallTable[4] = new LinuxSystemCalls.SysWrite(); + systemCallTable[5] = new LinuxSystemCalls.SysOpen(); + systemCallTable[6] = new LinuxSystemCalls.SysClose(); + systemCallTable[24] = new LinuxSystemCalls.SysGetUID(); + systemCallTable[45] = new LinuxSystemCalls.SysBrk(); + systemCallTable[47] = new LinuxSystemCalls.SysGetGID(); + systemCallTable[49] = new LinuxSystemCalls.SysGetEUID(); + systemCallTable[50] = new LinuxSystemCalls.SysGetEGID(); + systemCallTable[90] = new LinuxSystemCalls.SysMmap(); + systemCallTable[122] = new LinuxSystemCalls.SysUname(); + systemCallTable[146] = new LinuxSystemCalls.SysWriteV(); + systemCallTable[199] = new LinuxSystemCalls.SysGetEUID(); + systemCallTable[200] = new LinuxSystemCalls.SysGetEGID(); + systemCallTable[201] = new LinuxSystemCalls.SysGetEUID(); + systemCallTable[202] = new LinuxSystemCalls.SysGetEGID(); + systemCallTable[221] = new LinuxSystemCalls.SysFcntl64(); + systemCallTable[252] = new LinuxSystemCalls.SysExitGroup(); } @Override @@ -17,7 +37,308 @@ @Override public String sysCallToString(int syscall) { - throw new RuntimeException("Not yet implemented."); + switch(syscall) { + case 0: return "restart_syscall"; + case 1: return "exit"; + case 2: return "fork"; + case 3: return "read"; + case 4: return "write"; + case 5: return "open"; + case 6: return "close"; + case 7: return "waitpid"; + case 8: return "creat"; + case 9: return "link"; + case 10: return "unlink"; + case 11: return "execve"; + case 12: return "chdir"; + case 13: return "time"; + case 14: return "mknod"; + case 15: return "chmod"; + case 16: return "lchown"; + case 17: return "break"; + case 18: return "oldstat"; + case 19: return "lseek"; + case 20: return "getpid"; + case 21: return "mount"; + case 22: return "umount"; + case 23: return "setuid"; + case 24: return "getuid"; + case 25: return "stime"; + case 26: return "ptrace"; + case 27: return "alarm"; + case 28: return "oldfstat"; + case 29: return "pause"; + case 30: return "utime"; + case 31: return "stty"; + case 32: return "gtty"; + case 33: return "access"; + case 34: return "nice"; + case 35: return "ftime"; + case 36: return "sync"; + case 37: return "kill"; + case 38: return "rename"; + case 39: return "mkdir"; + case 40: return "rmdir"; + case 41: return "dup"; + case 42: return "pipe"; + case 43: return "times"; + case 44: return "prof"; + case 45: return "brk"; + case 46: return "setgid"; + case 47: return "getgid"; + case 48: return "signal"; + case 49: return "geteuid"; + case 50: return "getegid"; + case 51: return "acct"; + case 52: return "umount2"; + case 53: return "lock"; + case 54: return "ioctl"; + case 55: return "fcntl"; + case 56: return "mpx"; + case 57: return "setpgid"; + case 58: return "ulimit"; + case 59: return "oldolduname"; + case 60: return "umask"; + case 61: return "chroot"; + case 62: return "ustat"; + case 63: return "dup2"; + case 64: return "getppid"; + case 65: return "getpgrp"; + case 66: return "setsid"; + case 67: return "sigaction"; + case 68: return "sgetmask"; + case 69: return "ssetmask"; + case 70: return "setreuid"; + case 71: return "setregid"; + case 72: return "sigsuspend"; + case 73: return "sigpending"; + case 74: return "sethostname"; + case 75: return "setrlimit"; + case 76: return "getrlimit"; + case 77: return "getrusage"; + case 78: return "gettimeofday"; + case 79: return "settimeofday"; + case 80: return "getgroups"; + case 81: return "setgroups"; + case 82: return "select"; + case 83: return "symlink"; + case 84: return "oldlstat"; + case 85: return "readlink"; + case 86: return "uselib"; + case 87: return "swapon"; + case 88: return "reboot"; + case 89: return "readdir"; + case 90: return "mmap"; + case 91: return "munmap"; + case 92: return "truncate"; + case 93: return "ftruncate"; + case 94: return "fchmod"; + case 95: return "fchown"; + case 96: return "getpriority"; + case 97: return "setpriority"; + case 98: return "profil"; + case 99: return "statfs"; + case 100: return "fstatfs"; + case 101: return "ioperm"; + case 102: return "socketcall"; + case 103: return "syslog"; + case 104: return "setitimer"; + case 105: return "getitimer"; + case 106: return "stat"; + case 107: return "lstat"; + case 108: return "fstat"; + case 109: return "olduname"; + case 110: return "iopl"; + case 111: return "vhangup"; + case 112: return "idle"; + case 113: return "vm86old"; + case 114: return "wait4"; + case 115: return "swapoff"; + case 116: return "sysinfo"; + case 117: return "ipc"; + case 118: return "fsync"; + case 119: return "sigreturn"; + case 120: return "clone"; + case 121: return "setdomainname"; + case 122: return "uname"; + case 123: return "modify_ldt"; + case 124: return "adjtimex"; + case 125: return "mprotect"; + case 126: return "sigprocmask"; + case 127: return "create_module"; + case 128: return "init_module"; + case 129: return "delete_module"; + case 130: return "get_kernel_syms"; + case 131: return "quotactl"; + case 132: return "getpgid"; + case 133: return "fchdir"; + case 134: return "bdflush"; + case 135: return "sysfs"; + case 136: return "personality"; + case 137: return "afs_syscall"; + case 138: return "setfsuid"; + case 139: return "setfsgid"; + case 140: return "_llseek"; + case 141: return "getdents"; + case 142: return "_newselect"; + case 143: return "flock"; + case 144: return "msync"; + case 145: return "readv"; + case 146: return "writev"; + case 147: return "getsid"; + case 148: return "fdatasync"; + case 149: return "_sysctl"; + case 150: return "mlock"; + case 151: return "munlock"; + case 152: return "mlockall"; + case 153: return "munlockall"; + case 154: return "sched_setparam"; + case 155: return "sched_getparam"; + case 156: return "sched_setscheduler"; + case 157: return "sched_getscheduler"; + case 158: return "sched_yield"; + case 159: return "sched_get_priority_max"; + case 160: return "sched_get_priority_min"; + case 161: return "sched_rr_get_interval"; + case 162: return "nanosleep"; + case 163: return "mremap"; + case 164: return "setresuid"; + case 165: return "getresuid"; + case 166: return "vm86"; + case 167: return "query_module"; + case 168: return "poll"; + case 169: return "nfsservctl"; + case 170: return "setresgid"; + case 171: return "getresgid"; + case 172: return "prctl"; + case 173: return "rt_sigreturn"; + case 174: return "rt_sigaction"; + case 175: return "rt_sigprocmask"; + case 176: return "rt_sigpending"; + case 177: return "rt_sigtimedwait"; + case 178: return "rt_sigqueueinfo"; + case 179: return "rt_sigsuspend"; + case 180: return "pread64"; + case 181: return "pwrite64"; + case 182: return "chown"; + case 183: return "getcwd"; + case 184: return "capget"; + case 185: return "capset"; + case 186: return "sigaltstack"; + case 187: return "sendfile"; + case 188: return "getpmsg"; + case 189: return "putpmsg"; + case 190: return "vfork"; + case 191: return "ugetrlimit"; + case 192: return "mmap2"; + case 193: return "truncate64"; + case 194: return "ftruncate64"; + case 195: return "stat64"; + case 196: return "lstat64"; + case 197: return "fstat64"; + case 198: return "lchown32"; + case 199: return "getuid32"; + case 200: return "getgid32"; + case 201: return "geteuid32"; + case 202: return "getegid32"; + case 203: return "setreuid32"; + case 204: return "setregid32"; + case 205: return "getgroups32"; + case 206: return "setgroups32"; + case 207: return "fchown32"; + case 208: return "setresuid32"; + case 209: return "getresuid32"; + case 210: return "setresgid32"; + case 211: return "getresgid32"; + case 212: return "chown32"; + case 213: return "setuid32"; + case 214: return "setgid32"; + case 215: return "setfsuid32"; + case 216: return "setfsgid32"; + case 217: return "pivot_root"; + case 218: return "mincore"; + case 219: return "madvise"; + case 220: return "getdents64"; + case 221: return "fcntl64"; + + case 224: return "gettid"; + case 225: return "readahead"; + case 226: return "setxattr"; + case 227: return "lsetxattr"; + case 228: return "fsetxattr"; + case 229: return "getxattr"; + case 230: return "lgetxattr"; + case 231: return "fgetxattr"; + case 232: return "listxattr"; + case 233: return "llistxattr"; + case 234: return "flistxattr"; + case 235: return "removexattr"; + case 236: return "lremovexattr"; + case 237: return "fremovexattr"; + case 238: return "tkill"; + case 239: return "sendfile64"; + case 240: return "futex"; + case 241: return "sched_setaffinity"; + case 242: return "sched_getaffinity"; + case 243: return "set_thread_area"; + case 244: return "get_thread_area"; + case 245: return "io_setup"; + case 246: return "io_destroy"; + case 247: return "io_getevents"; + case 248: return "io_submit"; + case 249: return "io_cancel"; + case 250: return "fadvise64"; + case 251: return "set_zone_reclaim"; + case 252: return "exit_group"; + case 253: return "lookup_dcookie"; + case 254: return "epoll_create"; + case 255: return "epoll_ctl"; + case 256: return "epoll_wait"; + case 257: return "remap_file_pages"; + case 258: return "set_tid_address"; + case 259: return "timer_create"; + case 260: return "timer_settime"; + case 261: return "timer_gettime"; + case 262: return "timer_getoverrun"; + case 263: return "timer_delete"; + case 264: return "clock_settime"; + case 265: return "clock_gettime"; + case 266: return "clock_getres"; + case 267: return "clock_nanosleep"; + case 268: return "statfs64"; + case 269: return "fstatfs64"; + case 270: return "tgkill"; + case 271: return "utimes"; + case 272: return "fadvise64_64"; + case 273: return "vserver"; + case 274: return "mbind"; + case 275: return "get_mempolicy"; + case 276: return "set_mempolicy"; + case 277: return "mq_open"; + case 278: return "mq_unlink"; + case 279: return "mq_timedsend"; + case 280: return "mq_timedreceive"; + case 281: return "mq_notify"; + case 282: return "mq_getsetattr"; + case 283: return "sys_kexec_load"; + case 284: return "waitid"; + case 285: return "sys_setaltroot"; + case 286: return "add_key"; + case 287: return "request_key"; + case 288: return "keyctl"; + case 289: return "ioprio_set"; + case 290: return "ioprio_get"; + case 291: return "inotify_init"; + case 292: return "inotify_add_watch"; + case 293: return "inotify_rm_watch"; + default: + if ((syscall > 0) && (syscall < 294)) { + return "unused"; + } + else { + return "invalid system call number " + syscall; + } + } } } Modified: src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/arch/arm/os/process/ARM_ProcessSpace.java 2007-04-21 19:44:59 UTC (rev 79) @@ -5,7 +5,6 @@ import org.binarytranslator.arch.arm.decoder.ARM_Interpreter; import org.binarytranslator.arch.arm.os.process.image.ARM_ImageProcessSpace; import org.binarytranslator.arch.arm.os.process.linux.ARM_LinuxProcessSpace; -import org.binarytranslator.arch.x86.decoder.X86_InstructionDecoder; import org.binarytranslator.generic.decoder.Interpreter; import org.binarytranslator.generic.memory.DebugMemory; import org.binarytranslator.generic.os.loader.Loader; Modified: src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-04-21 19:44:59 UTC (rev 79) @@ -4,29 +4,25 @@ import org.binarytranslator.arch.arm.os.abi.linux.ARM_LinuxSystemCalls; import org.binarytranslator.arch.arm.os.process.ARM_ProcessSpace; import org.binarytranslator.arch.arm.os.process.ARM_Registers; +import org.binarytranslator.arch.arm.os.process.linux.abi.Legacy; import org.binarytranslator.generic.execution.GdbController.GdbTarget; import org.binarytranslator.generic.os.abi.linux.LinuxStackInitializer; import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; import org.binarytranslator.generic.os.abi.linux.LinuxSystemCalls; import org.binarytranslator.generic.os.loader.Loader; import org.binarytranslator.generic.os.loader.elf.ELF_Loader; -import org.binarytranslator.generic.os.process.ProcessSpace; -public class ARM_LinuxProcessSpace extends ARM_ProcessSpace implements - LinuxSystemCallGenerator { +public class ARM_LinuxProcessSpace extends ARM_ProcessSpace { /** * A link to the current system call interface */ private final LinuxSystemCalls sysCalls; + + /** As ARM provides two different linux ABIs, we put the system call specifics into a separate class.*/ + private final LinuxSystemCallGenerator sysCallGenerator; /** - * A re-used iterator that allows enumerating the argument of the current - * system call - */ - private final ARM_SyscallArgumentIterator syscallArgs; - - /** * The top of the stack */ private static final int STACK_TOP = 0xC0000000; @@ -37,13 +33,17 @@ private int brk; public ARM_LinuxProcessSpace() { - sysCalls = new ARM_LinuxSystemCalls(this); - syscallArgs = new ARM_SyscallArgumentIterator(this); + sysCallGenerator = new Legacy(this); + sysCalls = new ARM_LinuxSystemCalls(sysCallGenerator); } @Override public void doSysCall() { sysCalls.doSysCall(); + + //simulate a return from the call + //TODO: This actually assumes that we're calling from ARM32 + registers.set(ARM_Registers.PC, getCurrentInstructionAddress() + 4); } @Override @@ -75,38 +75,9 @@ registers.set(ARM_Registers.SP, LinuxStackInitializer.stackInit(memory, STACK_TOP, getEnvironmentVariables(), auxVector)); } - public int getBrk() { - return brk; - } - - public int getSysCallNumber() { - // TODO Auto-generated method stub - return 0; - } - - public CallArgumentIterator getSysCallArguments() { - syscallArgs.reset(); - return syscallArgs; - } - - public void setBrk(int address) { - brk = address; - } - - public void setSysCallError(int r) { - // TODO Auto-generated method stub - } - - public void setSysCallReturn(int r) { - // TODO Auto-generated method stub - } - @Override public GdbTarget getGdbTarget() { return null; } - public ProcessSpace getProcessSpace() { - return this; - } } Deleted: src/org/binarytranslator/arch/arm/os/process/linux/ARM_SyscallArgumentIterator.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/linux/ARM_SyscallArgumentIterator.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/arch/arm/os/process/linux/ARM_SyscallArgumentIterator.java 2007-04-21 19:44:59 UTC (rev 79) @@ -1,37 +0,0 @@ -package org.binarytranslator.arch.arm.os.process.linux; - -import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; - -public class ARM_SyscallArgumentIterator implements - LinuxSystemCallGenerator.CallArgumentIterator { - - private final ARM_LinuxProcessSpace ps; - - private int currentArgument; - - public ARM_SyscallArgumentIterator(ARM_LinuxProcessSpace ps) { - this.ps = ps; - this.currentArgument = 0; - } - - public int nextInt() { - return ps.registers.get(currentArgument++); - } - - public long nextLong() { - // only start reading longs from even registers - if ((currentArgument & 1) == 1) - currentArgument++; - - // TODO: This code is actually assuming that we're on little endian - long lowWord = nextInt(); - long highWord = nextInt(); - - return highWord << 32 | lowWord; - } - - public void reset() { - currentArgument = 0; - } - -} Added: src/org/binarytranslator/arch/arm/os/process/linux/abi/EABI.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/linux/abi/EABI.java (rev 0) +++ src/org/binarytranslator/arch/arm/os/process/linux/abi/EABI.java 2007-04-21 19:44:59 UTC (rev 79) @@ -0,0 +1,103 @@ +package org.binarytranslator.arch.arm.os.process.linux.abi; + +import org.binarytranslator.arch.arm.os.process.linux.ARM_LinuxProcessSpace; +import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; +import org.binarytranslator.generic.os.process.ProcessSpace; + +/** + * ARM EABI linux system call ABI. + * <code> + * Example call to long ftruncate64(unsigned int fd, loff_t length): + * + * EABI ABI: + * - put fd into r0 + * - put length into r2-r3 (skipping over r1) + * - put 194 into r7 + * - use "swi #0" to call the kernel + * + * </code> + * + * Therefore, note that long values are aligned to even registers. + * The holes, which are created within the register map are not filled, though. + * + * @author Michael Baer + * + */ +public class EABI implements LinuxSystemCallGenerator { + + /** The process space that we're running on. */ + private final ARM_LinuxProcessSpace ps; + private final ArgumentIterator args; + + public EABI(ARM_LinuxProcessSpace ps) { + this.ps = ps; + this.args = new ArgumentIterator(); + } + + public int getBrk() { + // TODO Auto-generated method stub + throw new RuntimeException("Not yet implemented."); + } + + public ProcessSpace getProcessSpace() { + return ps; + } + + public CallArgumentIterator getSysCallArguments() { + args.reset(); + return args; + } + + public int getSysCallNumber() { + return ps.registers.get(7); + } + + public void setBrk(int address) { +// TODO Auto-generated method stub + throw new RuntimeException("Not yet implemented."); + } + + public void setSysCallError(int r) { + // TODO Auto-generated method stub + throw new RuntimeException("Not yet implemented."); + } + + public void setSysCallReturn(int r) { + // TODO Auto-generated method stub + throw new RuntimeException("Not yet implemented."); + } + + /** An argument iterator that hides the layout of syscall arguments on the ARM architecture */ + public final class ArgumentIterator implements + LinuxSystemCallGenerator.CallArgumentIterator { + + /** The current argument number. Set to zero for the first agument.*/ + private int currentArgument; + + public ArgumentIterator() { + this.currentArgument = 0; + } + + public int nextInt() { + return ps.registers.get(currentArgument++); + } + + public long nextLong() { + // only start reading longs from even registers + if ((currentArgument & 1) != 0) + currentArgument++; + + // TODO: This code is actually assuming that we're on little endian + long lowWord = nextInt(); + long highWord = nextInt(); + + return highWord << 32 | lowWord; + } + + /** Restarts argument reading from the first argument. Allows this object to be reused for multiple sys calls. */ + public void reset() { + currentArgument = 0; + } + } + +} Added: src/org/binarytranslator/arch/arm/os/process/linux/abi/Legacy.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/linux/abi/Legacy.java (rev 0) +++ src/org/binarytranslator/arch/arm/os/process/linux/abi/Legacy.java 2007-04-21 19:44:59 UTC (rev 79) @@ -0,0 +1,114 @@ +package org.binarytranslator.arch.arm.os.process.linux.abi; + +import org.binarytranslator.DBT; +import org.binarytranslator.arch.arm.decoder.ARM_InstructionDecoder; +import org.binarytranslator.arch.arm.decoder.ARM_Instructions; +import org.binarytranslator.arch.arm.os.process.linux.ARM_LinuxProcessSpace; +import org.binarytranslator.generic.os.abi.linux.LinuxSystemCallGenerator; +import org.binarytranslator.generic.os.process.ProcessSpace; + +/** + * ARM legacy linux system call ABI. + * <code> + * Example call to long ftruncate64(unsigned int fd, loff_t length): + * + * legacy ABI: + * - put fd into r0 + * - put length into r1-r2 + * - use "swi #(0x900000 + 194)" to call the kernel (swi #194 for thumb linux). + * + * </code> + * + * @author Michael Baer + * + */ +public class Legacy implements LinuxSystemCallGenerator { + + /** The process space that we're running on. */ + private final ARM_LinuxProcessSpace ps; + + /** A re-used iterator that allows enumerating the argument of the current + * system call */ + private final ArgumentIterator syscallArgs; + + + public Legacy(ARM_LinuxProcessSpace ps) { + this.ps = ps; + syscallArgs = new ArgumentIterator(); + } + + public int getBrk() { +// TODO Auto-generated method stub + throw new RuntimeException("Not yet implemented."); + } + + public void setBrk(int address) { +// TODO Auto-generated method stub + throw new RuntimeException("Not yet implemented."); + } + + public ProcessSpace getProcessSpace() { + return ps; + } + + public CallArgumentIterator getSysCallArguments() { + syscallArgs.reset(); + return syscallArgs; + } + + public int getSysCallNumber() { + //ARM syscalls are trigged by a SWI instruction, which includes the syscall number within its opcode. + //therefore, we are going to decode the instruction first + int instruction = ps.memory.loadInstruction32(ps.getCurrentInstructionAddress()); + ARM_Instructions.Instruction instr = ARM_InstructionDecoder.decode(instruction); + + if (DBT.VerifyAssertions) { + if (!(instr instanceof ARM_Instructions.SoftwareInterrupt)) { + throw new Error("The current instruction is not a valid system call."); + } + } + + //Thumb system calls start from 0, while ARM calls start from 0x900000. + //Use a mask to let both calls start from the same address + int sysCallNr = ((ARM_Instructions.SoftwareInterrupt)instr).getInterruptNumber(); + return sysCallNr & 0xFFFFF; + } + + public void setSysCallError(int r) { +// TODO Auto-generated method stub + throw new RuntimeException("Not yet implemented."); + } + + public void setSysCallReturn(int value) { + ps.registers.set(0, value); + } + + /** An argument iterator that hides the layout of syscall arguments on the ARM architecture */ + public final class ArgumentIterator implements + LinuxSystemCallGenerator.CallArgumentIterator { + + /** The current argument number. Set to zero for the first agument.*/ + private int currentArgument; + + public ArgumentIterator() { + this.currentArgument = 0; + } + + public int nextInt() { + return ps.registers.get(currentArgument++); + } + + public long nextLong() { + // TODO: This code is actually assuming that we're on little endian + long lowWord = nextInt(); + long highWord = nextInt(); + + return highWord << 32 | lowWord; + } + + /** Restarts argument reading from the first argument. Allows this object to be reused for multiple sys calls. */ + private void reset() { + currentArgument = 0; + } + } +} Modified: src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxSyscallArgumentIterator.java =================================================================== --- src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxSyscallArgumentIterator.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxSyscallArgumentIterator.java 2007-04-21 19:44:59 UTC (rev 79) @@ -53,5 +53,4 @@ public void reset() { nextArgument = 0; } - } Modified: src/org/binarytranslator/generic/execution/InterpreterController.java =================================================================== --- src/org/binarytranslator/generic/execution/InterpreterController.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/generic/execution/InterpreterController.java 2007-04-21 19:44:59 UTC (rev 79) @@ -12,19 +12,21 @@ @Override public void run() { Interpreter interpreter = ps.createInstructionInterpreter(); + int pc = ps.getCurrentInstructionAddress(); while (!ps.finished) { Interpreter.Instruction instruction = interpreter.decode(pc); + System.out.println(String.format("[0x%x] %s", pc, instruction.toString())); pc = instruction.getSuccessor(pc); - System.out.println("Interpreting instruction: " + instruction.toString()); - instruction.execute(); if (pc == -1) pc = ps.getCurrentInstructionAddress(); + else + ps.setCurrentInstructionAddress(pc); } } Modified: src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java =================================================================== --- src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java 2007-04-20 22:55:52 UTC (rev 78) +++ src/org/binarytranslator/generic/os/abi/linux/LinuxSystemCalls.java 2007-04-21 19:44:59 UTC (rev 79) @@ -24,6 +24,9 @@ * The source of the system calls */ private LinuxSystemCallGenerator src; + + /** Allows access to the system call's arguments */ + private LinuxSystemCallGenerator.CallArgumentIterator arguments; /** * Maximum number of system calls @@ -160,6 +163,7 @@ public void doSysCall() { int sysCallNumber = src.getSysCallNumber(); System.err.println("Syscall "+ sysCallToString(sysCallNumber)); + arguments = src.getSysCallArguments(); systemCallTable[sysCallNumber].doSysCall(); } @@ -484,14 +488,6 @@ */ public abstract void doSysCall(); } - - abstract class ParameterizedSystemCall extends SystemCall { - protected final LinuxSystemCallGenerator.CallArgumentIterator arguments; - - public ParameterizedSystemCall() { - arguments = src.getSysCallArguments(); - } - } /** * Unknown System Call @@ -513,7 +509,7 @@ /** * Exit system call */ - public class SysExit extends ParameterizedSystemCall { + public class SysExit extends SystemCall { public void doSysCall() { int status = arguments.nextInt(); System.exit(status); @@ -523,7 +519,7 @@ /** * Read from a file */ - public class SysRead extends ParameterizedSystemCall { + public class SysRead extends SystemCall { public void doSysCall() { int fd = arguments.nextInt(); int buf = arguments.nextInt(); @@ -574,7 +570,7 @@ /** * Write to a file */ - public class SysWrite extends ParameterizedSystemCall { + public class SysWrite extends SystemCall { public void doSysCall() { int fd = arguments.nextInt(); int buf = arguments.nextInt(); @@ -626,7 +622,7 @@ /** * Write data into multiple buffers */ - public class SysWriteV extends ParameterizedSystemCall { + public class SysWriteV extends SystemCall { public void doSysCall() { int fd = arguments.nextInt(); int vector = arguments.nextInt(); @@ -655,7 +651,7 @@ } } - public class SysOpen extends ParameterizedSystemCall { + public class SysOpen extends SystemCall { public void doSysCall() { int pathname = arguments.nextInt(); int flags = arguments.nextInt(); @@ -703,7 +699,7 @@ } } - public class SysClose extends ParameterizedSystemCall { + public class SysClose extends SystemCall { public void doSysCall() { int fd = arguments.nextInt(); RandomAccessFile raFile = getRAFile(fd); @@ -747,7 +743,7 @@ } } - public class SysBrk extends ParameterizedSystemCall { + public class SysBrk extends SystemCall { public void doSysCall() { int brk = arguments.nextInt(); @@ -767,20 +763,20 @@ } } - public class SysFcntl64 extends ParameterizedSystemCall { + public class SysFcntl64 extends SystemCall { public void doSysCall() { // This is complicated so fudge it for now. int fd = arguments.nextInt(); int cmd = arguments.nextInt(); - if( ((fd == 0) | (fd == 1) | (fd == 2)) & (cmd == 1) ) + if( ((fd == 0) || (fd == 1) || (fd == 2)) && (cmd == 1) ) src.setSysCallReturn(0); else throw new Error("Unrecognised system call."); } } - public class SysUname extends ParameterizedSystemCall { + public class SysUname extends SystemCall { public void doSysCall() { // Simple uname support int addr = arguments.nextInt(); @@ -819,7 +815,7 @@ } } - public class SysMmap extends ParameterizedSystemCall { + public class SysMmap extends SystemCall { public void doSysCall() { int start = arguments.nextInt(); @@ -846,7 +842,7 @@ } } - public class SysMunmap extends ParameterizedSystemCall { + public class SysMunmap extends SystemCall { public void doSysCall() { int start = arguments.nextInt(); @@ -856,7 +852,7 @@ } } - public class SysExitGroup extends ParameterizedSystemCall { + public class SysExitGroup extends SystemCall { public void doSysCall() { // For now, equivalent to SysExit System.exit(arguments.nextInt()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |