Commit 59570ffbe31930ab4d678754daaeec0715117a3d

  • avatar
  • sewardj <sewardj @a5019735-40e9-0310…91ae7b9d1cf9.>
  • Fri Jan 01 12:59:33 CET 2010
Merge from branches/ARM, all parts of the ARM-Linux port except for
the changes to do with reading and using ELF and DWARF3 info.
This breaks all targets except amd64-linux and x86-linux.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10982 a5019735-40e9-0310-863c-91ae7b9d1cf9
  
116116# automake, but this does not really matter and seems hard to avoid.
117117
118118AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@ = \
119 -I$(top_srcdir) \
120 -I$(top_srcdir)/include \
119 -I$(top_srcdir) \
120 -I$(top_srcdir)/include \
121121 -I$(top_srcdir)/VEX/pub \
122122 -DVGA_@VGCONF_ARCH_PRI@=1 \
123123 -DVGO_@VGCONF_OS@=1 \
124124 -DVGP_@VGCONF_ARCH_PRI@_@VGCONF_OS@=1
125125if VGCONF_HAVE_PLATFORM_SEC
126126AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@ = \
127 -I$(top_srcdir) \
128 -I$(top_srcdir)/include \
127 -I$(top_srcdir) \
128 -I$(top_srcdir)/include \
129129 -I$(top_srcdir)/VEX/pub \
130130 -DVGA_@VGCONF_ARCH_SEC@=1 \
131131 -DVGO_@VGCONF_OS@=1 \
150150AM_CFLAGS_PPC64_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE)
151151AM_CCASFLAGS_PPC64_LINUX = $(AM_CPPFLAGS_PPC64_LINUX) @FLAG_M64@ -g
152152
153AM_FLAG_M3264_ARM_LINUX = @FLAG_M32@
154AM_CFLAGS_ARM_LINUX = @FLAG_M32@ @PREFERRED_STACK_BOUNDARY@ \
155 $(AM_CFLAGS_BASE)
156AM_CCASFLAGS_ARM_LINUX = $(AM_CPPFLAGS_ARM_LINUX) @FLAG_M32@ -g
157
153158AM_FLAG_M3264_PPC32_AIX5 = @FLAG_MAIX32@
154159AM_CFLAGS_PPC32_AIX5 = @FLAG_MAIX32@ -mcpu=powerpc $(AM_CFLAGS_BASE)
155160AM_CCASFLAGS_PPC32_AIX5 = $(AM_CPPFLAGS_PPC32_AIX5) \
202202PRELOAD_LDFLAGS_AMD64_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
203203PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@
204204PRELOAD_LDFLAGS_PPC64_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
205PRELOAD_LDFLAGS_ARM_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@
205206PRELOAD_LDFLAGS_PPC32_AIX5 = $(PRELOAD_LDFLAGS_COMMON_AIX5) @FLAG_MAIX32@
206207PRELOAD_LDFLAGS_PPC64_AIX5 = $(PRELOAD_LDFLAGS_COMMON_AIX5) @FLAG_MAIX64@
207208PRELOAD_LDFLAGS_X86_DARWIN = $(PRELOAD_LDFLAGS_COMMON_DARWIN) -arch i386
  
4949 $(TOOL_LDFLAGS_COMMON_LINUX) @FLAG_M64@ \
5050 -Wl,-T,$(top_builddir)/valt_load_address_ppc64_linux.lds
5151
52TOOL_LDFLAGS_ARM_LINUX = \
53 $(TOOL_LDFLAGS_COMMON_LINUX) @FLAG_M32@ \
54 -Wl,-T,$(top_builddir)/valt_load_address_arm_linux.lds
55
5256TOOL_LDFLAGS_PPC32_AIX5 = \
5357 $(TOOL_LDFLAGS_COMMON_AIX5) @FLAG_MAIX32@
5458
9292BUILT_SOURCES += $(top_builddir)/valt_load_address_ppc64_linux.lds
9393CLEANFILES += $(top_builddir)/valt_load_address_ppc64_linux.lds
9494endif
95if VGCONF_PLATFORMS_INCLUDE_ARM_LINUX
96BUILT_SOURCES += $(top_builddir)/valt_load_address_arm_linux.lds
97CLEANFILES += $(top_builddir)/valt_load_address_arm_linux.lds
98endif
9599if VGCONF_PLATFORMS_INCLUDE_PPC32_AIX5
96100# No need to generate $(top_builddir)/valt_load_address*.lds; the final
97101# executables can be linked to be at any address. They will be relocated by
157157 -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \
158158 || rm -f $@
159159
160$(top_builddir)/valt_load_address_arm_linux.lds: Makefile
161 $(CC) @FLAG_M32@ -Wl,--verbose -nostdlib 2>&1 | sed \
162 -e '1,/^=====\+$$/d' \
163 -e '/^=====\+$$/,/.\*/d' \
164 -e '/\. = \(0x[0-9A-Fa-f]\+\|SEGMENT_START("[^"]\+", 0x[0-9A-Fa-f]\+)\) + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \
165 || rm -f $@
166
160167#----------------------------------------------------------------------------
161168# vgpreload_<tool>-<platform>.a stuff
162169#----------------------------------------------------------------------------
180180LIBREPLACEMALLOC_PPC64_LINUX = \
181181 $(top_builddir)/coregrind/libreplacemalloc_toolpreload-ppc64-linux.a
182182
183LIBREPLACEMALLOC_ARM_LINUX = \
184 $(top_builddir)/coregrind/libreplacemalloc_toolpreload-arm-linux.a
185
183186LIBREPLACEMALLOC_PPC32_AIX5 = \
184187 $(top_builddir)/coregrind/libreplacemalloc_toolpreload-ppc32-aix5.a
185188
214214LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX = \
215215 -Wl,--whole-archive \
216216 $(LIBREPLACEMALLOC_PPC64_LINUX) \
217 -Wl,--no-whole-archive
218
219LIBREPLACEMALLOC_LDFLAGS_ARM_LINUX = \
220 -Wl,--whole-archive \
221 $(LIBREPLACEMALLOC_ARM_LINUX) \
217222 -Wl,--no-whole-archive
218223
219224LIBREPLACEMALLOC_LDFLAGS_PPC32_AIX5 = \
  
5656 $(CC) $(LIBVEX_CFLAGS) -O -S -o auxprogs/genoffsets.s \
5757 auxprogs/genoffsets.c
5858 grep xyzzy auxprogs/genoffsets.s | grep define \
59 | sed "s/xyzzy\\$$//g" | sed "s/xyzzy//g" \
59 | sed "s/xyzzy\\$$//g" \
60 | sed "s/xyzzy#//g" \
61 | sed "s/xyzzy//g" \
6062 > pub/libvex_guest_offsets.h
6163 rm -f auxprogs/genoffsets.s
6264
  
1#!/bin/sh
1#!/bin/bash
22
33# Do an automated test which involves building and regtesting version
44# 1.6 of the GNU Scientific Library (gsl). This has proven to be a
  
4040 cg_main.c \
4141 cg-x86-amd64.c \
4242 cg-ppc32.c \
43 cg-ppc64.c
43 cg-ppc64.c \
44 cg-arm.c
4445
4546cachegrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_SOURCES = \
4647 $(CACHEGRIND_SOURCES_COMMON)
  
1
2/*--------------------------------------------------------------------*/
3/*--- ARM-specific definitions. cg-arm.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Cachegrind, a Valgrind tool for cache
8 profiling programs.
9
10 Copyright (C) 2005-2009 Johan Bjork
11 jbjoerk@gmail.com
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#if defined(VGA_arm)
32
33#include "pub_tool_basics.h"
34#include "pub_tool_libcbase.h"
35#include "pub_tool_libcassert.h"
36#include "pub_tool_libcprint.h"
37
38#include "cg_arch.h"
39
40void VG_(configure_caches)(cache_t* I1c, cache_t* D1c, cache_t* L2c,
41 Bool all_caches_clo_defined)
42{
43 // Set caches to default (for Cortex-A8 ?)
44 *I1c = (cache_t) { 16384, 4, 64 };
45 *D1c = (cache_t) { 16384, 4, 64 };
46 *L2c = (cache_t) { 262144, 8, 64 };
47
48 if (!all_caches_clo_defined) {
49 VG_(message)(Vg_DebugMsg,
50 "Warning: Cannot auto-detect cache config on ARM, using one "
51 "or more defaults ");
52 }
53}
54
55#endif // #if defined(VGA_arm)
56
57/*--------------------------------------------------------------------*/
58/*--- end cg-arm.c ---*/
59/*--------------------------------------------------------------------*/
  
4444
4545/* How many bits at the bottom of an instruction address are
4646 guaranteed to be zero? */
47#if defined(VGA_ppc32) || defined(VGA_ppc64)
47#if defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_arm)
4848# define N_IADDR_LO_ZERO_BITS 2
4949#elif defined(VGA_x86) || defined(VGA_amd64)
5050# define N_IADDR_LO_ZERO_BITS 0
configure.in
(20 / 1)
  
151151 esac
152152 ;;
153153
154 armv7*)
155 AC_MSG_RESULT([ok (${host_cpu})])
156 ARCH_MAX="arm"
157 ;;
158
154159 *)
155160 AC_MSG_RESULT([no (${host_cpu})])
156161 AC_MSG_ERROR([Unsupported host architecture. Sorry])
464464 valt_load_address_inner="0x0"
465465 AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
466466 ;;
467 arm-linux)
468 VGCONF_ARCH_PRI="arm"
469 VGCONF_PLATFORM_PRI_CAPS="ARM_LINUX"
470 VGCONF_PLATFORM_SEC_CAPS=""
471 valt_load_address_normal="0x38000000"
472 valt_load_address_inner="0x28000000"
473 AC_MSG_RESULT([ok (${host_cpu}-${host_os})])
474 ;;
467475 *)
468476 VGCONF_ARCH_PRI="unknown"
469477 VGCONF_ARCH_SEC="unknown"
502502AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC64,
503503 test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX \
504504 -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_AIX5 )
505AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_ARM,
506 test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX )
505507
506508# Set up VGCONF_PLATFORMS_INCLUDE_<platform>. Either one or two of these
507509# become defined.
517517 -o x$VGCONF_PLATFORM_SEC_CAPS = xPPC32_LINUX)
518518AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX,
519519 test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX)
520AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM_LINUX,
521 test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX)
520522
521523AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC32_AIX5,
522524 test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_AIX5 \
540540 test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \
541541 -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX \
542542 -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \
543 -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX)
543 -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX \
544 -o x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX )
544545AM_CONDITIONAL(VGCONF_OS_IS_AIX5,
545546 test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_AIX5 \
546547 -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_AIX5)
19451945 none/tests/ppc32/Makefile
19461946 none/tests/ppc64/Makefile
19471947 none/tests/x86/Makefile
1948 none/tests/arm/Makefile
19481949 none/tests/linux/Makefile
19491950 none/tests/darwin/Makefile
19501951 none/tests/x86-linux/Makefile
  
1010#----------------------------------------------------------------------------
1111
1212AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@ += \
13 -I$(top_srcdir)/coregrind \
13 -I$(top_srcdir)/coregrind \
1414 -DVG_LIBDIR="\"$(pkglibdir)"\" \
1515 -DVG_PLATFORM="\"@VGCONF_ARCH_PRI@-@VGCONF_OS@\""
1616if VGCONF_HAVE_PLATFORM_SEC
1717AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@ += \
18 -I$(top_srcdir)/coregrind \
18 -I$(top_srcdir)/coregrind \
1919 -DVG_LIBDIR="\"$(pkglibdir)"\" \
2020 -DVG_PLATFORM="\"@VGCONF_ARCH_SEC@-@VGCONF_OS@\""
2121endif
281281 m_dispatch/dispatch-amd64-linux.S \
282282 m_dispatch/dispatch-ppc32-linux.S \
283283 m_dispatch/dispatch-ppc64-linux.S \
284 m_dispatch/dispatch-arm-linux.S \
284285 m_dispatch/dispatch-ppc32-aix5.S \
285286 m_dispatch/dispatch-ppc64-aix5.S \
286287 m_dispatch/dispatch-x86-darwin.S \
301301 m_sigframe/sigframe-amd64-linux.c \
302302 m_sigframe/sigframe-ppc32-linux.c \
303303 m_sigframe/sigframe-ppc64-linux.c \
304 m_sigframe/sigframe-arm-linux.c \
304305 m_sigframe/sigframe-ppc32-aix5.c \
305306 m_sigframe/sigframe-ppc64-aix5.c \
306307 m_sigframe/sigframe-x86-darwin.c \
312312 m_syswrap/syscall-amd64-linux.S \
313313 m_syswrap/syscall-ppc32-linux.S \
314314 m_syswrap/syscall-ppc64-linux.S \
315 m_syswrap/syscall-arm-linux.S \
315316 m_syswrap/syscall-ppc32-aix5.S \
316317 m_syswrap/syscall-ppc64-aix5.S \
317318 m_syswrap/syscall-x86-darwin.S \
327327 m_syswrap/syswrap-amd64-linux.c \
328328 m_syswrap/syswrap-ppc32-linux.c \
329329 m_syswrap/syswrap-ppc64-linux.c \
330 m_syswrap/syswrap-arm-linux.c \
330331 m_syswrap/syswrap-ppc32-aix5.c \
331332 m_syswrap/syswrap-ppc64-aix5.c \
332333 m_syswrap/syswrap-x86-darwin.c \
  
172172 ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
173173 platform = "x86-linux";
174174 }
175 else
176 if (ehdr->e_machine == EM_ARM &&
177 (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
178 ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
179 platform = "arm-linux";
180 }
175181 }
176182 else if (header[EI_DATA] == ELFDATA2MSB) {
177183 if (ehdr->e_machine == EM_PPC &&
186186 platform = "ppc32-linux";
187187 }
188188 }
189
189190 } else if (n_bytes >= sizeof(Elf64_Ehdr) && header[EI_CLASS] == ELFCLASS64) {
190191 const Elf64_Ehdr *ehdr = (Elf64_Ehdr *)header;
191192
273273 if ((0==strcmp(VG_PLATFORM,"x86-linux")) ||
274274 (0==strcmp(VG_PLATFORM,"amd64-linux")) ||
275275 (0==strcmp(VG_PLATFORM,"ppc32-linux")) ||
276 (0==strcmp(VG_PLATFORM,"ppc64-linux")))
276 (0==strcmp(VG_PLATFORM,"ppc64-linux")) ||
277 (0==strcmp(VG_PLATFORM,"arm-linux")))
277278 default_platform = VG_PLATFORM;
278279 else
279280 barf("Unknown VG_PLATFORM '%s'", VG_PLATFORM);
  
152152{
153153 SysRes res;
154154 aspacem_assert(VG_IS_PAGE_ALIGNED(offset));
155# if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
155# if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
156 || defined(VGP_arm_linux)
156157 /* mmap2 uses 4096 chunks even if actual page size is bigger. */
157158 aspacem_assert((offset % 4096) == 0);
158159 res = VG_(do_syscall6)(__NR_mmap2, (UWord)start, length,
  
16831683 VG_(debugLog)(2, "aspacem", "Reading /proc/self/maps\n");
16841684 parse_procselfmaps( read_maps_callback, NULL );
16851685
1686#if defined(VGP_arm_linux)
1687 /* ARM puts code at the end of memory that contains processor
1688 specific stuff (cmpxchg, getting the thread local storage, etc.)
1689 This isn't specified in /proc/self/maps, so do it here
1690
1691 EAZG: Is this the proper place for this? Seems like this is one
1692 of the few contexts when we can punch holes in the map
1693 */
1694 init_nsegment( &seg );
1695 seg.kind = SkFileC;
1696 seg.start = 0xFFFF0000;
1697 seg.end = 0xFFFFEFFF;
1698 seg.hasR = toBool(1);
1699 seg.hasW = toBool(0);
1700 seg.hasX = toBool(1);
1701 seg.fnIdx = allocate_segname( "arm_commpage" );
1702 add_segment( &seg );
1703#endif
1704
16861705 VG_(am_show_nsegments)(2, "With contents of /proc/self/maps");
16871706
16881707 AM_SANITY_CHECK;
  
324324 regs->dsisr = 0;
325325 regs->result = 0;
326326
327#elif defined(VGP_arm_linux)
328 regs->ARM_r0 = arch->vex.guest_R0;
329 regs->ARM_r1 = arch->vex.guest_R1;
330 regs->ARM_r2 = arch->vex.guest_R2;
331 regs->ARM_r3 = arch->vex.guest_R3;
332 regs->ARM_r4 = arch->vex.guest_R4;
333 regs->ARM_r5 = arch->vex.guest_R5;
334 regs->ARM_r6 = arch->vex.guest_R6;
335 regs->ARM_r7 = arch->vex.guest_R7;
336 regs->ARM_r8 = arch->vex.guest_R8;
337 regs->ARM_r9 = arch->vex.guest_R9;
338 regs->ARM_r10 = arch->vex.guest_R10;
339 regs->ARM_fp = arch->vex.guest_R11;
340 regs->ARM_ip = arch->vex.guest_R12;
341 regs->ARM_sp = arch->vex.guest_R13;
342 regs->ARM_lr = arch->vex.guest_R14;
343 regs->ARM_pc = arch->vex.guest_R15;
344 regs->ARM_cpsr = LibVEX_GuestARM_get_cpsr( &((ThreadArchState*)arch)->vex );
345
327346#else
328347# error Unknown ELF platform
329348#endif
411411 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
412412 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
413413# undef DO
414
415#elif defined(VGP_arm_linux)
416 // umm ...
414417
415418#else
416419# error Unknown ELF platform
  
3333/*
3434 Bool VG_(has_cpuid)(void)
3535 */
36.globl VG_(has_cpuid)
3736#if defined(VGA_x86)
37.text
38.globl VG_(has_cpuid)
3839 VG_(has_cpuid):
3940 pushl %ebp
4041 movl %esp, %ebp
5858 popl %ebp
5959 ret
6060#elif defined(VGA_amd64)
61.text
62.globl VG_(has_cpuid)
6163 VG_(has_cpuid):
6264 movq $1, %rax
6365 ret
6969 void VG_(cpuid)(UInt eax,
7070 UInt* eax_ret, UInt* ebx_ret, UInt* ecx_ret, UInt* edx_ret)
7171 */
72.globl VG_(cpuid)
7372#if defined(VGA_x86)
73.text
74.globl VG_(cpuid)
7475 VG_(cpuid):
7576 pushl %ebp
7677 movl %esp, %ebp
111111 popl %ebp
112112 ret
113113#elif defined(VGA_amd64)
114.text
115.globl VG_(cpuid)
114116 VG_(cpuid):
115117 pushq %rbp
116118 movq %rsp, %rbp
149149 ret
150150#endif
151151
152#if defined(VGO_linux)
152#if defined(VGA_x86) || defined(VGA_amd64)
153153/* Let the linker know we don't need an executable stack */
154154.section .note.GNU-stack,"",@progbits
155155#endif
  
205205 (void*)(long)LibVEX_GuestPPC64_get_XER(vex));
206206 return rc;
207207
208#elif defined(VGP_arm_linux)
209 struct vki_user_regs_struct uregs;
210 VG_(memset)(&uregs, 0, sizeof(uregs));
211 uregs.ARM_r0 = vex->guest_R0;
212 uregs.ARM_r1 = vex->guest_R1;
213 uregs.ARM_r2 = vex->guest_R2;
214 uregs.ARM_r3 = vex->guest_R3;
215 uregs.ARM_r4 = vex->guest_R4;
216 uregs.ARM_r5 = vex->guest_R5;
217 uregs.ARM_r6 = vex->guest_R6;
218 uregs.ARM_r7 = vex->guest_R7;
219 uregs.ARM_r8 = vex->guest_R8;
220 uregs.ARM_r9 = vex->guest_R9;
221 uregs.ARM_r10 = vex->guest_R10;
222 uregs.ARM_fp = vex->guest_R11;
223 uregs.ARM_ip = vex->guest_R12;
224 uregs.ARM_sp = vex->guest_R13;
225 uregs.ARM_lr = vex->guest_R14;
226 uregs.ARM_pc = vex->guest_R15;
227 uregs.ARM_cpsr = LibVEX_GuestARM_get_cpsr(vex);
228 return VG_(ptrace)(VKI_PTRACE_SETREGS, pid, NULL, &uregs);
229
208230#elif defined(VGP_ppc32_aix5)
209231 I_die_here;
210232
  
389389 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
390390# elif defined(VGP_ppc64_linux)
391391 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
392# elif defined(VGP_arm_linux)
393 if (regno == 13) { *a = regs->sp; return True; }
394 if (regno == 11) { *a = regs->fp; return True; }
392395# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
393396 vg_assert(0); /* this function should never be called */
394397# else
  
232232 return (UInt)__res;
233233}
234234
235#elif defined(VGP_arm_linux)
236
237static UInt local_sys_write_stderr ( HChar* buf, Int n )
238{
239 volatile Int block[2];
240 block[0] = (Int)buf;
241 block[1] = n;
242 __asm__ volatile (
243 "mov r0, #1\n\t"
244 "ldr r1, [%0]\n\t"
245 "ldr r2, [%0, #4]\n\t"
246 "mov r7, #"VG_STRINGIFY(__NR_write)"\n\t"
247 "svc 0x0\n" /* write() */
248 "str r0, [%0]\n\t"
249 :
250 : "r" (block)
251 : "r0","r1","r2","r7"
252 );
253 if (block[0] < 0)
254 block[0] = -1;
255 return (UInt)block[0];
256}
257
258static UInt local_sys_getpid ( void )
259{
260 UInt __res;
261 __asm__ volatile (
262 "mov r7, #"VG_STRINGIFY(__NR_getpid)"\n"
263 "svc 0x0\n" /* getpid() */
264 "mov %0, r0\n"
265 : "=r" (__res)
266 :
267 : "r0", "r7" );
268 return __res;
269}
270
235271#elif defined(VGP_ppc32_aix5)
236272
237273static UInt local_sys_write_stderr ( HChar* buf, Int n )
  
