// Called at stub *kill* static void handle_exception_exit( void ) { #ifdef CYGPKG_REDBOOT #ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF { // Reset the timer to default and cancel any callback extern void sys_profile_reset(void); sys_profile_reset(); } #endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF set_pc((target_register_t)return_from_stub); #else int i; for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++) registers[i] = orig_registers[i]; #endif }
// // Generic syscall handler. // // Returns 0 if syscall number is not handled by this // module, 1 otherwise. This allows applications to // extend the syscall handler by using exception chaining. // CYG_ADDRWORD __do_syscall(CYG_ADDRWORD func, // syscall function number CYG_ADDRWORD arg1, CYG_ADDRWORD arg2, // up to four args. CYG_ADDRWORD arg3, CYG_ADDRWORD arg4, CYG_ADDRWORD *retval, CYG_ADDRWORD *sig) // syscall return value { int err = 0; *sig = 0; switch (func) { case SYS_open: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_open( const char *name, int flags, int mode, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_open((const char *)arg1, (int)arg2, (int)arg3, (int *)sig); else #endif err = sys_open((const char *)arg1, (int)arg2, (int)arg3); break; } case SYS_read: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_read( int fd, void *buf, size_t count, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_read((int)arg1, (void *)arg2, (size_t)arg3, (int *)sig); else #endif err = sys_read((int)arg1, (char *)arg2, (int)arg3); break; } case SYS_write: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_write( int fd, const void *buf, size_t count, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_write((int)arg1, (const void *)arg2, (size_t)arg3, (int *)sig); else #endif err = sys_write((int)arg1, (char *)arg2, (int)arg3); break; } case SYS_close: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_close( int fd, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_close((int)arg1, (int *)sig); else #endif err = sys_close((int)arg1); break; } case SYS_lseek: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_lseek( int fd, long offset, int whence, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_lseek((int)arg1, (long)arg2, (int)arg3, (int *)sig); else #endif err = sys_lseek((int)arg1, (int)arg2, (int)arg3); break; } case SYS_stat: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_stat( const char *pathname, void *statbuf, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_stat((const char *)arg1, (void *)arg2, (int *)sig); else #endif err = -NEWLIB_ENOSYS; break; } case SYS_fstat: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_fstat( int fd, void *statbuf, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_fstat((int)arg1, (void *)arg2, (int *)sig); else #endif { struct newlib_stat *st = (struct newlib_stat *)arg2; st->st_mode = NEWLIB_S_IFCHR; st->st_blksize = 4096; err = 0; } break; } case SYS_rename: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_rename( const char *oldpath, const char *newpath, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_rename((const char *)arg1, (const char *)arg2, (int *)sig); else #endif err = -NEWLIB_ENOSYS; break; } case SYS_unlink: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_unlink( const char *pathname, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_unlink((const char *)arg1, (int *)sig); else #endif err = -NEWLIB_ENOSYS; break; } case SYS_isatty: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_isatty( int fd, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_isatty((int)arg1, (int *)sig); else #endif err = 1; break; } case SYS_system: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_system( const char *command, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_system((const char *)arg1, (int *)sig); else #endif err = -1; break; } case SYS_gettimeofday: { #ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol __externC int cyg_hal_gdbfileio_gettimeofday( void *tv, void *tz, int *sig ); if (gdb_active) err = cyg_hal_gdbfileio_gettimeofday((void *)arg1, (void *)arg2, (int *)sig); else #endif err = 0; break; } case SYS_utime: // FIXME. Some libglosses depend on this behavior. err = sys_times((unsigned long *)arg1); break; case SYS_times: err = sys_times((unsigned long *)arg1); break; case SYS_meminfo: err = 1; *(unsigned long *)arg1 = (unsigned long)(ram_end-ram_start); *(unsigned long *)arg2 = (unsigned long)ram_end; break; #ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF case SYS_timer_call_back: sys_profile_call_back( (char *)arg1, (char **)arg2 ); break; case SYS_timer_frequency: sys_profile_frequency( (int)arg1, (unsigned int *)arg2 ); break; case SYS_timer_reset: sys_profile_reset(); break; #endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF case __GET_SHARED: *(__shared_t **)arg1 = &__shared_data; break; case SYS_exit: *sig = -1; // signal exit err = arg1; if (gdb_active) { #ifdef CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP __send_exit_status((int)arg1); #else *sig = SIGTRAP; err = func; #endif // CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP } break; default: return 0; } *retval = err; return 1; }