Add framework for ppc64 support. Apologies in advance for the
inevitable breakage to other platforms.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5250 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/Makefile.am b/Makefile.am
index 6a0e9cd..d39d0ea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,6 +47,10 @@
BUILT_SOURCES += valt_load_address_ppc32_linux.lds
CLEANFILES += valt_load_address_ppc32_linux.lds
endif
+if VG_PPC64_LINUX
+BUILT_SOURCES += valt_load_address_ppc64_linux.lds
+CLEANFILES += valt_load_address_ppc64_linux.lds
+endif
default.supp: $(SUPP_FILES)
@@ -82,6 +86,7 @@
@VEX_DIR@/pub/libvex_guest_amd64.h \
@VEX_DIR@/pub/libvex_ir.h \
@VEX_DIR@/pub/libvex_guest_ppc32.h \
+ @VEX_DIR@/pub/libvex_guest_ppc64.h \
@VEX_DIR@/pub/libvex_basictypes.h \
@VEX_DIR@/pub/libvex_guest_offsets.h \
@VEX_DIR@/pub/libvex_emwarn.h \
@@ -101,6 +106,7 @@
VEX/pub/libvex_guest_amd64.h \
VEX/pub/libvex_ir.h \
VEX/pub/libvex_guest_ppc32.h \
+ VEX/pub/libvex_guest_ppc64.h \
VEX/pub/libvex_basictypes.h \
VEX/pub/libvex_guest_offsets.h \
VEX/pub/libvex_emwarn.h \
@@ -189,7 +195,14 @@
|| rm -f $@
valt_load_address_ppc32_linux.lds: Makefile
- $(CC) -Wl,--verbose -nostdlib 2>&1 | sed \
+ $(CC) @FLAG_M32@ -Wl,--verbose -nostdlib 2>&1 | sed \
+ -e '1,/^=====\+$$/d' \
+ -e '/^=====\+$$/d' \
+ -e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \
+ || rm -f $@
+
+valt_load_address_ppc64_linux.lds: Makefile
+ $(CC) -m64 -Wl,--verbose -nostdlib 2>&1 | sed \
-e '1,/^=====\+$$/d' \
-e '/^=====\+$$/d' \
-e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \
diff --git a/Makefile.core.am b/Makefile.core.am
index c9729fe..6cf336c 100644
--- a/Makefile.core.am
+++ b/Makefile.core.am
@@ -34,9 +34,22 @@
-DVGO_linux=1 \
-DVGP_ppc32_linux=1
+add_includes_ppc64_linux = -I$(top_srcdir)/coregrind \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/coregrind/ppc64 \
+ -I$(top_srcdir)/coregrind/linux \
+ -I$(top_srcdir)/coregrind/ppc64-linux \
+ -I$(top_srcdir)/include \
+ -I@VEX_DIR@/pub \
+ -DVG_PLATFORM="\"ppc64-linux\"" \
+ -DVGA_ppc64=1 \
+ -DVGO_linux=1 \
+ -DVGP_ppc64_linux=1
+
include $(top_srcdir)/Makefile.flags.am
PRELOAD_LDFLAGS_COMMON = -nostdlib -shared -Wl,-z,interpose,-z,initfirst
PRELOAD_LDFLAGS_X86_LINUX = $(PRELOAD_LDFLAGS_COMMON) @FLAG_M32@
PRELOAD_LDFLAGS_AMD64_LINUX = $(PRELOAD_LDFLAGS_COMMON) -m64
-PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON)
+PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON) @FLAG_M32@
+PRELOAD_LDFLAGS_PPC64_LINUX = $(PRELOAD_LDFLAGS_COMMON) -m64
diff --git a/Makefile.flags.am b/Makefile.flags.am
index 3f12c7e..1d4555e 100644
--- a/Makefile.flags.am
+++ b/Makefile.flags.am
@@ -12,8 +12,12 @@
AM_CCASFLAGS_AMD64_LINUX = $(add_includes_amd64_linux) -m64 -g
AM_CPPFLAGS_PPC32_LINUX = $(add_includes_ppc32_linux)
-AM_CFLAGS_PPC32_LINUX = $(WERROR) $(AM_CFLAGS_BASE)
-AM_CCASFLAGS_PPC32_LINUX = $(add_includes_ppc32_linux) -Wa,-maltivec -g
+AM_CFLAGS_PPC32_LINUX = $(WERROR) @FLAG_M32@ $(AM_CFLAGS_BASE)
+AM_CCASFLAGS_PPC32_LINUX = $(add_includes_ppc32_linux) -Wa,-maltivec @FLAG_M32@ -g
+
+AM_CPPFLAGS_PPC64_LINUX = $(add_includes_ppc64_linux)
+AM_CFLAGS_PPC64_LINUX = $(WERROR) -m64 $(AM_CFLAGS_BASE)
+AM_CCASFLAGS_PPC64_LINUX = $(add_includes_ppc64_linux) -Wa,-maltivec -m64 -g
AM_CPPFLAGS = $(AM_CPPFLAGS_@VG_MAKE_PLATFORM@)
AM_CFLAGS = $(AM_CFLAGS_@VG_MAKE_PLATFORM@)
diff --git a/Makefile.tool-flags.am b/Makefile.tool-flags.am
index 25100b9..26d08e6 100644
--- a/Makefile.tool-flags.am
+++ b/Makefile.tool-flags.am
@@ -16,4 +16,10 @@
-DVGO_linux=1 \
-DVGP_ppc32_linux=1
+add_includes_ppc64_linux = -I$(top_srcdir)/include \
+ -I@VEX_DIR@/pub \
+ -DVGA_ppc64=1 \
+ -DVGO_linux=1 \
+ -DVGP_ppc64_linux=1
+
include $(top_srcdir)/Makefile.flags.am
diff --git a/Makefile.tool.am b/Makefile.tool.am
index bab28fa..e985aec 100644
--- a/Makefile.tool.am
+++ b/Makefile.tool.am
@@ -15,6 +15,9 @@
LIBREPLACEMALLOC_PPC32_LINUX = \
$(top_builddir)/coregrind/libreplacemalloc_toolpreload_ppc32_linux.a
+LIBREPLACEMALLOC_PPC64_LINUX = \
+ $(top_builddir)/coregrind/libreplacemalloc_toolpreload_ppc64_linux.a
+
COREGRIND_LIBS_X86_LINUX = \
$(top_builddir)/coregrind/libcoregrind_x86_linux.a \
@VEX_DIR@/libvex_x86_linux.a
@@ -27,6 +30,10 @@
$(top_builddir)/coregrind/libcoregrind_ppc32_linux.a \
@VEX_DIR@/libvex_ppc32_linux.a
+COREGRIND_LIBS_PPC64_LINUX = \
+ $(top_builddir)/coregrind/libcoregrind_ppc64_linux.a \
+ @VEX_DIR@/libvex_ppc64_linux.a
+
##.PHONY: @VEX_DIR@/libvex.a
@VEX_DIR@/libvex_x86_linux.a: @VEX_DIR@/priv/main/vex_svnversion.h
@@ -38,6 +45,9 @@
@VEX_DIR@/libvex_ppc32_linux.a: @VEX_DIR@/priv/main/vex_svnversion.h
$(MAKE) -C @VEX_DIR@ CC="$(CC)" libvex_ppc32_linux.a EXTRA_CFLAGS="$(AM_CFLAGS_PPC32_LINUX)"
+@VEX_DIR@/libvex_ppc64_linux.a: @VEX_DIR@/priv/main/vex_svnversion.h
+ $(MAKE) -C @VEX_DIR@ CC="$(CC)" libvex_ppc64_linux.a EXTRA_CFLAGS="$(AM_CFLAGS_PPC64_LINUX)"
+
@VEX_DIR@/priv/main/vex_svnversion.h:
$(MAKE) -C @VEX_DIR@ CC="$(CC)" version
@@ -58,13 +68,19 @@
TOOL_LDADD_PPC32_LINUX = $(COREGRIND_LIBS_PPC32_LINUX) $(TOOL_LDADD_COMMON)
TOOL_LDFLAGS_PPC32_LINUX = \
- $(TOOL_LDFLAGS_COMMON) \
+ $(TOOL_LDFLAGS_COMMON) @FLAG_M32@ \
-Wl,-T,$(top_builddir)/valt_load_address_ppc32_linux.lds
+TOOL_LDADD_PPC64_LINUX = $(COREGRIND_LIBS_PPC64_LINUX) $(TOOL_LDADD_COMMON)
+TOOL_LDFLAGS_PPC64_LINUX = \
+ $(TOOL_LDFLAGS_COMMON) -m64 \
+ -Wl,-T,$(top_builddir)/valt_load_address_ppc64_linux.lds
+
PRELOAD_LDFLAGS_COMMON = -nostdlib -shared -Wl,-z,interpose,-z,initfirst
PRELOAD_LDFLAGS_X86_LINUX = $(PRELOAD_LDFLAGS_COMMON) @FLAG_M32@
PRELOAD_LDFLAGS_AMD64_LINUX = $(PRELOAD_LDFLAGS_COMMON) -m64
-PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON)
+PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON) @FLAG_M32@
+PRELOAD_LDFLAGS_PPC64_LINUX = $(PRELOAD_LDFLAGS_COMMON) -m64
LIBREPLACEMALLOC_LDFLAGS_X86_LINUX = \
-Wl,--whole-archive \
@@ -78,3 +94,7 @@
-Wl,--whole-archive \
$(LIBREPLACEMALLOC_PPC32_LINUX) \
-Wl,--no-whole-archive
+LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX = \
+ -Wl,--whole-archive \
+ $(LIBREPLACEMALLOC_PPC64_LINUX) \
+ -Wl,--no-whole-archive
diff --git a/cachegrind/Makefile.am b/cachegrind/Makefile.am
index 863c12b..51bd5bd 100644
--- a/cachegrind/Makefile.am
+++ b/cachegrind/Makefile.am
@@ -14,11 +14,15 @@
if VG_PPC32_LINUX
noinst_PROGRAMS += cachegrind-ppc32-linux
endif
+if VG_PPC64_LINUX
+noinst_PROGRAMS += cachegrind-ppc64-linux
+endif
CACHEGRIND_SOURCES_COMMON = cg_main.c
CACHEGRIND_SOURCES_X86 = cg-x86.c
CACHEGRIND_SOURCES_AMD64 = cg-amd64.c
CACHEGRIND_SOURCES_PPC32 = cg-ppc32.c
+CACHEGRIND_SOURCES_PPC64 = cg-ppc64.c
cachegrind_x86_linux_SOURCES = $(CACHEGRIND_SOURCES_COMMON) $(CACHEGRIND_SOURCES_X86)
cachegrind_x86_linux_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
@@ -40,3 +44,10 @@
cachegrind_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
cachegrind_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX)
cachegrind_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX)
+
+cachegrind_ppc64_linux_SOURCES = $(CACHEGRIND_SOURCES_COMMON) $(CACHEGRIND_SOURCES_PPC64)
+cachegrind_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+cachegrind_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX)
+cachegrind_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX)
+cachegrind_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX)
+cachegrind_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX)
diff --git a/cachegrind/cg-ppc64.c b/cachegrind/cg-ppc64.c
new file mode 100644
index 0000000..18a0e07
--- /dev/null
+++ b/cachegrind/cg-ppc64.c
@@ -0,0 +1,61 @@
+
+/*--------------------------------------------------------------------*/
+/*--- PPC64-specific definitions. ppc64/cg-ppc64.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Cachegrind, a Valgrind tool for cache
+ profiling programs.
+
+ Copyright (C) 2005 Nicholas Nethercote
+ njn@valgrind.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_tool_basics.h"
+#include "pub_tool_libcbase.h"
+#include "pub_tool_libcassert.h"
+#include "pub_tool_libcprint.h"
+
+#include "cg_arch.h"
+
+void VG_(configure_caches)(cache_t* I1c, cache_t* D1c, cache_t* L2c,
+ Bool all_caches_clo_defined)
+{
+ // Set caches to default.
+ *I1c = (cache_t) { 65536, 2, 64 };
+ *D1c = (cache_t) { 65536, 2, 64 };
+ *L2c = (cache_t) { 262144, 8, 64 };
+
+ // Warn if config not completely specified from cmd line. Note that
+ // this message is slightly different from the one we give on x86/AMD64
+ // when auto-detection fails; this lets us filter out this one (which is
+ // not important) in the regression test suite without filtering the
+ // x86/AMD64 one (which we want to see if it ever occurs in the
+ // regression test suite).
+ if (!all_caches_clo_defined) {
+ VG_(message)(Vg_DebugMsg,
+ "Warning: Cannot auto-detect cache config on PPC64, using one "
+ "or more defaults ");
+ }
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
diff --git a/cachegrind/tests/Makefile.am b/cachegrind/tests/Makefile.am
index 9ebfe90..aee2531 100644
--- a/cachegrind/tests/Makefile.am
+++ b/cachegrind/tests/Makefile.am
@@ -8,6 +8,9 @@
if VG_PPC32_LINUX
SUBDIRS += ppc32
endif
+if VG_PPC64_LINUX
+SUBDIRS += ppc64
+endif
DIST_SUBDIRS = ${VG_ARCH_ALL} .
diff --git a/configure.in b/configure.in
index 099b990..5681fd7 100644
--- a/configure.in
+++ b/configure.in
@@ -110,7 +110,7 @@
AC_MSG_CHECKING([for a supported CPU])
AC_SUBST(VG_ARCH)
AC_SUBST(VG_ARCH_ALL)
-VG_ARCH_ALL="amd64 ppc32 x86"
+VG_ARCH_ALL="amd64 ppc32 ppc64 x86"
AC_SUBST(VALT_LOAD_ADDRESS)
case "${host_cpu}" in
@@ -131,7 +131,14 @@
valt_load_address_inner="0x60000000"
;;
- powerpc*)
+ powerpc64)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ VG_ARCH="ppc64"
+ valt_load_address_normal="0x70000000"
+ valt_load_address_inner="0x60000000"
+ ;;
+
+ powerpc)
AC_MSG_RESULT([ok (${host_cpu})])
VG_ARCH="ppc32"
valt_load_address_normal="0x70000000"
@@ -205,12 +212,12 @@
AC_MSG_CHECKING([for a supported CPU/OS combination])
AC_SUBST(VG_PLATFORM)
AC_SUBST(VG_PLATFORM_ALL)
-VG_PLATFORM_ALL="amd64-linux ppc32-linux x86-linux"
+VG_PLATFORM_ALL="amd64-linux ppc32-linux ppc64-linux x86-linux"
VG_PLATFORM="$VG_ARCH-$VG_OS"
case $VG_PLATFORM in
- x86-linux|amd64-linux|ppc32-linux)
+ x86-linux|amd64-linux|ppc32-linux|ppc64-linux)
AC_MSG_RESULT([ok (${host_cpu}-${host_os})])
;;
@@ -220,12 +227,27 @@
;;
esac
-AM_CONDITIONAL(VG_X86_LINUX, test x$VG_PLATFORM = xx86-linux -o x$VG_PLATFORM = xamd64-linux)
+AM_CONDITIONAL(VG_X86_LINUX, test x$VG_PLATFORM = xx86-linux -o x$VG_PLATFORM = xamd64-linux)
AM_CONDITIONAL(VG_AMD64_LINUX, test x$VG_PLATFORM = xamd64-linux)
-AM_CONDITIONAL(VG_PPC32_LINUX, test x$VG_PLATFORM = xppc32-linux)
+AM_CONDITIONAL(VG_PPC32_LINUX, test x$VG_PLATFORM = xppc32-linux -o x$VG_PLATFORM = xppc64-linux)
+AM_CONDITIONAL(VG_PPC64_LINUX, test x$VG_PLATFORM = xppc64-linux)
AC_SUBST(VG_MAKE_PLATFORM)
-VG_MAKE_PLATFORM=`echo $VG_PLATFORM | tr [a-z-] [A-Z_]`
+case $VG_PLATFORM in
+ x86-linux)
+ VG_MAKE_PLATFORM=X86_LINUX
+ ;;
+ amd64-linux)
+ VG_MAKE_PLATFORM=AMD64_LINUX
+ ;;
+ ppc32-linux|ppc64-linux)
+ VG_MAKE_PLATFORM=PPC32_LINUX
+ ;;
+ *)
+ AC_MSG_ERROR([VG_PLATFORM is not known -- configure script bug])
+ ;;
+esac
+##VG_MAKE_PLATFORM=`echo $VG_PLATFORM | tr [a-z-] [A-Z_]`
AC_SUBST(DEFAULT_SUPP)
@@ -484,12 +506,14 @@
memcheck/tests/Makefile
memcheck/tests/amd64/Makefile
memcheck/tests/ppc32/Makefile
+ memcheck/tests/ppc64/Makefile
memcheck/tests/x86/Makefile
memcheck/docs/Makefile
cachegrind/Makefile
cachegrind/tests/Makefile
cachegrind/tests/amd64/Makefile
cachegrind/tests/ppc32/Makefile
+ cachegrind/tests/ppc64/Makefile
cachegrind/tests/x86/Makefile
cachegrind/docs/Makefile
cachegrind/cg_annotate
@@ -507,6 +531,7 @@
none/tests/Makefile
none/tests/amd64/Makefile
none/tests/ppc32/Makefile
+ none/tests/ppc64/Makefile
none/tests/x86/Makefile
none/docs/Makefile
)
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 45972c9..b61ab26 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -11,6 +11,7 @@
AM_CPPFLAGS_X86_LINUX += -DVG_LIBDIR="\"$(valdir)"\"
AM_CPPFLAGS_AMD64_LINUX += -DVG_LIBDIR="\"$(valdir)"\"
AM_CPPFLAGS_PPC32_LINUX += -DVG_LIBDIR="\"$(valdir)"\"
+AM_CPPFLAGS_PPC64_LINUX += -DVG_LIBDIR="\"$(valdir)"\"
default.supp: $(SUPP_FILES)
@@ -25,6 +26,9 @@
if VG_PPC32_LINUX
noinst_LIBRARIES += libcoregrind_ppc32_linux.a libreplacemalloc_toolpreload_ppc32_linux.a
endif
+if VG_PPC64_LINUX
+noinst_LIBRARIES += libcoregrind_ppc64_linux.a libreplacemalloc_toolpreload_ppc64_linux.a
+endif
bin_PROGRAMS = \
valgrind
@@ -39,6 +43,9 @@
if VG_PPC32_LINUX
noinst_PROGRAMS += vgpreload_core-ppc32-linux.so
endif
+if VG_PPC64_LINUX
+noinst_PROGRAMS += vgpreload_core-ppc64-linux.so
+endif
noinst_HEADERS = \
coregrind.h \
@@ -207,6 +214,19 @@
libcoregrind_ppc32_linux_a_CFLAGS = $(AM_CFLAGS_PPC32_LINUX)
libcoregrind_ppc32_linux_a_CCASFLAGS = $(AM_CCASFLAGS_PPC32_LINUX)
+libcoregrind_ppc64_linux_a_SOURCES = \
+ $(COREGRIND_SOURCES_COMMON) \
+ $(COREGRIND_LINUX_SOURCE) \
+ m_coredump/coredump-ppc64-linux.c \
+ m_dispatch/dispatch-ppc64-linux.S \
+ m_sigframe/sigframe-ppc64-linux.c \
+ m_syswrap/syscall-ppc64-linux.S \
+ m_syswrap/syswrap-ppc64-linux.c
+
+libcoregrind_ppc64_linux_a_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+libcoregrind_ppc64_linux_a_CFLAGS = $(AM_CFLAGS_PPC64_LINUX)
+libcoregrind_ppc64_linux_a_CCASFLAGS = $(AM_CCASFLAGS_PPC64_LINUX)
+
libreplacemalloc_toolpreload_x86_linux_a_SOURCES = m_replacemalloc/vg_replace_malloc.c
libreplacemalloc_toolpreload_x86_linux_a_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
libreplacemalloc_toolpreload_x86_linux_a_CFLAGS = $(AM_CFLAGS_X86_LINUX) -fpic -fno-omit-frame-pointer
@@ -219,12 +239,18 @@
libreplacemalloc_toolpreload_ppc32_linux_a_CPPFLAGS = $(AM_CPPFLAGS_PPC32_LINUX)
libreplacemalloc_toolpreload_ppc32_linux_a_CFLAGS = $(AM_CFLAGS_PPC32_LINUX) -fpic -fno-omit-frame-pointer
+libreplacemalloc_toolpreload_ppc64_linux_a_SOURCES = m_replacemalloc/vg_replace_malloc.c
+libreplacemalloc_toolpreload_ppc64_linux_a_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+libreplacemalloc_toolpreload_ppc64_linux_a_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) -fpic -fno-omit-frame-pointer
+
m_dispatch/dispatch-x86-linux.S: libvex_guest_offsets.h
m_dispatch/dispatch-amd64-linux.S: libvex_guest_offsets.h
m_dispatch/dispatch-ppc32-linux.S: libvex_guest_offsets.h
+m_dispatch/dispatch-ppc64-linux.S: libvex_guest_offsets.h
m_syswrap/syscall-x86-linux.S: libvex_guest_offsets.h
m_syswrap/syscall-amd64-linux.S: libvex_guest_offsets.h
m_syswrap/syscall-ppc32-linux.S: libvex_guest_offsets.h
+m_syswrap/syscall-ppc64-linux.S: libvex_guest_offsets.h
m_syswrap/syswrap-main.c: libvex_guest_offsets.h
libvex_guest_offsets.h:
@@ -247,6 +273,11 @@
vgpreload_core_ppc32_linux_so_CFLAGS = $(AM_CFLAGS_PPC32_LINUX) $(AM_CFLAGS_PIC)
vgpreload_core_ppc32_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_PPC32_LINUX)
+vgpreload_core_ppc64_linux_so_SOURCES = $(VGPRELOAD_CORE_SOURCES_COMMON)
+vgpreload_core_ppc64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+vgpreload_core_ppc64_linux_so_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_core_ppc64_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_PPC64_LINUX)
+
clean-local:
$(MAKE) -C @VEX_DIR@ CC="$(CC)" clean
diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c
index 693a784..d64b062 100644
--- a/coregrind/m_aspacemgr/aspacemgr.c
+++ b/coregrind/m_aspacemgr/aspacemgr.c
@@ -445,7 +445,7 @@
# if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
res = VG_(do_syscall6)(__NR_mmap2, (UWord)start, length,
prot, flags, fd, offset / VKI_PAGE_SIZE);
-# elif defined(VGP_amd64_linux)
+# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length,
prot, flags, fd, offset);
# else
diff --git a/coregrind/m_coredump/coredump-ppc64-linux.c b/coregrind/m_coredump/coredump-ppc64-linux.c
new file mode 100644
index 0000000..71cddca
--- /dev/null
+++ b/coregrind/m_coredump/coredump-ppc64-linux.c
@@ -0,0 +1,76 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Dumping core. coredump-ppc32-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward
+ jseward@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_coredump.h"
+#include "pub_core_threadstate.h"
+
+#include "priv_elf.h"
+
+void ML_(fill_elfregs_from_tst)(struct vki_user_regs_struct* regs,
+ const ThreadArchState* arch)
+{
+# define DO(n) regs->gpr[n] = arch->vex.guest_GPR##n
+ DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+ DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+ DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+ DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+# undef DO
+
+ regs->nip = arch->vex.guest_CIA;
+ regs->msr = 0xf032; /* pretty arbitrary */
+ regs->orig_gpr3 = arch->vex.guest_GPR3;
+ regs->ctr = arch->vex.guest_CTR;
+ regs->link = arch->vex.guest_LR;
+ regs->xer = LibVEX_GuestPPC64_get_XER( &((ThreadArchState*)arch)->vex );
+ regs->ccr = LibVEX_GuestPPC64_get_CR( &((ThreadArchState*)arch)->vex );
+ /* regs->mq = 0; */
+ regs->trap = 0;
+ regs->dar = 0; /* should be fault address? */
+ regs->dsisr = 0;
+ regs->result = 0;
+}
+
+void ML_(fill_elffpregs_from_tst)(vki_elf_fpregset_t* fpu,
+ const ThreadArchState* arch)
+{
+ /* The guest state has the FPR fields declared as ULongs, so need
+ to fish out the values without converting them. */
+# define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_FPR##n)
+ DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+ DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+ DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+ DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+# undef DO
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_coredump/priv_elf.h b/coregrind/m_coredump/priv_elf.h
index a1340a4..692cef6 100644
--- a/coregrind/m_coredump/priv_elf.h
+++ b/coregrind/m_coredump/priv_elf.h
@@ -28,8 +28,8 @@
The GNU General Public License is contained in the file COPYING.
*/
-#ifndef __PRIV_SYMTAB_H
-#define __PRIV_SYMTAB_H
+#ifndef __PRIV_ELF_H
+#define __PRIV_ELF_H
void ML_(fill_elfregs_from_tst)(struct vki_user_regs_struct* regs,
const ThreadArchState* arch);
@@ -42,7 +42,7 @@
const ThreadArchState* arch);
#endif
-#endif // __PRIV_SYMTAB_H
+#endif // __PRIV_ELF_H
/*--------------------------------------------------------------------*/
/*--- end ---*/
diff --git a/coregrind/m_debugger.c b/coregrind/m_debugger.c
index 8c0bc27..9a5cc0d 100644
--- a/coregrind/m_debugger.c
+++ b/coregrind/m_debugger.c
@@ -36,6 +36,7 @@
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h"
#include "pub_core_libcsignal.h"
+#include "pub_core_libcassert.h"
#include "pub_core_options.h"
@@ -130,6 +131,9 @@
(void*)LibVEX_GuestPPC32_get_XER(vex));
return rc;
+#elif defined(VGA_ppc64)
+ I_die_here;
+
#else
# error Unknown arch
#endif
diff --git a/coregrind/m_debuginfo/dwarf.c b/coregrind/m_debuginfo/dwarf.c
index 457c862..560ded2 100644
--- a/coregrind/m_debuginfo/dwarf.c
+++ b/coregrind/m_debuginfo/dwarf.c
@@ -1321,6 +1321,10 @@
# define FP_REG 1
# define SP_REG 1
# define RA_REG_DEFAULT 8 // CAB: What's a good default ?
+#elif defined(VGP_ppc64_linux)
+# define FP_REG 1
+# define SP_REG 1
+# define RA_REG_DEFAULT 8 // CAB: What's a good default ?
#else
# error Unknown platform
#endif
diff --git a/coregrind/m_debuginfo/symtab.c b/coregrind/m_debuginfo/symtab.c
index a92685f..0afe0d8 100644
--- a/coregrind/m_debuginfo/symtab.c
+++ b/coregrind/m_debuginfo/symtab.c
@@ -2267,8 +2267,8 @@
case 15: return (Addr) & arch->vex.guest_R15;
default: return 0;
}
-#elif defined(VGA_ppc32)
- /* This is the Intel register encoding -- integer regs. */
+#elif defined(VGA_ppc32) || defined(VGA_ppc64)
+ /* This is the PPC register encoding -- integer regs. */
# define R_STACK_PTR 1
# define R_FRAME_PTR 1
switch (regno) {
diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c
index 48d5caf..39473c8 100644
--- a/coregrind/m_debuglog.c
+++ b/coregrind/m_debuglog.c
@@ -54,7 +54,7 @@
/*--- Stuff to make us completely independent. ---*/
/*------------------------------------------------------------*/
-/* ----- x86-linux specifics ----- */
+/* ----- Platform-specifics ----- */
#if defined(VGP_x86_linux)
@@ -158,6 +158,39 @@
return __res;
}
+#elif defined(VGP_ppc64_linux)
+
+static UInt local_sys_write_stderr ( HChar* buf, Int n )
+{
+ UInt __res;
+ __asm__ volatile (
+ "li %%r0,4\n\t" /* set %r0 = __NR_write */
+ "li %%r3,2\n\t" /* set %r3 = stderr */
+ "mr %%r4,%1\n\t" /* set %r4 = buf */
+ "mr %%r5,%2\n\t" /* set %r5 = n */
+ "sc\n\t" /* write(stderr, buf, n) */
+ "mr %0,%%r3\n" /* set __res = r3 */
+ : "=mr" (__res)
+ : "g" (buf), "g" (n)
+ : "r0", "r3", "r4", "r5" );
+ if (__res < 0)
+ __res = -1;
+ return __res;
+}
+
+static UInt local_sys_getpid ( void )
+{
+ UInt __res;
+ __asm__ volatile (
+ "li %%r0,20\n" /* set %r0 = __NR_getpid */
+ "\tsc\n" /* getpid() */
+ "\tmr %0,%%r3\n" /* set __res = r3 */
+ : "=mr" (__res)
+ :
+ : "r0" );
+ return __res;
+}
+
#else
# error Unknown platform
#endif
diff --git a/coregrind/m_dispatch/dispatch-ppc64-linux.S b/coregrind/m_dispatch/dispatch-ppc64-linux.S
new file mode 100644
index 0000000..1eea790
--- /dev/null
+++ b/coregrind/m_dispatch/dispatch-ppc64-linux.S
@@ -0,0 +1,474 @@
+
+##--------------------------------------------------------------------##
+##--- The core dispatch loop, for jumping to a code address. ---##
+##--- dispatch-ppc64.S ---##
+##--------------------------------------------------------------------##
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2005 Cerion Armour-Brown <cerion@open-works.co.uk>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics_asm.h"
+#include "pub_core_dispatch_asm.h"
+#include "pub_core_transtab_asm.h"
+#include "libvex_guest_offsets.h" /* for OFFSET_ppc64_CIA */
+
+
+/* References to globals via the TOC */
+
+ .section ".toc","aw"
+tocent__vgPlain_tt_fast:
+ .tc vgPlain_tt_fast[TC],vgPlain_tt_fast
+
+/*------------------------------------------------------------*/
+/*--- The dispatch loop. ---*/
+/*------------------------------------------------------------*/
+
+ .section ".text"
+ .align 2
+
+/* signature: UWord VG_(run_innerloop) ( void* guest_state ) */
+
+ .globl .VG_(run_innerloop)
+.VG_(run_innerloop):
+ /* ----- entry point to VG_(run_innerloop) ----- */
+
+ /* For Linux/ppc32 we need the SysV ABI, which uses
+ LR->4(parent_sp), CR->anywhere.
+ (The AIX ABI, used on Darwin, and maybe Linux/ppc64?,
+ uses LR->8(prt_sp), CR->4(prt_sp))
+ */
+
+ /* Save lr */
+ mflr 0
+ stw 0,4(1)
+
+ /* New stack frame */
+ stwu 1,-624(1) /* sp should maintain 16-byte alignment */
+
+ /* Save callee-saved registers... */
+
+ /* Floating-point reg save area : 144 bytes */
+ stfd 31,616(1)
+ stfd 30,608(1)
+ stfd 29,600(1)
+ stfd 28,592(1)
+ stfd 27,584(1)
+ stfd 26,576(1)
+ stfd 25,568(1)
+ stfd 24,560(1)
+ stfd 23,552(1)
+ stfd 22,544(1)
+ stfd 21,536(1)
+ stfd 20,528(1)
+ stfd 19,520(1)
+ stfd 18,512(1)
+ stfd 17,504(1)
+ stfd 16,496(1)
+ stfd 15,488(1)
+ stfd 14,480(1)
+
+ /* General reg save area : 144 bytes */
+ stw 31,472(1)
+ stw 30,464(1)
+ stw 29,456(1)
+ stw 28,448(1)
+ stw 27,440(1)
+ stw 26,432(1)
+ stw 25,424(1)
+ stw 24,416(1)
+ stw 23,408(1)
+ stw 22,400(1)
+ stw 21,392(1)
+ stw 20,384(1)
+ stw 19,376(1)
+ stw 18,368(1)
+ stw 17,360(1)
+ stw 16,352(1)
+ stw 15,344(1)
+ stw 14,336(1)
+ /* Probably not necessary to save r13 (thread-specific ptr),
+ as VEX stays clear of it... but what the hey. */
+ stw 13,328(1)
+
+ /* It's necessary to save/restore VRSAVE in the AIX / Darwin ABI.
+ The Linux kernel might not actually use VRSAVE for its intended
+ purpose, but it should be harmless to preserve anyway. */
+ /* r3 is live here (guest state ptr), so use r4 */
+ lis 4,VG_(machine_ppc64_has_VMX)@ha
+ lwz 4,VG_(machine_ppc64_has_VMX)@l(4)
+ cmplwi 4,0
+ beq LafterVMX1
+
+ /* VRSAVE save word : 32 bytes */
+ mfspr 4,256 /* vrsave reg is spr number 256 */
+ stw 4,324(1)
+
+ /* Alignment padding : 4 bytes */
+
+ /* Vector reg save area (quadword aligned) : 192 bytes */
+ li 4,304
+ stvx 31,4,1
+ li 4,288
+ stvx 30,4,1
+ li 4,272
+ stvx 29,4,1
+ li 4,256
+ stvx 28,4,1
+ li 4,240
+ stvx 27,4,1
+ li 4,224
+ stvx 26,4,1
+ li 4,208
+ stvx 25,4,1
+ li 4,192
+ stvx 24,4,1
+ li 4,176
+ stvx 23,4,1
+ li 4,160
+ stvx 22,4,1
+ li 4,144
+ stvx 21,4,1
+ li 4,128
+ stvx 20,4,1
+LafterVMX1:
+
+ /* Save cr */
+ mfcr 0
+ stw 0,112(1)
+
+
+ /* Local variable space... */
+
+ /* r3 holds guest_state */
+ mr 31,3
+ stw 3,104(1) /* spill orig guest_state ptr */
+
+ /* 96(sp) used later to check FPSCR[RM] */
+
+ /* 88(sp) used later to stop ctr reg being clobbered */
+
+ /* 48:87(sp) free */
+
+ /* Linkage Area (reserved)
+ 40(sp) : TOC
+ 32(sp) : link editor doubleword
+ 24(sp) : compiler doubleword
+ 16(sp) : LR
+ 8(sp) : CR
+ 0(sp) : back-chain
+ */
+
+// CAB TODO: Use a caller-saved reg for orig guest_state ptr
+// - rem to set non-allocateable in isel.c
+
+ /* hold dispatch_ctr in ctr reg */
+ lis 17,VG_(dispatch_ctr)@ha
+ lwz 17,VG_(dispatch_ctr)@l(17)
+ mtctr 17
+
+ /* fetch %CIA into r30 */
+ lwz 30,OFFSET_ppc64_CIA(31)
+
+ /* set host FPU control word to the default mode expected
+ by VEX-generated code. See comments in libvex.h for
+ more info. */
+ fsub 3,3,3 /* generate zero */
+ mtfsf 0xFF,3
+
+ /* set host AltiVec control word to the default mode expected
+ by VEX-generated code. */
+ lis 3,VG_(machine_ppc64_has_VMX)@ha
+ lwz 3,VG_(machine_ppc64_has_VMX)@l(3)
+ cmplwi 3,0
+ beq LafterVMX2
+
+ vspltisw 3,0x0 /* generate zero */
+ mtvscr 3
+LafterVMX2:
+
+ /* make a stack frame for the code we are calling */
+ stwu 1,-48(1)
+
+ /* fall into main loop */
+
+/* Live regs:
+ r1 (=sp)
+ r2 (toc pointer)
+ r30 (=guest CIA = jump address)
+ r31 (=guest_state)
+ ctr (=dispatch_ctr)
+ Stack state:
+ 104 (r1) (=guest_state ptr)
+ 96 (r1) (=var space for FPSCR[RM])
+ 88 (r1) (=var space for CTR)
+ 44:87 (r1) (=free)
+ 0:43 (r1) (=stack frame header)
+*/
+
+dispatch_boring:
+ /* save the jump address in the guest state */
+ std 30,OFFSET_ppc64_CIA(31)
+
+ /* Are we out of timeslice? If yes, defer to scheduler. */
+ bdz counter_is_zero /* decrements ctr reg */
+
+ /* try a fast lookup in the translation cache */
+ /* r4=((r30<<3) & (VG_TT_FAST_MASK<<3)) */
+ rldic 4,30, 3,64-3-VG_TT_FAST_BITS
+// CAB: use a caller-saved reg for this ?
+ /* r5 = & VG_(tt_fast) */
+ ld 5, tocent__vgPlain_tt_fast@toc(2)
+ /* r5 = VG_(tt_fast)[r30 & VG_TT_FAST_MASK] */
+ ldx 5, 5,4
+ /* r6 = VG_(tt_fast)[r30 & VG_TT_FAST_MASK]->orig_addr */
+ ld 6, 0(5)
+ cmpw 30,6
+ bne fast_lookup_failed
+
+ /* increment bb profile counter */
+// CAB: use a caller-saved reg for this ?
+ /* r7 = & VG_(tt_fastN) */
+ ld 7, tocent__vgPlain_tt_fast@toc(2)
+ /* r7 = VG_(tt_fastN)[r30 & VG_TT_FAST_MASK] */
+ srdi 4, 4,1
+ lwzx 6, 7,4
+ addi 6, 6,1
+ stwx 6, 7,4
+
+ /* Found a match. Call tce[1], which is 8 bytes along, since
+ each tce element is a 64-bit int. */
+ addi 8,5,8
+ mtlr 8
+
+ /* stop ctr being clobbered */
+// CAB: use a caller-saved reg for this ?
+// but then (bdz) => (decr, cmp, bc)... still better than a stw?
+ mfctr 9
+ std 9,136(1) /* => 88(parent_sp) */
+
+ blrl
+
+
+ /* On return from guest code:
+ r3 holds destination (original) address.
+
+ r31 may be unchanged (guest_state), or may indicate further
+ details of the control transfer requested to *r3.
+
+ If r31 is unchanged, just jump next to r3.
+
+ Otherwise fall out, back to the scheduler, and let it
+ figure out what to do next.
+ */
+
+ /* reinstate clobbered ctr */
+ ld 9,136(1) /* => 88(parent_sp) */
+ mtctr 9
+
+ mr 30,3 /* put CIA (=r3) in r30 */
+ ld 16,152(1) /* gst_state ptr => 104(prnt_sp) */
+ cmpd 16,31
+ beq dispatch_boring /* r31 unchanged... */
+
+ mr 3,31 /* put return val (=r31) in r3 */
+ b dispatch_exceptional
+
+/* All exits from the dispatcher go through here.
+ r3 holds the return value.
+*/
+run_innerloop_exit:
+ /* We're leaving. Check that nobody messed with
+ VSCR or FPSCR. */
+
+/* This check avoidance may be removable if stfiwx is implemented. */
+#if !defined(ENABLE_INNER)
+ /* Check FPSCR & 0xFF == 0 (lowest 8bits are controls) */
+ mffs 4 /* fpscr -> fpr */
+ li 5,144 /* => 96(parent_sp) */
+ stfiwx 4,5,1 /* fpr to stack */
+ lwzx 6,5,1 /* load to gpr */
+ andi. 6,6,0xFF /* mask wanted bits */
+ cmplwi 6,0x0 /* cmp with zero */
+ bne invariant_violation /* branch if not zero */
+#endif
+
+ /* Using r11 - value used again further on, so don't trash! */
+ lis 11,VG_(machine_ppc64_has_VMX)@ha
+ lwz 11,VG_(machine_ppc64_has_VMX)@l(11)
+ cmplwi 11,0
+ beq LafterVMX8
+
+ /* Check VSCR[NJ] == 1 */
+ /* first generate 4x 0x00010000 */
+ vspltisw 4,0x1 /* 4x 0x00000001 */
+ vspltisw 5,0x0 /* zero */
+ vsldoi 6,4,5,0x2 /* <<2*8 => 4x 0x00010000 */
+ /* retrieve VSCR and mask wanted bits */
+ mfvscr 7
+ vand 7,7,6 /* gives NJ flag */
+ vspltw 7,7,0x3 /* flags-word to all lanes */
+ vcmpequw. 8,6,7 /* CR[24] = 1 if v6 == v7 */
+ bt 24,invariant_violation /* branch if all_equal */
+LafterVMX8:
+
+ /* otherwise we're OK */
+ b run_innerloop_exit_REALLY
+
+
+invariant_violation:
+ li 3,VG_TRC_INVARIANT_FAILED
+ b run_innerloop_exit_REALLY
+
+run_innerloop_exit_REALLY:
+ /* r3 holds VG_TRC_* value to return */
+
+ /* Return to parent stack */
+ addi 1,1,48
+
+ /* Write ctr to VG(dispatch_ctr) */
+ mfctr 17
+ lis 18,VG_(dispatch_ctr)@ha
+ stw 17,VG_(dispatch_ctr)@l(18)
+
+ /* Restore cr */
+ lwz 0,112(1)
+ mtcr 0
+
+ /* Restore callee-saved registers... */
+
+ /* Floating-point regs */
+ lfd 31,616(1)
+ lfd 30,608(1)
+ lfd 29,600(1)
+ lfd 28,592(1)
+ lfd 27,584(1)
+ lfd 26,576(1)
+ lfd 25,568(1)
+ lfd 24,560(1)
+ lfd 23,552(1)
+ lfd 22,544(1)
+ lfd 21,536(1)
+ lfd 20,528(1)
+ lfd 19,520(1)
+ lfd 18,512(1)
+ lfd 17,504(1)
+ lfd 16,496(1)
+ lfd 15,488(1)
+ lfd 14,480(1)
+
+ /* General regs */
+ lwz 31,472(1)
+ lwz 30,464(1)
+ lwz 29,456(1)
+ lwz 28,448(1)
+ lwz 27,440(1)
+ lwz 26,432(1)
+ lwz 25,424(1)
+ lwz 24,416(1)
+ lwz 23,408(1)
+ lwz 22,400(1)
+ lwz 21,392(1)
+ lwz 20,384(1)
+ lwz 19,376(1)
+ lwz 18,368(1)
+ lwz 17,360(1)
+ lwz 16,352(1)
+ lwz 15,344(1)
+ lwz 14,336(1)
+ lwz 13,328(1)
+
+ /* r11 already holds VG_(machine_ppc64_has_VMX) value */
+ cmplwi 11,0
+ beq LafterVMX9
+
+ /* VRSAVE */
+ lwz 4,324(1)
+ mfspr 4,256 /* VRSAVE reg is spr number 256 */
+
+ /* Vector regs */
+ li 4,304
+ lvx 31,4,1
+ li 4,288
+ lvx 30,4,1
+ li 4,272
+ lvx 29,4,1
+ li 4,256
+ lvx 28,4,1
+ li 4,240
+ lvx 27,4,1
+ li 4,224
+ lvx 26,4,1
+ li 4,208
+ lvx 25,4,1
+ li 4,192
+ lvx 24,4,1
+ li 4,176
+ lvx 23,4,1
+ li 4,160
+ lvx 22,4,1
+ li 4,144
+ lvx 21,4,1
+ li 4,128
+ lvx 20,4,1
+LafterVMX9:
+
+ /* reset lr & sp */
+ lwz 0,628(1) /* stack_size + 4 */
+ mtlr 0
+ addi 1,1,624 /* stack_size */
+ blr
+
+
+/* Other ways of getting out of the inner loop. Placed out-of-line to
+ make it look cleaner.
+*/
+dispatch_exceptional:
+ /* this is jumped to only, not fallen-through from above */
+ /* save r30 in %CIA and defer to sched */
+ lwz 16,152(1)
+ stw 30,OFFSET_ppc64_CIA(16)
+ b run_innerloop_exit
+
+fast_lookup_failed:
+ /* %CIA is up to date here since dispatch_boring dominates */
+ mfctr 17
+ addi 17,17,1
+ mtctr 17
+ li 3,VG_TRC_INNER_FASTMISS
+ b run_innerloop_exit
+
+counter_is_zero:
+ /* %CIA is up to date here since dispatch_boring dominates */
+ mfctr 17
+ addi 17,17,1
+ mtctr 17
+ li 3,VG_TRC_INNER_COUNTERZERO
+ b run_innerloop_exit
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
+##--------------------------------------------------------------------##
+##--- end ---##
+##--------------------------------------------------------------------##
diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c
index 8cd810b..773b601 100644
--- a/coregrind/m_libcassert.c
+++ b/coregrind/m_libcassert.c
@@ -75,6 +75,20 @@
"=r" (fp) \
: /* reads none */ \
: "r0" /* trashed */ );
+#elif defined(VGP_ppc64_linux)
+# define GET_REAL_PC_SP_AND_FP(pc, sp, fp) \
+ asm("mflr 0;" /* r0 = lr */ \
+ "bl m_libcassert_get_ip;" /* lr = pc */ \
+ "m_libcassert_get_ip:\n" \
+ "mflr %0;" \
+ "mtlr 0;" /* restore lr */ \
+ "mr %1,1;" \
+ "mr %2,1;" \
+ : "=r" (pc), \
+ "=r" (sp), \
+ "=r" (fp) \
+ : /* reads none */ \
+ : "r0" /* trashed */ );
#else
# error Unknown platform
#endif
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index 8a78d6d..c3ed7d3 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -478,7 +478,7 @@
static
Int my_socket ( Int domain, Int type, Int protocol )
{
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
SysRes res;
UWord args[3];
args[0] = domain;
@@ -501,7 +501,7 @@
Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr,
Int addrlen )
{
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
SysRes res;
UWord args[3];
args[0] = sockfd;
@@ -528,7 +528,7 @@
error is still returned. */
Int flags = VKI_MSG_NOSIGNAL;
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
SysRes res;
UWord args[4];
args[0] = sd;
@@ -552,7 +552,7 @@
{
SysRes res;
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
UWord args[3];
args[0] = sd;
args[1] = (UWord)name;
@@ -574,7 +574,7 @@
{
SysRes res;
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
UWord args[3];
args[0] = sd;
args[1] = (UWord)name;
@@ -597,7 +597,7 @@
{
SysRes res;
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
UWord args[5];
args[0] = sd;
args[1] = level;
diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c
index c851fc2..1db9d45 100644
--- a/coregrind/m_libcproc.c
+++ b/coregrind/m_libcproc.c
@@ -412,7 +412,7 @@
list[i] = (UInt)list16[i];
return size;
-# elif defined(VGP_amd64_linux)
+# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
SysRes sres;
sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
if (sres.isError)
diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c
index 8c3d096..403b8fd 100644
--- a/coregrind/m_machine.c
+++ b/coregrind/m_machine.c
@@ -58,7 +58,7 @@
Addr VG_(get_LR) ( ThreadId tid )
{
-# if defined(VGA_ppc32)
+# if defined(VGA_ppc32) || defined(VGA_ppc64)
return VG_(threads)[tid].arch.vex.guest_LR;
# elif defined(VGA_x86) || defined(VGA_amd64)
return 0;
@@ -137,7 +137,7 @@
(*f)(vex->guest_R13);
(*f)(vex->guest_R14);
(*f)(vex->guest_R15);
-#elif defined(VGA_ppc32)
+#elif defined(VGA_ppc32) || defined(VGA_ppc64)
/* XXX ask tool about validity? */
(*f)(vex->guest_GPR0);
(*f)(vex->guest_GPR1);
@@ -258,13 +258,16 @@
UInt VG_(machine_ppc32_has_FP) = 0;
UInt VG_(machine_ppc32_has_VMX) = 0;
#endif
+#if defined(VGA_ppc64)
+ULong VG_(machine_ppc64_has_VMX) = 0;
+#endif
/* Determine what insn set and insn set variant the host has, and
record it. To be called once at system startup. Returns False if
this a CPU incapable of running Valgrind. */
-#if defined(VGA_ppc32)
+#if defined(VGA_ppc32) || defined(VGA_ppc64)
#include <setjmp.h> // For jmp_buf
static jmp_buf env_sigill;
static void handler_sigill ( Int x ) { __builtin_longjmp(env_sigill,1); }
@@ -397,12 +400,54 @@
return True;
}
+#elif defined(VGA_ppc64)
+ { vki_sigset_t saved_set, tmp_set;
+ struct vki_sigaction saved_act, tmp_act;
+
+ volatile Bool have_vmx;
+
+ VG_(sigemptyset)(&tmp_set);
+ VG_(sigaddset)(&tmp_set, VKI_SIGILL);
+
+ VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
+
+ VG_(sigaction)(VKI_SIGILL, NULL, &saved_act);
+ tmp_act = saved_act;
+
+ tmp_act.sa_flags &= ~VKI_SA_RESETHAND;
+ tmp_act.sa_flags &= ~VKI_SA_SIGINFO;
+
+ tmp_act.ksa_handler = handler_sigill;
+ VG_(sigaction)(VKI_SIGILL, &tmp_act, NULL);
+
+ have_vmx = True;
+ if (__builtin_setjmp(env_sigill)) {
+ have_vmx = False;
+ } else {
+ __asm__ __volatile__("vor 0,0,0");
+ }
+
+ VG_(sigaction)(VKI_SIGILL, &saved_act, NULL);
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
+
+ /* VG_(printf)("VMX %d\n", (Int)have_vmx); */
+
+ VG_(machine_ppc64_has_VMX) = have_vmx ? 1 : 0;
+
+ va = VexArchPPC64;
+ vai.subarch = have_vmx ? VexSubArchPPC64_VFI : VexSubArchPPC64_FI;
+
+ /* But we're not done yet: VG_(machine_ppc64_set_clszB) must be
+ called before we're ready to go. */
+ return True;
+ }
+
#else
# error "Unknown arch"
#endif
}
-/* Notify host cpu cache line size, as per above comment. */
+/* Notify host cpu cache line size. */
#if defined(VGA_ppc32)
void VG_(machine_ppc32_set_clszB)( Int szB )
{
@@ -420,6 +465,24 @@
#endif
+/* Notify host cpu cache line size. */
+#if defined(VGA_ppc64)
+void VG_(machine_ppc64_set_clszB)( Int szB )
+{
+ vg_assert(hwcaps_done);
+
+ /* Either the value must not have been set yet (zero) or we can
+ tolerate it being set to the same value multiple times, as the
+ stack scanning logic in m_main is a bit stupid. */
+ vg_assert(vai.ppc32_cache_line_szB == 0
+ || vai.ppc32_cache_line_szB == szB);
+
+ vg_assert(szB == 32 || szB == 128);
+ vai.ppc32_cache_line_szB = szB;
+}
+#endif
+
+
/* Fetch host cpu info, once established. */
void VG_(machine_get_VexArchInfo)( /*OUT*/VexArch* pVa,
/*OUT*/VexArchInfo* pVai )
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 8f4b4b7..c4da14f 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -1741,6 +1741,20 @@
arch->vex.guest_GPR1 = client_sp;
arch->vex.guest_CIA = client_ip;
+#elif defined(VGA_ppc64)
+ vg_assert(0 == sizeof(VexGuestPPC64State) % 8);
+
+ /* Zero out the initial state, and set up the simulated FPU in a
+ sane way. */
+ LibVEX_GuestPPC64_initialise(&arch->vex);
+
+ /* Zero out the shadow area. */
+ VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC64State));
+
+ /* Put essential stuff into the new state. */
+ arch->vex.guest_GPR1 = client_sp;
+ arch->vex.guest_CIA = client_ip;
+
#else
# error Unknown arch
#endif
@@ -2320,7 +2334,7 @@
# if defined(VGP_x86_linux)
iters = 5;
-# elif defined(VGP_amd64_linux)
+# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux)
iters = 10;
# elif defined(VGP_ppc32_linux)
iters = 5;
@@ -2847,6 +2861,37 @@
"\ttrap\n"
".previous\n"
);
+#elif defined(VGP_ppc64_linux)
+asm("\n"
+ ".text\n"
+ "\t.globl _start\n"
+ "\t.type _start,@function\n"
+ "_start:\n"
+ /* set up the new stack in r16 */
+ "\tlis 16, vgPlain_interim_stack@highest\n"
+ "\tori 16,16,vgPlain_interim_stack@higher\n"
+ "\tsldi 16,16,32\n"
+ "\toris 16,16,vgPlain_interim_stack@h\n"
+ "\tori 16,16,vgPlain_interim_stack@l\n"
+ "\txor 17,17,17\n"
+ "\tlis 17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
+ "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
+ "\txor 18,18,18\n"
+ "\tlis 18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" >> 16)\n"
+ "\tori 18,18,("VG_STRINGIFY(VG_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
+ "\tadd 16,17,16\n"
+ "\tadd 16,18,16\n"
+ "\trldicr 16,16,0,59\n"
+ /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
+ VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
+ boundary. And r1 is the original SP. Set the SP to r16 and
+ call _start_in_C, passing it the initial SP. */
+ "\tmr 3,1\n"
+ "\tmr 1,16\n"
+ "\tbl _start_in_C\n"
+ "\ttrap\n"
+ ".previous\n"
+);
#else
#error "_start: needs implementation on this platform"
#endif
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index 56a89e4..1539980 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -404,6 +404,10 @@
}
+#elif defined(VGP_ppc64_linux)
+
+ // we'll have to stick some godawful hacks in here, no doubt
+
#else
# error Unknown platform
#endif
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
index 9bfc6ca..fd5a5ed 100644
--- a/coregrind/m_scheduler/scheduler.c
+++ b/coregrind/m_scheduler/scheduler.c
@@ -901,7 +901,7 @@
#elif defined(VGA_amd64)
# define VG_CLREQ_ARGS guest_RAX
# define VG_CLREQ_RET guest_RDX
-#elif defined(VGA_ppc32)
+#elif defined(VGA_ppc32) || defined(VGA_ppc64)
# define VG_CLREQ_ARGS guest_GPR4
# define VG_CLREQ_RET guest_GPR3
#else
diff --git a/coregrind/m_sigframe/sigframe-ppc64-linux.c b/coregrind/m_sigframe/sigframe-ppc64-linux.c
new file mode 100644
index 0000000..723bf03
--- /dev/null
+++ b/coregrind/m_sigframe/sigframe-ppc64-linux.c
@@ -0,0 +1,421 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Create/destroy signal delivery frames. ---*/
+/*--- sigframe-ppc64-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Nicholas Nethercote
+ njn@valgrind.org
+ Copyright (C) 2004-2005 Paul Mackerras
+ paulus@samba.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_machine.h"
+#include "pub_core_options.h"
+#include "pub_core_sigframe.h"
+#include "pub_core_signals.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_trampoline.h"
+#include "pub_core_transtab.h" // VG_(discard_translations)
+#include "vki_unistd-ppc64-linux.h" // __NR_rt_sigreturn
+
+
+/* This module creates and removes signal frames for signal deliveries
+ on ppc64-linux.
+
+ Note, this file contains kernel-specific knowledge in the form of
+ 'struct sigframe' and 'struct rt_sigframe'. How does that relate
+ to the vki kernel interface stuff?
+
+ Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
+ onto the client's stack. This contains a subsidiary
+ vki_ucontext. That holds the vcpu's state across the signal,
+ so that the sighandler can mess with the vcpu state if it
+ really wants.
+
+ FIXME: sigcontexting is basically broken for the moment. When
+ delivering a signal, the integer registers and %eflags are
+ correctly written into the sigcontext, however the FP and SSE state
+ is not. When returning from a signal, only the integer registers
+ are restored from the sigcontext; the rest of the CPU state is
+ restored to what it was before the signal.
+
+ This will be fixed.
+*/
+
+
+/*------------------------------------------------------------*/
+/*--- Signal frame layouts ---*/
+/*------------------------------------------------------------*/
+
+// A structure in which to save the application's registers
+// during the execution of signal handlers.
+
+// Linux has 2 signal frame structures: one for normal signal
+// deliveries, and one for SA_SIGINFO deliveries (also known as RT
+// signals).
+//
+// In theory, so long as we get the arguments to the handler function
+// right, it doesn't matter what the exact layout of the rest of the
+// frame is. Unfortunately, things like gcc's exception unwinding
+// make assumptions about the locations of various parts of the frame,
+// so we need to duplicate it exactly.
+
+/* Structure containing bits of information that we want to save
+ on signal delivery. */
+//zz struct vg_sig_private {
+//zz UInt magicPI;
+//zz UInt sigNo_private;
+//zz VexGuestPPC32State shadow;
+//zz };
+//zz
+//zz /* Structure put on stack for signal handlers with SA_SIGINFO clear. */
+//zz struct nonrt_sigframe {
+//zz UInt gap1[16];
+//zz struct vki_sigcontext sigcontext;
+//zz struct vki_mcontext mcontext;
+//zz struct vg_sig_private priv;
+//zz unsigned char abigap[224];
+//zz };
+//zz
+//zz /* Structure put on stack for signal handlers with SA_SIGINFO set. */
+//zz struct rt_sigframe {
+//zz UInt gap1[20];
+//zz vki_siginfo_t siginfo;
+//zz struct vki_ucontext ucontext;
+//zz struct vg_sig_private priv;
+//zz unsigned char abigap[224];
+//zz };
+
+#define SET_SIGNAL_LR(zztst, zzval) \
+ do { tst->arch.vex.guest_LR = (zzval); \
+ VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
+ offsetof(VexGuestPPC32State,guest_LR), \
+ sizeof(UWord) ); \
+ } while (0)
+
+#define SET_SIGNAL_GPR(zztst, zzn, zzval) \
+ do { tst->arch.vex.guest_GPR##zzn = (zzval); \
+ VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
+ offsetof(VexGuestPPC32State,guest_GPR##zzn), \
+ sizeof(UWord) ); \
+ } while (0)
+
+
+static
+void stack_mcontext ( struct vki_mcontext *mc,
+ ThreadState* tst,
+ Int ret,
+ UInt fault_addr )
+{
+// VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
+// (Addr)mc, sizeof(struct vki_pt_regs) );
+//
+//# define DO(gpr) mc->mc_gregs[VKI_PT_R0+gpr] = tst->arch.vex.guest_GPR##gpr
+// DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+// DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+// DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+// DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+//# undef DO
+//
+// mc->mc_gregs[VKI_PT_NIP] = tst->arch.vex.guest_CIA;
+// mc->mc_gregs[VKI_PT_MSR] = 0xf032; /* pretty arbitrary */
+// mc->mc_gregs[VKI_PT_ORIG_R3] = tst->arch.vex.guest_GPR3;
+// mc->mc_gregs[VKI_PT_CTR] = tst->arch.vex.guest_CTR;
+// mc->mc_gregs[VKI_PT_LNK] = tst->arch.vex.guest_LR;
+// mc->mc_gregs[VKI_PT_XER] = LibVEX_GuestPPC32_get_XER(&tst->arch.vex);
+// mc->mc_gregs[VKI_PT_CCR] = LibVEX_GuestPPC32_get_CR(&tst->arch.vex);
+// mc->mc_gregs[VKI_PT_MQ] = 0;
+// mc->mc_gregs[VKI_PT_TRAP] = 0;
+// mc->mc_gregs[VKI_PT_DAR] = fault_addr;
+// mc->mc_gregs[VKI_PT_DSISR] = 0;
+// mc->mc_gregs[VKI_PT_RESULT] = 0;
+// VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
+// (Addr)mc, sizeof(struct vki_pt_regs) );
+//
+// /* XXX should do FP and vector regs */
+//
+// /* set up signal return trampoline */
+// VG_TRACK(pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
+// (Addr)&mc->mc_pad, sizeof(mc->mc_pad));
+// mc->mc_pad[0] = 0x38000000U + ret; /* li 0,ret */
+// mc->mc_pad[1] = 0x44000002U; /* sc */
+// VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
+// (Addr)&mc->mc_pad, sizeof(mc->mc_pad) );
+// /* invalidate any translation of this area */
+// VG_(discard_translations)( (Addr64)(Addr)&mc->mc_pad,
+// sizeof(mc->mc_pad), "stack_mcontext" );
+//
+// /* set the signal handler to return to the trampoline */
+// SET_SIGNAL_LR(tst, (Addr) &mc->mc_pad[0]);
+}
+
+
+/* Extend the stack segment downwards if needed so as to ensure the
+ new signal frames are mapped to something. Return a Bool
+ indicating whether or not the operation was successful.
+*/
+static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
+{
+ I_die_here;
+// ThreadId tid = tst->tid;
+// NSegment *stackseg = NULL;
+//
+// if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
+// stackseg = VG_(am_find_nsegment)(addr);
+// if (0 && stackseg)
+// VG_(printf)("frame=%p seg=%p-%p\n",
+// addr, stackseg->start, stackseg->end);
+// }
+//
+// if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
+// VG_(message)(
+// Vg_UserMsg,
+// "Can't extend stack to %p during signal delivery for thread %d:",
+// addr, tid);
+// if (stackseg == NULL)
+// VG_(message)(Vg_UserMsg, " no stack segment");
+// else
+// VG_(message)(Vg_UserMsg, " too small or bad protection modes");
+//
+// /* set SIGSEGV to default handler */
+// VG_(set_default_handler)(VKI_SIGSEGV);
+// VG_(synth_fault_mapping)(tid, addr);
+//
+// /* The whole process should be about to die, since the default
+// action of SIGSEGV to kill the whole process. */
+// return False;
+// }
+//
+// /* For tracking memory events, indicate the entire frame has been
+// allocated. */
+// VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
+// size + VG_STACK_REDZONE_SZB );
+//
+// return True;
+}
+
+
+/* EXPORTED */
+void VG_(sigframe_create)( ThreadId tid,
+ Addr sp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler,
+ UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer )
+{
+ I_die_here;
+// struct vg_sig_private *priv;
+// Addr sp;
+// ThreadState *tst;
+// Int sigNo = siginfo->si_signo;
+// Addr faultaddr;
+//
+// /* Stack must be 16-byte aligned */
+// sp_top_of_frame &= ~0xf;
+//
+// if (flags & VKI_SA_SIGINFO) {
+// sp = sp_top_of_frame - sizeof(struct rt_sigframe);
+// } else {
+// sp = sp_top_of_frame - sizeof(struct nonrt_sigframe);
+// }
+//
+// tst = VG_(get_ThreadState)(tid);
+//
+// if (!extend(tst, sp, sp_top_of_frame - sp))
+// return;
+//
+// vg_assert(VG_IS_16_ALIGNED(sp));
+//
+// /* Set up the stack chain pointer */
+// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
+// sp, sizeof(UWord) );
+// *(Addr *)sp = tst->arch.vex.guest_GPR1;
+// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+// sp, sizeof(UWord) );
+//
+// faultaddr = (Addr)siginfo->_sifields._sigfault._addr;
+// if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
+// faultaddr = tst->arch.vex.guest_CIA;
+//
+// if (flags & VKI_SA_SIGINFO) {
+// struct rt_sigframe *frame = (struct rt_sigframe *) sp;
+// struct vki_ucontext *ucp = &frame->ucontext;
+//
+// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
+// (Addr)&frame->siginfo, sizeof(frame->siginfo) );
+// VG_(memcpy)(&frame->siginfo, siginfo, sizeof(*siginfo));
+// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+// (Addr)&frame->siginfo, sizeof(frame->siginfo) );
+//
+// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
+// (Addr)ucp, offsetof(struct vki_ucontext, uc_pad) );
+// ucp->uc_flags = 0;
+// ucp->uc_link = 0;
+// ucp->uc_stack = tst->altstack;
+// VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
+// offsetof(struct vki_ucontext, uc_pad) );
+//
+// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
+// (Addr)&ucp->uc_regs,
+// sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
+// ucp->uc_regs = &ucp->uc_mcontext;
+// ucp->uc_sigmask = tst->sig_mask;
+// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+// (Addr)&ucp->uc_regs,
+// sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
+//
+// stack_mcontext(&ucp->uc_mcontext, tst, __NR_rt_sigreturn, faultaddr);
+// priv = &frame->priv;
+//
+// SET_SIGNAL_GPR(tid, 4, (Addr) &frame->siginfo);
+// SET_SIGNAL_GPR(tid, 5, (Addr) ucp);
+// /* the kernel sets this, though it doesn't seem to be in the ABI */
+// SET_SIGNAL_GPR(tid, 6, (Addr) &frame->siginfo);
+//
+// } else {
+// /* non-RT signal delivery */
+// struct nonrt_sigframe *frame = (struct nonrt_sigframe *) sp;
+// struct vki_sigcontext *scp = &frame->sigcontext;
+//
+// VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame sigcontext",
+// (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) );
+// scp->signal = sigNo;
+// scp->handler = (Addr) handler;
+// scp->oldmask = tst->sig_mask.sig[0];
+// scp->_unused[3] = tst->sig_mask.sig[1];
+// VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+// (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) );
+//
+// stack_mcontext(&frame->mcontext, tst, __NR_sigreturn, faultaddr);
+// priv = &frame->priv;
+//
+// SET_SIGNAL_GPR(tid, 4, (Addr) scp);
+// }
+//
+// priv->magicPI = 0x31415927;
+// priv->sigNo_private = sigNo;
+// priv->shadow = tst->arch.vex_shadow;
+//
+// SET_SIGNAL_GPR(tid, 1, sp);
+// SET_SIGNAL_GPR(tid, 3, sigNo);
+// tst->arch.vex.guest_CIA = (Addr) handler;
+//
+// if (0)
+// VG_(printf)("pushed signal frame; %R1 now = %p, "
+// "next %%CIA = %p, status=%d\n",
+// sp, tst->arch.vex.guest_CIA, tst->status);
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Destroying signal frames ---*/
+/*------------------------------------------------------------*/
+
+/* EXPORTED */
+void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
+{
+ I_die_here;
+// ThreadState *tst;
+// struct vg_sig_private *priv;
+// Addr sp;
+// UInt frame_size;
+// struct vki_mcontext *mc;
+// Int sigNo;
+// Bool has_siginfo = isRT;
+//
+// vg_assert(VG_(is_valid_tid)(tid));
+// tst = VG_(get_ThreadState)(tid);
+//
+// /* Check that the stack frame looks valid */
+// sp = tst->arch.vex.guest_GPR1;
+// vg_assert(VG_IS_16_ALIGNED(sp));
+// /* JRS 17 Nov 05: This code used to check that *sp -- which should
+// have been set by the stwu at the start of the handler -- points
+// to just above the frame (ie, the previous frame). However, that
+// isn't valid when delivering signals on alt stacks. So I removed
+// it. The frame is still sanity-checked using the priv->magicPI
+// field. */
+//
+// if (has_siginfo) {
+// struct rt_sigframe *frame = (struct rt_sigframe *)sp;
+// frame_size = sizeof(*frame);
+// mc = &frame->ucontext.uc_mcontext;
+// priv = &frame->priv;
+// vg_assert(priv->magicPI == 0x31415927);
+// tst->sig_mask = frame->ucontext.uc_sigmask;
+// } else {
+// struct nonrt_sigframe *frame = (struct nonrt_sigframe *)sp;
+// frame_size = sizeof(*frame);
+// mc = &frame->mcontext;
+// priv = &frame->priv;
+// vg_assert(priv->magicPI == 0x31415927);
+// tst->sig_mask.sig[0] = frame->sigcontext.oldmask;
+// tst->sig_mask.sig[1] = frame->sigcontext._unused[3];
+// }
+// tst->tmp_sig_mask = tst->sig_mask;
+//
+// sigNo = priv->sigNo_private;
+//
+//# define DO(gpr) tst->arch.vex.guest_GPR##gpr = mc->mc_gregs[VKI_PT_R0+gpr]
+// DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+// DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+// DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+// DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+//# undef DO
+//
+// tst->arch.vex.guest_CIA = mc->mc_gregs[VKI_PT_NIP];
+//
+// // Umm ... ? (jrs 2005 July 8)
+// // tst->arch.m_orig_gpr3 = mc->mc_gregs[VKI_PT_ORIG_R3];
+//
+// LibVEX_GuestPPC32_put_CR( mc->mc_gregs[VKI_PT_CCR], &tst->arch.vex );
+//
+// tst->arch.vex.guest_LR = mc->mc_gregs[VKI_PT_LNK];
+// tst->arch.vex.guest_CTR = mc->mc_gregs[VKI_PT_CTR];
+// LibVEX_GuestPPC32_put_XER( mc->mc_gregs[VKI_PT_XER], &tst->arch.vex );
+//
+// tst->arch.vex_shadow = priv->shadow;
+//
+// VG_TRACK(die_mem_stack_signal, sp, frame_size);
+//
+// if (VG_(clo_trace_signals))
+// VG_(message)(Vg_DebugMsg,
+// "vg_pop_signal_frame (thread %d): isRT=%d valid magic; EIP=%p",
+// tid, has_siginfo, tst->arch.vex.guest_CIA);
+//
+// /* tell the tools */
+// VG_TRACK( post_deliver_signal, tid, sigNo );
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end sigframe-ppc64-linux.c ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c
index 881c13d..ace8de2 100644
--- a/coregrind/m_signals.c
+++ b/coregrind/m_signals.c
@@ -207,6 +207,19 @@
)
# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_LNK])
+#elif defined(VGP_ppc64_linux)
+# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
+# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
+# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
+# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R0])
+# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
+ /* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
+ VG_(mk_SysRes_ppc64_linux)( \
+ (uc)->uc_mcontext.gp_regs[VKI_PT_R3], \
+ (((uc)->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1) \
+ )
+# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_LNK])
+
#else
# error Unknown platform
#endif
@@ -462,6 +475,13 @@
" li 0, " #name "\n" \
" sc\n" \
".previous\n"
+#elif defined(VGP_ppc64_linux)
+# define _MYSIG(name) \
+ ".text\n" \
+ "my_sigreturn:\n" \
+ " li 0, " #name "\n" \
+ " sc\n" \
+ ".previous\n"
#else
# error Unknown platform
#endif
diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c
index fde3a25..63a3b93 100644
--- a/coregrind/m_stacktrace.c
+++ b/coregrind/m_stacktrace.c
@@ -54,7 +54,7 @@
Addr ip, Addr sp, Addr fp, Addr lr,
Addr fp_min, Addr fp_max_orig )
{
-#if defined(VGP_ppc32_linux)
+#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
Bool lr_is_first_RA = False; /* ppc only */
#endif
Bool debug = False;
@@ -234,7 +234,7 @@
break;
}
-# elif defined(VGP_ppc32_linux)
+# elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
/*--------------------- ppc32 ---------------------*/
diff --git a/coregrind/m_syscall.c b/coregrind/m_syscall.c
index af90517..28a79c0 100644
--- a/coregrind/m_syscall.c
+++ b/coregrind/m_syscall.c
@@ -54,7 +54,7 @@
syscall returns a value in -1 .. -4095 as a valid result so we can
safely test with -4095.
*/
-SysRes VG_(mk_SysRes_x86_linux) ( Word val ) {
+SysRes VG_(mk_SysRes_x86_linux) ( UInt val ) {
SysRes res;
res.isError = val >= -4095 && val <= -1;
res.val = res.isError ? -val : val;
@@ -62,7 +62,7 @@
}
/* Similarly .. */
-SysRes VG_(mk_SysRes_amd64_linux) ( Word val ) {
+SysRes VG_(mk_SysRes_amd64_linux) ( ULong val ) {
SysRes res;
res.isError = val >= -4095 && val <= -1;
res.val = res.isError ? -val : val;
@@ -78,6 +78,13 @@
return res;
}
+SysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong errflag ) {
+ SysRes res;
+ res.isError = errflag != 0;
+ res.val = val;
+ return res;
+}
+
SysRes VG_(mk_SysRes_Error) ( UWord val ) {
SysRes r = { val, True };
@@ -133,6 +140,7 @@
" ret\n"
".previous\n"
);
+
#elif defined(VGP_amd64_linux)
/* Incoming args (syscall number + up to 6 args) come in %rdi, %rsi,
%rdx, %rcx, %r8, %r9, and the last one on the stack (ie. the C
@@ -167,6 +175,7 @@
" ret\n"
".previous\n"
);
+
#elif defined(VGP_ppc32_linux)
/* Incoming args (syscall number + up to 6 args) come in %r3:%r9.
@@ -200,6 +209,36 @@
" blr\n" /* and return */
".previous\n"
);
+
+#elif defined(VGP_ppc64_linux)
+/* Due to the need to return 65 bits of result, this is completely
+ different from the ppc32 case. The single arg register points to a
+ 7-word block containing the syscall # and the 6 args. The syscall
+ result proper is put in [0] of the block, and %cr0.so is in the
+ bottom but of [1]. */
+extern void do_syscall_WRK ( ULong* argblock );
+asm(
+".text\n"
+".do_syscall_WRK:\n"
+" std 3,-16(1)\n" /* stash arg */
+" ld 8, 48(3)\n" /* sc arg 6 */
+" ld 7, 40(3)\n" /* sc arg 5 */
+" ld 6, 32(3)\n" /* sc arg 4 */
+" ld 5, 24(3)\n" /* sc arg 3 */
+" ld 4, 16(3)\n" /* sc arg 2 */
+" ld 0, 0(3)\n" /* sc number */
+" ld 3, 8(3)\n" /* sc arg 1 */
+" sc\n" /* result in r3 and cr0.so */
+" ld 5,-16(1)\n" /* reacquire argblock ptr (r5 is caller-save) */
+" std 3,0(5)\n" /* argblock[0] = r3 */
+" xor 3,3,3\n"
+" mfcr 3\n"
+" srwi 3,3,28\n"
+" andi. 3,3,1\n"
+" std 3,8(5)\n" /* argblock[1] = cr0.s0 & 1 */
+" blr\n"
+".previous\n"
+);
#else
# error Unknown platform
#endif
@@ -218,6 +257,17 @@
UInt val = (UInt)(ret>>32);
UInt cr0so = (UInt)(ret);
return VG_(mk_SysRes_ppc32_linux)( val, cr0so );
+#elif defined(VGP_ppc64_linux)
+ ULong argblock[7];
+ argblock[0] = sysno;
+ argblock[1] = a1;
+ argblock[2] = a2;
+ argblock[3] = a3;
+ argblock[4] = a4;
+ argblock[5] = a5;
+ argblock[6] = a6;
+ do_syscall_WRK( &argblock[0] );
+ return VG_(mk_SysRes_ppc64_linux)( argblock[0], argblock[1] );
#else
# error Unknown platform
#endif
diff --git a/coregrind/m_syswrap/syscall-ppc64-linux.S b/coregrind/m_syswrap/syscall-ppc64-linux.S
new file mode 100644
index 0000000..3d8134f
--- /dev/null
+++ b/coregrind/m_syswrap/syscall-ppc64-linux.S
@@ -0,0 +1,159 @@
+
+##--------------------------------------------------------------------##
+##--- Support for doing system calls. syscall-ppc64-linux.S ---##
+##--------------------------------------------------------------------##
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics_asm.h"
+#include "vki_unistd.h"
+#include "libvex_guest_offsets.h"
+
+
+/*----------------------------------------------------------------*/
+/*
+ Perform a syscall for the client. This will run a syscall
+ with the client's specific per-thread signal mask.
+
+ The structure of this function is such that, if the syscall is
+ interrupted by a signal, we can determine exactly what
+ execution state we were in with respect to the execution of
+ the syscall by examining the value of NIP in the signal
+ handler. This means that we can always do the appropriate
+ thing to precisely emulate the kernel's signal/syscall
+ interactions.
+
+ The syscall number is taken from the argument, even though it
+ should also be in regs->m_gpr[0]. The syscall result is written
+ back to regs->m_gpr[3]/m_xer/m_result on completion.
+
+ Returns 0 if the syscall was successfully called (even if the
+ syscall itself failed), or a -ve error code if one of the
+ sigprocmasks failed (there's no way to determine which one
+ failed).
+
+ VG_(fixup_guest_state_after_syscall_interrupted) does the
+ thread state fixup in the case where we were interrupted by a
+ signal.
+
+ Prototype:
+
+ Int ML_(do_syscall_for_client_WRK)(
+ Int syscallno, // r3
+ void* guest_state, // r4
+ const vki_sigset_t *sysmask, // r5
+ const vki_sigset_t *postmask, // r6
+ Int nsigwords) // r7
+*/
+/* from vki_arch.h */
+#define VKI_SIG_SETMASK 2
+
+.globl .ML_(do_syscall_for_client_WRK)
+.ML_(do_syscall_for_client_WRK):
+ /* make a stack frame */
+ stdu 1,-64(1)
+ std 31,56(1)
+ std 30,48(1)
+ std 29,40(1)
+ std 28,32(1)
+ mr 31,3 /* syscall number */
+ mr 30,4 /* guest_state */
+ mr 29,6 /* postmask */
+ mr 28,7 /* nsigwords */
+
+ /* set the signal mask for doing the system call */
+ /* set up for sigprocmask(SIG_SETMASK, sysmask, postmask) */
+1: li 0,__NR_sigprocmask
+ li 3,VKI_SIG_SETMASK
+ mr 4,5
+ mr 5,6
+ sc /* set the mask */
+ bso 7f /* if the sigprocmask fails */
+
+ /* load up syscall args from the threadstate */
+ ld 3,OFFSET_ppc64_GPR3(30)
+ ld 4,OFFSET_ppc64_GPR4(30)
+ ld 5,OFFSET_ppc64_GPR5(30)
+ ld 6,OFFSET_ppc64_GPR6(30)
+ ld 7,OFFSET_ppc64_GPR7(30)
+ ld 8,OFFSET_ppc64_GPR8(30)
+ mr 0,31 /* syscall number */
+2: sc /* do the syscall */
+
+ /* put the result back in the threadstate */
+3: std 3,OFFSET_ppc64_GPR3(30) /* gst->GPR3 = sc result */
+ /* copy cr0.so back to simulated state */
+ mfcr 5 /* r5 = CR */
+ rlwinm 5,5,4,31,31 /* r5 = (CR >> 28) & 1 */
+ stb 5,OFFSET_ppc64_CR0_0(30) /* gst->CR0.SO = cr0.so */
+
+ /* block signals again */
+ /* set up for sigprocmask(SIG_SETMASK, postmask, NULL) */
+4: li 0,__NR_sigprocmask
+ li 3,VKI_SIG_SETMASK
+ mr 4,29
+ li 5,0
+ mr 6,28
+ sc /* set the mask */
+ bso 7f /* if the sigprocmask fails */
+
+ /* now safe from signals */
+
+ /* pop off stack frame */
+5: ld 28,32(1)
+ ld 29,40(1)
+ ld 30,48(1)
+ ld 31,56(1)
+ addi 1,1,64
+ blr
+
+ /* failure: return -ve error code */
+7: neg 3,3
+ b 5b
+
+.section .rodata
+/* export the ranges so that
+ VG_(fixup_guest_state_after_syscall_interrupted) can do the
+ right thing */
+
+.globl ML_(blksys_setup)
+.globl ML_(blksys_restart)
+.globl ML_(blksys_complete)
+.globl ML_(blksys_committed)
+.globl ML_(blksys_finished)
+ML_(blksys_setup): .long 1b
+ML_(blksys_restart): .long 2b
+ML_(blksys_complete): .long 3b
+ML_(blksys_committed): .long 4b
+ML_(blksys_finished): .long 5b
+
+.previous
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
+##--------------------------------------------------------------------##
+##--- end ---##
+##--------------------------------------------------------------------##
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index fbaaba9..acfa922 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -3427,7 +3427,7 @@
case VKI_SOUND_PCM_READ_RATE:
case VKI_SOUND_PCM_READ_CHANNELS:
case VKI_SOUND_PCM_READ_BITS:
-#if !defined(VGA_ppc32)
+#if !defined(VGA_ppc32) && !defined(VGA_ppc64)
case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
#endif
case VKI_SOUND_PCM_READ_FILTER:
@@ -4134,7 +4134,7 @@
case VKI_SOUND_PCM_READ_RATE:
case VKI_SOUND_PCM_READ_CHANNELS:
case VKI_SOUND_PCM_READ_BITS:
-#if !defined(VGA_ppc32)
+#if !defined(VGA_ppc32) && !defined(VGA_ppc64)
case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
#endif
case VKI_SOUND_PCM_READ_FILTER:
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index faa6335..866f0c5 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -177,7 +177,7 @@
"syscall\n" /* exit(tst->os_state.exitcode) */
: "=m" (tst->status)
: "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode));
-#elif defined(VGP_ppc32_linux)
+#elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
{ UInt vgts_empty = (UInt)VgTs_Empty;
asm volatile (
"stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
@@ -304,7 +304,7 @@
/* Since this is the fork() form of clone, we don't need all that
VG_(clone) stuff */
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
res = VG_(do_syscall5)( __NR_clone, flags,
(UWord)NULL, (UWord)parent_tidptr,
(UWord)NULL, (UWord)child_tidptr );
diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c
index de85593..8251d03 100644
--- a/coregrind/m_syswrap/syswrap-main.c
+++ b/coregrind/m_syswrap/syswrap-main.c
@@ -56,6 +56,7 @@
x86 eax ebx ecx edx esi edi ebp eax (== NUM)
amd64 rax rdi rsi rdx r10 r8 r9 rax (== NUM)
ppc32 r0 r3 r4 r5 r6 r7 r8 r3+CR0.SO (== ARG1)
+ ppc64 r0 r3 r4 r5 r6 r7 r8 r3+CR0.SO (== ARG1)
*/
/* This is the top level of the system-call handler module. All
@@ -329,6 +330,16 @@
canonical->arg5 = gst->guest_GPR7;
canonical->arg6 = gst->guest_GPR8;
+#elif defined(VGP_ppc64_linux)
+ VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
+ canonical->sysno = gst->guest_GPR0;
+ canonical->arg1 = gst->guest_GPR3;
+ canonical->arg2 = gst->guest_GPR4;
+ canonical->arg3 = gst->guest_GPR5;
+ canonical->arg4 = gst->guest_GPR6;
+ canonical->arg5 = gst->guest_GPR7;
+ canonical->arg6 = gst->guest_GPR8;
+
#else
# error "getSyscallArgsFromGuestState: unknown arch"
#endif
@@ -368,6 +379,16 @@
gst->guest_GPR7 = canonical->arg5;
gst->guest_GPR8 = canonical->arg6;
+#elif defined(VGP_ppc64_linux)
+ VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
+ gst->guest_GPR0 = canonical->sysno;
+ gst->guest_GPR3 = canonical->arg1;
+ gst->guest_GPR4 = canonical->arg2;
+ gst->guest_GPR5 = canonical->arg3;
+ gst->guest_GPR6 = canonical->arg4;
+ gst->guest_GPR7 = canonical->arg5;
+ gst->guest_GPR8 = canonical->arg6;
+
#else
# error "putSyscallArgsIntoGuestState: unknown arch"
#endif
@@ -396,6 +417,13 @@
canonical->what = (err == 1) ? SsFailure : SsSuccess;
canonical->val = (UWord)gst->guest_GPR3;
+#elif defined(VGP_ppc64_linux)
+ VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
+ UInt cr = LibVEX_GuestPPC64_get_CR( gst );
+ UInt err = (cr >> 28) & 1; // CR0.SO
+ canonical->what = (err == 1) ? SsFailure : SsSuccess;
+ canonical->val = (UWord)gst->guest_GPR3;
+
#else
# error "getSyscallStatusFromGuestState: unknown arch"
#endif
@@ -447,6 +475,23 @@
LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), gst );
}
+#elif defined(VGP_ppc64_linux)
+ VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
+ UInt old_cr = LibVEX_GuestPPC64_get_CR(gst);
+
+ vg_assert(canonical->what == SsSuccess
+ || canonical->what == SsFailure);
+
+ gst->guest_GPR3 = canonical->val;
+
+ if (canonical->what == SsFailure) {
+ /* set CR0.SO */
+ LibVEX_GuestPPC64_put_CR( old_cr | (1<<28), gst );
+ } else {
+ /* clear CR0.SO */
+ LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), gst );
+ }
+
#else
# error "putSyscallStatusIntoGuestState: unknown arch"
#endif
@@ -490,6 +535,16 @@
layout->o_arg6 = OFFSET_ppc32_GPR8;
layout->o_retval = OFFSET_ppc32_GPR3;
+#elif defined(VGP_ppc64_linux)
+ layout->o_sysno = OFFSET_ppc64_GPR0;
+ layout->o_arg1 = OFFSET_ppc64_GPR3;
+ layout->o_arg2 = OFFSET_ppc64_GPR4;
+ layout->o_arg3 = OFFSET_ppc64_GPR5;
+ layout->o_arg4 = OFFSET_ppc64_GPR6;
+ layout->o_arg5 = OFFSET_ppc64_GPR7;
+ layout->o_arg6 = OFFSET_ppc64_GPR8;
+ layout->o_retval = OFFSET_ppc64_GPR3;
+
#else
# error "getSyscallLayout: unknown arch"
#endif
@@ -981,7 +1036,7 @@
vg_assert(p[0] == 0x0F && p[1] == 0x05);
}
-#elif defined(VGP_ppc32_linux)
+#elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
arch->vex.guest_CIA -= 4; // sizeof(ppc32 instr)
/* Make sure our caller is actually sane, and we're really backing
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
new file mode 100644
index 0000000..017bc27
--- /dev/null
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
@@ -0,0 +1,1495 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Platform-specific syscalls stuff. syswrap-ppc64-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2005 Nicholas Nethercote <njn@valgrind.org>
+ Copyright (C) 2005 Cerion Armour-Brown <cerion@open-works.co.uk>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_debuglog.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_libcproc.h"
+#include "pub_core_libcsignal.h"
+#include "pub_core_options.h"
+#include "pub_core_scheduler.h"
+#include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
+#include "pub_core_signals.h"
+#include "pub_core_syscall.h"
+#include "pub_core_syswrap.h"
+#include "pub_core_tooliface.h"
+
+#include "priv_types_n_macros.h"
+#include "priv_syswrap-generic.h" /* for decls of generic wrappers */
+#include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
+#include "priv_syswrap-main.h"
+
+#include "vki_unistd.h" /* for the __NR_* constants */
+
+
+/* ---------------------------------------------------------------------
+ clone() handling
+ ------------------------------------------------------------------ */
+
+/* Call f(arg1), but first switch stacks, using 'stack' as the new
+ stack, and use 'retaddr' as f's return-to address. Also, clear all
+ the integer registers before entering f.*/
+__attribute__((noreturn))
+void ML_(call_on_new_stack_0_1) ( Addr stack,
+ Addr retaddr,
+ void (*f)(Word),
+ Word arg1 );
+// r3 = stack
+// r4 = retaddr
+// r5 = f
+// r6 = arg1
+asm(
+".text\n"
+".globl .vgModuleLocal_call_on_new_stack_0_1\n"
+".vgModuleLocal_call_on_new_stack_0_1:\n"
+" mr %r1,%r3\n\t" // stack to %sp
+" mtlr %r4\n\t" // retaddr to %lr
+" mtctr %r5\n\t" // f to count reg
+" mr %r3,%r6\n\t" // arg1 to %r3
+" li 0,0\n\t" // zero all GP regs
+" li 4,0\n\t"
+" li 5,0\n\t"
+" li 6,0\n\t"
+" li 7,0\n\t"
+" li 8,0\n\t"
+" li 9,0\n\t"
+" li 10,0\n\t"
+" li 11,0\n\t"
+" li 12,0\n\t"
+" li 13,0\n\t"
+" li 14,0\n\t"
+" li 15,0\n\t"
+" li 16,0\n\t"
+" li 17,0\n\t"
+" li 18,0\n\t"
+" li 19,0\n\t"
+" li 20,0\n\t"
+" li 21,0\n\t"
+" li 22,0\n\t"
+" li 23,0\n\t"
+" li 24,0\n\t"
+" li 25,0\n\t"
+" li 26,0\n\t"
+" li 27,0\n\t"
+" li 28,0\n\t"
+" li 29,0\n\t"
+" li 30,0\n\t"
+" li 31,0\n\t"
+" mtxer 0\n\t" // CAB: Need this?
+" mtcr 0\n\t" // CAB: Need this?
+" bctr\n\t" // jump to dst
+" trap\n" // should never get here
+".previous\n"
+);
+
+
+/*
+ Perform a clone system call. clone is strange because it has
+ fork()-like return-twice semantics, so it needs special
+ handling here.
+
+ Upon entry, we have:
+
+ word (fn)(void*) in r3
+ void* child_stack in r4
+ word flags in r5
+ void* arg in r6
+ pid_t* child_tid in r7
+ pid_t* parent_tid in r8
+ void* ??? in r9
+
+ System call requires:
+
+ int $__NR_clone in r0 (sc number)
+ int flags in r3 (sc arg1)
+ void* child_stack in r4 (sc arg2)
+ pid_t* parent_tid in r5 (sc arg3)
+ ?? child_tls in r6 (sc arg4)
+ pid_t* child_tid in r7 (sc arg5)
+ void* ??? in r8 (sc arg6)
+
+ Returns a ULong encoded as: top half is %cr following syscall,
+ low half is syscall return value (r3).
+ */
+#define __NR_CLONE VG_STRINGIFY(__NR_clone)
+#define __NR_EXIT VG_STRINGIFY(__NR_exit)
+
+extern
+ULong do_syscall_clone_ppc64_linux ( Word (*fn)(void *),
+ void* stack,
+ Int flags,
+ void* arg,
+ Int* child_tid,
+ Int* parent_tid,
+ void/*vki_modify_ldt_t*/ * );
+asm(
+".text\n"
+".do_syscall_clone_ppc64_linux:\n"
+" stdu 1,-64(1)\n"
+" std 29,40(1)\n"
+" std 30,48(1)\n"
+" std 31,56(1)\n"
+" mr 30,3\n" // preserve fn
+" mr 31,6\n" // preserve arg
+
+ // setup child stack
+" rlwinm 4,4,0,~0xf\n" // trim sp to multiple of 16 bytes
+" li 0,0\n"
+" stdu 0,-32(4)\n" // make initial stack frame
+" mr 29,4\n" // preserve sp
+
+ // setup syscall
+" li 0,"__NR_CLONE"\n" // syscall number
+" mr 3,5\n" // syscall arg1: flags
+ // r4 already setup // syscall arg2: child_stack
+" mr 5,8\n" // syscall arg3: parent_tid
+" mr 6,2\n" // syscall arg4: REAL THREAD tls
+" mr 7,7\n" // syscall arg5: child_tid
+" mr 8,8\n" // syscall arg6: ????
+" mr 9,9\n" // syscall arg7: ????
+
+" sc\n" // clone()
+
+" mfcr 4\n" // CR now in low half r4
+" slwi 4,4,16\n"
+" slwi 4,4,16\n" // CR now in hi half r4
+
+" slwi 3,3,16\n"
+" slwi 3,3,16\n"
+" srwi 3,3,16\n"
+" srwi 3,3,16\n" // zero out hi half r3
+
+" and 3,3,4\n" // r3 = CR : syscall-retval
+" cmpwi 3,0\n" // child if retval == 0 (note, cmpw)
+" bne 1f\n" // jump if !child
+
+ /* CHILD - call thread function */
+ /* Note: 2.4 kernel doesn't set the child stack pointer,
+ so we do it here.
+ That does leave a small window for a signal to be delivered
+ on the wrong stack, unfortunately. */
+" mr 1,29\n"
+" mtctr 30\n" // ctr reg = fn
+" mr 3,31\n" // r3 = arg
+" bctrl\n" // call fn()
+
+ // exit with result
+" li 0,"__NR_EXIT"\n"
+" sc\n"
+
+ // Exit returned?!
+" .long 0\n"
+
+ // PARENT or ERROR - return
+"1: ld 29,40(1)\n"
+" ld 30,48(1)\n"
+" ld 31,56(1)\n"
+" addi 1,1,64\n"
+" blr\n"
+".previous\n"
+);
+
+#undef __NR_CLONE
+#undef __NR_EXIT
+
+// forward declarations
+static void setup_child ( ThreadArchState*, ThreadArchState* );
+
+/*
+ When a client clones, we need to keep track of the new thread. This means:
+ 1. allocate a ThreadId+ThreadState+stack for the the thread
+
+ 2. initialize the thread's new VCPU state
+
+ 3. create the thread using the same args as the client requested,
+ but using the scheduler entrypoint for IP, and a separate stack
+ for SP.
+ */
+static SysRes do_clone ( ThreadId ptid,
+ UInt flags, Addr sp,
+ Int *parent_tidptr,
+ Int *child_tidptr,
+ Addr child_tls)
+{
+ const Bool debug = False;
+
+ ThreadId ctid = VG_(alloc_ThreadState)();
+ ThreadState* ptst = VG_(get_ThreadState)(ptid);
+ ThreadState* ctst = VG_(get_ThreadState)(ctid);
+ ULong word64;
+ UWord* stack;
+ NSegment* seg;
+ SysRes res;
+ vki_sigset_t blockall, savedmask;
+
+ VG_(sigfillset)(&blockall);
+
+ vg_assert(VG_(is_running_thread)(ptid));
+ vg_assert(VG_(is_valid_tid)(ctid));
+
+ stack = (UWord*)ML_(allocstack)(ctid);
+ if (stack == NULL) {
+ res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
+ goto out;
+ }
+
+//? /* make a stack frame */
+//? stack -= 16;
+//? *(UWord *)stack = 0;
+
+
+ /* Copy register state
+
+ Both parent and child return to the same place, and the code
+ following the clone syscall works out which is which, so we
+ don't need to worry about it.
+
+ The parent gets the child's new tid returned from clone, but the
+ child gets 0.
+
+ If the clone call specifies a NULL SP for the new thread, then
+ it actually gets a copy of the parent's SP.
+
+ The child's TLS register (r2) gets set to the tlsaddr argument
+ if the CLONE_SETTLS flag is set.
+ */
+ setup_child( &ctst->arch, &ptst->arch );
+
+ /* Make sys_clone appear to have returned Success(0) in the
+ child. */
+ { UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
+ /* %r3 = 0 */
+ ctst->arch.vex.guest_GPR3 = 0;
+ /* %cr0.so = 0 */
+ LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
+ }
+
+ if (sp != 0)
+ ctst->arch.vex.guest_GPR1 = sp;
+
+ ctst->os_state.parent = ptid;
+
+ /* inherit signal mask */
+ ctst->sig_mask = ptst->sig_mask;
+ ctst->tmp_sig_mask = ptst->sig_mask;
+
+ /* We don't really know where the client stack is, because its
+ allocated by the client. The best we can do is look at the
+ memory mappings and try to derive some useful information. We
+ assume that esp starts near its highest possible value, and can
+ only go down to the start of the mmaped segment. */
+ seg = VG_(am_find_nsegment)(sp);
+ if (seg && seg->kind != SkResvn) {
+ ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
+ ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
+
+ if (debug)
+ VG_(printf)("\ntid %d: guessed client stack range %p-%p\n",
+ ctid, seg->start, VG_PGROUNDUP(sp));
+ } else {
+ VG_(message)(Vg_UserMsg, "!? New thread %d starts with R1(%p) unmapped\n",
+ ctid, sp);
+ ctst->client_stack_szB = 0;
+ }
+
+ if (flags & VKI_CLONE_SETTLS) {
+ if (debug)
+ VG_(printf)("clone child has SETTLS: tls at %p\n", child_tls);
+ ctst->arch.vex.guest_GPR13 = child_tls;
+ }
+
+ flags &= ~VKI_CLONE_SETTLS;
+
+ /* start the thread with everything blocked */
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
+
+ /* Create the new thread */
+ word64 = do_syscall_clone_ppc64_linux(
+ ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
+ child_tidptr, parent_tidptr, NULL
+ );
+ /* Low half word64 is syscall return value. Hi half is
+ the entire CR, from which we need to extract CR0.SO. */
+ /* VG_(printf)("word64 = 0x%llx\n", word64); */
+ res = VG_(mk_SysRes_ppc32_linux)(
+ /*val*/(UInt)(word64 & 0xFFFFFFFFULL),
+ /*errflag*/ (UInt)((word64 >> (32+28)) & 1)
+ );
+
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
+
+ out:
+ if (res.isError) {
+ /* clone failed */
+ VG_(cleanup_thread)(&ctst->arch);
+ ctst->status = VgTs_Empty;
+ }
+
+ return res;
+}
+
+
+
+/* ---------------------------------------------------------------------
+ More thread stuff
+ ------------------------------------------------------------------ */
+
+void VG_(cleanup_thread) ( ThreadArchState* arch )
+{
+}
+
+void setup_child ( /*OUT*/ ThreadArchState *child,
+ /*IN*/ ThreadArchState *parent )
+{
+ /* We inherit our parent's guest state. */
+ child->vex = parent->vex;
+ child->vex_shadow = parent->vex_shadow;
+}
+
+
+/* ---------------------------------------------------------------------
+ PRE/POST wrappers for ppc64/Linux-specific syscalls
+ ------------------------------------------------------------------ */
+
+#define PRE(name) DEFN_PRE_TEMPLATE(ppc32_linux, name)
+#define POST(name) DEFN_POST_TEMPLATE(ppc32_linux, name)
+
+/* Add prototypes for the wrappers declared here, so that gcc doesn't
+ harass us for not having prototypes. Really this is a kludge --
+ the right thing to do is to make these wrappers 'static' since they
+ aren't visible outside this file, but that requires even more macro
+ magic. */
+
+//zz DECL_TEMPLATE(ppc64_linux, sys_socketcall);
+//zz DECL_TEMPLATE(ppc64_linux, sys_mmap);
+//zz DECL_TEMPLATE(ppc64_linux, sys_mmap2);
+//zz DECL_TEMPLATE(ppc64_linux, sys_stat64);
+//zz DECL_TEMPLATE(ppc64_linux, sys_lstat64);
+//zz DECL_TEMPLATE(ppc64_linux, sys_fstat64);
+//zz DECL_TEMPLATE(ppc64_linux, sys_ipc);
+//zz DECL_TEMPLATE(ppc64_linux, sys_clone);
+//zz DECL_TEMPLATE(ppc64_linux, sys_sigreturn);
+//zz DECL_TEMPLATE(ppc64_linux, sys_rt_sigreturn);
+//zz DECL_TEMPLATE(ppc64_linux, sys_sigaction);
+//zz
+//zz PRE(sys_socketcall)
+//zz {
+//zz # define ARG2_0 (((UWord*)ARG2)[0])
+//zz # define ARG2_1 (((UWord*)ARG2)[1])
+//zz # define ARG2_2 (((UWord*)ARG2)[2])
+//zz # define ARG2_3 (((UWord*)ARG2)[3])
+//zz # define ARG2_4 (((UWord*)ARG2)[4])
+//zz # define ARG2_5 (((UWord*)ARG2)[5])
+//zz
+//zz *flags |= SfMayBlock;
+//zz PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
+//zz PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
+//zz
+//zz switch (ARG1 /* request */) {
+//zz
+//zz case VKI_SYS_SOCKETPAIR:
+//zz /* int socketpair(int d, int type, int protocol, int sv[2]); */
+//zz PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
+//zz break;
+//zz
+//zz case VKI_SYS_SOCKET:
+//zz /* int socket(int domain, int type, int protocol); */
+//zz PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
+//zz break;
+//zz
+//zz case VKI_SYS_BIND:
+//zz /* int bind(int sockfd, struct sockaddr *my_addr,
+//zz int addrlen); */
+//zz PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_LISTEN:
+//zz /* int listen(int s, int backlog); */
+//zz PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
+//zz break;
+//zz
+//zz case VKI_SYS_ACCEPT: {
+//zz /* int accept(int s, struct sockaddr *addr, int *addrlen); */
+//zz PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz }
+//zz
+//zz case VKI_SYS_SENDTO:
+//zz /* int sendto(int s, const void *msg, int len,
+//zz unsigned int flags,
+//zz const struct sockaddr *to, int tolen); */
+//zz PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
+//zz ARG2_3, ARG2_4, ARG2_5 );
+//zz break;
+//zz
+//zz case VKI_SYS_SEND:
+//zz /* int send(int s, const void *msg, size_t len, int flags); */
+//zz PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_RECVFROM:
+//zz /* int recvfrom(int s, void *buf, int len, unsigned int flags,
+//zz struct sockaddr *from, int *fromlen); */
+//zz PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
+//zz ARG2_3, ARG2_4, ARG2_5 );
+//zz break;
+//zz
+//zz case VKI_SYS_RECV:
+//zz /* int recv(int s, void *buf, int len, unsigned int flags); */
+//zz /* man 2 recv says:
+//zz The recv call is normally used only on a connected socket
+//zz (see connect(2)) and is identical to recvfrom with a NULL
+//zz from parameter.
+//zz */
+//zz PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_CONNECT:
+//zz /* int connect(int sockfd,
+//zz struct sockaddr *serv_addr, int addrlen ); */
+//zz PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_SETSOCKOPT:
+//zz /* int setsockopt(int s, int level, int optname,
+//zz const void *optval, int optlen); */
+//zz PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
+//zz ARG2_3, ARG2_4 );
+//zz break;
+//zz
+//zz case VKI_SYS_GETSOCKOPT:
+//zz /* int getsockopt(int s, int level, int optname,
+//zz void *optval, socklen_t *optlen); */
+//zz PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
+//zz ARG2_3, ARG2_4 );
+//zz break;
+//zz
+//zz case VKI_SYS_GETSOCKNAME:
+//zz /* int getsockname(int s, struct sockaddr* name, int* namelen) */
+//zz PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_GETPEERNAME:
+//zz /* int getpeername(int s, struct sockaddr* name, int* namelen) */
+//zz PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
+//zz ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_SHUTDOWN:
+//zz /* int shutdown(int s, int how); */
+//zz PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
+//zz break;
+//zz
+//zz case VKI_SYS_SENDMSG: {
+//zz /* int sendmsg(int s, const struct msghdr *msg, int flags); */
+//zz
+//zz /* this causes warnings, and I don't get why. glibc bug?
+//zz * (after all it's glibc providing the arguments array)
+//zz PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
+//zz */
+//zz ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
+//zz break;
+//zz }
+//zz
+//zz case VKI_SYS_RECVMSG: {
+//zz /* int recvmsg(int s, struct msghdr *msg, int flags); */
+//zz
+//zz /* this causes warnings, and I don't get why. glibc bug?
+//zz * (after all it's glibc providing the arguments array)
+//zz PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
+//zz */
+//zz ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
+//zz break;
+//zz }
+//zz
+//zz default:
+//zz VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
+//zz SET_STATUS_Failure( VKI_EINVAL );
+//zz break;
+//zz }
+//zz # undef ARG2_0
+//zz # undef ARG2_1
+//zz # undef ARG2_2
+//zz # undef ARG2_3
+//zz # undef ARG2_4
+//zz # undef ARG2_5
+//zz }
+//zz
+//zz POST(sys_socketcall)
+//zz {
+//zz # define ARG2_0 (((UWord*)ARG2)[0])
+//zz # define ARG2_1 (((UWord*)ARG2)[1])
+//zz # define ARG2_2 (((UWord*)ARG2)[2])
+//zz # define ARG2_3 (((UWord*)ARG2)[3])
+//zz # define ARG2_4 (((UWord*)ARG2)[4])
+//zz # define ARG2_5 (((UWord*)ARG2)[5])
+//zz
+//zz SysRes r;
+//zz vg_assert(SUCCESS);
+//zz switch (ARG1 /* request */) {
+//zz
+//zz case VKI_SYS_SOCKETPAIR:
+//zz r = ML_(generic_POST_sys_socketpair)(
+//zz tid, VG_(mk_SysRes_Success)(RES),
+//zz ARG2_0, ARG2_1, ARG2_2, ARG2_3
+//zz );
+//zz SET_STATUS_from_SysRes(r);
+//zz break;
+//zz
+//zz case VKI_SYS_SOCKET:
+//zz r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
+//zz SET_STATUS_from_SysRes(r);
+//zz break;
+//zz
+//zz case VKI_SYS_BIND:
+//zz /* int bind(int sockfd, struct sockaddr *my_addr,
+//zz int addrlen); */
+//zz break;
+//zz
+//zz case VKI_SYS_LISTEN:
+//zz /* int listen(int s, int backlog); */
+//zz break;
+//zz
+//zz case VKI_SYS_ACCEPT:
+//zz /* int accept(int s, struct sockaddr *addr, int *addrlen); */
+//zz r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
+//zz ARG2_0, ARG2_1, ARG2_2 );
+//zz SET_STATUS_from_SysRes(r);
+//zz break;
+//zz
+//zz case VKI_SYS_SENDTO:
+//zz break;
+//zz
+//zz case VKI_SYS_SEND:
+//zz break;
+//zz
+//zz case VKI_SYS_RECVFROM:
+//zz ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
+//zz ARG2_0, ARG2_1, ARG2_2,
+//zz ARG2_3, ARG2_4, ARG2_5 );
+//zz break;
+//zz
+//zz case VKI_SYS_RECV:
+//zz ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_CONNECT:
+//zz break;
+//zz
+//zz case VKI_SYS_SETSOCKOPT:
+//zz break;
+//zz
+//zz case VKI_SYS_GETSOCKOPT:
+//zz ML_(generic_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
+//zz ARG2_0, ARG2_1,
+//zz ARG2_2, ARG2_3, ARG2_4 );
+//zz break;
+//zz
+//zz case VKI_SYS_GETSOCKNAME:
+//zz ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
+//zz ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_GETPEERNAME:
+//zz ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
+//zz ARG2_0, ARG2_1, ARG2_2 );
+//zz break;
+//zz
+//zz case VKI_SYS_SHUTDOWN:
+//zz break;
+//zz
+//zz case VKI_SYS_SENDMSG:
+//zz break;
+//zz
+//zz case VKI_SYS_RECVMSG:
+//zz ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
+//zz break;
+//zz
+//zz default:
+//zz VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
+//zz VG_(core_panic)("... bye!\n");
+//zz break; /*NOTREACHED*/
+//zz }
+//zz # undef ARG2_0
+//zz # undef ARG2_1
+//zz # undef ARG2_2
+//zz # undef ARG2_3
+//zz # undef ARG2_4
+//zz # undef ARG2_5
+//zz }
+//zz
+//zz PRE(sys_mmap)
+//zz {
+//zz SysRes r;
+//zz
+//zz PRINT("sys_mmap ( %p, %llu, %d, %d, %d, %d )",
+//zz ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
+//zz PRE_REG_READ6(long, "mmap",
+//zz unsigned long, start, unsigned long, length,
+//zz unsigned long, prot, unsigned long, flags,
+//zz unsigned long, fd, unsigned long, offset);
+//zz
+//zz r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
+//zz (Off64T)ARG6 );
+//zz SET_STATUS_from_SysRes(r);
+//zz }
+//zz
+//zz PRE(sys_mmap2)
+//zz {
+//zz SysRes r;
+//zz
+//zz // Exactly like old_mmap() except:
+//zz // - the file offset is specified in pagesize units rather than bytes,
+//zz // so that it can be used for files bigger than 2^32 bytes.
+//zz PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
+//zz ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
+//zz PRE_REG_READ6(long, "mmap2",
+//zz unsigned long, start, unsigned long, length,
+//zz unsigned long, prot, unsigned long, flags,
+//zz unsigned long, fd, unsigned long, offset);
+//zz
+//zz r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
+//zz VKI_PAGE_SIZE * (Off64T)ARG6 );
+//zz SET_STATUS_from_SysRes(r);
+//zz }
+//zz
+//zz // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
+//zz // applicable to every architecture -- I think only to 32-bit archs.
+//zz // We're going to need something like linux/core_os32.h for such
+//zz // things, eventually, I think. --njn
+//zz PRE(sys_stat64)
+//zz {
+//zz PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
+//zz PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
+//zz PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
+//zz PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
+//zz }
+//zz
+//zz POST(sys_stat64)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+//zz }
+//zz
+//zz PRE(sys_lstat64)
+//zz {
+//zz PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
+//zz PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
+//zz PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
+//zz PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
+//zz }
+//zz
+//zz POST(sys_lstat64)
+//zz {
+//zz vg_assert(SUCCESS);
+//zz if (RES == 0) {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+//zz }
+//zz }
+//zz
+//zz PRE(sys_fstat64)
+//zz {
+//zz PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
+//zz PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
+//zz PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
+//zz }
+//zz
+//zz POST(sys_fstat64)
+//zz {
+//zz POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+//zz }
+//zz
+//zz static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
+//zz {
+//zz Addr* a_p = (Addr*)a;
+//zz PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
+//zz return *a_p;
+//zz }
+//zz
+//zz PRE(sys_ipc)
+//zz {
+//zz PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
+//zz // XXX: this is simplistic -- some args are not used in all circumstances.
+//zz PRE_REG_READ6(int, "ipc",
+//zz vki_uint, call, int, first, int, second, int, third,
+//zz void *, ptr, long, fifth)
+//zz
+//zz switch (ARG1 /* call */) {
+//zz case VKI_SEMOP:
+//zz ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
+//zz *flags |= SfMayBlock;
+//zz break;
+//zz case VKI_SEMGET:
+//zz break;
+//zz case VKI_SEMCTL:
+//zz {
+//zz UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
+//zz ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
+//zz break;
+//zz }
+//zz case VKI_SEMTIMEDOP:
+//zz ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
+//zz *flags |= SfMayBlock;
+//zz break;
+//zz case VKI_MSGSND:
+//zz ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
+//zz if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+//zz *flags |= SfMayBlock;
+//zz break;
+//zz case VKI_MSGRCV:
+//zz {
+//zz Addr msgp;
+//zz Word msgtyp;
+//zz
+//zz msgp = deref_Addr( tid,
+//zz (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
+//zz "msgrcv(msgp)" );
+//zz msgtyp = deref_Addr( tid,
+//zz (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
+//zz "msgrcv(msgp)" );
+//zz
+//zz ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
+//zz
+//zz if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+//zz *flags |= SfMayBlock;
+//zz break;
+//zz }
+//zz case VKI_MSGGET:
+//zz break;
+//zz case VKI_MSGCTL:
+//zz ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
+//zz break;
+//zz case VKI_SHMAT:
+//zz {
+//zz UWord w;
+//zz PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
+//zz w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
+//zz if (w == 0)
+//zz SET_STATUS_Failure( VKI_EINVAL );
+//zz else
+//zz ARG5 = w;
+//zz break;
+//zz }
+//zz case VKI_SHMDT:
+//zz if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
+//zz SET_STATUS_Failure( VKI_EINVAL );
+//zz break;
+//zz case VKI_SHMGET:
+//zz break;
+//zz case VKI_SHMCTL: /* IPCOP_shmctl */
+//zz ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
+//zz break;
+//zz default:
+//zz VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %d", ARG1 );
+//zz VG_(core_panic)("... bye!\n");
+//zz break; /*NOTREACHED*/
+//zz }
+//zz }
+//zz
+//zz POST(sys_ipc)
+//zz {
+//zz vg_assert(SUCCESS);
+//zz switch (ARG1 /* call */) {
+//zz case VKI_SEMOP:
+//zz case VKI_SEMGET:
+//zz break;
+//zz case VKI_SEMCTL:
+//zz {
+//zz UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
+//zz ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
+//zz break;
+//zz }
+//zz case VKI_SEMTIMEDOP:
+//zz case VKI_MSGSND:
+//zz break;
+//zz case VKI_MSGRCV:
+//zz {
+//zz Addr msgp;
+//zz Word msgtyp;
+//zz
+//zz msgp = deref_Addr( tid,
+//zz (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
+//zz "msgrcv(msgp)" );
+//zz msgtyp = deref_Addr( tid,
+//zz (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
+//zz "msgrcv(msgp)" );
+//zz
+//zz ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
+//zz break;
+//zz }
+//zz case VKI_MSGGET:
+//zz break;
+//zz case VKI_MSGCTL:
+//zz ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
+//zz break;
+//zz case VKI_SHMAT:
+//zz {
+//zz Addr addr;
+//zz
+//zz /* force readability. before the syscall it is
+//zz * indeed uninitialized, as can be seen in
+//zz * glibc/sysdeps/unix/sysv/linux/shmat.c */
+//zz POST_MEM_WRITE( ARG4, sizeof( Addr ) );
+//zz
+//zz addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
+//zz if ( addr > 0 ) {
+//zz ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
+//zz }
+//zz break;
+//zz }
+//zz case VKI_SHMDT:
+//zz ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
+//zz break;
+//zz case VKI_SHMGET:
+//zz break;
+//zz case VKI_SHMCTL:
+//zz ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
+//zz break;
+//zz default:
+//zz VG_(message)(Vg_DebugMsg,
+//zz "FATAL: unhandled syscall(ipc) %d",
+//zz ARG1 );
+//zz VG_(core_panic)("... bye!\n");
+//zz break; /*NOTREACHED*/
+//zz }
+//zz }
+//zz
+//zz PRE(sys_clone)
+//zz {
+//zz UInt cloneflags;
+//zz
+//zz PRINT("sys_clone ( %x, %p, %p, %p, %p )",ARG1,ARG2,ARG3,ARG4,ARG5);
+//zz PRE_REG_READ5(int, "clone",
+//zz unsigned long, flags,
+//zz void *, child_stack,
+//zz int *, parent_tidptr,
+//zz void *, child_tls,
+//zz int *, child_tidptr);
+//zz
+//zz if (ARG1 & VKI_CLONE_PARENT_SETTID) {
+//zz PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
+//zz if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
+//zz VKI_PROT_WRITE)) {
+//zz SET_STATUS_Failure( VKI_EFAULT );
+//zz return;
+//zz }
+//zz }
+//zz if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
+//zz PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
+//zz if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
+//zz VKI_PROT_WRITE)) {
+//zz SET_STATUS_Failure( VKI_EFAULT );
+//zz return;
+//zz }
+//zz }
+//zz
+//zz cloneflags = ARG1;
+//zz
+//zz if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
+//zz SET_STATUS_Failure( VKI_EINVAL );
+//zz return;
+//zz }
+//zz
+//zz /* Only look at the flags we really care about */
+//zz switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
+//zz | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
+//zz case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
+//zz /* thread creation */
+//zz SET_STATUS_from_SysRes(
+//zz do_clone(tid,
+//zz ARG1, /* flags */
+//zz (Addr)ARG2, /* child SP */
+//zz (Int *)ARG3, /* parent_tidptr */
+//zz (Int *)ARG5, /* child_tidptr */
+//zz (Addr)ARG4)); /* child_tls */
+//zz break;
+//zz
+//zz case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
+//zz /* FALLTHROUGH - assume vfork == fork */
+//zz cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
+//zz
+//zz case 0: /* plain fork */
+//zz SET_STATUS_from_SysRes(
+//zz ML_(do_fork_clone)(tid,
+//zz cloneflags, /* flags */
+//zz (Int *)ARG3, /* parent_tidptr */
+//zz (Int *)ARG5)); /* child_tidptr */
+//zz break;
+//zz
+//zz default:
+//zz /* should we just ENOSYS? */
+//zz VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%x", ARG1);
+//zz VG_(message)(Vg_UserMsg, "");
+//zz VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
+//zz VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
+//zz VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
+//zz VG_(unimplemented)
+//zz ("Valgrind does not support general clone().");
+//zz }
+//zz
+//zz if (SUCCESS) {
+//zz if (ARG1 & VKI_CLONE_PARENT_SETTID)
+//zz POST_MEM_WRITE(ARG3, sizeof(Int));
+//zz if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
+//zz POST_MEM_WRITE(ARG5, sizeof(Int));
+//zz
+//zz /* Thread creation was successful; let the child have the chance
+//zz to run */
+//zz *flags |= SfYieldAfter;
+//zz }
+//zz }
+//zz
+//zz PRE(sys_sigreturn)
+//zz {
+//zz ThreadState* tst;
+//zz PRINT("sigreturn ( )");
+//zz
+//zz vg_assert(VG_(is_valid_tid)(tid));
+//zz vg_assert(tid >= 1 && tid < VG_N_THREADS);
+//zz vg_assert(VG_(is_running_thread)(tid));
+//zz
+//zz ///* Adjust esp to point to start of frame; skip back up over
+//zz // sigreturn sequence's "popl %eax" and handler ret addr */
+//zz tst = VG_(get_ThreadState)(tid);
+//zz //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
+//zz // Should we do something equivalent on ppc64? Who knows.
+//zz
+//zz ///* This is only so that the EIP is (might be) useful to report if
+//zz // something goes wrong in the sigreturn */
+//zz //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
+//zz // Should we do something equivalent on ppc64? Who knows.
+//zz
+//zz VG_(sigframe_destroy)(tid, False);
+//zz
+//zz /* For unclear reasons, it appears we need the syscall to return
+//zz without changing R3. Since R3 is the return value, and can
+//zz denote either success or failure, we must set up so that the
+//zz driver logic copies it back unchanged. Also, note R3 is of
+//zz the guest registers written by VG_(sigframe_destroy). */
+//zz /* jrs 16 Nov 05: for some reason this occasionally causes the
+//zz is-this-a-sane-error-value sanity check to fail:
+//zz m_syswrap/syswrap-ppc64-linux.c:1037
+//zz (vgSysWrap_ppc64_linux_sys_sigreturn_before):
+//zz Assertion 'wzz >= 0 && wzz < 10000' failed.
+//zz Hence use a sanity-check-free version.
+//zz Perhaps we should ignore CR0.S0 here?
+//zz In general I have no idea what this is for or if it is necessary.
+//zz It's a conceptual copy-n-paste from the x86 equivalent, but I'm
+//zz equally unclear as to whether it is needed there either.
+//zz */
+//zz SET_STATUS_from_SysRes_NO_SANITY_CHECK(
+//zz VG_(mk_SysRes_ppc64_linux)(
+//zz tst->arch.vex.guest_GPR3,
+//zz /* get CR0.SO */
+//zz (LibVEX_GuestPPC32_get_CR( &tst->arch.vex ) >> 28) & 1
+//zz )
+//zz );
+//zz
+//zz /* Check to see if some any signals arose as a result of this. */
+//zz *flags |= SfPollAfter;
+//zz }
+//zz
+//zz PRE(sys_rt_sigreturn)
+//zz {
+//zz ThreadState* tst;
+//zz PRINT("rt_sigreturn ( )");
+//zz
+//zz vg_assert(VG_(is_valid_tid)(tid));
+//zz vg_assert(tid >= 1 && tid < VG_N_THREADS);
+//zz vg_assert(VG_(is_running_thread)(tid));
+//zz
+//zz ///* Adjust esp to point to start of frame; skip back up over handler
+//zz // ret addr */
+//zz tst = VG_(get_ThreadState)(tid);
+//zz //tst->arch.vex.guest_ESP -= sizeof(Addr);
+//zz // Should we do something equivalent on ppc64? Who knows.
+//zz
+//zz ///* This is only so that the EIP is (might be) useful to report if
+//zz // something goes wrong in the sigreturn */
+//zz //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
+//zz // Should we do something equivalent on ppc64? Who knows.
+//zz
+//zz VG_(sigframe_destroy)(tid, True);
+//zz
+//zz /* See comments above in PRE(sys_sigreturn) about this. */
+//zz SET_STATUS_from_SysRes_NO_SANITY_CHECK(
+//zz VG_(mk_SysRes_ppc64_linux)(
+//zz tst->arch.vex.guest_GPR3,
+//zz /* get CR0.SO */
+//zz (LibVEX_GuestPPC32_get_CR( &tst->arch.vex ) >> 28) & 1
+//zz )
+//zz );
+//zz
+//zz /* Check to see if some any signals arose as a result of this. */
+//zz *flags |= SfPollAfter;
+//zz }
+//zz
+//zz /* Convert from non-RT to RT sigset_t's */
+//zz static
+//zz void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
+//zz {
+//zz VG_(sigemptyset)(set);
+//zz set->sig[0] = *oldset;
+//zz }
+//zz PRE(sys_sigaction)
+//zz {
+//zz struct vki_sigaction new, old;
+//zz struct vki_sigaction *newp, *oldp;
+//zz
+//zz PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz PRE_REG_READ3(int, "sigaction",
+//zz int, signum, const struct old_sigaction *, act,
+//zz struct old_sigaction *, oldact);
+//zz
+//zz newp = oldp = NULL;
+//zz
+//zz if (ARG2 != 0) {
+//zz struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
+//zz PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
+//zz PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
+//zz PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
+//zz if (ML_(safe_to_deref)(sa,sizeof(sa))
+//zz && (sa->sa_flags & VKI_SA_RESTORER))
+//zz PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
+//zz }
+//zz
+//zz if (ARG3 != 0) {
+//zz PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
+//zz oldp = &old;
+//zz }
+//zz
+//zz //jrs 20050207: what?! how can this make any sense?
+//zz //if (VG_(is_kerror)(SYSRES))
+//zz // return;
+//zz
+//zz if (ARG2 != 0) {
+//zz struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
+//zz
+//zz new.ksa_handler = oldnew->ksa_handler;
+//zz new.sa_flags = oldnew->sa_flags;
+//zz new.sa_restorer = oldnew->sa_restorer;
+//zz convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
+//zz newp = &new;
+//zz }
+//zz
+//zz SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
+//zz
+//zz if (ARG3 != 0 && SUCCESS && RES == 0) {
+//zz struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
+//zz
+//zz oldold->ksa_handler = oldp->ksa_handler;
+//zz oldold->sa_flags = oldp->sa_flags;
+//zz oldold->sa_restorer = oldp->sa_restorer;
+//zz oldold->sa_mask = oldp->sa_mask.sig[0];
+//zz }
+//zz }
+//zz
+//zz POST(sys_sigaction)
+//zz {
+//zz vg_assert(SUCCESS);
+//zz if (RES == 0 && ARG3 != 0)
+//zz POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
+//zz }
+
+#undef PRE
+#undef POST
+
+/* ---------------------------------------------------------------------
+ The ppc64/Linux syscall table
+ ------------------------------------------------------------------ */
+
+/* Add an ppc64-linux specific wrapper to a syscall table. */
+#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(ppc64_linux, sysno, name)
+#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(ppc64_linux, sysno, name)
+
+// This table maps from __NR_xxx syscall numbers (from
+// linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo()
+// wrappers on ppc64 (as per sys_call_table in linux/arch/ppc/kernel/entry.S).
+//
+// For those syscalls not handled by Valgrind, the annotation indicate its
+// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
+// (unknown).
+
+const SyscallTableEntry ML_(syscall_table)[] = {
+// _____(__NR_restart_syscall, sys__NR_restart_syscall), // 0
+// _____(__NR_exit, sys__NR_exit), // 1
+// _____(__NR_fork, sys__NR_fork), // 2
+// _____(__NR_read, sys__NR_read), // 3
+// _____(__NR_write, sys__NR_write), // 4
+
+// _____(__NR_open, sys__NR_open), // 5
+// _____(__NR_close, sys__NR_close), // 6
+// _____(__NR_waitpid, sys__NR_waitpid), // 7
+// _____(__NR_creat, sys__NR_creat), // 8
+// _____(__NR_link, sys__NR_link), // 9
+
+// _____(__NR_unlink, sys__NR_unlink), // 10
+// _____(__NR_execve, sys__NR_execve), // 11
+// _____(__NR_chdir, sys__NR_chdir), // 12
+// _____(__NR_time, sys__NR_time), // 13
+// _____(__NR_mknod, sys__NR_mknod), // 14
+
+// _____(__NR_chmod, sys__NR_chmod), // 15
+// _____(__NR_lchown, sys__NR_lchown), // 16
+// _____(__NR_break, sys__NR_break), // 17
+// _____(__NR_oldstat, sys__NR_oldstat), // 18
+// _____(__NR_lseek, sys__NR_lseek), // 19
+
+// _____(__NR_getpid, sys__NR_getpid), // 20
+// _____(__NR_mount, sys__NR_mount), // 21
+// _____(__NR_umount, sys__NR_umount), // 22
+// _____(__NR_setuid, sys__NR_setuid), // 23
+// _____(__NR_getuid, sys__NR_getuid), // 24
+
+// _____(__NR_stime, sys__NR_stime), // 25
+// _____(__NR_ptrace, sys__NR_ptrace), // 26
+// _____(__NR_alarm, sys__NR_alarm), // 27
+// _____(__NR_oldfstat, sys__NR_oldfstat), // 28
+// _____(__NR_pause, sys__NR_pause), // 29
+
+// _____(__NR_utime, sys__NR_utime), // 30
+// _____(__NR_stty, sys__NR_stty), // 31
+// _____(__NR_gtty, sys__NR_gtty), // 32
+// _____(__NR_access, sys__NR_access), // 33
+// _____(__NR_nice, sys__NR_nice), // 34
+
+// _____(__NR_ftime, sys__NR_ftime), // 35
+// _____(__NR_sync, sys__NR_sync), // 36
+// _____(__NR_kill, sys__NR_kill), // 37
+// _____(__NR_rename, sys__NR_rename), // 38
+// _____(__NR_mkdir, sys__NR_mkdir), // 39
+
+// _____(__NR_rmdir, sys__NR_rmdir), // 40
+// _____(__NR_dup, sys__NR_dup), // 41
+// _____(__NR_pipe, sys__NR_pipe), // 42
+// _____(__NR_times, sys__NR_times), // 43
+// _____(__NR_prof, sys__NR_prof), // 44
+
+// _____(__NR_brk, sys__NR_brk), // 45
+// _____(__NR_setgid, sys__NR_setgid), // 46
+// _____(__NR_getgid, sys__NR_getgid), // 47
+// _____(__NR_signal, sys__NR_signal), // 48
+// _____(__NR_geteuid, sys__NR_geteuid), // 49
+
+// _____(__NR_getegid, sys__NR_getegid), // 50
+// _____(__NR_acct, sys__NR_acct), // 51
+// _____(__NR_umount2, sys__NR_umount2), // 52
+// _____(__NR_lock, sys__NR_lock), // 53
+// _____(__NR_ioctl, sys__NR_ioctl), // 54
+
+// _____(__NR_fcntl, sys__NR_fcntl), // 55
+// _____(__NR_mpx, sys__NR_mpx), // 56
+// _____(__NR_setpgid, sys__NR_setpgid), // 57
+// _____(__NR_ulimit, sys__NR_ulimit), // 58
+// _____(__NR_oldolduname, sys__NR_oldolduname), // 59
+
+// _____(__NR_umask, sys__NR_umask), // 60
+// _____(__NR_chroot, sys__NR_chroot), // 61
+// _____(__NR_ustat, sys__NR_ustat), // 62
+// _____(__NR_dup2, sys__NR_dup2), // 63
+// _____(__NR_getppid, sys__NR_getppid), // 64
+
+// _____(__NR_getpgrp, sys__NR_getpgrp), // 65
+// _____(__NR_setsid, sys__NR_setsid), // 66
+// _____(__NR_sigaction, sys__NR_sigaction), // 67
+// _____(__NR_sgetmask, sys__NR_sgetmask), // 68
+// _____(__NR_ssetmask, sys__NR_ssetmask), // 69
+
+// _____(__NR_setreuid, sys__NR_setreuid), // 70
+// _____(__NR_setregid, sys__NR_setregid), // 71
+// _____(__NR_sigsuspend, sys__NR_sigsuspend), // 72
+// _____(__NR_sigpending, sys__NR_sigpending), // 73
+// _____(__NR_sethostname, sys__NR_sethostname), // 74
+
+// _____(__NR_setrlimit, sys__NR_setrlimit), // 75
+// _____(__NR_getrlimit, sys__NR_getrlimit), // 76
+// _____(__NR_getrusage, sys__NR_getrusage), // 77
+// _____(__NR_gettimeofday, sys__NR_gettimeofday), // 78
+// _____(__NR_settimeofday, sys__NR_settimeofday), // 79
+
+// _____(__NR_getgroups, sys__NR_getgroups), // 80
+// _____(__NR_setgroups, sys__NR_setgroups), // 81
+// _____(__NR_select, sys__NR_select), // 82
+// _____(__NR_symlink, sys__NR_symlink), // 83
+// _____(__NR_oldlstat, sys__NR_oldlstat), // 84
+
+// _____(__NR_readlink, sys__NR_readlink), // 85
+// _____(__NR_uselib, sys__NR_uselib), // 86
+// _____(__NR_swapon, sys__NR_swapon), // 87
+// _____(__NR_reboot, sys__NR_reboot), // 88
+// _____(__NR_readdir, sys__NR_readdir), // 89
+
+// _____(__NR_mmap, sys__NR_mmap), // 90
+// _____(__NR_munmap, sys__NR_munmap), // 91
+// _____(__NR_truncate, sys__NR_truncate), // 92
+// _____(__NR_ftruncate, sys__NR_ftruncate), // 93
+// _____(__NR_fchmod, sys__NR_fchmod), // 94
+
+// _____(__NR_fchown, sys__NR_fchown), // 95
+// _____(__NR_getpriority, sys__NR_getpriority), // 96
+// _____(__NR_setpriority, sys__NR_setpriority), // 97
+// _____(__NR_profil, sys__NR_profil), // 98
+// _____(__NR_statfs, sys__NR_statfs), // 99
+
+// _____(__NR_fstatfs, sys__NR_fstatfs), // 100
+// _____(__NR_ioperm, sys__NR_ioperm), // 101
+// _____(__NR_socketcall, sys__NR_socketcall), // 102
+// _____(__NR_syslog, sys__NR_syslog), // 103
+// _____(__NR_setitimer, sys__NR_setitimer), // 104
+
+// _____(__NR_getitimer, sys__NR_getitimer), // 105
+// _____(__NR_stat, sys__NR_stat), // 106
+// _____(__NR_lstat, sys__NR_lstat), // 107
+// _____(__NR_fstat, sys__NR_fstat), // 108
+// _____(__NR_olduname, sys__NR_olduname), // 109
+
+// _____(__NR_iopl, sys__NR_iopl), // 110
+// _____(__NR_vhangup, sys__NR_vhangup), // 111
+// _____(__NR_idle, sys__NR_idle), // 112
+// _____(__NR_vm86, sys__NR_vm86), // 113
+// _____(__NR_wait4, sys__NR_wait4), // 114
+
+// _____(__NR_swapoff, sys__NR_swapoff), // 115
+// _____(__NR_sysinfo, sys__NR_sysinfo), // 116
+// _____(__NR_ipc, sys__NR_ipc), // 117
+// _____(__NR_fsync, sys__NR_fsync), // 118
+// _____(__NR_sigreturn, sys__NR_sigreturn), // 119
+
+// _____(__NR_clone, sys__NR_clone), // 120
+// _____(__NR_setdomainname, sys__NR_setdomainname), // 121
+// _____(__NR_uname, sys__NR_uname), // 122
+// _____(__NR_modify_ldt, sys__NR_modify_ldt), // 123
+// _____(__NR_adjtimex, sys__NR_adjtimex), // 124
+
+// _____(__NR_mprotect, sys__NR_mprotect), // 125
+// _____(__NR_sigprocmask, sys__NR_sigprocmask), // 126
+// _____(__NR_create_module, sys__NR_create_module), // 127
+// _____(__NR_init_module, sys__NR_init_module), // 128
+// _____(__NR_delete_module, sys__NR_delete_module), // 129
+
+// _____(__NR_get_kernel_syms, sys__NR_get_kernel_syms), // 130
+// _____(__NR_quotactl, sys__NR_quotactl), // 131
+// _____(__NR_getpgid, sys__NR_getpgid), // 132
+// _____(__NR_fchdir, sys__NR_fchdir), // 133
+// _____(__NR_bdflush, sys__NR_bdflush), // 134
+
+// _____(__NR_sysfs, sys__NR_sysfs), // 135
+// _____(__NR_personality, sys__NR_personality), // 136
+// _____(__NR_afs_syscall, sys__NR_afs_syscall), // 137
+// _____(__NR_setfsuid, sys__NR_setfsuid), // 138
+// _____(__NR_setfsgid, sys__NR_setfsgid), // 139
+
+// _____(__NR__llseek, sys__NR__llseek), // 140
+// _____(__NR_getdents, sys__NR_getdents), // 141
+// _____(__NR__newselect, sys__NR__newselect), // 142
+// _____(__NR_flock, sys__NR_flock), // 143
+// _____(__NR_msync, sys__NR_msync), // 144
+
+// _____(__NR_readv, sys__NR_readv), // 145
+// _____(__NR_writev, sys__NR_writev), // 146
+// _____(__NR_getsid, sys__NR_getsid), // 147
+// _____(__NR_fdatasync, sys__NR_fdatasync), // 148
+// _____(__NR__sysctl, sys__NR__sysctl), // 149
+
+// _____(__NR_mlock, sys__NR_mlock), // 150
+// _____(__NR_munlock, sys__NR_munlock), // 151
+// _____(__NR_mlockall, sys__NR_mlockall), // 152
+// _____(__NR_munlockall, sys__NR_munlockall), // 153
+// _____(__NR_sched_setparam, sys__NR_sched_setparam), // 154
+
+// _____(__NR_sched_getparam, sys__NR_sched_getparam), // 155
+// _____(__NR_sched_setscheduler, sys__NR_sched_setscheduler), // 156
+// _____(__NR_sched_getscheduler, sys__NR_sched_getscheduler), // 157
+// _____(__NR_sched_yield, sys__NR_sched_yield), // 158
+// _____(__NR_sched_get_priority_max, sys__NR_sched_get_priority_max), // 159
+
+// _____(__NR_sched_get_priority_min, sys__NR_sched_get_priority_min), // 160
+// _____(__NR_sched_rr_get_interval, sys__NR_sched_rr_get_interval), // 161
+// _____(__NR_nanosleep, sys__NR_nanosleep), // 162
+// _____(__NR_mremap, sys__NR_mremap), // 163
+// _____(__NR_setresuid, sys__NR_setresuid), // 164
+
+// _____(__NR_getresuid, sys__NR_getresuid), // 165
+// _____(__NR_query_module, sys__NR_query_module), // 166
+// _____(__NR_poll, sys__NR_poll), // 167
+// _____(__NR_nfsservctl, sys__NR_nfsservctl), // 168
+// _____(__NR_setresgid, sys__NR_setresgid), // 169
+
+// _____(__NR_getresgid, sys__NR_getresgid), // 170
+// _____(__NR_prctl, sys__NR_prctl), // 171
+// _____(__NR_rt_sigreturn, sys__NR_rt_sigreturn), // 172
+// _____(__NR_rt_sigaction, sys__NR_rt_sigaction), // 173
+// _____(__NR_rt_sigprocmask, sys__NR_rt_sigprocmask), // 174
+
+// _____(__NR_rt_sigpending, sys__NR_rt_sigpending), // 175
+// _____(__NR_rt_sigtimedwait, sys__NR_rt_sigtimedwait), // 176
+// _____(__NR_rt_sigqueueinfo, sys__NR_rt_sigqueueinfo), // 177
+// _____(__NR_rt_sigsuspend, sys__NR_rt_sigsuspend), // 178
+// _____(__NR_pread64, sys__NR_pread64), // 179
+
+// _____(__NR_pwrite64, sys__NR_pwrite64), // 180
+// _____(__NR_chown, sys__NR_chown), // 181
+// _____(__NR_getcwd, sys__NR_getcwd), // 182
+// _____(__NR_capget, sys__NR_capget), // 183
+// _____(__NR_capset, sys__NR_capset), // 184
+
+// _____(__NR_sigaltstack, sys__NR_sigaltstack), // 185
+// _____(__NR_sendfile, sys__NR_sendfile), // 186
+// _____(__NR_getpmsg, sys__NR_getpmsg), // 187
+// _____(__NR_putpmsg, sys__NR_putpmsg), // 188
+// _____(__NR_vfork, sys__NR_vfork), // 189
+
+// _____(__NR_ugetrlimit, sys__NR_ugetrlimit), // 190
+// _____(__NR_readahead, sys__NR_readahead), // 191
+// /* #define __NR_mmap2 192 32bit only */
+// /* #define __NR_truncate64 193 32bit only */
+// /* #define __NR_ftruncate64 194 32bit only */
+
+// /* #define __NR_stat64 195 32bit only */
+// /* #define __NR_lstat64 196 32bit only */
+// /* #define __NR_fstat64 197 32bit only */
+// _____(__NR_pciconfig_read, sys__NR_pciconfig_read), // 198
+// _____(__NR_pciconfig_write, sys__NR_pciconfig_write), // 199
+
+// _____(__NR_pciconfig_iobase, sys__NR_pciconfig_iobase), // 200
+// _____(__NR_multiplexer, sys__NR_multiplexer), // 201
+// _____(__NR_getdents64, sys__NR_getdents64), // 202
+// _____(__NR_pivot_root, sys__NR_pivot_root), // 203
+// /* #define __NR_fcntl64 204 32bit only */
+
+// _____(__NR_madvise, sys__NR_madvise), // 205
+// _____(__NR_mincore, sys__NR_mincore), // 206
+// _____(__NR_gettid, sys__NR_gettid), // 207
+// _____(__NR_tkill, sys__NR_tkill), // 208
+// _____(__NR_setxattr, sys__NR_setxattr), // 209
+
+// _____(__NR_lsetxattr, sys__NR_lsetxattr), // 210
+// _____(__NR_fsetxattr, sys__NR_fsetxattr), // 211
+// _____(__NR_getxattr, sys__NR_getxattr), // 212
+// _____(__NR_lgetxattr, sys__NR_lgetxattr), // 213
+// _____(__NR_fgetxattr, sys__NR_fgetxattr), // 214
+
+// _____(__NR_listxattr, sys__NR_listxattr), // 215
+// _____(__NR_llistxattr, sys__NR_llistxattr), // 216
+// _____(__NR_flistxattr, sys__NR_flistxattr), // 217
+// _____(__NR_removexattr, sys__NR_removexattr), // 218
+// _____(__NR_lremovexattr, sys__NR_lremovexattr), // 219
+
+// _____(__NR_fremovexattr, sys__NR_fremovexattr), // 220
+// _____(__NR_futex, sys__NR_futex), // 221
+// _____(__NR_sched_setaffinity, sys__NR_sched_setaffinity), // 222
+// _____(__NR_sched_getaffinity, sys__NR_sched_getaffinity), // 223
+// /* 224 currently unused */
+
+// _____(__NR_tuxcall, sys__NR_tuxcall), // 225
+// /* #define __NR_sendfile64 226 32bit only */
+// _____(__NR_io_setup, sys__NR_io_setup), // 227
+// _____(__NR_io_destroy, sys__NR_io_destroy), // 228
+// _____(__NR_io_getevents, sys__NR_io_getevents), // 229
+
+// _____(__NR_io_submit, sys__NR_io_submit), // 230
+// _____(__NR_io_cancel, sys__NR_io_cancel), // 231
+// _____(__NR_set_tid_address, sys__NR_set_tid_address), // 232
+// _____(__NR_fadvise64, sys__NR_fadvise64), // 233
+// _____(__NR_exit_group, sys__NR_exit_group), // 234
+
+// _____(__NR_lookup_dcookie, sys__NR_lookup_dcookie), // 235
+// _____(__NR_epoll_create, sys__NR_epoll_create), // 236
+// _____(__NR_epoll_ctl, sys__NR_epoll_ctl), // 237
+// _____(__NR_epoll_wait, sys__NR_epoll_wait), // 238
+// _____(__NR_remap_file_pages, sys__NR_remap_file_pages), // 239
+
+// _____(__NR_timer_create, sys__NR_timer_create), // 240
+// _____(__NR_timer_settime, sys__NR_timer_settime), // 241
+// _____(__NR_timer_gettime, sys__NR_timer_gettime), // 242
+// _____(__NR_timer_getoverrun, sys__NR_timer_getoverrun), // 243
+// _____(__NR_timer_delete, sys__NR_timer_delete), // 244
+
+// _____(__NR_clock_settime, sys__NR_clock_settime), // 245
+// _____(__NR_clock_gettime, sys__NR_clock_gettime), // 246
+// _____(__NR_clock_getres, sys__NR_clock_getres), // 247
+// _____(__NR_clock_nanosleep, sys__NR_clock_nanosleep), // 248
+// _____(__NR_swapcontext, sys__NR_swapcontext), // 249
+
+// _____(__NR_tgkill, sys__NR_tgkill), // 250
+// _____(__NR_utimes, sys__NR_utimes), // 251
+// _____(__NR_statfs64, sys__NR_statfs64), // 252
+// _____(__NR_fstatfs64, sys__NR_fstatfs64), // 253
+// /* #define __NR_fadvise64_64 254 32bit only */
+
+// _____(__NR_rtas, sys__NR_rtas), // 255
+// /* Number 256 is reserved for sys_debug_setcontext */
+// /* Number 257 is reserved for vserver */
+// /* 258 currently unused */
+// _____(__NR_mbind, sys__NR_mbind), // 259
+
+// _____(__NR_get_mempolicy, sys__NR_get_mempolicy), // 260
+// _____(__NR_set_mempolicy, sys__NR_set_mempolicy), // 261
+// _____(__NR_mq_open, sys__NR_mq_open), // 262
+// _____(__NR_mq_unlink, sys__NR_mq_unlink), // 263
+// _____(__NR_mq_timedsend, sys__NR_mq_timedsend), // 264
+
+// _____(__NR_mq_timedreceive, sys__NR_mq_timedreceive), // 265
+// _____(__NR_mq_notify, sys__NR_mq_notify), // 266
+// _____(__NR_mq_getsetattr, sys__NR_mq_getsetattr), // 267
+// _____(__NR_kexec_load, sys__NR_kexec_load), // 268
+// _____(__NR_add_key, sys__NR_add_key), // 269
+
+// _____(__NR_request_key, sys__NR_request_key), // 270
+// _____(__NR_keyctl, sys__NR_keyctl), // 271
+// _____(__NR_waitid, sys__NR_waitid), // 272
+// _____(__NR_ioprio_set, sys__NR_ioprio_set), // 273
+// _____(__NR_ioprio_get, sys__NR_ioprio_get), // 274
+
+// _____(__NR_inotify_init, sys__NR_inotify_init), // 275
+// _____(__NR_inotify_add_watch, sys__NR_inotify_add_watch), // 276
+// _____(__NR_inotify_rm_watch, sys__NR_inotify_rm_watch) // 277
+};
+
+const UInt ML_(syscall_table_size) =
+ sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S
index e4930f9..8423fed 100644
--- a/coregrind/m_trampoline.S
+++ b/coregrind/m_trampoline.S
@@ -283,6 +283,31 @@
# undef UD2_1024
# undef UD2_PAGE
+/*---------------- ppc64-linux ----------------*/
+#else
+#if defined(VGP_ppc64_linux)
+
+# define UD2_16 trap ; trap ; trap; trap
+# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
+# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
+# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
+# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
+
+ /* a leading page of unexecutable code */
+ UD2_PAGE
+
+.global VG_(trampoline_stuff_start)
+VG_(trampoline_stuff_start):
+
+.global VG_(trampoline_stuff_end)
+VG_(trampoline_stuff_end):
+
+# undef UD2_16
+# undef UD2_64
+# undef UD2_256
+# undef UD2_1024
+# undef UD2_PAGE
+
/*---------------- unknown ----------------*/
#else
# error Unknown platform
@@ -290,6 +315,7 @@
#endif
#endif
#endif
+#endif
/* Let the linker know we don't need an executable stack */
diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c
index bf57d09..d8f671a 100644
--- a/coregrind/m_transtab.c
+++ b/coregrind/m_transtab.c
@@ -734,7 +734,7 @@
static void invalidate_icache ( void *ptr, Int nbytes )
{
-# if defined(VGA_ppc32)
+# if defined(VGA_ppc32) || defined(VGA_ppc64)
Addr startaddr = (Addr) ptr;
Addr endaddr = startaddr + nbytes;
Addr cls;
diff --git a/coregrind/pub_core_basics.h b/coregrind/pub_core_basics.h
index c421b84..160add6 100644
--- a/coregrind/pub_core_basics.h
+++ b/coregrind/pub_core_basics.h
@@ -55,6 +55,8 @@
# include "libvex_guest_amd64.h"
#elif defined(VGA_ppc32)
# include "libvex_guest_ppc32.h"
+#elif defined(VGA_ppc64)
+# include "libvex_guest_ppc64.h"
#else
# error Unknown arch
#endif
diff --git a/coregrind/pub_core_machine.h b/coregrind/pub_core_machine.h
index 389f757..1b68204 100644
--- a/coregrind/pub_core_machine.h
+++ b/coregrind/pub_core_machine.h
@@ -51,6 +51,10 @@
# define VG_ELF_DATA2XXX ELFDATA2MSB
# define VG_ELF_MACHINE EM_PPC
# define VG_ELF_CLASS ELFCLASS32
+#elif defined(VGA_ppc64)
+# define VG_ELF_DATA2XXX ELFDATA2MSB
+# define VG_ELF_MACHINE EM_PPC64
+# define VG_ELF_CLASS ELFCLASS64
#else
# error Unknown arch
#endif
@@ -67,6 +71,10 @@
# define VG_INSTR_PTR guest_CIA
# define VG_STACK_PTR guest_GPR1
# define VG_FRAME_PTR guest_GPR1 // No frame ptr for PPC
+#elif defined(VGA_ppc64)
+# define VG_INSTR_PTR guest_CIA
+# define VG_STACK_PTR guest_GPR1
+# define VG_FRAME_PTR guest_GPR1 // No frame ptr for PPC
#else
# error Unknown arch
#endif
@@ -100,6 +108,12 @@
then safe to use VG_(machine_get_VexArchInfo)
and VG_(machine_ppc32_has_FP)
and VG_(machine_ppc32_has_VMX)
+ -------------
+ ppc64: initially: call VG_(machine_get_hwcaps)
+ call VG_(machine_ppc64_set_clszB)
+
+ then safe to use VG_(machine_get_VexArchInfo)
+ and VG_(machine_ppc64_has_VMX)
VG_(machine_get_hwcaps) may use signals (although it attempts to
leave signal state unchanged) and therefore should only be
@@ -120,6 +134,10 @@
extern void VG_(machine_ppc32_set_clszB)( Int );
#endif
+#if defined(VGA_ppc64)
+extern void VG_(machine_ppc64_set_clszB)( Int );
+#endif
+
/* X86: set to 1 if the host is able to do {ld,st}mxcsr (load/store
the SSE control/status register), else zero. Is referenced from
assembly code, so do not change from a 32-bit int. */
@@ -141,6 +159,13 @@
extern UInt VG_(machine_ppc32_has_VMX);
#endif
+/* PPC64: set to 1 if Altivec instructions are supported in
+ user-space, else 0. Is referenced from assembly code, so do not
+ change from a 64-bit int. */
+#if defined(VGA_ppc64)
+extern ULong VG_(machine_ppc64_has_VMX);
+#endif
+
#endif // __PUB_CORE_MACHINE_H
/*--------------------------------------------------------------------*/
diff --git a/coregrind/pub_core_syscall.h b/coregrind/pub_core_syscall.h
index f5c7628..1fef4d9 100644
--- a/coregrind/pub_core_syscall.h
+++ b/coregrind/pub_core_syscall.h
@@ -61,9 +61,10 @@
#define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),\
(c),(d),(e),(f))
-extern SysRes VG_(mk_SysRes_x86_linux) ( Word val );
-extern SysRes VG_(mk_SysRes_amd64_linux) ( Word val );
-extern SysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so );
+extern SysRes VG_(mk_SysRes_x86_linux) ( UInt val );
+extern SysRes VG_(mk_SysRes_amd64_linux) ( ULong val );
+extern SysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so );
+extern SysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong cr0so );
extern SysRes VG_(mk_SysRes_Error) ( UWord val );
extern SysRes VG_(mk_SysRes_Success) ( UWord val );
diff --git a/coregrind/pub_core_threadstate.h b/coregrind/pub_core_threadstate.h
index e58e032..c4dd5f7 100644
--- a/coregrind/pub_core_threadstate.h
+++ b/coregrind/pub_core_threadstate.h
@@ -81,6 +81,8 @@
typedef VexGuestAMD64State VexGuestArchState;
#elif defined(VGA_ppc32)
typedef VexGuestPPC32State VexGuestArchState;
+#elif defined(VGA_ppc64)
+ typedef VexGuestPPC64State VexGuestArchState;
#else
# error Unknown architecture
#endif
diff --git a/coregrind/vki_unistd-ppc64-linux.h b/coregrind/vki_unistd-ppc64-linux.h
new file mode 100644
index 0000000..17f640c
--- /dev/null
+++ b/coregrind/vki_unistd-ppc64-linux.h
@@ -0,0 +1,312 @@
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2005 Julian Seward
+ jseward@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VKI_UNISTD_PPC64_LINUX_H
+#define __VKI_UNISTD_PPC64_LINUX_H
+
+// From linux-2.6.13/include/asm-ppc64/unistd.h
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_query_module 166
+#define __NR_poll 167
+#define __NR_nfsservctl 168
+#define __NR_setresgid 169
+#define __NR_getresgid 170
+#define __NR_prctl 171
+#define __NR_rt_sigreturn 172
+#define __NR_rt_sigaction 173
+#define __NR_rt_sigprocmask 174
+#define __NR_rt_sigpending 175
+#define __NR_rt_sigtimedwait 176
+#define __NR_rt_sigqueueinfo 177
+#define __NR_rt_sigsuspend 178
+#define __NR_pread64 179
+#define __NR_pwrite64 180
+#define __NR_chown 181
+#define __NR_getcwd 182
+#define __NR_capget 183
+#define __NR_capset 184
+#define __NR_sigaltstack 185
+#define __NR_sendfile 186
+#define __NR_getpmsg 187 /* some people actually want streams */
+#define __NR_putpmsg 188 /* some people actually want streams */
+#define __NR_vfork 189
+#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
+#define __NR_readahead 191
+/* #define __NR_mmap2 192 32bit only */
+/* #define __NR_truncate64 193 32bit only */
+/* #define __NR_ftruncate64 194 32bit only */
+/* #define __NR_stat64 195 32bit only */
+/* #define __NR_lstat64 196 32bit only */
+/* #define __NR_fstat64 197 32bit only */
+#define __NR_pciconfig_read 198
+#define __NR_pciconfig_write 199
+#define __NR_pciconfig_iobase 200
+#define __NR_multiplexer 201
+#define __NR_getdents64 202
+#define __NR_pivot_root 203
+/* #define __NR_fcntl64 204 32bit only */
+#define __NR_madvise 205
+#define __NR_mincore 206
+#define __NR_gettid 207
+#define __NR_tkill 208
+#define __NR_setxattr 209
+#define __NR_lsetxattr 210
+#define __NR_fsetxattr 211
+#define __NR_getxattr 212
+#define __NR_lgetxattr 213
+#define __NR_fgetxattr 214
+#define __NR_listxattr 215
+#define __NR_llistxattr 216
+#define __NR_flistxattr 217
+#define __NR_removexattr 218
+#define __NR_lremovexattr 219
+#define __NR_fremovexattr 220
+#define __NR_futex 221
+#define __NR_sched_setaffinity 222
+#define __NR_sched_getaffinity 223
+/* 224 currently unused */
+#define __NR_tuxcall 225
+/* #define __NR_sendfile64 226 32bit only */
+#define __NR_io_setup 227
+#define __NR_io_destroy 228
+#define __NR_io_getevents 229
+#define __NR_io_submit 230
+#define __NR_io_cancel 231
+#define __NR_set_tid_address 232
+#define __NR_fadvise64 233
+#define __NR_exit_group 234
+#define __NR_lookup_dcookie 235
+#define __NR_epoll_create 236
+#define __NR_epoll_ctl 237
+#define __NR_epoll_wait 238
+#define __NR_remap_file_pages 239
+#define __NR_timer_create 240
+#define __NR_timer_settime 241
+#define __NR_timer_gettime 242
+#define __NR_timer_getoverrun 243
+#define __NR_timer_delete 244
+#define __NR_clock_settime 245
+#define __NR_clock_gettime 246
+#define __NR_clock_getres 247
+#define __NR_clock_nanosleep 248
+#define __NR_swapcontext 249
+#define __NR_tgkill 250
+#define __NR_utimes 251
+#define __NR_statfs64 252
+#define __NR_fstatfs64 253
+/* #define __NR_fadvise64_64 254 32bit only */
+#define __NR_rtas 255
+/* Number 256 is reserved for sys_debug_setcontext */
+/* Number 257 is reserved for vserver */
+/* 258 currently unused */
+#define __NR_mbind 259
+#define __NR_get_mempolicy 260
+#define __NR_set_mempolicy 261
+#define __NR_mq_open 262
+#define __NR_mq_unlink 263
+#define __NR_mq_timedsend 264
+#define __NR_mq_timedreceive 265
+#define __NR_mq_notify 266
+#define __NR_mq_getsetattr 267
+#define __NR_kexec_load 268
+#define __NR_add_key 269
+#define __NR_request_key 270
+#define __NR_keyctl 271
+#define __NR_waitid 272
+#define __NR_ioprio_set 273
+#define __NR_ioprio_get 274
+#define __NR_inotify_init 275
+#define __NR_inotify_add_watch 276
+#define __NR_inotify_rm_watch 277
+
+
+#endif /* __VKI_UNISTD_PPC32_LINUX_H */
diff --git a/coregrind/vki_unistd.h b/coregrind/vki_unistd.h
index 4945cb0..934442d 100644
--- a/coregrind/vki_unistd.h
+++ b/coregrind/vki_unistd.h
@@ -38,6 +38,8 @@
# include "vki_unistd-amd64-linux.h"
#elif defined(VGP_ppc32_linux)
# include "vki_unistd-ppc32-linux.h"
+#elif defined(VGP_ppc64_linux)
+# include "vki_unistd-ppc64-linux.h"
#else
# error Unknown platform
#endif
diff --git a/helgrind/Makefile.am b/helgrind/Makefile.am
index 469a55e..cf47a01 100644
--- a/helgrind/Makefile.am
+++ b/helgrind/Makefile.am
@@ -10,6 +10,9 @@
if VG_PPC32_LINUX
noinst_PROGRAMS += helgrind-ppc32-linux vgpreload_helgrind-ppc32-linux.so
endif
+if VG_PPC64_LINUX
+noinst_PROGRAMS += helgrind-ppc64-linux vgpreload_helgrind-ppc64-linux.so
+endif
vgpreload_helgrind_x86_linux_so_SOURCES =
vgpreload_helgrind_x86_linux_so_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
@@ -35,6 +38,14 @@
$(PRELOAD_LDFLAGS_PPC32_LINUX) \
$(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX)
+vgpreload_helgrind_ppc64_linux_so_SOURCES =
+vgpreload_helgrind_ppc64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+vgpreload_helgrind_ppc64_linux_so_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_helgrind_ppc64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC64_LINUX)
+vgpreload_helgrind_ppc64_linux_so_LDFLAGS = \
+ $(PRELOAD_LDFLAGS_PPC64_LINUX) \
+ $(LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX)
+
HELGRIND_SOURCES_COMMON = hg_main.c
helgrind_x86_linux_SOURCES = $(HELGRIND_SOURCES_COMMON)
@@ -58,6 +69,13 @@
helgrind_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX)
helgrind_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX)
+helgrind_ppc64_linux_SOURCES = $(HELGRIND_SOURCES_COMMON)
+helgrind_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+helgrind_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX)
+helgrind_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX)
+helgrind_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX)
+helgrind_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX)
+
hgincludedir = $(includedir)/valgrind
hginclude_HEADERS = helgrind.h
diff --git a/include/Makefile.am b/include/Makefile.am
index b575825..5b9ed13 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -32,7 +32,9 @@
vki-linux.h \
vki-amd64-linux.h \
vki-ppc32-linux.h \
+ vki-ppc64-linux.h \
vki-x86-linux.h \
vki_posixtypes-amd64-linux.h \
vki_posixtypes-ppc32-linux.h \
+ vki_posixtypes-ppc64-linux.h \
vki_posixtypes-x86-linux.h
diff --git a/include/pub_tool_basics.h b/include/pub_tool_basics.h
index 2733007..4947d44 100644
--- a/include/pub_tool_basics.h
+++ b/include/pub_tool_basics.h
@@ -121,14 +121,14 @@
#if defined(VGA_x86) || defined(VGA_amd64)
# define VG_LITTLEENDIAN 1
-#elif defined(VGA_ppc32)
+#elif defined(VGA_ppc32) || defined(VGA_ppc64)
# define VG_BIGENDIAN 1
#endif
/* Regparmness */
#if defined(VGA_x86)
# define VG_REGPARM(n) __attribute__((regparm(n)))
-#elif defined(VGA_amd64) || defined(VGA_ppc32)
+#elif defined(VGA_amd64) || defined(VGA_ppc32) || defined(VGA_ppc64)
# define VG_REGPARM(n) /* */
#else
# error Unknown arch
diff --git a/include/pub_tool_machine.h b/include/pub_tool_machine.h
index b569e85..fe4d847 100644
--- a/include/pub_tool_machine.h
+++ b/include/pub_tool_machine.h
@@ -47,6 +47,11 @@
# define VG_MAX_INSTR_SZB 4
# define VG_CLREQ_SZB 24
# define VG_STACK_REDZONE_SZB 0
+#elif defined(VGA_ppc64)
+# define VG_MIN_INSTR_SZB 4
+# define VG_MAX_INSTR_SZB 4
+# define VG_CLREQ_SZB 24
+# define VG_STACK_REDZONE_SZB 0
#else
# error Unknown arch
#endif
diff --git a/include/valgrind.h b/include/valgrind.h
index a712085..ff7fd72 100644
--- a/include/valgrind.h
+++ b/include/valgrind.h
@@ -81,7 +81,9 @@
/* If we're not compiling for our target architecture, don't generate
any inline asms. Note that in this file we're using the compiler's
CPP symbols for identifying architectures, which are different to
- the ones we use within the rest of Valgrind. */
+ the ones we use within the rest of Valgrind. Note, __powerpc__ is
+ active for both 32 and 64-bit PPC, whereas __powerpc64__ is only
+ active for the latter. */
#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__)
# ifndef NVALGRIND
# define NVALGRIND 1
@@ -165,7 +167,7 @@
}
#endif /* __i386__ */
-#ifdef __powerpc__
+#if defined(__powerpc__) && !defined(__powerpc64__)
#define VALGRIND_MAGIC_SEQUENCE( \
_zzq_rlval, _zzq_default, _zzq_request, \
_zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
@@ -190,7 +192,34 @@
: "memory"); \
_zzq_rlval = (__typeof__(_zzq_rlval)) _zzq_tmp; \
}
-#endif /* __powerpc__ */
+#endif /* __powerpc__ 32-bit only */
+
+#if defined(__powerpc__) && defined(__powerpc64__)
+#define VALGRIND_MAGIC_SEQUENCE( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
+ \
+ { volatile unsigned long long int _zzq_args[5]; \
+ register unsigned long long int _zzq_tmp __asm__("r3"); \
+ register volatile unsigned long long int *_zzq_ptr __asm__("r4"); \
+ _zzq_args[0] = (volatile unsigned long long int)(_zzq_request); \
+ _zzq_args[1] = (volatile unsigned long long int)(_zzq_arg1); \
+ _zzq_args[2] = (volatile unsigned long long int)(_zzq_arg2); \
+ _zzq_args[3] = (volatile unsigned long long int)(_zzq_arg3); \
+ _zzq_args[4] = (volatile unsigned long long int)(_zzq_arg4); \
+ _zzq_ptr = _zzq_args; \
+ __asm__ volatile("tw 0,3,27\n\t" \
+ "rotldi 0,0,61\n\t" \
+ "rotldi 0,0,3\n\t" \
+ "rotldi 0,0,13\n\t" \
+ "rotldi 0,0,51\n\t" \
+ "nop\n\t" \
+ : "=r" (_zzq_tmp) \
+ : "0" (_zzq_default), "r" (_zzq_ptr) \
+ : "memory"); \
+ _zzq_rlval = (__typeof__(_zzq_rlval)) _zzq_tmp; \
+ }
+#endif /* __powerpc__ 64-bit only */
/* Insert assembly code for other architectures here... */
diff --git a/include/vki-linux.h b/include/vki-linux.h
index 1eb61d6..5232596 100644
--- a/include/vki-linux.h
+++ b/include/vki-linux.h
@@ -70,6 +70,8 @@
# include "vki_posixtypes-amd64-linux.h"
#elif defined(VGA_ppc32)
# include "vki_posixtypes-ppc32-linux.h"
+#elif defined(VGA_ppc64)
+# include "vki_posixtypes-ppc64-linux.h"
#else
# error Unknown platform
#endif
@@ -150,6 +152,8 @@
# include "vki-amd64-linux.h"
#elif defined(VGA_ppc32)
# include "vki-ppc32-linux.h"
+#elif defined(VGA_ppc64)
+# include "vki-ppc64-linux.h"
#else
# error Unknown platform
#endif
diff --git a/include/vki-ppc64-linux.h b/include/vki-ppc64-linux.h
new file mode 100644
index 0000000..1e8c1b0
--- /dev/null
+++ b/include/vki-ppc64-linux.h
@@ -0,0 +1,750 @@
+
+/*--------------------------------------------------------------------*/
+/*--- PPC64/Linux-specific kernel interface. ---*/
+/*--- ppc64-linux/vki-ppc64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2005 Julian Seward
+ jseward@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PPC64_LINUX_VKI_ARCH_H
+#define __PPC64_LINUX_VKI_ARCH_H
+
+// ppc64 is big-endian.
+#define VKI_BIG_ENDIAN 1
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/types.h
+//----------------------------------------------------------------------
+
+typedef __signed__ char __vki_s8;
+typedef unsigned char __vki_u8;
+
+typedef __signed__ short __vki_s16;
+typedef unsigned short __vki_u16;
+
+typedef __signed__ int __vki_s32;
+typedef unsigned int __vki_u32;
+
+typedef __signed__ long __vki_s64;
+typedef unsigned long __vki_u64;
+
+typedef struct {
+ __vki_u32 u[4];
+} __attribute((aligned(16))) __vki_vector128;
+
+typedef unsigned short vki_u16;
+
+typedef unsigned int vki_u32;
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/page.h
+//----------------------------------------------------------------------
+
+/* PAGE_SHIFT determines the page size */
+#define VKI_PAGE_SHIFT 12
+#define VKI_PAGE_SIZE (1UL << VKI_PAGE_SHIFT)
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/signal.h
+//----------------------------------------------------------------------
+
+#define VKI_MINSIGSTKSZ 2048
+
+/* Next 9 non-blank lines asm-generic/signal.h */
+#define VKI_SIG_BLOCK 0 /* for blocking signals */
+#define VKI_SIG_UNBLOCK 1 /* for unblocking signals */
+#define VKI_SIG_SETMASK 2 /* for setting the signal mask */
+
+typedef void __vki_signalfn_t(int);
+typedef __vki_signalfn_t __user *__vki_sighandler_t;
+
+typedef void __vki_restorefn_t(void);
+typedef __vki_restorefn_t __user *__vki_sigrestore_t;
+
+#define VKI_SIG_DFL ((__vki_sighandler_t)0) /* default signal handling */
+#define VKI_SIG_IGN ((__vki_sighandler_t)1) /* ignore signal */
+
+/* Back in asm-ppc64/signal.h */
+#define _VKI_NSIG 64
+#define _VKI_NSIG_BPW 64
+#define _VKI_NSIG_WORDS (_VKI_NSIG / _VKI_NSIG_BPW)
+
+typedef unsigned long vki_old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_VKI_NSIG_WORDS];
+} vki_sigset_t;
+
+#define VKI_SIGHUP 1
+#define VKI_SIGINT 2
+#define VKI_SIGQUIT 3
+#define VKI_SIGILL 4
+#define VKI_SIGTRAP 5
+#define VKI_SIGABRT 6
+#define VKI_SIGIOT 6
+#define VKI_SIGBUS 7
+#define VKI_SIGFPE 8
+#define VKI_SIGKILL 9
+#define VKI_SIGUSR1 10
+#define VKI_SIGSEGV 11
+#define VKI_SIGUSR2 12
+#define VKI_SIGPIPE 13
+#define VKI_SIGALRM 14
+#define VKI_SIGTERM 15
+#define VKI_SIGSTKFLT 16
+#define VKI_SIGCHLD 17
+#define VKI_SIGCONT 18
+#define VKI_SIGSTOP 19
+#define VKI_SIGTSTP 20
+#define VKI_SIGTTIN 21
+#define VKI_SIGTTOU 22
+#define VKI_SIGURG 23
+#define VKI_SIGXCPU 24
+#define VKI_SIGXFSZ 25
+#define VKI_SIGVTALRM 26
+#define VKI_SIGPROF 27
+#define VKI_SIGWINCH 28
+#define VKI_SIGIO 29
+#define VKI_SIGPOLL VKI_SIGIO
+#define VKI_SIGPWR 30
+#define VKI_SIGSYS 31
+#define VKI_SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define VKI_SIGRTMIN 32
+#define VKI_SIGRTMAX _VKI_NSIG
+
+#define VKI_SA_NOCLDSTOP 0x00000001u
+#define VKI_SA_NOCLDWAIT 0x00000002u
+#define VKI_SA_SIGINFO 0x00000004u
+#define VKI_SA_ONSTACK 0x08000000u
+#define VKI_SA_RESTART 0x10000000u
+#define VKI_SA_NODEFER 0x40000000u
+#define VKI_SA_RESETHAND 0x80000000u
+
+#define VKI_SA_NOMASK VKI_SA_NODEFER
+#define VKI_SA_ONESHOT VKI_SA_RESETHAND
+//#define VKI_SA_INTERRUPT 0x20000000u /* dummy -- ignored */
+
+#define VKI_SA_RESTORER 0x04000000u
+
+#define VKI_SS_ONSTACK 1
+#define VKI_SS_DISABLE 2
+
+// See comments on corresponding decls in vki-x86-linux.h re ksa_handler
+struct vki_old_sigaction {
+ __vki_sighandler_t ksa_handler;
+ vki_old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ __vki_sigrestore_t sa_restorer;
+};
+
+struct vki_sigaction {
+ __vki_sighandler_t ksa_handler;
+ unsigned long sa_flags;
+ __vki_sigrestore_t sa_restorer;
+ vki_sigset_t sa_mask; /* mask last for extensibility */
+};
+
+typedef struct vki_sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ vki_size_t ss_size;
+} vki_stack_t;
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/ptrace.h
+//----------------------------------------------------------------------
+
+#define VKI_PPC_REG unsigned long
+struct vki_pt_regs {
+ VKI_PPC_REG gpr[32];
+ VKI_PPC_REG nip;
+ VKI_PPC_REG msr;
+ VKI_PPC_REG orig_gpr3; /* Used for restarting system calls */
+ VKI_PPC_REG ctr;
+ VKI_PPC_REG link;
+ VKI_PPC_REG xer;
+ VKI_PPC_REG ccr;
+ VKI_PPC_REG softe; /* Soft enabled/disabled */
+ VKI_PPC_REG trap; /* Reason for being here */
+ VKI_PPC_REG dar; /* Fault registers */
+ VKI_PPC_REG dsisr;
+ VKI_PPC_REG result; /* Result of a system call */
+};
+
+/* Kludge? I don't know where this came from or if it is right. */
+#define vki_user_regs_struct vki_pt_regs
+
+#define VKI_PT_R0 0
+#define VKI_PT_R1 1
+#define VKI_PT_R2 2
+#define VKI_PT_R3 3
+#define VKI_PT_R4 4
+#define VKI_PT_R5 5
+#define VKI_PT_R6 6
+#define VKI_PT_R7 7
+#define VKI_PT_R8 8
+#define VKI_PT_R9 9
+#define VKI_PT_R10 10
+#define VKI_PT_R11 11
+#define VKI_PT_R12 12
+#define VKI_PT_R13 13
+#define VKI_PT_R14 14
+#define VKI_PT_R15 15
+#define VKI_PT_R16 16
+#define VKI_PT_R17 17
+#define VKI_PT_R18 18
+#define VKI_PT_R19 19
+#define VKI_PT_R20 20
+#define VKI_PT_R21 21
+#define VKI_PT_R22 22
+#define VKI_PT_R23 23
+#define VKI_PT_R24 24
+#define VKI_PT_R25 25
+#define VKI_PT_R26 26
+#define VKI_PT_R27 27
+#define VKI_PT_R28 28
+#define VKI_PT_R29 29
+#define VKI_PT_R30 30
+#define VKI_PT_R31 31
+#define VKI_PT_NIP 32
+#define VKI_PT_MSR 33
+#define VKI_PT_ORIG_R3 34
+#define VKI_PT_CTR 35
+#define VKI_PT_LNK 36
+#define VKI_PT_XER 37
+#define VKI_PT_CCR 38
+#define VKI_PT_SOFTE 39
+#define VKI_PT_RESULT 43
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/elf.h
+//----------------------------------------------------------------------
+
+#define VKI_ELF_NGREG 48 /* includes nip, msr, lr, etc. */
+#define VKI_ELF_NFPREG 33 /* includes fpscr */
+#define VKI_ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
+
+typedef unsigned long vki_elf_greg_t64;
+typedef vki_elf_greg_t64 vki_elf_gregset_t64[VKI_ELF_NGREG];
+
+typedef vki_elf_gregset_t64 vki_elf_gregset_t;
+
+typedef double vki_elf_fpreg_t;
+typedef vki_elf_fpreg_t vki_elf_fpregset_t[VKI_ELF_NFPREG];
+
+/* Altivec registers */
+/*
+ * The entries with indexes 0-31 contain the corresponding vector registers.
+ * The entry with index 32 contains the vscr as the last word (offset 12)
+ * within the quadword. This allows the vscr to be stored as either a
+ * quadword (since it must be copied via a vector register to/from storage)
+ * or as a word. The entry with index 33 contains the vrsave as the first
+ * word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the same
+ * structures. This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ *
+ * Note that it's _not_ compatible with 32 bits ucontext which stuffs the
+ * vrsave along with vscr and so only uses 33 vectors for the register set
+ */
+typedef __vki_vector128 vki_elf_vrreg_t;
+typedef vki_elf_vrreg_t vki_elf_vrregset_t[VKI_ELF_NVRREG];
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/sigcontext.h
+//----------------------------------------------------------------------
+
+struct vki_sigcontext {
+ unsigned long _unused[4];
+ int signal;
+ int _pad0;
+ unsigned long handler;
+ unsigned long oldmask;
+ struct vki_pt_regs __user *regs;
+ vki_elf_gregset_t gp_regs;
+ vki_elf_fpregset_t fp_regs;
+ /*
+ * To maintain compatibility with current implementations the sigcontext is
+ * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t)
+ * followed by an unstructured (vmx_reserve) field of 69 doublewords. This
+ * allows the array of vector registers to be quadword aligned independent of
+ * the alignment of the containing sigcontext or ucontext. It is the
+ * responsibility of the code setting the sigcontext to set this pointer to
+ * either NULL (if this processor does not support the VMX feature) or the
+ * address of the first quadword within the allocated (vmx_reserve) area.
+ *
+ * The pointer (v_regs) of vector type (elf_vrreg_t) is type compatible with
+ * an array of 34 quadword entries (elf_vrregset_t). The entries with
+ * indexes 0-31 contain the corresponding vector registers. The entry with
+ * index 32 contains the vscr as the last word (offset 12) within the
+ * quadword. This allows the vscr to be stored as either a quadword (since
+ * it must be copied via a vector register to/from storage) or as a word.
+ * The entry with index 33 contains the vrsave as the first word (offset 0)
+ * within the quadword.
+ */
+ vki_elf_vrreg_t __user *v_regs;
+ long vmx_reserve[VKI_ELF_NVRREG+VKI_ELF_NVRREG+1];
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/mman.h
+//----------------------------------------------------------------------
+
+#define VKI_PROT_NONE 0x0 /* page can not be accessed */
+#define VKI_PROT_READ 0x1 /* page can be read */
+#define VKI_PROT_WRITE 0x2 /* page can be written */
+#define VKI_PROT_EXEC 0x4 /* page can be executed */
+#define VKI_PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend
+ change to start of
+ growsdown vma */
+#define VKI_PROT_GROWSUP 0x02000000 /* mprotect flag: extend
+ change to end of
+ growsup vma */
+
+#define VKI_MAP_SHARED 0x01 /* Share changes */
+#define VKI_MAP_PRIVATE 0x02 /* Changes are private */
+#define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */
+#define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */
+#define VKI_MAP_NORESERVE 0x40 /* don't reserve swap pages */
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/fcntl.h
+//----------------------------------------------------------------------
+
+#define VKI_O_RDONLY 00
+#define VKI_O_WRONLY 01
+#define VKI_O_RDWR 02
+#define VKI_O_CREAT 0100 /* not fcntl */
+#define VKI_O_EXCL 0200 /* not fcntl */
+#define VKI_O_TRUNC 01000 /* not fcntl */
+#define VKI_O_APPEND 02000
+#define VKI_O_NONBLOCK 04000
+
+#define VKI_F_DUPFD 0 /* dup */
+#define VKI_F_GETFD 1 /* get close_on_exec */
+#define VKI_F_SETFD 2 /* set/clear close_on_exec */
+#define VKI_F_GETFL 3 /* get file->f_flags */
+#define VKI_F_SETFL 4 /* set file->f_flags */
+#define VKI_F_GETLK 5
+#define VKI_F_SETLK 6
+#define VKI_F_SETLKW 7
+
+#define VKI_F_SETOWN 8 /* for sockets. */
+#define VKI_F_GETOWN 9 /* for sockets. */
+#define VKI_F_SETSIG 10 /* for sockets. */
+#define VKI_F_GETSIG 11 /* for sockets. */
+
+/* for F_[GET|SET]FL */
+#define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+#define VKI_F_LINUX_SPECIFIC_BASE 1024
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/resource.h
+//----------------------------------------------------------------------
+
+// which just does #include <asm-generic/resource.h>
+
+#define VKI_RLIMIT_DATA 2 /* max data size */
+#define VKI_RLIMIT_STACK 3 /* max stack size */
+#define VKI_RLIMIT_CORE 4 /* max core file size */
+#define VKI_RLIMIT_NOFILE 7 /* max number of open files */
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/socket.h
+//----------------------------------------------------------------------
+
+#define VKI_SOL_SOCKET 1
+
+#define VKI_SO_TYPE 3
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/sockios.h
+//----------------------------------------------------------------------
+
+#define VKI_SIOCSPGRP 0x8902
+#define VKI_SIOCGPGRP 0x8904
+#define VKI_SIOCGSTAMP 0x8906 /* Get stamp */
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/stat.h
+//----------------------------------------------------------------------
+
+struct vki_stat {
+ unsigned long st_dev;
+ unsigned long st_ino;
+ unsigned short st_nlink;
+ unsigned short st_mode;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned long st_rdev;
+ long st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+ unsigned long __unused4;
+ unsigned long __unused5;
+ unsigned long __unused6;
+};
+
+#define VKI_STAT_HAVE_NSEC 1
+
+/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
+struct vki_stat64 {
+ unsigned long st_dev; /* Device. */
+ unsigned long st_ino; /* File serial number. */
+ unsigned int st_mode; /* File mode. */
+ unsigned int st_nlink; /* Link count. */
+ unsigned int st_uid; /* User ID of the file's owner. */
+ unsigned int st_gid; /* Group ID of the file's group. */
+ unsigned long st_rdev; /* Device number, if device. */
+ unsigned short __pad2;
+ long st_size; /* Size of file, in bytes. */
+ int st_blksize; /* Optimal block size for I/O. */
+
+ long st_blocks; /* Number 512-byte blocks allocated. */
+ int st_atime; /* Time of last access. */
+ int st_atime_nsec;
+ int st_mtime; /* Time of last modification. */
+ int st_mtime_nsec;
+ int st_ctime; /* Time of last status change. */
+ int st_ctime_nsec;
+ unsigned int __unused4;
+ unsigned int __unused5;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/statfs.h
+//----------------------------------------------------------------------
+
+struct vki_statfs {
+ long f_type;
+ long f_bsize;
+ long f_blocks;
+ long f_bfree;
+ long f_bavail;
+ long f_files;
+ long f_ffree;
+ __vki_kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/termios.h
+//----------------------------------------------------------------------
+
+struct vki_winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define VKI_NCC 10
+struct vki_termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[VKI_NCC]; /* control characters */
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/termbits.h
+//----------------------------------------------------------------------
+
+typedef unsigned char vki_cc_t;
+typedef unsigned int vki_speed_t;
+typedef unsigned int vki_tcflag_t;
+
+#define VKI_NCCS 19
+struct vki_termios {
+ vki_tcflag_t c_iflag; /* input mode flags */
+ vki_tcflag_t c_oflag; /* output mode flags */
+ vki_tcflag_t c_cflag; /* control mode flags */
+ vki_tcflag_t c_lflag; /* local mode flags */
+ vki_cc_t c_cc[VKI_NCCS]; /* control characters */
+ vki_cc_t c_line; /* line discipline (== c_cc[19]) */
+ vki_speed_t c_ispeed; /* input speed */
+ vki_speed_t c_ospeed; /* output speed */
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/ioctl.h
+//----------------------------------------------------------------------
+
+#define _VKI_IOC_NRBITS 8
+#define _VKI_IOC_TYPEBITS 8
+#define _VKI_IOC_SIZEBITS 13
+#define _VKI_IOC_DIRBITS 3
+
+#define _VKI_IOC_NRMASK ((1 << _VKI_IOC_NRBITS)-1)
+#define _VKI_IOC_TYPEMASK ((1 << _VKI_IOC_TYPEBITS)-1)
+#define _VKI_IOC_SIZEMASK ((1 << _VKI_IOC_SIZEBITS)-1)
+#define _VKI_IOC_DIRMASK ((1 << _VKI_IOC_DIRBITS)-1)
+
+#define _VKI_IOC_NRSHIFT 0
+#define _VKI_IOC_TYPESHIFT (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS)
+#define _VKI_IOC_SIZESHIFT (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS)
+#define _VKI_IOC_DIRSHIFT (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS)
+
+/*
+ * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
+ * And this turns out useful to catch old ioctl numbers in header
+ * files for us.
+ */
+#define _VKI_IOC_NONE 1U
+#define _VKI_IOC_READ 2U
+#define _VKI_IOC_WRITE 4U
+
+#define _VKI_IOC(dir,type,nr,size) \
+ (((dir) << _VKI_IOC_DIRSHIFT) | \
+ ((type) << _VKI_IOC_TYPESHIFT) | \
+ ((nr) << _VKI_IOC_NRSHIFT) | \
+ ((size) << _VKI_IOC_SIZESHIFT))
+
+/* provoke compile error for invalid uses of size argument */
+extern unsigned int __invalid_size_argument_for_IOC;
+#define _VKI_IOC_TYPECHECK(t) \
+ ((sizeof(t) == sizeof(t[1]) && \
+ sizeof(t) < (1 << _VKI_IOC_SIZEBITS)) ? \
+ sizeof(t) : __invalid_size_argument_for_IOC)
+
+/* used to create numbers */
+#define _VKI_IO(type,nr) _VKI_IOC(_VKI_IOC_NONE,(type),(nr),0)
+#define _VKI_IOR(type,nr,size) _VKI_IOC(_VKI_IOC_READ,(type),(nr), \
+ (_VKI_IOC_TYPECHECK(size)))
+#define _VKI_IOW(type,nr,size) _VKI_IOC(_VKI_IOC_WRITE,(type),(nr), \
+ (_VKI_IOC_TYPECHECK(size)))
+#define _VKI_IOWR(type,nr,size) _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE, \
+ (type),(nr),(_VKI_IOC_TYPECHECK(size)))
+#define _VKI_IOR_BAD(type,nr,size) _VKI_IOC(_VKI_IOC_READ,(type),(nr), \
+ sizeof(size))
+#define _VKI_IOW_BAD(type,nr,size) _VKI_IOC(_VKI_IOC_WRITE,(type),(nr), \
+ sizeof(size))
+#define _VKI_IOWR_BAD(type,nr,size) _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE, \
+ (type),(nr),sizeof(size))
+
+/* used to decode them.. */
+#define _VKI_IOC_DIR(nr) (((nr) >> _VKI_IOC_DIRSHIFT) & _VKI_IOC_DIRMASK)
+#define _VKI_IOC_TYPE(nr) (((nr) >> _VKI_IOC_TYPESHIFT) & _VKI_IOC_TYPEMASK)
+#define _VKI_IOC_NR(nr) (((nr) >> _VKI_IOC_NRSHIFT) & _VKI_IOC_NRMASK)
+#define _VKI_IOC_SIZE(nr) (((nr) >> _VKI_IOC_SIZESHIFT) & _VKI_IOC_SIZEMASK)
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/ioctls.h
+//----------------------------------------------------------------------
+
+#define VKI_TCGETS _VKI_IOR('t', 19, struct vki_termios)
+#define VKI_TCSETS _VKI_IOW('t', 20, struct vki_termios)
+#define VKI_TCSETSW _VKI_IOW('t', 21, struct vki_termios)
+#define VKI_TCSETSF _VKI_IOW('t', 22, struct vki_termios)
+#define VKI_TCGETA _VKI_IOR('t', 23, struct vki_termio)
+#define VKI_TCSETA _VKI_IOW('t', 24, struct vki_termio)
+#define VKI_TCSETAW _VKI_IOW('t', 25, struct vki_termio)
+#define VKI_TCSETAF _VKI_IOW('t', 28, struct vki_termio)
+#define VKI_TCSBRK _VKI_IO('t', 29)
+#define VKI_TCXONC _VKI_IO('t', 30)
+#define VKI_TCFLSH _VKI_IO('t', 31)
+#define VKI_TIOCSCTTY 0x540E
+#define VKI_TIOCGPGRP _VKI_IOR('t', 119, int)
+#define VKI_TIOCSPGRP _VKI_IOW('t', 118, int)
+#define VKI_TIOCOUTQ _VKI_IOR('t', 115, int) /* output queue size */
+#define VKI_TIOCGWINSZ _VKI_IOR('t', 104, struct vki_winsize)
+#define VKI_TIOCSWINSZ _VKI_IOW('t', 103, struct vki_winsize)
+#define VKI_TIOCMGET 0x5415
+#define VKI_TIOCMBIS 0x5416
+#define VKI_TIOCMBIC 0x5417
+#define VKI_TIOCMSET 0x5418
+#define VKI_FIONREAD _VKI_IOR('f', 127, int)
+#define VKI_TIOCLINUX 0x541C
+#define VKI_FIONBIO _VKI_IOW('f', 126, int)
+#define VKI_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+#define VKI_TIOCGPTN _VKI_IOR('T',0x30, unsigned int)
+ /* Get Pty Number (of pty-mux device) */
+#define VKI_TIOCSPTLCK _VKI_IOW('T',0x31, int) /* Lock/unlock Pty */
+#define VKI_FIOASYNC _VKI_IOW('f', 125, int)
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/poll.h
+//----------------------------------------------------------------------
+
+#define VKI_POLLIN 0x0001
+
+struct vki_pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/user.h
+//----------------------------------------------------------------------
+
+// Not sure what's needed from here
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/elf.h
+//----------------------------------------------------------------------
+
+// Not sure what's needed from here
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/ucontext.h
+//----------------------------------------------------------------------
+
+struct vki_ucontext {
+ unsigned long uc_flags;
+ struct vki_ucontext *uc_link;
+ vki_stack_t uc_stack;
+ vki_sigset_t uc_sigmask;
+ vki_sigset_t __unused[15]; /* Allow for uc_sigmask growth */
+ struct vki_sigcontext uc_mcontext; /* last for extensibility */
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/ipcbuf.h
+//----------------------------------------------------------------------
+
+struct vki_ipc64_perm
+{
+ __vki_kernel_key_t key;
+ __vki_kernel_uid_t uid;
+ __vki_kernel_gid_t gid;
+ __vki_kernel_uid_t cuid;
+ __vki_kernel_gid_t cgid;
+ __vki_kernel_mode_t mode;
+ unsigned int seq;
+ unsigned int __pad1;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/sembuf.h
+//----------------------------------------------------------------------
+
+struct vki_semid64_ds {
+ struct vki_ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __vki_kernel_time_t sem_otime; /* last semop time */
+ __vki_kernel_time_t sem_ctime; /* last change time */
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/msgbuf.h
+//----------------------------------------------------------------------
+
+struct vki_msqid64_ds {
+ struct vki_ipc64_perm msg_perm;
+ __vki_kernel_time_t msg_stime; /* last msgsnd time */
+ __vki_kernel_time_t msg_rtime; /* last msgrcv time */
+ __vki_kernel_time_t msg_ctime; /* last change time */
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __vki_kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __vki_kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/ipc.h
+//----------------------------------------------------------------------
+
+// this just does #include <asm-generic/ipc.h>
+
+struct vki_ipc_kludge {
+ struct vki_msgbuf __user *msgp;
+ long msgtyp;
+};
+
+#define VKI_SEMOP 1
+#define VKI_SEMGET 2
+#define VKI_SEMCTL 3
+#define VKI_SEMTIMEDOP 4
+#define VKI_MSGSND 11
+#define VKI_MSGRCV 12
+#define VKI_MSGGET 13
+#define VKI_MSGCTL 14
+#define VKI_SHMAT 21
+#define VKI_SHMDT 22
+#define VKI_SHMGET 23
+#define VKI_SHMCTL 24
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/shmbuf.h
+//----------------------------------------------------------------------
+
+struct vki_shmid64_ds {
+ struct vki_ipc64_perm shm_perm; /* operation perms */
+ __vki_kernel_time_t shm_atime; /* last attach time */
+ __vki_kernel_time_t shm_dtime; /* last detach time */
+ __vki_kernel_time_t shm_ctime; /* last change time */
+ vki_size_t shm_segsz; /* size of segment (bytes) */
+ __vki_kernel_pid_t shm_cpid; /* pid of creator */
+ __vki_kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+struct vki_shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+//----------------------------------------------------------------------
+// end
+//----------------------------------------------------------------------
+
+#endif // __PPC64_LINUX_VKI_ARCH_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
diff --git a/include/vki_posixtypes-ppc64-linux.h b/include/vki_posixtypes-ppc64-linux.h
new file mode 100644
index 0000000..d9d38cb
--- /dev/null
+++ b/include/vki_posixtypes-ppc64-linux.h
@@ -0,0 +1,75 @@
+
+/*--------------------------------------------------------------------*/
+/*--- PPC64/Linux-specific kernel interface: posix types. ---*/
+/*--- vki_posixtypes-ppc64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2005 Julian Seward
+ jseward@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PPC64_LINUX_VKI_ARCH_POSIXTYPES_H
+#define __PPC64_LINUX_VKI_ARCH_POSIXTYPES_H
+
+//----------------------------------------------------------------------
+// From linux-2.6.13/include/asm-ppc64/posix_types.h
+//----------------------------------------------------------------------
+
+typedef unsigned long __vki_kernel_ino_t;
+typedef unsigned long __vki_kernel_nlink_t;
+typedef unsigned int __vki_kernel_mode_t;
+typedef long __vki_kernel_off_t;
+typedef long long __vki_kernel_loff_t;
+typedef int __vki_kernel_pid_t;
+typedef int __vki_kernel_ipc_pid_t;
+typedef unsigned int __vki_kernel_uid_t;
+typedef unsigned int __vki_kernel_gid_t;
+typedef unsigned long __vki_kernel_size_t;
+typedef long __vki_kernel_ssize_t;
+typedef long __vki_kernel_ptrdiff_t;
+typedef long __vki_kernel_time_t;
+typedef int __vki_kernel_timer_t;
+typedef int __vki_kernel_clockid_t;
+typedef long __vki_kernel_suseconds_t;
+typedef long __vki_kernel_clock_t;
+typedef int __vki_kernel_daddr_t;
+typedef char * __vki_kernel_caddr_t;
+typedef unsigned short __vki_kernel_uid16_t;
+typedef unsigned short __vki_kernel_gid16_t;
+typedef unsigned int __vki_kernel_uid32_t;
+typedef unsigned int __vki_kernel_gid32_t;
+
+typedef unsigned int __vki_kernel_old_uid_t;
+typedef unsigned int __vki_kernel_old_gid_t;
+typedef unsigned long __vki_kernel_old_dev_t;
+
+typedef struct {
+ int val[2];
+} __vki_kernel_fsid_t;
+
+#endif // __PPC64_LINUX_VKI_ARCH_POSIXTYPES_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
diff --git a/lackey/Makefile.am b/lackey/Makefile.am
index b25f67a..50b1b07 100644
--- a/lackey/Makefile.am
+++ b/lackey/Makefile.am
@@ -10,6 +10,9 @@
if VG_PPC32_LINUX
noinst_PROGRAMS += lackey-ppc32-linux
endif
+if VG_PPC64_LINUX
+noinst_PROGRAMS += lackey-ppc64-linux
+endif
LACKEY_SOURCES_COMMON = lk_main.c
@@ -33,3 +36,10 @@
lackey_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
lackey_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX)
lackey_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX)
+
+lackey_ppc64_linux_SOURCES = $(LACKEY_SOURCES_COMMON)
+lackey_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+lackey_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX)
+lackey_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX)
+lackey_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX)
+lackey_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX)
diff --git a/massif/Makefile.am b/massif/Makefile.am
index ca30d72..39480dd 100644
--- a/massif/Makefile.am
+++ b/massif/Makefile.am
@@ -12,6 +12,9 @@
if VG_PPC32_LINUX
noinst_PROGRAMS += massif-ppc32-linux vgpreload_massif-ppc32-linux.so
endif
+if VG_PPC64_LINUX
+noinst_PROGRAMS += massif-ppc64-linux vgpreload_massif-ppc64-linux.so
+endif
vgpreload_massif_x86_linux_so_SOURCES =
vgpreload_massif_x86_linux_so_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
@@ -37,6 +40,14 @@
$(PRELOAD_LDFLAGS_PPC32_LINUX) \
$(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX)
+vgpreload_massif_ppc64_linux_so_SOURCES =
+vgpreload_massif_ppc64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+vgpreload_massif_ppc64_linux_so_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_massif_ppc64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC64_LINUX)
+vgpreload_massif_ppc64_linux_so_LDFLAGS = \
+ $(PRELOAD_LDFLAGS_PPC64_LINUX) \
+ $(LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX)
+
MASSIF_SOURCES_COMMON = ms_main.c
massif_x86_linux_SOURCES = $(MASSIF_SOURCES_COMMON)
@@ -59,3 +70,10 @@
massif_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
massif_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX)
massif_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX)
+
+massif_ppc64_linux_SOURCES = $(MASSIF_SOURCES_COMMON)
+massif_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+massif_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX)
+massif_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX)
+massif_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX)
+massif_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX)
diff --git a/memcheck/Makefile.am b/memcheck/Makefile.am
index a47a8e5..b003e4c 100644
--- a/memcheck/Makefile.am
+++ b/memcheck/Makefile.am
@@ -10,6 +10,9 @@
if VG_PPC32_LINUX
noinst_PROGRAMS += memcheck-ppc32-linux vgpreload_memcheck-ppc32-linux.so
endif
+if VG_PPC64_LINUX
+noinst_PROGRAMS += memcheck-ppc64-linux vgpreload_memcheck-ppc64-linux.so
+endif
VGPRELOAD_MEMCHECK_SOURCES_COMMON = mac_replace_strmem.c
@@ -40,6 +43,15 @@
$(PRELOAD_LDFLAGS_PPC32_LINUX) \
$(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX)
+vgpreload_memcheck_ppc64_linux_so_SOURCES = $(VGPRELOAD_MEMCHECK_SOURCES_COMMON)
+vgpreload_memcheck_ppc64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+vgpreload_memcheck_ppc64_linux_so_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) $(AM_CFLAGS_PIC) -O2
+vgpreload_memcheck_ppc64_linux_so_CCASFLAGS = $(AM_CCASFLAGS_PPC64_LINUX)
+vgpreload_memcheck_ppc64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC64_LINUX)
+vgpreload_memcheck_ppc64_linux_so_LDFLAGS = \
+ $(PRELOAD_LDFLAGS_PPC64_LINUX) \
+ $(LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX)
+
MEMCHECK_SOURCES_COMMON = \
mac_leakcheck.c \
mac_malloc_wrappers.c \
@@ -71,6 +83,14 @@
memcheck_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX)
memcheck_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX)
+memcheck_ppc64_linux_SOURCES = $(MEMCHECK_SOURCES_COMMON)
+memcheck_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+memcheck_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) -O2
+memcheck_ppc64_linux_CCASFLAGS = $(AM_CCASFLAGS_PPC64_LINUX)
+memcheck_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX)
+memcheck_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX)
+memcheck_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX)
+
mcincludedir = $(includedir)/valgrind
mcinclude_HEADERS = \
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 03b245c..3f424fd 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -8,6 +8,9 @@
if VG_PPC32_LINUX
SUBDIRS += ppc32
endif
+if VG_PPC64_LINUX
+SUBDIRS += ppc64
+endif
DIST_SUBDIRS = ${VG_ARCH_ALL} .
diff --git a/none/Makefile.am b/none/Makefile.am
index 01a501f..aa340bb 100644
--- a/none/Makefile.am
+++ b/none/Makefile.am
@@ -10,6 +10,9 @@
if VG_PPC32_LINUX
noinst_PROGRAMS += none-ppc32-linux
endif
+if VG_PPC64_LINUX
+noinst_PROGRAMS += none-ppc64-linux
+endif
NONE_SOURCES_COMMON = nl_main.c
@@ -33,3 +36,10 @@
none_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
none_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX)
none_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX)
+
+none_ppc64_linux_SOURCES = $(NONE_SOURCES_COMMON)
+none_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX)
+none_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX)
+none_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX)
+none_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX)
+none_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX)
diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am
index 3360c76..9668140 100644
--- a/none/tests/Makefile.am
+++ b/none/tests/Makefile.am
@@ -8,6 +8,9 @@
if VG_PPC32_LINUX
SUBDIRS += ppc32
endif
+if VG_PPC64_LINUX
+SUBDIRS += ppc64
+endif
DIST_SUBDIRS = ${VG_ARCH_ALL} .