1
2/*--------------------------------------------------------------------*/
3/*--- The core dispatch loop, for jumping to a code address. ---*/
4/*--- dispatch-arm-linux.S ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2008-2009 Evan Geller
12 gaze@bea.ms
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32#if defined(VGP_arm_linux)
33
34#include "pub_core_basics_asm.h"
35#include "pub_core_dispatch_asm.h"
36#include "pub_core_transtab_asm.h"
37#include "libvex_guest_offsets.h" /* for OFFSET_arm_R* */
38
39
40/*------------------------------------------------------------*/
41/*--- ---*/
42/*--- The dispatch loop. VG_(run_innerloop) is used to ---*/
43/*--- run all translations except no-redir ones. ---*/
44/*--- ---*/
45/*------------------------------------------------------------*/
46
47/*----------------------------------------------------*/
48/*--- Preamble (set everything up) ---*/
49/*----------------------------------------------------*/
50
51/* signature:
52UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
53*/
54.text
55.globl VG_(run_innerloop)
56VG_(run_innerloop):
57 push {r0, r1, r4, r5, r6, r7, r8, r9, fp, lr}
58
59 /* set FPSCR to vex-required default value */
60 mov r4, #0
61 fmxr fpscr, r4
62
63 /* r0 (hence also [sp,#0]) holds guest_state */
64 /* r1 holds do_profiling */
65 mov r8, r0
66 ldr r0, [r8, #OFFSET_arm_R15]
67
68 /* fall into main loop (the right one) */
69 cmp r1, #0 /* do_profiling */
70 beq VG_(run_innerloop__dispatch_unprofiled)
71 b VG_(run_innerloop__dispatch_profiled)
72
73
74/*----------------------------------------------------*/
75/*--- NO-PROFILING (standard) dispatcher ---*/
76/*----------------------------------------------------*/
77
78.global VG_(run_innerloop__dispatch_unprofiled)
79VG_(run_innerloop__dispatch_unprofiled):
80
81 /* AT ENTRY: r0 is next guest addr, r8 is possibly
82 modified guest state ptr */
83
84 /* Has the guest state pointer been messed with? If yes, exit. */
85 ldr r1, [sp, #0]
86 cmp r8, r1
87 bne gsp_changed
88
89 /* save the jump address in the guest state */
90 str r0, [r8, #OFFSET_arm_R15]
91
92 /* Are we out of timeslice? If yes, defer to scheduler. */
93 ldr r1, =VG_(dispatch_ctr)
94 ldr r2, [r1]
95 subs r2, r2, #1
96 str r2, [r1]
97 beq counter_is_zero
98
99 /* try a fast lookup in the translation cache */
100 // r0 = next guest, r1,r2,r3 scratch
101 ldr r1, =VG_TT_FAST_MASK // r1 = VG_TT_FAST_MASK
102 and r2, r1, r0, LSR #2 // r2 = entry #
103 ldr r1, =VG_(tt_fast) // r1 = &tt_fast[0]
104 add r1, r1, r2, LSL #3 // r1 = &tt_fast[entry#]
105 ldr r3, [r1, #0] /* .guest */
106 ldr r1, [r1, #4] /* .host */
107 cmp r0, r3
108 bne fast_lookup_failed
109 // r1: live, next-host r8: live, gsp
110 // r2: entry # (but not live)
111 // r0, r3: dead
112
113 /* Found a match. Jump to .host. */
114 blx r1
115 b VG_(run_innerloop__dispatch_unprofiled)
116.ltorg
117 /*NOTREACHED*/
118
119/*----------------------------------------------------*/
120/*--- PROFILING dispatcher (can be much slower) ---*/
121/*----------------------------------------------------*/
122
123.global VG_(run_innerloop__dispatch_profiled)
124VG_(run_innerloop__dispatch_profiled):
125
126 /* AT ENTRY: r0 is next guest addr, r8 is possibly
127 modified guest state ptr */
128
129 /* Has the guest state pointer been messed with? If yes, exit. */
130 ldr r1, [sp, #0]
131 cmp r8, r1
132 bne gsp_changed
133
134 /* save the jump address in the guest state */
135 str r0, [r8, #OFFSET_arm_R15]
136
137 /* Are we out of timeslice? If yes, defer to scheduler. */
138 ldr r1, =VG_(dispatch_ctr)
139 ldr r2, [r1]
140 subs r2, r2, #1
141 str r2, [r1]
142 beq counter_is_zero
143
144 /* try a fast lookup in the translation cache */
145 // r0 = next guest, r1,r2,r3 scratch
146 ldr r1, =VG_TT_FAST_MASK // r1 = VG_TT_FAST_MASK
147 and r2, r1, r0, LSR #2 // r2 = entry #
148 ldr r1, =VG_(tt_fast) // r1 = &tt_fast[0]
149 add r1, r1, r2, LSL #3 // r1 = &tt_fast[entry#]
150 ldr r3, [r1, #0] /* .guest */
151 ldr r1, [r1, #4] /* .host */
152 cmp r0, r3
153 bne fast_lookup_failed
154 // r1: live, next-host r8: live, gsp
155 // r2: entry # (but not live)
156 // r0, r3: dead
157
158 /* increment bb profile counter */
159 ldr r0, =VG_(tt_fastN) // r0 = &tt_fastN[0]
160 ldr r0, [r0, r2, LSL #2] // r0 = tt_fast[entry #]
161 ldr r3, [r0] // *r0 ++
162 add r3, r3, #1
163 str r3, [r0]
164
165 /* Found a match. Jump to .host. */
166 blx r1
167 b VG_(run_innerloop__dispatch_profiled)
168 /*NOTREACHED*/
169
170/*----------------------------------------------------*/
171/*--- exit points ---*/
172/*----------------------------------------------------*/
173
174gsp_changed:
175 // r0 = next guest addr (R15), r8 = modified gsp
176 /* Someone messed with the gsp. Have to
177 defer to scheduler to resolve this. dispatch ctr
178 is not yet decremented, so no need to increment. */
179 /* R15 is NOT up to date here. First, need to write
180 r0 back to R15, but without trashing r8 since
181 that holds the value we want to return to the scheduler.
182 Hence use r1 transiently for the guest state pointer. */
183 ldr r1, [sp, #0]
184 str r0, [r1, #OFFSET_arm_R15]
185 mov r0, r8 // "return modified gsp"
186 b run_innerloop_exit
187 /*NOTREACHED*/
188
189counter_is_zero:
190 /* R15 is up to date here */
191 /* Back out increment of the dispatch ctr */
192 ldr r1, =VG_(dispatch_ctr)
193 ldr r2, [r1]
194 add r2, r2, #1
195 str r2, [r1]
196 mov r0, #VG_TRC_INNER_COUNTERZERO
197 b run_innerloop_exit
198 /*NOTREACHED*/
199
200fast_lookup_failed:
201 /* R15 is up to date here */
202 /* Back out increment of the dispatch ctr */
203 ldr r1, =VG_(dispatch_ctr)
204 ldr r2, [r1]
205 add r2, r2, #1
206 str r2, [r1]
207 mov r0, #VG_TRC_INNER_FASTMISS
208 b run_innerloop_exit
209 /*NOTREACHED*/
210
211/* All exits from the dispatcher go through here. %r0 holds
212 the return value.
213*/
214run_innerloop_exit:
215 /* We're leaving. Check that nobody messed with
216 FPSCR in ways we don't expect. */
217 fmrx r4, fpscr
218 bic r4, #0xF0000000 /* mask out NZCV */
219 bic r4, #0x0000001F /* mask out IXC,UFC,OFC,DZC,IOC */
220 cmp r4, #0
221 bne invariant_violation
222 b run_innerloop_exit_REALLY
223
224invariant_violation:
225 mov r0, #VG_TRC_INVARIANT_FAILED
226 b run_innerloop_exit_REALLY
227
228run_innerloop_exit_REALLY:
229 add sp, sp, #8
230 pop {r4, r5, r6, r7, r8, r9, fp, pc}
231
232.size VG_(run_innerloop), .-VG_(run_innerloop)
233
234
235/*------------------------------------------------------------*/
236/*--- ---*/
237/*--- A special dispatcher, for running no-redir ---*/
238/*--- translations. Just runs the given translation once. ---*/
239/*--- ---*/
240/*------------------------------------------------------------*/
241
242/* signature:
243void VG_(run_a_noredir_translation) ( UWord* argblock );
244*/
245
246/* Run a no-redir translation. argblock points to 4 UWords, 2 to carry args
247 and 2 to carry results:
248 0: input: ptr to translation
249 1: input: ptr to guest state
250 2: output: next guest PC
251 3: output: guest state pointer afterwards (== thread return code)
252*/
253.global VG_(run_a_noredir_translation)
254VG_(run_a_noredir_translation):
255 push {r0,r1 /* EABI compliance */, r4-r12, lr}
256 ldr r8, [r0, #4]
257 mov lr, pc
258 ldr pc, [r0, #0]
259
260 pop {r1}
261 str r0, [r1, #8]
262 str r8, [r1, #12]
263 pop {r1/*EABI compliance*/,r4-r12, pc}
264
265.size VG_(run_a_noredir_translation), .-VG_(run_a_noredir_translation)
266
267/* Let the linker know we don't need an executable stack */
268.section .note.GNU-stack,"",%progbits
269
270#endif // defined(VGP_arm_linux)
271
272/*--------------------------------------------------------------------*/
273/*--- end dispatch-arm-linux.S ---*/
274/*--------------------------------------------------------------------*/
  
10041004 arch->vex.guest_GPR2 = iifii.initial_client_TOC;
10051005 arch->vex.guest_CIA = iifii.initial_client_IP;
10061006
1007# elif defined(VGP_arm_linux)
1008 /* Zero out the initial state, and set up the simulated FPU in a
1009 sane way. */
1010 LibVEX_GuestARM_initialise(&arch->vex);
1011
1012 /* Zero out the shadow areas. */
1013 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARMState));
1014 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARMState));
1015
1016 arch->vex.guest_R13 = iifii.initial_client_SP;
1017 arch->vex.guest_R15 = iifii.initial_client_IP;
1018
1019 /* This is just EABI stuff. */
1020 // FIXME jrs: what's this for?
1021 arch->vex.guest_R1 = iifii.initial_client_SP;
1022
10071023# else
10081024# error Unknown platform
10091025# endif
  
4545 Assertery.
4646 ------------------------------------------------------------------ */
4747
48#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
49# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \
50 asm("call 0f;" \
51 "0: popl %0;" \
52 "movl %%esp, %1;" \
53 "movl %%ebp, %2;" \
54 : "=r" (pc),\
55 "=r" (sp),\
56 "=r" (fp));
57#elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
58# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \
59 asm("leaq 0(%%rip), %0;" \
60 "movq %%rsp, %1;" \
61 "movq %%rbp, %2;" \
62 : "=r" (pc),\
63 "=r" (sp),\
64 "=r" (fp));
48#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
49# define GET_STARTREGS(srP) \
50 { UInt eip, esp, ebp; \
51 __asm__ __volatile__( \
52 "call 0f;" \
53 "0: popl %0;" \
54 "movl %%esp, %1;" \
55 "movl %%ebp, %2;" \
56 : "=r" (eip), "=r" (esp), "=r" (ebp) \
57 : /* reads none */ \
58 : "memory" \
59 ); \
60 (srP)->r_pc = (ULong)eip; \
61 (srP)->r_sp = (ULong)esp; \
62 (srP)->misc.X86.r_ebp = ebp; \
63 }
64#elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
65# define GET_STARTREGS(srP) \
66 { ULong rip, rsp, rbp; \
67 __asm__ __volatile__( \
68 "leaq 0(%%rip), %0;" \
69 "movq %%rsp, %1;" \
70 "movq %%rbp, %2;" \
71 : "=r" (rip), "=r" (rsp), "=r" (rbp) \
72 : /* reads none */ \
73 : "memory" \
74 ); \
75 (srP)->r_pc = rip; \
76 (srP)->r_sp = rsp; \
77 (srP)->misc.AMD64.r_rbp = rbp; \
78 }
6579#elif defined(VGP_ppc32_linux) || defined(VGP_ppc32_aix5)
66# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \
67 asm("mflr 0;" /* r0 = lr */ \
68 "bl m_libcassert_get_ip;" /* lr = pc */ \
69 "m_libcassert_get_ip:\n" \
70 "mflr %0;" \
71 "mtlr 0;" /* restore lr */ \
72 "mr %1,1;" \
73 "mr %2,1;" \
74 : "=r" (pc), \
75 "=r" (sp), \
76 "=r" (fp) \
77 : /* reads none */ \
78 : "r0" /* trashed */ );
80# define GET_STARTREGS(srP) \
81 { UInt cia, r1, lr; \
82 __asm__ __volatile__( \
83 "mflr 0;" /* r0 = lr */ \
84 "bl m_libcassert_get_ip;" /* lr = pc */ \
85 "m_libcassert_get_ip:\n" \
86 "mflr %0;" /* %0 = pc */ \
87 "mtlr 0;" /* restore lr */ \
88 "mr %1,1;" /* %1 = r1 */ \
89 "mr %2,0;" /* %2 = lr */ \
90 : "=r" (cia), "=r" (r1), "=r" (lr) \
91 : /* reads none */ \
92 : "r0" /* trashed */ \
93 ); \
94 srP->r_pc = (ULong)cia; \
95 srP->r_sp = (ULong)r1; \
96 srP->misc.PPC32.lr = lr; \
97 }
7998#elif defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
80# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \
81 asm("mflr 0;" /* r0 = lr */ \
82 "bl .m_libcassert_get_ip;" /* lr = pc */ \
83 ".m_libcassert_get_ip:\n" \
84 "mflr %0;" \
85 "mtlr 0;" /* restore lr */ \
86 "mr %1,1;" \
87 "mr %2,1;" \
88 : "=r" (pc), \
89 "=r" (sp), \
90 "=r" (fp) \
91 : /* reads none */ \
92 : "r0" /* trashed */ );
99# define GET_STARTREGS(srP) \
100 { ULong cia, r1, lr; \
101 __asm__ __volatile__( \
102 "mflr 0;" /* r0 = lr */ \
103 "bl .m_libcassert_get_ip;" /* lr = pc */ \
104 ".m_libcassert_get_ip:\n" \
105 "mflr %0;" /* %0 = pc */ \
106 "mtlr 0;" /* restore lr */ \
107 "mr %1,1;" /* %1 = r1 */ \
108 "mr %2,0;" /* %2 = lr */ \
109 : "=r" (cia), "=r" (r1), "=r" (lr) \
110 : /* reads none */ \
111 : "r0" /* trashed */ \
112 ); \
113 srP->r_pc = cia; \
114 srP->r_sp = r1; \
115 srP->misc.PPC64.lr = lr; \
116 }
117#elif defined(VGP_arm_linux)
118# define GET_STARTREGS(srP) \
119 { UInt block[5]; \
120 __asm__ __volatile__( \
121 "str r15, [%0, #+0];" \
122 "str r14, [%0, #+4];" \
123 "str r13, [%0, #+8];" \
124 "str r12, [%0, #+12];" \
125 "str r11, [%0, #+16];" \
126 : /* out */ \
127 : /* in */ "r"(&block[0]) \
128 : /* trash */ "memory" \
129 ); \
130 (srP)->r_pc = block[0] - 8; \
131 (srP)->r_sp = block[1]; \
132 (srP)->misc.ARM.r14 = block[2]; \
133 (srP)->misc.ARM.r12 = block[3]; \
134 (srP)->misc.ARM.r11 = block[4]; \
135 }
93136#else
94137# error Unknown platform
95138#endif
172172}
173173
174174__attribute__ ((noreturn))
175static void report_and_quit ( const Char* report,
176 Addr ip, Addr sp, Addr fp, Addr lr )
175static void report_and_quit ( const Char* report,
176 UnwindStartRegs* startRegsIN )
177177{
178178 Addr stacktop;
179179 Addr ips[BACKTRACE_DEPTH];
184184 // If necessary, fake up an ExeContext which is of our actual real CPU
185185 // state. Could cause problems if we got the panic/exception within the
186186 // execontext/stack dump/symtab code. But it's better than nothing.
187 if (0 == ip && 0 == sp && 0 == fp) {
188 GET_REAL_PC_SP_AND_FP(ip, sp, fp);
187 UnwindStartRegs startRegs;
188 VG_(memset)(&startRegs, 0, sizeof(startRegs));
189
190 if (startRegsIN == NULL) {
191 GET_STARTREGS(&startRegs);
192 } else {
193 startRegs = *startRegsIN;
189194 }
190195
191196 stacktop = tst->os_state.valgrind_stack_init_SP;
201201 ips, BACKTRACE_DEPTH,
202202 NULL/*array to dump SP values in*/,
203203 NULL/*array to dump FP values in*/,
204 ip, sp, fp, lr, sp, stacktop
204 &startRegs, stacktop
205205 );
206206 VG_(clo_xml) = False;
207207 VG_(pp_StackTrace) (ips, n_ips);
262262 if (!VG_STREQ(buf, ""))
263263 VG_(printf)("%s: %s\n", component, buf );
264264
265 report_and_quit(bugs_to, 0,0,0,0);
265 report_and_quit(bugs_to, NULL);
266266}
267267
268268__attribute__ ((noreturn))
269269static void panic ( Char* name, Char* report, Char* str,
270 Addr ip, Addr sp, Addr fp, Addr lr )
270 UnwindStartRegs* startRegs )
271271{
272272 if (VG_(clo_xml))
273273 VG_(printf_xml)("</valgrindoutput>\n");
274274 VG_(printf)("\n%s: the 'impossible' happened:\n %s\n", name, str);
275 report_and_quit(report, ip, sp, fp, lr);
275 report_and_quit(report, startRegs);
276276}
277277
278void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp, Addr lr )
278void VG_(core_panic_at) ( Char* str, UnwindStartRegs* startRegs )
279279{
280 panic("valgrind", VG_BUGS_TO, str, ip, sp, fp, lr);
280 panic("valgrind", VG_BUGS_TO, str, startRegs);
281281}
282282
283283void VG_(core_panic) ( Char* str )
284284{
285 VG_(core_panic_at)(str, 0,0,0,0);
285 VG_(core_panic_at)(str, NULL);
286286}
287287
288288void VG_(tool_panic) ( Char* str )
289289{
290 panic(VG_(details).name, VG_(details).bug_reports_to, str, 0,0,0,0);
290 panic(VG_(details).name, VG_(details).bug_reports_to, str, NULL);
291291}
292292
293293/* Print some helpful-ish text about unimplemented things, and give up. */
  
804804 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
805805 return sr_isError(res) ? -1 : sr_Res(res);
806806
807# elif defined(VGP_amd64_linux)
807# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
808808 SysRes res;
809809 res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
810810 return sr_isError(res) ? -1 : sr_Res(res);
845845 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
846846 return sr_isError(res) ? -1 : sr_Res(res);
847847
848# elif defined(VGP_amd64_linux)
848# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
849849 SysRes res;
850850 res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
851851 return sr_isError(res) ? -1 : sr_Res(res);
886886 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
887887 return sr_isError(res) ? -1 : sr_Res(res);
888888
889# elif defined(VGP_amd64_linux)
889# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
890890 SysRes res;
891891 res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
892892 count, VKI_MSG_NOSIGNAL, 0,0);
917917 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
918918 return sr_isError(res) ? -1 : sr_Res(res);
919919
920# elif defined(VGP_amd64_linux)
920# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
921921 SysRes res;
922922 res = VG_(do_syscall3)( __NR_getsockname,
923923 (UWord)sd, (UWord)name, (UWord)namelen );
949949 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
950950 return sr_isError(res) ? -1 : sr_Res(res);
951951
952# elif defined(VGP_amd64_linux)
952# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
953953 SysRes res;
954954 res = VG_(do_syscall3)( __NR_getpeername,
955955 (UWord)sd, (UWord)name, (UWord)namelen );
984984 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
985985 return sr_isError(res) ? -1 : sr_Res(res);
986986
987# elif defined(VGP_amd64_linux)
987# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
988988 SysRes res;
989989 res = VG_(do_syscall5)( __NR_getsockopt,
990990 (UWord)sd, (UWord)level, (UWord)optname,
  
529529 list[i] = (UInt)list16[i];
530530 return sr_Res(sres);
531531
532# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) \
532# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) \
533 || defined(VGP_arm_linux) \
533534 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) \
534535 || defined(VGO_darwin)
535536 SysRes sres;
  
6464 return VG_(threads)[tid].arch.vex.guest_LR;
6565# elif defined(VGA_x86) || defined(VGA_amd64)
6666 return 0;
67# elif defined(VGA_arm)
68 return VG_(threads)[tid].arch.vex.guest_R14;
6769# else
6870# error "Unknown arch"
6971# endif
8181 INSTR_PTR( VG_(threads)[tid].arch ) = ip;
8282}
8383
84
85void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
86 ThreadId tid )
87{
88# if defined(VGA_x86)
89 regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_EIP;
90 regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_ESP;
91 regs->misc.X86.r_ebp
92 = VG_(threads)[tid].arch.vex.guest_EBP;
93# elif defined(VGA_amd64)
94 regs->r_pc = VG_(threads)[tid].arch.vex.guest_RIP;
95 regs->r_sp = VG_(threads)[tid].arch.vex.guest_RSP;
96 regs->misc.AMD64.r_rbp
97 = VG_(threads)[tid].arch.vex.guest_RBP;
98# elif defined(VGA_ppc32)
99 regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_CIA;
100 regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_R1;
101 regs->misc.PPC32.r_lr
102 = VG_(threads)[tid].arch.vex.guest_LR;
103# elif defined(VGA_ppc64)
104 regs->r_pc = VG_(threads)[tid].arch.vex.guest_CIA;
105 regs->r_sp = VG_(threads)[tid].arch.vex.guest_R1;
106 regs->misc.PPC64.r_lr
107 = VG_(threads)[tid].arch.vex.guest_LR;
108# elif defined(VGA_arm)
109 regs->r_pc = (ULong)VG_(threads)[tid].arch.vex.guest_R15;
110 regs->r_sp = (ULong)VG_(threads)[tid].arch.vex.guest_R13;
111 regs->misc.ARM.r14
112 = VG_(threads)[tid].arch.vex.guest_R14;
113 regs->misc.ARM.r12
114 = VG_(threads)[tid].arch.vex.guest_R12;
115 regs->misc.ARM.r11
116 = VG_(threads)[tid].arch.vex.guest_R11;
117# else
118# error "Unknown arch"
119# endif
120}
121
122
84123void VG_(set_syscall_return_shadows) ( ThreadId tid,
85124 /* shadow vals for the result */
86125 UWord s1res, UWord s2res,
135135# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
136136 VG_(threads)[tid].arch.vex_shadow1.guest_GPR3 = s1res;
137137 VG_(threads)[tid].arch.vex_shadow2.guest_GPR3 = s2res;
138# elif defined(VGP_arm_linux)
139 VG_(threads)[tid].arch.vex_shadow1.guest_R0 = s1res;
140 VG_(threads)[tid].arch.vex_shadow2.guest_R0 = s2res;
138141# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
139142 VG_(threads)[tid].arch.vex_shadow1.guest_GPR3 = s1res;
140143 VG_(threads)[tid].arch.vex_shadow2.guest_GPR3 = s2res;
228228 (*f)(vex->guest_R14);
229229 (*f)(vex->guest_R15);
230230#elif defined(VGA_ppc32) || defined(VGA_ppc64)
231 /* XXX ask tool about validity? */
232231 (*f)(vex->guest_GPR0);
233232 (*f)(vex->guest_GPR1);
234233 (*f)(vex->guest_GPR2);
262262 (*f)(vex->guest_GPR31);
263263 (*f)(vex->guest_CTR);
264264 (*f)(vex->guest_LR);
265
265#elif defined(VGA_arm)
266 (*f)(vex->guest_R0);
267 (*f)(vex->guest_R1);
268 (*f)(vex->guest_R2);
269 (*f)(vex->guest_R3);
270 (*f)(vex->guest_R4);
271 (*f)(vex->guest_R5);
272 (*f)(vex->guest_R6);
273 (*f)(vex->guest_R8);
274 (*f)(vex->guest_R9);
275 (*f)(vex->guest_R10);
276 (*f)(vex->guest_R11);
277 (*f)(vex->guest_R12);
278 (*f)(vex->guest_R13);
279 (*f)(vex->guest_R14);
266280#else
267281# error Unknown arch
268282#endif
369369*/
370370
371371/* --------- State --------- */
372static Bool hwcaps_done = False;
372static Bool hwcaps_done = False;
373373
374374/* --- all archs --- */
375375static VexArch va;
713713 return True;
714714 }
715715
716#elif defined(VGA_arm)
717 {
718 va = VexArchARM;
719 vai.hwcaps = 0;
720 return True;
721 }
722
716723#else
717724# error "Unknown arch"
718725#endif
775775// produce a pointer to the actual entry point for the function.
776776void* VG_(fnptr_to_fnentry)( void* f )
777777{
778#if defined(VGP_x86_linux) || defined(VGP_amd64_linux) || \
779 defined(VGP_ppc32_linux) || defined(VGO_darwin)
778#if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
779 || defined(VGP_arm_linux) \
780 || defined(VGP_ppc32_linux) || defined(VGO_darwin)
780781 return f;
781782#elif defined(VGP_ppc64_linux) || defined(VGP_ppc32_aix5) \
782783 || defined(VGP_ppc64_aix5)
  
19511951 iters = 10;
19521952# elif defined(VGP_ppc32_linux)
19531953 iters = 5;
1954# elif defined(VGP_arm_linux)
1955 iters = 1;
19541956# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
19551957 iters = 4;
19561958# elif defined(VGO_darwin)
26272627 return VG_(memset)(s,c,n);
26282628}
26292629
2630/* EAZG: ARM's EABI will call floating point exception handlers in
2631 libgcc which boil down to an abort or raise, that's usually defined
2632 in libc. Instead, define them here. */
2633#if defined(VGP_arm_linux)
2634void raise(void);
2635void raise(void){
2636 VG_(printf)("Something called raise().\n");
2637 vg_assert(0);
2638}
2639
2640void abort(void);
2641void abort(void){
2642 VG_(printf)("Something called raise().\n");
2643 vg_assert(0);
2644}
2645
2646void __aeabi_unwind_cpp_pr0(void);
2647void __aeabi_unwind_cpp_pr0(void){
2648 VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
2649 vg_assert(0);
2650}
2651#endif
2652
26302653/* ---------------- Requirement 2 ---------------- */
26312654
26322655/* Glibc's sysdeps/i386/elf/start.S has the following gem of a
27822782 "\tbl ._start_in_C_linux\n"
27832783 "\tnop\n"
27842784 "\ttrap\n"
2785);
2786#elif defined(VGP_arm_linux)
2787asm("\n"
2788 "\t.align 2\n"
2789 "\t.global _start\n"
2790 "_start:\n"
2791 "\tldr r0, [pc, #36]\n"
2792 "\tldr r1, [pc, #36]\n"
2793 "\tadd r0, r1, r0\n"
2794 "\tldr r1, [pc, #32]\n"
2795 "\tadd r0, r1, r0\n"
2796 "\tmvn r1, #15\n"
2797 "\tand r0, r0, r1\n"
2798 "\tmov r1, sp\n"
2799 "\tmov sp, r0\n"
2800 "\tmov r0, r1\n"
2801 "\tb _start_in_C_linux\n"
2802 "\t.word vgPlain_interim_stack\n"
2803 "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
2804 "\t.word "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
27852805);
27862806#else
27872807# error "Unknown linux platform"
  
995995 );
996996 }
997997
998# elif defined(VGP_arm_linux)
999 /* If we're using memcheck, use these intercepts right from
1000 the start, otherwise ld.so makes a lot of noise. */
1001 if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
1002 add_hardwired_spec(
1003 "ld-linux.so.3", "strlen",
1004 (Addr)&VG_(arm_linux_REDIR_FOR_strlen),
1005 NULL
1006 );
1007 //add_hardwired_spec(
1008 // "ld-linux.so.3", "index",
1009 // (Addr)&VG_(arm_linux_REDIR_FOR_index),
1010 // NULL
1011 //);
1012 add_hardwired_spec(
1013 "ld-linux.so.3", "memcpy",
1014 (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
1015 NULL
1016 );
1017 }
1018 /* nothing so far */
1019
9981020# elif defined(VGP_ppc32_aix5)
9991021 /* nothing so far */
10001022
  
4242
4343 It is called vg_replace_malloc.c because this filename appears in stack
4444 traces, so we want the name to be (hopefully!) meaningful to users.
45
46 IMPORTANT: this file must not contain any floating point code, nor
47 any integer division. This is because on ARM these can cause calls
48 to helper functions, which will be unresolved within this .so.
49 Although it is usually the case that the client's ld.so instance
50 can bind them at runtime to the relevant functions in the client
51 executable, there is no guarantee of this; and so the client may
52 die via a runtime link failure. Hence the only safe approach is to
53 avoid such function calls in the first place. See "#define CALLOC"
54 below for a specific example.
55
56 A useful command is
57 for f in `find . -name "*preload*.so*"` ; \
58 do nm -A $f | grep " U " ; \
59 done
60
61 to see all the undefined symbols in all the preload shared objects.
4562 ------------------------------------------------------------------ */
4663
4764#include "pub_core_basics.h"
111111#endif
112112
113113
114/* Compute the high word of the double-length unsigned product of U
115 and V. This is for calloc argument overflow checking; see comments
116 below. Algorithm as described in Hacker's Delight, chapter 8. */
117static UWord umulHW ( UWord u, UWord v )
118{
119 UWord u0, v0, w0, rHi;
120 UWord u1, v1, w1,w2,t;
121 UWord halfMask = sizeof(UWord)==4 ? (UWord)0xFFFF
122 : (UWord)0xFFFFFFFFULL;
123 UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
124 u0 = u & halfMask;
125 u1 = u >> halfShift;
126 v0 = v & halfMask;
127 v1 = v >> halfShift;
128 w0 = u0 * v0;
129 t = u1 * v0 + (w0 >> halfShift);
130 w1 = t & halfMask;
131 w2 = t >> halfShift;
132 w1 = u0 * v1 + w1;
133 rHi = u1 * v1 + w2 + (w1 >> halfShift);
134 return rHi;
135}
136
137
114138/*------------------------------------------------------------*/
115139/*--- Replacing malloc() et al ---*/
116140/*------------------------------------------------------------*/
449449 if (!init_done) init(); \
450450 MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
451451 \
452 /* Protect against overflow. See bug 24078. */ \
453 if (size && nmemb > (SizeT)-1 / size) return NULL; \
452 /* Protect against overflow. See bug 24078. (that bug number is
453 invalid. Which one really?) */ \
454 /* But don't use division, since that produces an external symbol
455 reference on ARM, in the form of a call to __aeabi_uidiv. It's
456 normally OK, because ld.so manages to resolve it to something in the
457 executable, or one of its shared objects. But that isn't guaranteed
458 to be the case, and it has been observed to fail in rare cases, eg:
459 echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
460 So instead compute the high word of the product and check it is zero. */ \
461 if (umulHW(size, nmemb) != 0) return NULL; \
454462 v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
455463 MALLOC_TRACE(" = %p\n", v ); \
456464 return v; \
  
655655 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow1.guest_VR1));
656656 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow2.guest_VR1));
657657# endif
658
659# if defined(VGA_arm)
660 /* arm guest_state VFP regs must be 8 byte aligned for
661 loads/stores. */
662 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex.guest_D0));
663 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow1.guest_D0));
664 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow2.guest_D0));
665 /* be extra paranoid .. */
666 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex.guest_D1));
667 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow1.guest_D1));
668 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow2.guest_D1));
669# endif
658670}
659671
660672
12071207 be in on entry to Vex-generated code, and they should be
12081208 unchanged on exit from it. Failure of this assertion
12091209 usually means a bug in Vex's code generation. */
1210 //{ UInt xx;
1211 // __asm__ __volatile__ (
1212 // "\t.word 0xEEF12A10\n" // fmrx r2,fpscr
1213 // "\tmov %0, r2" : "=r"(xx) : : "r2" );
1214 // VG_(printf)("QQQQ new fpscr = %08x\n", xx);
1215 //}
12101216 vg_assert2(0, "VG_(scheduler), phase 3: "
12111217 "run_innerloop detected host "
12121218 "state invariant failure", trc);
12971297#elif defined(VGA_ppc32) || defined(VGA_ppc64)
12981298# define VG_CLREQ_ARGS guest_GPR4
12991299# define VG_CLREQ_RET guest_GPR3
1300#elif defined(VGA_arm)
1301# define VG_CLREQ_ARGS guest_R4
1302# define VG_CLREQ_RET guest_R3
13001303#else
13011304# error Unknown arch
13021305#endif
  
1
2/*--------------------------------------------------------------------*/
3/*--- Create/destroy signal delivery frames. ---*/
4/*--- sigframe-arm-linux.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2009 Nicholas Nethercote
12 njn@valgrind.org
13 Copyright (C) 2004-2009 Paul Mackerras
14 paulus@samba.org
15 Copyright (C) 2008-2009 Evan Geller
16 gaze@bea.ms
17
18 This program is free software; you can redistribute it and/or
19 modify it under the terms of the GNU General Public License as
20 published by the Free Software Foundation; either version 2 of the
21 License, or (at your option) any later version.
22
23 This program is distributed in the hope that it will be useful, but
24 WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
31 02111-1307, USA.
32
33 The GNU General Public License is contained in the file COPYING.
34*/
35
36#if defined(VGP_arm_linux)
37
38#include "pub_core_basics.h"
39#include "pub_core_vki.h"
40#include "pub_core_vkiscnums.h"
41#include "pub_core_threadstate.h"
42#include "pub_core_aspacemgr.h"
43#include "pub_core_libcbase.h"
44#include "pub_core_libcassert.h"
45#include "pub_core_libcprint.h"
46#include "pub_core_machine.h"
47#include "pub_core_options.h"
48#include "pub_core_sigframe.h"
49#include "pub_core_signals.h"
50#include "pub_core_tooliface.h"
51#include "pub_core_trampoline.h"
52#include "pub_core_transtab.h" // VG_(discard_translations)
53
54
55struct vg_sig_private {
56 UInt magicPI;
57 UInt sigNo_private;
58 VexGuestARMState vex_shadow1;
59 VexGuestARMState vex_shadow2;
60};
61
62struct sigframe {
63 struct vki_ucontext uc;
64 unsigned long retcode[2];
65 struct vg_sig_private vp;
66};
67
68struct rt_sigframe {
69 vki_siginfo_t info;
70 struct sigframe sig;
71};
72
73static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
74{
75 ThreadId tid = tst->tid;
76 NSegment const* stackseg = NULL;
77
78 if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
79 stackseg = VG_(am_find_nsegment)(addr);
80 if (0 && stackseg)
81 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
82 addr, stackseg->start, stackseg->end);
83 }
84
85 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
86 VG_(message)(
87 Vg_UserMsg,
88 "Can't extend stack to %#lx during signal delivery for thread %d:",
89 addr, tid);
90 if (stackseg == NULL)
91 VG_(message)(Vg_UserMsg, " no stack segment");
92 else
93 VG_(message)(Vg_UserMsg, " too small or bad protection modes");
94
95 /* set SIGSEGV to default handler */
96 VG_(set_default_handler)(VKI_SIGSEGV);
97 VG_(synth_fault_mapping)(tid, addr);
98
99 /* The whole process should be about to die, since the default
100 action of SIGSEGV to kill the whole process. */
101 return False;
102 }
103
104 /* For tracking memory events, indicate the entire frame has been
105 allocated. */
106 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
107 size + VG_STACK_REDZONE_SZB, tid );
108
109 return True;
110}
111
112static void synth_ucontext( ThreadId tid, const vki_siginfo_t *si,
113 UWord trapno, UWord err, const vki_sigset_t *set,
114 struct vki_ucontext *uc){
115
116 ThreadState *tst = VG_(get_ThreadState)(tid);
117 struct vki_sigcontext *sc = &uc->uc_mcontext;
118
119 VG_(memset)(uc, 0, sizeof(*uc));
120
121 uc->uc_flags = 0;
122 uc->uc_link = 0;
123 uc->uc_sigmask = *set;
124 uc->uc_stack = tst->altstack;
125
126# define SC2(reg,REG) sc->arm_##reg = tst->arch.vex.guest_##REG
127 SC2(r0,R0);
128 SC2(r1,R1);
129 SC2(r2,R2);
130 SC2(r3,R3);
131 SC2(r4,R4);
132 SC2(r5,R5);
133 SC2(r6,R6);
134 SC2(r7,R7);
135 SC2(r8,R8);
136 SC2(r9,R9);
137 SC2(r10,R10);
138 SC2(fp,R11);
139 SC2(ip,R12);
140 SC2(sp,R13);
141 SC2(lr,R14);
142 SC2(pc,R15);
143# undef SC2
144
145 sc->trap_no = trapno;
146 sc->error_code = err;
147 sc->fault_address = (UInt)si->_sifields._sigfault._addr;
148}
149
150
151static void build_sigframe(ThreadState *tst,
152 struct sigframe *frame,
153 const vki_siginfo_t *siginfo,
154 const struct vki_ucontext *siguc,
155 void *handler, UInt flags,
156 const vki_sigset_t *mask,
157 void *restorer){
158
159 UWord trapno;
160 UWord err;
161 Int sigNo = siginfo->si_signo;
162 struct vg_sig_private *priv = &frame->vp;
163
164 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
165 (Addr)frame, offsetof(struct sigframe, vp));
166
167 if(siguc) {
168 trapno = siguc->uc_mcontext.trap_no;
169 err = siguc->uc_mcontext.error_code;
170 } else {
171 trapno = 0;
172 err = 0;
173 }
174
175 synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uc);
176
177 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
178 (Addr)frame, offsetof(struct sigframe, vp));
179
180 priv->magicPI = 0x31415927;
181 priv->sigNo_private = sigNo;
182 priv->vex_shadow1 = tst->arch.vex_shadow1;
183 priv->vex_shadow2 = tst->arch.vex_shadow2;
184
185}
186
187
188
189/* EXPORTED */
190void VG_(sigframe_create)( ThreadId tid,
191 Addr sp_top_of_frame,
192 const vki_siginfo_t *siginfo,
193 const struct vki_ucontext *siguc,
194 void *handler,
195 UInt flags,
196 const vki_sigset_t *mask,
197 void *restorer )
198{
199// struct vg_sig_private *priv;
200 Addr sp = sp_top_of_frame;
201 ThreadState *tst;
202 Int sigNo = siginfo->si_signo;
203// Addr faultaddr;
204 UInt size;
205
206 tst = VG_(get_ThreadState)(tid);
207
208 size = flags & VKI_SA_SIGINFO ? sizeof(struct rt_sigframe) :
209 sizeof(struct sigframe);
210
211 sp -= size;
212 sp = VG_ROUNDDN(sp, 16);
213
214 if(!extend(tst, sp, size))
215 I_die_here; // XXX Incorrect behavior
216
217
218 if (flags & VKI_SA_SIGINFO){
219 struct rt_sigframe *rsf = (struct rt_sigframe *)sp;
220
221 /* Track our writes to siginfo */
222 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, /* VVVVV */
223 "signal handler siginfo", (Addr)rsf,
224 offsetof(struct rt_sigframe, sig));
225
226 VG_(memcpy)(&rsf->info, siginfo, sizeof(vki_siginfo_t));
227
228 if(sigNo == VKI_SIGILL && siginfo->si_code > 0) {
229 rsf->info._sifields._sigfault._addr = (Addr *) (tst)->arch.vex.guest_R12; /* IP */
230 }
231 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, /* ^^^^^ */
232 (Addr)rsf, offsetof(struct rt_sigframe, sig));
233
234 build_sigframe(tst, &rsf->sig, siginfo, siguc,
235 handler, flags, mask, restorer);
236 tst->arch.vex.guest_R1 = (Addr)&rsf->info;
237 tst->arch.vex.guest_R2 = (Addr)&rsf->sig.uc;
238 }
239 else{
240 build_sigframe(tst, (struct sigframe *)sp, siginfo, siguc,
241 handler, flags, mask, restorer);
242 }
243
244 VG_(set_SP)(tid, sp);
245 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR,
246 sizeof(Addr));
247 tst->arch.vex.guest_R0 = sigNo;
248
249 if(flags & VKI_SA_RESTORER)
250 tst->arch.vex.guest_R14 = (Addr) restorer;
251
252 tst->arch.vex.guest_R15 = (Addr) handler; /* R15 == PC */
253}
254
255
256/*------------------------------------------------------------*/
257/*--- Destroying signal frames ---*/
258/*------------------------------------------------------------*/
259
260/* EXPORTED */
261void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
262{
263 ThreadState *tst;
264 struct vg_sig_private *priv;
265 Addr sp;
266 UInt frame_size;
267 struct vki_sigcontext *mc;
268 Int sigNo;
269 Bool has_siginfo = isRT;
270
271 vg_assert(VG_(is_valid_tid)(tid));
272 tst = VG_(get_ThreadState)(tid);
273 sp = tst->arch.vex.guest_R13;
274
275 if (has_siginfo) {
276 struct rt_sigframe *frame = (struct rt_sigframe *)sp;
277 frame_size = sizeof(*frame);
278 mc = &frame->sig.uc.uc_mcontext;
279 priv = &frame->sig.vp;
280 vg_assert(priv->magicPI == 0x31415927);
281 tst->sig_mask = frame->sig.uc.uc_sigmask;
282 } else {
283 struct sigframe *frame = (struct sigframe *)sp;
284 frame_size = sizeof(*frame);
285 mc = &frame->uc.uc_mcontext;
286 priv = &frame->vp;
287 vg_assert(priv->magicPI == 0x31415927);
288 tst->sig_mask = frame->uc.uc_sigmask;
289 /*tst->sig_mask.sig[0] = frame->uc.uc_mcontext.oldmask;
290 tst->sig_mask.sig[1] = frame->uc.uc_mcontext._unused[3];
291 VG_(printf)("Setting signmask to %08x%08x\n",tst->sig_mask[0],tst->sig_mask[1]);
292*/
293 }
294 tst->tmp_sig_mask = tst->sig_mask;
295
296 sigNo = priv->sigNo_private;
297
298 //XXX: restore regs
299# define REST(reg,REG) tst->arch.vex.guest_##REG = mc->arm_##reg;
300 REST(r0,R0);
301 REST(r1,R1);
302 REST(r2,R2);
303 REST(r3,R3);
304 REST(r4,R4);
305 REST(r5,R5);
306 REST(r6,R6);
307 REST(r7,R7);
308 REST(r8,R8);
309 REST(r9,R9);
310 REST(r10,R10);
311 REST(fp,R11);
312 REST(ip,R12);
313 REST(sp,R13);
314 REST(lr,R14);
315 REST(pc,R15);
316# undef REST
317
318 tst->arch.vex_shadow1 = priv->vex_shadow1;
319 tst->arch.vex_shadow2 = priv->vex_shadow2;
320
321 VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB,
322 frame_size + VG_STACK_REDZONE_SZB );
323
324 if (VG_(clo_trace_signals))
325 VG_(message)(Vg_DebugMsg,
326 "vg_pop_signal_frame (thread %d): isRT=%d valid magic; PC=%#x",
327 tid, has_siginfo, tst->arch.vex.guest_R15);
328
329 /* tell the tools */
330 VG_TRACK( post_deliver_signal, tid, sigNo );
331}
332
333#endif // defined(VGP_arm_linux)
334
335/*--------------------------------------------------------------------*/
336/*--- end sigframe-arm-linux.c ---*/
337/*--------------------------------------------------------------------*/
  
