00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "ac_syscall.H"
00030 #include "archc.H"
00031 #include "ac_resources.H"
00032
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #include <fcntl.h>
00040 #include <unistd.h>
00041 #include <errno.h>
00042
00043 #include <sys/times.h>
00044 #include <time.h>
00045
00046 #ifdef DEBUG
00047 # define DEBUG_SYSCALL(name) AC_RUN_MSG("@@@@@ syscall: " name " @@@@@\n")
00048 #else
00049 # define DEBUG_SYSCALL(name)
00050 #endif
00051
00052
00053
00054
00055 #define NEWLIB_O_RDONLY 0x0000
00056 #define NEWLIB_O_WRONLY 0x0001
00057 #define NEWLIB_O_RDWR 0x0002
00058 #define NEWLIB_O_APPEND 0x0008
00059 #define NEWLIB_O_CREAT 0x0200
00060 #define NEWLIB_O_TRUNC 0x0400
00061 #define NEWLIB_O_EXCL 0x0800
00062 #define NEWLIB_O_NOCTTY 0x8000
00063 #define NEWLIB_O_NONBLOCK 0x4000
00064
00065 #define CORRECT_O_RDONLY 00
00066 #define CORRECT_O_WRONLY 01
00067 #define CORRECT_O_RDWR 02
00068 #define CORRECT_O_CREAT 0100
00069 #define CORRECT_O_EXCL 0200
00070 #define CORRECT_O_NOCTTY 0400
00071 #define CORRECT_O_TRUNC 01000
00072 #define CORRECT_O_APPEND 02000
00073 #define CORRECT_O_NONBLOCK 04000
00074
00075 void correct_flags( int* val )
00076 {
00077 int f = *val;
00078 int flags = 0;
00079
00080 if( f & NEWLIB_O_RDONLY )
00081 flags |= CORRECT_O_RDONLY;
00082 if( f & NEWLIB_O_WRONLY )
00083 flags |= CORRECT_O_WRONLY;
00084 if( f & NEWLIB_O_RDWR )
00085 flags |= CORRECT_O_RDWR;
00086 if( f & NEWLIB_O_CREAT )
00087 flags |= CORRECT_O_CREAT;
00088 if( f & NEWLIB_O_EXCL )
00089 flags |= CORRECT_O_EXCL;
00090 if( f & NEWLIB_O_NOCTTY )
00091 flags |= CORRECT_O_NOCTTY;
00092 if( f & NEWLIB_O_TRUNC )
00093 flags |= CORRECT_O_TRUNC;
00094 if( f & NEWLIB_O_APPEND )
00095 flags |= CORRECT_O_APPEND;
00096 if( f & NEWLIB_O_NONBLOCK )
00097 flags |= CORRECT_O_NONBLOCK;
00098
00099 *val = flags;
00100 }
00101
00102
00104
00105 void ac_syscall::open()
00106 {
00107 DEBUG_SYSCALL("open");
00108 unsigned char pathname[100];
00109 get_buffer(0, pathname, 100);
00110 int flags = get_int(1); correct_flags(&flags);
00111 int mode = get_int(2);
00112 int ret = ::open((char*)pathname, flags, mode);
00113 if (ret == -1) {
00114 AC_RUN_ERROR("System Call open (file '%s'): %s\n", pathname, strerror(errno));
00115 exit(EXIT_FAILURE);
00116 }
00117 set_int(0, ret);
00118 return_from_syscall();
00119 }
00120
00121
00122 void ac_syscall::creat()
00123 {
00124 DEBUG_SYSCALL("creat");
00125 unsigned char pathname[100];
00126 get_buffer(0, pathname, 100);
00127 int mode = get_int(1);
00128 int ret = ::creat((char*)pathname, mode);
00129 if (ret == -1) {
00130 AC_RUN_ERROR("System Call creat (file '%s'): %s\n", pathname,strerror(errno));
00131 exit(EXIT_FAILURE);
00132 }
00133 set_int(0, ret);
00134 return_from_syscall();
00135 }
00136
00137
00138 void ac_syscall::close()
00139 {
00140 DEBUG_SYSCALL("close");
00141 int fd = get_int(0);
00142 int ret = ::close(fd);
00143 if (ret == -1) {
00144 AC_RUN_ERROR("System Call close (fd %d): %s\n", fd, strerror(errno));
00145 exit(EXIT_FAILURE);
00146 }
00147 set_int(0, ret);
00148 return_from_syscall();
00149 }
00150
00151
00152 void ac_syscall::read()
00153 {
00154 DEBUG_SYSCALL("read");
00155 int fd = get_int(0);
00156 unsigned count = get_int(2);
00157 unsigned char *buf = (unsigned char*) malloc(count);
00158 int ret = ::read(fd, buf, count);
00159 if (ret == -1) {
00160 AC_RUN_ERROR("System Call read (fd %d): %s\n", fd, strerror(errno));
00161 exit(EXIT_FAILURE);
00162 }
00163 set_buffer(1, buf, ret);
00164 set_int(0, ret);
00165 return_from_syscall();
00166 free(buf);
00167 }
00168
00169
00170 void ac_syscall::write()
00171 {
00172 DEBUG_SYSCALL("write");
00173 int fd = get_int(0);
00174 unsigned count = get_int(2);
00175 unsigned char *buf = (unsigned char*) malloc(count);
00176 get_buffer(1, buf, count);
00177 int ret = ::write(fd, buf, count);
00178 if (ret == -1) {
00179 AC_RUN_ERROR("System Call write (fd %d): %s\n", fd, strerror(errno));
00180 exit(EXIT_FAILURE);
00181 }
00182 set_int(0, ret);
00183 return_from_syscall();
00184 free(buf);
00185 }
00186
00187
00188 void ac_syscall::isatty()
00189 {
00190 DEBUG_SYSCALL("isatty");
00191 int desc = get_int(0);
00192 int ret = ::isatty(desc);
00193 set_int(0, ret);
00194 return_from_syscall();
00195 }
00196
00197
00198 void ac_syscall::sbrk()
00199 {
00200 DEBUG_SYSCALL("sbrk");
00201 int base;
00202 extern unsigned int ac_heap_ptr;
00203
00204 int increment = get_int(0);
00205 if ((AC_RAMSIZE - ac_heap_ptr - increment) >= 0) {
00206 base = ac_heap_ptr;
00207 ac_heap_ptr += increment;
00208 }
00209 else {
00210 AC_RUN_ERROR("System Call sbrk: Not enough memory left in the virtual machine to allocate %d bytes (ram size=%u, heap=%u)\n", increment, AC_RAMSIZE, ac_heap_ptr);
00211 exit(EXIT_FAILURE);
00212 }
00213
00214 set_int(0, base);
00215 return_from_syscall();
00216 }
00217
00218
00219 void ac_syscall::lseek()
00220 {
00221 DEBUG_SYSCALL("lseek");
00222 int fd = get_int(0);
00223 int offset = get_int(1);
00224 int whence = get_int(2);
00225 int ret = ::lseek(fd, offset, whence);
00226 set_int(0, ret);
00227 return_from_syscall();
00228 }
00229
00230
00231 void ac_syscall::fstat()
00232 {
00233 DEBUG_SYSCALL("fstat");
00234 int fd = get_int(0);
00235 struct stat buf;
00236 int ret = ::fstat(fd, &buf);
00237 if (ret == -1) {
00238 AC_RUN_ERROR("System Call fstat (fd %d): %s\n", fd, strerror(errno));
00239 exit(EXIT_FAILURE);
00240 }
00241 set_int(0, ret);
00242 return_from_syscall();
00243 }
00244
00245
00246 void ac_syscall::_exit()
00247 {
00248 DEBUG_SYSCALL("_exit");
00249 int ac_exit_status = get_int(0);
00250 #ifdef USE_GDB
00251 if (gdbstub) gdbstub->exit(ac_exit_status);
00252 #endif
00253 ac_stop(ac_exit_status);
00254 }
00255
00256
00257 void ac_syscall::times()
00258 {
00259 DEBUG_SYSCALL("times");
00260 unsigned char zeros[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00261 set_buffer(0, zeros, 16);
00262 set_int(0, 0);
00263 return_from_syscall();
00264 }
00265
00266
00267 void ac_syscall::time()
00268 {
00269 DEBUG_SYSCALL("time");
00270 int t = get_int(0);
00271 int ret = ::time(0);
00272 if (t!=0) set_buffer(0, (unsigned char *) &ret, 4);
00273 set_int(0, ret);
00274 return_from_syscall();
00275 }
00276
00277
00278 void ac_syscall::random()
00279 {
00280 DEBUG_SYSCALL("random");
00281 int ret = ::random();
00282 set_int(0, ret);
00283 return_from_syscall();
00284 }
00285
00286
00287 #include <ac_syscall_codes.h>
00288
00289 void ac_syscall::ac_syscall_wrapper()
00290 {
00291 int ret = -1;
00292 unsigned char pathname[100];
00293 int mode;
00294
00295 int syscall_code = get_int(0);
00296
00297 switch(syscall_code) {
00298
00299 case __NR_getpid:
00300 DEBUG_SYSCALL("getpid");
00301 ret = 123;
00302 break;
00303
00304 case __NR_chmod:
00305 DEBUG_SYSCALL("chmod");
00306 get_buffer(0, pathname, 100);
00307 mode = get_int(1);
00308 ret = ::chmod((char*)pathname, mode);
00309 break;
00310
00311 default:
00312 AC_RUN_ERROR("System Call code %d not implemented yet.\n", syscall_code);
00313 }
00314
00315 set_int(0, ret);
00316 return_from_syscall();
00317 }
00318
00319
00320 void ac_syscall::ac_syscall_geterrno()
00321 {
00322 set_int(0, errno);
00323 return_from_syscall();
00324 }
00325
00326
00327 void ac_syscall::ac_syscall_stat_mode()
00328 {
00329 AC_RUN_ERROR("System Call ac_syscall_geterrno not implemented yet.\n",0);
00330 }
00331
00332