Commit 59570ffbe31930ab4d678754daaeec0715117a3d
- Diff rendering mode:
- inline
- side by side
Makefile.all.am
(10 / 4)
|   | |||
| 116 | 116 | # automake, but this does not really matter and seems hard to avoid. | |
| 117 | 117 | ||
| 118 | 118 | AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@ = \ | |
| 119 | -I$(top_srcdir) \ | ||
| 120 | -I$(top_srcdir)/include \ | ||
| 119 | -I$(top_srcdir) \ | ||
| 120 | -I$(top_srcdir)/include \ | ||
| 121 | 121 | -I$(top_srcdir)/VEX/pub \ | |
| 122 | 122 | -DVGA_@VGCONF_ARCH_PRI@=1 \ | |
| 123 | 123 | -DVGO_@VGCONF_OS@=1 \ | |
| 124 | 124 | -DVGP_@VGCONF_ARCH_PRI@_@VGCONF_OS@=1 | |
| 125 | 125 | if VGCONF_HAVE_PLATFORM_SEC | |
| 126 | 126 | AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@ = \ | |
| 127 | -I$(top_srcdir) \ | ||
| 128 | -I$(top_srcdir)/include \ | ||
| 127 | -I$(top_srcdir) \ | ||
| 128 | -I$(top_srcdir)/include \ | ||
| 129 | 129 | -I$(top_srcdir)/VEX/pub \ | |
| 130 | 130 | -DVGA_@VGCONF_ARCH_SEC@=1 \ | |
| 131 | 131 | -DVGO_@VGCONF_OS@=1 \ | |
| … | … | ||
| 150 | 150 | AM_CFLAGS_PPC64_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE) | |
| 151 | 151 | AM_CCASFLAGS_PPC64_LINUX = $(AM_CPPFLAGS_PPC64_LINUX) @FLAG_M64@ -g | |
| 152 | 152 | ||
| 153 | AM_FLAG_M3264_ARM_LINUX = @FLAG_M32@ | ||
| 154 | AM_CFLAGS_ARM_LINUX = @FLAG_M32@ @PREFERRED_STACK_BOUNDARY@ \ | ||
| 155 | $(AM_CFLAGS_BASE) | ||
| 156 | AM_CCASFLAGS_ARM_LINUX = $(AM_CPPFLAGS_ARM_LINUX) @FLAG_M32@ -g | ||
| 157 | |||
| 153 | 158 | AM_FLAG_M3264_PPC32_AIX5 = @FLAG_MAIX32@ | |
| 154 | 159 | AM_CFLAGS_PPC32_AIX5 = @FLAG_MAIX32@ -mcpu=powerpc $(AM_CFLAGS_BASE) | |
| 155 | 160 | AM_CCASFLAGS_PPC32_AIX5 = $(AM_CPPFLAGS_PPC32_AIX5) \ | |
| … | … | ||
| 202 | 202 | PRELOAD_LDFLAGS_AMD64_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@ | |
| 203 | 203 | PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@ | |
| 204 | 204 | PRELOAD_LDFLAGS_PPC64_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@ | |
| 205 | PRELOAD_LDFLAGS_ARM_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@ | ||
| 205 | 206 | PRELOAD_LDFLAGS_PPC32_AIX5 = $(PRELOAD_LDFLAGS_COMMON_AIX5) @FLAG_MAIX32@ | |
| 206 | 207 | PRELOAD_LDFLAGS_PPC64_AIX5 = $(PRELOAD_LDFLAGS_COMMON_AIX5) @FLAG_MAIX64@ | |
| 207 | 208 | PRELOAD_LDFLAGS_X86_DARWIN = $(PRELOAD_LDFLAGS_COMMON_DARWIN) -arch i386 |
Makefile.tool.am
(23 / 0)
|   | |||
| 49 | 49 | $(TOOL_LDFLAGS_COMMON_LINUX) @FLAG_M64@ \ | |
| 50 | 50 | -Wl,-T,$(top_builddir)/valt_load_address_ppc64_linux.lds | |
| 51 | 51 | ||
| 52 | TOOL_LDFLAGS_ARM_LINUX = \ | ||
| 53 | $(TOOL_LDFLAGS_COMMON_LINUX) @FLAG_M32@ \ | ||
| 54 | -Wl,-T,$(top_builddir)/valt_load_address_arm_linux.lds | ||
| 55 | |||
| 52 | 56 | TOOL_LDFLAGS_PPC32_AIX5 = \ | |
| 53 | 57 | $(TOOL_LDFLAGS_COMMON_AIX5) @FLAG_MAIX32@ | |
| 54 | 58 | ||
| … | … | ||
| 92 | 92 | BUILT_SOURCES += $(top_builddir)/valt_load_address_ppc64_linux.lds | |
| 93 | 93 | CLEANFILES += $(top_builddir)/valt_load_address_ppc64_linux.lds | |
| 94 | 94 | endif | |
| 95 | if VGCONF_PLATFORMS_INCLUDE_ARM_LINUX | ||
| 96 | BUILT_SOURCES += $(top_builddir)/valt_load_address_arm_linux.lds | ||
| 97 | CLEANFILES += $(top_builddir)/valt_load_address_arm_linux.lds | ||
| 98 | endif | ||
| 95 | 99 | if VGCONF_PLATFORMS_INCLUDE_PPC32_AIX5 | |
| 96 | 100 | # No need to generate $(top_builddir)/valt_load_address*.lds; the final | |
| 97 | 101 | # executables can be linked to be at any address. They will be relocated by | |
| … | … | ||
| 157 | 157 | -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' > $@ \ | |
| 158 | 158 | || rm -f $@ | |
| 159 | 159 | ||
| 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 | |||
| 160 | 167 | #---------------------------------------------------------------------------- | |
| 161 | 168 | # vgpreload_<tool>-<platform>.a stuff | |
| 162 | 169 | #---------------------------------------------------------------------------- | |
| … | … | ||
| 180 | 180 | LIBREPLACEMALLOC_PPC64_LINUX = \ | |
| 181 | 181 | $(top_builddir)/coregrind/libreplacemalloc_toolpreload-ppc64-linux.a | |
| 182 | 182 | ||
| 183 | LIBREPLACEMALLOC_ARM_LINUX = \ | ||
| 184 | $(top_builddir)/coregrind/libreplacemalloc_toolpreload-arm-linux.a | ||
| 185 | |||
| 183 | 186 | LIBREPLACEMALLOC_PPC32_AIX5 = \ | |
| 184 | 187 | $(top_builddir)/coregrind/libreplacemalloc_toolpreload-ppc32-aix5.a | |
| 185 | 188 | ||
| … | … | ||
| 214 | 214 | LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX = \ | |
| 215 | 215 | -Wl,--whole-archive \ | |
| 216 | 216 | $(LIBREPLACEMALLOC_PPC64_LINUX) \ | |
| 217 | -Wl,--no-whole-archive | ||
| 218 | |||
| 219 | LIBREPLACEMALLOC_LDFLAGS_ARM_LINUX = \ | ||
| 220 | -Wl,--whole-archive \ | ||
| 221 | $(LIBREPLACEMALLOC_ARM_LINUX) \ | ||
| 217 | 222 | -Wl,--no-whole-archive | |
| 218 | 223 | ||
| 219 | 224 | LIBREPLACEMALLOC_LDFLAGS_PPC32_AIX5 = \ |
Makefile.vex.am
(3 / 1)
|   | |||
| 56 | 56 | $(CC) $(LIBVEX_CFLAGS) -O -S -o auxprogs/genoffsets.s \ | |
| 57 | 57 | auxprogs/genoffsets.c | |
| 58 | 58 | 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" \ | ||
| 60 | 62 | > pub/libvex_guest_offsets.h | |
| 61 | 63 | rm -f auxprogs/genoffsets.s | |
| 62 | 64 |
auxprogs/gsl16test
(1 / 1)
|   | |||
| 1 | #!/bin/sh | ||
| 1 | #!/bin/bash | ||
| 2 | 2 | ||
| 3 | 3 | # Do an automated test which involves building and regtesting version | |
| 4 | 4 | # 1.6 of the GNU Scientific Library (gsl). This has proven to be a |
cachegrind/Makefile.am
(2 / 1)
|   | |||
| 40 | 40 | cg_main.c \ | |
| 41 | 41 | cg-x86-amd64.c \ | |
| 42 | 42 | cg-ppc32.c \ | |
| 43 | cg-ppc64.c | ||
| 43 | cg-ppc64.c \ | ||
| 44 | cg-arm.c | ||
| 44 | 45 | ||
| 45 | 46 | cachegrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_SOURCES = \ | |
| 46 | 47 | $(CACHEGRIND_SOURCES_COMMON) |
cachegrind/cg-arm.c
(59 / 0)
|   | |||
| 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 | |||
| 40 | void 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 | /*--------------------------------------------------------------------*/ |
cachegrind/cg_branchpred.c
(1 / 1)
|   | |||
| 44 | 44 | ||
| 45 | 45 | /* How many bits at the bottom of an instruction address are | |
| 46 | 46 | guaranteed to be zero? */ | |
| 47 | #if defined(VGA_ppc32) || defined(VGA_ppc64) | ||
| 47 | #if defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_arm) | ||
| 48 | 48 | # define N_IADDR_LO_ZERO_BITS 2 | |
| 49 | 49 | #elif defined(VGA_x86) || defined(VGA_amd64) | |
| 50 | 50 | # define N_IADDR_LO_ZERO_BITS 0 |
configure.in
(20 / 1)
|   | |||
| 151 | 151 | esac | |
| 152 | 152 | ;; | |
| 153 | 153 | ||
| 154 | armv7*) | ||
| 155 | AC_MSG_RESULT([ok (${host_cpu})]) | ||
| 156 | ARCH_MAX="arm" | ||
| 157 | ;; | ||
| 158 | |||
| 154 | 159 | *) | |
| 155 | 160 | AC_MSG_RESULT([no (${host_cpu})]) | |
| 156 | 161 | AC_MSG_ERROR([Unsupported host architecture. Sorry]) | |
| … | … | ||
| 464 | 464 | valt_load_address_inner="0x0" | |
| 465 | 465 | AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})]) | |
| 466 | 466 | ;; | |
| 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 | ;; | ||
| 467 | 475 | *) | |
| 468 | 476 | VGCONF_ARCH_PRI="unknown" | |
| 469 | 477 | VGCONF_ARCH_SEC="unknown" | |
| … | … | ||
| 502 | 502 | AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC64, | |
| 503 | 503 | test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX \ | |
| 504 | 504 | -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_AIX5 ) | |
| 505 | AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_ARM, | ||
| 506 | test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX ) | ||
| 505 | 507 | ||
| 506 | 508 | # Set up VGCONF_PLATFORMS_INCLUDE_<platform>. Either one or two of these | |
| 507 | 509 | # become defined. | |
| … | … | ||
| 517 | 517 | -o x$VGCONF_PLATFORM_SEC_CAPS = xPPC32_LINUX) | |
| 518 | 518 | AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX, | |
| 519 | 519 | test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX) | |
| 520 | AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM_LINUX, | ||
| 521 | test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX) | ||
| 520 | 522 | ||
| 521 | 523 | AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC32_AIX5, | |
| 522 | 524 | test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_AIX5 \ | |
| … | … | ||
| 540 | 540 | test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \ | |
| 541 | 541 | -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX \ | |
| 542 | 542 | -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 ) | ||
| 544 | 545 | AM_CONDITIONAL(VGCONF_OS_IS_AIX5, | |
| 545 | 546 | test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_AIX5 \ | |
| 546 | 547 | -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_AIX5) | |
| … | … | ||
| 1945 | 1945 | none/tests/ppc32/Makefile | |
| 1946 | 1946 | none/tests/ppc64/Makefile | |
| 1947 | 1947 | none/tests/x86/Makefile | |
| 1948 | none/tests/arm/Makefile | ||
| 1948 | 1949 | none/tests/linux/Makefile | |
| 1949 | 1950 | none/tests/darwin/Makefile | |
| 1950 | 1951 | none/tests/x86-linux/Makefile |
coregrind/Makefile.am
(6 / 2)
|   | |||
| 10 | 10 | #---------------------------------------------------------------------------- | |
| 11 | 11 | ||
| 12 | 12 | AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@ += \ | |
| 13 | -I$(top_srcdir)/coregrind \ | ||
| 13 | -I$(top_srcdir)/coregrind \ | ||
| 14 | 14 | -DVG_LIBDIR="\"$(pkglibdir)"\" \ | |
| 15 | 15 | -DVG_PLATFORM="\"@VGCONF_ARCH_PRI@-@VGCONF_OS@\"" | |
| 16 | 16 | if VGCONF_HAVE_PLATFORM_SEC | |
| 17 | 17 | AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@ += \ | |
| 18 | -I$(top_srcdir)/coregrind \ | ||
| 18 | -I$(top_srcdir)/coregrind \ | ||
| 19 | 19 | -DVG_LIBDIR="\"$(pkglibdir)"\" \ | |
| 20 | 20 | -DVG_PLATFORM="\"@VGCONF_ARCH_SEC@-@VGCONF_OS@\"" | |
| 21 | 21 | endif | |
| … | … | ||
| 281 | 281 | m_dispatch/dispatch-amd64-linux.S \ | |
| 282 | 282 | m_dispatch/dispatch-ppc32-linux.S \ | |
| 283 | 283 | m_dispatch/dispatch-ppc64-linux.S \ | |
| 284 | m_dispatch/dispatch-arm-linux.S \ | ||
| 284 | 285 | m_dispatch/dispatch-ppc32-aix5.S \ | |
| 285 | 286 | m_dispatch/dispatch-ppc64-aix5.S \ | |
| 286 | 287 | m_dispatch/dispatch-x86-darwin.S \ | |
| … | … | ||
| 301 | 301 | m_sigframe/sigframe-amd64-linux.c \ | |
| 302 | 302 | m_sigframe/sigframe-ppc32-linux.c \ | |
| 303 | 303 | m_sigframe/sigframe-ppc64-linux.c \ | |
| 304 | m_sigframe/sigframe-arm-linux.c \ | ||
| 304 | 305 | m_sigframe/sigframe-ppc32-aix5.c \ | |
| 305 | 306 | m_sigframe/sigframe-ppc64-aix5.c \ | |
| 306 | 307 | m_sigframe/sigframe-x86-darwin.c \ | |
| … | … | ||
| 312 | 312 | m_syswrap/syscall-amd64-linux.S \ | |
| 313 | 313 | m_syswrap/syscall-ppc32-linux.S \ | |
| 314 | 314 | m_syswrap/syscall-ppc64-linux.S \ | |
| 315 | m_syswrap/syscall-arm-linux.S \ | ||
| 315 | 316 | m_syswrap/syscall-ppc32-aix5.S \ | |
| 316 | 317 | m_syswrap/syscall-ppc64-aix5.S \ | |
| 317 | 318 | m_syswrap/syscall-x86-darwin.S \ | |
| … | … | ||
| 327 | 327 | m_syswrap/syswrap-amd64-linux.c \ | |
| 328 | 328 | m_syswrap/syswrap-ppc32-linux.c \ | |
| 329 | 329 | m_syswrap/syswrap-ppc64-linux.c \ | |
| 330 | m_syswrap/syswrap-arm-linux.c \ | ||
| 330 | 331 | m_syswrap/syswrap-ppc32-aix5.c \ | |
| 331 | 332 | m_syswrap/syswrap-ppc64-aix5.c \ | |
| 332 | 333 | m_syswrap/syswrap-x86-darwin.c \ |
coregrind/launcher-linux.c
(9 / 1)
|   | |||
| 172 | 172 | ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) { | |
| 173 | 173 | platform = "x86-linux"; | |
| 174 | 174 | } | |
| 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 | } | ||
| 175 | 181 | } | |
| 176 | 182 | else if (header[EI_DATA] == ELFDATA2MSB) { | |
| 177 | 183 | if (ehdr->e_machine == EM_PPC && | |
| … | … | ||
| 186 | 186 | platform = "ppc32-linux"; | |
| 187 | 187 | } | |
| 188 | 188 | } | |
| 189 | |||
| 189 | 190 | } else if (n_bytes >= sizeof(Elf64_Ehdr) && header[EI_CLASS] == ELFCLASS64) { | |
| 190 | 191 | const Elf64_Ehdr *ehdr = (Elf64_Ehdr *)header; | |
| 191 | 192 | ||
| … | … | ||
| 273 | 273 | if ((0==strcmp(VG_PLATFORM,"x86-linux")) || | |
| 274 | 274 | (0==strcmp(VG_PLATFORM,"amd64-linux")) || | |
| 275 | 275 | (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"))) | ||
| 277 | 278 | default_platform = VG_PLATFORM; | |
| 278 | 279 | else | |
| 279 | 280 | barf("Unknown VG_PLATFORM '%s'", VG_PLATFORM); |
|   | |||
| 152 | 152 | { | |
| 153 | 153 | SysRes res; | |
| 154 | 154 | 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) | ||
| 156 | 157 | /* mmap2 uses 4096 chunks even if actual page size is bigger. */ | |
| 157 | 158 | aspacem_assert((offset % 4096) == 0); | |
| 158 | 159 | res = VG_(do_syscall6)(__NR_mmap2, (UWord)start, length, |
|   | |||
| 1683 | 1683 | VG_(debugLog)(2, "aspacem", "Reading /proc/self/maps\n"); | |
| 1684 | 1684 | parse_procselfmaps( read_maps_callback, NULL ); | |
| 1685 | 1685 | ||
| 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 | |||
| 1686 | 1705 | VG_(am_show_nsegments)(2, "With contents of /proc/self/maps"); | |
| 1687 | 1706 | ||
| 1688 | 1707 | AM_SANITY_CHECK; |
|   | |||
| 324 | 324 | regs->dsisr = 0; | |
| 325 | 325 | regs->result = 0; | |
| 326 | 326 | ||
| 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 | |||
| 327 | 346 | #else | |
| 328 | 347 | # error Unknown ELF platform | |
| 329 | 348 | #endif | |
| … | … | ||
| 411 | 411 | DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); | |
| 412 | 412 | DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); | |
| 413 | 413 | # undef DO | |
| 414 | |||
| 415 | #elif defined(VGP_arm_linux) | ||
| 416 | // umm ... | ||
| 414 | 417 | ||
| 415 | 418 | #else | |
| 416 | 419 | # error Unknown ELF platform |
coregrind/m_cpuid.S
(9 / 3)
|   | |||
| 33 | 33 | /* | |
| 34 | 34 | Bool VG_(has_cpuid)(void) | |
| 35 | 35 | */ | |
| 36 | .globl VG_(has_cpuid) | ||
| 37 | 36 | #if defined(VGA_x86) | |
| 37 | .text | ||
| 38 | .globl VG_(has_cpuid) | ||
| 38 | 39 | VG_(has_cpuid): | |
| 39 | 40 | pushl %ebp | |
| 40 | 41 | movl %esp, %ebp | |
| … | … | ||
| 58 | 58 | popl %ebp | |
| 59 | 59 | ret | |
| 60 | 60 | #elif defined(VGA_amd64) | |
| 61 | .text | ||
| 62 | .globl VG_(has_cpuid) | ||
| 61 | 63 | VG_(has_cpuid): | |
| 62 | 64 | movq $1, %rax | |
| 63 | 65 | ret | |
| … | … | ||
| 69 | 69 | void VG_(cpuid)(UInt eax, | |
| 70 | 70 | UInt* eax_ret, UInt* ebx_ret, UInt* ecx_ret, UInt* edx_ret) | |
| 71 | 71 | */ | |
| 72 | .globl VG_(cpuid) | ||
| 73 | 72 | #if defined(VGA_x86) | |
| 73 | .text | ||
| 74 | .globl VG_(cpuid) | ||
| 74 | 75 | VG_(cpuid): | |
| 75 | 76 | pushl %ebp | |
| 76 | 77 | movl %esp, %ebp | |
| … | … | ||
| 111 | 111 | popl %ebp | |
| 112 | 112 | ret | |
| 113 | 113 | #elif defined(VGA_amd64) | |
| 114 | .text | ||
| 115 | .globl VG_(cpuid) | ||
| 114 | 116 | VG_(cpuid): | |
| 115 | 117 | pushq %rbp | |
| 116 | 118 | movq %rsp, %rbp | |
| … | … | ||
| 149 | 149 | ret | |
| 150 | 150 | #endif | |
| 151 | 151 | ||
| 152 | #if defined(VGO_linux) | ||
| 152 | #if defined(VGA_x86) || defined(VGA_amd64) | ||
| 153 | 153 | /* Let the linker know we don't need an executable stack */ | |
| 154 | 154 | .section .note.GNU-stack,"",@progbits | |
| 155 | 155 | #endif |
coregrind/m_debugger.c
(22 / 0)
|   | |||
| 205 | 205 | (void*)(long)LibVEX_GuestPPC64_get_XER(vex)); | |
| 206 | 206 | return rc; | |
| 207 | 207 | ||
| 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 | |||
| 208 | 230 | #elif defined(VGP_ppc32_aix5) | |
| 209 | 231 | I_die_here; | |
| 210 | 232 |
|   | |||
| 389 | 389 | if (regno == 1/*SP*/) { *a = regs->sp; return True; } | |
| 390 | 390 | # elif defined(VGP_ppc64_linux) | |
| 391 | 391 | 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; } | ||
| 392 | 395 | # elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) | |
| 393 | 396 | vg_assert(0); /* this function should never be called */ | |
| 394 | 397 | # else |
coregrind/m_debuglog.c
(36 / 0)
|   | |||
| 232 | 232 | return (UInt)__res; | |
| 233 | 233 | } | |
| 234 | 234 | ||
| 235 | #elif defined(VGP_arm_linux) | ||
| 236 | |||
| 237 | static 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 | |||
| 258 | static 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 | |||
| 235 | 271 | #elif defined(VGP_ppc32_aix5) | |
| 236 | 272 | ||
| 237 | 273 | static 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: | ||
| 52 | UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling ); | ||
| 53 | */ | ||
| 54 | .text | ||
| 55 | .globl VG_(run_innerloop) | ||
| 56 | VG_(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) | ||
| 79 | VG_(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) | ||
| 124 | VG_(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 | |||
| 174 | gsp_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 | |||
| 189 | counter_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 | |||
| 200 | fast_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 | */ | ||
| 214 | run_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 | |||
| 224 | invariant_violation: | ||
| 225 | mov r0, #VG_TRC_INVARIANT_FAILED | ||
| 226 | b run_innerloop_exit_REALLY | ||
| 227 | |||
| 228 | run_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: | ||
| 243 | void 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) | ||
| 254 | VG_(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 | /*--------------------------------------------------------------------*/ |
|   | |||
| 1004 | 1004 | arch->vex.guest_GPR2 = iifii.initial_client_TOC; | |
| 1005 | 1005 | arch->vex.guest_CIA = iifii.initial_client_IP; | |
| 1006 | 1006 | ||
| 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 | |||
| 1007 | 1023 | # else | |
| 1008 | 1024 | # error Unknown platform | |
| 1009 | 1025 | # endif |
coregrind/m_libcassert.c
(103 / 55)
|   | |||
| 45 | 45 | Assertery. | |
| 46 | 46 | ------------------------------------------------------------------ */ | |
| 47 | 47 | ||
| 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 | } | ||
| 65 | 79 | #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 | } | ||
| 79 | 98 | #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 | } | ||
| 93 | 136 | #else | |
| 94 | 137 | # error Unknown platform | |
| 95 | 138 | #endif | |
| … | … | ||
| 172 | 172 | } | |
| 173 | 173 | ||
| 174 | 174 | __attribute__ ((noreturn)) | |
| 175 | static void report_and_quit ( const Char* report, | ||
| 176 | Addr ip, Addr sp, Addr fp, Addr lr ) | ||
| 175 | static void report_and_quit ( const Char* report, | ||
| 176 | UnwindStartRegs* startRegsIN ) | ||
| 177 | 177 | { | |
| 178 | 178 | Addr stacktop; | |
| 179 | 179 | Addr ips[BACKTRACE_DEPTH]; | |
| … | … | ||
| 184 | 184 | // If necessary, fake up an ExeContext which is of our actual real CPU | |
| 185 | 185 | // state. Could cause problems if we got the panic/exception within the | |
| 186 | 186 | // 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; | ||
| 189 | 194 | } | |
| 190 | 195 | ||
| 191 | 196 | stacktop = tst->os_state.valgrind_stack_init_SP; | |
| … | … | ||
| 201 | 201 | ips, BACKTRACE_DEPTH, | |
| 202 | 202 | NULL/*array to dump SP values in*/, | |
| 203 | 203 | NULL/*array to dump FP values in*/, | |
| 204 | ip, sp, fp, lr, sp, stacktop | ||
| 204 | &startRegs, stacktop | ||
| 205 | 205 | ); | |
| 206 | 206 | VG_(clo_xml) = False; | |
| 207 | 207 | VG_(pp_StackTrace) (ips, n_ips); | |
| … | … | ||
| 262 | 262 | if (!VG_STREQ(buf, "")) | |
| 263 | 263 | VG_(printf)("%s: %s\n", component, buf ); | |
| 264 | 264 | ||
| 265 | report_and_quit(bugs_to, 0,0,0,0); | ||
| 265 | report_and_quit(bugs_to, NULL); | ||
| 266 | 266 | } | |
| 267 | 267 | ||
| 268 | 268 | __attribute__ ((noreturn)) | |
| 269 | 269 | static void panic ( Char* name, Char* report, Char* str, | |
| 270 | Addr ip, Addr sp, Addr fp, Addr lr ) | ||
| 270 | UnwindStartRegs* startRegs ) | ||
| 271 | 271 | { | |
| 272 | 272 | if (VG_(clo_xml)) | |
| 273 | 273 | VG_(printf_xml)("</valgrindoutput>\n"); | |
| 274 | 274 | 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); | ||
| 276 | 276 | } | |
| 277 | 277 | ||
| 278 | void VG_(core_panic_at) ( Char* str, Addr ip, Addr sp, Addr fp, Addr lr ) | ||
| 278 | void VG_(core_panic_at) ( Char* str, UnwindStartRegs* startRegs ) | ||
| 279 | 279 | { | |
| 280 | panic("valgrind", VG_BUGS_TO, str, ip, sp, fp, lr); | ||
| 280 | panic("valgrind", VG_BUGS_TO, str, startRegs); | ||
| 281 | 281 | } | |
| 282 | 282 | ||
| 283 | 283 | void VG_(core_panic) ( Char* str ) | |
| 284 | 284 | { | |
| 285 | VG_(core_panic_at)(str, 0,0,0,0); | ||
| 285 | VG_(core_panic_at)(str, NULL); | ||
| 286 | 286 | } | |
| 287 | 287 | ||
| 288 | 288 | void VG_(tool_panic) ( Char* str ) | |
| 289 | 289 | { | |
| 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); | ||
| 291 | 291 | } | |
| 292 | 292 | ||
| 293 | 293 | /* Print some helpful-ish text about unimplemented things, and give up. */ |
coregrind/m_libcfile.c
(6 / 6)
|   | |||
| 804 | 804 | res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args); | |
| 805 | 805 | return sr_isError(res) ? -1 : sr_Res(res); | |
| 806 | 806 | ||
| 807 | # elif defined(VGP_amd64_linux) | ||
| 807 | # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) | ||
| 808 | 808 | SysRes res; | |
| 809 | 809 | res = VG_(do_syscall3)(__NR_socket, domain, type, protocol ); | |
| 810 | 810 | return sr_isError(res) ? -1 : sr_Res(res); | |
| … | … | ||
| 845 | 845 | res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args); | |
| 846 | 846 | return sr_isError(res) ? -1 : sr_Res(res); | |
| 847 | 847 | ||
| 848 | # elif defined(VGP_amd64_linux) | ||
| 848 | # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) | ||
| 849 | 849 | SysRes res; | |
| 850 | 850 | res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen); | |
| 851 | 851 | return sr_isError(res) ? -1 : sr_Res(res); | |
| … | … | ||
| 886 | 886 | res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args); | |
| 887 | 887 | return sr_isError(res) ? -1 : sr_Res(res); | |
| 888 | 888 | ||
| 889 | # elif defined(VGP_amd64_linux) | ||
| 889 | # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) | ||
| 890 | 890 | SysRes res; | |
| 891 | 891 | res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg, | |
| 892 | 892 | count, VKI_MSG_NOSIGNAL, 0,0); | |
| … | … | ||
| 917 | 917 | res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args); | |
| 918 | 918 | return sr_isError(res) ? -1 : sr_Res(res); | |
| 919 | 919 | ||
| 920 | # elif defined(VGP_amd64_linux) | ||
| 920 | # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) | ||
| 921 | 921 | SysRes res; | |
| 922 | 922 | res = VG_(do_syscall3)( __NR_getsockname, | |
| 923 | 923 | (UWord)sd, (UWord)name, (UWord)namelen ); | |
| … | … | ||
| 949 | 949 | res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args); | |
| 950 | 950 | return sr_isError(res) ? -1 : sr_Res(res); | |
| 951 | 951 | ||
| 952 | # elif defined(VGP_amd64_linux) | ||
| 952 | # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) | ||
| 953 | 953 | SysRes res; | |
| 954 | 954 | res = VG_(do_syscall3)( __NR_getpeername, | |
| 955 | 955 | (UWord)sd, (UWord)name, (UWord)namelen ); | |
| … | … | ||
| 984 | 984 | res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args); | |
| 985 | 985 | return sr_isError(res) ? -1 : sr_Res(res); | |
| 986 | 986 | ||
| 987 | # elif defined(VGP_amd64_linux) | ||
| 987 | # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) | ||
| 988 | 988 | SysRes res; | |
| 989 | 989 | res = VG_(do_syscall5)( __NR_getsockopt, | |
| 990 | 990 | (UWord)sd, (UWord)level, (UWord)optname, |
coregrind/m_libcproc.c
(2 / 1)
|   | |||
| 529 | 529 | list[i] = (UInt)list16[i]; | |
| 530 | 530 | return sr_Res(sres); | |
| 531 | 531 | ||
| 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) \ | ||
| 533 | 534 | || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) \ | |
| 534 | 535 | || defined(VGO_darwin) | |
| 535 | 536 | SysRes sres; |
coregrind/m_machine.c
(70 / 5)
|   | |||
| 64 | 64 | return VG_(threads)[tid].arch.vex.guest_LR; | |
| 65 | 65 | # elif defined(VGA_x86) || defined(VGA_amd64) | |
| 66 | 66 | return 0; | |
| 67 | # elif defined(VGA_arm) | ||
| 68 | return VG_(threads)[tid].arch.vex.guest_R14; | ||
| 67 | 69 | # else | |
| 68 | 70 | # error "Unknown arch" | |
| 69 | 71 | # endif | |
| … | … | ||
| 81 | 81 | INSTR_PTR( VG_(threads)[tid].arch ) = ip; | |
| 82 | 82 | } | |
| 83 | 83 | ||
| 84 | |||
| 85 | void 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 | |||
| 84 | 123 | void VG_(set_syscall_return_shadows) ( ThreadId tid, | |
| 85 | 124 | /* shadow vals for the result */ | |
| 86 | 125 | UWord s1res, UWord s2res, | |
| … | … | ||
| 135 | 135 | # elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) | |
| 136 | 136 | VG_(threads)[tid].arch.vex_shadow1.guest_GPR3 = s1res; | |
| 137 | 137 | 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; | ||
| 138 | 141 | # elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) | |
| 139 | 142 | VG_(threads)[tid].arch.vex_shadow1.guest_GPR3 = s1res; | |
| 140 | 143 | VG_(threads)[tid].arch.vex_shadow2.guest_GPR3 = s2res; | |
| … | … | ||
| 228 | 228 | (*f)(vex->guest_R14); | |
| 229 | 229 | (*f)(vex->guest_R15); | |
| 230 | 230 | #elif defined(VGA_ppc32) || defined(VGA_ppc64) | |
| 231 | /* XXX ask tool about validity? */ | ||
| 232 | 231 | (*f)(vex->guest_GPR0); | |
| 233 | 232 | (*f)(vex->guest_GPR1); | |
| 234 | 233 | (*f)(vex->guest_GPR2); | |
| … | … | ||
| 262 | 262 | (*f)(vex->guest_GPR31); | |
| 263 | 263 | (*f)(vex->guest_CTR); | |
| 264 | 264 | (*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); | ||
| 266 | 280 | #else | |
| 267 | 281 | # error Unknown arch | |
| 268 | 282 | #endif | |
| … | … | ||
| 369 | 369 | */ | |
| 370 | 370 | ||
| 371 | 371 | /* --------- State --------- */ | |
| 372 | static Bool hwcaps_done = False; | ||
| 372 | static Bool hwcaps_done = False; | ||
| 373 | 373 | ||
| 374 | 374 | /* --- all archs --- */ | |
| 375 | 375 | static VexArch va; | |
| … | … | ||
| 713 | 713 | return True; | |
| 714 | 714 | } | |
| 715 | 715 | ||
| 716 | #elif defined(VGA_arm) | ||
| 717 | { | ||
| 718 | va = VexArchARM; | ||
| 719 | vai.hwcaps = 0; | ||
| 720 | return True; | ||
| 721 | } | ||
| 722 | |||
| 716 | 723 | #else | |
| 717 | 724 | # error "Unknown arch" | |
| 718 | 725 | #endif | |
| … | … | ||
| 775 | 775 | // produce a pointer to the actual entry point for the function. | |
| 776 | 776 | void* VG_(fnptr_to_fnentry)( void* f ) | |
| 777 | 777 | { | |
| 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) | ||
| 780 | 781 | return f; | |
| 781 | 782 | #elif defined(VGP_ppc64_linux) || defined(VGP_ppc32_aix5) \ | |
| 782 | 783 | || defined(VGP_ppc64_aix5) |
coregrind/m_main.c
(45 / 0)
|   | |||
| 1951 | 1951 | iters = 10; | |
| 1952 | 1952 | # elif defined(VGP_ppc32_linux) | |
| 1953 | 1953 | iters = 5; | |
| 1954 | # elif defined(VGP_arm_linux) | ||
| 1955 | iters = 1; | ||
| 1954 | 1956 | # elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) | |
| 1955 | 1957 | iters = 4; | |
| 1956 | 1958 | # elif defined(VGO_darwin) | |
| … | … | ||
| 2627 | 2627 | return VG_(memset)(s,c,n); | |
| 2628 | 2628 | } | |
| 2629 | 2629 | ||
| 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) | ||
| 2634 | void raise(void); | ||
| 2635 | void raise(void){ | ||
| 2636 | VG_(printf)("Something called raise().\n"); | ||
| 2637 | vg_assert(0); | ||
| 2638 | } | ||
| 2639 | |||
| 2640 | void abort(void); | ||
| 2641 | void abort(void){ | ||
| 2642 | VG_(printf)("Something called raise().\n"); | ||
| 2643 | vg_assert(0); | ||
| 2644 | } | ||
| 2645 | |||
| 2646 | void __aeabi_unwind_cpp_pr0(void); | ||
| 2647 | void __aeabi_unwind_cpp_pr0(void){ | ||
| 2648 | VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n"); | ||
| 2649 | vg_assert(0); | ||
| 2650 | } | ||
| 2651 | #endif | ||
| 2652 | |||
| 2630 | 2653 | /* ---------------- Requirement 2 ---------------- */ | |
| 2631 | 2654 | ||
| 2632 | 2655 | /* Glibc's sysdeps/i386/elf/start.S has the following gem of a | |
| … | … | ||
| 2782 | 2782 | "\tbl ._start_in_C_linux\n" | |
| 2783 | 2783 | "\tnop\n" | |
| 2784 | 2784 | "\ttrap\n" | |
| 2785 | ); | ||
| 2786 | #elif defined(VGP_arm_linux) | ||
| 2787 | asm("\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" | ||
| 2785 | 2805 | ); | |
| 2786 | 2806 | #else | |
| 2787 | 2807 | # error "Unknown linux platform" |
coregrind/m_redir.c
(22 / 0)
|   | |||
| 995 | 995 | ); | |
| 996 | 996 | } | |
| 997 | 997 | ||
| 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 | |||
| 998 | 1020 | # elif defined(VGP_ppc32_aix5) | |
| 999 | 1021 | /* nothing so far */ | |
| 1000 | 1022 |
|   | |||
| 42 | 42 | ||
| 43 | 43 | It is called vg_replace_malloc.c because this filename appears in stack | |
| 44 | 44 | 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. | ||
| 45 | 62 | ------------------------------------------------------------------ */ | |
| 46 | 63 | ||
| 47 | 64 | #include "pub_core_basics.h" | |
| … | … | ||
| 111 | 111 | #endif | |
| 112 | 112 | ||
| 113 | 113 | ||
| 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. */ | ||
| 117 | static 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 | |||
| 114 | 138 | /*------------------------------------------------------------*/ | |
| 115 | 139 | /*--- Replacing malloc() et al ---*/ | |
| 116 | 140 | /*------------------------------------------------------------*/ | |
| … | … | ||
| 449 | 449 | if (!init_done) init(); \ | |
| 450 | 450 | MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \ | |
| 451 | 451 | \ | |
| 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; \ | ||
| 454 | 462 | v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \ | |
| 455 | 463 | MALLOC_TRACE(" = %p\n", v ); \ | |
| 456 | 464 | return v; \ |
|   | |||
| 655 | 655 | vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow1.guest_VR1)); | |
| 656 | 656 | vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow2.guest_VR1)); | |
| 657 | 657 | # 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 | ||
| 658 | 670 | } | |
| 659 | 671 | ||
| 660 | 672 | ||
| … | … | ||
| 1207 | 1207 | be in on entry to Vex-generated code, and they should be | |
| 1208 | 1208 | unchanged on exit from it. Failure of this assertion | |
| 1209 | 1209 | 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 | //} | ||
| 1210 | 1216 | vg_assert2(0, "VG_(scheduler), phase 3: " | |
| 1211 | 1217 | "run_innerloop detected host " | |
| 1212 | 1218 | "state invariant failure", trc); | |
| … | … | ||
| 1297 | 1297 | #elif defined(VGA_ppc32) || defined(VGA_ppc64) | |
| 1298 | 1298 | # define VG_CLREQ_ARGS guest_GPR4 | |
| 1299 | 1299 | # 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 | ||
| 1300 | 1303 | #else | |
| 1301 | 1304 | # error Unknown arch | |
| 1302 | 1305 | #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 | |||
| 55 | struct vg_sig_private { | ||
| 56 | UInt magicPI; | ||
| 57 | UInt sigNo_private; | ||
| 58 | VexGuestARMState vex_shadow1; | ||
| 59 | VexGuestARMState vex_shadow2; | ||
| 60 | }; | ||
| 61 | |||
| 62 | struct sigframe { | ||
| 63 | struct vki_ucontext uc; | ||
| 64 | unsigned long retcode[2]; | ||
| 65 | struct vg_sig_private vp; | ||
| 66 | }; | ||
| 67 | |||
| 68 | struct rt_sigframe { | ||
| 69 | vki_siginfo_t info; | ||
| 70 | struct sigframe sig; | ||
| 71 | }; | ||
| 72 | |||
| 73 | static 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 | |||
| 112 | static 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 | |||
| 151 | static 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 */ | ||
| 190 | void 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 */ | ||
| 261 | void 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 | /*--------------------------------------------------------------------*/ |
coregrind/m_signals.c
(44 / 9)
|   | |||
| 266 | 266 | #if defined(VGP_x86_linux) | |
| 267 | 267 | # define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip) | |
| 268 | 268 | # define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp) | |
| 269 | # define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.ebp) | ||
| 270 | 269 | # define VG_UCONTEXT_SYSCALL_SYSRES(uc) \ | |
| 271 | 270 | /* Convert the value in uc_mcontext.eax into a SysRes. */ \ | |
| 272 | 271 | 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 | } | ||
| 274 | 277 | ||
| 275 | 278 | #elif defined(VGP_amd64_linux) | |
| 276 | 279 | # define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip) | |
| 277 | 280 | # define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp) | |
| 278 | # define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.rbp) | ||
| 279 | 281 | # define VG_UCONTEXT_SYSCALL_SYSRES(uc) \ | |
| 280 | 282 | /* Convert the value in uc_mcontext.rax into a SysRes. */ \ | |
| 281 | 283 | 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 | } | ||
| 283 | 289 | ||
| 284 | 290 | #elif defined(VGP_ppc32_linux) | |
| 285 | 291 | /* Comments from Paul Mackerras 25 Nov 05: | |
| … | … | ||
| 363 | 363 | } | |
| 364 | 364 | # define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_LNK]) | |
| 365 | 365 | ||
| 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 | |||
| 366 | 380 | #elif defined(VGP_ppc32_aix5) | |
| 367 | 381 | ||
| 368 | 382 | /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ | |
| … | … | ||
| 783 | 783 | " movl $" #name ", %eax\n" \ | |
| 784 | 784 | " int $0x80\n" \ | |
| 785 | 785 | ".previous\n" | |
| 786 | |||
| 786 | 787 | #elif defined(VGP_amd64_linux) | |
| 787 | 788 | # define _MY_SIGRETURN(name) \ | |
| 788 | 789 | ".text\n" \ | |
| … | … | ||
| 791 | 791 | " movq $" #name ", %rax\n" \ | |
| 792 | 792 | " syscall\n" \ | |
| 793 | 793 | ".previous\n" | |
| 794 | |||
| 794 | 795 | #elif defined(VGP_ppc32_linux) | |
| 795 | 796 | # define _MY_SIGRETURN(name) \ | |
| 796 | 797 | ".text\n" \ | |
| … | … | ||
| 799 | 799 | " li 0, " #name "\n" \ | |
| 800 | 800 | " sc\n" \ | |
| 801 | 801 | ".previous\n" | |
| 802 | |||
| 802 | 803 | #elif defined(VGP_ppc64_linux) | |
| 803 | 804 | # define _MY_SIGRETURN(name) \ | |
| 804 | 805 | ".align 2\n" \ | |
| … | … | ||
| 814 | 814 | ".my_sigreturn:\n" \ | |
| 815 | 815 | " li 0, " #name "\n" \ | |
| 816 | 816 | " 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 | |||
| 817 | 826 | #elif defined(VGP_ppc32_aix5) | |
| 818 | 827 | # define _MY_SIGRETURN(name) \ | |
| 819 | 828 | ".globl my_sigreturn\n" \ | |
| … | … | ||
| 833 | 833 | ".globl my_sigreturn\n" \ | |
| 834 | 834 | "my_sigreturn:\n" \ | |
| 835 | 835 | ".long 0\n" | |
| 836 | |||
| 836 | 837 | #elif defined(VGP_x86_darwin) | |
| 837 | 838 | # define _MY_SIGRETURN(name) \ | |
| 838 | 839 | ".text\n" \ | |
| 839 | 840 | "my_sigreturn:\n" \ | |
| 840 | 841 | "movl $" VG_STRINGIFY(__NR_DARWIN_FAKE_SIGRETURN) ",%eax\n" \ | |
| 841 | 842 | "int $0x80" | |
| 843 | |||
| 842 | 844 | #elif defined(VGP_amd64_darwin) | |
| 843 | 845 | // DDD: todo | |
| 844 | 846 | # define _MY_SIGRETURN(name) \ | |
| 845 | 847 | ".text\n" \ | |
| 846 | 848 | "my_sigreturn:\n" \ | |
| 847 | 849 | "ud2\n" | |
| 850 | |||
| 848 | 851 | #else | |
| 849 | 852 | # error Unknown platform | |
| 850 | 853 | #endif | |
| … | … | ||
| 2323 | 2323 | // tid = VG_(master_tid); | |
| 2324 | 2324 | vg_assert(tid != 0); | |
| 2325 | 2325 | ||
| 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); | ||
| 2331 | 2331 | } | |
| 2332 | 2332 | } | |
| 2333 | 2333 |
coregrind/m_stacktrace.c
(256 / 52)
|   | |||
| 44 | 44 | #include "pub_core_clientstate.h" // VG_(client__dl_sysinfo_int80) | |
| 45 | 45 | #include "pub_core_trampoline.h" | |
| 46 | 46 | ||
| 47 | |||
| 47 | 48 | /*------------------------------------------------------------*/ | |
| 48 | /*--- Exported functions. ---*/ | ||
| 49 | /*--- ---*/ | ||
| 50 | /*--- BEGIN platform-dependent unwinder worker functions ---*/ | ||
| 51 | /*--- ---*/ | ||
| 49 | 52 | /*------------------------------------------------------------*/ | |
| 50 | 53 | ||
| 51 | 54 | /* Take a snapshot of the client's stack, putting up to 'max_n_ips' | |
| … | … | ||
| 60 | 60 | first parameter, else send zero. This helps generate better stack | |
| 61 | 61 | traces on ppc64-linux and has no effect on other platforms. | |
| 62 | 62 | */ | |
| 63 | |||
| 64 | /* ------------------------ x86 ------------------------- */ | ||
| 65 | |||
| 66 | #if defined(VGP_x86_linux) || defined(VGP_x86_darwin) | ||
| 67 | |||
| 63 | 68 | UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, | |
| 64 | 69 | /*OUT*/Addr* ips, UInt max_n_ips, | |
| 65 | 70 | /*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 ) | ||
| 68 | 73 | { | |
| 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 | |||
| 80 | 74 | Bool debug = False; | |
| 81 | 75 | Int i; | |
| 82 | 76 | Addr fp_max; | |
| … | … | ||
| 79 | 79 | vg_assert(sizeof(Addr) == sizeof(UWord)); | |
| 80 | 80 | vg_assert(sizeof(Addr) == sizeof(void*)); | |
| 81 | 81 | ||
| 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 | |||
| 82 | 87 | /* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1], | |
| 83 | 88 | stopping when the trail goes cold, which we guess to be | |
| 84 | 89 | when FP is not a reasonable stack location. */ | |
| … | … | ||
| 105 | 105 | /* vg_assert(fp_min <= fp_max);*/ | |
| 106 | 106 | // On Darwin, this kicks in for pthread-related stack traces, so they're | |
| 107 | 107 | // only 1 entry long which is wrong. | |
| 108 | #if !defined(VGO_darwin) | ||
| 108 | # if !defined(VGO_darwin) | ||
| 109 | 109 | if (fp_min + 512 >= fp_max) { | |
| 110 | 110 | /* If the stack limits look bogus, don't poke around ... but | |
| 111 | 111 | don't bomb out either. */ | |
| … | … | ||
| 114 | 114 | ips[0] = ip; | |
| 115 | 115 | return 1; | |
| 116 | 116 | } | |
| 117 | #endif | ||
| 117 | # endif | ||
| 118 | 118 | ||
| 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 | |||
| 128 | 119 | /* fp is %ebp. sp is %esp. ip is %eip. */ | |
| 129 | 120 | ||
| 130 | 121 | if (sps) sps[0] = sp; | |
| … | … | ||
| 206 | 206 | break; | |
| 207 | 207 | } | |
| 208 | 208 | ||
| 209 | # elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) | ||
| 209 | n_found = i; | ||
| 210 | return n_found; | ||
| 211 | } | ||
| 210 | 212 | ||
| 211 | /*--------------------- amd64 ---------------------*/ | ||
| 213 | #endif | ||
| 212 | 214 | ||
| 215 | /* ----------------------- amd64 ------------------------ */ | ||
| 216 | |||
| 217 | #if defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) | ||
| 218 | |||
| 219 | UInt 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 | |||
| 213 | 270 | /* fp is %rbp. sp is %rsp. ip is %rip. */ | |
| 214 | 271 | ||
| 215 | 272 | ips[0] = ip; | |
| … | … | ||
| 369 | 369 | break; | |
| 370 | 370 | } | |
| 371 | 371 | ||
| 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 | } | ||
| 374 | 375 | ||
| 375 | /*--------------------- ppc32/64 ---------------------*/ | ||
| 376 | #endif | ||
| 376 | 377 | ||
| 378 | /* -----------------------ppc32/64 ---------------------- */ | ||
| 379 | |||
| 380 | #if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \ | ||
| 381 | || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) | ||
| 382 | |||
| 383 | UInt 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 | |||
| 377 | 431 | /* fp is %r1. ip is %cia. Note, ppc uses r1 as both the stack and | |
| 378 | 432 | frame pointers. */ | |
| 379 | 433 | ||
| … | … | ||
| 490 | 490 | /* On ppc64-linux (ppc64-elf, really), and on AIX, the lr save | |
| 491 | 491 | slot is 2 words back from sp, whereas on ppc32-elf(?) it's | |
| 492 | 492 | 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) | ||
| 495 | 494 | const Int lr_offset = 2; | |
| 496 | 495 | # else | |
| 497 | 496 | const Int lr_offset = 1; | |
| … | … | ||
| 550 | 550 | } | |
| 551 | 551 | } | |
| 552 | 552 | ||
| 553 | # else | ||
| 554 | # error "Unknown platform" | ||
| 555 | # endif | ||
| 553 | n_found = i; | ||
| 554 | return n_found; | ||
| 555 | } | ||
| 556 | 556 | ||
| 557 | #endif | ||
| 558 | |||
| 559 | /* ------------------------ arm ------------------------- */ | ||
| 560 | |||
| 561 | #if defined(VGP_arm_linux) | ||
| 562 | |||
| 563 | UInt 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 | |||
| 557 | 644 | n_found = i; | |
| 558 | 645 | return n_found; | |
| 559 | 646 | } | |
| 560 | 647 | ||
| 648 | #endif | ||
| 649 | |||
| 650 | /*------------------------------------------------------------*/ | ||
| 651 | /*--- ---*/ | ||
| 652 | /*--- END platform-dependent unwinder worker functions ---*/ | ||
| 653 | /*--- ---*/ | ||
| 654 | /*------------------------------------------------------------*/ | ||
| 655 | |||
| 656 | /*------------------------------------------------------------*/ | ||
| 657 | /*--- Exported functions. ---*/ | ||
| 658 | /*------------------------------------------------------------*/ | ||
| 659 | |||
| 561 | 660 | UInt VG_(get_StackTrace) ( ThreadId tid, | |
| 562 | 661 | /*OUT*/StackTrace ips, UInt max_n_ips, | |
| 563 | 662 | /*OUT*/StackTrace sps, | |
| 564 | 663 | /*OUT*/StackTrace fps, | |
| 565 | 664 | Word first_ip_delta ) | |
| 566 | 665 | { | |
| 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 | |||
| 572 | 671 | Addr stack_highest_word = VG_(threads)[tid].client_stack_highest_word; | |
| 573 | 672 | Addr stack_lowest_word = 0; | |
| 574 | 673 | ||
| … | … | ||
| 690 | 690 | bothered. | |
| 691 | 691 | */ | |
| 692 | 692 | 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); | ||
| 698 | 699 | } | |
| 699 | 700 | # endif | |
| 700 | 701 | ||
| 701 | 702 | /* 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 ); | ||
| 703 | 705 | ||
| 704 | 706 | /* 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; | ||
| 707 | 708 | ||
| 708 | 709 | 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); | ||
| 712 | 714 | ||
| 713 | 715 | return VG_(get_StackTrace_wrk)(tid, ips, max_n_ips, | |
| 714 | 716 | sps, fps, | |
| 715 | ip, sp, fp, lr, sp, | ||
| 717 | &startRegs, | ||
| 716 | 718 | stack_highest_word); | |
| 717 | 719 | } | |
| 718 | 720 |
coregrind/m_syscall.c
(41 / 0)
|   | |||
| 100 | 100 | return res; | |
| 101 | 101 | } | |
| 102 | 102 | ||
| 103 | SysRes 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 | |||
| 103 | 114 | /* Generic constructors. */ | |
| 104 | 115 | SysRes VG_(mk_SysRes_Error) ( UWord err ) { | |
| 105 | 116 | SysRes r; | |
| … | … | ||
| 410 | 410 | " blr\n" | |
| 411 | 411 | ); | |
| 412 | 412 | ||
| 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 | */ | ||
| 421 | extern UWord do_syscall_WRK ( | ||
| 422 | UWord a1, UWord a2, UWord a3, | ||
| 423 | UWord a4, UWord a5, UWord a6, | ||
| 424 | UWord syscall_no | ||
| 425 | ); | ||
| 426 | asm( | ||
| 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 | |||
| 413 | 439 | #elif defined(VGP_ppc32_aix5) | |
| 414 | 440 | static void do_syscall_WRK ( UWord* res_r3, UWord* res_r4, | |
| 415 | 441 | UWord sysno, | |
| … | … | ||
| 756 | 756 | argblock[6] = a6; | |
| 757 | 757 | do_syscall_WRK( &argblock[0] ); | |
| 758 | 758 | 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 ); | ||
| 759 | 763 | ||
| 760 | 764 | # elif defined(VGP_ppc32_aix5) | |
| 761 | 765 | UWord res; |
|   | |||
| 83 | 83 | // Note that, depending on the platform, arguments may be found in | |
| 84 | 84 | // registers or on the stack. (See the comment at the top of | |
| 85 | 85 | // 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 | ||
| 87 | 87 | // the vex register state. For stack arguments (which have s_arg | |
| 88 | 88 | // field names), the s_arg value is the offset from the stack pointer. | |
| 89 | 89 | Int o_sysno; | |
| 90 | 90 | # 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) | ||
| 92 | 93 | Int o_arg1; | |
| 93 | 94 | Int o_arg2; | |
| 94 | 95 | Int o_arg3; | |
| … | … | ||
| 171 | 171 | */ | |
| 172 | 172 | ||
| 173 | 173 | ||
| 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) | ||
| 180 | extern | ||
| 181 | SyscallTableEntry* ML_(get_linux_syscall_entry)( UInt sysno ); | ||
| 178 | 182 | ||
| 179 | extern const SyscallTableEntry ML_(syscall_table)[]; | ||
| 180 | |||
| 181 | extern const UInt ML_(syscall_table_size); | ||
| 182 | |||
| 183 | 183 | #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. */ | ||
| 188 | 187 | extern | |
| 189 | 188 | SyscallTableEntry* ML_(get_ppc32_aix5_syscall_entry) ( UInt sysno ); | |
| 190 | 189 | ||
| 191 | 190 | #elif defined(VGP_ppc64_aix5) | |
| 192 | 191 | extern | |
| 193 | 192 | SyscallTableEntry* 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 | |||
| 199 | extern const SyscallTableEntry ML_(syscall_table)[]; | ||
| 200 | extern const UInt ML_(syscall_table_size); | ||
| 194 | 201 | ||
| 195 | 202 | #else | |
| 196 | 203 | # 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) | ||
| 77 | ML_(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 | |||
| 82 | 1: | ||
| 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 | |||
| 102 | 2: svc 0x00000000 | ||
| 103 | 3: | ||
| 104 | ldr r5, [sp, #4] /* guest_state */ | ||
| 105 | str r0, [r5, #OFFSET_arm_R0] | ||
| 106 | |||
| 107 | 4: | ||
| 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 | |||
| 119 | 5: /* Success */ | ||
| 120 | mov r0, #0 | ||
| 121 | pop {r1, r3, r4, r5, r7, fp, pc} | ||
| 122 | |||
| 123 | 7: /* 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) | ||
| 138 | ML_(blksys_setup): .long 1b | ||
| 139 | ML_(blksys_restart): .long 2b | ||
| 140 | ML_(blksys_complete): .long 3b | ||
| 141 | ML_(blksys_committed): .long 4b | ||
| 142 | ML_(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 | /*--------------------------------------------------------------------*/ |
|   | |||
| 1040 | 1040 | // When implementing these wrappers, you need to work out if the wrapper is | |
| 1041 | 1041 | // generic, Linux-only (but arch-independent), or AMD64/Linux only. | |
| 1042 | 1042 | ||
| 1043 | const SyscallTableEntry ML_(syscall_table)[] = { | ||
| 1043 | static SyscallTableEntry syscall_table[] = { | ||
| 1044 | 1044 | GENXY(__NR_read, sys_read), // 0 | |
| 1045 | 1045 | GENX_(__NR_write, sys_write), // 1 | |
| 1046 | 1046 | GENXY(__NR_open, sys_open), // 2 | |
| … | … | ||
| 1401 | 1401 | LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 298 | |
| 1402 | 1402 | }; | |
| 1403 | 1403 | ||
| 1404 | const UInt ML_(syscall_table_size) = | ||
| 1405 | sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]); | ||
| 1404 | SyscallTableEntry* 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 | } | ||
| 1406 | 1421 | ||
| 1407 | 1422 | #endif // defined(VGP_amd64_linux) | |
| 1408 | 1423 |
coregrind/m_syswrap/syswrap-arm-linux.c
(1709 / 0)
|   | |||
| 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)) | ||
| 69 | void 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 | ||
| 77 | asm( | ||
| 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 | |||
| 105 | extern | ||
| 106 | ULong 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 ); | ||
| 113 | asm( | ||
| 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 | ||
| 150 | static void setup_child ( ThreadArchState*, ThreadArchState* ); | ||
| 151 | static 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 | */ | ||
| 163 | static 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 | |||
| 240 | out: | ||
| 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 | ||
| 258 | void VG_(cleanup_thread) ( ThreadArchState* arch ) | ||
| 259 | { | ||
| 260 | } | ||
| 261 | |||
| 262 | void 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 | |||
| 270 | static 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 | |||
| 289 | DECL_TEMPLATE(arm_linux, sys_socketcall); | ||
| 290 | DECL_TEMPLATE(arm_linux, sys_socket); | ||
| 291 | DECL_TEMPLATE(arm_linux, sys_setsockopt); | ||
| 292 | DECL_TEMPLATE(arm_linux, sys_getsockopt); | ||
| 293 | DECL_TEMPLATE(arm_linux, sys_connect); | ||
| 294 | DECL_TEMPLATE(arm_linux, sys_accept); | ||
| 295 | DECL_TEMPLATE(arm_linux, sys_sendto); | ||
| 296 | DECL_TEMPLATE(arm_linux, sys_recvfrom); | ||
| 297 | //XXX: Semaphore code ripped from AMD64. | ||
| 298 | DECL_TEMPLATE(arm_linux, sys_semget); | ||
| 299 | DECL_TEMPLATE(arm_linux, sys_semop); | ||
| 300 | DECL_TEMPLATE(arm_linux, sys_semctl); | ||
| 301 | DECL_TEMPLATE(arm_linux, sys_semtimedop); | ||
| 302 | //XXX: Shared memory code ripped from AMD64 | ||
| 303 | // | ||
| 304 | DECL_TEMPLATE(arm_linux, wrap_sys_shmat); | ||
| 305 | DECL_TEMPLATE(arm_linux, sys_shmget); | ||
| 306 | DECL_TEMPLATE(arm_linux, sys_shmdt); | ||
| 307 | DECL_TEMPLATE(arm_linux, sys_shmctl); | ||
| 308 | DECL_TEMPLATE(arm_linux, sys_sendmsg); | ||
| 309 | DECL_TEMPLATE(arm_linux, sys_recvmsg); | ||
| 310 | //msg* code from AMD64 | ||
| 311 | DECL_TEMPLATE(arm_linux, sys_msgget); | ||
| 312 | DECL_TEMPLATE(arm_linux, sys_msgrcv); | ||
| 313 | DECL_TEMPLATE(arm_linux, sys_msgsnd); | ||
| 314 | DECL_TEMPLATE(arm_linux, sys_msgctl); | ||
| 315 | DECL_TEMPLATE(arm_linux, sys_shutdown); | ||
| 316 | DECL_TEMPLATE(arm_linux, sys_bind); | ||
| 317 | DECL_TEMPLATE(arm_linux, sys_listen); | ||
| 318 | DECL_TEMPLATE(arm_linux, sys_getsockname); | ||
| 319 | DECL_TEMPLATE(arm_linux, sys_getpeername); | ||
| 320 | DECL_TEMPLATE(arm_linux, sys_socketpair); | ||
| 321 | DECL_TEMPLATE(arm_linux, sys_send); | ||
| 322 | DECL_TEMPLATE(arm_linux, sys_recv); | ||
| 323 | DECL_TEMPLATE(arm_linux, sys_mmap); | ||
| 324 | DECL_TEMPLATE(arm_linux, sys_mmap2); | ||
| 325 | DECL_TEMPLATE(arm_linux, sys_stat64); | ||
| 326 | DECL_TEMPLATE(arm_linux, sys_lstat64); | ||
| 327 | DECL_TEMPLATE(arm_linux, sys_fstatat64); | ||
| 328 | DECL_TEMPLATE(arm_linux, sys_fstat64); | ||
| 329 | DECL_TEMPLATE(arm_linux, sys_ipc); | ||
| 330 | DECL_TEMPLATE(arm_linux, sys_clone); | ||
| 331 | DECL_TEMPLATE(arm_linux, sys_sigreturn); | ||
| 332 | DECL_TEMPLATE(arm_linux, sys_rt_sigreturn); | ||
| 333 | DECL_TEMPLATE(arm_linux, sys_sigaction); | ||
| 334 | DECL_TEMPLATE(arm_linux, sys_sigsuspend); | ||
| 335 | DECL_TEMPLATE(arm_linux, sys_set_tls); | ||
| 336 | DECL_TEMPLATE(arm_linux, sys_cacheflush); | ||
| 337 | |||
| 338 | PRE(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 | |||
| 492 | POST(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 | |||
| 595 | PRE(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 | } | ||
| 600 | POST(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 | |||
| 608 | PRE(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 | |||
| 617 | PRE(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 | } | ||
| 625 | POST(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 | |||
| 632 | PRE(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 | |||
| 641 | PRE(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 | } | ||
| 649 | POST(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 | |||
| 658 | PRE(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 | |||
| 669 | PRE(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 | } | ||
| 678 | POST(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 | |||
| 685 | PRE(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 | |||
| 694 | PRE(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 | } | ||
| 701 | POST(sys_recvmsg) | ||
| 702 | { | ||
| 703 | ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2); | ||
| 704 | } | ||
| 705 | |||
| 706 | //XXX: Semaphore code ripped from AMD64. | ||
| 707 | PRE(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 | |||
| 713 | PRE(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 | |||
| 722 | PRE(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 | |||
| 753 | POST(sys_semctl) | ||
| 754 | { | ||
| 755 | ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4); | ||
| 756 | } | ||
| 757 | |||
| 758 | PRE(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 | ||
| 769 | PRE(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 | |||
| 775 | PRE(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 | |||
| 785 | PRE(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 | } | ||
| 795 | POST(sys_msgrcv) | ||
| 796 | { | ||
| 797 | ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5); | ||
| 798 | } | ||
| 799 | |||
| 800 | |||
| 801 | PRE(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 | } | ||
| 808 | POST(sys_msgctl) | ||
| 809 | { | ||
| 810 | ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3); | ||
| 811 | } | ||
| 812 | |||
| 813 | //shared memory code from AMD64 | ||
| 814 | PRE(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 | |||
| 820 | PRE(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 | |||
| 833 | POST(wrap_sys_shmat) | ||
| 834 | { | ||
| 835 | ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3); | ||
| 836 | } | ||
| 837 | |||
| 838 | PRE(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 | |||
| 846 | POST(sys_shmdt) | ||
| 847 | { | ||
| 848 | ML_(generic_POST_sys_shmdt)(tid, RES,ARG1); | ||
| 849 | } | ||
| 850 | |||
| 851 | PRE(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 | |||
| 859 | POST(sys_shmctl) | ||
| 860 | { | ||
| 861 | ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3); | ||
| 862 | } | ||
| 863 | |||
| 864 | PRE(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 | |||
| 871 | PRE(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 | |||
| 879 | PRE(sys_listen) | ||
| 880 | { | ||
| 881 | PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2); | ||
| 882 | PRE_REG_READ2(long, "listen", int, s, int, backlog); | ||
| 883 | } | ||
| 884 | |||
| 885 | PRE(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 | } | ||
| 892 | POST(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 | |||
| 899 | PRE(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 | } | ||
| 906 | POST(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 | |||
| 913 | PRE(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 | } | ||
| 920 | POST(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 | |||
| 927 | PRE(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 | |||
| 938 | PRE(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 | |||
| 947 | POST(sys_recv) | ||
| 948 | { | ||
| 949 | ML_(generic_POST_sys_recv)( tid, RES, ARG1, ARG2, ARG3 ); | ||
| 950 | } | ||
| 951 | |||
| 952 | PRE(sys_mmap) | ||
| 953 | { | ||
| 954 | I_die_here; | ||
| 955 | } | ||
| 956 | |||
| 957 | PRE(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 | ||
| 984 | PRE(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 | |||
| 992 | POST(sys_lstat64) | ||
| 993 | { | ||
| 994 | vg_assert(SUCCESS); | ||
| 995 | if (RES == 0) { | ||
| 996 | POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); | ||
| 997 | } | ||
| 998 | } | ||
| 999 | |||
| 1000 | PRE(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 | |||
| 1008 | POST(sys_stat64) | ||
| 1009 | { | ||
| 1010 | POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | PRE(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 | |||
| 1022 | POST(sys_fstatat64) | ||
| 1023 | { | ||
| 1024 | POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) ); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | PRE(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 | |||
| 1034 | POST(sys_fstat64) | ||
| 1035 | { | ||
| 1036 | POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | |||
| 1040 | PRE(sys_ipc) | ||
| 1041 | { | ||
| 1042 | I_die_here; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | POST(sys_ipc) | ||
| 1046 | { | ||
| 1047 | I_die_here; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | PRE(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 | |||
| 1145 | PRE(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 | |||
| 1168 | PRE(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 | |||
| 1191 | PRE(sys_sigaction) | ||
| 1192 | { | ||
| 1193 | I_die_here; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | POST(sys_sigaction) | ||
| 1197 | { I_die_here; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | PRE(sys_sigsuspend) | ||
| 1201 | { I_die_here; | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | /* Very much ARM specific */ | ||
| 1205 | |||
| 1206 | PRE(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 | |||
| 1213 | PRE(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 | |||
| 1244 | static 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 | |||
| 1674 | static SyscallTableEntry ste___ARM_set_tls | ||
| 1675 | = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL }; | ||
| 1676 | |||
| 1677 | static SyscallTableEntry ste___ARM_cacheflush | ||
| 1678 | = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL }; | ||
| 1679 | |||
| 1680 | SyscallTableEntry* 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 | /*--------------------------------------------------------------------*/ |
|   | |||
| 195 | 195 | : "=m" (tst->status) | |
| 196 | 196 | : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)); | |
| 197 | 197 | } | |
| 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)); | ||
| 198 | 206 | #else | |
| 199 | 207 | # error Unknown platform | |
| 200 | 208 | #endif | |
| … | … | ||
| 327 | 327 | ||
| 328 | 328 | /* Since this is the fork() form of clone, we don't need all that | |
| 329 | 329 | 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) | ||
| 331 | 333 | res = VG_(do_syscall5)( __NR_clone, flags, | |
| 332 | 334 | (UWord)NULL, (UWord)parent_tidptr, | |
| 333 | 335 | (UWord)NULL, (UWord)child_tidptr ); |
|   | |||
| 455 | 455 | canonical->arg7 = 0; | |
| 456 | 456 | canonical->arg8 = 0; | |
| 457 | 457 | ||
| 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 | |||
| 458 | 470 | #elif defined(VGP_ppc32_aix5) | |
| 459 | 471 | VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; | |
| 460 | 472 | canonical->sysno = gst->guest_GPR2; | |
| … | … | ||
| 659 | 659 | gst->guest_GPR7 = canonical->arg5; | |
| 660 | 660 | gst->guest_GPR8 = canonical->arg6; | |
| 661 | 661 | ||
| 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 | |||
| 662 | 672 | #elif defined(VGP_ppc32_aix5) | |
| 663 | 673 | VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; | |
| 664 | 674 | gst->guest_GPR2 = canonical->sysno; | |
| … | … | ||
| 760 | 760 | canonical->sres = VG_(mk_SysRes_ppc64_linux)( gst->guest_GPR3, cr0so ); | |
| 761 | 761 | canonical->what = SsComplete; | |
| 762 | 762 | ||
| 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 | |||
| 763 | 768 | # elif defined(VGP_ppc32_aix5) | |
| 764 | 769 | VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; | |
| 765 | 770 | canonical->sres = VG_(mk_SysRes_ppc32_aix5)( gst->guest_GPR3, | |
| … | … | ||
| 871 | 871 | if (sr_isError(canonical->sres)) { | |
| 872 | 872 | /* This isn't exactly right, in that really a Failure with res | |
| 873 | 873 | not in the range 1 .. 4095 is unrepresentable in the | |
| 874 | Linux-x86 scheme. Oh well. */ | ||
| 874 | Linux-amd64 scheme. Oh well. */ | ||
| 875 | 875 | gst->guest_RAX = - (Long)sr_Err(canonical->sres); | |
| 876 | 876 | } else { | |
| 877 | 877 | gst->guest_RAX = sr_Res(canonical->sres); | |
| … | … | ||
| 915 | 915 | VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, | |
| 916 | 916 | OFFSET_ppc64_CR0_0, sizeof(UChar) ); | |
| 917 | 917 | ||
| 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 | |||
| 918 | 932 | # elif defined(VGP_ppc32_aix5) | |
| 919 | 933 | VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; | |
| 920 | 934 | vg_assert(canonical->what == SsComplete); | |
| … | … | ||
| 1072 | 1072 | layout->uu_arg7 = -1; /* impossible value */ | |
| 1073 | 1073 | layout->uu_arg8 = -1; /* impossible value */ | |
| 1074 | 1074 | ||
| 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 | |||
| 1075 | 1086 | #elif defined(VGP_ppc32_aix5) | |
| 1076 | 1087 | layout->o_sysno = OFFSET_ppc32_GPR2; | |
| 1077 | 1088 | layout->o_arg1 = OFFSET_ppc32_GPR3; | |
| … | … | ||
| 1169 | 1169 | const SyscallTableEntry* sys = NULL; | |
| 1170 | 1170 | ||
| 1171 | 1171 | # 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 ); | ||
| 1175 | 1173 | ||
| 1176 | 1174 | # elif defined(VGP_ppc32_aix5) | |
| 1177 | 1175 | sys = ML_(get_ppc32_aix5_syscall_entry) ( syscallno ); | |
| … | … | ||
| 1861 | 1861 | arch->vex.guest_CIA + 0ULL, p[0], p[1], p[2], p[3]); | |
| 1862 | 1862 | ||
| 1863 | 1863 | 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); | ||
| 1864 | 1877 | } | |
| 1865 | 1878 | ||
| 1866 | 1879 | #elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) |
|   | |||
| 1861 | 1861 | // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? | |
| 1862 | 1862 | // (unknown). | |
| 1863 | 1863 | ||
| 1864 | const SyscallTableEntry ML_(syscall_table)[] = { | ||
| 1864 | static SyscallTableEntry syscall_table[] = { | ||
| 1865 | 1865 | //zz // (restart_syscall) // 0 | |
| 1866 | 1866 | GENX_(__NR_exit, sys_exit), // 1 | |
| 1867 | 1867 | GENX_(__NR_fork, sys_fork), // 2 | |
| … | … | ||
| 2271 | 2271 | LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 336 | |
| 2272 | 2272 | }; | |
| 2273 | 2273 | ||
| 2274 | const UInt ML_(syscall_table_size) = | ||
| 2275 | sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]); | ||
| 2274 | SyscallTableEntry* 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 | } | ||
| 2276 | 2291 | ||
| 2277 | 2292 | #endif // defined(VGP_x86_linux) | |
| 2278 | 2293 |
coregrind/m_trampoline.S
(150 / 1)
|   | |||
| 479 | 479 | # undef UD2_1024 | |
| 480 | 480 | # undef UD2_PAGE | |
| 481 | 481 | ||
| 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) | ||
| 497 | VG_(trampoline_stuff_start): | ||
| 498 | |||
| 499 | .global VG_(arm_linux_REDIR_FOR_strlen) | ||
| 500 | VG_(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) | ||
| 537 | VG_(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) | ||
| 615 | VG_(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 | |||
| 482 | 627 | /*---------------- ppc32-aix5 ----------------*/ | |
| 483 | 628 | #else | |
| 484 | 629 | #if defined(VGP_ppc32_aix5) | |
| … | … | ||
| 1221 | 1221 | ||
| 1222 | 1222 | #if defined(VGO_linux) | |
| 1223 | 1223 | /* 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 | ||
| 1225 | 1229 | #endif | |
| 1226 | 1230 | ||
| 1227 | 1231 | /*--------------------------------------------------------------------*/ |
coregrind/m_translate.c
(2 / 1)
|   | |||
| 1507 | 1507 | VG_(clo_profile_flags) > 0 | |
| 1508 | 1508 | ? (void*) &VG_(run_innerloop__dispatch_profiled) | |
| 1509 | 1509 | : (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) | ||
| 1511 | 1512 | vta.dispatch = NULL; | |
| 1512 | 1513 | # else | |
| 1513 | 1514 | # error "Unknown arch" |
coregrind/m_transtab.c
(21 / 6)
|   | |||
| 41 | 41 | #include "pub_core_aspacemgr.h" | |
| 42 | 42 | #include "pub_core_mallocfree.h" // VG_(out_of_memory_NORETURN) | |
| 43 | 43 | ||
| 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 | |||
| 44 | 51 | /* #define DEBUG_TRANSTAB */ | |
| 45 | 52 | ||
| 46 | 53 | ||
| … | … | ||
| 815 | 815 | vg_assert(cls == 32 || cls == 64 || cls == 128); | |
| 816 | 816 | ||
| 817 | 817 | 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"); | ||
| 824 | 826 | ||
| 825 | 827 | # elif defined(VGA_x86) | |
| 826 | 828 | /* no need to do anything, hardware provides coherence */ | |
| 827 | 829 | ||
| 828 | 830 | # elif defined(VGA_amd64) | |
| 829 | 831 | /* 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); | ||
| 830 | 838 | ||
| 831 | 839 | # else | |
| 832 | 840 | # error "Unknown ARCH" |
coregrind/pub_core_basics.h
(46 / 0)
|   | |||
| 56 | 56 | # include "libvex_guest_ppc32.h" | |
| 57 | 57 | #elif defined(VGA_ppc64) | |
| 58 | 58 | # include "libvex_guest_ppc64.h" | |
| 59 | #elif defined(VGA_arm) | ||
| 60 | # include "libvex_guest_arm.h" | ||
| 59 | 61 | #else | |
| 60 | 62 | # error Unknown arch | |
| 61 | 63 | #endif | |
| 62 | 64 | ||
| 63 | 65 | // For jmp_buf | |
| 64 | 66 | #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 | |||
| 85 | typedef | ||
| 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 | |||
| 65 | 111 | ||
| 66 | 112 | #endif // __PUB_CORE_BASICS_H | |
| 67 | 113 |
|   | |||
| 63 | 63 | __attribute__ ((__noreturn__)) | |
| 64 | 64 | extern void VG_(core_panic) ( Char* str ); | |
| 65 | 65 | __attribute__ ((__noreturn__)) | |
| 66 | extern void VG_(core_panic_at) ( Char* str, | ||
| 67 | Addr ip, Addr sp, Addr fp, Addr lr ); | ||
| 66 | extern void VG_(core_panic_at) ( Char* str, UnwindStartRegs* ); | ||
| 68 | 67 | ||
| 69 | 68 | /* Called when some unhandleable client behaviour is detected. | |
| 70 | 69 | Prints a msg and aborts. */ |
coregrind/pub_core_machine.h
(16 / 0)
|   | |||
| 60 | 60 | # define VG_ELF_MACHINE EM_PPC64 | |
| 61 | 61 | # define VG_ELF_CLASS ELFCLASS64 | |
| 62 | 62 | # 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 | ||
| 63 | 68 | #elif defined(VGO_aix5) | |
| 64 | 69 | # undef VG_ELF_DATA2XXX | |
| 65 | 70 | # undef VG_ELF_MACHINE | |
| … | … | ||
| 95 | 95 | # define VG_INSTR_PTR guest_CIA | |
| 96 | 96 | # define VG_STACK_PTR guest_GPR1 | |
| 97 | 97 | # 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 | ||
| 98 | 102 | #else | |
| 99 | 103 | # error Unknown arch | |
| 100 | 104 | #endif | |
| … | … | ||
| 107 | 107 | // Offsets for the Vex state | |
| 108 | 108 | #define VG_O_STACK_PTR (offsetof(VexGuestArchState, VG_STACK_PTR)) | |
| 109 | 109 | #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. | ||
| 115 | void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs, | ||
| 116 | ThreadId tid ); | ||
| 110 | 117 | ||
| 111 | 118 | ||
| 112 | 119 | //------------------------------------------------------------- |
|   | |||
| 71 | 71 | // greater than 8. | |
| 72 | 72 | #if defined(VGP_x86_linux) || \ | |
| 73 | 73 | defined(VGP_ppc32_linux) || \ | |
| 74 | defined(VGP_ppc32_aix5) | ||
| 74 | defined(VGP_arm_linux) | ||
| 75 | 75 | # define VG_MIN_MALLOC_SZB 8 | |
| 76 | 76 | // Nb: We always use 16 bytes for Darwin, even on 32-bits, so it can be used | |
| 77 | 77 | // for any AltiVec- or SSE-related type. This matches the Darwin libc. | |
| 78 | 78 | #elif defined(VGP_amd64_linux) || \ | |
| 79 | 79 | defined(VGP_ppc64_linux) || \ | |
| 80 | 80 | defined(VGP_ppc64_aix5) || \ | |
| 81 | defined(VGP_ppc32_aix5) || \ | ||
| 81 | 82 | defined(VGP_x86_darwin) || \ | |
| 82 | 83 | defined(VGP_amd64_darwin) | |
| 83 | 84 | # define VG_MIN_MALLOC_SZB 16 |
|   | |||
| 53 | 53 | UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, | |
| 54 | 54 | /*OUT*/Addr* ips, UInt n_ips, | |
| 55 | 55 | /*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 ); | ||
| 58 | 58 | ||
| 59 | 59 | #endif // __PUB_CORE_STACKTRACE_H | |
| 60 | 60 |
coregrind/pub_core_syscall.h
(1 / 0)
|   | |||
| 73 | 73 | extern SysRes VG_(mk_SysRes_amd64_linux) ( Long val ); | |
| 74 | 74 | extern SysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so ); | |
| 75 | 75 | extern SysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong cr0so ); | |
| 76 | extern SysRes VG_(mk_SysRes_arm_linux) ( Int val ); | ||
| 76 | 77 | extern SysRes VG_(mk_SysRes_ppc32_aix5) ( UInt val, UInt err ); | |
| 77 | 78 | extern SysRes VG_(mk_SysRes_ppc64_aix5) ( ULong val, ULong err ); | |
| 78 | 79 | extern SysRes VG_(mk_SysRes_x86_darwin) ( UChar scclass, Bool isErr, |
|   | |||
| 83 | 83 | typedef VexGuestPPC32State VexGuestArchState; | |
| 84 | 84 | #elif defined(VGA_ppc64) | |
| 85 | 85 | typedef VexGuestPPC64State VexGuestArchState; | |
| 86 | #elif defined(VGA_arm) | ||
| 87 | typedef VexGuestARMState VexGuestArchState; | ||
| 86 | 88 | #else | |
| 87 | 89 | # error Unknown architecture | |
| 88 | 90 | #endif |
|   | |||
| 91 | 91 | extern void VG_(ppctoc_magic_redirect_return_stub); | |
| 92 | 92 | #endif | |
| 93 | 93 | ||
| 94 | #if defined(VGP_arm_linux) | ||
| 95 | extern UInt VG_(arm_linux_REDIR_FOR_strlen)( void* ); | ||
| 96 | //extern void* VG_(arm_linux_REDIR_FOR_index) ( void*, Int ); | ||
| 97 | extern void* VG_(arm_linux_REDIR_FOR_memcpy)( void*, void*, Int ); | ||
| 98 | #endif | ||
| 99 | |||
| 94 | 100 | #if defined(VGP_ppc32_aix5) | |
| 95 | 101 | /* A label (sans dot) marking the client start point for ppc32_aix5. | |
| 96 | 102 | This function is entered with r3 holding a pointer to the |
|   | |||
| 40 | 40 | On ppc32/ppc64, the bottom two bits of instruction addresses are | |
| 41 | 41 | zero, which means that function causes only 1/4 of the entries to | |
| 42 | 42 | 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. | ||
| 44 | 44 | ||
| 45 | On ARM we do like ppc32/ppc64, although that will have to be | ||
| 46 | revisited when we come to implement Thumb. */ | ||
| 47 | |||
| 45 | 48 | #define VG_TT_FAST_BITS 15 | |
| 46 | 49 | #define VG_TT_FAST_SIZE (1 << VG_TT_FAST_BITS) | |
| 47 | 50 | #define VG_TT_FAST_MASK ((VG_TT_FAST_SIZE) - 1) | |
| … | … | ||
| 53 | 53 | like a good place to put it. */ | |
| 54 | 54 | #if defined(VGA_x86) || defined(VGA_amd64) | |
| 55 | 55 | # 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) | ||
| 57 | 57 | # define VG_TT_FAST_HASH(_addr) ((((UWord)(_addr)) >> 2) & VG_TT_FAST_MASK) | |
| 58 | 58 | #else | |
| 59 | 59 | # error "VG_TT_FAST_HASH: unknown platform" |
docs/internals/register-uses.txt
(31 / 0)
|   | |||
| 95 | 95 | TBD | |
| 96 | 96 | ||
| 97 | 97 | ||
| 98 | arm-linux | ||
| 99 | ~~~~~~~~~ | ||
| 100 | |||
| 101 | Reg Callee Arg | ||
| 102 | Name Saves? Reg? Comment Vex-uses? | ||
| 103 | -------------------------------------------------------------- | ||
| 104 | r0 int#1 int[31:0] retreg? avail | ||
| 105 | r1 int#2 int[63:32] retreg? avail | ||
| 106 | r2 int#3 avail | ||
| 107 | r3 int#4 avail | ||
| 108 | r4 y avail | ||
| 109 | r5 y avail | ||
| 110 | r6 y avail | ||
| 111 | r7 y avail | ||
| 112 | r8 y GSP | ||
| 113 | r9 y (but only on Linux; not in general) avail | ||
| 114 | r10 y avail | ||
| 115 | r11 y avail | ||
| 116 | r12 possibly used by linker? unavail | ||
| 117 | r13(sp) unavail | ||
| 118 | r14(lr) unavail | ||
| 119 | r15(pc) unavail | ||
| 120 | |||
| 121 | VFP: d8-d15 are callee-saved | ||
| 122 | r12 (IP) is probably available for use as a caller-saved | ||
| 123 | register; but instead we use it as an intermediate for | ||
| 124 | holding the address for F32/F64 spills, since the VFP load/store | ||
| 125 | insns have reg+offset forms for offsets only up to 1020, which | ||
| 126 | often isn't enough. | ||
| 127 | |||
| 128 | |||
| 98 | 129 | ppc32-aix5 | |
| 99 | 130 | ~~~~~~~~~~ | |
| 100 | 131 |
include/pub_tool_basics.h
(3 / 2)
|   | |||
| 290 | 290 | #undef VG_BIGENDIAN | |
| 291 | 291 | #undef VG_LITTLEENDIAN | |
| 292 | 292 | ||
| 293 | #if defined(VGA_x86) || defined(VGA_amd64) | ||
| 293 | #if defined(VGA_x86) || defined(VGA_amd64) || defined (VGA_arm) | ||
| 294 | 294 | # define VG_LITTLEENDIAN 1 | |
| 295 | 295 | #elif defined(VGA_ppc32) || defined(VGA_ppc64) | |
| 296 | 296 | # define VG_BIGENDIAN 1 | |
| … | … | ||
| 301 | 301 | /* Regparmness */ | |
| 302 | 302 | #if defined(VGA_x86) | |
| 303 | 303 | # 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) | ||
| 305 | 306 | # define VG_REGPARM(n) /* */ | |
| 306 | 307 | #else | |
| 307 | 308 | # error Unknown arch |
include/pub_tool_machine.h
(16 / 1)
|   | |||
| 37 | 37 | # define VG_CLREQ_SZB 14 // length of a client request, may | |
| 38 | 38 | // be larger than VG_MAX_INSTR_SZB | |
| 39 | 39 | # define VG_STACK_REDZONE_SZB 0 // number of addressable bytes below %RSP | |
| 40 | |||
| 40 | 41 | #elif defined(VGP_amd64_linux) | |
| 41 | 42 | # define VG_MIN_INSTR_SZB 1 | |
| 42 | 43 | # define VG_MAX_INSTR_SZB 16 | |
| 43 | 44 | # define VG_CLREQ_SZB 19 | |
| 44 | 45 | # define VG_STACK_REDZONE_SZB 128 | |
| 46 | |||
| 45 | 47 | #elif defined(VGP_ppc32_linux) | |
| 46 | 48 | # define VG_MIN_INSTR_SZB 4 | |
| 47 | 49 | # define VG_MAX_INSTR_SZB 4 | |
| 48 | 50 | # define VG_CLREQ_SZB 20 | |
| 49 | 51 | # define VG_STACK_REDZONE_SZB 0 | |
| 52 | |||
| 50 | 53 | #elif defined(VGP_ppc64_linux) | |
| 51 | 54 | # define VG_MIN_INSTR_SZB 4 | |
| 52 | 55 | # define VG_MAX_INSTR_SZB 4 | |
| 53 | 56 | # define VG_CLREQ_SZB 20 | |
| 54 | 57 | # 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 | |||
| 56 | 67 | #elif defined(VGP_ppc32_aix5) | |
| 57 | 68 | # define VG_MIN_INSTR_SZB 4 | |
| 58 | 69 | # define VG_MAX_INSTR_SZB 4 | |
| … | … | ||
| 74 | 74 | 8-alignment of the area to be messed with. So let's just say | |
| 75 | 75 | 224 instead. Gdb has a similar kludge. */ | |
| 76 | 76 | # define VG_STACK_REDZONE_SZB 224 | |
| 77 | |||
| 77 | 78 | #elif defined(VGP_ppc64_aix5) | |
| 78 | 79 | # define VG_MIN_INSTR_SZB 4 | |
| 79 | 80 | # define VG_MAX_INSTR_SZB 4 | |
| 80 | 81 | # define VG_CLREQ_SZB 20 | |
| 81 | 82 | # define VG_STACK_REDZONE_SZB 288 // is this right? | |
| 83 | |||
| 82 | 84 | #elif defined(VGP_x86_darwin) | |
| 83 | 85 | # define VG_MIN_INSTR_SZB 1 // min length of native instruction | |
| 84 | 86 | # define VG_MAX_INSTR_SZB 16 // max length of native instruction | |
| 85 | 87 | # define VG_CLREQ_SZB 14 // length of a client request, may | |
| 86 | 88 | // be larger than VG_MAX_INSTR_SZB | |
| 87 | 89 | # define VG_STACK_REDZONE_SZB 0 // number of addressable bytes below %RSP | |
| 90 | |||
| 88 | 91 | #elif defined(VGP_amd64_darwin) | |
| 89 | 92 | # define VG_MIN_INSTR_SZB 1 | |
| 90 | 93 | # define VG_MAX_INSTR_SZB 16 | |
| 91 | 94 | # define VG_CLREQ_SZB 19 | |
| 92 | 95 | # define VG_STACK_REDZONE_SZB 128 | |
| 96 | |||
| 93 | 97 | #else | |
| 94 | 98 | # error Unknown platform | |
| 95 | 99 | #endif |
|   | |||
| 45 | 45 | #elif defined(VGP_ppc64_linux) | |
| 46 | 46 | # include "vki/vki-scnums-ppc64-linux.h" | |
| 47 | 47 | ||
| 48 | #elif defined(VGP_arm_linux) | ||
| 49 | # include "vki/vki-scnums-arm-linux.h" | ||
| 50 | |||
| 48 | 51 | #elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) | |
| 49 | 52 | // Nothing: vki-scnums-aix5.h only contains stuff suitable for inclusion | |
| 50 | 53 | // in C files, not asm files. So unlike all the other |
include/valgrind.h
(488 / 6)
|   | |||
| 84 | 84 | identifying architectures, which are different to the ones we use | |
| 85 | 85 | within the rest of Valgrind. Note, __powerpc__ is active for both | |
| 86 | 86 | 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 | */ | ||
| 88 | 92 | #undef PLAT_x86_linux | |
| 89 | 93 | #undef PLAT_amd64_linux | |
| 90 | 94 | #undef PLAT_ppc32_linux | |
| 91 | 95 | #undef PLAT_ppc64_linux | |
| 96 | #undef PLAT_arm_linux | ||
| 92 | 97 | #undef PLAT_ppc32_aix5 | |
| 93 | 98 | #undef PLAT_ppc64_aix5 | |
| 94 | 99 | ||
| 95 | |||
| 96 | 100 | #if defined(_AIX) && defined(__64BIT__) | |
| 97 | 101 | # define PLAT_ppc64_aix5 1 | |
| 98 | 102 | #elif defined(_AIX) && !defined(__64BIT__) | |
| … | … | ||
| 105 | 105 | # define PLAT_x86_darwin 1 | |
| 106 | 106 | #elif defined(__APPLE__) && defined(__x86_64__) | |
| 107 | 107 | # define PLAT_amd64_darwin 1 | |
| 108 | #elif defined(__i386__) | ||
| 108 | #elif defined(__linux__) && defined(__i386__) | ||
| 109 | 109 | # define PLAT_x86_linux 1 | |
| 110 | #elif defined(__x86_64__) | ||
| 110 | #elif defined(__linux__) && defined(__x86_64__) | ||
| 111 | 111 | # define PLAT_amd64_linux 1 | |
| 112 | #elif defined(__powerpc__) && !defined(__powerpc64__) | ||
| 112 | #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) | ||
| 113 | 113 | # define PLAT_ppc32_linux 1 | |
| 114 | #elif defined(__powerpc__) && defined(__powerpc64__) | ||
| 114 | #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) | ||
| 115 | 115 | # define PLAT_ppc64_linux 1 | |
| 116 | #elif defined(__linux__) && defined(__arm__) | ||
| 117 | # define PLAT_arm_linux 1 | ||
| 116 | 118 | #else | |
| 117 | 119 | /* If we're not compiling for our target platform, don't generate | |
| 118 | 120 | any inline asms. */ | |
| … | … | ||
| 412 | 412 | ||
| 413 | 413 | #endif /* PLAT_ppc64_linux */ | |
| 414 | 414 | ||
| 415 | /* ------------------------- arm-linux ------------------------- */ | ||
| 416 | |||
| 417 | #if defined(PLAT_arm_linux) | ||
| 418 | |||
| 419 | typedef | ||
| 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 | |||
| 415 | 474 | /* ------------------------ ppc32-aix5 ------------------------- */ | |
| 416 | 475 | ||
| 417 | 476 | #if defined(PLAT_ppc32_aix5) | |
| … | … | ||
| 2523 | 2523 | ||
| 2524 | 2524 | #endif /* PLAT_ppc64_linux */ | |
| 2525 | 2525 | ||
| 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 | |||
| 2526 | 2942 | /* ------------------------ ppc32-aix5 ------------------------- */ | |
| 2527 | 2943 | ||
| 2528 | 2944 | #if defined(PLAT_ppc32_aix5) | |
| … | … | ||
| 4495 | 4495 | #undef PLAT_amd64_linux | |
| 4496 | 4496 | #undef PLAT_ppc32_linux | |
| 4497 | 4497 | #undef PLAT_ppc64_linux | |
| 4498 | #undef PLAT_arm_linux | ||
| 4498 | 4499 | #undef PLAT_ppc32_aix5 | |
| 4499 | 4500 | #undef PLAT_ppc64_aix5 | |
| 4500 | 4501 |
include/vki/vki-arm-linux.h
(889 / 0)
|   | |||
| 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 | |||
| 41 | typedef unsigned char __vki_u8; | ||
| 42 | |||
| 43 | typedef __signed__ short __vki_s16; | ||
| 44 | typedef unsigned short __vki_u16; | ||
| 45 | |||
| 46 | typedef __signed__ int __vki_s32; | ||
| 47 | typedef unsigned int __vki_u32; | ||
| 48 | |||
| 49 | typedef __signed__ long long __vki_s64; | ||
| 50 | typedef unsigned long long __vki_u64; | ||
| 51 | |||
| 52 | typedef unsigned short vki_u16; | ||
| 53 | |||
| 54 | typedef 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. */ | ||
| 77 | typedef void __vki_signalfn_t(int); | ||
| 78 | typedef __vki_signalfn_t __user *__vki_sighandler_t; | ||
| 79 | |||
| 80 | typedef void __vki_restorefn_t(void); | ||
| 81 | typedef __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 | |||
| 90 | typedef unsigned long vki_old_sigset_t; /* at least 32 bits */ | ||
| 91 | |||
| 92 | typedef 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 | |||
| 152 | struct 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 | |||
| 163 | struct 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: */ | ||
| 173 | typedef struct vki_sigaction_base vki_sigaction_toK_t; | ||
| 174 | typedef struct vki_sigaction_base vki_sigaction_fromK_t; | ||
| 175 | |||
| 176 | |||
| 177 | typedef 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 | |||
| 187 | struct _vki_fpreg { | ||
| 188 | unsigned short significand[4]; | ||
| 189 | unsigned short exponent; | ||
| 190 | }; | ||
| 191 | |||
| 192 | struct _vki_fpxreg { | ||
| 193 | unsigned short significand[4]; | ||
| 194 | unsigned short exponent; | ||
| 195 | unsigned short padding[3]; | ||
| 196 | }; | ||
| 197 | |||
| 198 | struct _vki_xmmreg { | ||
| 199 | unsigned long element[4]; | ||
| 200 | }; | ||
| 201 | |||
| 202 | struct _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 | |||
| 224 | struct 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 | |||
| 335 | struct 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 | |||
| 356 | struct 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]] | ||
| 395 | struct 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 | |||
| 413 | struct 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 | ||
| 421 | struct 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 | |||
| 435 | typedef unsigned char vki_cc_t; | ||
| 436 | typedef unsigned int vki_tcflag_t; | ||
| 437 | |||
| 438 | #define VKI_NCCS 19 | ||
| 439 | struct 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 */ | ||
| 478 | extern 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 | |||
| 540 | struct 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 | |||
| 550 | struct 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 | |||
| 561 | struct 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 | |||
| 577 | struct 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 | |||
| 602 | typedef unsigned long vki_elf_greg_t; | ||
| 603 | |||
| 604 | #define VKI_ELF_NGREG (sizeof (struct vki_user_regs_struct) / sizeof(vki_elf_greg_t)) | ||
| 605 | typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG]; | ||
| 606 | |||
| 607 | typedef struct vki_user_i387_struct vki_elf_fpregset_t; | ||
| 608 | typedef 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 | |||
| 616 | struct 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.]] */ | ||
| 643 | struct 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]] | ||
| 662 | typedef struct vki_user_desc vki_modify_ldt_t; | ||
| 663 | |||
| 664 | //---------------------------------------------------------------------- | ||
| 665 | // From linux-2.6.8.1/include/asm-i386/ipcbuf.h | ||
| 666 | //---------------------------------------------------------------------- | ||
| 667 | |||
| 668 | struct 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 | |||
| 687 | struct 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 | |||
| 702 | struct 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 | |||
| 723 | struct 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 | |||
| 746 | struct 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 | |||
| 762 | struct 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 | |||
| 819 | struct 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 | |||
| 849 | struct vki_revectored_struct { | ||
| 850 | unsigned long __map[8]; /* 256 bits */ | ||
| 851 | }; | ||
| 852 | |||
| 853 | struct 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 | |||
| 862 | struct 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 | |||
| 871 | struct 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 | /*--------------------------------------------------------------------*/ |
include/vki/vki-linux.h
(4 / 0)
|   | |||
| 87 | 87 | # include "vki-posixtypes-ppc32-linux.h" | |
| 88 | 88 | #elif defined(VGA_ppc64) | |
| 89 | 89 | # include "vki-posixtypes-ppc64-linux.h" | |
| 90 | #elif defined(VGA_arm) | ||
| 91 | # include "vki-posixtypes-arm-linux.h" | ||
| 90 | 92 | #else | |
| 91 | 93 | # error Unknown platform | |
| 92 | 94 | #endif | |
| … | … | ||
| 171 | 171 | # include "vki-ppc32-linux.h" | |
| 172 | 172 | #elif defined(VGA_ppc64) | |
| 173 | 173 | # include "vki-ppc64-linux.h" | |
| 174 | #elif defined(VGA_arm) | ||
| 175 | # include "vki-arm-linux.h" | ||
| 174 | 176 | #else | |
| 175 | 177 | # error Unknown platform | |
| 176 | 178 | #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 | |||
| 39 | typedef unsigned short __vki_kernel_mode_t; | ||
| 40 | typedef long __vki_kernel_off_t; | ||
| 41 | typedef int __vki_kernel_pid_t; | ||
| 42 | typedef unsigned short __vki_kernel_ipc_pid_t; | ||
| 43 | typedef unsigned short __vki_kernel_uid_t; | ||
| 44 | typedef unsigned short __vki_kernel_gid_t; | ||
| 45 | typedef unsigned int __vki_kernel_size_t; | ||
| 46 | typedef long __vki_kernel_time_t; | ||
| 47 | typedef long __vki_kernel_suseconds_t; | ||
| 48 | typedef long __vki_kernel_clock_t; | ||
| 49 | typedef int __vki_kernel_timer_t; | ||
| 50 | typedef int __vki_kernel_clockid_t; | ||
| 51 | typedef char * __vki_kernel_caddr_t; | ||
| 52 | typedef unsigned int __vki_kernel_uid32_t; | ||
| 53 | typedef unsigned int __vki_kernel_gid32_t; | ||
| 54 | |||
| 55 | typedef unsigned short __vki_kernel_old_uid_t; | ||
| 56 | typedef unsigned short __vki_kernel_old_gid_t; | ||
| 57 | |||
| 58 | typedef long long __vki_kernel_loff_t; | ||
| 59 | |||
| 60 | typedef 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 | /*--------------------------------------------------------------------*/ |
include/vki/vki-scnums-arm-linux.h
(408 / 0)
|   | |||
| 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 | /*--------------------------------------------------------------------*/ |
memcheck/mc_machine.c
(84 / 0)
|   | |||
| 65 | 65 | # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC64State) | |
| 66 | 66 | #endif | |
| 67 | 67 | ||
| 68 | #if defined(VGA_arm) | ||
| 69 | # include "libvex_guest_arm.h" | ||
| 70 | # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestARMState) | ||
| 71 | #endif | ||
| 72 | |||
| 68 | 73 | static inline Bool host_is_big_endian ( void ) { | |
| 69 | 74 | UInt x = 0x11223344; | |
| 70 | 75 | return 0x1122 == *(UShort*)(&x); | |
| … | … | ||
| 679 | 679 | # undef GOF | |
| 680 | 680 | # undef SZB | |
| 681 | 681 | ||
| 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 | |||
| 682 | 753 | # else | |
| 683 | 754 | # error "FIXME: not implemented for this architecture" | |
| 684 | 755 | # endif | |
| … | … | ||
| 827 | 827 | return Ity_I64; | |
| 828 | 828 | ||
| 829 | 829 | 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: "); | ||
| 830 | 838 | ppIRRegArray(arr); | |
| 831 | 839 | VG_(printf)("\n"); | |
| 832 | 840 | tl_assert(0); |
memcheck/mc_translate.c
(24 / 1)
|   | |||
| 1392 | 1392 | /* I32 x I64 x I64 -> I32 */ | |
| 1393 | 1393 | if (t1 == Ity_I32 && t2 == Ity_I64 && t3 == Ity_I64 | |
| 1394 | 1394 | && 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"); | ||
| 1396 | 1396 | at = mkPCastTo(mce, Ity_I64, va1); | |
| 1397 | 1397 | at = mkUifU(mce, Ity_I64, at, va2); | |
| 1398 | 1398 | at = mkUifU(mce, Ity_I64, at, va3); | |
| … | … | ||
| 1400 | 1400 | return at; | |
| 1401 | 1401 | } | |
| 1402 | 1402 | ||
| 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 | |||
| 1403 | 1415 | if (1) { | |
| 1404 | 1416 | VG_(printf)("mkLazy3: "); | |
| 1405 | 1417 | ppIRType(t1); | |
| … | … | ||
| 2071 | 2071 | case Iop_PRem1C3210F64: | |
| 2072 | 2072 | /* I32(rm) x F64 x F64 -> I32 */ | |
| 2073 | 2073 | 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); | ||
| 2074 | 2080 | default: | |
| 2075 | 2081 | ppIROp(op); | |
| 2076 | 2082 | VG_(tool_panic)("memcheck:expr2vbits_Triop"); | |
| … | … | ||
| 2426 | 2426 | /* I32(rm) x I64/F64 -> I64/F64 */ | |
| 2427 | 2427 | return mkLazy2(mce, Ity_I64, vatom1, vatom2); | |
| 2428 | 2428 | ||
| 2429 | case Iop_F64toI32U: | ||
| 2429 | 2430 | case Iop_F64toI32S: | |
| 2430 | 2431 | case Iop_F64toF32: | |
| 2431 | 2432 | /* First arg is I32 (rounding mode), second is F64 (data). */ | |
| … | … | ||
| 2686 | 2686 | ||
| 2687 | 2687 | case Iop_F32toF64: | |
| 2688 | 2688 | case Iop_I32StoF64: | |
| 2689 | case Iop_I32UtoF64: | ||
| 2689 | 2690 | case Iop_NegF64: | |
| 2690 | 2691 | case Iop_AbsF64: | |
| 2691 | 2692 | case Iop_Est5FRSqrt: | |
| … | … | ||
| 2701 | 2701 | case Iop_Clz32: | |
| 2702 | 2702 | case Iop_Ctz32: | |
| 2703 | 2703 | case Iop_TruncF64asF32: | |
| 2704 | case Iop_NegF32: | ||
| 2705 | case Iop_AbsF32: | ||
| 2704 | 2706 | return mkPCastTo(mce, Ity_I32, vatom); | |
| 2705 | 2707 | ||
| 2706 | 2708 | case Iop_1Uto64: | |
| … | … | ||
| 2752 | 2752 | case Iop_ReinterpF64asI64: | |
| 2753 | 2753 | case Iop_ReinterpI64asF64: | |
| 2754 | 2754 | case Iop_ReinterpI32asF32: | |
| 2755 | case Iop_ReinterpF32asI32: | ||
| 2755 | 2756 | case Iop_NotV128: | |
| 2756 | 2757 | case Iop_Not64: | |
| 2757 | 2758 | case Iop_Not32: |
memcheck/tests/atomic_incs.c
(8 / 2)
|   | |||
| 42 | 42 | ); | |
| 43 | 43 | #elif defined(VGA_ppc32) | |
| 44 | 44 | /* 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. */ | ||
| 46 | 46 | unsigned long success; | |
| 47 | 47 | do { | |
| 48 | 48 | __asm__ __volatile__( | |
| … | … | ||
| 74 | 74 | : /*trash*/ "memory", "cc", "r15" | |
| 75 | 75 | ); | |
| 76 | 76 | } while (success != 1); | |
| 77 | #elif defined(VGA_arm) | ||
| 78 | *p += n; | ||
| 77 | 79 | #else | |
| 78 | 80 | # error "Unsupported arch" | |
| 79 | 81 | #endif | |
| … | … | ||
| 138 | 138 | : /*trash*/ "memory", "cc", "r15" | |
| 139 | 139 | ); | |
| 140 | 140 | } while (success != 1); | |
| 141 | #elif defined(VGA_arm) | ||
| 142 | *p += n; | ||
| 141 | 143 | #else | |
| 142 | 144 | # error "Unsupported arch" | |
| 143 | 145 | #endif | |
| … | … | ||
| 199 | 199 | : /*trash*/ "memory", "cc", "r15" | |
| 200 | 200 | ); | |
| 201 | 201 | } while (success != 1); | |
| 202 | #elif defined(VGA_arm) | ||
| 203 | *p += n; | ||
| 202 | 204 | #else | |
| 203 | 205 | # error "Unsupported arch" | |
| 204 | 206 | #endif | |
| … | … | ||
| 208 | 208 | ||
| 209 | 209 | __attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n ) | |
| 210 | 210 | { | |
| 211 | #if defined(VGA_x86) || defined(VGA_ppc32) | ||
| 211 | #if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_arm) | ||
| 212 | 212 | /* do nothing; is not supported */ | |
| 213 | 213 | #elif defined(VGA_amd64) | |
| 214 | 214 | // this is a bit subtle. It relies on the fact that, on a 64-bit platform, |
none/tests/arm/Makefile.am
(16 / 0)
|   | |||
| 1 | |||
| 2 | ### jrs: re-check this against known-good equivalents, eg x86 version | ||
| 3 | |||
| 4 | EXTRA_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 | |||
| 10 | check_PROGRAMS = instructions | ||
| 11 | |||
| 12 | AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow \ | ||
| 13 | @FLAG_M32@ -g -I$(top_srcdir)/include \ | ||
| 14 | $(FLAG_MMMX) $(FLAG_MSSE) | ||
| 15 | AM_CXXFLAGS = $(AM_CFLAGS) | ||
| 16 | AM_CCASFLAGS = @FLAG_M32@ |
tests/arch_test.c
(3 / 0)
|   | |||
| 55 | 55 | if ( 0 == strcmp( arch, "ppc32" ) ) return True; | |
| 56 | 56 | } | |
| 57 | 57 | ||
| 58 | #elif defined(VGP_arm_linux) | ||
| 59 | if ( 0 == strcmp( arch, "arm" ) ) return True; | ||
| 60 | |||
| 58 | 61 | #else | |
| 59 | 62 | # error Unknown platform | |
| 60 | 63 | #endif // VGP_* |