266266#if defined(VGP_x86_linux)
267267# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
268268# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
269# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.ebp)
270269# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
271270 /* Convert the value in uc_mcontext.eax into a SysRes. */ \
272271 VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
273# define VG_UCONTEXT_LINK_REG(uc) 0 /* Dude, where's my LR? */
272# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
273 { (srP)->r_pc = (ULong)((uc)->uc_mcontext.eip); \
274 (srP)->r_sp = (ULong)((uc)->uc_mcontext.esp); \
275 (srP)->misc.X86.r_ebp = (uc)->uc_mcontext.ebp; \
276 }
274277
275278#elif defined(VGP_amd64_linux)
276279# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
277280# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
278# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.rbp)
279281# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
280282 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
281283 VG_(mk_SysRes_amd64_linux)( (uc)->uc_mcontext.rax )
282# define VG_UCONTEXT_LINK_REG(uc) 0 /* No LR on amd64 either */
284# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
285 { (srP)->r_pc = (uc)->uc_mcontext.rip; \
286 (srP)->r_sp = (uc)->uc_mcontext.rsp; \
287 (srP)->misc.AMD64.r_rbp = (uc)->uc_mcontext.rbp; \
288 }
283289
284290#elif defined(VGP_ppc32_linux)
285291/* Comments from Paul Mackerras 25 Nov 05:
363363 }
364364# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_LNK])
365365
366#elif defined(VGP_arm_linux)
367# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.arm_pc)
368# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.arm_sp)
369# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
370 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
371 VG_(mk_SysRes_arm_linux)( (uc)->uc_mcontext.arm_r0 )
372# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
373 { (srP)->r_pc = (uc)->uc_mcontext.arm_pc; \
374 (srP)->r_sp = (uc)->uc_mcontext.arm_sp; \
375 (srP)->misc.ARM.r14 = (uc)->uc_mcontext.arm_lr; \
376 (srP)->misc.ARM.r12 = (uc)->uc_mcontext.arm_ip; \
377 (srP)->misc.ARM.r11 = (uc)->uc_mcontext.arm_fp; \
378 }
379
366380#elif defined(VGP_ppc32_aix5)
367381
368382 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
783783 " movl $" #name ", %eax\n" \
784784 " int $0x80\n" \
785785 ".previous\n"
786
786787#elif defined(VGP_amd64_linux)
787788# define _MY_SIGRETURN(name) \
788789 ".text\n" \
791791 " movq $" #name ", %rax\n" \
792792 " syscall\n" \
793793 ".previous\n"
794
794795#elif defined(VGP_ppc32_linux)
795796# define _MY_SIGRETURN(name) \
796797 ".text\n" \
799799 " li 0, " #name "\n" \
800800 " sc\n" \
801801 ".previous\n"
802
802803#elif defined(VGP_ppc64_linux)
803804# define _MY_SIGRETURN(name) \
804805 ".align 2\n" \
814814 ".my_sigreturn:\n" \
815815 " li 0, " #name "\n" \
816816 " sc\n"
817
818#elif defined(VGP_arm_linux)
819# define _MY_SIGRETURN(name) \
820 ".text\n" \
821 "my_sigreturn:\n\t" \
822 " mov r7, #" #name "\n\t" \
823 " svc 0x00000000\n" \
824 ".previous\n"
825
817826#elif defined(VGP_ppc32_aix5)
818827# define _MY_SIGRETURN(name) \
819828 ".globl my_sigreturn\n" \
833833 ".globl my_sigreturn\n" \
834834 "my_sigreturn:\n" \
835835 ".long 0\n"
836
836837#elif defined(VGP_x86_darwin)
837838# define _MY_SIGRETURN(name) \
838839 ".text\n" \
839840 "my_sigreturn:\n" \
840841 "movl $" VG_STRINGIFY(__NR_DARWIN_FAKE_SIGRETURN) ",%eax\n" \
841842 "int $0x80"
843
842844#elif defined(VGP_amd64_darwin)
843845 // DDD: todo
844846# define _MY_SIGRETURN(name) \
845847 ".text\n" \
846848 "my_sigreturn:\n" \
847849 "ud2\n"
850
848851#else
849852# error Unknown platform
850853#endif
23232323 // tid = VG_(master_tid);
23242324 vg_assert(tid != 0);
23252325
2326 VG_(core_panic_at)("Killed by fatal signal",
2327 VG_UCONTEXT_INSTR_PTR(uc),
2328 VG_UCONTEXT_STACK_PTR(uc),
2329 VG_UCONTEXT_FRAME_PTR(uc),
2330 VG_UCONTEXT_LINK_REG(uc));
2326 UnwindStartRegs startRegs;
2327 VG_(memset)(&startRegs, 0, sizeof(startRegs));
2328
2329 VG_UCONTEXT_TO_UnwindStartRegs(&startRegs, uc);
2330 VG_(core_panic_at)("Killed by fatal signal", &startRegs);
23312331 }
23322332}
23332333
  
4444#include "pub_core_clientstate.h" // VG_(client__dl_sysinfo_int80)
4545#include "pub_core_trampoline.h"
4646
47
4748/*------------------------------------------------------------*/
48/*--- Exported functions. ---*/
49/*--- ---*/
50/*--- BEGIN platform-dependent unwinder worker functions ---*/
51/*--- ---*/
4952/*------------------------------------------------------------*/
5053
5154/* Take a snapshot of the client's stack, putting up to 'max_n_ips'
6060 first parameter, else send zero. This helps generate better stack
6161 traces on ppc64-linux and has no effect on other platforms.
6262*/
63
64/* ------------------------ x86 ------------------------- */
65
66#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
67
6368UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
6469 /*OUT*/Addr* ips, UInt max_n_ips,
6570 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
66 Addr ip, Addr sp, Addr fp, Addr lr,
67 Addr fp_min, Addr fp_max_orig )
71 UnwindStartRegs* startRegs,
72 Addr fp_max_orig )
6873{
69# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
70 || defined(VGP_ppc32_aix5) \
71 || defined(VGP_ppc64_aix5)
72 Bool lr_is_first_RA = False;
73# endif
74# if defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5) \
75 || defined(VGP_ppc32_aix5)
76 Word redir_stack_size = 0;
77 Word redirs_used = 0;
78# endif
79
8074 Bool debug = False;
8175 Int i;
8276 Addr fp_max;
7979 vg_assert(sizeof(Addr) == sizeof(UWord));
8080 vg_assert(sizeof(Addr) == sizeof(void*));
8181
82 Addr ip = (Addr)startRegs->r_pc;
83 Addr sp = (Addr)startRegs->r_sp;
84 Addr fp = startRegs->misc.X86.r_ebp;
85 Addr fp_min = sp;
86
8287 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
8388 stopping when the trail goes cold, which we guess to be
8489 when FP is not a reasonable stack location. */
105105 /* vg_assert(fp_min <= fp_max);*/
106106 // On Darwin, this kicks in for pthread-related stack traces, so they're
107107 // only 1 entry long which is wrong.
108#if !defined(VGO_darwin)
108# if !defined(VGO_darwin)
109109 if (fp_min + 512 >= fp_max) {
110110 /* If the stack limits look bogus, don't poke around ... but
111111 don't bomb out either. */
114114 ips[0] = ip;
115115 return 1;
116116 }
117#endif
117# endif
118118
119 /* Otherwise unwind the stack in a platform-specific way. Trying
120 to merge the x86, amd64, ppc32 and ppc64 logic into a single
121 piece of code is just too confusing and difficult to
122 performance-tune. */
123
124# if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
125
126 /*--------------------- x86 ---------------------*/
127
128119 /* fp is %ebp. sp is %esp. ip is %eip. */
129120
130121 if (sps) sps[0] = sp;
206206 break;
207207 }
208208
209# elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
209 n_found = i;
210 return n_found;
211}
210212
211 /*--------------------- amd64 ---------------------*/
213#endif
212214
215/* ----------------------- amd64 ------------------------ */
216
217#if defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
218
219UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
220 /*OUT*/Addr* ips, UInt max_n_ips,
221 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
222 UnwindStartRegs* startRegs,
223 Addr fp_max_orig )
224{
225 Bool debug = False;
226 Int i;
227 Addr fp_max;
228 UInt n_found = 0;
229
230 vg_assert(sizeof(Addr) == sizeof(UWord));
231 vg_assert(sizeof(Addr) == sizeof(void*));
232
233 Addr ip = startRegs->r_pc;
234 Addr sp = startRegs->r_sp;
235 Addr fp = startRegs->misc.AMD64.r_rbp;
236 Addr fp_min = sp;
237
238 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
239 stopping when the trail goes cold, which we guess to be
240 when FP is not a reasonable stack location. */
241
242 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
243 // current page, at least. Dunno if it helps.
244 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
245 fp_max = VG_PGROUNDUP(fp_max_orig);
246 if (fp_max >= sizeof(Addr))
247 fp_max -= sizeof(Addr);
248
249 if (debug)
250 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
251 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
252 max_n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
253
254 /* Assertion broken before main() is reached in pthreaded programs; the
255 * offending stack traces only have one item. --njn, 2002-aug-16 */
256 /* vg_assert(fp_min <= fp_max);*/
257 // On Darwin, this kicks in for pthread-related stack traces, so they're
258 // only 1 entry long which is wrong.
259# if !defined(VGO_darwin)
260 if (fp_min + 512 >= fp_max) {
261 /* If the stack limits look bogus, don't poke around ... but
262 don't bomb out either. */
263 if (sps) sps[0] = sp;
264 if (fps) fps[0] = fp;
265 ips[0] = ip;
266 return 1;
267 }
268# endif
269
213270 /* fp is %rbp. sp is %rsp. ip is %rip. */
214271
215272 ips[0] = ip;
369369 break;
370370 }
371371
372# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
373 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
372 n_found = i;
373 return n_found;
374}
374375
375 /*--------------------- ppc32/64 ---------------------*/
376#endif
376377
378/* -----------------------ppc32/64 ---------------------- */
379
380#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
381 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
382
383UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
384 /*OUT*/Addr* ips, UInt max_n_ips,
385 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
386 Addr ip, Addr sp, Addr fp, Addr lr,
387 Addr fp_min, Addr fp_max_orig )
388{
389 Bool lr_is_first_RA = False;
390# if defined(VG_PLAT_USES_PPCTOC)
391 Word redir_stack_size = 0;
392 Word redirs_used = 0;
393# endif
394
395 Bool debug = False;
396 Int i;
397 Addr fp_max;
398 UInt n_found = 0;
399
400 vg_assert(sizeof(Addr) == sizeof(UWord));
401 vg_assert(sizeof(Addr) == sizeof(void*));
402
403 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
404 stopping when the trail goes cold, which we guess to be
405 when FP is not a reasonable stack location. */
406
407 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
408 // current page, at least. Dunno if it helps.
409 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
410 fp_max = VG_PGROUNDUP(fp_max_orig);
411 if (fp_max >= sizeof(Addr))
412 fp_max -= sizeof(Addr);
413
414 if (debug)
415 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
416 "fp_max=0x%lx ip=0x%lx fp=0x%lx\n",
417 max_n_ips, fp_min, fp_max_orig, fp_max, ip, fp);
418
419 /* Assertion broken before main() is reached in pthreaded programs; the
420 * offending stack traces only have one item. --njn, 2002-aug-16 */
421 /* vg_assert(fp_min <= fp_max);*/
422 if (fp_min + 512 >= fp_max) {
423 /* If the stack limits look bogus, don't poke around ... but
424 don't bomb out either. */
425 if (sps) sps[0] = sp;
426 if (fps) fps[0] = fp;
427 ips[0] = ip;
428 return 1;
429 }
430
377431 /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and
378432 frame pointers. */
379433
490490 /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save
491491 slot is 2 words back from sp, whereas on ppc32-elf(?) it's
492492 only one word back. */
493# if defined(VGP_ppc64_linux) \
494 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
493# if defined(VG_PLAT_USES_PPCTOC)
495494 const Int lr_offset = 2;
496495# else
497496 const Int lr_offset = 1;
550550 }
551551 }
552552
553# else
554# error "Unknown platform"
555# endif
553 n_found = i;
554 return n_found;
555}
556556
557#endif
558
559/* ------------------------ arm ------------------------- */
560
561#if defined(VGP_arm_linux)
562
563UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
564 /*OUT*/Addr* ips, UInt max_n_ips,
565 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
566 UnwindStartRegs* startRegs,
567 Addr fp_max_orig )
568{
569 Bool debug = False;
570 Int i;
571 Addr fp_max;
572 UInt n_found = 0;
573
574 vg_assert(sizeof(Addr) == sizeof(UWord));
575 vg_assert(sizeof(Addr) == sizeof(void*));
576
577 Addr r15 = startRegs->r_pc;
578 Addr r13 = startRegs->r_sp;
579 Addr r14 = startRegs->misc.ARM.r14;
580 Addr r12 = startRegs->misc.ARM.r12;
581 Addr r11 = startRegs->misc.ARM.r11;
582 Addr fp_min = r13;
583
584 /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
585 stopping when the trail goes cold, which we guess to be
586 when FP is not a reasonable stack location. */
587
588 // JRS 2002-sep-17: hack, to round up fp_max to the end of the
589 // current page, at least. Dunno if it helps.
590 // NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
591 fp_max = VG_PGROUNDUP(fp_max_orig);
592 if (fp_max >= sizeof(Addr))
593 fp_max -= sizeof(Addr);
594
595 if (debug)
596 VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
597 "fp_max=0x%lx r15=0x%lx r13=0x%lx\n",
598 max_n_ips, fp_min, fp_max_orig, fp_max, r15, r13);
599
600 /* Assertion broken before main() is reached in pthreaded programs; the
601 * offending stack traces only have one item. --njn, 2002-aug-16 */
602 /* vg_assert(fp_min <= fp_max);*/
603 // On Darwin, this kicks in for pthread-related stack traces, so they're
604 // only 1 entry long which is wrong.
605 if (fp_min + 512 >= fp_max) {
606 /* If the stack limits look bogus, don't poke around ... but
607 don't bomb out either. */
608 if (sps) sps[0] = r13;
609 if (fps) fps[0] = 0;
610 ips[0] = r15;
611 return 1;
612 }
613
614 /* */
615
616 if (sps) sps[0] = r13;
617 if (fps) fps[0] = 0;
618 ips[0] = r15;
619 i = 1;
620
621 /* Loop unwinding the stack. */
622
623 while (True) {
624 if (debug) {
625 VG_(printf)("i: %d, r15: 0x%lx, r13: 0x%lx\n",i, r15, r13);
626 }
627
628 if (i >= max_n_ips)
629 break;
630
631 if (VG_(use_CF_info)( &r15, &r14, &r13, &r12, &r11, fp_min, fp_max )) {
632 if (sps) sps[i] = r13;
633 if (fps) fps[i] = 0;
634 ips[i++] = r15 -1;
635 if (debug)
636 VG_(printf)("USING CFI: r15: 0x%lx, r13: 0x%lx\n", r15, r13);
637 r15 = r15 - 1;
638 continue;
639 }
640 /* No luck. We have to give up. */
641 break;
642 }
643
557644 n_found = i;
558645 return n_found;
559646}
560647
648#endif
649
650/*------------------------------------------------------------*/
651/*--- ---*/
652/*--- END platform-dependent unwinder worker functions ---*/
653/*--- ---*/
654/*------------------------------------------------------------*/
655
656/*------------------------------------------------------------*/
657/*--- Exported functions. ---*/
658/*------------------------------------------------------------*/
659
561660UInt VG_(get_StackTrace) ( ThreadId tid,
562661 /*OUT*/StackTrace ips, UInt max_n_ips,
563662 /*OUT*/StackTrace sps,
564663 /*OUT*/StackTrace fps,
565664 Word first_ip_delta )
566665{
567 /* thread in thread table */
568 Addr ip = VG_(get_IP)(tid);
569 Addr fp = VG_(get_FP)(tid);
570 Addr sp = VG_(get_SP)(tid);
571 Addr lr = VG_(get_LR)(tid);
666 /* Get the register values with which to start the unwind. */
667 UnwindStartRegs startRegs;
668 VG_(memset)( &startRegs, 0, sizeof(startRegs) );
669 VG_(get_UnwindStartRegs)( &startRegs, tid );
670
572671 Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word;
573672 Addr stack_lowest_word = 0;
574673
690690 bothered.
691691 */
692692 if (VG_(client__dl_sysinfo_int80) != 0 /* we know its address */
693 && ip >= VG_(client__dl_sysinfo_int80)
694 && ip < VG_(client__dl_sysinfo_int80)+3
695 && VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) {
696 ip = *(Addr *)sp;
697 sp += sizeof(Addr);
693 && startRegs.r_pc >= VG_(client__dl_sysinfo_int80)
694 && startRegs.r_pc < VG_(client__dl_sysinfo_int80)+3
695 && VG_(am_is_valid_for_client)(startRegs.r_pc, sizeof(Addr),
696 VKI_PROT_READ)) {
697 startRegs.r_pc = (ULong) *(Addr*)(UWord)startRegs.r_sp;
698 startRegs.r_sp += (ULong) sizeof(Addr);
698699 }
699700# endif
700701
701702 /* See if we can get a better idea of the stack limits */
702 VG_(stack_limits)(sp, &stack_lowest_word, &stack_highest_word);
703 VG_(stack_limits)( (Addr)startRegs.r_sp,
704 &stack_lowest_word, &stack_highest_word );
703705
704706 /* Take into account the first_ip_delta. */
705 vg_assert( sizeof(Addr) == sizeof(Word) );
706 ip += first_ip_delta;
707 startRegs.r_pc += (Long)(Word)first_ip_delta;
707708
708709 if (0)
709 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%08lx "
710 "sp=0x%08lx fp=0x%08lx\n",
711 tid, stack_highest_word, ip, sp, fp);
710 VG_(printf)("tid %d: stack_highest=0x%08lx ip=0x%010llx "
711 "sp=0x%010llx\n",
712 tid, stack_highest_word,
713 startRegs.r_pc, startRegs.r_sp);
712714
713715 return VG_(get_StackTrace_wrk)(tid, ips, max_n_ips,
714716 sps, fps,
715 ip, sp, fp, lr, sp,
717 &startRegs,
716718 stack_highest_word);
717719}
718720
  
