diff --git a/cachegrind/arm/Makefile.am b/cachegrind/arm/Makefile.am new file mode 100644 index 000000000..53d27a1b0 --- /dev/null +++ b/cachegrind/arm/Makefile.am @@ -0,0 +1,7 @@ +include $(top_srcdir)/Makefile.tool-flags.am + +AM_CPPFLAGS += -I$(top_srcdir)/cachegrind + +noinst_LIBRARIES = libcgarch.a + +libcgarch_a_SOURCES = cg_arch.c diff --git a/cachegrind/arm/cg_arch.c b/cachegrind/arm/cg_arch.c new file mode 100644 index 000000000..e3e83dd93 --- /dev/null +++ b/cachegrind/arm/cg_arch.c @@ -0,0 +1,49 @@ + +/*--------------------------------------------------------------------*/ +/*--- Arch-specific definitions. arm/cg_arch.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Cachegrind, a Valgrind tool for cache + profiling programs. + + Copyright (C) 2002-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "tool.h" +#include "cg_arch.h" + +void VGA_(configure_caches)(cache_t* I1c, cache_t* D1c, cache_t* L2c, + Bool all_caches_clo_defined) +{ + // XXX: I1 and D1 are vaguely plausible, although they could really be + // anything. However, most (all?) ARMs don't have an L2 cache. But + // Cachegrind assumes the presence of an L2 cache... so we just copy the + // x86 defaults. Urk. + *I1c = (cache_t) { 4096, 2, 32 }; + *D1c = (cache_t) { 4096, 2, 32 }; + *L2c = (cache_t) { 262144, 8, 64 }; +} + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ + diff --git a/cachegrind/tests/arm/Makefile.am b/cachegrind/tests/arm/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/cachegrind/x86/Makefile.am b/cachegrind/x86/Makefile.am index 5c07f3961..53d27a1b0 100644 --- a/cachegrind/x86/Makefile.am +++ b/cachegrind/x86/Makefile.am @@ -5,4 +5,3 @@ AM_CPPFLAGS += -I$(top_srcdir)/cachegrind noinst_LIBRARIES = libcgarch.a libcgarch_a_SOURCES = cg_arch.c - diff --git a/configure.in b/configure.in index 1d664b750..882fdf1e9 100644 --- a/configure.in +++ b/configure.in @@ -29,7 +29,7 @@ CFLAGS="" AC_PROG_LN_S AC_PROG_CC -AM_PROG_CC_C_O +##AM_PROG_CC_C_O AC_PROG_CPP AC_PROG_CXX AC_PROG_RANLIB @@ -350,26 +350,33 @@ AC_OUTPUT( include/valgrind.h include/Makefile include/x86/Makefile + include/arm/Makefile include/linux/Makefile include/x86-linux/Makefile + include/arm-linux/Makefile auxprogs/Makefile coregrind/Makefile coregrind/demangle/Makefile coregrind/docs/Makefile coregrind/x86/Makefile + coregrind/arm/Makefile coregrind/linux/Makefile coregrind/x86-linux/Makefile + coregrind/arm-linux/Makefile addrcheck/Makefile addrcheck/tests/Makefile addrcheck/docs/Makefile memcheck/Makefile memcheck/tests/Makefile memcheck/tests/x86/Makefile + memcheck/tests/arm/Makefile memcheck/docs/Makefile cachegrind/Makefile cachegrind/x86/Makefile + cachegrind/arm/Makefile cachegrind/tests/Makefile cachegrind/tests/x86/Makefile + cachegrind/tests/arm/Makefile cachegrind/docs/Makefile cachegrind/cg_annotate helgrind/Makefile @@ -388,6 +395,7 @@ AC_OUTPUT( none/Makefile none/tests/Makefile none/tests/x86/Makefile + none/tests/arm/Makefile none/docs/Makefile ) diff --git a/coregrind/arm-linux/Makefile.am b/coregrind/arm-linux/Makefile.am new file mode 100644 index 000000000..1d545341c --- /dev/null +++ b/coregrind/arm-linux/Makefile.am @@ -0,0 +1,14 @@ +include $(top_srcdir)/Makefile.all.am +include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am + +AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g + +noinst_HEADERS = \ + core_platform.h \ + vki_unistd.h + +noinst_LIBRARIES = libplatform.a + +libplatform_a_SOURCES = \ + syscall.S \ + syscalls.c diff --git a/coregrind/arm-linux/core_platform.h b/coregrind/arm-linux/core_platform.h new file mode 100644 index 000000000..43a09293a --- /dev/null +++ b/coregrind/arm-linux/core_platform.h @@ -0,0 +1,86 @@ + +/*--------------------------------------------------------------------*/ +/*--- ARM-Linux-specific stuff for the core. ---*/ +/*--- arm-linux/core_platform.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __ARM_LINUX_CORE_PLATFORM_H +#define __ARM_LINUX_CORE_PLATFORM_H + +//#include "core_platform_asm.h" // platform-specific asm stuff +//#include "platform_arch.h" // platform-specific tool stuff + +/* --------------------------------------------------------------------- + Dealing with registers + ------------------------------------------------------------------ */ + +// Accessors for the ThreadArchState +#define PLATFORM_SYSCALL_NUM guest_SYSCALLNO +#define PLATFORM_SYSCALL_ARG1 guest_R0 +#define PLATFORM_SYSCALL_ARG2 guest_R1 +#define PLATFORM_SYSCALL_ARG3 guest_R2 +#define PLATFORM_SYSCALL_ARG4 guest_R3 +#define PLATFORM_SYSCALL_ARG5 guest_R4 +#define PLATFORM_SYSCALL_ARG6 guest_R5 +#define PLATFORM_SYSCALL_RET guest_R0 // ToDo XXX ???????? + +#define PLATFORM_SET_SYSCALL_RESULT(regs, val) \ + ((regs).vex.guest_R0 = (val)) // ToDo XXX ???????? + +// Setting thread regs and shadow regs from within the core +// XXX ToDo: not sure about this +#define SET_SYSCALL_RETVAL(zztid, zzval) \ + SET_THREAD_REG(zztid, zzval, SYSCALL_RET, post_reg_write, \ + Vg_CoreSysCall, zztid, O_SYSCALL_RET, sizeof(UWord)) + +/* --------------------------------------------------------------------- + ucontext stuff + ------------------------------------------------------------------ */ + +#define UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.arm_pc) +#define UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.arm_sp) +#define UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.arm_fp) +#define UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.arm_r0) + +/* --------------------------------------------------------------------- + mmap() stuff + ------------------------------------------------------------------ */ + +#define PLATFORM_DO_MMAP(ret, start, length, prot, flags, fd, offset) { \ + I_die_here; \ +} + +#define PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6) do { \ + I_die_here; \ +} while (0) + +#endif // __ARM_LINUX_CORE_PLATFORM_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/arm-linux/syscall.S b/coregrind/arm-linux/syscall.S new file mode 100644 index 000000000..307d92f7b --- /dev/null +++ b/coregrind/arm-linux/syscall.S @@ -0,0 +1,54 @@ + +##--------------------------------------------------------------------## +##--- Support for doing system calls. arm-linux/syscall.S ---## +##--------------------------------------------------------------------## + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "core_asm.h" +#include "vki_unistd.h" + +# XXX: must reinstate comments also -- see x86-linux/syscall.S + +.globl VG_(do_syscall) +VG_(do_syscall): + swi + +.globl VG_(clone) +VG_(clone): + swi + +.globl VG_(sigreturn) +VG_(sigreturn): + swi + +# ToDo XXX: Assembler did not like this... +#/* Let the linker know we don't need an executable stack */ +#.section .note.GNU-stack,"",@progbits + +##--------------------------------------------------------------------## +##--- end ---## +##--------------------------------------------------------------------## diff --git a/coregrind/arm-linux/syscalls.c b/coregrind/arm-linux/syscalls.c new file mode 100644 index 000000000..235881cc8 --- /dev/null +++ b/coregrind/arm-linux/syscalls.c @@ -0,0 +1,190 @@ + +/*--------------------------------------------------------------------*/ +/*--- ARM/Linux-specific syscalls, etc. arm-linux/syscalls.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "core.h" + + +// See the comment accompanying the declaration of VGA_(thread_syscall)() in +// coregrind/core.h for an explanation of what this does, and why. +// +// XXX: this function and these variables should be assembly code! See the +// x86 version. +const Addr VGA_(sys_before), VGA_(sys_restarted), + VGA_(sys_after), VGA_(sys_done); +void VGA_(do_thread_syscall)(UWord sys, + UWord arg1, UWord arg2, UWord arg3, + UWord arg4, UWord arg5, UWord arg6, + UWord *result, /*enum PXState*/Int *statep, + /*enum PXState*/Int poststate) +{ + I_die_here; +} + + +// Back up to restart a system call. +void VGA_(restart_syscall)(ThreadArchState *arch) +{ + I_die_here; +#if 0 + arch->vex.guest_EIP -= 2; // sizeof(int $0x80) + + /* Make sure our caller is actually sane, and we're really backing + back over a syscall. + + int $0x80 == CD 80 + */ + { + UChar *p = (UChar *)arch->vex.guest_EIP; + + if (p[0] != 0xcd || p[1] != 0x80) + VG_(message)(Vg_DebugMsg, + "?! restarting over syscall at %p %02x %02x\n", + arch->vex.guest_EIP, p[0], p[1]); + + vg_assert(p[0] == 0xcd && p[1] == 0x80); + } +#endif +} + +/* --------------------------------------------------------------------- + PRE/POST wrappers for ARM/Linux-specific syscalls + ------------------------------------------------------------------ */ + +// Nb: See the comment above the generic PRE/POST wrappers in +// coregrind/vg_syscalls.c for notes about how they work. + +#define PRE(x,f) \ + static UInt arm_linux_##x##_flags = f; \ + static void arm_linux_##x##_before(ThreadId tid, ThreadState *tst) +#define POST(x) \ + static void arm_linux_##x##_after (ThreadId tid, ThreadState *tst) + +#define SYSNO PLATFORM_SYSCALL_NUM(tst->arch) // in PRE(x) +#define res PLATFORM_SYSCALL_RET(tst->arch) // in POST(x) +#define arg1 PLATFORM_SYSCALL_ARG1(tst->arch) +#define arg2 PLATFORM_SYSCALL_ARG2(tst->arch) +#define arg3 PLATFORM_SYSCALL_ARG3(tst->arch) +#define arg4 PLATFORM_SYSCALL_ARG4(tst->arch) +#define arg5 PLATFORM_SYSCALL_ARG5(tst->arch) +#define arg6 PLATFORM_SYSCALL_ARG6(tst->arch) + +#define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val)) + +#define PRINT(format, args...) \ + if (VG_(clo_trace_syscalls)) \ + VG_(printf)(format, ## args) + +PRE(sys_syscall, Special) +{ + // Nb!!! + // + // __NR_syscall is a "higher-order syscall" on ARM; it's all a bit + // strange. To implement this, you'll need to shuffle the args down, do + // the same for the shadow args, and maybe some other stuff. + VG_(printf)("__NR_syscall detected!"); + I_die_here; +} + +PRE(sys_clone, Special) +{ + I_die_here; + // XXX: maybe this clone stuff could be factored out +#if 0 + PRINT("sys_clone ( %d, %p, %p, %p, %p )",arg1,arg2,arg3,arg4,arg5); + // XXX: really not sure about the last two args... if they are really + // there, we should do PRE_MEM_READs for both of them... + PRE_REG_READ4(int, "clone", + unsigned long, flags, void *, child_stack, + int *, parent_tidptr, int *, child_tidptr); + + if (arg2 == 0 && + (arg1 == (VKI_CLONE_CHILD_CLEARTID|VKI_CLONE_CHILD_SETTID|VKI_SIGCHLD) + || arg1 == (VKI_CLONE_PARENT_SETTID|VKI_SIGCHLD))) + { + VGA_(gen_sys_fork_before)(tid, tst); + set_result( VG_(do_syscall)(SYSNO, arg1, arg2, arg3, arg4, arg5) ); + VGA_(gen_sys_fork_after) (tid, tst); + } else { + VG_(unimplemented) + ("clone(): not supported by Valgrind.\n " + "We do support programs linked against\n " + "libpthread.so, though. Re-run with -v and ensure that\n " + "you are picking up Valgrind's implementation of libpthread.so."); + } +#endif +} + +#undef PRE +#undef POST + +/* --------------------------------------------------------------------- + The ARM/Linux syscall table + ------------------------------------------------------------------ */ + +#define GENX_(const, name) \ + [const] = { &VGA_(gen_##name##_flags), VGA_(gen_##name##_before), NULL } +#define GENXY(const, name) \ + [const] = { &VGA_(gen_##name##_flags), VGA_(gen_##name##_before), \ + VGA_(gen_##name##_after) } + +#define LINX_(const, name) \ + [const] = { &VGA_(linux_##name##_flags), VGA_(linux_##name##_before), NULL } +#define LINXY(const, name) \ + [const] = { &VGA_(linux_##name##_flags), VGA_(linux_##name##_before), \ + VGA_(linux_##name##_after) } +#define PLAX_(const, name) \ + [const] = { &arm_linux_##name##_flags, arm_linux_##name##_before, NULL } +#define PLAXY(const, name) \ + [const] = { &arm_linux_##name##_flags, arm_linux_##name##_before, \ + arm_linux_##name##_after } + +// This table maps from __NR_xxx syscall numbers (from +// linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo() +// wrappers on ARM (as per sys_call_table in linux/arch/arm/kernel/entry.S). +// +// For those syscalls not handled by Valgrind, the annotation indicate its +// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? +// (unknown). + +const struct SyscallTableEntry VGA_(syscall_table)[] = { + // (restart_syscall) // 0 + PLAX_(__NR_syscall, sys_syscall), // 113 + PLAX_(__NR_clone, sys_clone), // 120 +}; + +const UInt VGA_(syscall_table_size) = + sizeof(VGA_(syscall_table)) / sizeof(VGA_(syscall_table)[0]); + +#undef GENX_ +#undef GENXY + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/arm-linux/vki_unistd.h b/coregrind/arm-linux/vki_unistd.h new file mode 100644 index 000000000..5082ed35b --- /dev/null +++ b/coregrind/arm-linux/vki_unistd.h @@ -0,0 +1,311 @@ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __ARM_LINUX_VKI_UNISTD_H_ +#define __ARM_LINUX_VKI_UNISTD_H_ + +// From linux-2.6.8.1/include/asm-arm/unistd.h + +// Nb: ARM Thumb has a different __NR_SYSCALL_BASE, but we don't care about +// that architecture. +#define __NR_SYSCALL_BASE 0x900000 + +#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0) +#define __NR_exit (__NR_SYSCALL_BASE+ 1) +#define __NR_fork (__NR_SYSCALL_BASE+ 2) +#define __NR_read (__NR_SYSCALL_BASE+ 3) +#define __NR_write (__NR_SYSCALL_BASE+ 4) +#define __NR_open (__NR_SYSCALL_BASE+ 5) +#define __NR_close (__NR_SYSCALL_BASE+ 6) + /* 7 was sys_waitpid */ +#define __NR_creat (__NR_SYSCALL_BASE+ 8) +#define __NR_link (__NR_SYSCALL_BASE+ 9) +#define __NR_unlink (__NR_SYSCALL_BASE+ 10) +#define __NR_execve (__NR_SYSCALL_BASE+ 11) +#define __NR_chdir (__NR_SYSCALL_BASE+ 12) +#define __NR_time (__NR_SYSCALL_BASE+ 13) +#define __NR_mknod (__NR_SYSCALL_BASE+ 14) +#define __NR_chmod (__NR_SYSCALL_BASE+ 15) +#define __NR_lchown (__NR_SYSCALL_BASE+ 16) + /* 17 was sys_break */ + /* 18 was sys_stat */ +#define __NR_lseek (__NR_SYSCALL_BASE+ 19) +#define __NR_getpid (__NR_SYSCALL_BASE+ 20) +#define __NR_mount (__NR_SYSCALL_BASE+ 21) +#define __NR_umount (__NR_SYSCALL_BASE+ 22) +#define __NR_setuid (__NR_SYSCALL_BASE+ 23) +#define __NR_getuid (__NR_SYSCALL_BASE+ 24) +#define __NR_stime (__NR_SYSCALL_BASE+ 25) +#define __NR_ptrace (__NR_SYSCALL_BASE+ 26) +#define __NR_alarm (__NR_SYSCALL_BASE+ 27) + /* 28 was sys_fstat */ +#define __NR_pause (__NR_SYSCALL_BASE+ 29) +#define __NR_utime (__NR_SYSCALL_BASE+ 30) + /* 31 was sys_stty */ + /* 32 was sys_gtty */ +#define __NR_access (__NR_SYSCALL_BASE+ 33) +#define __NR_nice (__NR_SYSCALL_BASE+ 34) + /* 35 was sys_ftime */ +#define __NR_sync (__NR_SYSCALL_BASE+ 36) +#define __NR_kill (__NR_SYSCALL_BASE+ 37) +#define __NR_rename (__NR_SYSCALL_BASE+ 38) +#define __NR_mkdir (__NR_SYSCALL_BASE+ 39) +#define __NR_rmdir (__NR_SYSCALL_BASE+ 40) +#define __NR_dup (__NR_SYSCALL_BASE+ 41) +#define __NR_pipe (__NR_SYSCALL_BASE+ 42) +#define __NR_times (__NR_SYSCALL_BASE+ 43) + /* 44 was sys_prof */ +#define __NR_brk (__NR_SYSCALL_BASE+ 45) +#define __NR_setgid (__NR_SYSCALL_BASE+ 46) +#define __NR_getgid (__NR_SYSCALL_BASE+ 47) + /* 48 was sys_signal */ +#define __NR_geteuid (__NR_SYSCALL_BASE+ 49) +#define __NR_getegid (__NR_SYSCALL_BASE+ 50) +#define __NR_acct (__NR_SYSCALL_BASE+ 51) +#define __NR_umount2 (__NR_SYSCALL_BASE+ 52) + /* 53 was sys_lock */ +#define __NR_ioctl (__NR_SYSCALL_BASE+ 54) +#define __NR_fcntl (__NR_SYSCALL_BASE+ 55) + /* 56 was sys_mpx */ +#define __NR_setpgid (__NR_SYSCALL_BASE+ 57) + /* 58 was sys_ulimit */ + /* 59 was sys_olduname */ +#define __NR_umask (__NR_SYSCALL_BASE+ 60) +#define __NR_chroot (__NR_SYSCALL_BASE+ 61) +#define __NR_ustat (__NR_SYSCALL_BASE+ 62) +#define __NR_dup2 (__NR_SYSCALL_BASE+ 63) +#define __NR_getppid (__NR_SYSCALL_BASE+ 64) +#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65) +#define __NR_setsid (__NR_SYSCALL_BASE+ 66) +#define __NR_sigaction (__NR_SYSCALL_BASE+ 67) + /* 68 was sys_sgetmask */ + /* 69 was sys_ssetmask */ +#define __NR_setreuid (__NR_SYSCALL_BASE+ 70) +#define __NR_setregid (__NR_SYSCALL_BASE+ 71) +#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72) +#define __NR_sigpending (__NR_SYSCALL_BASE+ 73) +#define __NR_sethostname (__NR_SYSCALL_BASE+ 74) +#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75) +#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */ +#define __NR_getrusage (__NR_SYSCALL_BASE+ 77) +#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78) +#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79) +#define __NR_getgroups (__NR_SYSCALL_BASE+ 80) +#define __NR_setgroups (__NR_SYSCALL_BASE+ 81) +#define __NR_select (__NR_SYSCALL_BASE+ 82) +#define __NR_symlink (__NR_SYSCALL_BASE+ 83) + /* 84 was sys_lstat */ +#define __NR_readlink (__NR_SYSCALL_BASE+ 85) +#define __NR_uselib (__NR_SYSCALL_BASE+ 86) +#define __NR_swapon (__NR_SYSCALL_BASE+ 87) +#define __NR_reboot (__NR_SYSCALL_BASE+ 88) +#define __NR_readdir (__NR_SYSCALL_BASE+ 89) +#define __NR_mmap (__NR_SYSCALL_BASE+ 90) +#define __NR_munmap (__NR_SYSCALL_BASE+ 91) +#define __NR_truncate (__NR_SYSCALL_BASE+ 92) +#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93) +#define __NR_fchmod (__NR_SYSCALL_BASE+ 94) +#define __NR_fchown (__NR_SYSCALL_BASE+ 95) +#define __NR_getpriority (__NR_SYSCALL_BASE+ 96) +#define __NR_setpriority (__NR_SYSCALL_BASE+ 97) + /* 98 was sys_profil */ +#define __NR_statfs (__NR_SYSCALL_BASE+ 99) +#define __NR_fstatfs (__NR_SYSCALL_BASE+100) + /* 101 was sys_ioperm */ +#define __NR_socketcall (__NR_SYSCALL_BASE+102) +#define __NR_syslog (__NR_SYSCALL_BASE+103) +#define __NR_setitimer (__NR_SYSCALL_BASE+104) +#define __NR_getitimer (__NR_SYSCALL_BASE+105) +#define __NR_stat (__NR_SYSCALL_BASE+106) +#define __NR_lstat (__NR_SYSCALL_BASE+107) +#define __NR_fstat (__NR_SYSCALL_BASE+108) + /* 109 was sys_uname */ + /* 110 was sys_iopl */ +#define __NR_vhangup (__NR_SYSCALL_BASE+111) + /* 112 was sys_idle */ +#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */ +#define __NR_wait4 (__NR_SYSCALL_BASE+114) +#define __NR_swapoff (__NR_SYSCALL_BASE+115) +#define __NR_sysinfo (__NR_SYSCALL_BASE+116) +#define __NR_ipc (__NR_SYSCALL_BASE+117) +#define __NR_fsync (__NR_SYSCALL_BASE+118) +#define __NR_sigreturn (__NR_SYSCALL_BASE+119) +#define __NR_clone (__NR_SYSCALL_BASE+120) +#define __NR_setdomainname (__NR_SYSCALL_BASE+121) +#define __NR_uname (__NR_SYSCALL_BASE+122) + /* 123 was sys_modify_ldt */ +#define __NR_adjtimex (__NR_SYSCALL_BASE+124) +#define __NR_mprotect (__NR_SYSCALL_BASE+125) +#define __NR_sigprocmask (__NR_SYSCALL_BASE+126) + /* 127 was sys_create_module */ +#define __NR_init_module (__NR_SYSCALL_BASE+128) +#define __NR_delete_module (__NR_SYSCALL_BASE+129) + /* 130 was sys_get_kernel_syms */ +#define __NR_quotactl (__NR_SYSCALL_BASE+131) +#define __NR_getpgid (__NR_SYSCALL_BASE+132) +#define __NR_fchdir (__NR_SYSCALL_BASE+133) +#define __NR_bdflush (__NR_SYSCALL_BASE+134) +#define __NR_sysfs (__NR_SYSCALL_BASE+135) +#define __NR_personality (__NR_SYSCALL_BASE+136) + /* 137 was sys_afs_syscall */ +#define __NR_setfsuid (__NR_SYSCALL_BASE+138) +#define __NR_setfsgid (__NR_SYSCALL_BASE+139) +#define __NR__llseek (__NR_SYSCALL_BASE+140) +#define __NR_getdents (__NR_SYSCALL_BASE+141) +#define __NR__newselect (__NR_SYSCALL_BASE+142) +#define __NR_flock (__NR_SYSCALL_BASE+143) +#define __NR_msync (__NR_SYSCALL_BASE+144) +#define __NR_readv (__NR_SYSCALL_BASE+145) +#define __NR_writev (__NR_SYSCALL_BASE+146) +#define __NR_getsid (__NR_SYSCALL_BASE+147) +#define __NR_fdatasync (__NR_SYSCALL_BASE+148) +#define __NR__sysctl (__NR_SYSCALL_BASE+149) +#define __NR_mlock (__NR_SYSCALL_BASE+150) +#define __NR_munlock (__NR_SYSCALL_BASE+151) +#define __NR_mlockall (__NR_SYSCALL_BASE+152) +#define __NR_munlockall (__NR_SYSCALL_BASE+153) +#define __NR_sched_setparam (__NR_SYSCALL_BASE+154) +#define __NR_sched_getparam (__NR_SYSCALL_BASE+155) +#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156) +#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157) +#define __NR_sched_yield (__NR_SYSCALL_BASE+158) +#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159) +#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160) +#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161) +#define __NR_nanosleep (__NR_SYSCALL_BASE+162) +#define __NR_mremap (__NR_SYSCALL_BASE+163) +#define __NR_setresuid (__NR_SYSCALL_BASE+164) +#define __NR_getresuid (__NR_SYSCALL_BASE+165) + /* 166 was sys_vm86 */ + /* 167 was sys_query_module */ +#define __NR_poll (__NR_SYSCALL_BASE+168) +#define __NR_nfsservctl (__NR_SYSCALL_BASE+169) +#define __NR_setresgid (__NR_SYSCALL_BASE+170) +#define __NR_getresgid (__NR_SYSCALL_BASE+171) +#define __NR_prctl (__NR_SYSCALL_BASE+172) +#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173) +#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174) +#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175) +#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176) +#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177) +#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178) +#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179) +#define __NR_pread64 (__NR_SYSCALL_BASE+180) +#define __NR_pwrite64 (__NR_SYSCALL_BASE+181) +#define __NR_chown (__NR_SYSCALL_BASE+182) +#define __NR_getcwd (__NR_SYSCALL_BASE+183) +#define __NR_capget (__NR_SYSCALL_BASE+184) +#define __NR_capset (__NR_SYSCALL_BASE+185) +#define __NR_sigaltstack (__NR_SYSCALL_BASE+186) +#define __NR_sendfile (__NR_SYSCALL_BASE+187) + /* 188 reserved */ + /* 189 reserved */ +#define __NR_vfork (__NR_SYSCALL_BASE+190) +#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */ +#define __NR_mmap2 (__NR_SYSCALL_BASE+192) +#define __NR_truncate64 (__NR_SYSCALL_BASE+193) +#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194) +#define __NR_stat64 (__NR_SYSCALL_BASE+195) +#define __NR_lstat64 (__NR_SYSCALL_BASE+196) +#define __NR_fstat64 (__NR_SYSCALL_BASE+197) +#define __NR_lchown32 (__NR_SYSCALL_BASE+198) +#define __NR_getuid32 (__NR_SYSCALL_BASE+199) +#define __NR_getgid32 (__NR_SYSCALL_BASE+200) +#define __NR_geteuid32 (__NR_SYSCALL_BASE+201) +#define __NR_getegid32 (__NR_SYSCALL_BASE+202) +#define __NR_setreuid32 (__NR_SYSCALL_BASE+203) +#define __NR_setregid32 (__NR_SYSCALL_BASE+204) +#define __NR_getgroups32 (__NR_SYSCALL_BASE+205) +#define __NR_setgroups32 (__NR_SYSCALL_BASE+206) +#define __NR_fchown32 (__NR_SYSCALL_BASE+207) +#define __NR_setresuid32 (__NR_SYSCALL_BASE+208) +#define __NR_getresuid32 (__NR_SYSCALL_BASE+209) +#define __NR_setresgid32 (__NR_SYSCALL_BASE+210) +#define __NR_getresgid32 (__NR_SYSCALL_BASE+211) +#define __NR_chown32 (__NR_SYSCALL_BASE+212) +#define __NR_setuid32 (__NR_SYSCALL_BASE+213) +#define __NR_setgid32 (__NR_SYSCALL_BASE+214) +#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215) +#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216) +#define __NR_getdents64 (__NR_SYSCALL_BASE+217) +#define __NR_pivot_root (__NR_SYSCALL_BASE+218) +#define __NR_mincore (__NR_SYSCALL_BASE+219) +#define __NR_madvise (__NR_SYSCALL_BASE+220) +#define __NR_fcntl64 (__NR_SYSCALL_BASE+221) + /* 222 for tux */ + /* 223 is unused */ +#define __NR_gettid (__NR_SYSCALL_BASE+224) +#define __NR_readahead (__NR_SYSCALL_BASE+225) +#define __NR_setxattr (__NR_SYSCALL_BASE+226) +#define __NR_lsetxattr (__NR_SYSCALL_BASE+227) +#define __NR_fsetxattr (__NR_SYSCALL_BASE+228) +#define __NR_getxattr (__NR_SYSCALL_BASE+229) +#define __NR_lgetxattr (__NR_SYSCALL_BASE+230) +#define __NR_fgetxattr (__NR_SYSCALL_BASE+231) +#define __NR_listxattr (__NR_SYSCALL_BASE+232) +#define __NR_llistxattr (__NR_SYSCALL_BASE+233) +#define __NR_flistxattr (__NR_SYSCALL_BASE+234) +#define __NR_removexattr (__NR_SYSCALL_BASE+235) +#define __NR_lremovexattr (__NR_SYSCALL_BASE+236) +#define __NR_fremovexattr (__NR_SYSCALL_BASE+237) +#define __NR_tkill (__NR_SYSCALL_BASE+238) +#define __NR_sendfile64 (__NR_SYSCALL_BASE+239) +#define __NR_futex (__NR_SYSCALL_BASE+240) +#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241) +#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242) +#define __NR_io_setup (__NR_SYSCALL_BASE+243) +#define __NR_io_destroy (__NR_SYSCALL_BASE+244) +#define __NR_io_getevents (__NR_SYSCALL_BASE+245) +#define __NR_io_submit (__NR_SYSCALL_BASE+246) +#define __NR_io_cancel (__NR_SYSCALL_BASE+247) +#define __NR_exit_group (__NR_SYSCALL_BASE+248) +#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249) +#define __NR_epoll_create (__NR_SYSCALL_BASE+250) +#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251) +#define __NR_epoll_wait (__NR_SYSCALL_BASE+252) +#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253) + /* 254 for set_thread_area */ + /* 255 for get_thread_area */ + /* 256 for set_tid_address */ +#define __NR_timer_create (__NR_SYSCALL_BASE+257) +#define __NR_timer_settime (__NR_SYSCALL_BASE+258) +#define __NR_timer_gettime (__NR_SYSCALL_BASE+259) +#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260) +#define __NR_timer_delete (__NR_SYSCALL_BASE+261) +#define __NR_clock_settime (__NR_SYSCALL_BASE+262) +#define __NR_clock_gettime (__NR_SYSCALL_BASE+263) +#define __NR_clock_getres (__NR_SYSCALL_BASE+264) +#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265) +#define __NR_statfs64 (__NR_SYSCALL_BASE+266) +#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) +#define __NR_tgkill (__NR_SYSCALL_BASE+268) +#define __NR_utimes (__NR_SYSCALL_BASE+269) +#define __NR_fadvise64_64 (__NR_SYSCALL_BASE+270) +#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) +#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) +#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) + +#endif /* __ARM_LINUX_VKI_UNISTD_H_ */ diff --git a/coregrind/arm/Makefile.am b/coregrind/arm/Makefile.am new file mode 100644 index 000000000..b0874de0e --- /dev/null +++ b/coregrind/arm/Makefile.am @@ -0,0 +1,29 @@ +include $(top_srcdir)/Makefile.all.am +include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am + +AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g + +noinst_HEADERS = \ + core_arch.h \ + core_arch_asm.h + +noinst_LIBRARIES = libarch.a + +EXTRA_DIST = \ + jmp_with_stack.c \ + libpthread.c + +BUILT_SOURCES = stage2.lds +CLEANFILES = stage2.lds + +libarch_a_SOURCES = \ + dispatch.S \ + signal.c \ + state.c + +# Extract ld's default linker script and hack it to our needs +stage2.lds: Makefile + $(CC) -Wl,--verbose -nostdlib 2>&1 | sed \ + -e '1,/^=====\+$$/d' \ + -e '/^=====\+$$/d' \ + -e 's/0x08048000/kickstart_base/g' > $@ || rm -f $@ diff --git a/coregrind/arm/core_arch.h b/coregrind/arm/core_arch.h new file mode 100644 index 000000000..26b234dca --- /dev/null +++ b/coregrind/arm/core_arch.h @@ -0,0 +1,133 @@ + +/*--------------------------------------------------------------------*/ +/*--- ARM-specific stuff for the core. arm/core_arch.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __ARM_CORE_ARCH_H +#define __ARM_CORE_ARCH_H + +#include "core_arch_asm.h" // arch-specific asm stuff +#include "tool_arch.h" // arch-specific tool stuff + +#include "libvex_guest_arm.h" + + +/* --------------------------------------------------------------------- + Interesting registers + ------------------------------------------------------------------ */ +// Vex field names +// Not sure, but I think: +// r11 = frame pointer +// r12 = ip (??) +// r13 = stack pointer +// r14 = link register +// r15 = program counter +#define ARCH_INSTR_PTR guest_R15 +#define ARCH_STACK_PTR guest_R13 // XXX ??? +#define ARCH_FRAME_PTR guest_R0 // XXX ??? + +#define ARCH_CLREQ_ARGS guest_R0 +#define ARCH_CLREQ_RET guest_R0 +#define ARCH_PTHREQ_RET guest_R0 + +// Register numbers, for vg_symtab2.c +#define R_STACK_PTR 13 +#define R_FRAME_PTR 0 // XXX ??? + +// Stack frame layout and linkage +// XXX ToDo: ??? +#define FIRST_STACK_FRAME(ebp) (ebp) +#define STACK_FRAME_RET(ebp) (((UInt*)ebp)[1]) +#define STACK_FRAME_NEXT(ebp) (((UInt*)ebp)[0]) + +// Get stack pointer and frame pointer +#define ARCH_GET_REAL_STACK_PTR(esp) do { \ + I_die_here; \ +} while (0) + +#define ARCH_GET_REAL_FRAME_PTR(ebp) do { \ + I_die_here; \ +} while (0) + +#if 0 +// So the dispatch loop can find %EIP +extern Int VGOFF_(m_eip); +#endif + +/* --------------------------------------------------------------------- + Elf stuff + ------------------------------------------------------------------ */ + +#define VG_ELF_ENDIANNESS ELFDATA2LSB +#define VG_ELF_MACHINE EM_ARM +#define VG_ELF_CLASS ELFCLASS32 + +/* --------------------------------------------------------------------- + Architecture-specific part of a ThreadState + ------------------------------------------------------------------ */ + +// Architecture-specific part of a ThreadState +// XXX: eventually this should be made abstract, ie. the fields not visible +// to the core... ?? +typedef struct { + /* Saved machine context. */ + VexGuestARMState vex; + + /* Saved shadow context. */ + VexGuestARMState vex_shadow; + + /* Spill area. */ + UChar vex_spill[LibVEX_N_SPILL_BYTES]; +} +ThreadArchState; + +typedef VexGuestARMState VexGuestArchState; + +/* --------------------------------------------------------------------- + libpthread stuff + ------------------------------------------------------------------ */ + +struct _ThreadArchAux { + // XXX: nothing? +}; + +/* --------------------------------------------------------------------- + Miscellaneous constants + ------------------------------------------------------------------ */ + +// Valgrind's signal stack size, in words. +#define VG_SIGSTACK_SIZE_W 10000 + +// Base address of client address space. +#define CLIENT_BASE 0x00000000ul + +#endif // __ARM_CORE_ARCH_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/arm/core_arch_asm.h b/coregrind/arm/core_arch_asm.h new file mode 100644 index 000000000..f46f4be91 --- /dev/null +++ b/coregrind/arm/core_arch_asm.h @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------*/ +/*--- arm/core_arch_asm.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __ARM_CORE_ARCH_ASM_H +#define __ARM_CORE_ARCH_ASM_H + +#if 0 +/* size of call instruction put into generated code at jump sites */ +#define VG_PATCHME_CALLSZ 5 + +/* size of jmp instruction which overwrites the call */ +#define VG_PATCHME_JMPSZ 5 +#endif + +// XXX: ??? +/* maximum number of normal jumps which can appear in a basic block */ +#define VG_MAX_JUMPS 2 + +/* Offset of code in a TCEntry */ +#define VG_CODE_OFFSET (8 + VG_MAX_JUMPS * 2) + +#if 0 +/* Debugging hack for assembly code ... sigh. */ +#if 0 +#define OYNK(nnn) pushal; pushl $nnn; call VG_(oynk) ; addl $4,%esp; popal +#else +#define OYNK(nnn) +#endif + +#if 0 +#define OYNNK(nnn) pushal; pushl $nnn; call VG_(oynk) ; addl $4,%esp; popal +#else +#define OYNNK(nnn) +#endif +#endif + +#endif // __ARM_CORE_ARCH_ASM_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/arm/dispatch.S b/coregrind/arm/dispatch.S new file mode 100644 index 000000000..ed74cb9fb --- /dev/null +++ b/coregrind/arm/dispatch.S @@ -0,0 +1,41 @@ + +##--------------------------------------------------------------------## +##--- The core dispatch loop, for jumping to a code address. ---## +##--- arm/dispatch.S ---## +##--------------------------------------------------------------------## + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "core_asm.h" + +.globl VG_(run_innerloop) +VG_(run_innerloop): + # this needs some improvement... + swi + +##--------------------------------------------------------------------## +##--- end ---## +##--------------------------------------------------------------------## diff --git a/coregrind/arm/jmp_with_stack.c b/coregrind/arm/jmp_with_stack.c new file mode 100644 index 000000000..b2f82f294 --- /dev/null +++ b/coregrind/arm/jmp_with_stack.c @@ -0,0 +1,58 @@ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "ume.h" + +/* + Jump to a particular IP with a particular SP. This is intended + to simulate the initial CPU state when the kernel starts an program + after exec; it therefore also clears all the other registers. + */ +void jmp_with_stack(Addr eip, Addr esp) +{ + // XXX: temporary only +extern int printf (__const char *__restrict __format, ...); +extern void exit (int __status); + printf("jmp_with_stack: argh\n"); + exit(1); +#if 0 + asm volatile ("movl %1, %%esp;" /* set esp */ + "pushl %%eax;" /* push esp */ + "xorl %%eax,%%eax;" /* clear registers */ + "xorl %%ebx,%%ebx;" + "xorl %%ecx,%%ecx;" + "xorl %%edx,%%edx;" + "xorl %%esi,%%esi;" + "xorl %%edi,%%edi;" + "xorl %%ebp,%%ebp;" + + "ret" /* return into entry */ + : : "a" (eip), "r" (esp)); + /* we should never get here */ + for(;;) + asm volatile("ud2"); +#endif +} diff --git a/coregrind/arm/libpthread.c b/coregrind/arm/libpthread.c new file mode 100644 index 000000000..a99657134 --- /dev/null +++ b/coregrind/arm/libpthread.c @@ -0,0 +1,257 @@ + +/*--------------------------------------------------------------------*/ +/*--- ARM-specific libpthread code. arm/libpthread.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +/* ALL THIS CODE RUNS ON THE SIMULATED CPU. + + See the comments at the top of coregrind/vg_libpthread.c for some + caveats. +*/ + +#include "core.h" /* For the VG_USERREQ__* constants */ + +#define __USE_UNIX98 +#include +#undef __USE_UNIX98 + +#define __USE_GNU +#include +#undef __USE_GNU + +#include + +// Struct used to describe a TDB header, copied from glibc. +typedef + struct { + void *tcb; + void *dtv; + void *self; + int multiple_threads; + unsigned long sysinfo; + } + tcbhead_t; + +/* --------------------------------------------------- + Helper functions for running a thread + and for clearing up afterwards. + ------------------------------------------------ */ + +#if 0 +typedef void *(*__attribute__ ((stdcall)) REGPARM(3) allocate_tls_t) (void *result); +typedef void (*__attribute__ ((stdcall)) REGPARM(3) deallocate_tls_t) (void *tcb, int dealloc_tcb); + +static allocate_tls_t allocate_tls = NULL; +static deallocate_tls_t deallocate_tls = NULL; + +static int get_gs() +{ + int gs; + asm volatile ("movw %%gs, %w0" : "=q" (gs)); + return gs & 0xffff; +} + +static void set_gs( int gs ) +{ + I_die_here; + asm volatile ("movw %w0, %%gs" :: "q" (gs)); +} + +static void *get_tcb() +{ + void *tcb; + asm volatile ("movl %%gs:0, %0" : "=r" (tcb)); + return tcb; +} +#endif + +Bool VGA_(has_tls)(void) +{ + I_die_here; +#if 0 + return (get_gs() & 7) == 3; +#endif +} + + +void VGA_(thread_create)(ThreadArchAux *aux) +{ + I_die_here; +#if 0 + if (VGA_(has_tls)()) { + tcbhead_t *tcb = get_tcb(); + + if (allocate_tls == NULL || deallocate_tls == NULL) { + allocate_tls = (allocate_tls_t)dlsym(RTLD_DEFAULT, "_dl_allocate_tls"); + deallocate_tls = (deallocate_tls_t)dlsym(RTLD_DEFAULT, "_dl_deallocate_tls"); + } + + my_assert(allocate_tls != NULL); + + aux->tls_data = allocate_tls(NULL); + aux->tls_segment = get_gs() >> 3; + aux->sysinfo = tcb->sysinfo; + + tcb->multiple_threads = 1; + } else { + aux->tls_data = NULL; + aux->tls_segment = -1; + aux->sysinfo = 0; + } +#endif +} + +void VGA_(thread_wrapper)(ThreadArchAux *aux) +{ + I_die_here; +#if 0 + void* tls_data; + int tls_segment; + unsigned long sysinfo; + + tls_data = aux->tls_data; + tls_segment = aux->tls_segment; + sysinfo = aux->sysinfo; + + if (tls_data) { + tcbhead_t *tcb = tls_data; + vki_modify_ldt_t ldt_info; + + /* Fill in the TCB header */ + tcb->tcb = tcb; + tcb->self = tcb; + tcb->multiple_threads = 1; + tcb->sysinfo = sysinfo; + + /* Fill in an LDT descriptor */ + ldt_info.entry_number = tls_segment; + ldt_info.base_addr = (unsigned long)tls_data; + ldt_info.limit = 0xfffff; + ldt_info.seg_32bit = 1; + ldt_info.contents = 0; + ldt_info.read_exec_only = 0; + ldt_info.limit_in_pages = 1; + ldt_info.seg_not_present = 0; + ldt_info.useable = 1; + ldt_info.reserved = 0; + + /* Install the thread area */ + VG_(do_syscall)(__NR_set_thread_area, &ldt_info); + + /* Setup the GS segment register */ + set_gs(ldt_info.entry_number * 8 + 3); + } +#endif +} + +void VGA_(thread_exit)(void) +{ + I_die_here; +#if 0 + /* Free up any TLS data */ + if ((get_gs() & 7) == 3 && pthread_self() > 1) { + my_assert(deallocate_tls != NULL); + deallocate_tls(get_tcb(), 1); + } +#endif +} + +/* POSIX spinlocks, taken from glibc linuxthreads/sysdeps/i386 */ + +typedef volatile int pthread_spinlock_t; /* Huh? Guarded by __USE_XOPEN2K */ + +int pthread_spin_init(pthread_spinlock_t *lock, int pshared) +{ + I_die_here; +#if 0 + /* We can ignore the `pshared' parameter. Since we are busy-waiting + all processes which can access the memory location `lock' points + to can use the spinlock. */ + *lock = 1; + return 0; +#endif +} + +int pthread_spin_lock(pthread_spinlock_t *lock) +{ + I_die_here; +#if 0 + asm volatile + ("\n" + "1:\n\t" + "lock; decl %0\n\t" + "js 2f\n\t" + ".section .text.spinlock,\"ax\"\n" + "2:\n\t" + "cmpl $0,%0\n\t" + "rep; nop\n\t" + "jle 2b\n\t" + "jmp 1b\n\t" + ".previous" + : "=m" (*lock)); + return 0; +#endif +} + +int pthread_spin_unlock(pthread_spinlock_t *lock) +{ + I_die_here; +#if 0 + asm volatile + ("movl $1,%0" + : "=m" (*lock)); + return 0; +#endif +} + +int pthread_spin_destroy(pthread_spinlock_t *lock) +{ + I_die_here; +#if 0 + /* Nothing to do. */ + return 0; +#endif +} + +int pthread_spin_trylock(pthread_spinlock_t *lock) +{ + I_die_here; +#if 0 + int oldval; + + asm volatile + ("xchgl %0,%1" + : "=r" (oldval), "=m" (*lock) + : "0" (0)); + return oldval > 0 ? 0 : EBUSY; +#endif +} + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/arm/signal.c b/coregrind/arm/signal.c new file mode 100644 index 000000000..17b81f6db --- /dev/null +++ b/coregrind/arm/signal.c @@ -0,0 +1,312 @@ + +/*--------------------------------------------------------------------*/ +/*--- ARM signals, etc. arm/signal.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "core.h" + +#include "libvex_guest_arm.h" + +/*------------------------------------------------------------*/ +/*--- Signal frame ---*/ +/*------------------------------------------------------------*/ + +// A structure in which to save the application's registers +// during the execution of signal handlers. + +#if 0 +typedef + struct { + /* There are two different stack frame formats, depending on + whether the client set the SA_SIGINFO flag for the handler. + This structure is put onto the client's stack as part of + signal delivery, and therefore appears as the signal + handler's arguments. + + The first two words are common for both frame formats - + they're the return address and the signal number. */ + + /* Sig handler's (bogus) return address */ + Addr retaddr; + /* The arg to the sig handler. We need to inspect this after + the handler returns, but it's unreasonable to assume that the + handler won't change it. So we keep a second copy of it in + sigNo_private. */ + Int sigNo; + + /* This is where the two frames start differing. */ + union { + struct { /* set SA_SIGINFO */ + /* ptr to siginfo_t. */ + Addr psigInfo; + + /* ptr to ucontext */ + Addr puContext; + } sigInfo; + struct vki_sigcontext sigContext; /* did not set SA_SIGINFO */ + } handlerArgs; + + /* The rest are private fields which the handler is unaware of. */ + + /* Sanity check word. */ + UInt magicPI; + /* pointed to by psigInfo */ + vki_siginfo_t sigInfo; + /* pointed to by puContext */ + struct vki_ucontext uContext; + + /* Safely-saved version of sigNo, as described above. */ + Int sigNo_private; + + /* Saved processor state. */ + VexGuestX86State vex; + VexGuestX86State vex_shadow; + + /* saved signal mask to be restored when handler returns */ + vki_sigset_t mask; + + /* Scheduler-private stuff: what was the thread's status prior to + delivering this signal? */ + ThreadStatus status; + void* /*pthread_mutex_t* */ associated_mx; + void* /*pthread_cond_t* */ associated_cv; + + /* Sanity check word. Is the highest-addressed word; do not + move!*/ + UInt magicE; + } + VgSigFrame; +#endif + +/*------------------------------------------------------------*/ +/*--- Signal operations ---*/ +/*------------------------------------------------------------*/ + +#if 0 +/* Make up a plausible-looking thread state from the thread's current state */ +static void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, + const vki_sigset_t *set, struct vki_ucontext *uc) +{ + ThreadState *tst = VG_(get_ThreadState)(tid); + struct vki_sigcontext *sc = &uc->uc_mcontext; + + VG_(memset)(uc, 0, sizeof(*uc)); + + uc->uc_flags = 0; + uc->uc_link = 0; + uc->uc_sigmask = *set; + uc->uc_stack = tst->altstack; + +#define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG + SC2(gs,GS); + SC2(fs,FS); + SC2(es,ES); + SC2(ds,DS); + + SC2(edi,EDI); + SC2(esi,ESI); + SC2(ebp,EBP); + SC2(esp,ESP); + SC2(ebx,EBX); + SC2(edx,EDX); + SC2(ecx,ECX); + SC2(eax,EAX); + + SC2(eip,EIP); + SC2(cs,CS); + sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex); + SC2(ss,SS); + /* XXX esp_at_signal */ + /* XXX trapno */ + /* XXX err */ +#undef SC2 + + sc->cr2 = (UInt)si->_sifields._sigfault._addr; +} +#endif + +#if 0 +#define SET_SIGNAL_ESP(zztid, zzval) \ + SET_THREAD_REG(zztid, zzval, ARCH_STACK_PTR, R_STACK_PTR, \ + post_reg_write_deliver_signal) +#endif + +void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame, + const vki_siginfo_t *siginfo, + void *handler, UInt flags, + const vki_sigset_t *mask) +{ + I_die_here; +#if 0 + Addr esp; + ThreadState* tst; + VgSigFrame* frame; + Int sigNo = siginfo->si_signo; + + esp = esp_top_of_frame; + esp -= sizeof(VgSigFrame); + frame = (VgSigFrame*)esp; + + tst = & VG_(threads)[tid]; + + /* For tracking memory events, indicate the entire frame has been + * allocated, but pretend that only the first four words are written */ + VG_TRACK( new_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) ); + + /* Assert that the frame is placed correctly. */ + vg_assert( (sizeof(VgSigFrame) & 0x3) == 0 ); + vg_assert( ((Char*)(&frame->magicE)) + sizeof(UInt) + == ((Char*)(esp_top_of_frame)) ); + + /* retaddr, sigNo, psigInfo, puContext fields are to be written */ + VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame", + (Addr)frame, offsetof(VgSigFrame, handlerArgs) ); + frame->retaddr = (UInt)VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset); + frame->sigNo = sigNo; + frame->sigNo_private = sigNo; + VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerArgs) ); + + if (flags & VKI_SA_SIGINFO) { + /* if the client asked for a siginfo delivery, then build the stack that way */ + VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)", + (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) ); + frame->handlerArgs.sigInfo.psigInfo = (Addr)&frame->sigInfo; + frame->handlerArgs.sigInfo.puContext = (Addr)&frame->uContext; + VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) ); + + VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)", + (Addr)&frame->sigInfo, sizeof(frame->sigInfo) ); + VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); + VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) ); + + VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)", + (Addr)&frame->uContext, sizeof(frame->uContext) ); + synth_ucontext(tid, siginfo, mask, &frame->uContext); + VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uContext) ); + } else { + struct vki_ucontext uc; + + /* otherwise just put the sigcontext there */ + + synth_ucontext(tid, siginfo, mask, &uc); + + VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (sigcontext)", + (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) ); + VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext, + sizeof(struct vki_sigcontext)); + VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, + sizeof(frame->handlerArgs.sigContext) ); + + frame->handlerArgs.sigContext.oldmask = tst->sig_mask.sig[0]; + } + + frame->magicPI = 0x31415927; + + frame->vex = tst->arch.vex; + if (VG_(needs).shadow_regs) + frame->vex_shadow = tst->arch.vex_shadow; + + frame->mask = tst->sig_mask; + + /* If the thread is currently blocked in a syscall, we want it to + resume as runnable. */ + if (tst->status == VgTs_WaitSys) + frame->status = VgTs_Runnable; + else + frame->status = tst->status; + + frame->associated_mx = tst->associated_mx; + frame->associated_cv = tst->associated_cv; + + frame->magicE = 0x27182818; + + /* Ensure 'tid' and 'tst' correspond */ + vg_assert(& VG_(threads)[tid] == tst); + /* Set the thread so it will next run the handler. */ + /* tst->m_esp = esp; */ + SET_SIGNAL_ESP(tid, esp); + + tst->arch.vex.guest_EIP = (Addr) handler; + /* This thread needs to be marked runnable, but we leave that the + caller to do. */ + + if (0) + VG_(printf)("pushed signal frame; %%ESP now = %p, next %%EBP = %p, status=%d\n", + esp, tst->arch.vex.guest_EIP, tst->status); +#endif +} + +Int VGA_(pop_signal_frame)(ThreadId tid) +{ + I_die_here; +#if 0 + Addr esp; + VgSigFrame* frame; + ThreadState* tst; + + vg_assert(VG_(is_valid_tid)(tid)); + tst = & VG_(threads)[tid]; + + /* Correctly reestablish the frame base address. */ + esp = tst->arch.vex.guest_ESP; + frame = (VgSigFrame*) + (esp -4 /* because the handler's RET pops the RA */ + +20 /* because signalreturn_bogusRA pushes 5 words */); + + vg_assert(frame->magicPI == 0x31415927); + vg_assert(frame->magicE == 0x27182818); + if (VG_(clo_trace_signals)) + VG_(message)(Vg_DebugMsg, + "vg_pop_signal_frame (thread %d): valid magic; EIP=%p", tid, frame->vex.guest_EIP); + + /* Mark the frame structure as nonaccessible. */ + VG_TRACK( die_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) ); + + /* restore machine state */ + tst->arch.vex = frame->vex; + if (VG_(needs).shadow_regs) + tst->arch.vex_shadow = frame->vex_shadow; + + /* And restore the thread's status to what it was before the signal + was delivered. */ + tst->status = frame->status; + + tst->associated_mx = frame->associated_mx; + tst->associated_cv = frame->associated_cv; + + tst->sig_mask = frame->mask; + + /* don't use the copy exposed to the handler; it might have changed + it. */ + return frame->sigNo_private; +#endif +} + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/arm/state.c b/coregrind/arm/state.c new file mode 100644 index 000000000..5204c9fb0 --- /dev/null +++ b/coregrind/arm/state.c @@ -0,0 +1,281 @@ + +/*--------------------------------------------------------------------*/ +/*--- x86 registers, etc. x86/state.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "core.h" +#include + +#include "libvex_guest_arm.h" + + +/*------------------------------------------------------------*/ +/*--- Initialising the first thread ---*/ +/*------------------------------------------------------------*/ + +Int VGOFF_(m_eip) = INVALID_OFFSET; + + +/* Given a pointer to the ThreadArchState for thread 1 (the root + thread), initialise the VEX guest state, and copy in essential + starting values. +*/ +void VGA_(init_thread1state) ( Addr client_eip, + Addr esp_at_startup, + /*MOD*/ ThreadArchState* arch ) +{ + I_die_here; +#if 0 + vg_assert(0 == sizeof(VexGuestX86State) % 8); + + /* Zero out the initial state, and set up the simulated FPU in a + sane way. */ + LibVEX_GuestX86_initialise(&arch->vex); + + /* Zero out the shadow area. */ + VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestX86State)); + + /* Put essential stuff into the new state. */ + /* initialise %cs, %ds and %ss to point at the operating systems + default code, data and stack segments */ + arch->vex.guest_ESP = esp_at_startup; + arch->vex.guest_EIP = client_eip; + + asm volatile("movw %%cs, %0" + : + : "m" (arch->vex.guest_CS)); + asm volatile("movw %%ds, %0" + : + : "m" (arch->vex.guest_DS)); + asm volatile("movw %%ss, %0" + : + : "m" (arch->vex.guest_SS)); + + /* The dispatch loop needs to be able to find %EIP given a pointer + to the start of the .vex field. */ + VGOFF_(m_eip) = offsetof(VexGuestX86State,guest_EIP)/4; + + VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0, + sizeof(VexGuestArchState)); + + /* I assume that if we have SSE2 we also have SSE */ + VG_(have_ssestate) = False; + // VG_(cpu_has_feature)(VG_X86_FEAT_FXSR) && + // VG_(cpu_has_feature)(VG_X86_FEAT_SSE); + + if (0) { + if (VG_(have_ssestate)) + VG_(printf)("Looks like a SSE-capable CPU\n"); + else + VG_(printf)("Looks like a MMX-only CPU\n"); + } +#endif +} + + +/*------------------------------------------------------------*/ +/*--- Thread stuff ---*/ +/*------------------------------------------------------------*/ + +void VGA_(clear_thread)( ThreadArchState *arch ) +{ + I_die_here; +#if 0 + arch->ldt = NULL; + VG_(clear_TLS_for_thread)(arch->tls); +#endif +} + +void VGA_(init_thread)( ThreadArchState *arch ) +{ + I_die_here; +#if 0 + VG_(baseBlock)[VGOFF_(tls_ptr)] = (UInt)arch->tls; +#endif +} + +void VGA_(cleanup_thread) ( ThreadArchState *arch ) +{ + I_die_here; +#if 0 + /* Deallocate its LDT, if it ever had one. */ + VG_(deallocate_LDT_for_thread)( arch->ldt ); + arch->ldt = NULL; + + /* Clear its TLS array. */ + VG_(clear_TLS_for_thread)( arch->tls ); +#endif +} + +void VGA_(setup_child) ( ThreadArchState *regs, ThreadArchState *parent_regs ) +{ + I_die_here; +#if 0 + /* We inherit our parent's LDT. */ + if (parent_regs->ldt == NULL) { + /* We hope this is the common case. */ + VG_(baseBlock)[VGOFF_(ldt)] = 0; + } else { + /* No luck .. we have to take a copy of the parent's. */ + regs->ldt = VG_(allocate_LDT_for_thread)( parent_regs->ldt ); + VG_(baseBlock)[VGOFF_(ldt)] = (UInt) regs->ldt; + } + + /* Initialise the thread's TLS array */ + VG_(clear_TLS_for_thread)( regs->tls ); + VG_(baseBlock)[VGOFF_(tls_ptr)] = (UInt) regs->tls; +#endif +} + +void VGA_(set_arg_and_bogus_ret)( ThreadId tid, UWord arg, Addr ret ) +{ + I_die_here; +#if 0 + /* Push the arg, and mark it as readable. */ + SET_PTHREQ_ESP(tid, VG_(threads)[tid].arch.vex.guest_ESP - sizeof(UWord)); + * (UInt*)(VG_(threads)[tid].arch.vex.guest_ESP) = arg; + VG_TRACK( post_mem_write, VG_(threads)[tid].arch.vex.guest_ESP, sizeof(void*) ); + + /* Don't mark the pushed return address as readable; any attempt to read + this is an internal valgrind bug since thread_exit_wrapper() should not + return. */ + SET_PTHREQ_ESP(tid, VG_(threads)[tid].arch.vex.guest_ESP - sizeof(UWord)); + * (UInt*)(VG_(threads)[tid].arch.vex.guest_ESP) = ret; +#endif +} + +void VGA_(thread_initial_stack)(ThreadId tid, UWord arg, Addr ret) +{ + I_die_here; +#if 0 + Addr esp = (Addr)ARCH_STACK_PTR(VG_(threads)[tid].arch); + + /* push two args */ + esp -= 2 * sizeof(UWord); + SET_PTHREQ_ESP(tid, esp); + + VG_TRACK ( new_mem_stack, esp, 2 * sizeof(UWord) ); + VG_TRACK ( pre_mem_write, Vg_CorePThread, tid, "new thread: stack", + esp, 2 * sizeof(UWord) ); + + /* push arg and (bogus) return address */ + *(UWord*)(esp+sizeof(UWord)) = arg; + *(UWord*)(esp) = ret; + + VG_TRACK ( post_mem_write, esp, 2 * sizeof(UWord) ); +#endif +} + + +/*------------------------------------------------------------*/ +/*--- Symtab stuff ---*/ +/*------------------------------------------------------------*/ + +UInt *VGA_(reg_addr_from_tst)(Int regno, ThreadArchState *arch) +{ + I_die_here; +#if 0 + switch (regno) { + case R_EAX: return &arch->vex.guest_EAX; + case R_ECX: return &arch->vex.guest_ECX; + case R_EDX: return &arch->vex.guest_EDX; + case R_EBX: return &arch->vex.guest_EBX; + case R_ESP: return &arch->vex.guest_ESP; + case R_EBP: return &arch->vex.guest_EBP; + case R_ESI: return &arch->vex.guest_ESI; + case R_EDI: return &arch->vex.guest_EDI; + default: return NULL; + } +#endif +} + +/*------------------------------------------------------------*/ +/*--- pointercheck ---*/ +/*------------------------------------------------------------*/ + +Bool VGA_(setup_pointercheck)(void) +{ + I_die_here; +#if 0 + vki_modify_ldt_t ldt = { + VG_POINTERCHECK_SEGIDX, // entry_number + VG_(client_base), // base_addr + (VG_(client_end)-VG_(client_base)) / VKI_PAGE_SIZE, // limit + 1, // seg_32bit + 0, // contents: data, RW, non-expanding + 0, // ! read_exec_only + 1, // limit_in_pages + 0, // ! seg not present + 1, // useable + }; + int ret = VG_(do_syscall)(__NR_modify_ldt, 1, &ldt, sizeof(ldt)); + if (ret < 0) { + VG_(message)(Vg_UserMsg, + "Warning: ignoring --pointercheck=yes, " + "because modify_ldt failed (errno=%d)", -ret); + return False; + } else { + return True; + } +#endif +} + +/*------------------------------------------------------------*/ +/*--- Debugger-related operations ---*/ +/*------------------------------------------------------------*/ + +Int VGA_(ptrace_setregs_from_tst)(Int pid, ThreadArchState* arch) +{ + I_die_here; +#if 0 + struct vki_user_regs_struct regs; + + regs.cs = arch->vex.guest_CS; + regs.ss = arch->vex.guest_SS; + regs.ds = arch->vex.guest_DS; + regs.es = arch->vex.guest_ES; + regs.fs = arch->vex.guest_FS; + regs.gs = arch->vex.guest_GS; + regs.eax = arch->vex.guest_EAX; + regs.ebx = arch->vex.guest_EBX; + regs.ecx = arch->vex.guest_ECX; + regs.edx = arch->vex.guest_EDX; + regs.esi = arch->vex.guest_ESI; + regs.edi = arch->vex.guest_EDI; + regs.ebp = arch->vex.guest_EBP; + regs.esp = arch->vex.guest_ESP; + regs.eflags = LibVEX_GuestX86_get_eflags(&arch->vex); + regs.eip = arch->vex.guest_EIP; + + return ptrace(PTRACE_SETREGS, pid, NULL, ®s); +#endif +} + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/core.h b/coregrind/core.h index 7d131eab0..4d4dd927d 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -79,7 +79,6 @@ external tools. */ - /* For system call numbers __NR_... */ #include "vki_unistd.h" @@ -992,6 +991,12 @@ extern void VG_(get_sigstack_bounds)( Addr* low, Addr* high ); Exports of vg_mylibc.c ------------------------------------------------------------------ */ +// Useful for making failing stubs, when certain things haven't yet been +// implemented. +#define I_die_here \ + VG_(core_assert_fail) ("Unimplemented functionality", \ + __FILE__, __LINE__, __PRETTY_FUNCTION__) + #define vg_assert(expr) \ ((void) ((expr) ? 0 : \ (VG_(core_assert_fail) (VG__STRING(expr), \ diff --git a/coregrind/gen_intercepts.pl b/coregrind/gen_intercepts.pl index d522908fa..692ee1e2b 100644 --- a/coregrind/gen_intercepts.pl +++ b/coregrind/gen_intercepts.pl @@ -28,19 +28,21 @@ use strict; while(<>) { if(/VG_INTERCEPT\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/) { my $ver = $1 . ":" . $2; - $ver =~ s/\*/\$2A/g; - $ver =~ s/\+/\$2B/g; - $ver =~ s/\-/\$2D/g; - $ver =~ s/\./\$2E/g; - $ver =~ s/\:/\$3A/g; + ($ver =~ /J/) and die "Argh, 'J' in intercept muck..."; + $ver =~ s/\*/J2A/g; + $ver =~ s/\+/J2B/g; + $ver =~ s/\-/J2D/g; + $ver =~ s/\./J2E/g; + $ver =~ s/\:/J3A/g; s/VG_INTERCEPT\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/VG_INTERCEPT($ver)/g; } elsif(/VG_INTERCEPT_ALIAS\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/) { my $ver = $1 . ":" . $2; - $ver =~ s/\*/\$2A/g; - $ver =~ s/\+/\$2B/g; - $ver =~ s/\-/\$2D/g; - $ver =~ s/\./\$2E/g; - $ver =~ s/\:/\$3A/g; + ($ver =~ /J/) and die "Argh, 'J' in intercept muck..."; + $ver =~ s/\*/J2A/g; + $ver =~ s/\+/J2B/g; + $ver =~ s/\-/J2D/g; + $ver =~ s/\./J2E/g; + $ver =~ s/\:/J3A/g; s/VG_INTERCEPT_ALIAS\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/VG_INTERCEPT_ALIAS($ver)/g; } print $_; diff --git a/coregrind/vg_execontext.c b/coregrind/vg_execontext.c index 8f53fc484..16be0f445 100644 --- a/coregrind/vg_execontext.c +++ b/coregrind/vg_execontext.c @@ -311,6 +311,7 @@ void get_needed_regs(ThreadId tid, Addr* ip, Addr* fp, Addr* sp, *sp = STACK_PTR(tst->arch); *stack_highest_word = tst->stack_highest_word; +#ifdef __x86__ /* Nasty little hack to deal with sysinfo syscalls - if libc is using the sysinfo page for syscalls (the TLS version does), then ip will always appear to be in that page when doing a syscall, @@ -325,6 +326,7 @@ void get_needed_regs(ThreadId tid, Addr* ip, Addr* fp, Addr* sp, *ip = *(Addr *)*sp; *sp += sizeof(Addr); } +#endif } ExeContext* VG_(get_ExeContext) ( ThreadId tid ) diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index a92af0fb2..0930f2c41 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -1120,9 +1120,11 @@ static Addr setup_client_stack(void* init_sp, *auxv = *orig_auxv; vg_assert(auxv->a_type == AT_NULL); +#ifdef __x86__ /* --- trampoline page --- */ VG_(memcpy)( (void *)VG_(client_trampoline_code), &VG_(trampoline_code_start), VG_(trampoline_code_length) ); +#endif vg_assert((strtab-stringbase) == stringsize); @@ -1671,7 +1673,6 @@ static void pre_process_cmd_line_options static void process_cmd_line_options( UInt* client_auxv, const char* toolname ) { Int i, eventually_log_fd; - Int *auxp; Int toolname_len = VG_(strlen)(toolname); /* log to stderr by default, but usage message goes to stdout */ @@ -1682,13 +1683,18 @@ static void process_cmd_line_options( UInt* client_auxv, const char* toolname ) config_error("Please use absolute paths in " "./configure --prefix=... or --libdir=..."); - for (auxp = client_auxv; auxp[0] != AT_NULL; auxp += 2) { - switch(auxp[0]) { - case AT_SYSINFO: - auxp[1] = (Int)(VG_(client_trampoline_code) + VG_(tramp_syscall_offset)); - break; - } - } +#ifdef __x86__ + { + Int *auxp; + for (auxp = client_auxv; auxp[0] != AT_NULL; auxp += 2) { + switch(auxp[0]) { + case AT_SYSINFO: + auxp[1] = (Int)(VG_(client_trampoline_code) + VG_(tramp_syscall_offset)); + break; + } + } + } +#endif for (i = 1; i < vg_argc; i++) { @@ -2565,12 +2571,14 @@ int main(int argc, char **argv) VG_(parse_procselfmaps) ( build_segment_map_callback ); /* everything */ sp_at_startup___global_arg = 0; +#ifdef __i386__ //-------------------------------------------------------------- // Protect client trampoline page (which is also sysinfo stuff) // p: segment stuff [otherwise get seg faults...] //-------------------------------------------------------------- VG_(mprotect)( (void *)VG_(client_trampoline_code), VG_(trampoline_code_length), VKI_PROT_READ|VKI_PROT_EXEC ); +#endif //============================================================== // Can use VG_(map)() after segments set up diff --git a/coregrind/vg_proxylwp.c b/coregrind/vg_proxylwp.c index 5c92166e8..f3b235f27 100644 --- a/coregrind/vg_proxylwp.c +++ b/coregrind/vg_proxylwp.c @@ -359,15 +359,15 @@ static Bool recv_reply(struct PX_Reply *reply) static void thread_syscall(Int syscallno, ThreadArchState *arch, enum PXState *state , enum PXState poststate) { - VGA_(do_thread_syscall)(syscallno, // syscall no. - arch->vex.guest_EBX, // arg 1 - arch->vex.guest_ECX, // arg 2 - arch->vex.guest_EDX, // arg 3 - arch->vex.guest_ESI, // arg 4 - arch->vex.guest_EDI, // arg 5 - arch->vex.guest_EBP, // arg 6 - (UWord*)&arch->vex.guest_EAX, // result - state, // state to update + VGA_(do_thread_syscall)(syscallno, + arch->vex.PLATFORM_SYSCALL_ARG1, + arch->vex.PLATFORM_SYSCALL_ARG2, + arch->vex.PLATFORM_SYSCALL_ARG3, + arch->vex.PLATFORM_SYSCALL_ARG4, + arch->vex.PLATFORM_SYSCALL_ARG5, + arch->vex.PLATFORM_SYSCALL_ARG6, + (UWord*)&arch->vex.PLATFORM_SYSCALL_RET, // result + state, // state to update poststate); // state when syscall has finished } diff --git a/coregrind/vg_symtab2.c b/coregrind/vg_symtab2.c index 05b0efadd..f67c19df8 100644 --- a/coregrind/vg_symtab2.c +++ b/coregrind/vg_symtab2.c @@ -790,13 +790,13 @@ intercept_demangle(const Char* symbol, Char* result, Int nbytes) int len = VG_(strlen)(symbol); for(i = VG_INTERCEPT_PREFIX_LEN; i < len; i++) { - if(symbol[i] == '$') { + if(symbol[i] == 'J') { i++; - if(symbol[i] == '$') { - result[j] = '$'; - } else if((symbol[i] >= '0' && symbol[i] <= '9') || - (symbol[i] >= 'a' && symbol[i] <= 'f') || - (symbol[i] >= 'A' && symbol[i] <= 'F')) { + vg_assert('J' != symbol[i]); + if((symbol[i] >= '0' && symbol[i] <= '9') || + (symbol[i] >= 'a' && symbol[i] <= 'f') || + (symbol[i] >= 'A' && symbol[i] <= 'F')) + { int x = symbol[i++]; int y = symbol[i]; if(x >= '0' && x <= '9') { @@ -2506,12 +2506,14 @@ void VG_(setup_code_redirect_table) ( void ) "soname:libpthread.so.0", redirects[i].to); } +#ifdef __x86__ /* Redirect _dl_sysinfo_int80, which is glibc's default system call routine, to the routine in our trampoline page so that the special sysinfo unwind hack in vg_execontext.c will kick in. */ add_redirect_addr("soname:ld-linux.so.2", "_dl_sysinfo_int80", VG_(client_trampoline_code)+VG_(tramp_syscall_offset)); +#endif /* Overenthusiastic use of PLT bypassing by the glibc people also means we need to patch the following functions to our own diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index 88cdd1329..01a5b5c0a 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -1062,69 +1062,6 @@ PRE(sys_ni_syscall, Special) set_result( -VKI_ENOSYS ); } -// XXX: I think this is x86/linux-specific... at least some of the entries -// are non-generic -// XXX: Why is the memory pointed to by arg3 never checked? -PRE(sys_ptrace, 0) -{ - PRINT("sys_ptrace ( %d, %d, %p, %p )", arg1,arg2,arg3,arg4); - PRE_REG_READ4(int, "ptrace", - long, request, long, pid, long, addr, long, data); - switch (arg1) { - case 12: /* PTRACE_GETREGS */ - PRE_MEM_WRITE( "ptrace(getregs)", arg4, - sizeof (struct vki_user_regs_struct)); - break; - case 14: /* PTRACE_GETFPREGS */ - PRE_MEM_WRITE( "ptrace(getfpregs)", arg4, - sizeof (struct vki_user_i387_struct)); - break; - case 18: /* PTRACE_GETFPXREGS */ - PRE_MEM_WRITE( "ptrace(getfpxregs)", arg4, - sizeof(struct vki_user_fxsr_struct) ); - break; - case 1: case 2: case 3: /* PTRACE_PEEK{TEXT,DATA,USER} */ - PRE_MEM_WRITE( "ptrace(peek)", arg4, - sizeof (long)); - break; - case 13: /* PTRACE_SETREGS */ - PRE_MEM_READ( "ptrace(setregs)", arg4, - sizeof (struct vki_user_regs_struct)); - break; - case 15: /* PTRACE_SETFPREGS */ - PRE_MEM_READ( "ptrace(setfpregs)", arg4, - sizeof (struct vki_user_i387_struct)); - break; - case 19: /* PTRACE_SETFPXREGS */ - PRE_MEM_READ( "ptrace(setfpxregs)", arg4, - sizeof(struct vki_user_fxsr_struct) ); - break; - default: - break; - } -} - -// XXX: I think this is x86/linux-specific -POST(sys_ptrace) -{ - switch (arg1) { - case 12: /* PTRACE_GETREGS */ - POST_MEM_WRITE( arg4, sizeof (struct vki_user_regs_struct)); - break; - case 14: /* PTRACE_GETFPREGS */ - POST_MEM_WRITE( arg4, sizeof (struct vki_user_i387_struct)); - break; - case 18: /* PTRACE_GETFPXREGS */ - POST_MEM_WRITE( arg4, sizeof(struct vki_user_fxsr_struct) ); - break; - case 1: case 2: case 3: /* PTRACE_PEEK{TEXT,DATA,USER} */ - POST_MEM_WRITE( arg4, sizeof (long)); - break; - default: - break; - } -} - PRE(sys_set_tid_address, Special) { // We don't let this syscall run, and don't do anything to simulate it @@ -4347,7 +4284,7 @@ PRE(sys_read, MayBlock) { PRINT("sys_read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3); PRE_REG_READ3(ssize_t, "read", - unsigned int, fd, char *, buf, size_t, count); + unsigned int, fd, char *, buf, vki_size_t, count); if (!VG_(fd_allowed)(arg1, "read", tid, False)) set_result( -VKI_EBADF ); @@ -4364,7 +4301,7 @@ PRE(sys_write, MayBlock) { PRINT("sys_write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3); PRE_REG_READ3(ssize_t, "write", - unsigned int, fd, const char *, buf, size_t, count); + unsigned int, fd, const char *, buf, vki_size_t, count); if (!VG_(fd_allowed)(arg1, "write", tid, False)) set_result( -VKI_EBADF ); else diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c index e5cedbe8d..6d146d760 100644 --- a/coregrind/x86-linux/syscalls.c +++ b/coregrind/x86-linux/syscalls.c @@ -239,6 +239,71 @@ PRE(sys_get_thread_area, Special) } } +// Parts of this are x86-specific, but the *PEEK* cases are generic. +// XXX: Why is the memory pointed to by arg3 never checked? +PRE(sys_ptrace, 0) +{ + PRINT("sys_ptrace ( %d, %d, %p, %p )", arg1,arg2,arg3,arg4); + PRE_REG_READ4(int, "ptrace", + long, request, long, pid, long, addr, long, data); + switch (arg1) { + case VKI_PTRACE_PEEKTEXT: + case VKI_PTRACE_PEEKDATA: + case VKI_PTRACE_PEEKUSR: + PRE_MEM_WRITE( "ptrace(peek)", arg4, + sizeof (long)); + break; + case VKI_PTRACE_GETREGS: + PRE_MEM_WRITE( "ptrace(getregs)", arg4, + sizeof (struct vki_user_regs_struct)); + break; + case VKI_PTRACE_GETFPREGS: + PRE_MEM_WRITE( "ptrace(getfpregs)", arg4, + sizeof (struct vki_user_i387_struct)); + break; + case VKI_PTRACE_GETFPXREGS: + PRE_MEM_WRITE( "ptrace(getfpxregs)", arg4, + sizeof(struct vki_user_fxsr_struct) ); + break; + case VKI_PTRACE_SETREGS: + PRE_MEM_READ( "ptrace(setregs)", arg4, + sizeof (struct vki_user_regs_struct)); + break; + case VKI_PTRACE_SETFPREGS: + PRE_MEM_READ( "ptrace(setfpregs)", arg4, + sizeof (struct vki_user_i387_struct)); + break; + case VKI_PTRACE_SETFPXREGS: + PRE_MEM_READ( "ptrace(setfpxregs)", arg4, + sizeof(struct vki_user_fxsr_struct) ); + break; + default: + break; + } +} + +POST(sys_ptrace) +{ + switch (arg1) { + case VKI_PTRACE_PEEKTEXT: + case VKI_PTRACE_PEEKDATA: + case VKI_PTRACE_PEEKUSR: + POST_MEM_WRITE( arg4, sizeof (long)); + break; + case VKI_PTRACE_GETREGS: + POST_MEM_WRITE( arg4, sizeof (struct vki_user_regs_struct)); + break; + case VKI_PTRACE_GETFPREGS: + POST_MEM_WRITE( arg4, sizeof (struct vki_user_i387_struct)); + break; + case VKI_PTRACE_GETFPXREGS: + POST_MEM_WRITE( arg4, sizeof(struct vki_user_fxsr_struct) ); + break; + default: + break; + } +} + #undef PRE #undef POST @@ -303,7 +368,7 @@ const struct SyscallTableEntry VGA_(syscall_table)[] = { GENX_(__NR_getuid, sys_getuid16), // 24 ## P // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN) - GENXY(__NR_ptrace, sys_ptrace), // 26 + PLAXY(__NR_ptrace, sys_ptrace), // 26 GENX_(__NR_alarm, sys_alarm), // 27 // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete GENX_(__NR_pause, sys_pause), // 29 diff --git a/include/arm-linux/Makefile.am b/include/arm-linux/Makefile.am new file mode 100644 index 000000000..ccd9861f8 --- /dev/null +++ b/include/arm-linux/Makefile.am @@ -0,0 +1,5 @@ +incincdir = $(includedir)/valgrind/arm-linux + +incinc_HEADERS = \ + vki_arch.h \ + vki_arch_posixtypes.h diff --git a/include/arm-linux/vki_arch.h b/include/arm-linux/vki_arch.h new file mode 100644 index 000000000..cc971cae3 --- /dev/null +++ b/include/arm-linux/vki_arch.h @@ -0,0 +1,620 @@ + +/*--------------------------------------------------------------------*/ +/*--- ARM/Linux-specific kernel interface. arm-linux/vki_arch.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __ARM_LINUX_VKI_ARCH_H +#define __ARM_LINUX_VKI_ARCH_H + +// ARM can be big or little endian; we're only supporting little endian. +#define VKI_LITTLE_ENDIAN 1 + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/types.h +//---------------------------------------------------------------------- + +typedef unsigned char __vki_u8; + +typedef __signed__ short __vki_s16; +typedef unsigned short __vki_u16; + +typedef unsigned int __vki_u32; + +typedef __signed__ long long __vki_s64; +typedef unsigned long long __vki_u64; + +typedef unsigned short vki_u16; + +typedef unsigned int vki_u32; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/page.h +//---------------------------------------------------------------------- + +#define VKI_PAGE_SHIFT 12 +#define VKI_PAGE_SIZE (1UL << VKI_PAGE_SHIFT) + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/signal.h +//---------------------------------------------------------------------- + +#define _VKI_NSIG 64 +#define _VKI_NSIG_BPW 32 +#define _VKI_NSIG_WORDS (_VKI_NSIG / _VKI_NSIG_BPW) + +typedef unsigned long vki_old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_VKI_NSIG_WORDS]; +} vki_sigset_t; + +#define VKI_SIGHUP 1 +#define VKI_SIGINT 2 +#define VKI_SIGQUIT 3 +#define VKI_SIGILL 4 +#define VKI_SIGTRAP 5 +#define VKI_SIGABRT 6 +//#define VKI_SIGIOT 6 +#define VKI_SIGBUS 7 +#define VKI_SIGFPE 8 +#define VKI_SIGKILL 9 +#define VKI_SIGUSR1 10 +#define VKI_SIGSEGV 11 +#define VKI_SIGUSR2 12 +#define VKI_SIGPIPE 13 +#define VKI_SIGALRM 14 +#define VKI_SIGTERM 15 +#define VKI_SIGSTKFLT 16 +#define VKI_SIGCHLD 17 +#define VKI_SIGCONT 18 +#define VKI_SIGSTOP 19 +#define VKI_SIGTSTP 20 +#define VKI_SIGTTIN 21 +#define VKI_SIGTTOU 22 +#define VKI_SIGURG 23 +#define VKI_SIGXCPU 24 +#define VKI_SIGXFSZ 25 +#define VKI_SIGVTALRM 26 +#define VKI_SIGPROF 27 +#define VKI_SIGWINCH 28 +#define VKI_SIGIO 29 +#define VKI_SIGPWR 30 +#define VKI_SIGSYS 31 +#define VKI_SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define VKI_SIGRTMIN 32 +#define VKI_SIGRTMAX _VKI_NSIG + +#define VKI_SIGSWI 32 + +#define VKI_SA_NOCLDSTOP 0x00000001 +#define VKI_SA_NOCLDWAIT 0x00000002 +#define VKI_SA_SIGINFO 0x00000004 +//#define VKI_SA_THIRTYTWO 0x02000000 +#define VKI_SA_RESTORER 0x04000000 +#define VKI_SA_ONSTACK 0x08000000 +#define VKI_SA_RESTART 0x10000000 +#define VKI_SA_NODEFER 0x40000000 +#define VKI_SA_RESETHAND 0x80000000 + +#define VKI_SA_NOMASK VKI_SA_NODEFER +#define VKI_SA_ONESHOT VKI_SA_RESETHAND +//#define VKI_SA_INTERRUPT 0x20000000 /* dummy -- ignored */ + + +#define VKI_SS_ONSTACK 1 +#define VKI_SS_DISABLE 2 + +#define VKI_MINSIGSTKSZ 2048 + +#define VKI_SIG_BLOCK 0 /* for blocking signals */ +#define VKI_SIG_UNBLOCK 1 /* for unblocking signals */ +#define VKI_SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void __vki_signalfn_t(int); +typedef __vki_signalfn_t __user *__vki_sighandler_t; + +typedef void __vki_restorefn_t(void); +typedef __vki_restorefn_t __user *__vki_sigrestore_t; + +#define VKI_SIG_DFL ((__vki_sighandler_t)0) /* default signal handling */ +#define VKI_SIG_IGN ((__vki_sighandler_t)1) /* ignore signal */ + +struct vki_old_sigaction { + // [[Nb: a 'k' prefix is added to "sa_handler" because + // bits/sigaction.h (which gets dragged in somehow via signal.h) + // #defines it as something else. Since that is done for glibc's + // purposes, which we don't care about here, we use our own name.]] + __vki_sighandler_t ksa_handler; + vki_old_sigset_t sa_mask; + unsigned long sa_flags; + __vki_sigrestore_t sa_restorer; +}; + +struct vki_sigaction { + // [[See comment about extra 'k' above]] + __vki_sighandler_t ksa_handler; + unsigned long sa_flags; + __vki_sigrestore_t sa_restorer; + vki_sigset_t sa_mask; /* mask last for extensibility */ +}; + +typedef struct vki_sigaltstack { + void __user *ss_sp; + int ss_flags; + vki_size_t ss_size; +} vki_stack_t; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/sigcontext.h +//---------------------------------------------------------------------- + +struct vki_sigcontext { + unsigned long trap_no; + unsigned long error_code; + unsigned long oldmask; + unsigned long arm_r0; + unsigned long arm_r1; + unsigned long arm_r2; + unsigned long arm_r3; + unsigned long arm_r4; + unsigned long arm_r5; + unsigned long arm_r6; + unsigned long arm_r7; + unsigned long arm_r8; + unsigned long arm_r9; + unsigned long arm_r10; + unsigned long arm_fp; + unsigned long arm_ip; + unsigned long arm_sp; + unsigned long arm_lr; + unsigned long arm_pc; + unsigned long arm_cpsr; + unsigned long fault_address; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/mman.h +//---------------------------------------------------------------------- + +#define VKI_PROT_READ 0x1 /* page can be read */ +#define VKI_PROT_WRITE 0x2 /* page can be written */ +#define VKI_PROT_EXEC 0x4 /* page can be executed */ +//#define VKI_PROT_SEM 0x8 /* page may be used for atomic ops */ +//#define VKI_PROT_NONE 0x0 /* page can not be accessed */ + +#define VKI_MAP_SHARED 0x01 /* Share changes */ +#define VKI_MAP_PRIVATE 0x02 /* Changes are private */ +#define VKI_MAP_TYPE 0x0f /* Mask for type of mapping */ +#define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ +#define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/fcntl.h +//---------------------------------------------------------------------- + +#define VKI_O_RDONLY 00 +#define VKI_O_WRONLY 01 +#define VKI_O_CREAT 0100 /* not fcntl */ +#define VKI_O_EXCL 0200 /* not fcntl */ +#define VKI_O_TRUNC 01000 /* not fcntl */ +#define VKI_O_NONBLOCK 04000 + +#define VKI_F_DUPFD 0 /* dup */ +#define VKI_F_GETFD 1 /* get close_on_exec */ +#define VKI_F_SETFD 2 /* set/clear close_on_exec */ +#define VKI_F_GETFL 3 /* get file->f_flags */ +#define VKI_F_SETFL 4 /* set file->f_flags */ +#define VKI_F_GETLK 5 +#define VKI_F_SETLK 6 +#define VKI_F_SETLKW 7 + +#define VKI_F_SETOWN 8 /* for sockets. */ +#define VKI_F_GETOWN 9 /* for sockets. */ +#define VKI_F_SETSIG 10 /* for sockets. */ +#define VKI_F_GETSIG 11 /* for sockets. */ + +#define VKI_F_GETLK64 12 /* using 'struct flock64' */ +#define VKI_F_SETLK64 13 +#define VKI_F_SETLKW64 14 + +/* for F_[GET|SET]FL */ +#define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +#define VKI_F_LINUX_SPECIFIC_BASE 1024 + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/resource.h +//---------------------------------------------------------------------- + +#define VKI_RLIMIT_DATA 2 /* max data size */ +#define VKI_RLIMIT_STACK 3 /* max stack size */ +#define VKI_RLIMIT_CORE 4 /* max core file size */ +#define VKI_RLIMIT_NOFILE 7 /* max number of open files */ + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/socket.h +//---------------------------------------------------------------------- + +#define VKI_SOL_SOCKET 1 + +#define VKI_SO_TYPE 3 + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/sockios.h +//---------------------------------------------------------------------- + +#define VKI_SIOCSPGRP 0x8902 +#define VKI_SIOCGPGRP 0x8904 +#define VKI_SIOCGSTAMP 0x8906 /* Get stamp */ + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/stat.h +//---------------------------------------------------------------------- + +// [[Nb: resolved some #ifdefs by assuming __ARMEB__ is false, ie. that +// we're not big-endian.]] +struct vki_stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned long st_rdev; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long st_atime_nsec; + unsigned long st_mtime; + unsigned long st_mtime_nsec; + unsigned long st_ctime; + unsigned long st_ctime_nsec; + unsigned long __unused4; + unsigned long __unused5; +}; + +struct vki_stat64 { + unsigned long long st_dev; + unsigned char __pad0[4]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* Future possible st_blocks hi bits */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long long st_ino; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/statfs.h +//---------------------------------------------------------------------- + +// [[Nb: asm-arm/statfs.h just #include asm-generic/statfs.h directly]] +struct vki_statfs { + __vki_u32 f_type; + __vki_u32 f_bsize; + __vki_u32 f_blocks; + __vki_u32 f_bfree; + __vki_u32 f_bavail; + __vki_u32 f_files; + __vki_u32 f_ffree; + __vki_kernel_fsid_t f_fsid; + __vki_u32 f_namelen; + __vki_u32 f_frsize; + __vki_u32 f_spare[5]; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/termios.h +//---------------------------------------------------------------------- + +struct vki_winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define VKI_NCC 8 +struct vki_termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[VKI_NCC]; /* control characters */ +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/termbits.h +//---------------------------------------------------------------------- + +typedef unsigned char vki_cc_t; +typedef unsigned int vki_tcflag_t; + +#define VKI_NCCS 19 +struct vki_termios { + vki_tcflag_t c_iflag; /* input mode flags */ + vki_tcflag_t c_oflag; /* output mode flags */ + vki_tcflag_t c_cflag; /* control mode flags */ + vki_tcflag_t c_lflag; /* local mode flags */ + vki_cc_t c_line; /* line discipline */ + vki_cc_t c_cc[VKI_NCCS]; /* control characters */ +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/ioctl.h +//---------------------------------------------------------------------- + +#define _VKI_IOC_NRBITS 8 +#define _VKI_IOC_TYPEBITS 8 +#define _VKI_IOC_SIZEBITS 14 +#define _VKI_IOC_DIRBITS 2 + +#define _VKI_IOC_SIZEMASK ((1 << _VKI_IOC_SIZEBITS)-1) +#define _VKI_IOC_DIRMASK ((1 << _VKI_IOC_DIRBITS)-1) + +#define _VKI_IOC_NRSHIFT 0 +#define _VKI_IOC_TYPESHIFT (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS) +#define _VKI_IOC_SIZESHIFT (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS) +#define _VKI_IOC_DIRSHIFT (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS) + +#define _VKI_IOC_NONE 0U +#define _VKI_IOC_WRITE 1U +#define _VKI_IOC_READ 2U + +#define _VKI_IOC(dir,type,nr,size) \ + (((dir) << _VKI_IOC_DIRSHIFT) | \ + ((type) << _VKI_IOC_TYPESHIFT) | \ + ((nr) << _VKI_IOC_NRSHIFT) | \ + ((size) << _VKI_IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _VKI_IO(type,nr) _VKI_IOC(_VKI_IOC_NONE,(type),(nr),0) +#define _VKI_IOR(type,nr,size) _VKI_IOC(_VKI_IOC_READ,(type),(nr),sizeof(size)) +#define _VKI_IOW(type,nr,size) _VKI_IOC(_VKI_IOC_WRITE,(type),(nr),sizeof(size)) +#define _VKI_IOWR(type,nr,size) _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _VKI_IOC_DIR(nr) (((nr) >> _VKI_IOC_DIRSHIFT) & _VKI_IOC_DIRMASK) +#define _VKI_IOC_SIZE(nr) (((nr) >> _VKI_IOC_SIZESHIFT) & _VKI_IOC_SIZEMASK) + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/ioctls.h +//---------------------------------------------------------------------- + +#define VKI_TCGETS 0x5401 +#define VKI_TCSETS 0x5402 +#define VKI_TCSETSW 0x5403 +#define VKI_TCSETSF 0x5404 +#define VKI_TCGETA 0x5405 +#define VKI_TCSETA 0x5406 +#define VKI_TCSETAW 0x5407 +#define VKI_TCSETAF 0x5408 +#define VKI_TCSBRK 0x5409 +#define VKI_TCXONC 0x540A +#define VKI_TCFLSH 0x540B +#define VKI_TIOCSCTTY 0x540E +#define VKI_TIOCGPGRP 0x540F +#define VKI_TIOCSPGRP 0x5410 +#define VKI_TIOCOUTQ 0x5411 +#define VKI_TIOCGWINSZ 0x5413 +#define VKI_TIOCSWINSZ 0x5414 +#define VKI_TIOCMBIS 0x5416 +#define VKI_TIOCMBIC 0x5417 +#define VKI_TIOCMSET 0x5418 +#define VKI_FIONREAD 0x541B +#define VKI_TIOCLINUX 0x541C +#define VKI_FIONBIO 0x5421 +#define VKI_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define VKI_TIOCGPTN _VKI_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define VKI_TIOCSPTLCK _VKI_IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define VKI_FIOASYNC 0x5452 + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/poll.h +//---------------------------------------------------------------------- + +#define VKI_POLLIN 0x0001 + +struct vki_pollfd { + int fd; + short events; + short revents; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/user.h +//---------------------------------------------------------------------- + +// XXX: For x86, had here: +// struct vki_user_i387_struct +// struct vki_user_fxsr_struct +// struct vki_user_regs_struct + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/ptrace.h +//---------------------------------------------------------------------- + +struct vki_pt_regs { + long uregs[18]; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/elf.h +//---------------------------------------------------------------------- + +typedef unsigned long vki_elf_greg_t; + +#define VKI_ELF_NGREG (sizeof (struct vki_pt_regs) / sizeof(vki_elf_greg_t)) +typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG]; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/ucontext.h +//---------------------------------------------------------------------- + +struct vki_ucontext { + unsigned long uc_flags; + struct vki_ucontext *uc_link; + vki_stack_t uc_stack; + struct vki_sigcontext uc_mcontext; + vki_sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/ipcbuf.h +//---------------------------------------------------------------------- + +struct vki_ipc64_perm +{ + __vki_kernel_key_t key; + __vki_kernel_uid32_t uid; + __vki_kernel_gid32_t gid; + __vki_kernel_uid32_t cuid; + __vki_kernel_gid32_t cgid; + __vki_kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/sembuf.h +//---------------------------------------------------------------------- + +struct vki_semid64_ds { + struct vki_ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __vki_kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __vki_kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/msgbuf.h +//---------------------------------------------------------------------- + +struct vki_msqid64_ds { + struct vki_ipc64_perm msg_perm; + __vki_kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __vki_kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __vki_kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __vki_kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __vki_kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/ipc.h +//---------------------------------------------------------------------- + +struct vki_ipc_kludge { + struct vki_msgbuf __user *msgp; + long msgtyp; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-arm/shmbuf.h +//---------------------------------------------------------------------- + +struct vki_shmid64_ds { + struct vki_ipc64_perm shm_perm; /* operation perms */ + vki_size_t shm_segsz; /* size of segment (bytes) */ + __vki_kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __vki_kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __vki_kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __vki_kernel_pid_t shm_cpid; /* pid of creator */ + __vki_kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct vki_shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +//---------------------------------------------------------------------- +// And that's it! +//---------------------------------------------------------------------- + +#endif // __ARM_LINUX_VKI_ARCH_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/arm-linux/vki_arch_posixtypes.h b/include/arm-linux/vki_arch_posixtypes.h new file mode 100644 index 000000000..9f57856b1 --- /dev/null +++ b/include/arm-linux/vki_arch_posixtypes.h @@ -0,0 +1,69 @@ + +/*--------------------------------------------------------------------*/ +/*--- ARM/Linux-specific kernel interface: posix types. ---*/ +/*--- vki_arch_posixtypes.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Julian Seward + jseward@acm.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __ARM_LINUX_VKI_ARCH_POSIXTYPES_H +#define __ARM_LINUX_VKI_ARCH_POSIXTYPES_H + +//---------------------------------------------------------------------- +// From linux-2.6.8.1/include/asm-i386/posix_types.h +//---------------------------------------------------------------------- + +typedef unsigned short __vki_kernel_mode_t; +typedef long __vki_kernel_off_t; +typedef int __vki_kernel_pid_t; +typedef unsigned short __vki_kernel_ipc_pid_t; +typedef unsigned short __vki_kernel_uid_t; +typedef unsigned short __vki_kernel_gid_t; +typedef unsigned int __vki_kernel_size_t; +typedef long __vki_kernel_time_t; +typedef long __vki_kernel_suseconds_t; +typedef long __vki_kernel_clock_t; +typedef int __vki_kernel_timer_t; +typedef int __vki_kernel_clockid_t; +typedef char * __vki_kernel_caddr_t; +typedef unsigned int __vki_kernel_uid32_t; +typedef unsigned int __vki_kernel_gid32_t; + +typedef unsigned short __vki_kernel_old_uid_t; +typedef unsigned short __vki_kernel_old_gid_t; + +typedef long long __vki_kernel_loff_t; + +typedef struct { + int val[2]; +} __vki_kernel_fsid_t; + + +#endif // __ARM_LINUX_VKI_ARCH_POSIXTYPES_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/arm/Makefile.am b/include/arm/Makefile.am new file mode 100644 index 000000000..9abfc6b51 --- /dev/null +++ b/include/arm/Makefile.am @@ -0,0 +1,4 @@ +incincdir = $(includedir)/valgrind/arm + +incinc_HEADERS = tool_arch.h + diff --git a/include/arm/tool_arch.h b/include/arm/tool_arch.h new file mode 100644 index 000000000..91d286c4a --- /dev/null +++ b/include/arm/tool_arch.h @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------*/ +/*--- arm/tool_arch.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, an extensible x86 protected-mode + emulator for monitoring program execution on x86-Unixes. + + Copyright (C) 2000-2004 Nicholas Nethercote + njn25@cam.ac.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __ARM_TOOL_ARCH_H +#define __ARM_TOOL_ARCH_H + +/*====================================================================*/ +/*=== Registers, etc ===*/ +/*====================================================================*/ + +#define REGPARM(n) + +#define MIN_INSTR_SIZE 4 +#define MAX_INSTR_SIZE 4 + +#endif // __ARM_TOOL_ARCH_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/linux/vki.h b/include/linux/vki.h index bdc1da2e1..c1a7875d5 100644 --- a/include/linux/vki.h +++ b/include/linux/vki.h @@ -328,6 +328,14 @@ struct vki_sched_param { int sched_priority; }; +//---------------------------------------------------------------------- +// From nowhere: constants internal to Valgrind +//---------------------------------------------------------------------- + +#define VKI_SIGVGINT (VKI_SIGRTMIN+0) // [[internal: interrupt]] +#define VKI_SIGVGKILL (VKI_SIGRTMIN+1) // [[internal: kill]] +#define VKI_SIGVGRTUSERMIN (VKI_SIGRTMIN+2) // [[internal: first + //---------------------------------------------------------------------- // From linux-2.6.8.1/include/asm-generic/siginfo.h //---------------------------------------------------------------------- @@ -480,6 +488,11 @@ typedef struct vki_sigevent { #define VKI_SYS_SENDMSG 16 /* sys_sendmsg(2) */ #define VKI_SYS_RECVMSG 17 /* sys_recvmsg(2) */ +enum vki_sock_type { + VKI_SOCK_STREAM = 1, + // [[others omitted]] +}; + //---------------------------------------------------------------------- // From linux-2.6.8.1/include/linux/uio.h //---------------------------------------------------------------------- @@ -1860,6 +1873,13 @@ struct vki_kbd_repeat { typedef __vki_kernel_uid32_t vki_qid_t; /* Type in which we store ids in memory */ +//---------------------------------------------------------------------- +// From linux-2.6.9/include/linux/ptrace.h +//---------------------------------------------------------------------- + +#define VKI_PTRACE_PEEKTEXT 1 +#define VKI_PTRACE_PEEKDATA 2 +#define VKI_PTRACE_PEEKUSR 3 #endif // __LINUX_VKI_H diff --git a/include/tool.h.base b/include/tool.h.base index 3d01ef647..168135159 100644 --- a/include/tool.h.base +++ b/include/tool.h.base @@ -855,7 +855,6 @@ extern void VG_(HT_destruct) ( VgHashTable t ); should allocate them with VG_(SkipNode_Alloc), which will allocate enough memory for the extra bits. */ -#include /* for offsetof */ typedef struct _SkipList SkipList; typedef struct _SkipNode SkipNode; diff --git a/include/valgrind.h.in b/include/valgrind.h.in index 7f3c183b5..9718c0f23 100644 --- a/include/valgrind.h.in +++ b/include/valgrind.h.in @@ -120,7 +120,29 @@ : "eax", "edx", "cc", "memory" \ ); \ } -#endif // __x86__ +#endif // __x86__ +#ifdef __arm__ +// XXX: termporary, until MAGIC_SEQUENCE is written properly +extern int printf (__const char *__restrict __format, ...); +extern void exit (int __status); +#define VALGRIND_MAGIC_SEQUENCE( \ + _zzq_rlval, _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \ + \ + { volatile unsigned int _zzq_args[5]; \ + _zzq_args[0] = (volatile unsigned int)(_zzq_request); \ + _zzq_args[1] = (volatile unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (volatile unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (volatile unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (volatile unsigned int)(_zzq_arg4); \ + (_zzq_rlval) = (_zzq_default);/* temporary only */ \ + printf("argh: MAGIC_SEQUENCE"); exit(1); \ + asm volatile(""); \ + } +// XXX: make sure that the register holding the args and the register taking +// the return value match ARCH_CLREQ_ARGS and ARCH_CLREQ_RET in +// arm/core_arch.h! +#endif // __arm__ // Insert assembly code for other architectures here... diff --git a/include/x86-linux/vki_arch.h b/include/x86-linux/vki_arch.h index 95a32d5f9..f1c4488ad 100644 --- a/include/x86-linux/vki_arch.h +++ b/include/x86-linux/vki_arch.h @@ -129,11 +129,6 @@ typedef struct { // [[This was (_NSIG-1) in 2.4.X... not sure if it matters.]] #define VKI_SIGRTMAX _VKI_NSIG -#define VKI_SIGVGINT (VKI_SIGRTMIN+0) // [[internal: interrupt]] -#define VKI_SIGVGKILL (VKI_SIGRTMIN+1) // [[internal: kill]] -#define VKI_SIGVGRTUSERMIN (VKI_SIGRTMIN+2) // [[internal: first - // user-usable RT signal]] - #define VKI_SA_NOCLDSTOP 0x00000001u #define VKI_SA_NOCLDWAIT 0x00000002u #define VKI_SA_SIGINFO 0x00000004u @@ -309,8 +304,6 @@ struct vki_sigcontext { #define VKI_SO_TYPE 3 -#define VKI_SOCK_STREAM 1 /* stream (connection) socket */ - //---------------------------------------------------------------------- // From linux-2.6.8.1/include/asm-i386/sockios.h //---------------------------------------------------------------------- @@ -382,6 +375,7 @@ struct vki_stat64 { // From linux-2.6.8.1/include/asm-i386/statfs.h //---------------------------------------------------------------------- +// [[Nb: asm-i386/statfs.h just #include asm-generic/statfs.h directly]] struct vki_statfs { __vki_u32 f_type; __vki_u32 f_bsize; @@ -731,6 +725,17 @@ struct vki_shminfo64 { unsigned long __unused4; }; +//---------------------------------------------------------------------- +// From linux-2.6.9/include/asm-i386/shmbuf.h +//---------------------------------------------------------------------- + +#define VKI_PTRACE_GETREGS 12 +#define VKI_PTRACE_SETREGS 13 +#define VKI_PTRACE_GETFPREGS 14 +#define VKI_PTRACE_SETFPREGS 15 +#define VKI_PTRACE_GETFPXREGS 18 +#define VKI_PTRACE_SETFPXREGS 19 + //---------------------------------------------------------------------- // And that's it! //---------------------------------------------------------------------- diff --git a/memcheck/tests/arm/Makefile.am b/memcheck/tests/arm/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/none/tests/arm/Makefile.am b/none/tests/arm/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/tests/cputest.c b/tests/cputest.c index 3933c6ca3..ac6d7863c 100644 --- a/tests/cputest.c +++ b/tests/cputest.c @@ -16,8 +16,9 @@ typedef int Bool; char* all_archs[] = { "x86", - "ppc", + "arm", "amd64", + "ppc", NULL }; @@ -73,6 +74,16 @@ static Bool go(char* cpu) #endif // __x86__ +#ifdef __arm__ +static Bool go(char* cpu) +{ + if ( strcmp( cpu, "arm" ) == 0 ) + return True; + else + return False; +} +#endif // __arm__ + #ifdef __ppc__ static Bool go(char* cpu) {