100100 return res;
101101}
102102
103SysRes VG_(mk_SysRes_arm_linux) ( Int val ) {
104 SysRes res;
105 res._isError = val >= -4095 && val <= -1;
106 if (res._isError) {
107 res._val = (UInt)(-val);
108 } else {
109 res._val = (UInt)val;
110 }
111 return res;
112}
113
103114/* Generic constructors. */
104115SysRes VG_(mk_SysRes_Error) ( UWord err ) {
105116 SysRes r;
410410" blr\n"
411411);
412412
413#elif defined(VGP_arm_linux)
414/* I think the conventions are:
415 args in r0 r1 r2 r3 r4 r5
416 sysno in r7
417 return value in r0, w/ same conventions as x86-linux, viz r0 in
418 -4096 .. -1 is an error value. All other values are success
419 values.
420*/
421extern UWord do_syscall_WRK (
422 UWord a1, UWord a2, UWord a3,
423 UWord a4, UWord a5, UWord a6,
424 UWord syscall_no
425 );
426asm(
427".text\n"
428"do_syscall_WRK:\n"
429" push {r4, r5, r7}\n"
430" ldr r4, [sp, #12]\n"
431" ldr r5, [sp, #16]\n"
432" ldr r7, [sp, #20]\n"
433" svc 0x0\n"
434" pop {r4, r5, r7}\n"
435" bx lr\n"
436".previous\n"
437);
438
413439#elif defined(VGP_ppc32_aix5)
414440static void do_syscall_WRK ( UWord* res_r3, UWord* res_r4,
415441 UWord sysno,
756756 argblock[6] = a6;
757757 do_syscall_WRK( &argblock[0] );
758758 return VG_(mk_SysRes_ppc64_linux)( argblock[0], argblock[1] );
759
760# elif defined(VGP_arm_linux)
761 UWord val = do_syscall_WRK(a1,a2,a3,a4,a5,a6,sysno);
762 return VG_(mk_SysRes_arm_linux)( val );
759763
760764# elif defined(VGP_ppc32_aix5)
761765 UWord res;
  
8383 // Note that, depending on the platform, arguments may be found in
8484 // registers or on the stack. (See the comment at the top of
8585 // syswrap-main.c for per-platform details.) For register arguments
86 // (which have o_arg field names) the o_arg value is the offset from
86 // (which have o_arg field names) the o_arg value is the offset into
8787 // the vex register state. For stack arguments (which have s_arg
8888 // field names), the s_arg value is the offset from the stack pointer.
8989 Int o_sysno;
9090# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
91 || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
91 || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
92 || defined(VGP_arm_linux)
9293 Int o_arg1;
9394 Int o_arg2;
9495 Int o_arg3;
171171*/
172172
173173
174#if defined(VGO_linux) || defined(VGO_darwin)
175/* On Linux, finding the wrapper is easy: just look up in fixed,
176 platform-specific tables. These are defined in the relevant
177 platform-specific files -- syswrap-arch-os.c */
174/* A function to find the syscall table entry for a given sysno. If
175 none is found, return NULL. This used to be done with a single
176 fixed sized table exposed to the caller, but that's too inflexible;
177 hence now use a function which can do arbitrary messing around to
178 find the required entry. */
179#if defined(VGO_linux)
180extern
181SyscallTableEntry* ML_(get_linux_syscall_entry)( UInt sysno );
178182
179extern const SyscallTableEntry ML_(syscall_table)[];
180
181extern const UInt ML_(syscall_table_size);
182
183183#elif defined(VGP_ppc32_aix5)
184/* On AIX5 this is more complex than the simple fixed table lookup on
185 Linux, since the syscalls don't have fixed numbers. So it's
186 simplest to use a function, which does all the required messing
187 around. */
184/* Same scheme on AIX5. This is more complex than the simple fixed
185 table lookup typical for Linux, since the syscalls don't have fixed
186 numbers. */
188187extern
189188SyscallTableEntry* ML_(get_ppc32_aix5_syscall_entry) ( UInt sysno );
190189
191190#elif defined(VGP_ppc64_aix5)
192191extern
193192SyscallTableEntry* ML_(get_ppc64_aix5_syscall_entry) ( UInt sysno );
193
194#elif defined(VGO_darwin)
195/* XXX: Darwin still uses the old scheme of exposing the table
196 array(s) and size(s) directly to syswrap-main.c. This should be
197 fixed. */
198
199extern const SyscallTableEntry ML_(syscall_table)[];
200extern const UInt ML_(syscall_table_size);
194201
195202#else
196203# error Unknown OS
  
1
2/*--------------------------------------------------------------------*/
3/*--- Support for doing system calls. syscall-arm-linux.S ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2008-2009 Evan Geller (gaze@bea.ms)
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30#if defined(VGP_arm_linux)
31
32#include "pub_core_basics_asm.h"
33#include "pub_core_vkiscnums_asm.h"
34#include "libvex_guest_offsets.h"
35
36
37/*----------------------------------------------------------------*/
38/*
39 Perform a syscall for the client. This will run a syscall
40 with the client's specific per-thread signal mask.
41
42 The structure of this function is such that, if the syscall is
43 interrupted by a signal, we can determine exactly what
44 execution state we were in with respect to the execution of
45 the syscall by examining the value of IP in the signal
46 handler. This means that we can always do the appropriate
47 thing to precisely emulate the kernel's signal/syscall
48 interactions.
49
50 The syscall number is taken from the argument, even though it
51 should also be in regs->m_R7. The syscall result is written
52 back to regs->m_R0 on completion.
53
54 Returns 0 if the syscall was successfully called (even if the
55 syscall itself failed), or a nonzero error code in the lowest
56 8 bits if one of the sigprocmasks failed (there's no way to
57 determine which one failed). And there's no obvious way to
58 recover from that either, but nevertheless we want to know.
59
60 VG_(fixup_guest_state_after_syscall_interrupted) does the
61 thread state fixup in the case where we were interrupted by a
62 signal.
63
64 Prototype:
65
66 UWord ML_(do_syscall_for_client_WRK)(
67 Int syscallno, // r0
68 void* guest_state, // r1
69 const vki_sigset_t *sysmask, // r2
70 const vki_sigset_t *postmask, // r3
71 Int nsigwords) // [sp, #0]
72*/
73/* from vki_arch.h */
74#define VKI_SIG_SETMASK 2
75
76.globl ML_(do_syscall_for_client_WRK)
77ML_(do_syscall_for_client_WRK):
78
79 /* Stash callee-saves and our args on the stack */
80 push {r0, r1, r3, r4, r5, r7, fp, lr}
81
821:
83
84 mov r7, #__NR_rt_sigprocmask
85 mov r0, #VKI_SIG_SETMASK
86 mov r1, r2 /* sysmask */
87 mov r2, r3 /* postmask */
88 ldr r3, [sp, #32] /* nsigwords */
89 svc 0x00000000
90
91
92 ldr r5, [sp, #4] /* guest_state */
93
94 ldr r7, [sp, #0] /* syscall# */
95 ldr r0, [r5, #OFFSET_arm_R0]
96 ldr r1, [r5, #OFFSET_arm_R1]
97 ldr r2, [r5, #OFFSET_arm_R2]
98 ldr r3, [r5, #OFFSET_arm_R3]
99 ldr r4, [r5, #OFFSET_arm_R4]
100 ldr r5, [r5, #OFFSET_arm_R5]
101
1022: svc 0x00000000
1033:
104 ldr r5, [sp, #4] /* guest_state */
105 str r0, [r5, #OFFSET_arm_R0]
106
1074:
108 mov r7, #__NR_rt_sigprocmask
109 mov r0, #VKI_SIG_SETMASK
110 ldr r1, [sp, #8] /* postmask */
111 mov r2, #0
112 ldr r3, [sp, #32] /* nsigwords */
113 svc 0x00000000
114
115 cmp r0, #0
116 blt 7f
117 add sp, sp, #4 /* r0 contains return value */
118
1195: /* Success */
120 mov r0, #0
121 pop {r1, r3, r4, r5, r7, fp, pc}
122
1237: /* Failure: return 0x8000 | error code */
124 orr r0, r0, #0x8000
125 pop {r1, r3, r4, r5, r7, fp, pc}
126
127
128.section .rodata
129/* export the ranges so that
130 VG_(fixup_guest_state_after_syscall_interrupted) can do the
131 right thing */
132
133.globl ML_(blksys_setup)
134.globl ML_(blksys_restart)
135.globl ML_(blksys_complete)
136.globl ML_(blksys_committed)
137.globl ML_(blksys_finished)
138ML_(blksys_setup): .long 1b
139ML_(blksys_restart): .long 2b
140ML_(blksys_complete): .long 3b
141ML_(blksys_committed): .long 4b
142ML_(blksys_finished): .long 5b
143
144/* Let the linker know we don't need an executable stack */
145.section .note.GNU-stack,"",%progbits
146
147.previous
148
149#endif // defined(VGP_arm_linux)
150
151/*--------------------------------------------------------------------*/
152/*--- end ---*/
153/*--------------------------------------------------------------------*/
  
10401040// When implementing these wrappers, you need to work out if the wrapper is
10411041// generic, Linux-only (but arch-independent), or AMD64/Linux only.
10421042
1043const SyscallTableEntry ML_(syscall_table)[] = {
1043static SyscallTableEntry syscall_table[] = {
10441044 GENXY(__NR_read, sys_read), // 0
10451045 GENX_(__NR_write, sys_write), // 1
10461046 GENXY(__NR_open, sys_open), // 2
14011401 LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 298
14021402};
14031403
1404const UInt ML_(syscall_table_size) =
1405 sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
1404SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1405{
1406 const UInt syscall_table_size
1407 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1408
1409 /* Is it in the contiguous initial section of the table? */
1410 if (sysno < syscall_table_size) {
1411 SyscallTableEntry* sys = &syscall_table[sysno];
1412 if (sys->before == NULL)
1413 return NULL; /* no entry */
1414 else
1415 return sys;
1416 }
1417
1418 /* Can't find a wrapper */
1419 return NULL;
1420}
14061421
14071422#endif // defined(VGP_amd64_linux)
14081423
  
1
2/*--------------------------------------------------------------------*/
3/*--- Platform-specific syscalls stuff. syswrap-arm-linux.c -----*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2009 Nicholas Nethercote
11 njn@valgrind.org
12 Copyright (C) 2008-2009 Evan Geller
13 gaze@bea.ms
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31*/
32
33#if defined(VGP_arm_linux)
34
35#include "pub_core_basics.h"
36#include "pub_core_vki.h"
37#include "pub_core_vkiscnums.h"
38#include "pub_core_threadstate.h"
39#include "pub_core_aspacemgr.h"
40#include "pub_core_debuglog.h"
41#include "pub_core_libcbase.h"
42#include "pub_core_libcassert.h"
43#include "pub_core_libcprint.h"
44#include "pub_core_libcproc.h"
45#include "pub_core_libcsignal.h"
46#include "pub_core_options.h"
47#include "pub_core_scheduler.h"
48#include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
49#include "pub_core_signals.h"
50#include "pub_core_syscall.h"
51#include "pub_core_syswrap.h"
52#include "pub_core_tooliface.h"
53#include "pub_core_stacks.h" // VG_(register_stack)
54
55#include "priv_types_n_macros.h"
56#include "priv_syswrap-generic.h" /* for decls of generic wrappers */
57#include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
58#include "priv_syswrap-main.h"
59
60
61/* ---------------------------------------------------------------------
62 clone() handling
63 ------------------------------------------------------------------ */
64
65/* Call f(arg1), but first switch stacks, using 'stack' as the new
66 stack, and use 'retaddr' as f's return-to address. Also, clear all
67 the integer registers before entering f.*/
68__attribute__((noreturn))
69void ML_(call_on_new_stack_0_1) ( Addr stack,
70 Addr retaddr,
71 void (*f)(Word),
72 Word arg1 );
73// r0 = stack
74// r1 = retaddr
75// r2 = f
76// r3 = arg1
77asm(
78".text\n"
79".globl vgModuleLocal_call_on_new_stack_0_1\n"
80"vgModuleLocal_call_on_new_stack_0_1:\n"
81" mov sp,r0\n\t" /* Stack pointer */
82" mov lr,r1\n\t" /* Return address */
83" mov r0,r3\n\t" /* First argument */
84" push {r2}\n\t" /* So we can ret to the new dest */
85" mov r1, #0\n\t" /* Clear our GPRs */
86" mov r2, #0\n\t"
87" mov r3, #0\n\t"
88" mov r4, #0\n\t"
89" mov r5, #0\n\t"
90" mov r6, #0\n\t"
91" mov r7, #0\n\t"
92" mov r8, #0\n\t"
93" mov r9, #0\n\t"
94" mov r10, #0\n\t"
95" mov r11, #0\n\t"
96" mov r12, #0\n\t"
97" pop {pc}\n\t" /* Herrre we go! */
98".previous\n"
99);
100
101
102#define __NR_CLONE VG_STRINGIFY(__NR_clone)
103#define __NR_EXIT VG_STRINGIFY(__NR_exit)
104
105extern
106ULong do_syscall_clone_arm_linux ( Word (*fn)(void *),
107 void* stack,
108 Int flags,
109 void* arg,
110 Int* child_tid,
111 Int* parent_tid,
112 void* tls );
113asm(
114".text\n"
115"do_syscall_clone_arm_linux:\n"
116
117/*Setup child stack */
118" str r0, [r1, #-4]!\n"
119" str r3, [r1, #-4]!\n"
120" push {r4,r7}\n"
121" mov r0, r2\n" /* arg1: flags */
122/* r1 (arg2) is already our child's stack */
123" ldr r2, [sp, #12]\n" // parent tid
124" ldr r3, [sp, #16]\n" // tls
125" ldr r4, [sp, #8]\n" // Child tid
126" mov r7, #"__NR_CLONE"\n"
127" svc 0x00000000\n"
128" cmp r0, #0\n"
129" beq 1f\n"
130
131/* Parent */
132" pop {r4,r7}\n"
133" bx lr\n"
134
135"1:\n" /*child*/
136" mov lr, pc\n"
137" pop {r0,pc}\n"
138/* Retval from child is already in r0 */
139" mov r7, #"__NR_EXIT"\n"
140" svc 0x00000000\n"
141/* Urh.. why did exit return? */
142" .long 0\n"
143" .previous\n"
144);
145
146#undef __NR_CLONE
147#undef __NR_EXIT
148
149// forward declarations
150static void setup_child ( ThreadArchState*, ThreadArchState* );
151static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr );
152
153/*
154 When a client clones, we need to keep track of the new thread. This means:
155 1. allocate a ThreadId+ThreadState+stack for the the thread
156
157 2. initialize the thread's new VCPU state
158
159 3. create the thread using the same args as the client requested,
160 but using the scheduler entrypoint for IP, and a separate stack
161 for SP.
162 */
163static SysRes do_clone ( ThreadId ptid,
164 UInt flags, Addr sp,
165 Int *parent_tidptr,
166 Int *child_tidptr,
167 Addr child_tls)
168{
169 const Bool debug = False;
170
171 ThreadId ctid = VG_(alloc_ThreadState)();
172 ThreadState* ptst = VG_(get_ThreadState)(ptid);
173 ThreadState* ctst = VG_(get_ThreadState)(ctid);
174 UInt r0;
175 UWord *stack;
176 NSegment const* seg;
177 SysRes res;
178 vki_sigset_t blockall, savedmask;
179
180 VG_(sigfillset)(&blockall);
181
182 vg_assert(VG_(is_running_thread)(ptid));
183 vg_assert(VG_(is_valid_tid)(ctid));
184
185 stack = (UWord*)ML_(allocstack)(ctid);
186
187 if(stack == NULL) {
188 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
189 goto out;
190 }
191
192 setup_child( &ctst->arch, &ptst->arch );
193
194 ctst->arch.vex.guest_R0 = 0;
195 if(sp != 0)
196 ctst->arch.vex.guest_R13 = sp;
197
198 ctst->os_state.parent = ptid;
199
200 ctst->sig_mask = ptst->sig_mask;
201 ctst->tmp_sig_mask = ptst->sig_mask;
202
203 seg = VG_(am_find_nsegment)((Addr)sp);
204 if (seg && seg->kind != SkResvn) {
205 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
206 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
207
208 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
209
210 if (debug)
211 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
212 ctid, seg->start, VG_PGROUNDUP(sp));
213 } else {
214 VG_(message)(Vg_UserMsg, "!? New thread %d starts with sp+%#lx) unmapped\n", ctid, sp);
215 ctst->client_stack_szB = 0;
216 }
217
218 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
219
220 if (flags & VKI_CLONE_SETTLS) {
221 res = sys_set_tls(ctid, child_tls);
222 if (sr_isError(res))
223 goto out;
224 }
225
226 flags &= ~VKI_CLONE_SETTLS;
227
228 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
229
230 r0 = do_syscall_clone_arm_linux(
231 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
232 child_tidptr, parent_tidptr, NULL
233 );
234 //VG_(printf)("AFTER SYSCALL, %x and %x CHILD: %d PARENT: %d\n",child_tidptr, parent_tidptr,*child_tidptr,*parent_tidptr);
235
236 res = VG_(mk_SysRes_arm_linux)( r0 );
237
238 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
239
240out:
241 if (sr_isError(res)) {
242 VG_(cleanup_thread)(&ctst->arch);
243 ctst->status = VgTs_Empty;
244 VG_TRACK( pre_thread_ll_exit, ctid );
245 }
246
247 return res;
248}
249
250
251
252/* ---------------------------------------------------------------------
253 More thread stuff
254 ------------------------------------------------------------------ */
255
256// ARM doesn't have any architecture specific thread stuff that
257// needs to be cleaned up
258void VG_(cleanup_thread) ( ThreadArchState* arch )
259{
260}
261
262void setup_child ( /*OUT*/ ThreadArchState *child,
263 /*IN*/ ThreadArchState *parent )
264{
265 child->vex = parent->vex;
266 child->vex_shadow1 = parent->vex_shadow1;
267 child->vex_shadow2 = parent->vex_shadow2;
268}
269
270static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
271{
272 VG_(threads)[tid].arch.vex.guest_TPIDRURO = tlsptr;
273 return VG_(mk_SysRes_Success)( 0 );
274}
275
276/* ---------------------------------------------------------------------
277 PRE/POST wrappers for arm/Linux-specific syscalls
278 ------------------------------------------------------------------ */
279
280#define PRE(name) DEFN_PRE_TEMPLATE(arm_linux, name)
281#define POST(name) DEFN_POST_TEMPLATE(arm_linux, name)
282
283/* Add prototypes for the wrappers declared here, so that gcc doesn't
284 harass us for not having prototypes. Really this is a kludge --
285 the right thing to do is to make these wrappers 'static' since they
286 aren't visible outside this file, but that requires even more macro
287 magic. */
288
289DECL_TEMPLATE(arm_linux, sys_socketcall);
290DECL_TEMPLATE(arm_linux, sys_socket);
291DECL_TEMPLATE(arm_linux, sys_setsockopt);
292DECL_TEMPLATE(arm_linux, sys_getsockopt);
293DECL_TEMPLATE(arm_linux, sys_connect);
294DECL_TEMPLATE(arm_linux, sys_accept);
295DECL_TEMPLATE(arm_linux, sys_sendto);
296DECL_TEMPLATE(arm_linux, sys_recvfrom);
297//XXX: Semaphore code ripped from AMD64.
298DECL_TEMPLATE(arm_linux, sys_semget);
299DECL_TEMPLATE(arm_linux, sys_semop);
300DECL_TEMPLATE(arm_linux, sys_semctl);
301DECL_TEMPLATE(arm_linux, sys_semtimedop);
302//XXX: Shared memory code ripped from AMD64
303//
304DECL_TEMPLATE(arm_linux, wrap_sys_shmat);
305DECL_TEMPLATE(arm_linux, sys_shmget);
306DECL_TEMPLATE(arm_linux, sys_shmdt);
307DECL_TEMPLATE(arm_linux, sys_shmctl);
308DECL_TEMPLATE(arm_linux, sys_sendmsg);
309DECL_TEMPLATE(arm_linux, sys_recvmsg);
310//msg* code from AMD64
311DECL_TEMPLATE(arm_linux, sys_msgget);
312DECL_TEMPLATE(arm_linux, sys_msgrcv);
313DECL_TEMPLATE(arm_linux, sys_msgsnd);
314DECL_TEMPLATE(arm_linux, sys_msgctl);
315DECL_TEMPLATE(arm_linux, sys_shutdown);
316DECL_TEMPLATE(arm_linux, sys_bind);
317DECL_TEMPLATE(arm_linux, sys_listen);
318DECL_TEMPLATE(arm_linux, sys_getsockname);
319DECL_TEMPLATE(arm_linux, sys_getpeername);
320DECL_TEMPLATE(arm_linux, sys_socketpair);
321DECL_TEMPLATE(arm_linux, sys_send);
322DECL_TEMPLATE(arm_linux, sys_recv);
323DECL_TEMPLATE(arm_linux, sys_mmap);
324DECL_TEMPLATE(arm_linux, sys_mmap2);
325DECL_TEMPLATE(arm_linux, sys_stat64);
326DECL_TEMPLATE(arm_linux, sys_lstat64);
327DECL_TEMPLATE(arm_linux, sys_fstatat64);
328DECL_TEMPLATE(arm_linux, sys_fstat64);
329DECL_TEMPLATE(arm_linux, sys_ipc);
330DECL_TEMPLATE(arm_linux, sys_clone);
331DECL_TEMPLATE(arm_linux, sys_sigreturn);
332DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
333DECL_TEMPLATE(arm_linux, sys_sigaction);
334DECL_TEMPLATE(arm_linux, sys_sigsuspend);
335DECL_TEMPLATE(arm_linux, sys_set_tls);
336DECL_TEMPLATE(arm_linux, sys_cacheflush);
337
338PRE(sys_socketcall)
339{
340# define ARG2_0 (((UWord*)ARG2)[0])
341# define ARG2_1 (((UWord*)ARG2)[1])
342# define ARG2_2 (((UWord*)ARG2)[2])
343# define ARG2_3 (((UWord*)ARG2)[3])
344# define ARG2_4 (((UWord*)ARG2)[4])
345# define ARG2_5 (((UWord*)ARG2)[5])
346
347 *flags |= SfMayBlock;
348 PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
349 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
350
351 switch (ARG1 /* request */) {
352
353 case VKI_SYS_SOCKETPAIR:
354 /* int socketpair(int d, int type, int protocol, int sv[2]); */
355 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
356 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
357 break;
358
359 case VKI_SYS_SOCKET:
360 /* int socket(int domain, int type, int protocol); */
361 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
362 break;
363
364 case VKI_SYS_BIND:
365 /* int bind(int sockfd, struct sockaddr *my_addr,
366 int addrlen); */
367 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
368 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
369 break;
370
371 case VKI_SYS_LISTEN:
372 /* int listen(int s, int backlog); */
373 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
374 break;
375
376 case VKI_SYS_ACCEPT: {
377 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
378 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
379 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
380 break;
381 }
382
383 case VKI_SYS_SENDTO:
384 /* int sendto(int s, const void *msg, int len,
385 unsigned int flags,
386 const struct sockaddr *to, int tolen); */
387 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
388 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
389 ARG2_3, ARG2_4, ARG2_5 );
390 break;
391
392 case VKI_SYS_SEND:
393 /* int send(int s, const void *msg, size_t len, int flags); */
394 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
395 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
396 break;
397
398 case VKI_SYS_RECVFROM:
399 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
400 struct sockaddr *from, int *fromlen); */
401 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
402 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
403 ARG2_3, ARG2_4, ARG2_5 );
404 break;
405
406 case VKI_SYS_RECV:
407 /* int recv(int s, void *buf, int len, unsigned int flags); */
408 /* man 2 recv says:
409 The recv call is normally used only on a connected socket
410 (see connect(2)) and is identical to recvfrom with a NULL
411 from parameter.
412 */
413 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
414 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
415 break;
416
417 case VKI_SYS_CONNECT:
418 /* int connect(int sockfd,
419 struct sockaddr *serv_addr, int addrlen ); */
420 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
421 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
422 break;
423
424 case VKI_SYS_SETSOCKOPT:
425 /* int setsockopt(int s, int level, int optname,
426 const void *optval, int optlen); */
427 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
428 ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
429 ARG2_3, ARG2_4 );
430 break;
431
432 case VKI_SYS_GETSOCKOPT:
433 /* int getsockopt(int s, int level, int optname,
434 void *optval, socklen_t *optlen); */
435 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
436 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
437 ARG2_3, ARG2_4 );
438 break;
439
440 case VKI_SYS_GETSOCKNAME:
441 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
442 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
443 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
444 break;
445
446 case VKI_SYS_GETPEERNAME:
447 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
448 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
449 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
450 break;
451
452 case VKI_SYS_SHUTDOWN:
453 /* int shutdown(int s, int how); */
454 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
455 break;
456
457 case VKI_SYS_SENDMSG: {
458 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
459
460 /* this causes warnings, and I don't get why. glibc bug?
461 * (after all it's glibc providing the arguments array)
462 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
463 */
464 ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
465 break;
466 }
467
468 case VKI_SYS_RECVMSG: {
469 /* int recvmsg(int s, struct msghdr *msg, int flags); */
470
471 /* this causes warnings, and I don't get why. glibc bug?
472 * (after all it's glibc providing the arguments array)
473 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
474 */
475 ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
476 break;
477 }
478
479 default:
480 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx",ARG1);
481 SET_STATUS_Failure( VKI_EINVAL );
482 break;
483 }
484# undef ARG2_0
485# undef ARG2_1
486# undef ARG2_2
487# undef ARG2_3
488# undef ARG2_4
489# undef ARG2_5
490}
491
492POST(sys_socketcall)
493{
494# define ARG2_0 (((UWord*)ARG2)[0])
495# define ARG2_1 (((UWord*)ARG2)[1])
496# define ARG2_2 (((UWord*)ARG2)[2])
497# define ARG2_3 (((UWord*)ARG2)[3])
498# define ARG2_4 (((UWord*)ARG2)[4])
499# define ARG2_5 (((UWord*)ARG2)[5])
500
501 SysRes r;
502 vg_assert(SUCCESS);
503 switch (ARG1 /* request */) {
504
505 case VKI_SYS_SOCKETPAIR:
506 r = ML_(generic_POST_sys_socketpair)(
507 tid, VG_(mk_SysRes_Success)(RES),
508 ARG2_0, ARG2_1, ARG2_2, ARG2_3
509 );
510 SET_STATUS_from_SysRes(r);
511 break;
512
513 case VKI_SYS_SOCKET:
514 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
515 SET_STATUS_from_SysRes(r);
516 break;
517
518 case VKI_SYS_BIND:
519 /* int bind(int sockfd, struct sockaddr *my_addr,
520 int addrlen); */
521 break;
522
523 case VKI_SYS_LISTEN:
524 /* int listen(int s, int backlog); */
525 break;
526
527 case VKI_SYS_ACCEPT:
528 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
529 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
530 ARG2_0, ARG2_1, ARG2_2 );
531 SET_STATUS_from_SysRes(r);
532 break;
533
534 case VKI_SYS_SENDTO:
535 break;
536
537 case VKI_SYS_SEND:
538 break;
539
540 case VKI_SYS_RECVFROM:
541 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
542 ARG2_0, ARG2_1, ARG2_2,
543 ARG2_3, ARG2_4, ARG2_5 );
544 break;
545
546 case VKI_SYS_RECV:
547 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
548 break;
549
550 case VKI_SYS_CONNECT:
551 break;
552
553 case VKI_SYS_SETSOCKOPT:
554 break;
555
556 case VKI_SYS_GETSOCKOPT:
557 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
558 ARG2_0, ARG2_1,
559 ARG2_2, ARG2_3, ARG2_4 );
560 break;
561
562 case VKI_SYS_GETSOCKNAME:
563 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
564 ARG2_0, ARG2_1, ARG2_2 );
565 break;
566
567 case VKI_SYS_GETPEERNAME:
568 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
569 ARG2_0, ARG2_1, ARG2_2 );
570 break;
571
572 case VKI_SYS_SHUTDOWN:
573 break;
574
575 case VKI_SYS_SENDMSG:
576 break;
577
578 case VKI_SYS_RECVMSG:
579 ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
580 break;
581
582 default:
583 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx",ARG1);
584 VG_(core_panic)("... bye!\n");
585 break; /*NOTREACHED*/
586 }
587# undef ARG2_0
588# undef ARG2_1
589# undef ARG2_2
590# undef ARG2_3
591# undef ARG2_4
592# undef ARG2_5
593}
594
595PRE(sys_socket)
596{
597 PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
598 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
599}
600POST(sys_socket)
601{
602 SysRes r;
603 vg_assert(SUCCESS);
604 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
605 SET_STATUS_from_SysRes(r);
606}
607
608PRE(sys_setsockopt)
609{
610 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
611 PRE_REG_READ5(long, "setsockopt",
612 int, s, int, level, int, optname,
613 const void *, optval, int, optlen);
614 ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
615}
616
617PRE(sys_getsockopt)
618{
619 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
620 PRE_REG_READ5(long, "getsockopt",
621 int, s, int, level, int, optname,
622 void *, optval, int, *optlen);
623 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
624}
625POST(sys_getsockopt)
626{
627 vg_assert(SUCCESS);
628 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
629 ARG1,ARG2,ARG3,ARG4,ARG5);
630}
631
632PRE(sys_connect)
633{
634 *flags |= SfMayBlock;
635 PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
636 PRE_REG_READ3(long, "connect",
637 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
638 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
639}
640
641PRE(sys_accept)
642{
643 *flags |= SfMayBlock;
644 PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
645 PRE_REG_READ3(long, "accept",
646 int, s, struct sockaddr *, addr, int, *addrlen);
647 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
648}
649POST(sys_accept)
650{
651 SysRes r;
652 vg_assert(SUCCESS);
653 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
654 ARG1,ARG2,ARG3);
655 SET_STATUS_from_SysRes(r);
656}
657
658PRE(sys_sendto)
659{
660 *flags |= SfMayBlock;
661 PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
662 PRE_REG_READ6(long, "sendto",
663 int, s, const void *, msg, int, len,
664 unsigned int, flags,
665 const struct sockaddr *, to, int, tolen);
666 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
667}
668
669PRE(sys_recvfrom)
670{
671 *flags |= SfMayBlock;
672 PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
673 PRE_REG_READ6(long, "recvfrom",
674 int, s, void *, buf, int, len, unsigned int, flags,
675 struct sockaddr *, from, int *, fromlen);
676 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
677}
678POST(sys_recvfrom)
679{
680 vg_assert(SUCCESS);
681 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
682 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
683}
684
685PRE(sys_sendmsg)
686{
687 *flags |= SfMayBlock;
688 PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
689 PRE_REG_READ3(long, "sendmsg",
690 int, s, const struct msghdr *, msg, int, flags);
691 ML_(generic_PRE_sys_sendmsg)(tid, ARG1,ARG2);
692}
693
694PRE(sys_recvmsg)
695{
696 *flags |= SfMayBlock;
697 PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
698 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
699 ML_(generic_PRE_sys_recvmsg)(tid, ARG1,ARG2);
700}
701POST(sys_recvmsg)
702{
703 ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
704}
705
706//XXX: Semaphore code ripped from AMD64.
707PRE(sys_semget)
708{
709 PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
710 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
711}
712
713PRE(sys_semop)
714{
715 *flags |= SfMayBlock;
716 PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
717 PRE_REG_READ3(long, "semop",
718 int, semid, struct sembuf *, sops, unsigned, nsoops);
719 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
720}
721
722PRE(sys_semctl)
723{
724 switch (ARG3 & ~VKI_IPC_64) {
725 case VKI_IPC_INFO:
726 case VKI_SEM_INFO:
727 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
728 PRE_REG_READ4(long, "semctl",
729 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
730 break;
731 case VKI_IPC_STAT:
732 case VKI_SEM_STAT:
733 case VKI_IPC_SET:
734 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
735 PRE_REG_READ4(long, "semctl",
736 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
737 break;
738 case VKI_GETALL:
739 case VKI_SETALL:
740 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
741 PRE_REG_READ4(long, "semctl",
742 int, semid, int, semnum, int, cmd, unsigned short *, arg);
743 break;
744 default:
745 PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
746 PRE_REG_READ3(long, "semctl",
747 int, semid, int, semnum, int, cmd);
748 break;
749 }
750 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
751}
752
753POST(sys_semctl)
754{
755 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
756}
757
758PRE(sys_semtimedop)
759{
760 *flags |= SfMayBlock;
761 PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
762 PRE_REG_READ4(long, "semtimedop",
763 int, semid, struct sembuf *, sops, unsigned, nsoops,
764 struct timespec *, timeout);
765 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
766}
767
768//amd64
769PRE(sys_msgget)
770{
771 PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
772 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
773}
774
775PRE(sys_msgsnd)
776{
777 PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
778 PRE_REG_READ4(long, "msgsnd",
779 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
780 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
781 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
782 *flags |= SfMayBlock;
783}
784
785PRE(sys_msgrcv)
786{
787 PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
788 PRE_REG_READ5(long, "msgrcv",
789 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
790 long, msgytp, int, msgflg);
791 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
792 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
793 *flags |= SfMayBlock;
794}
795POST(sys_msgrcv)
796{
797 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
798}
799
800
801PRE(sys_msgctl)
802{
803 PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
804 PRE_REG_READ3(long, "msgctl",
805 int, msqid, int, cmd, struct msqid_ds *, buf);
806 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
807}
808POST(sys_msgctl)
809{
810 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
811}
812
813//shared memory code from AMD64
814PRE(sys_shmget)
815{
816 PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
817 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
818}
819
820PRE(wrap_sys_shmat)
821{
822 UWord arg2tmp;
823 PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
824 PRE_REG_READ3(long, "shmat",
825 int, shmid, const void *, shmaddr, int, shmflg);
826 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
827 if (arg2tmp == 0)
828 SET_STATUS_Failure( VKI_EINVAL );
829 else
830 ARG2 = arg2tmp;
831}
832
833POST(wrap_sys_shmat)
834{
835 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
836}
837
838PRE(sys_shmdt)
839{
840 PRINT("sys_shmdt ( %#lx )",ARG1);
841 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
842 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
843 SET_STATUS_Failure( VKI_EINVAL );
844}
845
846POST(sys_shmdt)
847{
848 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
849}
850
851PRE(sys_shmctl)
852{
853 PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
854 PRE_REG_READ3(long, "shmctl",
855 int, shmid, int, cmd, struct shmid_ds *, buf);
856 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
857}
858
859POST(sys_shmctl)
860{
861 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
862}
863
864PRE(sys_shutdown)
865{
866 *flags |= SfMayBlock;
867 PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
868 PRE_REG_READ2(int, "shutdown", int, s, int, how);
869}
870
871PRE(sys_bind)
872{
873 PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
874 PRE_REG_READ3(long, "bind",
875 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
876 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
877}
878
879PRE(sys_listen)
880{
881 PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
882 PRE_REG_READ2(long, "listen", int, s, int, backlog);
883}
884
885PRE(sys_getsockname)
886{
887 PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
888 PRE_REG_READ3(long, "getsockname",
889 int, s, struct sockaddr *, name, int *, namelen);
890 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
891}
892POST(sys_getsockname)
893{
894 vg_assert(SUCCESS);
895 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
896 ARG1,ARG2,ARG3);
897}
898
899PRE(sys_getpeername)
900{
901 PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
902 PRE_REG_READ3(long, "getpeername",
903 int, s, struct sockaddr *, name, int *, namelen);
904 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
905}
906POST(sys_getpeername)
907{
908 vg_assert(SUCCESS);
909 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
910 ARG1,ARG2,ARG3);
911}
912
913PRE(sys_socketpair)
914{
915 PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
916 PRE_REG_READ4(long, "socketpair",
917 int, d, int, type, int, protocol, int [2], sv);
918 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
919}
920POST(sys_socketpair)
921{
922 vg_assert(SUCCESS);
923 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
924 ARG1,ARG2,ARG3,ARG4);
925}
926
927PRE(sys_send)
928{
929 *flags |= SfMayBlock;
930 PRINT("sys_send ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
931 PRE_REG_READ4(long, "send",
932 int, s, const void *, msg, int, len,
933 unsigned int, flags);
934
935 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
936}
937
938PRE(sys_recv)
939{
940 *flags |= SfMayBlock;
941 PRINT("sys_recv ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
942 PRE_REG_READ4(long, "recv",
943 int, s, void *, buf, int, len, unsigned int, flags);
944 ML_(generic_PRE_sys_recv)( tid, ARG1, ARG2, ARG3 );
945}
946
947POST(sys_recv)
948{
949 ML_(generic_POST_sys_recv)( tid, RES, ARG1, ARG2, ARG3 );
950}
951
952PRE(sys_mmap)
953{
954 I_die_here;
955}
956
957PRE(sys_mmap2)
958{
959 SysRes r;
960
961 // Exactly like old_mmap() except:
962 // - all 6 args are passed in regs, rather than in a memory-block.
963 // - the file offset is specified in pagesize units rather than bytes,
964 // so that it can be used for files bigger than 2^32 bytes.
965 // pagesize or 4K-size units in offset? For ppc32/64-linux, this is
966 // 4K-sized. Assert that the page size is 4K here for safety.
967 vg_assert(VKI_PAGE_SIZE == 4096);
968 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
969 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
970 PRE_REG_READ6(long, "mmap2",
971 unsigned long, start, unsigned long, length,
972 unsigned long, prot, unsigned long, flags,
973 unsigned long, fd, unsigned long, offset);
974
975 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
976 4096 * (Off64T)ARG6 );
977 SET_STATUS_from_SysRes(r);
978}
979
980// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
981// applicable to every architecture -- I think only to 32-bit archs.
982// We're going to need something like linux/core_os32.h for such
983// things, eventually, I think. --njn
984PRE(sys_lstat64)
985{
986 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
987 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
988 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
989 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
990}
991
992POST(sys_lstat64)
993{
994 vg_assert(SUCCESS);
995 if (RES == 0) {
996 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
997 }
998}
999
1000PRE(sys_stat64)
1001{
1002 PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
1003 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
1004 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
1005 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
1006}
1007
1008POST(sys_stat64)
1009{
1010 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1011}
1012
1013PRE(sys_fstatat64)
1014{
1015 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
1016 PRE_REG_READ3(long, "fstatat64",
1017 int, dfd, char *, file_name, struct stat64 *, buf);
1018 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
1019 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
1020}
1021
1022POST(sys_fstatat64)
1023{
1024 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
1025}
1026
1027PRE(sys_fstat64)
1028{
1029 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
1030 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
1031 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1032}
1033
1034POST(sys_fstat64)
1035{
1036 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1037}
1038
1039
1040PRE(sys_ipc)
1041{
1042 I_die_here;
1043}
1044
1045POST(sys_ipc)
1046{
1047 I_die_here;
1048}
1049
1050PRE(sys_clone)
1051{
1052 UInt cloneflags;
1053
1054 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
1055 PRE_REG_READ5(int, "clone",
1056 unsigned long, flags,
1057 void *, child_stack,
1058 int *, parent_tidptr,
1059 void *, child_tls,
1060 int *, child_tidptr);
1061
1062 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
1063 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
1064 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
1065 VKI_PROT_WRITE)) {
1066 SET_STATUS_Failure( VKI_EFAULT );
1067 return;
1068 }
1069 }
1070 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
1071 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
1072 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
1073 VKI_PROT_WRITE)) {
1074 SET_STATUS_Failure( VKI_EFAULT );
1075 return;
1076 }
1077 }
1078 if (ARG1 & VKI_CLONE_SETTLS) {
1079 PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
1080 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
1081 VKI_PROT_READ)) {
1082 SET_STATUS_Failure( VKI_EFAULT );
1083 return;
1084 }
1085 }
1086
1087 cloneflags = ARG1;
1088
1089 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
1090 SET_STATUS_Failure( VKI_EINVAL );
1091 return;
1092 }
1093
1094 /* Only look at the flags we really care about */
1095 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
1096 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
1097 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
1098 /* thread creation */
1099 SET_STATUS_from_SysRes(
1100 do_clone(tid,
1101 ARG1, /* flags */
1102 (Addr)ARG2, /* child ESP */
1103 (Int *)ARG3, /* parent_tidptr */
1104 (Int *)ARG5, /* child_tidptr */
1105 (Addr)ARG4)); /* set_tls */
1106 break;
1107
1108 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
1109 /* FALLTHROUGH - assume vfork == fork */
1110 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
1111
1112 case 0: /* plain fork */
1113 SET_STATUS_from_SysRes(
1114 ML_(do_fork_clone)(tid,
1115 cloneflags, /* flags */
1116 (Int *)ARG3, /* parent_tidptr */
1117 (Int *)ARG5)); /* child_tidptr */
1118 break;
1119
1120 default:
1121 /* should we just ENOSYS? */
1122 VG_(message)(Vg_UserMsg, "");
1123 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
1124 VG_(message)(Vg_UserMsg, "");
1125 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
1126 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
1127 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
1128 VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver");
1129 VG_(unimplemented)
1130 ("Valgrind does not support general clone().");
1131 }
1132
1133 if (SUCCESS) {
1134 if (ARG1 & VKI_CLONE_PARENT_SETTID)
1135 POST_MEM_WRITE(ARG3, sizeof(Int));
1136 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
1137 POST_MEM_WRITE(ARG5, sizeof(Int));
1138
1139 /* Thread creation was successful; let the child have the chance
1140 to run */
1141 *flags |= SfYieldAfter;
1142 }
1143}
1144
1145PRE(sys_sigreturn)
1146{
1147 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1148 an explanation of what follows. */
1149
1150 PRINT("sys_sigreturn ( )");
1151
1152 vg_assert(VG_(is_valid_tid)(tid));
1153 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1154 vg_assert(VG_(is_running_thread)(tid));
1155
1156 /* Restore register state from frame and remove it */
1157 VG_(sigframe_destroy)(tid, False);
1158
1159 /* Tell the driver not to update the guest state with the "result",
1160 and set a bogus result to keep it happy. */
1161 *flags |= SfNoWriteResult;
1162 SET_STATUS_Success(0);
1163
1164 /* Check to see if any signals arose as a result of this. */
1165 *flags |= SfPollAfter;
1166}
1167
1168PRE(sys_rt_sigreturn)
1169{
1170 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1171 an explanation of what follows. */
1172
1173 PRINT("rt_sigreturn ( )");
1174
1175 vg_assert(VG_(is_valid_tid)(tid));
1176 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1177 vg_assert(VG_(is_running_thread)(tid));
1178
1179 /* Restore register state from frame and remove it */
1180 VG_(sigframe_destroy)(tid, True);
1181
1182 /* Tell the driver not to update the guest state with the "result",
1183 and set a bogus result to keep it happy. */
1184 *flags |= SfNoWriteResult;
1185 SET_STATUS_Success(0);
1186
1187 /* Check to see if any signals arose as a result of this. */
1188 *flags |= SfPollAfter;
1189}
1190
1191PRE(sys_sigaction)
1192{
1193 I_die_here;
1194}
1195
1196POST(sys_sigaction)
1197{ I_die_here;
1198}
1199
1200PRE(sys_sigsuspend)
1201{ I_die_here;
1202}
1203
1204/* Very much ARM specific */
1205
1206PRE(sys_set_tls)
1207{
1208 PRE_REG_READ1(long, "set_tls", unsigned long, addr);
1209
1210 SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
1211}
1212
1213PRE(sys_cacheflush)
1214{
1215 PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3);
1216 PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags);
1217}
1218
1219
1220#undef PRE
1221#undef POST
1222
1223/* ---------------------------------------------------------------------
1224 The arm/Linux syscall table
1225 ------------------------------------------------------------------ */
1226
1227#if 0
1228#define __NR_OABI_SYSCALL_BASE 0x900000
1229#else
1230#define __NR_OABI_SYSCALL_BASE 0x0
1231#endif
1232
1233#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(arm_linux, sysno, name)
1234#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(arm_linux, sysno, name)
1235
1236// This table maps from __NR_xxx syscall numbers (from
1237// linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo()
1238// wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S).
1239//
1240// For those syscalls not handled by Valgrind, the annotation indicate its
1241// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1242// (unknown).
1243
1244static SyscallTableEntry syscall_main_table[] = {
1245//zz // (restart_syscall) // 0
1246 GENX_(__NR_exit, sys_exit), // 1
1247 GENX_(__NR_fork, sys_fork), // 2
1248 GENXY(__NR_read, sys_read), // 3
1249 GENX_(__NR_write, sys_write), // 4
1250
1251 GENXY(__NR_open, sys_open), // 5
1252 GENXY(__NR_close, sys_close), // 6
1253// GENXY(__NR_waitpid, sys_waitpid), // 7
1254 GENXY(__NR_creat, sys_creat), // 8
1255 GENX_(__NR_link, sys_link), // 9
1256
1257 GENX_(__NR_unlink, sys_unlink), // 10
1258 GENX_(__NR_execve, sys_execve), // 11
1259 GENX_(__NR_chdir, sys_chdir), // 12
1260 GENXY(__NR_time, sys_time), // 13
1261 GENX_(__NR_mknod, sys_mknod), // 14
1262
1263 GENX_(__NR_chmod, sys_chmod), // 15
1264//zz LINX_(__NR_lchown, sys_lchown16), // 16
1265// GENX_(__NR_break, sys_ni_syscall), // 17
1266//zz // (__NR_oldstat, sys_stat), // 18 (obsolete)
1267 LINX_(__NR_lseek, sys_lseek), // 19
1268
1269 GENX_(__NR_getpid, sys_getpid), // 20
1270 LINX_(__NR_mount, sys_mount), // 21
1271 LINX_(__NR_umount, sys_oldumount), // 22
1272 LINX_(__NR_setuid, sys_setuid16), // 23 ## P
1273 LINX_(__NR_getuid, sys_getuid16), // 24 ## P
1274//zz
1275//zz // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
1276// PLAXY(__NR_ptrace, sys_ptrace), // 26
1277 GENX_(__NR_alarm, sys_alarm), // 27
1278//zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
1279 GENX_(__NR_pause, sys_pause), // 29
1280
1281 LINX_(__NR_utime, sys_utime), // 30
1282// GENX_(__NR_stty, sys_ni_syscall), // 31
1283// GENX_(__NR_gtty, sys_ni_syscall), // 32
1284 GENX_(__NR_access, sys_access), // 33
1285 GENX_(__NR_nice, sys_nice), // 34
1286
1287// GENX_(__NR_ftime, sys_ni_syscall), // 35
1288 GENX_(__NR_sync, sys_sync), // 36
1289 GENX_(__NR_kill, sys_kill), // 37
1290 GENX_(__NR_rename, sys_rename), // 38
1291 GENX_(__NR_mkdir, sys_mkdir), // 39
1292
1293 GENX_(__NR_rmdir, sys_rmdir), // 40
1294 GENXY(__NR_dup, sys_dup), // 41
1295 LINXY(__NR_pipe, sys_pipe), // 42
1296 GENXY(__NR_times, sys_times), // 43
1297// GENX_(__NR_prof, sys_ni_syscall), // 44
1298//zz
1299 GENX_(__NR_brk, sys_brk), // 45
1300 LINX_(__NR_setgid, sys_setgid16), // 46
1301 LINX_(__NR_getgid, sys_getgid16), // 47
1302//zz // (__NR_signal, sys_signal), // 48 */* (ANSI C)
1303 LINX_(__NR_geteuid, sys_geteuid16), // 49
1304
1305 LINX_(__NR_getegid, sys_getegid16), // 50
1306 GENX_(__NR_acct, sys_acct), // 51
1307 LINX_(__NR_umount2, sys_umount), // 52
1308// GENX_(__NR_lock, sys_ni_syscall), // 53
1309 LINXY(__NR_ioctl, sys_ioctl), // 54
1310
1311 LINXY(__NR_fcntl, sys_fcntl), // 55
1312// GENX_(__NR_mpx, sys_ni_syscall), // 56
1313 GENX_(__NR_setpgid, sys_setpgid), // 57
1314// GENX_(__NR_ulimit, sys_ni_syscall), // 58
1315//zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
1316//zz
1317 GENX_(__NR_umask, sys_umask), // 60
1318 GENX_(__NR_chroot, sys_chroot), // 61
1319//zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
1320 GENXY(__NR_dup2, sys_dup2), // 63
1321 GENX_(__NR_getppid, sys_getppid), // 64
1322
1323 GENX_(__NR_getpgrp, sys_getpgrp), // 65
1324 GENX_(__NR_setsid, sys_setsid), // 66
1325 PLAXY(__NR_sigaction, sys_sigaction), // 67
1326//zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
1327//zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
1328//zz
1329 LINX_(__NR_setreuid, sys_setreuid16), // 70
1330 LINX_(__NR_setregid, sys_setregid16), // 71
1331 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72
1332 LINXY(__NR_sigpending, sys_sigpending), // 73
1333//zz // (__NR_sethostname, sys_sethostname), // 74 */*
1334//zz
1335 GENX_(__NR_setrlimit, sys_setrlimit), // 75
1336 GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
1337 GENXY(__NR_getrusage, sys_getrusage), // 77
1338 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
1339 GENX_(__NR_settimeofday, sys_settimeofday), // 79
1340
1341 LINXY(__NR_getgroups, sys_getgroups16), // 80
1342 LINX_(__NR_setgroups, sys_setgroups16), // 81
1343// PLAX_(__NR_select, old_select), // 82
1344 GENX_(__NR_symlink, sys_symlink), // 83
1345//zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
1346//zz
1347 GENX_(__NR_readlink, sys_readlink), // 85
1348//zz // (__NR_uselib, sys_uselib), // 86 */Linux
1349//zz // (__NR_swapon, sys_swapon), // 87 */Linux
1350//zz // (__NR_reboot, sys_reboot), // 88 */Linux
1351//zz // (__NR_readdir, old_readdir), // 89 -- superseded
1352//zz
1353// PLAX_(__NR_mmap, old_mmap), // 90
1354 GENXY(__NR_munmap, sys_munmap), // 91
1355 GENX_(__NR_truncate, sys_truncate), // 92
1356 GENX_(__NR_ftruncate, sys_ftruncate), // 93
1357 GENX_(__NR_fchmod, sys_fchmod), // 94
1358
1359 LINX_(__NR_fchown, sys_fchown16), // 95
1360 GENX_(__NR_getpriority, sys_getpriority), // 96
1361 GENX_(__NR_setpriority, sys_setpriority), // 97
1362// GENX_(__NR_profil, sys_ni_syscall), // 98
1363 GENXY(__NR_statfs, sys_statfs), // 99
1364
1365 GENXY(__NR_fstatfs, sys_fstatfs), // 100
1366// LINX_(__NR_ioperm, sys_ioperm), // 101
1367 PLAXY(__NR_socketcall, sys_socketcall), // 102
1368 LINXY(__NR_syslog, sys_syslog), // 103
1369 GENXY(__NR_setitimer, sys_setitimer), // 104
1370
1371 GENXY(__NR_getitimer, sys_getitimer), // 105
1372 GENXY(__NR_stat, sys_newstat), // 106
1373 GENXY(__NR_lstat, sys_newlstat), // 107
1374 GENXY(__NR_fstat, sys_newfstat), // 108
1375//zz // (__NR_olduname, sys_uname), // 109 -- obsolete
1376//zz
1377// GENX_(__NR_iopl, sys_iopl), // 110
1378 LINX_(__NR_vhangup, sys_vhangup), // 111
1379// GENX_(__NR_idle, sys_ni_syscall), // 112
1380// PLAXY(__NR_vm86old, sys_vm86old), // 113 __NR_syscall... weird
1381 GENXY(__NR_wait4, sys_wait4), // 114
1382//zz
1383//zz // (__NR_swapoff, sys_swapoff), // 115 */Linux
1384 LINXY(__NR_sysinfo, sys_sysinfo), // 116
1385 PLAXY(__NR_ipc, sys_ipc), // 117
1386 GENX_(__NR_fsync, sys_fsync), // 118
1387 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
1388
1389 PLAX_(__NR_clone, sys_clone), // 120
1390//zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
1391 GENXY(__NR_uname, sys_newuname), // 122
1392// PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
1393//zz LINXY(__NR_adjtimex, sys_adjtimex), // 124
1394//zz
1395 GENXY(__NR_mprotect, sys_mprotect), // 125
1396 // LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
1397//zz // Nb: create_module() was removed 2.4-->2.6
1398// GENX_(__NR_create_module, sys_ni_syscall), // 127
1399 LINX_(__NR_init_module, sys_init_module), // 128
1400 LINX_(__NR_delete_module, sys_delete_module), // 129
1401//zz
1402//zz // Nb: get_kernel_syms() was removed 2.4-->2.6
1403// GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
1404 LINX_(__NR_quotactl, sys_quotactl), // 131
1405 GENX_(__NR_getpgid, sys_getpgid), // 132
1406 GENX_(__NR_fchdir, sys_fchdir), // 133
1407//zz // (__NR_bdflush, sys_bdflush), // 134 */Linux
1408//zz
1409//zz // (__NR_sysfs, sys_sysfs), // 135 SVr4
1410 LINX_(__NR_personality, sys_personality), // 136
1411// GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
1412 LINX_(__NR_setfsuid, sys_setfsuid16), // 138
1413 LINX_(__NR_setfsgid, sys_setfsgid16), // 139
1414
1415 LINXY(__NR__llseek, sys_llseek), // 140
1416 GENXY(__NR_getdents, sys_getdents), // 141
1417 GENX_(__NR__newselect, sys_select), // 142
1418 GENX_(__NR_flock, sys_flock), // 143
1419 GENX_(__NR_msync, sys_msync), // 144
1420
1421 GENXY(__NR_readv, sys_readv), // 145
1422 GENX_(__NR_writev, sys_writev), // 146
1423 GENX_(__NR_getsid, sys_getsid), // 147
1424 GENX_(__NR_fdatasync, sys_fdatasync), // 148
1425 LINXY(__NR__sysctl, sys_sysctl), // 149
1426
1427 GENX_(__NR_mlock, sys_mlock), // 150
1428 GENX_(__NR_munlock, sys_munlock), // 151
1429 GENX_(__NR_mlockall, sys_mlockall), // 152
1430 LINX_(__NR_munlockall, sys_munlockall), // 153
1431 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
1432
1433 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
1434 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
1435 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
1436 LINX_(__NR_sched_yield, sys_sched_yield), // 158
1437 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1438
1439 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1440//zz //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */*
1441 GENXY(__NR_nanosleep, sys_nanosleep), // 162
1442 GENX_(__NR_mremap, sys_mremap), // 163
1443 LINX_(__NR_setresuid, sys_setresuid16), // 164
1444
1445 LINXY(__NR_getresuid, sys_getresuid16), // 165
1446// PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only
1447// GENX_(__NR_query_module, sys_ni_syscall), // 167
1448 GENXY(__NR_poll, sys_poll), // 168
1449//zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux
1450//zz
1451 LINX_(__NR_setresgid, sys_setresgid16), // 170
1452 LINXY(__NR_getresgid, sys_getresgid16), // 171
1453 LINXY(__NR_prctl, sys_prctl), // 172
1454 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173
1455 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
1456
1457 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
1458 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
1459 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177
1460 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178
1461 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
1462
1463 // GENXY(__NR_pread64, sys_pread64_on32bitplat), // 180
1464 //GENX_(__NR_pwrite64, sys_pwrite64_on32bitplat), // 181
1465 LINX_(__NR_chown, sys_chown16), // 182
1466 GENXY(__NR_getcwd, sys_getcwd), // 183
1467 LINXY(__NR_capget, sys_capget), // 184
1468
1469 LINX_(__NR_capset, sys_capset), // 185
1470 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
1471 LINXY(__NR_sendfile, sys_sendfile), // 187
1472// GENXY(__NR_getpmsg, sys_getpmsg), // 188
1473// GENX_(__NR_putpmsg, sys_putpmsg), // 189
1474
1475 // Nb: we treat vfork as fork
1476 GENX_(__NR_vfork, sys_fork), // 190
1477 GENXY(__NR_ugetrlimit, sys_getrlimit), // 191
1478 PLAX_(__NR_mmap2, sys_mmap2), // 192
1479 GENX_(__NR_truncate64, sys_truncate64), // 193
1480 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
1481
1482 PLAXY(__NR_stat64, sys_stat64), // 195
1483 PLAXY(__NR_lstat64, sys_lstat64), // 196
1484 PLAXY(__NR_fstat64, sys_fstat64), // 197
1485 GENX_(__NR_lchown32, sys_lchown), // 198
1486 GENX_(__NR_getuid32, sys_getuid), // 199
1487
1488 GENX_(__NR_getgid32, sys_getgid), // 200
1489 GENX_(__NR_geteuid32, sys_geteuid), // 201
1490 GENX_(__NR_getegid32, sys_getegid), // 202
1491 GENX_(__NR_setreuid32, sys_setreuid), // 203
1492 GENX_(__NR_setregid32, sys_setregid), // 204
1493
1494 GENXY(__NR_getgroups32, sys_getgroups), // 205
1495 GENX_(__NR_setgroups32, sys_setgroups), // 206
1496 GENX_(__NR_fchown32, sys_fchown), // 207
1497 LINX_(__NR_setresuid32, sys_setresuid), // 208
1498 LINXY(__NR_getresuid32, sys_getresuid), // 209
1499
1500 LINX_(__NR_setresgid32, sys_setresgid), // 210
1501 LINXY(__NR_getresgid32, sys_getresgid), // 211
1502 GENX_(__NR_chown32, sys_chown), // 212
1503 GENX_(__NR_setuid32, sys_setuid), // 213
1504 GENX_(__NR_setgid32, sys_setgid), // 214
1505
1506 LINX_(__NR_setfsuid32, sys_setfsuid), // 215
1507 LINX_(__NR_setfsgid32, sys_setfsgid), // 216
1508//zz // (__NR_pivot_root, sys_pivot_root), // 217 */Linux
1509 GENXY(__NR_mincore, sys_mincore), // 218
1510 GENX_(__NR_madvise, sys_madvise), // 219
1511
1512 GENXY(__NR_getdents64, sys_getdents64), // 220
1513 LINXY(__NR_fcntl64, sys_fcntl64), // 221
1514// GENX_(222, sys_ni_syscall), // 222
1515// PLAXY(223, sys_syscall223), // 223 // sys_bproc?
1516 LINX_(__NR_gettid, sys_gettid), // 224
1517
1518//zz // (__NR_readahead, sys_readahead), // 225 */(Linux?)
1519 LINX_(__NR_setxattr, sys_setxattr), // 226
1520 LINX_(__NR_lsetxattr, sys_lsetxattr), // 227
1521 LINX_(__NR_fsetxattr, sys_fsetxattr), // 228
1522 LINXY(__NR_getxattr, sys_getxattr), // 229
1523
1524 LINXY(__NR_lgetxattr, sys_lgetxattr), // 230
1525 LINXY(__NR_fgetxattr, sys_fgetxattr), // 231
1526 LINXY(__NR_listxattr, sys_listxattr), // 232
1527 LINXY(__NR_llistxattr, sys_llistxattr), // 233
1528 LINXY(__NR_flistxattr, sys_flistxattr), // 234
1529
1530 LINX_(__NR_removexattr, sys_removexattr), // 235
1531 LINX_(__NR_lremovexattr, sys_lremovexattr), // 236
1532 LINX_(__NR_fremovexattr, sys_fremovexattr), // 237
1533 LINXY(__NR_tkill, sys_tkill), // 238 */Linux
1534 LINXY(__NR_sendfile64, sys_sendfile64), // 239
1535
1536 LINXY(__NR_futex, sys_futex), // 240
1537 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
1538 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
1539// PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243
1540// PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244
1541
1542 LINXY(__NR_io_setup, sys_io_setup), // 245
1543 LINX_(__NR_io_destroy, sys_io_destroy), // 246
1544 LINXY(__NR_io_getevents, sys_io_getevents), // 247
1545 LINX_(__NR_io_submit, sys_io_submit), // 248
1546 LINXY(__NR_io_cancel, sys_io_cancel), // 249
1547
1548// LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?)
1549 GENX_(251, sys_ni_syscall), // 251
1550 LINX_(__NR_exit_group, sys_exit_group), // 252
1551// GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253
1552 LINXY(__NR_epoll_create, sys_epoll_create), // 254
1553
1554 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255
1555 LINXY(__NR_epoll_wait, sys_epoll_wait), // 256
1556//zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux
1557 LINX_(__NR_set_tid_address, sys_set_tid_address), // 258
1558 LINXY(__NR_timer_create, sys_timer_create), // 259
1559
1560 LINXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1)
1561 LINXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2)
1562 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3)
1563 LINX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4)
1564 LINX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5)
1565
1566 LINXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6)
1567 LINXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7)
1568 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */*
1569 GENXY(__NR_statfs64, sys_statfs64), // 268
1570 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269
1571
1572 LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux
1573 GENX_(__NR_utimes, sys_utimes), // 271
1574// LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?)
1575 GENX_(__NR_vserver, sys_ni_syscall), // 273
1576 LINX_(__NR_mbind, sys_mbind), // 274 ?/?
1577
1578 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/?
1579 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/?
1580 LINXY(__NR_mq_open, sys_mq_open), // 277
1581 LINX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1)
1582 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2)
1583
1584 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3)
1585 LINX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4)
1586 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5)
1587 LINXY(__NR_waitid, sys_waitid), // 280
1588
1589 PLAXY(__NR_socket, sys_socket), // 281
1590 PLAX_(__NR_bind, sys_bind), // 282
1591 PLAX_(__NR_connect, sys_connect), // 283
1592 PLAX_(__NR_listen, sys_listen), // 284
1593 PLAXY(__NR_accept, sys_accept), // 285
1594 PLAXY(__NR_getsockname, sys_getsockname), // 286
1595 PLAXY(__NR_getpeername, sys_getpeername), // 287
1596 PLAXY(__NR_socketpair, sys_socketpair), // 288
1597 PLAX_(__NR_send, sys_send),
1598 PLAX_(__NR_sendto, sys_sendto), // 290
1599 PLAXY(__NR_recv, sys_recv),
1600 PLAXY(__NR_recvfrom, sys_recvfrom), // 292
1601 PLAX_(__NR_shutdown, sys_shutdown), // 293
1602 PLAX_(__NR_setsockopt, sys_setsockopt), // 294
1603 PLAXY(__NR_getsockopt, sys_getsockopt), // 295
1604 PLAX_(__NR_sendmsg, sys_sendmsg), // 296
1605 PLAXY(__NR_recvmsg, sys_recvmsg), // 297
1606 PLAX_(__NR_semop, sys_semop), // 298
1607 PLAX_(__NR_semget, sys_semget), // 299
1608 PLAXY(__NR_semctl, sys_semctl), // 300
1609 PLAX_(__NR_msgget, sys_msgget),
1610 PLAX_(__NR_msgsnd, sys_msgsnd),
1611 PLAXY(__NR_msgrcv, sys_msgrcv),
1612 PLAXY(__NR_msgctl, sys_msgctl), // 304
1613 PLAX_(__NR_semtimedop, sys_semtimedop), // 312
1614
1615 LINX_(__NR_add_key, sys_add_key), // 286
1616 LINX_(__NR_request_key, sys_request_key), // 287
1617 LINXY(__NR_keyctl, sys_keyctl), // not 288...
1618// LINX_(__NR_ioprio_set, sys_ioprio_set), // 289
1619
1620// LINX_(__NR_ioprio_get, sys_ioprio_get), // 290
1621 LINX_(__NR_inotify_init, sys_inotify_init), // 291
1622 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
1623 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293
1624// LINX_(__NR_migrate_pages, sys_migrate_pages), // 294
1625
1626 LINXY(__NR_openat, sys_openat), // 295
1627 LINX_(__NR_mkdirat, sys_mkdirat), // 296
1628 LINX_(__NR_mknodat, sys_mknodat), // 297
1629 LINX_(__NR_fchownat, sys_fchownat), // 298
1630 LINX_(__NR_futimesat, sys_futimesat), // 326 on arm
1631
1632 PLAXY(__NR_fstatat64, sys_fstatat64), // 300
1633 LINX_(__NR_unlinkat, sys_unlinkat), // 301
1634 LINX_(__NR_renameat, sys_renameat), // 302
1635 LINX_(__NR_linkat, sys_linkat), // 303
1636 LINX_(__NR_symlinkat, sys_symlinkat), // 304
1637
1638 LINX_(__NR_readlinkat, sys_readlinkat), //
1639 LINX_(__NR_fchmodat, sys_fchmodat), //
1640 LINX_(__NR_faccessat, sys_faccessat), //
1641 PLAXY(__NR_shmat, wrap_sys_shmat), //305
1642 PLAXY(__NR_shmdt, sys_shmdt), //306
1643 PLAX_(__NR_shmget, sys_shmget), //307
1644 PLAXY(__NR_shmctl, sys_shmctl), // 308
1645// LINX_(__NR_pselect6, sys_pselect6), //
1646// LINXY(__NR_ppoll, sys_ppoll), // 309
1647
1648// LINX_(__NR_unshare, sys_unshare), // 310
1649 LINX_(__NR_set_robust_list, sys_set_robust_list), // 311
1650 LINXY(__NR_get_robust_list, sys_get_robust_list), // 312
1651// LINX_(__NR_splice, sys_ni_syscall), // 313
1652// LINX_(__NR_sync_file_range, sys_sync_file_range), // 314
1653
1654// LINX_(__NR_tee, sys_ni_syscall), // 315
1655// LINX_(__NR_vmsplice, sys_ni_syscall), // 316
1656// LINX_(__NR_move_pages, sys_ni_syscall), // 317
1657// LINX_(__NR_getcpu, sys_ni_syscall), // 318
1658// LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 319
1659
1660 LINX_(__NR_utimensat, sys_utimensat), // 320
1661 LINXY(__NR_signalfd, sys_signalfd), // 321
1662 LINXY(__NR_timerfd_create, sys_timerfd_create), // 322
1663 LINX_(__NR_eventfd, sys_eventfd), // 323
1664// LINX_(__NR_fallocate, sys_ni_syscall), // 324
1665 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325
1666 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime) // 326
1667};
1668
1669
1670/* These are not in the main table because there indexes are not small
1671 integers, but rather values close to one million. So their
1672 inclusion would force the main table to be huge (about 8 MB). */
1673
1674static SyscallTableEntry ste___ARM_set_tls
1675 = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL };
1676
1677static SyscallTableEntry ste___ARM_cacheflush
1678 = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL };
1679
1680SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1681{
1682 const UInt syscall_main_table_size
1683 = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
1684
1685 /* Is it in the contiguous initial section of the table? */
1686 if (sysno < syscall_main_table_size) {
1687 SyscallTableEntry* sys = &syscall_main_table[sysno];
1688 if (sys->before == NULL)
1689 return NULL; /* no entry */
1690 else
1691 return sys;
1692 }
1693
1694 /* Check if it's one of the out-of-line entries. */
1695 switch (sysno) {
1696 case __NR_ARM_set_tls: return &ste___ARM_set_tls;
1697 case __NR_ARM_cacheflush: return &ste___ARM_cacheflush;
1698 default: break;
1699 }
1700
1701 /* Can't find a wrapper */
1702 return NULL;
1703}
1704
1705#endif // defined(VGP_arm_linux)
1706
1707/*--------------------------------------------------------------------*/
1708/*--- end syswrap-arm-linux.c ---*/
1709/*--------------------------------------------------------------------*/
  
195195 : "=m" (tst->status)
196196 : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode));
197197 }
198#elif defined(VGP_arm_linux)
199 asm volatile (
200 "str %1, %0\n" /* set tst->status = VgTs_Empty */
201 "mov r7, %2\n" /* set %r7 = __NR_exit */
202 "ldr r0, %3\n" /* set %r0 = tst->os_state.exitcode */
203 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
204 : "=m" (tst->status)
205 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode));
198206#else
199207# error Unknown platform
200208#endif
327327
328328 /* Since this is the fork() form of clone, we don't need all that
329329 VG_(clone) stuff */
330#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
330#if defined(VGP_x86_linux) \
331 || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
332 || defined(VGP_arm_linux)
331333 res = VG_(do_syscall5)( __NR_clone, flags,
332334 (UWord)NULL, (UWord)parent_tidptr,
333335 (UWord)NULL, (UWord)child_tidptr );
  
455455 canonical->arg7 = 0;
456456 canonical->arg8 = 0;
457457
458#elif defined(VGP_arm_linux)
459 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
460 canonical->sysno = gst->guest_R7;
461 canonical->arg1 = gst->guest_R0;
462 canonical->arg2 = gst->guest_R1;
463 canonical->arg3 = gst->guest_R2;
464 canonical->arg4 = gst->guest_R3;
465 canonical->arg5 = gst->guest_R4;
466 canonical->arg6 = gst->guest_R5;
467 canonical->arg7 = 0;
468 canonical->arg8 = 0;
469
458470#elif defined(VGP_ppc32_aix5)
459471 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
460472 canonical->sysno = gst->guest_GPR2;
659659 gst->guest_GPR7 = canonical->arg5;
660660 gst->guest_GPR8 = canonical->arg6;
661661
662#elif defined(VGP_arm_linux)
663 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
664 gst->guest_R7 = canonical->sysno;
665 gst->guest_R0 = canonical->arg1;
666 gst->guest_R1 = canonical->arg2;
667 gst->guest_R2 = canonical->arg3;
668 gst->guest_R3 = canonical->arg4;
669 gst->guest_R4 = canonical->arg5;
670 gst->guest_R5 = canonical->arg6;
671
662672#elif defined(VGP_ppc32_aix5)
663673 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
664674 gst->guest_GPR2 = canonical->sysno;
760760 canonical->sres = VG_(mk_SysRes_ppc64_linux)( gst->guest_GPR3, cr0so );
761761 canonical->what = SsComplete;
762762
763# elif defined(VGP_arm_linux)
764 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
765 canonical->sres = VG_(mk_SysRes_arm_linux)( gst->guest_R0 );
766 canonical->what = SsComplete;
767
763768# elif defined(VGP_ppc32_aix5)
764769 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
765770 canonical->sres = VG_(mk_SysRes_ppc32_aix5)( gst->guest_GPR3,
871871 if (sr_isError(canonical->sres)) {
872872 /* This isn't exactly right, in that really a Failure with res
873873 not in the range 1 .. 4095 is unrepresentable in the
874 Linux-x86 scheme. Oh well. */
874 Linux-amd64 scheme. Oh well. */
875875 gst->guest_RAX = - (Long)sr_Err(canonical->sres);
876876 } else {
877877 gst->guest_RAX = sr_Res(canonical->sres);
915915 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
916916 OFFSET_ppc64_CR0_0, sizeof(UChar) );
917917
918# elif defined(VGP_arm_linux)
919 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
920 vg_assert(canonical->what == SsComplete);
921 if (sr_isError(canonical->sres)) {
922 /* This isn't exactly right, in that really a Failure with res
923 not in the range 1 .. 4095 is unrepresentable in the
924 Linux-arm scheme. Oh well. */
925 gst->guest_R0 = - (Int)sr_Err(canonical->sres);
926 } else {
927 gst->guest_R0 = sr_Res(canonical->sres);
928 }
929 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
930 OFFSET_arm_R0, sizeof(UWord) );
931
918932# elif defined(VGP_ppc32_aix5)
919933 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
920934 vg_assert(canonical->what == SsComplete);
10721072 layout->uu_arg7 = -1; /* impossible value */
10731073 layout->uu_arg8 = -1; /* impossible value */
10741074
1075#elif defined(VGP_arm_linux)
1076 layout->o_sysno = OFFSET_arm_R7;
1077 layout->o_arg1 = OFFSET_arm_R0;
1078 layout->o_arg2 = OFFSET_arm_R1;
1079 layout->o_arg3 = OFFSET_arm_R2;
1080 layout->o_arg4 = OFFSET_arm_R3;
1081 layout->o_arg5 = OFFSET_arm_R4;
1082 layout->o_arg6 = OFFSET_arm_R5;
1083 layout->uu_arg7 = -1; /* impossible value */
1084 layout->uu_arg8 = -1; /* impossible value */
1085
10751086#elif defined(VGP_ppc32_aix5)
10761087 layout->o_sysno = OFFSET_ppc32_GPR2;
10771088 layout->o_arg1 = OFFSET_ppc32_GPR3;
11691169 const SyscallTableEntry* sys = NULL;
11701170
11711171# if defined(VGO_linux)
1172 if (syscallno < ML_(syscall_table_size) &&
1173 ML_(syscall_table)[syscallno].before != NULL)
1174 sys = &ML_(syscall_table)[syscallno];
1172 sys = ML_(get_linux_syscall_entry)( syscallno );
11751173
11761174# elif defined(VGP_ppc32_aix5)
11771175 sys = ML_(get_ppc32_aix5_syscall_entry) ( syscallno );
18611861 arch->vex.guest_CIA + 0ULL, p[0], p[1], p[2], p[3]);
18621862
18631863 vg_assert(p[0] == 0x44 && p[1] == 0x0 && p[2] == 0x0 && p[3] == 0x2);
1864 }
1865
1866#elif defined(VGP_arm_linux)
1867 arch->vex.guest_R15 -= 4; // sizeof(arm instr)
1868 {
1869 UChar *p = (UChar*)arch->vex.guest_R15;
1870
1871 if ((p[3] & 0xF) != 0xF)
1872 VG_(message)(Vg_DebugMsg,
1873 "?! restarting over syscall that is not syscall at %#llx %02x %02x %02x %02x\n",
1874 arch->vex.guest_R15 + 0ULL, p[0], p[1], p[2], p[3]);
1875
1876 vg_assert((p[3] & 0xF) == 0xF);
18641877 }
18651878
18661879#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
  
18611861// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
18621862// (unknown).
18631863
1864const SyscallTableEntry ML_(syscall_table)[] = {
1864static SyscallTableEntry syscall_table[] = {
18651865//zz // (restart_syscall) // 0
18661866 GENX_(__NR_exit, sys_exit), // 1
18671867 GENX_(__NR_fork, sys_fork), // 2
22712271 LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 336
22722272};
22732273
2274const UInt ML_(syscall_table_size) =
2275 sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
2274SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
2275{
2276 const UInt syscall_table_size
2277 = sizeof(syscall_table) / sizeof(syscall_table[0]);
2278
2279 /* Is it in the contiguous initial section of the table? */
2280 if (sysno < syscall_table_size) {
2281 SyscallTableEntry* sys = &syscall_table[sysno];
2282 if (sys->before == NULL)
2283 return NULL; /* no entry */
2284 else
2285 return sys;
2286 }
2287
2288 /* Can't find a wrapper */
2289 return NULL;
2290}
22762291
22772292#endif // defined(VGP_x86_linux)
22782293
  
479479# undef UD2_1024
480480# undef UD2_PAGE
481481
482/*---------------- ppc32-linux ----------------*/
483
484#elif defined(VGP_arm_linux)
485
486# define UD2_4 .word 0xFFFFFFFF
487# define UD2_16 UD2_4 ; UD2_4 ; UD2_4 ; UD2_4
488# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
489# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
490# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
491# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
492
493 /* a leading page of unexecutable code */
494 UD2_PAGE
495
496.global VG_(trampoline_stuff_start)
497VG_(trampoline_stuff_start):
498
499.global VG_(arm_linux_REDIR_FOR_strlen)
500VG_(arm_linux_REDIR_FOR_strlen):
501 mov r2, r0
502 ldrb r0, [r0, #0] @ zero_extendqisi2
503 @ lr needed for prologue
504 cmp r0, #0
505 bxeq lr
506 mov r0, #0
507.L5:
508 add r0, r0, #1
509 ldrb r3, [r0, r2] @ zero_extendqisi2
510 cmp r3, #0
511 bne .L5
512 bx lr
513 UD2_4
514
515//.global VG_(arm_linux_REDIR_FOR_index)
516//VG_(arm_linux_REDIR_FOR_index):
517// ldrb r3, [r0, #0] @ zero_extendqisi2
518// and r1, r1, #255
519// cmp r3, r1
520// @ lr needed for prologue
521// bne .L9
522// bx lr
523//.L12:
524// ldrb r3, [r0, #1]! @ zero_extendqisi2
525// cmp r3, r1
526// beq .L11
527//.L9:
528// cmp r3, #0
529// bne .L12
530// mov r0, #0
531// bx lr
532//.L11:
533// bx lr
534// UD2_4
535
536.global VG_(arm_linux_REDIR_FOR_memcpy)
537VG_(arm_linux_REDIR_FOR_memcpy):
538 stmfd sp!, {r4, r5, lr}
539 subs lr, r2, #0
540 mov r5, r0
541 beq .L2
542 cmp r0, r1
543 bls .L4
544 add r3, r0, lr
545 add r1, lr, r1
546 cmp lr, #3
547 sub r4, r3, #1
548 sub r0, r1, #1
549 ble .L28
550 sub ip, r3, #5
551 sub r1, r1, #5
552.L8:
553 ldrb r3, [r1, #4] @ zero_extendqisi2
554 sub lr, lr, #4
555 strb r3, [ip, #4]
556 ldrb r2, [r1, #3] @ zero_extendqisi2
557 cmp lr, #3
558 strb r2, [ip, #3]
559 ldrb r3, [r1, #2] @ zero_extendqisi2
560 mov r4, ip
561 strb r3, [ip, #2]
562 ldrb r2, [r1, #1] @ zero_extendqisi2
563 mov r0, r1
564 strb r2, [ip, #1]
565 sub r1, r1, #4
566 sub ip, ip, #4
567 bgt .L8
568 cmp lr, #0
569 beq .L2
570.L28:
571 sub r2, lr, #1
572.L21:
573 sub r2, r2, #1
574 ldrb r3, [r0], #-1 @ zero_extendqisi2
575 cmn r2, #1
576 strb r3, [r4], #-1
577 bne .L21
578.L2:
579 mov r0, r5
580 ldmfd sp!, {r4, r5, pc}
581.L4:
582 bcs .L2
583 cmp lr, #3
584 mov ip, r0
585 ble .L29
586.L19:
587 ldrb r3, [r1, #0] @ zero_extendqisi2
588 sub lr, lr, #4
589 strb r3, [ip, #0]
590 ldrb r2, [r1, #1] @ zero_extendqisi2
591 cmp lr, #3
592 strb r2, [ip, #1]
593 ldrb r3, [r1, #2] @ zero_extendqisi2
594 strb r3, [ip, #2]
595 ldrb r2, [r1, #3] @ zero_extendqisi2
596 add r1, r1, #4
597 strb r2, [ip, #3]
598 add ip, ip, #4
599 bgt .L19
600 cmp lr, #0
601 beq .L2
602.L29:
603 sub r2, lr, #1
604.L20:
605 sub r2, r2, #1
606 ldrb r3, [r1], #1 @ zero_extendqisi2
607 cmn r2, #1
608 strb r3, [ip], #1
609 bne .L20
610 mov r0, r5
611 ldmfd sp!, {r4, r5, pc}
612 UD2_4
613
614.global VG_(trampoline_stuff_end)
615VG_(trampoline_stuff_end):
616
617 /* and a trailing page of unexecutable code */
618 UD2_PAGE
619
620# undef UD2_4
621# undef UD2_16
622# undef UD2_64
623# undef UD2_256
624# undef UD2_1024
625# undef UD2_PAGE
626
482627/*---------------- ppc32-aix5 ----------------*/
483628#else
484629#if defined(VGP_ppc32_aix5)
12211221
12221222#if defined(VGO_linux)
12231223/* Let the linker know we don't need an executable stack */
1224.section .note.GNU-stack,"",@progbits
1224# if defined(VGP_arm_linux)
1225 .section .note.GNU-stack,"",%progbits
1226# else
1227 .section .note.GNU-stack,"",@progbits
1228# endif
12251229#endif
12261230
12271231/*--------------------------------------------------------------------*/
  
15071507 VG_(clo_profile_flags) > 0
15081508 ? (void*) &VG_(run_innerloop__dispatch_profiled)
15091509 : (void*) &VG_(run_innerloop__dispatch_unprofiled);
1510# elif defined(VGA_ppc32) || defined(VGA_ppc64)
1510# elif defined(VGA_ppc32) || defined(VGA_ppc64) \
1511 || defined(VGA_arm)
15111512 vta.dispatch = NULL;
15121513# else
15131514# error "Unknown arch"
  
4141#include "pub_core_aspacemgr.h"
4242#include "pub_core_mallocfree.h" // VG_(out_of_memory_NORETURN)
4343
44// JRS FIXME get rid of this somehow
45#if defined(VGP_arm_linux)
46# include "pub_core_vkiscnums.h" // __ARM_NR_cacheflush
47# include "pub_core_syscall.h" // VG_(do_syscallN)
48#endif
49
50
4451/* #define DEBUG_TRANSTAB */
4552
4653
815815 vg_assert(cls == 32 || cls == 64 || cls == 128);
816816
817817 startaddr &= ~(cls - 1);
818 for (addr = startaddr; addr < endaddr; addr += cls)
819 asm volatile("dcbst 0,%0" : : "r" (addr));
820 asm volatile("sync");
821 for (addr = startaddr; addr < endaddr; addr += cls)
822 asm volatile("icbi 0,%0" : : "r" (addr));
823 asm volatile("sync; isync");
818 for (addr = startaddr; addr < endaddr; addr += cls) {
819 __asm__ __volatile__("dcbst 0,%0" : : "r" (addr));
820 }
821 __asm__ __volatile__("sync");
822 for (addr = startaddr; addr < endaddr; addr += cls) {
823 __asm__ __volatile__("icbi 0,%0" : : "r" (addr));
824 }
825 __asm__ __volatile__("sync; isync");
824826
825827# elif defined(VGA_x86)
826828 /* no need to do anything, hardware provides coherence */
827829
828830# elif defined(VGA_amd64)
829831 /* no need to do anything, hardware provides coherence */
832
833# elif defined(VGP_arm_linux)
834 /* ARM cache flushes are privileged, so we must defer to the kernel. */
835 Addr startaddr = (Addr) ptr;
836 Addr endaddr = startaddr + nbytes;
837 VG_(do_syscall2)(__NR_ARM_cacheflush, startaddr, endaddr);
830838
831839# else
832840# error "Unknown ARCH"
  
5656# include "libvex_guest_ppc32.h"
5757#elif defined(VGA_ppc64)
5858# include "libvex_guest_ppc64.h"
59#elif defined(VGA_arm)
60# include "libvex_guest_arm.h"
5961#else
6062# error Unknown arch
6163#endif
6264
6365// For jmp_buf
6466#include <setjmp.h>
67
68
69/* ---------------------------------------------------------------------
70 A struct to hold starting values for stack unwinding.
71 ------------------------------------------------------------------ */
72
73/* This really shouldn't be here. But putting it elsewhere leads to a
74 veritable swamp of new module cycles. */
75
76/* To support CFA-based stack unwinding, and stack unwinding in
77 general, we need to be able to get hold of the values of specific
78 registers, in order to start the unwinding process. This is
79 unavoidably arch and platform dependent. Here is a struct which
80 holds the relevant values. All platforms must have a program
81 counter and a stack pointer register, but the other fields (frame
82 pointer? link register? misc other regs?) are ad-hoc. Note, the
83 common fields are 64-bit, so as to make this host-independent. */
84
85typedef
86 struct {
87 ULong r_pc; /* x86:EIP, amd64:RIP, ppc:CIA, arm:R15 */
88 ULong r_sp; /* x86:ESP, amd64:RSP, ppc:R1, arm:R13 */
89 union {
90 struct {
91 UInt r_ebp;
92 } X86;
93 struct {
94 ULong r_rbp;
95 } AMD64;
96 struct {
97 UInt r_lr;
98 } PPC32;
99 struct {
100 ULong r_lr;
101 } PPC64;
102 struct {
103 UInt r14;
104 UInt r12;
105 UInt r11;
106 } ARM;
107 } misc;
108 }
109 UnwindStartRegs;
110
65111
66112#endif // __PUB_CORE_BASICS_H
67113
  
6363__attribute__ ((__noreturn__))
6464extern void VG_(core_panic) ( Char* str );
6565__attribute__ ((__noreturn__))
66extern void VG_(core_panic_at) ( Char* str,
67 Addr ip, Addr sp, Addr fp, Addr lr );
66extern void VG_(core_panic_at) ( Char* str, UnwindStartRegs* );
6867
6968/* Called when some unhandleable client behaviour is detected.
7069 Prints a msg and aborts. */
  
6060# define VG_ELF_MACHINE EM_PPC64
6161# define VG_ELF_CLASS ELFCLASS64
6262# define VG_PLAT_USES_PPCTOC 1
63#elif defined(VGP_arm_linux)
64# define VG_ELF_DATA2XXX ELFDATA2LSB
65# define VG_ELF_MACHINE EM_ARM
66# define VG_ELF_CLASS ELFCLASS32
67# undef VG_PLAT_USES_PPCTOC
6368#elif defined(VGO_aix5)
6469# undef VG_ELF_DATA2XXX
6570# undef VG_ELF_MACHINE
9595# define VG_INSTR_PTR guest_CIA
9696# define VG_STACK_PTR guest_GPR1
9797# define VG_FRAME_PTR guest_GPR1 // No frame ptr for PPC
98#elif defined(VGA_arm)
99# define VG_INSTR_PTR guest_R15
100# define VG_STACK_PTR guest_R13
101# define VG_FRAME_PTR guest_R11
98102#else
99103# error Unknown arch
100104#endif
107107// Offsets for the Vex state
108108#define VG_O_STACK_PTR (offsetof(VexGuestArchState, VG_STACK_PTR))
109109#define VG_O_INSTR_PTR (offsetof(VexGuestArchState, VG_INSTR_PTR))
110
111
112//-------------------------------------------------------------
113// Get hold of the values needed for a stack unwind, for the specified
114// (client) thread.
115void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
116 ThreadId tid );
110117
111118
112119//-------------------------------------------------------------
  
7171// greater than 8.
7272#if defined(VGP_x86_linux) || \
7373 defined(VGP_ppc32_linux) || \
74 defined(VGP_ppc32_aix5)
74 defined(VGP_arm_linux)
7575# define VG_MIN_MALLOC_SZB 8
7676// Nb: We always use 16 bytes for Darwin, even on 32-bits, so it can be used
7777// for any AltiVec- or SSE-related type. This matches the Darwin libc.
7878#elif defined(VGP_amd64_linux) || \
7979 defined(VGP_ppc64_linux) || \
8080 defined(VGP_ppc64_aix5) || \
81 defined(VGP_ppc32_aix5) || \
8182 defined(VGP_x86_darwin) || \
8283 defined(VGP_amd64_darwin)
8384# define VG_MIN_MALLOC_SZB 16
  
5353UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
5454 /*OUT*/Addr* ips, UInt n_ips,
5555 /*OUT*/Addr* sps, /*OUT*/Addr* fps,
56 Addr ip, Addr sp, Addr fp, Addr lr,
57 Addr fp_min, Addr fp_max_orig );
56 UnwindStartRegs* startRegs,
57 Addr fp_max_orig );
5858
5959#endif // __PUB_CORE_STACKTRACE_H
6060
  
7373extern SysRes VG_(mk_SysRes_amd64_linux) ( Long val );
7474extern SysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so );
7575extern SysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong cr0so );
76extern SysRes VG_(mk_SysRes_arm_linux) ( Int val );
7677extern SysRes VG_(mk_SysRes_ppc32_aix5) ( UInt val, UInt err );
7778extern SysRes VG_(mk_SysRes_ppc64_aix5) ( ULong val, ULong err );
7879extern SysRes VG_(mk_SysRes_x86_darwin) ( UChar scclass, Bool isErr,
  
8383 typedef VexGuestPPC32State VexGuestArchState;
8484#elif defined(VGA_ppc64)
8585 typedef VexGuestPPC64State VexGuestArchState;
86#elif defined(VGA_arm)
87 typedef VexGuestARMState VexGuestArchState;
8688#else
8789# error Unknown architecture
8890#endif
  
9191extern void VG_(ppctoc_magic_redirect_return_stub);
9292#endif
9393
94#if defined(VGP_arm_linux)
95extern UInt VG_(arm_linux_REDIR_FOR_strlen)( void* );
96//extern void* VG_(arm_linux_REDIR_FOR_index) ( void*, Int );
97extern void* VG_(arm_linux_REDIR_FOR_memcpy)( void*, void*, Int );
98#endif
99
94100#if defined(VGP_ppc32_aix5)
95101/* A label (sans dot) marking the client start point for ppc32_aix5.
96102 This function is entered with r3 holding a pointer to the
  
4040 On ppc32/ppc64, the bottom two bits of instruction addresses are
4141 zero, which means that function causes only 1/4 of the entries to
4242 ever be used. So instead the function is '(address >>u
43 2)[VG_TT_FAST_BITS-1 : 0]' on those targets. */
43 2)[VG_TT_FAST_BITS-1 : 0]' on those targets.
4444
45 On ARM we do like ppc32/ppc64, although that will have to be
46 revisited when we come to implement Thumb. */
47
4548#define VG_TT_FAST_BITS 15
4649#define VG_TT_FAST_SIZE (1 << VG_TT_FAST_BITS)
4750#define VG_TT_FAST_MASK ((VG_TT_FAST_SIZE) - 1)
5353 like a good place to put it. */
5454#if defined(VGA_x86) || defined(VGA_amd64)
5555# define VG_TT_FAST_HASH(_addr) ((((UWord)(_addr)) ) & VG_TT_FAST_MASK)
56#elif defined(VGA_ppc32) || defined(VGA_ppc64)
56#elif defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_arm)
5757# define VG_TT_FAST_HASH(_addr) ((((UWord)(_addr)) >> 2) & VG_TT_FAST_MASK)
5858#else
5959# error "VG_TT_FAST_HASH: unknown platform"
  
9595TBD
9696
9797
98arm-linux
99~~~~~~~~~
100
101Reg Callee Arg
102Name Saves? Reg? Comment Vex-uses?
103--------------------------------------------------------------
104r0 int#1 int[31:0] retreg? avail
105r1 int#2 int[63:32] retreg? avail
106r2 int#3 avail
107r3 int#4 avail
108r4 y avail
109r5 y avail
110r6 y avail
111r7 y avail
112r8 y GSP
113r9 y (but only on Linux; not in general) avail
114r10 y avail
115r11 y avail
116r12 possibly used by linker? unavail
117r13(sp) unavail
118r14(lr) unavail
119r15(pc) unavail
120
121VFP: d8-d15 are callee-saved
122r12 (IP) is probably available for use as a caller-saved
123register; but instead we use it as an intermediate for
124holding the address for F32/F64 spills, since the VFP load/store
125insns have reg+offset forms for offsets only up to 1020, which
126often isn't enough.
127
128
98129ppc32-aix5
99130~~~~~~~~~~
100131
  
290290#undef VG_BIGENDIAN
291291#undef VG_LITTLEENDIAN
292292
293#if defined(VGA_x86) || defined(VGA_amd64)
293#if defined(VGA_x86) || defined(VGA_amd64) || defined (VGA_arm)
294294# define VG_LITTLEENDIAN 1
295295#elif defined(VGA_ppc32) || defined(VGA_ppc64)
296296# define VG_BIGENDIAN 1
301301/* Regparmness */
302302#if defined(VGA_x86)
303303# define VG_REGPARM(n) __attribute__((regparm(n)))
304#elif defined(VGA_amd64) || defined(VGA_ppc32) || defined(VGA_ppc64)
304#elif defined(VGA_amd64) || defined(VGA_ppc32) \
305 || defined(VGA_ppc64) || defined(VGA_arm)
305306# define VG_REGPARM(n) /* */
306307#else
307308# error Unknown arch
  
3737# define VG_CLREQ_SZB 14 // length of a client request, may
3838 // be larger than VG_MAX_INSTR_SZB
3939# define VG_STACK_REDZONE_SZB 0 // number of addressable bytes below %RSP
40
4041#elif defined(VGP_amd64_linux)
4142# define VG_MIN_INSTR_SZB 1
4243# define VG_MAX_INSTR_SZB 16
4344# define VG_CLREQ_SZB 19
4445# define VG_STACK_REDZONE_SZB 128
46
4547#elif defined(VGP_ppc32_linux)
4648# define VG_MIN_INSTR_SZB 4
4749# define VG_MAX_INSTR_SZB 4
4850# define VG_CLREQ_SZB 20
4951# define VG_STACK_REDZONE_SZB 0
52
5053#elif defined(VGP_ppc64_linux)
5154# define VG_MIN_INSTR_SZB 4
5255# define VG_MAX_INSTR_SZB 4
5356# define VG_CLREQ_SZB 20
5457# define VG_STACK_REDZONE_SZB 288 // number of addressable bytes below R1
55 // from 64-bit PowerPC ELF ABI Supplement 1.7
58 // from 64-bit PowerPC ELF ABI
59 // Supplement 1.7
60
61#elif defined(VGP_arm_linux)
62# define VG_MIN_INSTR_SZB 4
63# define VG_MAX_INSTR_SZB 4
64# define VG_CLREQ_SZB 28
65# define VG_STACK_REDZONE_SZB 0
66
5667#elif defined(VGP_ppc32_aix5)
5768# define VG_MIN_INSTR_SZB 4
5869# define VG_MAX_INSTR_SZB 4
7474 8-alignment of the area to be messed with. So let's just say
7575 224 instead. Gdb has a similar kludge. */
7676# define VG_STACK_REDZONE_SZB 224
77
7778#elif defined(VGP_ppc64_aix5)
7879# define VG_MIN_INSTR_SZB 4
7980# define VG_MAX_INSTR_SZB 4
8081# define VG_CLREQ_SZB 20
8182# define VG_STACK_REDZONE_SZB 288 // is this right?
83
8284#elif defined(VGP_x86_darwin)
8385# define VG_MIN_INSTR_SZB 1 // min length of native instruction
8486# define VG_MAX_INSTR_SZB 16 // max length of native instruction
8587# define VG_CLREQ_SZB 14 // length of a client request, may
8688 // be larger than VG_MAX_INSTR_SZB
8789# define VG_STACK_REDZONE_SZB 0 // number of addressable bytes below %RSP
90
8891#elif defined(VGP_amd64_darwin)
8992# define VG_MIN_INSTR_SZB 1
9093# define VG_MAX_INSTR_SZB 16
9194# define VG_CLREQ_SZB 19
9295# define VG_STACK_REDZONE_SZB 128
96
9397#else
9498# error Unknown platform
9599#endif
  
4545#elif defined(VGP_ppc64_linux)
4646# include "vki/vki-scnums-ppc64-linux.h"
4747
48#elif defined(VGP_arm_linux)
49# include "vki/vki-scnums-arm-linux.h"
50
4851#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
4952 // Nothing: vki-scnums-aix5.h only contains stuff suitable for inclusion
5053 // in C files, not asm files. So unlike all the other
  
8484 identifying architectures, which are different to the ones we use
8585 within the rest of Valgrind. Note, __powerpc__ is active for both
8686 32 and 64-bit PPC, whereas __powerpc64__ is only active for the
87 latter (on Linux, that is). */
87 latter (on Linux, that is).
88
89 Misc note: how to find out what's predefined in gcc by default:
90 gcc -Wp,-dM somefile.c
91*/
8892#undef PLAT_x86_linux
8993#undef PLAT_amd64_linux
9094#undef PLAT_ppc32_linux
9195#undef PLAT_ppc64_linux
96#undef PLAT_arm_linux
9297#undef PLAT_ppc32_aix5
9398#undef PLAT_ppc64_aix5
9499
95
96100#if defined(_AIX) && defined(__64BIT__)
97101# define PLAT_ppc64_aix5 1
98102#elif defined(_AIX) && !defined(__64BIT__)
105105# define PLAT_x86_darwin 1
106106#elif defined(__APPLE__) && defined(__x86_64__)
107107# define PLAT_amd64_darwin 1
108#elif defined(__i386__)
108#elif defined(__linux__) && defined(__i386__)
109109# define PLAT_x86_linux 1
110#elif defined(__x86_64__)
110#elif defined(__linux__) && defined(__x86_64__)
111111# define PLAT_amd64_linux 1
112#elif defined(__powerpc__) && !defined(__powerpc64__)
112#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
113113# define PLAT_ppc32_linux 1
114#elif defined(__powerpc__) && defined(__powerpc64__)
114#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
115115# define PLAT_ppc64_linux 1
116#elif defined(__linux__) && defined(__arm__)
117# define PLAT_arm_linux 1
116118#else
117119/* If we're not compiling for our target platform, don't generate
118120 any inline asms. */
412412
413413#endif /* PLAT_ppc64_linux */
414414
415/* ------------------------- arm-linux ------------------------- */
416
417#if defined(PLAT_arm_linux)
418
419typedef
420 struct {
421 unsigned int nraddr; /* where's the code? */
422 }
423 OrigFn;
424
425#define __SPECIAL_INSTRUCTION_PREAMBLE \
426 "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \
427 "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
428
429#define VALGRIND_DO_CLIENT_REQUEST( \
430 _zzq_rlval, _zzq_default, _zzq_request, \
431 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
432 \
433 { volatile unsigned int _zzq_args[6]; \
434 volatile unsigned int _zzq_result; \
435 _zzq_args[0] = (unsigned int)(_zzq_request); \
436 _zzq_args[1] = (unsigned int)(_zzq_arg1); \
437 _zzq_args[2] = (unsigned int)(_zzq_arg2); \
438 _zzq_args[3] = (unsigned int)(_zzq_arg3); \
439 _zzq_args[4] = (unsigned int)(_zzq_arg4); \
440 _zzq_args[5] = (unsigned int)(_zzq_arg5); \
441 __asm__ volatile("mov r3, %1\n\t" /*default*/ \
442 "mov r4, %2\n\t" /*ptr*/ \
443 __SPECIAL_INSTRUCTION_PREAMBLE \
444 /* R3 = client_request ( R4 ) */ \
445 "orr r10, r10, r10\n\t" \
446 "mov %0, r3" /*result*/ \
447 : "=r" (_zzq_result) \
448 : "r" (_zzq_default), "r" (&_zzq_args[0]) \
449 : "cc","memory", "r3", "r4"); \
450 _zzq_rlval = _zzq_result; \
451 }
452
453#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
454 { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
455 unsigned int __addr; \
456 __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
457 /* R3 = guest_NRADDR */ \
458 "orr r11, r11, r11\n\t" \
459 "mov %0, r3" \
460 : "=r" (__addr) \
461 : \
462 : "cc", "memory", "r3" \
463 ); \
464 _zzq_orig->nraddr = __addr; \
465 }
466
467#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
468 __SPECIAL_INSTRUCTION_PREAMBLE \
469 /* branch-and-link-to-noredir *%R4 */ \
470 "orr r12, r12, r12\n\t"
471
472#endif /* PLAT_arm_linux */
473
415474/* ------------------------ ppc32-aix5 ------------------------- */
416475
417476#if defined(PLAT_ppc32_aix5)
25232523
25242524#endif /* PLAT_ppc64_linux */
25252525
2526/* ------------------------- arm-linux ------------------------- */
2527
2528#if defined(PLAT_arm_linux)
2529
2530/* These regs are trashed by the hidden call. */
2531#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
2532
2533/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
2534 long) == 4. */
2535
2536#define CALL_FN_W_v(lval, orig) \
2537 do { \
2538 volatile OrigFn _orig = (orig); \
2539 volatile unsigned long _argvec[1]; \
2540 volatile unsigned long _res; \
2541 _argvec[0] = (unsigned long)_orig.nraddr; \
2542 __asm__ volatile( \
2543 "ldr r4, [%1] \n\t" /* target->r4 */ \
2544 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2545 "mov %0, r0\n" \
2546 : /*out*/ "=r" (_res) \
2547 : /*in*/ "0" (&_argvec[0]) \
2548 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2549 ); \
2550 lval = (__typeof__(lval)) _res; \
2551 } while (0)
2552
2553#define CALL_FN_W_W(lval, orig, arg1) \
2554 do { \
2555 volatile OrigFn _orig = (orig); \
2556 volatile unsigned long _argvec[2]; \
2557 volatile unsigned long _res; \
2558 _argvec[0] = (unsigned long)_orig.nraddr; \
2559 _argvec[1] = (unsigned long)(arg1); \
2560 __asm__ volatile( \
2561 "ldr r0, [%1, #4] \n\t" \
2562 "ldr r4, [%1] \n\t" /* target->r4 */ \
2563 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2564 "mov %0, r0\n" \
2565 : /*out*/ "=r" (_res) \
2566 : /*in*/ "0" (&_argvec[0]) \
2567 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2568 ); \
2569 lval = (__typeof__(lval)) _res; \
2570 } while (0)
2571
2572#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
2573 do { \
2574 volatile OrigFn _orig = (orig); \
2575 volatile unsigned long _argvec[3]; \
2576 volatile unsigned long _res; \
2577 _argvec[0] = (unsigned long)_orig.nraddr; \
2578 _argvec[1] = (unsigned long)(arg1); \
2579 _argvec[2] = (unsigned long)(arg2); \
2580 __asm__ volatile( \
2581 "ldr r0, [%1, #4] \n\t" \
2582 "ldr r1, [%1, #8] \n\t" \
2583 "ldr r4, [%1] \n\t" /* target->r4 */ \
2584 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2585 "mov %0, r0\n" \
2586 : /*out*/ "=r" (_res) \
2587 : /*in*/ "0" (&_argvec[0]) \
2588 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2589 ); \
2590 lval = (__typeof__(lval)) _res; \
2591 } while (0)
2592
2593#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2594 do { \
2595 volatile OrigFn _orig = (orig); \
2596 volatile unsigned long _argvec[4]; \
2597 volatile unsigned long _res; \
2598 _argvec[0] = (unsigned long)_orig.nraddr; \
2599 _argvec[1] = (unsigned long)(arg1); \
2600 _argvec[2] = (unsigned long)(arg2); \
2601 _argvec[3] = (unsigned long)(arg3); \
2602 __asm__ volatile( \
2603 "ldr r0, [%1, #4] \n\t" \
2604 "ldr r1, [%1, #8] \n\t" \
2605 "ldr r2, [%1, #12] \n\t" \
2606 "ldr r4, [%1] \n\t" /* target->r4 */ \
2607 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2608 "mov %0, r0\n" \
2609 : /*out*/ "=r" (_res) \
2610 : /*in*/ "0" (&_argvec[0]) \
2611 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2612 ); \
2613 lval = (__typeof__(lval)) _res; \
2614 } while (0)
2615
2616#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2617 do { \
2618 volatile OrigFn _orig = (orig); \
2619 volatile unsigned long _argvec[5]; \
2620 volatile unsigned long _res; \
2621 _argvec[0] = (unsigned long)_orig.nraddr; \
2622 _argvec[1] = (unsigned long)(arg1); \
2623 _argvec[2] = (unsigned long)(arg2); \
2624 _argvec[3] = (unsigned long)(arg3); \
2625 _argvec[4] = (unsigned long)(arg4); \
2626 __asm__ volatile( \
2627 "ldr r0, [%1, #4] \n\t" \
2628 "ldr r1, [%1, #8] \n\t" \
2629 "ldr r2, [%1, #12] \n\t" \
2630 "ldr r3, [%1, #16] \n\t" \
2631 "ldr r4, [%1] \n\t" /* target->r4 */ \
2632 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2633 "mov %0, r0" \
2634 : /*out*/ "=r" (_res) \
2635 : /*in*/ "0" (&_argvec[0]) \
2636 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2637 ); \
2638 lval = (__typeof__(lval)) _res; \
2639 } while (0)
2640
2641#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2642 do { \
2643 volatile OrigFn _orig = (orig); \
2644 volatile unsigned long _argvec[6]; \
2645 volatile unsigned long _res; \
2646 _argvec[0] = (unsigned long)_orig.nraddr; \
2647 _argvec[1] = (unsigned long)(arg1); \
2648 _argvec[2] = (unsigned long)(arg2); \
2649 _argvec[3] = (unsigned long)(arg3); \
2650 _argvec[4] = (unsigned long)(arg4); \
2651 _argvec[5] = (unsigned long)(arg5); \
2652 __asm__ volatile( \
2653 "ldr r0, [%1, #20] \n\t" \
2654 "push {r0} \n\t" \
2655 "ldr r0, [%1, #4] \n\t" \
2656 "ldr r1, [%1, #8] \n\t" \
2657 "ldr r2, [%1, #12] \n\t" \
2658 "ldr r3, [%1, #16] \n\t" \
2659 "ldr r4, [%1] \n\t" /* target->r4 */ \
2660 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2661 "add sp, sp, #4 \n\t" \
2662 "mov %0, r0" \
2663 : /*out*/ "=r" (_res) \
2664 : /*in*/ "0" (&_argvec[0]) \
2665 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2666 ); \
2667 lval = (__typeof__(lval)) _res; \
2668 } while (0)
2669
2670#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
2671 do { \
2672 volatile OrigFn _orig = (orig); \
2673 volatile unsigned long _argvec[7]; \
2674 volatile unsigned long _res; \
2675 _argvec[0] = (unsigned long)_orig.nraddr; \
2676 _argvec[1] = (unsigned long)(arg1); \
2677 _argvec[2] = (unsigned long)(arg2); \
2678 _argvec[3] = (unsigned long)(arg3); \
2679 _argvec[4] = (unsigned long)(arg4); \
2680 _argvec[5] = (unsigned long)(arg5); \
2681 _argvec[6] = (unsigned long)(arg6); \
2682 __asm__ volatile( \
2683 "ldr r0, [%1, #20] \n\t" \
2684 "ldr r1, [%1, #24] \n\t" \
2685 "push {r0, r1} \n\t" \
2686 "ldr r0, [%1, #4] \n\t" \
2687 "ldr r1, [%1, #8] \n\t" \
2688 "ldr r2, [%1, #12] \n\t" \
2689 "ldr r3, [%1, #16] \n\t" \
2690 "ldr r4, [%1] \n\t" /* target->r4 */ \
2691 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2692 "add sp, sp, #8 \n\t" \
2693 "mov %0, r0" \
2694 : /*out*/ "=r" (_res) \
2695 : /*in*/ "0" (&_argvec[0]) \
2696 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2697 ); \
2698 lval = (__typeof__(lval)) _res; \
2699 } while (0)
2700
2701#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2702 arg7) \
2703 do { \
2704 volatile OrigFn _orig = (orig); \
2705 volatile unsigned long _argvec[8]; \
2706 volatile unsigned long _res; \
2707 _argvec[0] = (unsigned long)_orig.nraddr; \
2708 _argvec[1] = (unsigned long)(arg1); \
2709 _argvec[2] = (unsigned long)(arg2); \
2710 _argvec[3] = (unsigned long)(arg3); \
2711 _argvec[4] = (unsigned long)(arg4); \
2712 _argvec[5] = (unsigned long)(arg5); \
2713 _argvec[6] = (unsigned long)(arg6); \
2714 _argvec[7] = (unsigned long)(arg7); \
2715 __asm__ volatile( \
2716 "ldr r0, [%1, #20] \n\t" \
2717 "ldr r1, [%1, #24] \n\t" \
2718 "ldr r2, [%1, #28] \n\t" \
2719 "push {r0, r1, r2} \n\t" \
2720 "ldr r0, [%1, #4] \n\t" \
2721 "ldr r1, [%1, #8] \n\t" \
2722 "ldr r2, [%1, #12] \n\t" \
2723 "ldr r3, [%1, #16] \n\t" \
2724 "ldr r4, [%1] \n\t" /* target->r4 */ \
2725 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2726 "add sp, sp, #12 \n\t" \
2727 "mov %0, r0" \
2728 : /*out*/ "=r" (_res) \
2729 : /*in*/ "0" (&_argvec[0]) \
2730 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2731 ); \
2732 lval = (__typeof__(lval)) _res; \
2733 } while (0)
2734
2735#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2736 arg7,arg8) \
2737 do { \
2738 volatile OrigFn _orig = (orig); \
2739 volatile unsigned long _argvec[9]; \
2740 volatile unsigned long _res; \
2741 _argvec[0] = (unsigned long)_orig.nraddr; \
2742 _argvec[1] = (unsigned long)(arg1); \
2743 _argvec[2] = (unsigned long)(arg2); \
2744 _argvec[3] = (unsigned long)(arg3); \
2745 _argvec[4] = (unsigned long)(arg4); \
2746 _argvec[5] = (unsigned long)(arg5); \
2747 _argvec[6] = (unsigned long)(arg6); \
2748 _argvec[7] = (unsigned long)(arg7); \
2749 _argvec[8] = (unsigned long)(arg8); \
2750 __asm__ volatile( \
2751 "ldr r0, [%1, #20] \n\t" \
2752 "ldr r1, [%1, #24] \n\t" \
2753 "ldr r2, [%1, #28] \n\t" \
2754 "ldr r3, [%1, #32] \n\t" \
2755 "push {r0, r1, r2, r3} \n\t" \
2756 "ldr r0, [%1, #4] \n\t" \
2757 "ldr r1, [%1, #8] \n\t" \
2758 "ldr r2, [%1, #12] \n\t" \
2759 "ldr r3, [%1, #16] \n\t" \
2760 "ldr r4, [%1] \n\t" /* target->r4 */ \
2761 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2762 "add sp, sp, #16 \n\t" \
2763 "mov %0, r0" \
2764 : /*out*/ "=r" (_res) \
2765 : /*in*/ "0" (&_argvec[0]) \
2766 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2767 ); \
2768 lval = (__typeof__(lval)) _res; \
2769 } while (0)
2770
2771#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2772 arg7,arg8,arg9) \
2773 do { \
2774 volatile OrigFn _orig = (orig); \
2775 volatile unsigned long _argvec[10]; \
2776 volatile unsigned long _res; \
2777 _argvec[0] = (unsigned long)_orig.nraddr; \
2778 _argvec[1] = (unsigned long)(arg1); \
2779 _argvec[2] = (unsigned long)(arg2); \
2780 _argvec[3] = (unsigned long)(arg3); \
2781 _argvec[4] = (unsigned long)(arg4); \
2782 _argvec[5] = (unsigned long)(arg5); \
2783 _argvec[6] = (unsigned long)(arg6); \
2784 _argvec[7] = (unsigned long)(arg7); \
2785 _argvec[8] = (unsigned long)(arg8); \
2786 _argvec[9] = (unsigned long)(arg9); \
2787 __asm__ volatile( \
2788 "ldr r0, [%1, #20] \n\t" \
2789 "ldr r1, [%1, #24] \n\t" \
2790 "ldr r2, [%1, #28] \n\t" \
2791 "ldr r3, [%1, #32] \n\t" \
2792 "ldr r4, [%1, #36] \n\t" \
2793 "push {r0, r1, r2, r3, r4} \n\t" \
2794 "ldr r0, [%1, #4] \n\t" \
2795 "ldr r1, [%1, #8] \n\t" \
2796 "ldr r2, [%1, #12] \n\t" \
2797 "ldr r3, [%1, #16] \n\t" \
2798 "ldr r4, [%1] \n\t" /* target->r4 */ \
2799 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2800 "add sp, sp, #20 \n\t" \
2801 "mov %0, r0" \
2802 : /*out*/ "=r" (_res) \
2803 : /*in*/ "0" (&_argvec[0]) \
2804 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2805 ); \
2806 lval = (__typeof__(lval)) _res; \
2807 } while (0)
2808
2809#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2810 arg7,arg8,arg9,arg10) \
2811 do { \
2812 volatile OrigFn _orig = (orig); \
2813 volatile unsigned long _argvec[11]; \
2814 volatile unsigned long _res; \
2815 _argvec[0] = (unsigned long)_orig.nraddr; \
2816 _argvec[1] = (unsigned long)(arg1); \
2817 _argvec[2] = (unsigned long)(arg2); \
2818 _argvec[3] = (unsigned long)(arg3); \
2819 _argvec[4] = (unsigned long)(arg4); \
2820 _argvec[5] = (unsigned long)(arg5); \
2821 _argvec[6] = (unsigned long)(arg6); \
2822 _argvec[7] = (unsigned long)(arg7); \
2823 _argvec[8] = (unsigned long)(arg8); \
2824 _argvec[9] = (unsigned long)(arg9); \
2825 _argvec[10] = (unsigned long)(arg10); \
2826 __asm__ volatile( \
2827 "ldr r0, [%1, #40] \n\t" \
2828 "push {r0} \n\t" \
2829 "ldr r0, [%1, #20] \n\t" \
2830 "ldr r1, [%1, #24] \n\t" \
2831 "ldr r2, [%1, #28] \n\t" \
2832 "ldr r3, [%1, #32] \n\t" \
2833 "ldr r4, [%1, #36] \n\t" \
2834 "push {r0, r1, r2, r3, r4} \n\t" \
2835 "ldr r0, [%1, #4] \n\t" \
2836 "ldr r1, [%1, #8] \n\t" \
2837 "ldr r2, [%1, #12] \n\t" \
2838 "ldr r3, [%1, #16] \n\t" \
2839 "ldr r4, [%1] \n\t" /* target->r4 */ \
2840 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2841 "add sp, sp, #24 \n\t" \
2842 "mov %0, r0" \
2843 : /*out*/ "=r" (_res) \
2844 : /*in*/ "0" (&_argvec[0]) \
2845 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2846 ); \
2847 lval = (__typeof__(lval)) _res; \
2848 } while (0)
2849
2850#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
2851 arg6,arg7,arg8,arg9,arg10, \
2852 arg11) \
2853 do { \
2854 volatile OrigFn _orig = (orig); \
2855 volatile unsigned long _argvec[12]; \
2856 volatile unsigned long _res; \
2857 _argvec[0] = (unsigned long)_orig.nraddr; \
2858 _argvec[1] = (unsigned long)(arg1); \
2859 _argvec[2] = (unsigned long)(arg2); \
2860 _argvec[3] = (unsigned long)(arg3); \
2861 _argvec[4] = (unsigned long)(arg4); \
2862 _argvec[5] = (unsigned long)(arg5); \
2863 _argvec[6] = (unsigned long)(arg6); \
2864 _argvec[7] = (unsigned long)(arg7); \
2865 _argvec[8] = (unsigned long)(arg8); \
2866 _argvec[9] = (unsigned long)(arg9); \
2867 _argvec[10] = (unsigned long)(arg10); \
2868 _argvec[11] = (unsigned long)(arg11); \
2869 __asm__ volatile( \
2870 "ldr r0, [%1, #40] \n\t" \
2871 "ldr r1, [%1, #44] \n\t" \
2872 "push {r0, r1} \n\t" \
2873 "ldr r0, [%1, #20] \n\t" \
2874 "ldr r1, [%1, #24] \n\t" \
2875 "ldr r2, [%1, #28] \n\t" \
2876 "ldr r3, [%1, #32] \n\t" \
2877 "ldr r4, [%1, #36] \n\t" \
2878 "push {r0, r1, r2, r3, r4} \n\t" \
2879 "ldr r0, [%1, #4] \n\t" \
2880 "ldr r1, [%1, #8] \n\t" \
2881 "ldr r2, [%1, #12] \n\t" \
2882 "ldr r3, [%1, #16] \n\t" \
2883 "ldr r4, [%1] \n\t" /* target->r4 */ \
2884 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2885 "add sp, sp, #28 \n\t" \
2886 "mov %0, r0" \
2887 : /*out*/ "=r" (_res) \
2888 : /*in*/ "0" (&_argvec[0]) \
2889 : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS \
2890 ); \
2891 lval = (__typeof__(lval)) _res; \
2892 } while (0)
2893
2894#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
2895 arg6,arg7,arg8,arg9,arg10, \
2896 arg11,arg12) \
2897 do { \
2898 volatile OrigFn _orig = (orig); \
2899 volatile unsigned long _argvec[13]; \
2900 volatile unsigned long _res; \
2901 _argvec[0] = (unsigned long)_orig.nraddr; \
2902 _argvec[1] = (unsigned long)(arg1); \
2903 _argvec[2] = (unsigned long)(arg2); \
2904 _argvec[3] = (unsigned long)(arg3); \
2905 _argvec[4] = (unsigned long)(arg4); \
2906 _argvec[5] = (unsigned long)(arg5); \
2907 _argvec[6] = (unsigned long)(arg6); \
2908 _argvec[7] = (unsigned long)(arg7); \
2909 _argvec[8] = (unsigned long)(arg8); \
2910 _argvec[9] = (unsigned long)(arg9); \
2911 _argvec[10] = (unsigned long)(arg10); \
2912 _argvec[11] = (unsigned long)(arg11); \
2913 _argvec[12] = (unsigned long)(arg12); \
2914 __asm__ volatile( \
2915 "ldr r0, [%1, #40] \n\t" \
2916 "ldr r1, [%1, #44] \n\t" \
2917 "ldr r2, [%1, #48] \n\t" \
2918 "push {r0, r1, r2} \n\t" \
2919 "ldr r0, [%1, #20] \n\t" \
2920 "ldr r1, [%1, #24] \n\t" \
2921 "ldr r2, [%1, #28] \n\t" \
2922 "ldr r3, [%1, #32] \n\t" \
2923 "ldr r4, [%1, #36] \n\t" \
2924 "push {r0, r1, r2, r3, r4} \n\t" \
2925 "ldr r0, [%1, #4] \n\t" \
2926 "ldr r1, [%1, #8] \n\t" \
2927 "ldr r2, [%1, #12] \n\t" \
2928 "ldr r3, [%1, #16] \n\t" \
2929 "ldr r4, [%1] \n\t" /* target->r4 */ \
2930 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2931 "add sp, sp, #32 \n\t" \
2932 "mov %0, r0" \
2933 : /*out*/ "=r" (_res) \
2934 : /*in*/ "0" (&_argvec[0]) \
2935 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2936 ); \
2937 lval = (__typeof__(lval)) _res; \
2938 } while (0)
2939
2940#endif /* PLAT_arm_linux */
2941
25262942/* ------------------------ ppc32-aix5 ------------------------- */
25272943
25282944#if defined(PLAT_ppc32_aix5)
44954495#undef PLAT_amd64_linux
44964496#undef PLAT_ppc32_linux
44974497#undef PLAT_ppc64_linux
4498#undef PLAT_arm_linux
44984499#undef PLAT_ppc32_aix5
44994500#undef PLAT_ppc64_aix5
45004501
  
1
2/*--------------------------------------------------------------------*/
3/*--- arm/Linux-specific kernel interface. vki-arm-linux.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2008 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#ifndef __VKI_ARM_LINUX_H
32#define __VKI_ARM_LINUX_H
33
34// arm is little-endian.
35#define VKI_LITTLE_ENDIAN 1
36
37//----------------------------------------------------------------------
38// From linux-2.6.8.1/include/asm-i386/types.h
39//----------------------------------------------------------------------
40
41typedef unsigned char __vki_u8;
42
43typedef __signed__ short __vki_s16;
44typedef unsigned short __vki_u16;
45
46typedef __signed__ int __vki_s32;
47typedef unsigned int __vki_u32;
48
49typedef __signed__ long long __vki_s64;
50typedef unsigned long long __vki_u64;
51
52typedef unsigned short vki_u16;
53
54typedef unsigned int vki_u32;
55
56//----------------------------------------------------------------------
57// From linux-2.6.8.1/include/asm-i386/page.h
58//----------------------------------------------------------------------
59
60/* PAGE_SHIFT determines the page size */
61#define VKI_PAGE_SHIFT 12
62#define VKI_PAGE_SIZE (1UL << VKI_PAGE_SHIFT)
63#define VKI_MAX_PAGE_SHIFT VKI_PAGE_SHIFT
64#define VKI_MAX_PAGE_SIZE VKI_PAGE_SIZE
65
66//----------------------------------------------------------------------
67// From linux-2.6.8.1/include/asm-i386/signal.h
68//----------------------------------------------------------------------
69
70#define VKI_MINSIGSTKSZ 2048
71
72#define VKI_SIG_BLOCK 0 /* for blocking signals */
73#define VKI_SIG_UNBLOCK 1 /* for unblocking signals */
74#define VKI_SIG_SETMASK 2 /* for setting the signal mask */
75
76/* Type of a signal handler. */
77typedef void __vki_signalfn_t(int);
78typedef __vki_signalfn_t __user *__vki_sighandler_t;
79
80typedef void __vki_restorefn_t(void);
81typedef __vki_restorefn_t __user *__vki_sigrestore_t;
82
83#define VKI_SIG_DFL ((__vki_sighandler_t)0) /* default signal handling */
84#define VKI_SIG_IGN ((__vki_sighandler_t)1) /* ignore signal */
85
86#define _VKI_NSIG 64
87#define _VKI_NSIG_BPW 32
88#define _VKI_NSIG_WORDS (_VKI_NSIG / _VKI_NSIG_BPW)
89
90typedef unsigned long vki_old_sigset_t; /* at least 32 bits */
91
92typedef struct {
93 unsigned long sig[_VKI_NSIG_WORDS];
94} vki_sigset_t;
95
96#define VKI_SIGHUP 1
97#define VKI_SIGINT 2
98#define VKI_SIGQUIT 3
99#define VKI_SIGILL 4
100#define VKI_SIGTRAP 5
101#define VKI_SIGABRT 6
102//#define VKI_SIGIOT 6
103#define VKI_SIGBUS 7
104#define VKI_SIGFPE 8
105#define VKI_SIGKILL 9
106#define VKI_SIGUSR1 10
107#define VKI_SIGSEGV 11
108#define VKI_SIGUSR2 12
109#define VKI_SIGPIPE 13
110#define VKI_SIGALRM 14
111#define VKI_SIGTERM 15
112#define VKI_SIGSTKFLT 16
113#define VKI_SIGCHLD 17
114#define VKI_SIGCONT 18
115#define VKI_SIGSTOP 19
116#define VKI_SIGTSTP 20
117#define VKI_SIGTTIN 21
118#define VKI_SIGTTOU 22
119#define VKI_SIGURG 23
120#define VKI_SIGXCPU 24
121#define VKI_SIGXFSZ 25
122#define VKI_SIGVTALRM 26
123#define VKI_SIGPROF 27
124#define VKI_SIGWINCH 28
125#define VKI_SIGIO 29
126#define VKI_SIGPWR 30
127#define VKI_SIGSYS 31
128#define VKI_SIGUNUSED 31
129
130/* These should not be considered constants from userland. */
131#define VKI_SIGRTMIN 32
132// [[This was (_NSIG-1) in 2.4.X... not sure if it matters.]]
133#define VKI_SIGRTMAX _VKI_NSIG
134
135#define VKI_SA_NOCLDSTOP 0x00000001u
136#define VKI_SA_NOCLDWAIT 0x00000002u
137#define VKI_SA_SIGINFO 0x00000004u
138#define VKI_SA_ONSTACK 0x08000000u
139#define VKI_SA_RESTART 0x10000000u
140#define VKI_SA_NODEFER 0x40000000u
141#define VKI_SA_RESETHAND 0x80000000u
142
143#define VKI_SA_NOMASK VKI_SA_NODEFER
144#define VKI_SA_ONESHOT VKI_SA_RESETHAND
145//#define VKI_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
146
147#define VKI_SA_RESTORER 0x04000000
148
149#define VKI_SS_ONSTACK 1
150#define VKI_SS_DISABLE 2
151
152struct vki_old_sigaction {
153 // [[Nb: a 'k' prefix is added to "sa_handler" because
154 // bits/sigaction.h (which gets dragged in somehow via signal.h)
155 // #defines it as something else. Since that is done for glibc's
156 // purposes, which we don't care about here, we use our own name.]]
157 __vki_sighandler_t ksa_handler;
158 vki_old_sigset_t sa_mask;
159 unsigned long sa_flags;
160 __vki_sigrestore_t sa_restorer;
161};
162
163struct vki_sigaction_base {
164 // [[See comment about extra 'k' above]]
165 __vki_sighandler_t ksa_handler;
166 unsigned long sa_flags;
167 __vki_sigrestore_t sa_restorer;
168 vki_sigset_t sa_mask; /* mask last for extensibility */
169};
170
171/* On Linux we use the same type for passing sigactions to
172 and from the kernel. Hence: */
173typedef struct vki_sigaction_base vki_sigaction_toK_t;
174typedef struct vki_sigaction_base vki_sigaction_fromK_t;
175
176
177typedef struct vki_sigaltstack {
178 void __user *ss_sp;
179 int ss_flags;
180 vki_size_t ss_size;
181} vki_stack_t;
182
183//----------------------------------------------------------------------
184// From linux-2.6.8.1/include/asm-i386/sigcontext.h
185//----------------------------------------------------------------------
186
187struct _vki_fpreg {
188 unsigned short significand[4];
189 unsigned short exponent;
190};
191
192struct _vki_fpxreg {
193 unsigned short significand[4];
194 unsigned short exponent;
195 unsigned short padding[3];
196};
197
198struct _vki_xmmreg {
199 unsigned long element[4];
200};
201
202struct _vki_fpstate {
203 /* Regular FPU environment */
204 unsigned long cw;
205 unsigned long sw;
206 unsigned long tag;
207 unsigned long ipoff;
208 unsigned long cssel;
209 unsigned long dataoff;
210 unsigned long datasel;
211 struct _vki_fpreg _st[8];
212 unsigned short status;
213 unsigned short magic; /* 0xffff = regular FPU data only */
214
215 /* FXSR FPU environment */
216 unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */
217 unsigned long mxcsr;
218 unsigned long reserved;
219 struct _vki_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
220 struct _vki_xmmreg _xmm[8];
221 unsigned long padding[56];
222};
223
224struct vki_sigcontext {
225 unsigned long trap_no;
226 unsigned long error_code;
227 unsigned long oldmask;
228 unsigned long arm_r0;
229 unsigned long arm_r1;
230 unsigned long arm_r2;
231 unsigned long arm_r3;
232 unsigned long arm_r4;
233 unsigned long arm_r5;
234 unsigned long arm_r6;
235 unsigned long arm_r7;
236 unsigned long arm_r8;
237 unsigned long arm_r9;
238 unsigned long arm_r10;
239 unsigned long arm_fp;
240 unsigned long arm_ip;
241 unsigned long arm_sp;
242 unsigned long arm_lr;
243 unsigned long arm_pc;
244 unsigned long arm_cpsr;
245 unsigned long fault_address;
246};
247
248//----------------------------------------------------------------------
249// From linux-2.6.8.1/include/asm-i386/mman.h
250//----------------------------------------------------------------------
251
252#define VKI_PROT_NONE 0x0 /* No page permissions */
253#define VKI_PROT_READ 0x1 /* page can be read */
254#define VKI_PROT_WRITE 0x2 /* page can be written */
255#define VKI_PROT_EXEC 0x4 /* page can be executed */
256#define VKI_PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
257#define VKI_PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */
258
259#define VKI_MAP_SHARED 0x01 /* Share changes */
260#define VKI_MAP_PRIVATE 0x02 /* Changes are private */
261//#define VKI_MAP_TYPE 0x0f /* Mask for type of mapping */
262#define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */
263#define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */
264#define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */
265
266//----------------------------------------------------------------------
267// From linux-2.6.8.1/include/asm-i386/fcntl.h
268//----------------------------------------------------------------------
269
270#define VKI_O_RDONLY 00
271#define VKI_O_WRONLY 01
272#define VKI_O_RDWR 02
273#define VKI_O_CREAT 0100 /* not fcntl */
274#define VKI_O_EXCL 0200 /* not fcntl */
275#define VKI_O_TRUNC 01000 /* not fcntl */
276#define VKI_O_APPEND 02000
277#define VKI_O_NONBLOCK 04000
278#define VKI_O_LARGEFILE 0100000
279
280#define VKI_AT_FDCWD -100
281
282#define VKI_F_DUPFD 0 /* dup */
283#define VKI_F_GETFD 1 /* get close_on_exec */
284#define VKI_F_SETFD 2 /* set/clear close_on_exec */
285#define VKI_F_GETFL 3 /* get file->f_flags */
286#define VKI_F_SETFL 4 /* set file->f_flags */
287#define VKI_F_GETLK 5
288#define VKI_F_SETLK 6
289#define VKI_F_SETLKW 7
290
291#define VKI_F_SETOWN 8 /* for sockets. */
292#define VKI_F_GETOWN 9 /* for sockets. */
293#define VKI_F_SETSIG 10 /* for sockets. */
294#define VKI_F_GETSIG 11 /* for sockets. */
295
296#define VKI_F_GETLK64 12 /* using 'struct flock64' */
297#define VKI_F_SETLK64 13
298#define VKI_F_SETLKW64 14
299
300/* for F_[GET|SET]FL */
301#define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */
302
303#define VKI_F_LINUX_SPECIFIC_BASE 1024
304
305//----------------------------------------------------------------------
306// From linux-2.6.8.1/include/asm-i386/resource.h
307//----------------------------------------------------------------------
308
309#define VKI_RLIMIT_DATA 2 /* max data size */
310#define VKI_RLIMIT_STACK 3 /* max stack size */
311#define VKI_RLIMIT_CORE 4 /* max core file size */
312#define VKI_RLIMIT_NOFILE 7 /* max number of open files */
313
314//----------------------------------------------------------------------
315// From linux-2.6.8.1/include/asm-i386/socket.h
316//----------------------------------------------------------------------
317
318#define VKI_SOL_SOCKET 1
319
320#define VKI_SO_TYPE 3
321
322//----------------------------------------------------------------------
323// From linux-2.6.8.1/include/asm-i386/sockios.h
324//----------------------------------------------------------------------
325
326#define VKI_SIOCSPGRP 0x8902
327#define VKI_SIOCGPGRP 0x8904
328#define VKI_SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
329#define VKI_SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
330
331//----------------------------------------------------------------------
332// From linux-2.6.8.1/include/asm-i386/stat.h
333//----------------------------------------------------------------------
334
335struct vki_stat {
336 unsigned long st_dev;
337 unsigned long st_ino;
338 unsigned short st_mode;
339 unsigned short st_nlink;
340 unsigned short st_uid;
341 unsigned short st_gid;
342 unsigned long st_rdev;
343 unsigned long st_size;
344 unsigned long st_blksize;
345 unsigned long st_blocks;
346 unsigned long st_atime;
347 unsigned long st_atime_nsec;
348 unsigned long st_mtime;
349 unsigned long st_mtime_nsec;
350 unsigned long st_ctime;
351 unsigned long st_ctime_nsec;
352 unsigned long __unused4;
353 unsigned long __unused5;
354};
355
356struct vki_stat64 {
357 unsigned long long st_dev;
358 unsigned char __pad0[4];
359
360#define STAT64_HAS_BROKEN_ST_INO 1
361 unsigned long __st_ino;
362
363 unsigned int st_mode;
364 unsigned int st_nlink;
365
366 unsigned long st_uid;
367 unsigned long st_gid;
368
369 unsigned long long st_rdev;
370 unsigned char __pad3[4];
371
372 long long st_size;
373 unsigned long st_blksize;
374
375 unsigned long st_blocks; /* Number 512-byte blocks allocated. */
376 unsigned long __pad4; /* future possible st_blocks high bits */
377
378 unsigned long st_atime;
379 unsigned long st_atime_nsec;
380
381 unsigned long st_mtime;
382 unsigned int st_mtime_nsec;
383
384 unsigned long st_ctime;
385 unsigned long st_ctime_nsec;
386
387 unsigned long long st_ino;
388};
389
390//----------------------------------------------------------------------
391// From linux-2.6.8.1/include/asm-i386/statfs.h
392//----------------------------------------------------------------------
393
394// [[Nb: asm-i386/statfs.h just #include asm-generic/statfs.h directly]]
395struct vki_statfs {
396 __vki_u32 f_type;
397 __vki_u32 f_bsize;
398 __vki_u32 f_blocks;
399 __vki_u32 f_bfree;
400 __vki_u32 f_bavail;
401 __vki_u32 f_files;
402 __vki_u32 f_ffree;
403 __vki_kernel_fsid_t f_fsid;
404 __vki_u32 f_namelen;
405 __vki_u32 f_frsize;
406 __vki_u32 f_spare[5];
407};
408
409//----------------------------------------------------------------------
410// From linux-2.6.8.1/include/asm-i386/termios.h
411//----------------------------------------------------------------------
412
413struct vki_winsize {
414 unsigned short ws_row;
415 unsigned short ws_col;
416 unsigned short ws_xpixel;
417 unsigned short ws_ypixel;
418};
419
420#define VKI_NCC 8
421struct vki_termio {
422 unsigned short c_iflag; /* input mode flags */
423 unsigned short c_oflag; /* output mode flags */
424 unsigned short c_cflag; /* control mode flags */
425 unsigned short c_lflag; /* local mode flags */
426 unsigned char c_line; /* line discipline */
427 unsigned char c_cc[VKI_NCC]; /* control characters */
428};
429
430
431//----------------------------------------------------------------------
432// From linux-2.6.8.1/include/asm-i386/termbits.h
433//----------------------------------------------------------------------
434
435typedef unsigned char vki_cc_t;
436typedef unsigned int vki_tcflag_t;
437
438#define VKI_NCCS 19
439struct vki_termios {
440 vki_tcflag_t c_iflag; /* input mode flags */
441 vki_tcflag_t c_oflag; /* output mode flags */
442 vki_tcflag_t c_cflag; /* control mode flags */
443 vki_tcflag_t c_lflag; /* local mode flags */
444 vki_cc_t c_line; /* line discipline */
445 vki_cc_t c_cc[VKI_NCCS]; /* control characters */
446};
447
448//----------------------------------------------------------------------
449// From linux-2.6.8.1/include/asm-i386/ioctl.h
450//----------------------------------------------------------------------
451
452#define _VKI_IOC_NRBITS 8
453#define _VKI_IOC_TYPEBITS 8
454#define _VKI_IOC_SIZEBITS 14
455#define _VKI_IOC_DIRBITS 2
456
457#define _VKI_IOC_NRMASK ((1 << _VKI_IOC_NRBITS)-1)
458#define _VKI_IOC_TYPEMASK ((1 << _VKI_IOC_TYPEBITS)-1)
459#define _VKI_IOC_SIZEMASK ((1 << _VKI_IOC_SIZEBITS)-1)
460#define _VKI_IOC_DIRMASK ((1 << _VKI_IOC_DIRBITS)-1)
461
462#define _VKI_IOC_NRSHIFT 0
463#define _VKI_IOC_TYPESHIFT (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS)
464#define _VKI_IOC_SIZESHIFT (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS)
465#define _VKI_IOC_DIRSHIFT (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS)
466
467#define _VKI_IOC_NONE 0U
468#define _VKI_IOC_WRITE 1U
469#define _VKI_IOC_READ 2U
470
471#define _VKI_IOC(dir,type,nr,size) \
472 (((dir) << _VKI_IOC_DIRSHIFT) | \
473 ((type) << _VKI_IOC_TYPESHIFT) | \
474 ((nr) << _VKI_IOC_NRSHIFT) | \
475 ((size) << _VKI_IOC_SIZESHIFT))
476
477/* provoke compile error for invalid uses of size argument */
478extern unsigned int __vki_invalid_size_argument_for_IOC;
479#define _VKI_IOC_TYPECHECK(t) \
480 ((sizeof(t) == sizeof(t[1]) && \
481 sizeof(t) < (1 << _VKI_IOC_SIZEBITS)) ? \
482 sizeof(t) : __vki_invalid_size_argument_for_IOC)
483
484/* used to create numbers */
485#define _VKI_IO(type,nr) _VKI_IOC(_VKI_IOC_NONE,(type),(nr),0)
486#define _VKI_IOR(type,nr,size) _VKI_IOC(_VKI_IOC_READ,(type),(nr),(_VKI_IOC_TYPECHECK(size)))
487#define _VKI_IOW(type,nr,size) _VKI_IOC(_VKI_IOC_WRITE,(type),(nr),(_VKI_IOC_TYPECHECK(size)))
488#define _VKI_IOWR(type,nr,size) _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE,(type),(nr),(_VKI_IOC_TYPECHECK(size)))
489
490/* used to decode ioctl numbers.. */
491#define _VKI_IOC_DIR(nr) (((nr) >> _VKI_IOC_DIRSHIFT) & _VKI_IOC_DIRMASK)
492#define _VKI_IOC_TYPE(nr) (((nr) >> _VKI_IOC_TYPESHIFT) & _VKI_IOC_TYPEMASK)
493#define _VKI_IOC_NR(nr) (((nr) >> _VKI_IOC_NRSHIFT) & _VKI_IOC_NRMASK)
494#define _VKI_IOC_SIZE(nr) (((nr) >> _VKI_IOC_SIZESHIFT) & _VKI_IOC_SIZEMASK)
495
496//----------------------------------------------------------------------
497// From linux-2.6.8.1/include/asm-i386/ioctls.h
498//----------------------------------------------------------------------
499
500#define VKI_TCGETS 0x5401
501#define VKI_TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
502#define VKI_TCSETSW 0x5403
503#define VKI_TCSETSF 0x5404
504#define VKI_TCGETA 0x5405
505#define VKI_TCSETA 0x5406
506#define VKI_TCSETAW 0x5407
507#define VKI_TCSETAF 0x5408
508#define VKI_TCSBRK 0x5409
509#define VKI_TCXONC 0x540A
510#define VKI_TCFLSH 0x540B
511#define VKI_TIOCSCTTY 0x540E
512#define VKI_TIOCGPGRP 0x540F
513#define VKI_TIOCSPGRP 0x5410
514#define VKI_TIOCOUTQ 0x5411
515#define VKI_TIOCGWINSZ 0x5413
516#define VKI_TIOCSWINSZ 0x5414
517#define VKI_TIOCMGET 0x5415
518#define VKI_TIOCMBIS 0x5416
519#define VKI_TIOCMBIC 0x5417
520#define VKI_TIOCMSET 0x5418
521#define VKI_FIONREAD 0x541B
522#define VKI_TIOCLINUX 0x541C
523#define VKI_FIONBIO 0x5421
524#define VKI_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
525#define VKI_TIOCGPTN _VKI_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
526#define VKI_TIOCSPTLCK _VKI_IOW('T',0x31, int) /* Lock/unlock Pty */
527
528#define VKI_FIOASYNC 0x5452
529#define VKI_TIOCSERGETLSR 0x5459 /* Get line status register */
530
531#define VKI_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
532
533//----------------------------------------------------------------------
534// From asm-generic/poll.h
535//----------------------------------------------------------------------
536
537/* These are specified by iBCS2 */
538#define VKI_POLLIN 0x0001
539
540struct vki_pollfd {
541 int fd;
542 short events;
543 short revents;
544};
545
546//----------------------------------------------------------------------
547// From linux-2.6.8.1/include/asm-i386/user.h
548//----------------------------------------------------------------------
549
550struct vki_user_i387_struct {
551 long cwd;
552 long swd;
553 long twd;
554 long fip;
555 long fcs;
556 long foo;
557 long fos;
558 long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
559};
560
561struct vki_user_fxsr_struct {
562 unsigned short cwd;
563 unsigned short swd;
564 unsigned short twd;
565 unsigned short fop;
566 long fip;
567 long fcs;
568 long foo;
569 long fos;
570 long mxcsr;
571 long reserved;
572 long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
573 long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
574 long padding[56];
575};
576
577struct vki_user_regs_struct {
578 long uregs[18];
579};
580#define ARM_cpsr uregs[16]
581#define ARM_pc uregs[15]
582#define ARM_lr uregs[14]
583#define ARM_sp uregs[13]
584#define ARM_ip uregs[12]
585#define ARM_fp uregs[11]
586#define ARM_r10 uregs[10]
587#define ARM_r9 uregs[9]
588#define ARM_r8 uregs[8]
589#define ARM_r7 uregs[7]
590#define ARM_r6 uregs[6]
591#define ARM_r5 uregs[5]
592#define ARM_r4 uregs[4]
593#define ARM_r3 uregs[3]
594#define ARM_r2 uregs[2]
595#define ARM_r1 uregs[1]
596#define ARM_r0 uregs[0]
597#define ARM_ORIG_r0 uregs[17]
598//----------------------------------------------------------------------
599// From linux-2.6.8.1/include/asm-i386/elf.h
600//----------------------------------------------------------------------
601
602typedef unsigned long vki_elf_greg_t;
603
604#define VKI_ELF_NGREG (sizeof (struct vki_user_regs_struct) / sizeof(vki_elf_greg_t))
605typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG];
606
607typedef struct vki_user_i387_struct vki_elf_fpregset_t;
608typedef struct vki_user_fxsr_struct vki_elf_fpxregset_t;
609
610#define VKI_AT_SYSINFO 32
611
612//----------------------------------------------------------------------
613// From linux-2.6.8.1/include/asm-i386/ucontext.h
614//----------------------------------------------------------------------
615
616struct vki_ucontext {
617 unsigned long uc_flags;
618 struct vki_ucontext *uc_link;
619 vki_stack_t uc_stack;
620 struct vki_sigcontext uc_mcontext;
621 vki_sigset_t uc_sigmask; /* mask last for extensibility */
622 int __unused[32 - (sizeof (vki_sigset_t) / sizeof (int))];
623 unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
624
625};
626
627//----------------------------------------------------------------------
628// From linux-2.6.8.1/include/asm-i386/segment.h
629//----------------------------------------------------------------------
630
631#define VKI_GDT_ENTRY_TLS_ENTRIES 3
632#define VKI_GDT_ENTRY_TLS_MIN 6
633#define VKI_GDT_ENTRY_TLS_MAX (VKI_GDT_ENTRY_TLS_MIN + VKI_GDT_ENTRY_TLS_ENTRIES - 1)
634
635//----------------------------------------------------------------------
636// From linux-2.6.8.1/include/asm-i386/ldt.h
637//----------------------------------------------------------------------
638
639/* [[Nb: This is the structure passed to the modify_ldt syscall. Just so as
640 to confuse and annoy everyone, this is _not_ the same as an
641 VgLdtEntry and has to be translated into such. The logic for doing
642 so, in vg_ldt.c, is copied from the kernel sources.]] */
643struct vki_user_desc {
644 unsigned int entry_number;
645 unsigned long base_addr;
646 unsigned int limit;
647 unsigned int seg_32bit:1;
648 unsigned int contents:2;
649 unsigned int read_exec_only:1;
650 unsigned int limit_in_pages:1;
651 unsigned int seg_not_present:1;
652 unsigned int useable:1;
653 // [[Nb: this field is not in the kernel sources, but it has always
654 // been in the Valgrind sources so I will keep it there in case it's
655 // important... this is an x86-defined data structure so who
656 // knows; maybe it's important to set this field to zero at some
657 // point. --njn]]
658 unsigned int reserved:25;
659};
660
661// [[Nb: for our convenience within Valgrind, use a more specific name]]
662typedef struct vki_user_desc vki_modify_ldt_t;
663
664//----------------------------------------------------------------------
665// From linux-2.6.8.1/include/asm-i386/ipcbuf.h
666//----------------------------------------------------------------------
667
668struct vki_ipc64_perm
669{
670 __vki_kernel_key_t key;
671 __vki_kernel_uid32_t uid;
672 __vki_kernel_gid32_t gid;
673 __vki_kernel_uid32_t cuid;
674 __vki_kernel_gid32_t cgid;
675 __vki_kernel_mode_t mode;
676 unsigned short __pad1;
677 unsigned short seq;
678 unsigned short __pad2;
679 unsigned long __unused1;
680 unsigned long __unused2;
681};
682
683//----------------------------------------------------------------------
684// From linux-2.6.8.1/include/asm-i386/sembuf.h
685//----------------------------------------------------------------------
686
687struct vki_semid64_ds {
688 struct vki_ipc64_perm sem_perm; /* permissions .. see ipc.h */
689 __vki_kernel_time_t sem_otime; /* last semop time */
690 unsigned long __unused1;
691 __vki_kernel_time_t sem_ctime; /* last change time */
692 unsigned long __unused2;
693 unsigned long sem_nsems; /* no. of semaphores in array */
694 unsigned long __unused3;
695 unsigned long __unused4;
696};
697
698//----------------------------------------------------------------------
699// From linux-2.6.8.1/include/asm-i386/msgbuf.h
700//----------------------------------------------------------------------
701
702struct vki_msqid64_ds {
703 struct vki_ipc64_perm msg_perm;
704 __vki_kernel_time_t msg_stime; /* last msgsnd time */
705 unsigned long __unused1;
706 __vki_kernel_time_t msg_rtime; /* last msgrcv time */
707 unsigned long __unused2;
708 __vki_kernel_time_t msg_ctime; /* last change time */
709 unsigned long __unused3;
710 unsigned long msg_cbytes; /* current number of bytes on queue */
711 unsigned long msg_qnum; /* number of messages in queue */
712 unsigned long msg_qbytes; /* max number of bytes on queue */
713 __vki_kernel_pid_t msg_lspid; /* pid of last msgsnd */
714 __vki_kernel_pid_t msg_lrpid; /* last receive pid */
715 unsigned long __unused4;
716 unsigned long __unused5;
717};
718
719//----------------------------------------------------------------------
720// From linux-2.6.8.1/include/asm-i386/ipc.h
721//----------------------------------------------------------------------
722
723struct vki_ipc_kludge {
724 struct vki_msgbuf __user *msgp;
725 long msgtyp;
726};
727
728#define VKI_SEMOP 1
729#define VKI_SEMGET 2
730#define VKI_SEMCTL 3
731#define VKI_SEMTIMEDOP 4
732#define VKI_MSGSND 11
733#define VKI_MSGRCV 12
734#define VKI_MSGGET 13
735#define VKI_MSGCTL 14
736#define VKI_SHMAT 21
737#define VKI_SHMDT 22
738#define VKI_SHMGET 23
739#define VKI_SHMCTL 24
740
741
742//----------------------------------------------------------------------
743// From linux-2.6.8.1/include/asm-i386/shmbuf.h
744//----------------------------------------------------------------------
745
746struct vki_shmid64_ds {
747 struct vki_ipc64_perm shm_perm; /* operation perms */
748 vki_size_t shm_segsz; /* size of segment (bytes) */
749 __vki_kernel_time_t shm_atime; /* last attach time */
750 unsigned long __unused1;
751 __vki_kernel_time_t shm_dtime; /* last detach time */
752 unsigned long __unused2;
753 __vki_kernel_time_t shm_ctime; /* last change time */
754 unsigned long __unused3;
755 __vki_kernel_pid_t shm_cpid; /* pid of creator */
756 __vki_kernel_pid_t shm_lpid; /* pid of last operator */
757 unsigned long shm_nattch; /* no. of current attaches */
758 unsigned long __unused4;
759 unsigned long __unused5;
760};
761
762struct vki_shminfo64 {
763 unsigned long shmmax;
764 unsigned long shmmin;
765 unsigned long shmmni;
766 unsigned long shmseg;
767 unsigned long shmall;
768 unsigned long __unused1;
769 unsigned long __unused2;
770 unsigned long __unused3;
771 unsigned long __unused4;
772};
773
774//----------------------------------------------------------------------
775// DRM ioctls
776//----------------------------------------------------------------------
777
778// jrs 20050207: where did all this stuff come from? Is it really
779// i386 specific, or should it go into the linux-generic category?
780//struct vki_drm_buf_pub {
781// Int idx; /**< Index into the master buffer list */
782// Int total; /**< Buffer size */
783// Int used; /**< Amount of buffer in use (for DMA) */
784// void __user *address; /**< Address of buffer */
785//};
786//
787//struct vki_drm_buf_map {
788// Int count; /**< Length of the buffer list */
789// void __user *virtual; /**< Mmap'd area in user-virtual */
790// struct vki_drm_buf_pub __user *list; /**< Buffer information */
791//};
792//
793///* We need to pay attention to this, because it mmaps memory */
794//#define VKI_DRM_IOCTL_MAP_BUFS _VKI_IOWR('d', 0x19, struct vki_drm_buf_map)
795
796//----------------------------------------------------------------------
797// From linux-2.6.9/include/asm-i386/ptrace.h
798//----------------------------------------------------------------------
799
800#define VKI_PTRACE_GETREGS 12
801#define VKI_PTRACE_SETREGS 13
802#define VKI_PTRACE_GETFPREGS 14
803#define VKI_PTRACE_SETFPREGS 15
804#define VKI_PTRACE_GETFPXREGS 18
805#define VKI_PTRACE_SETFPXREGS 19
806
807//----------------------------------------------------------------------
808// From linux-2.6.15.4/include/asm-i386/vm86.h
809//----------------------------------------------------------------------
810
811#define VKI_VM86_PLUS_INSTALL_CHECK 0
812#define VKI_VM86_ENTER 1
813#define VKI_VM86_ENTER_NO_BYPASS 2
814#define VKI_VM86_REQUEST_IRQ 3
815#define VKI_VM86_FREE_IRQ 4
816#define VKI_VM86_GET_IRQ_BITS 5
817#define VKI_VM86_GET_AND_RESET_IRQ 6
818
819struct vki_vm86_regs {
820/*
821 * normal regs, with special meaning for the segment descriptors..
822 */
823 long ebx;
824 long ecx;
825 long edx;
826 long esi;
827 long edi;
828 long ebp;
829 long eax;
830 long __null_ds;
831 long __null_es;
832 long __null_fs;
833 long __null_gs;
834 long orig_eax;
835 long eip;
836 unsigned short cs, __csh;
837 long eflags;
838 long esp;
839 unsigned short ss, __ssh;
840/*
841 * these are specific to v86 mode:
842 */
843 unsigned short es, __esh;
844 unsigned short ds, __dsh;
845 unsigned short fs, __fsh;
846 unsigned short gs, __gsh;
847};
848
849struct vki_revectored_struct {
850 unsigned long __map[8]; /* 256 bits */
851};
852
853struct vki_vm86_struct {
854 struct vki_vm86_regs regs;
855 unsigned long flags;
856 unsigned long screen_bitmap;
857 unsigned long cpu_type;
858 struct vki_revectored_struct int_revectored;
859 struct vki_revectored_struct int21_revectored;
860};
861
862struct vki_vm86plus_info_struct {
863 unsigned long force_return_for_pic:1;
864 unsigned long vm86dbg_active:1; /* for debugger */
865 unsigned long vm86dbg_TFpendig:1; /* for debugger */
866 unsigned long unused:28;
867 unsigned long is_vm86pus:1; /* for vm86 internal use */
868 unsigned char vm86dbg_intxxtab[32]; /* for debugger */
869};
870
871struct vki_vm86plus_struct {
872 struct vki_vm86_regs regs;
873 unsigned long flags;
874 unsigned long screen_bitmap;
875 unsigned long cpu_type;
876 struct vki_revectored_struct int_revectored;
877 struct vki_revectored_struct int21_revectored;
878 struct vki_vm86plus_info_struct vm86plus;
879};
880
881//----------------------------------------------------------------------
882// And that's it!
883//----------------------------------------------------------------------
884
885#endif // __VKI_ARM_LINUX_H
886
887/*--------------------------------------------------------------------*/
888/*--- end vki-arm-linux.h ---*/
889/*--------------------------------------------------------------------*/
  
8787# include "vki-posixtypes-ppc32-linux.h"
8888#elif defined(VGA_ppc64)
8989# include "vki-posixtypes-ppc64-linux.h"
90#elif defined(VGA_arm)
91# include "vki-posixtypes-arm-linux.h"
9092#else
9193# error Unknown platform
9294#endif
171171# include "vki-ppc32-linux.h"
172172#elif defined(VGA_ppc64)
173173# include "vki-ppc64-linux.h"
174#elif defined(VGA_arm)
175# include "vki-arm-linux.h"
174176#else
175177# error Unknown platform
176178#endif
  
1
2/*--------------------------------------------------------------------*/
3/*--- arm/Linux-specific kernel interface: posix types. ---*/
4/*--- vki-posixtypes-arm-linux.h ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2009 Julian Seward
12 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32#ifndef __VKI_POSIXTYPES_ARM_LINUX_H
33#define __VKI_POSIXTYPES_ARM_LINUX_H
34
35//----------------------------------------------------------------------
36// From linux-2.6.8.1/include/asm-i386/posix_types.h
37//----------------------------------------------------------------------
38
39typedef unsigned short __vki_kernel_mode_t;
40typedef long __vki_kernel_off_t;
41typedef int __vki_kernel_pid_t;
42typedef unsigned short __vki_kernel_ipc_pid_t;
43typedef unsigned short __vki_kernel_uid_t;
44typedef unsigned short __vki_kernel_gid_t;
45typedef unsigned int __vki_kernel_size_t;
46typedef long __vki_kernel_time_t;
47typedef long __vki_kernel_suseconds_t;
48typedef long __vki_kernel_clock_t;
49typedef int __vki_kernel_timer_t;
50typedef int __vki_kernel_clockid_t;
51typedef char * __vki_kernel_caddr_t;
52typedef unsigned int __vki_kernel_uid32_t;
53typedef unsigned int __vki_kernel_gid32_t;
54
55typedef unsigned short __vki_kernel_old_uid_t;
56typedef unsigned short __vki_kernel_old_gid_t;
57
58typedef long long __vki_kernel_loff_t;
59
60typedef struct {
61 int val[2];
62} __vki_kernel_fsid_t;
63
64#endif // __VKI_POSIXTYPES_ARM_LINUX_H
65
66/*--------------------------------------------------------------------*/
67/*--- end vki-posixtypes-arm-linux.h ---*/
68/*--------------------------------------------------------------------*/
  
1
2/*--------------------------------------------------------------------*/
3/*--- System call numbers for arm-linux. ---*/
4/*--- vki-scnums-arm-linux.h ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2008-2009 Evan Geller
12 gaze@bea.ms
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32#ifndef __VKI_SCNUMS_ARM_LINUX_H
33#define __VKI_SCNUMS_ARM_LINUX_H
34
35// From linux-2.6.26.2/include/asm-arm/unistd.h
36
37#define __NR_restart_syscall 0
38#define __NR_exit 1
39#define __NR_fork 2
40#define __NR_read 3
41#define __NR_write 4
42#define __NR_open 5
43#define __NR_close 6
44 /* 7 was sys_waitpid */
45#define __NR_creat 8
46#define __NR_link 9
47#define __NR_unlink 10
48#define __NR_execve 11
49#define __NR_chdir 12
50#define __NR_time 13
51#define __NR_mknod 14
52#define __NR_chmod 15
53#define __NR_lchown 16
54 /* 17 was sys_break */
55 /* 18 was sys_stat */
56#define __NR_lseek 19
57#define __NR_getpid 20
58#define __NR_mount 21
59#define __NR_umount 22
60#define __NR_setuid 23
61#define __NR_getuid 24
62#define __NR_stime 25
63#define __NR_ptrace 26
64#define __NR_alarm 27
65 /* 28 was sys_fstat */
66#define __NR_pause 29
67#define __NR_utime 30
68 /* 31 was sys_stty */
69 /* 32 was sys_gtty */
70#define __NR_access 33
71#define __NR_nice 34
72 /* 35 was sys_ftime */
73#define __NR_sync 36
74#define __NR_kill 37
75#define __NR_rename 38
76#define __NR_mkdir 39
77#define __NR_rmdir 40
78#define __NR_dup 41
79#define __NR_pipe 42
80#define __NR_times 43
81 /* 44 was sys_prof */
82#define __NR_brk 45
83#define __NR_setgid 46
84#define __NR_getgid 47
85 /* 48 was sys_signal */
86#define __NR_geteuid 49
87#define __NR_getegid 50
88#define __NR_acct 51
89#define __NR_umount2 52
90 /* 53 was sys_lock */
91#define __NR_ioctl 54
92#define __NR_fcntl 55
93 /* 56 was sys_mpx */
94#define __NR_setpgid 57
95 /* 58 was sys_ulimit */
96 /* 59 was sys_olduname */
97#define __NR_umask 60
98#define __NR_chroot 61
99#define __NR_ustat 62
100#define __NR_dup2 63
101#define __NR_getppid 64
102#define __NR_getpgrp 65
103#define __NR_setsid 66
104#define __NR_sigaction 67
105 /* 68 was sys_sgetmask */
106 /* 69 was sys_ssetmask */
107#define __NR_setreuid 70
108#define __NR_setregid 71
109#define __NR_sigsuspend 72
110#define __NR_sigpending 73
111#define __NR_sethostname 74
112#define __NR_setrlimit 75
113#define __NR_getrlimit 76 /* Back compat 2GB limited rlimit */
114#define __NR_getrusage 77
115#define __NR_gettimeofday 78
116#define __NR_settimeofday 79
117#define __NR_getgroups 80
118#define __NR_setgroups 81
119#define __NR_select 82
120#define __NR_symlink 83
121 /* 84 was sys_lstat */
122#define __NR_readlink 85
123#define __NR_uselib 86
124#define __NR_swapon 87
125#define __NR_reboot 88
126#define __NR_readdir 89
127#define __NR_mmap 90
128#define __NR_munmap 91
129#define __NR_truncate 92
130#define __NR_ftruncate 93
131#define __NR_fchmod 94
132#define __NR_fchown 95
133#define __NR_getpriority 96
134#define __NR_setpriority 97
135 /* 98 was sys_profil */
136#define __NR_statfs 99
137#define __NR_fstatfs 100
138 /* 101 was sys_ioperm */
139#define __NR_socketcall 102
140#define __NR_syslog 103
141#define __NR_setitimer 104
142#define __NR_getitimer 105
143#define __NR_stat 106
144#define __NR_lstat 107
145#define __NR_fstat 108
146 /* 109 was sys_uname */
147 /* 110 was sys_iopl */
148#define __NR_vhangup 111
149 /* 112 was sys_idle */
150#define __NR_syscall 113 /* syscall to call a syscall! */
151#define __NR_wait4 114
152#define __NR_swapoff 115
153#define __NR_sysinfo 116
154#define __NR_ipc 117
155#define __NR_fsync 118
156#define __NR_sigreturn 119
157#define __NR_clone 120
158#define __NR_setdomainname 121
159#define __NR_uname 122
160 /* 123 was sys_modify_ldt */
161#define __NR_adjtimex 124
162#define __NR_mprotect 125
163#define __NR_sigprocmask 126
164 /* 127 was sys_create_module */
165#define __NR_init_module 128
166#define __NR_delete_module 129
167 /* 130 was sys_get_kernel_syms */
168#define __NR_quotactl 131
169#define __NR_getpgid 132
170#define __NR_fchdir 133
171#define __NR_bdflush 134
172#define __NR_sysfs 135
173#define __NR_personality 136
174 /* 137 was sys_afs_syscall */
175#define __NR_setfsuid 138
176#define __NR_setfsgid 139
177#define __NR__llseek 140
178#define __NR_getdents 141
179#define __NR__newselect 142
180#define __NR_flock 143
181#define __NR_msync 144
182#define __NR_readv 145
183#define __NR_writev 146
184#define __NR_getsid 147
185#define __NR_fdatasync 148
186#define __NR__sysctl 149
187#define __NR_mlock 150
188#define __NR_munlock 151
189#define __NR_mlockall 152
190#define __NR_munlockall 153
191#define __NR_sched_setparam 154
192#define __NR_sched_getparam 155
193#define __NR_sched_setscheduler 156
194#define __NR_sched_getscheduler 157
195#define __NR_sched_yield 158
196#define __NR_sched_get_priority_max 159
197#define __NR_sched_get_priority_min 160
198#define __NR_sched_rr_get_interval 161
199#define __NR_nanosleep 162
200#define __NR_mremap 163
201#define __NR_setresuid 164
202#define __NR_getresuid 165
203 /* 166 was sys_vm86 */
204 /* 167 was sys_query_module */
205#define __NR_poll 168
206#define __NR_nfsservctl 169
207#define __NR_setresgid 170
208#define __NR_getresgid 171
209#define __NR_prctl 172
210#define __NR_rt_sigreturn 173
211#define __NR_rt_sigaction 174
212#define __NR_rt_sigprocmask 175
213#define __NR_rt_sigpending 176
214#define __NR_rt_sigtimedwait 177
215#define __NR_rt_sigqueueinfo 178
216#define __NR_rt_sigsuspend 179
217#define __NR_pread64 180
218#define __NR_pwrite64 181
219#define __NR_chown 182
220#define __NR_getcwd 183
221#define __NR_capget 184
222#define __NR_capset 185
223#define __NR_sigaltstack 186
224#define __NR_sendfile 187
225 /* 188 reserved */
226 /* 189 reserved */
227#define __NR_vfork 190
228#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
229#define __NR_mmap2 192
230#define __NR_truncate64 193
231#define __NR_ftruncate64 194
232#define __NR_stat64 195
233#define __NR_lstat64 196
234#define __NR_fstat64 197
235#define __NR_lchown32 198
236#define __NR_getuid32 199
237#define __NR_getgid32 200
238#define __NR_geteuid32 201
239#define __NR_getegid32 202
240#define __NR_setreuid32 203
241#define __NR_setregid32 204
242#define __NR_getgroups32 205
243#define __NR_setgroups32 206
244#define __NR_fchown32 207
245#define __NR_setresuid32 208
246#define __NR_getresuid32 209
247#define __NR_setresgid32 210
248#define __NR_getresgid32 211
249#define __NR_chown32 212
250#define __NR_setuid32 213
251#define __NR_setgid32 214
252#define __NR_setfsuid32 215
253#define __NR_setfsgid32 216
254#define __NR_getdents64 217
255#define __NR_pivot_root 218
256#define __NR_mincore 219
257#define __NR_madvise 220
258#define __NR_fcntl64 221
259 /* 222 for tux */
260 /* 223 is unused */
261#define __NR_gettid 224
262#define __NR_readahead 225
263#define __NR_setxattr 226
264#define __NR_lsetxattr 227
265#define __NR_fsetxattr 228
266#define __NR_getxattr 229
267#define __NR_lgetxattr 230
268#define __NR_fgetxattr 231
269#define __NR_listxattr 232
270#define __NR_llistxattr 233
271#define __NR_flistxattr 234
272#define __NR_removexattr 235
273#define __NR_lremovexattr 236
274#define __NR_fremovexattr 237
275#define __NR_tkill 238
276#define __NR_sendfile64 239
277#define __NR_futex 240
278#define __NR_sched_setaffinity 241
279#define __NR_sched_getaffinity 242
280#define __NR_io_setup 243
281#define __NR_io_destroy 244
282#define __NR_io_getevents 245
283#define __NR_io_submit 246
284#define __NR_io_cancel 247
285#define __NR_exit_group 248
286#define __NR_lookup_dcookie 249
287#define __NR_epoll_create 250
288#define __NR_epoll_ctl 251
289#define __NR_epoll_wait 252
290#define __NR_remap_file_pages 253
291 /* 254 for set_thread_area */
292 /* 255 for get_thread_area */
293#define __NR_set_tid_address 256
294#define __NR_timer_create 257
295#define __NR_timer_settime 258
296#define __NR_timer_gettime 259
297#define __NR_timer_getoverrun 260
298#define __NR_timer_delete 261
299#define __NR_clock_settime 262
300#define __NR_clock_gettime 263
301#define __NR_clock_getres 264
302#define __NR_clock_nanosleep 265
303#define __NR_statfs64 266
304#define __NR_fstatfs64 267
305#define __NR_tgkill 268
306#define __NR_utimes 269
307#define __NR_arm_fadvise64_64 270
308#define __NR_fadvise64 270 //Added by Johan, 2008-10-11, not sure why it's called _arm_.. otherwise.
309#define __NR_pciconfig_iobase 271
310#define __NR_pciconfig_read 272
311#define __NR_pciconfig_write 273
312#define __NR_mq_open 274
313#define __NR_mq_unlink 275
314#define __NR_mq_timedsend 276
315#define __NR_mq_timedreceive 277
316#define __NR_mq_notify 278
317#define __NR_mq_getsetattr 279
318#define __NR_waitid 280
319#define __NR_socket 281
320#define __NR_bind 282
321#define __NR_connect 283
322#define __NR_listen 284
323#define __NR_accept 285
324#define __NR_getsockname 286
325#define __NR_getpeername 287
326#define __NR_socketpair 288
327#define __NR_send 289
328#define __NR_sendto 290
329#define __NR_recv 291
330#define __NR_recvfrom 292
331#define __NR_shutdown 293
332#define __NR_setsockopt 294
333#define __NR_getsockopt 295
334#define __NR_sendmsg 296
335#define __NR_recvmsg 297
336#define __NR_semop 298
337#define __NR_semget 299
338#define __NR_semctl 300
339#define __NR_msgsnd 301
340#define __NR_msgrcv 302
341#define __NR_msgget 303
342#define __NR_msgctl 304
343#define __NR_shmat 305
344#define __NR_shmdt 306
345#define __NR_shmget 307
346#define __NR_shmctl 308
347#define __NR_add_key 309
348#define __NR_request_key 310
349#define __NR_keyctl 311
350#define __NR_semtimedop 312
351#define __NR_vserver 313
352#define __NR_ioprio_set 314
353#define __NR_ioprio_get 315
354#define __NR_inotify_init 316
355#define __NR_inotify_add_watch 317
356#define __NR_inotify_rm_watch 318
357#define __NR_mbind 319
358#define __NR_get_mempolicy 320
359#define __NR_set_mempolicy 321
360#define __NR_openat 322
361#define __NR_mkdirat 323
362#define __NR_mknodat 324
363#define __NR_fchownat 325
364#define __NR_futimesat 326
365#define __NR_fstatat64 327
366#define __NR_unlinkat 328
367#define __NR_renameat 329
368#define __NR_linkat 330
369#define __NR_symlinkat 331
370#define __NR_readlinkat 332
371#define __NR_fchmodat 333
372#define __NR_faccessat 334
373 /* 335 for pselect6 */
374 /* 336 for ppoll */
375#define __NR_unshare 337
376#define __NR_set_robust_list 338
377#define __NR_get_robust_list 339
378#define __NR_splice 340
379#define __NR_arm_sync_file_range 341
380#define __NR_sync_file_range2 __NR_arm_sync_file_range
381#define __NR_tee 342
382#define __NR_vmsplice 343
383#define __NR_move_pages 344
384#define __NR_getcpu 345
385 /* 346 for epoll_pwait */
386#define __NR_kexec_load 347
387#define __NR_utimensat 348
388#define __NR_signalfd 349
389#define __NR_timerfd_create 350
390#define __NR_eventfd 351
391#define __NR_fallocate 352
392#define __NR_timerfd_settime 353
393#define __NR_timerfd_gettime 354
394
395
396#define __NR_ARM_BASE (0x0f0000)
397#define __NR_ARM_breakpoint (__NR_ARM_BASE+1)
398#define __NR_ARM_cacheflush (__NR_ARM_BASE+2)
399#define __NR_ARM_usr26 (__NR_ARM_BASE+3)
400#define __NR_ARM_usr32 (__NR_ARM_BASE+4)
401#define __NR_ARM_set_tls (__NR_ARM_BASE+5)
402
403
404#endif /* __VKI_SCNUMS_ARM_LINUX_H */
405
406/*--------------------------------------------------------------------*/
407/*--- end vki-scnums-arm-linux.h ---*/
408/*--------------------------------------------------------------------*/
  
6565# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC64State)
6666#endif
6767
68#if defined(VGA_arm)
69# include "libvex_guest_arm.h"
70# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestARMState)
71#endif
72
6873static inline Bool host_is_big_endian ( void ) {
6974 UInt x = 0x11223344;
7075 return 0x1122 == *(UShort*)(&x);
679679# undef GOF
680680# undef SZB
681681
682 /* --------------------- arm --------------------- */
683
684# elif defined(VGA_arm)
685
686# define GOF(_fieldname) \
687 (offsetof(VexGuestARMState,guest_##_fieldname))
688# define SZB(_fieldname) \
689 (sizeof(((VexGuestARMState*)0)->guest_##_fieldname))
690
691 Int o = offset;
692 Int sz = szB;
693 tl_assert(sz > 0);
694 tl_assert(host_is_little_endian());
695
696 if (o == GOF(R0) && sz == 4) return o;
697 if (o == GOF(R1) && sz == 4) return o;
698 if (o == GOF(R2) && sz == 4) return o;
699 if (o == GOF(R3) && sz == 4) return o;
700 if (o == GOF(R4) && sz == 4) return o;
701 if (o == GOF(R5) && sz == 4) return o;
702 if (o == GOF(R6) && sz == 4) return o;
703 if (o == GOF(R7) && sz == 4) return o;
704 if (o == GOF(R8) && sz == 4) return o;
705 if (o == GOF(R9) && sz == 4) return o;
706 if (o == GOF(R10) && sz == 4) return o;
707 if (o == GOF(R11) && sz == 4) return o;
708 if (o == GOF(R12) && sz == 4) return o;
709 if (o == GOF(R13) && sz == 4) return o;
710 if (o == GOF(R14) && sz == 4) return o;
711
712 /* EAZG: These may be completely wrong. */
713 if (o == GOF(R15) && sz == 4) return -1; /* slot unused */
714 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot unused */
715
716 if (o == GOF(CC_DEP1) && sz == 4) return o;
717 if (o == GOF(CC_DEP2) && sz == 4) return o;
718
719 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot unused */
720
721 //if (o == GOF(SYSCALLNO) && sz == 4) return -1; /* slot unused */
722 //if (o == GOF(CC) && sz == 4) return -1; /* slot unused */
723 //if (o == GOF(EMWARN) && sz == 4) return -1; /* slot unused */
724 //if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
725 //if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
726
727 if (o == GOF(FPSCR) && sz == 4) return -1;
728 if (o == GOF(TPIDRURO) && sz == 4) return -1;
729
730 if (o >= GOF(D0) && o+sz <= GOF(D0) +SZB(D0)) return -1;
731 if (o >= GOF(D1) && o+sz <= GOF(D1) +SZB(D1)) return -1;
732 if (o >= GOF(D2) && o+sz <= GOF(D2) +SZB(D2)) return -1;
733 if (o >= GOF(D3) && o+sz <= GOF(D3) +SZB(D3)) return -1;
734 if (o >= GOF(D4) && o+sz <= GOF(D4) +SZB(D4)) return -1;
735 if (o >= GOF(D5) && o+sz <= GOF(D5) +SZB(D5)) return -1;
736 if (o >= GOF(D6) && o+sz <= GOF(D6) +SZB(D6)) return -1;
737 if (o >= GOF(D7) && o+sz <= GOF(D7) +SZB(D7)) return -1;
738 if (o >= GOF(D8) && o+sz <= GOF(D8) +SZB(D8)) return -1;
739 if (o >= GOF(D9) && o+sz <= GOF(D9) +SZB(D9)) return -1;
740 if (o >= GOF(D10) && o+sz <= GOF(D10)+SZB(D10)) return -1;
741 if (o >= GOF(D11) && o+sz <= GOF(D11)+SZB(D11)) return -1;
742 if (o >= GOF(D12) && o+sz <= GOF(D12)+SZB(D12)) return -1;
743 if (o >= GOF(D13) && o+sz <= GOF(D13)+SZB(D13)) return -1;
744 if (o >= GOF(D14) && o+sz <= GOF(D14)+SZB(D14)) return -1;
745 if (o >= GOF(D15) && o+sz <= GOF(D15)+SZB(D15)) return -1;
746
747 VG_(printf)("MC_(get_otrack_shadow_offset)(arm)(off=%d,sz=%d)\n",
748 offset,szB);
749 tl_assert(0);
750# undef GOF
751# undef SZB
752
682753# else
683754# error "FIXME: not implemented for this architecture"
684755# endif
827827 return Ity_I64;
828828
829829 VG_(printf)("get_reg_array_equiv_int_type(x86): unhandled: ");
830 ppIRRegArray(arr);
831 VG_(printf)("\n");
832 tl_assert(0);
833
834 /* --------------------- arm --------------------- */
835# elif defined(VGA_arm)
836
837 VG_(printf)("get_reg_array_equiv_int_type(arm): unhandled: ");
830838 ppIRRegArray(arr);
831839 VG_(printf)("\n");
832840 tl_assert(0);
  
13921392 /* I32 x I64 x I64 -> I32 */
13931393 if (t1 == Ity_I32 && t2 == Ity_I64 && t3 == Ity_I64
13941394 && finalVty == Ity_I32) {
1395 if (0) VG_(printf)("mkLazy3: I32 x I64 x I64 -> I64\n");
1395 if (0) VG_(printf)("mkLazy3: I32 x I64 x I64 -> I32\n");
13961396 at = mkPCastTo(mce, Ity_I64, va1);
13971397 at = mkUifU(mce, Ity_I64, at, va2);
13981398 at = mkUifU(mce, Ity_I64, at, va3);
14001400 return at;
14011401 }
14021402
1403 /* I32 x I32 x I32 -> I32 */
1404 /* 32-bit FP idiom, as (eg) happens on ARM */
1405 if (t1 == Ity_I32 && t2 == Ity_I32 && t3 == Ity_I32
1406 && finalVty == Ity_I32) {
1407 if (0) VG_(printf)("mkLazy3: I32 x I32 x I32 -> I32\n");
1408 at = va1;
1409 at = mkUifU(mce, Ity_I32, at, va2);
1410 at = mkUifU(mce, Ity_I32, at, va3);
1411 at = mkPCastTo(mce, Ity_I32, at);
1412 return at;
1413 }
1414
14031415 if (1) {
14041416 VG_(printf)("mkLazy3: ");
14051417 ppIRType(t1);
20712071 case Iop_PRem1C3210F64:
20722072 /* I32(rm) x F64 x F64 -> I32 */
20732073 return mkLazy3(mce, Ity_I32, vatom1, vatom2, vatom3);
2074 case Iop_AddF32:
2075 case Iop_SubF32:
2076 case Iop_MulF32:
2077 case Iop_DivF32:
2078 /* I32(rm) x F32 x F32 -> I32 */
2079 return mkLazy3(mce, Ity_I32, vatom1, vatom2, vatom3);
20742080 default:
20752081 ppIROp(op);
20762082 VG_(tool_panic)("memcheck:expr2vbits_Triop");
24262426 /* I32(rm) x I64/F64 -> I64/F64 */
24272427 return mkLazy2(mce, Ity_I64, vatom1, vatom2);
24282428
2429 case Iop_F64toI32U:
24292430 case Iop_F64toI32S:
24302431 case Iop_F64toF32:
24312432 /* First arg is I32 (rounding mode), second is F64 (data). */
26862686
26872687 case Iop_F32toF64:
26882688 case Iop_I32StoF64:
2689 case Iop_I32UtoF64:
26892690 case Iop_NegF64:
26902691 case Iop_AbsF64:
26912692 case Iop_Est5FRSqrt:
27012701 case Iop_Clz32:
27022702 case Iop_Ctz32:
27032703 case Iop_TruncF64asF32:
2704 case Iop_NegF32:
2705 case Iop_AbsF32:
27042706 return mkPCastTo(mce, Ity_I32, vatom);
27052707
27062708 case Iop_1Uto64:
27522752 case Iop_ReinterpF64asI64:
27532753 case Iop_ReinterpI64asF64:
27542754 case Iop_ReinterpI32asF32:
2755 case Iop_ReinterpF32asI32:
27552756 case Iop_NotV128:
27562757 case Iop_Not64:
27572758 case Iop_Not32:
  
4242 );
4343#elif defined(VGA_ppc32)
4444 /* Nasty hack. Does correctly atomically do *p += n, but only if p
45 is 8-aligned -- guaranteed by caller. */
45 is 4-aligned -- guaranteed by caller. */
4646 unsigned long success;
4747 do {
4848 __asm__ __volatile__(
7474 : /*trash*/ "memory", "cc", "r15"
7575 );
7676 } while (success != 1);
77#elif defined(VGA_arm)
78 *p += n;
7779#else
7880# error "Unsupported arch"
7981#endif
138138 : /*trash*/ "memory", "cc", "r15"
139139 );
140140 } while (success != 1);
141#elif defined(VGA_arm)
142 *p += n;
141143#else
142144# error "Unsupported arch"
143145#endif
199199 : /*trash*/ "memory", "cc", "r15"
200200 );
201201 } while (success != 1);
202#elif defined(VGA_arm)
203 *p += n;
202204#else
203205# error "Unsupported arch"
204206#endif
208208
209209__attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n )
210210{
211#if defined(VGA_x86) || defined(VGA_ppc32)
211#if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_arm)
212212 /* do nothing; is not supported */
213213#elif defined(VGA_amd64)
214214 // this is a bit subtle. It relies on the fact that, on a 64-bit platform,
  
1
2### jrs: re-check this against known-good equivalents, eg x86 version
3
4EXTRA_DIST = $(noinst_SCRIPTS) \
5 instructions.stderr.exp instructions.stdout.exp
6# if any tests appear here, remember to include @FLAG_M32@ in the
7# compilation flags
8#
9
10check_PROGRAMS = instructions
11
12AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow \
13 @FLAG_M32@ -g -I$(top_srcdir)/include \
14 $(FLAG_MMMX) $(FLAG_MSSE)
15AM_CXXFLAGS = $(AM_CFLAGS)
16AM_CCASFLAGS = @FLAG_M32@
  
5555 if ( 0 == strcmp( arch, "ppc32" ) ) return True;
5656 }
5757
58#elif defined(VGP_arm_linux)
59 if ( 0 == strcmp( arch, "arm" ) ) return True;
60
5861#else
5962# error Unknown platform
6063#endif // VGP_*