# stack traces, since users often see stack traces extending
# into (and through) the preloads.
if VGCONF_OS_IS_DARWIN
-AM_CFLAGS_PIC = -dynamic -O -g -fno-omit-frame-pointer -fno-strict-aliasing -mno-dynamic-no-pic
+AM_CFLAGS_PIC = -dynamic -O -g -fno-omit-frame-pointer -fno-strict-aliasing \
+ -mno-dynamic-no-pic -fpic -fPIC
else
AM_CFLAGS_PIC = -fpic -O -g -fno-omit-frame-pointer -fno-strict-aliasing
endif
AM_FLAG_M3264_X86_DARWIN = -arch i386
AM_CFLAGS_X86_DARWIN = $(WERROR) -arch i386 $(AM_CFLAGS_BASE) \
- -mmacosx-version-min=10.5 -fno-stack-protector \
- -mdynamic-no-pic
+ -mmacosx-version-min=10.5 \
+ -fno-stack-protector -fno-pic -fno-PIC
+
AM_CCASFLAGS_X86_DARWIN = $(AM_CPPFLAGS_X86_DARWIN) -arch i386 -g
AM_FLAG_M3264_AMD64_DARWIN = -arch x86_64
glibc-2.2-LinuxThreads-helgrind.supp \
glibc-2.X-drd.supp \
exp-ptrcheck.supp \
- darwin9.supp darwin9-drd.supp
+ darwin9.supp darwin9-drd.supp \
+ darwin10.supp darwin10-drd.supp
DEFAULT_SUPP_FILES = @DEFAULT_SUPP@
# We include all the base .supp files in the distribution, but not
TOOL_LDFLAGS_COMMON_AIX5 = \
-static -Wl,-e_start_valgrind
TOOL_LDFLAGS_COMMON_DARWIN = \
- -nodefaultlibs -nostartfiles \
- -Wl,-u,__start -Wl,-e,__start -Wl,-bind_at_load /usr/lib/dyld
+ -nodefaultlibs -nostartfiles -Wl,-u,__start -Wl,-e,__start
TOOL_LDFLAGS_X86_LINUX = \
$(TOOL_LDFLAGS_COMMON_LINUX) @FLAG_M32@
$(TOOL_LDFLAGS_COMMON_AIX5) @FLAG_MAIX64@ -Wl,-bbigtoc
TOOL_LDFLAGS_X86_DARWIN = \
- $(TOOL_LDFLAGS_COMMON_DARWIN) -arch i386 \
- -Wl,-seg1addr,0xf0080000 \
- -Wl,-stack_addr,0xf0080000 -Wl,-stack_size,0x80000 \
- -Wl,-pagezero_size,0xf0000000
+ $(TOOL_LDFLAGS_COMMON_DARWIN) -arch i386
-# pagezero can't be unmapped and remapped. Use stack instead.
-# GrP fixme no stack guard
TOOL_LDFLAGS_AMD64_DARWIN = \
- $(TOOL_LDFLAGS_COMMON_DARWIN) -arch x86_64 \
- -Wl,-seg1addr,0x7fff55000000 \
- -Wl,-stack_addr,0x7fff50080000 -Wl,-stack_size,0x7ffe50080000 \
- -Wl,-pagezero_size,0x100000000
+ $(TOOL_LDFLAGS_COMMON_DARWIN) -arch x86_64
+
+# NB for 64-bit darwin. We may want to set -Wl,-pagezero_size to
+# something smaller than the default of 4G, so as to facilitate
+# loading clients who are also linked thusly (currently m_ume.c
+# will fail to load them). Although such setting is probably
+# better done in link_tool_exe.c.
+#
+# -Wl,-pagezero_size,0x100000000
#----------------------------------------------------------------------------
valgrind_listener_CFLAGS = $(AM_CFLAGS_PRI)
valgrind_listener_CCASFLAGS = $(AM_CCASFLAGS_PRI)
valgrind_listener_LDFLAGS = $(AM_CFLAGS_PRI)
-
+if VGCONF_PLATFORMS_INCLUDE_X86_DARWIN
+valgrind_listener_LDFLAGS += -Wl,-read_only_relocs -Wl,suppress
+endif
cg_merge_CFLAGS = $(AM_CFLAGS_PRI)
cg_merge_CCASFLAGS = $(AM_CCASFLAGS_PRI)
cg_merge_LDFLAGS = $(AM_CFLAGS_PRI)
+if VGCONF_PLATFORMS_INCLUDE_X86_DARWIN
+cg_merge_LDFLAGS += -Wl,-read_only_relocs -Wl,suppress
+endif
#----------------------------------------------------------------------------
# cachegrind-<platform>
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
cachegrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(cachegrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(cachegrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
cachegrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(cachegrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(cachegrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(callgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
callgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(callgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(callgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
*darwin*)
AC_MSG_RESULT([ok (${host_os})])
VGCONF_OS="darwin"
+ AC_DEFINE([DARWIN_10_5], 100500, [DARWIN_VERS value for Mac OS X 10.5])
+ AC_DEFINE([DARWIN_10_6], 100600, [DARWIN_VERS value for Mac OS X 10.6])
+ AC_DEFINE([DARWIN_10_7], 100700, [DARWIN_VERS value for Mac OS X 10.7])
AC_MSG_CHECKING([for the kernel version])
kernel=`uname -r`
# Nb: for Darwin we set DEFAULT_SUPP here. That's because Darwin
# has only one relevant version, the OS version. The `uname` check
# is a good way to get that version (i.e. "Darwin 9.6.0" is Mac OS
- # X 10.5.6, and "Darwin 10.x" would presumably be Mac OS X 10.6.x
- # Snow Leopard and darwin10.supp), and we don't know of an macros
- # similar to __GLIBC__ to get that info.
+ # X 10.5.6, and "Darwin 10.x" is Mac OS X 10.6.x Snow Leopard),
+ # and we don't know of an macros similar to __GLIBC__ to get that info.
#
# XXX: `uname -r` won't do the right thing for cross-compiles, but
# that's not a problem yet.
case "${kernel}" in
9.*)
AC_MSG_RESULT([Darwin 9.x (${kernel}) / Mac OS X 10.5 Leopard])
+ AC_DEFINE([DARWIN_VERS], DARWIN_10_5, [Darwin / Mac OS X version])
DEFAULT_SUPP="darwin9.supp ${DEFAULT_SUPP}"
DEFAULT_SUPP="darwin9-drd.supp ${DEFAULT_SUPP}"
;;
+ 10.*)
+ AC_MSG_RESULT([Darwin 10.x (${kernel}) / Mac OS X 10.6 Snow Leopard])
+ AC_DEFINE([DARWIN_VERS], DARWIN_10_6, [Darwin / Mac OS X version])
+ DEFAULT_SUPP="darwin10.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="darwin10-drd.supp ${DEFAULT_SUPP}"
+ ;;
*)
AC_MSG_RESULT([unsupported (${kernel})])
- AC_MSG_ERROR([Valgrind works on Darwin 9.x (Mac OS X 10.5)])
+ AC_MSG_ERROR([Valgrind works on Darwin 9.x and 10.x (Mac OS X 10.5 and 10.6)])
;;
esac
;;
AC_MSG_CHECKING([for a supported CPU/OS combination])
+# NB. The load address for a given platform may be specified in more
+# than one place, in some cases, depending on whether we're doing a biarch,
+# 32-bit only or 64-bit only build. eg see case for amd64-linux below.
+# Be careful to give consistent values in all subcases. Also, all four
+# valt_load_addres_{pri,sec}_{norml,inner} values must always be set,
+# even if it is to "0xUNSET".
+#
case "$ARCH_MAX-$VGCONF_OS" in
x86-linux)
VGCONF_ARCH_PRI="x86"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="X86_LINUX"
VGCONF_PLATFORM_SEC_CAPS=""
- valt_load_address_normal="0x38000000"
- valt_load_address_inner="0x28000000"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
amd64-linux)
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
if test x$vg_cv_only64bit = xyes; then
VGCONF_ARCH_PRI="amd64"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX"
VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
elif test x$vg_cv_only32bit = xyes; then
VGCONF_ARCH_PRI="x86"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="X86_LINUX"
VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
else
VGCONF_ARCH_PRI="amd64"
VGCONF_ARCH_SEC="x86"
VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX"
VGCONF_PLATFORM_SEC_CAPS="X86_LINUX"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0x38000000"
+ valt_load_address_sec_inner="0x28000000"
fi
- valt_load_address_normal="0x38000000"
- valt_load_address_inner="0x28000000"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
ppc32-linux)
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX"
VGCONF_PLATFORM_SEC_CAPS=""
- valt_load_address_normal="0x38000000"
- valt_load_address_inner="0x28000000"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
ppc64-aix5)
+ valt_load_address_pri_norml="0xUNSET"
+ valt_load_address_pri_inner="0xUNSET"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
if test x$vg_cv_only64bit = xyes; then
VGCONF_ARCH_PRI="ppc64"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="PPC64_AIX5"
VGCONF_PLATFORM_SEC_CAPS="PPC32_AIX5"
fi
- valt_load_address_normal="0x38000000"
- valt_load_address_inner="0x28000000"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
ppc64-linux)
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
if test x$vg_cv_only64bit = xyes; then
VGCONF_ARCH_PRI="ppc64"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="PPC64_LINUX"
VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
elif test x$vg_cv_only32bit = xyes; then
VGCONF_ARCH_PRI="ppc32"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX"
VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
else
VGCONF_ARCH_PRI="ppc64"
VGCONF_ARCH_SEC="ppc32"
VGCONF_PLATFORM_PRI_CAPS="PPC64_LINUX"
VGCONF_PLATFORM_SEC_CAPS="PPC32_LINUX"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0x38000000"
+ valt_load_address_sec_inner="0x28000000"
fi
- valt_load_address_normal="0x38000000"
- valt_load_address_inner="0x28000000"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
x86-darwin)
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="X86_DARWIN"
VGCONF_PLATFORM_SEC_CAPS=""
- valt_load_address_normal="0x0"
- valt_load_address_inner="0x0"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
amd64-darwin)
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
if test x$vg_cv_only64bit = xyes; then
VGCONF_ARCH_PRI="amd64"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="AMD64_DARWIN"
VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x138000000"
+ valt_load_address_pri_inner="0x128000000"
elif test x$vg_cv_only32bit = xyes; then
VGCONF_ARCH_PRI="x86"
VGCONF_ARCH_SEC=""
VGCONF_PLATFORM_PRI_CAPS="X86_DARWIN"
VGCONF_PLATFORM_SEC_CAPS=""
VGCONF_ARCH_PRI_CAPS="x86"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
else
VGCONF_ARCH_PRI="amd64"
VGCONF_ARCH_SEC="x86"
VGCONF_PLATFORM_PRI_CAPS="AMD64_DARWIN"
VGCONF_PLATFORM_SEC_CAPS="X86_DARWIN"
+ valt_load_address_pri_norml="0x138000000"
+ valt_load_address_pri_inner="0x128000000"
+ valt_load_address_sec_norml="0x38000000"
+ valt_load_address_sec_inner="0x28000000"
fi
- valt_load_address_normal="0x0"
- valt_load_address_inner="0x0"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
arm-linux)
VGCONF_ARCH_PRI="arm"
VGCONF_PLATFORM_PRI_CAPS="ARM_LINUX"
VGCONF_PLATFORM_SEC_CAPS=""
- valt_load_address_normal="0x38000000"
- valt_load_address_inner="0x28000000"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
AC_MSG_RESULT([ok (${host_cpu}-${host_os})])
;;
*)
VGCONF_ARCH_SEC="unknown"
VGCONF_PLATFORM_PRI_CAPS="UNKNOWN"
VGCONF_PLATFORM_SEC_CAPS="UNKNOWN"
+ valt_load_address_pri_norml="0xUNSET"
+ valt_load_address_pri_inner="0xUNSET"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
AC_MSG_RESULT([no (${ARCH_MAX}-${VGCONF_OS})])
AC_MSG_ERROR([Valgrind is platform specific. Sorry. Please consider doing a port.])
;;
# Check if this should be built as an inner Valgrind, to be run within
# another Valgrind. Choose the load address accordingly.
-AC_SUBST(VALT_LOAD_ADDRESS)
+AC_SUBST(VALT_LOAD_ADDRESS_PRI)
+AC_SUBST(VALT_LOAD_ADDRESS_SEC)
AC_CACHE_CHECK([for use as an inner Valgrind], vg_cv_inner,
[AC_ARG_ENABLE(inner,
[ --enable-inner enables self-hosting],
[vg_cv_inner=no])])
if test "$vg_cv_inner" = yes; then
AC_DEFINE([ENABLE_INNER], 1, [configured to run as an inner Valgrind])
- VALT_LOAD_ADDRESS=$valt_load_address_inner
+ VALT_LOAD_ADDRESS_PRI=$valt_load_address_pri_inner
+ VALT_LOAD_ADDRESS_SEC=$valt_load_address_sec_inner
else
- VALT_LOAD_ADDRESS=$valt_load_address_normal
+ VALT_LOAD_ADDRESS_PRI=$valt_load_address_pri_norml
+ VALT_LOAD_ADDRESS_SEC=$valt_load_address_sec_norml
fi
memcheck/tests/x86/Makefile
memcheck/tests/linux/Makefile
memcheck/tests/darwin/Makefile
+ memcheck/tests/amd64-linux/Makefile
memcheck/tests/x86-linux/Makefile
memcheck/perf/Makefile
cachegrind/Makefile
valgrind_CFLAGS = $(AM_CFLAGS_PRI)
valgrind_CCASFLAGS = $(AM_CCASFLAGS_PRI)
valgrind_LDFLAGS = $(AM_CFLAGS_PRI)
+if VGCONF_PLATFORMS_INCLUDE_X86_DARWIN
+valgrind_LDFLAGS += -Wl,-read_only_relocs -Wl,suppress
+endif
no_op_client_for_valgrind_SOURCES = no_op_client_for_valgrind.c
no_op_client_for_valgrind_CPPFLAGS = $(AM_CPPFLAGS_PRI)
no_op_client_for_valgrind_CFLAGS = $(AM_CFLAGS_PRI)
no_op_client_for_valgrind_CCASFLAGS = $(AM_CCASFLAGS_PRI)
no_op_client_for_valgrind_LDFLAGS = $(AM_CFLAGS_PRI)
+if VGCONF_PLATFORMS_INCLUDE_X86_DARWIN
+no_op_client_for_valgrind_LDFLAGS += -Wl,-read_only_relocs -Wl,suppress
+endif
#----------------------------------------------------------------------------
# Darwin Mach stuff
/usr/include/mach/vm_map.defs
endif
-# Be careful w.r.t. parellel builds. See section 27.9 of the automake info
+# Be careful w.r.t. parallel builds. See section 27.9 of the automake info
# page, "Handling Tools that Produce many Outputs".
-$(mach_user_srcs): $(mach_defs)
+$(abs_builddir)/m_mach:
+ mkdir -p $@
+$(mach_user_srcs): $(mach_defs) $(abs_builddir)/m_mach
(cd m_mach && mig $(mach_defs))
-$(mach_hdrs): $(mach_defs) $(mach_user_srcs)
+$(mach_hdrs): $(mach_defs) $(mach_user_srcs) $(abs_builddir)/m_mach
(cd m_mach && mig $(mach_defs))
#----------------------------------------------------------------------------
m_sigframe/sigframe-ppc64-aix5.c \
m_sigframe/sigframe-x86-darwin.c \
m_sigframe/sigframe-amd64-darwin.c \
- m_start-x86-darwin.S \
- m_start-amd64-darwin.S \
m_syswrap/syscall-x86-linux.S \
m_syswrap/syscall-amd64-linux.S \
m_syswrap/syscall-ppc32-linux.S \
#! @PERL@
-# This script handles linking the tool executables on MacOSX.
+# This script handles linking the tool executables on Linux,
+# statically and at an alternative load address.
+#
+# Linking statically sidesteps all sorts of complications to do with
+# having two copies of the dynamic linker (valgrind's and the
+# client's) coexisting in the same process. The alternative load
+# address is needed because Valgrind itself will load the client at
+# whatever address it specifies, which is almost invariably the
+# default load address. Hence we can't allow Valgrind itself (viz,
+# the tool executable) to be loaded at that address.
+#
+# Unfortunately there's no standard way to do 'static link at
+# alternative address', so these link_tool_exe_*.in scripts handle
+# the per-platform hoop-jumping.
#
# What we get passed here is:
# first arg
# the gcc invokation to do the final link, that
# the build system would have done, left to itself
#
-# Just ignore argv[1] and run the command specified by argv[2..] unchanged.
+# We just let the script 'die' if something is wrong, rather than do
+# proper error reporting. We don't expect the users to run this
+# directly. It is only run as part of the build process, with
+# carefully constrained inputs.
+#
+#
+# So: what we actually do is:
+#
+# Look at the specified gcc invokation. Ignore all parts of it except
+# the *.a, *.o and -o outfile parts. Wrap them up in a new command
+# which looks (eg) as follows:
+#
+# (64-bit):
+#
+# /usr/bin/ld -static -arch x86_64 -macosx_version_min 10.5 \
+# -o memcheck-amd64-darwin -u __start -e __start \
+# -image_base 0x138000000 -stack_addr 0x13c000000 \
+# -stack_size 0x800000 \
+# memcheck_amd*.o \
+# ../coregrind/libcoregrind-amd64-darwin.a \
+# ../VEX/libvex-amd64-darwin.a
+#
+# (32-bit)
+#
+# /usr/bin/ld -static -arch i386 -macosx_version_min 10.5 \
+# -o memcheck-x86-darwin -u __start -e __start \
+# -image_base 0x38000000 -stack_addr 0x3c000000 \
+# -stack_size 0x800000 \
+# memcheck_x86*.o \
+# ../coregrind/libcoregrind-x86-darwin.a \
+# ../VEX/libvex-x86-darwin.a
+#
+# The addresses shown above will actually work, although "for real" we
+# of course need to take it from argv[1]. In these examples the stack
+# is placed 64M after the executable start. It is probably safer to
+# place it 64M before the executable's start point, so the executable
+# + data + bss can grow arbitrarily in future without colliding with
+# the stack.
+#
+# There's one more twist: we need to know the word size of the
+# executable for which we are linking. We need to know this because
+# we must tell the linker that, by handing it either "-arch x86_64" or
+# "-arch i386". Fortunately we can figure this out by scanning the
+# gcc invokation, which itself must contain either "-arch x86_64" or
+# "-arch i386".
use warnings;
use strict;
+# we need to be able to do 64-bit arithmetic:
+use Math::BigInt;
+
+
+# User configurable constants: how far before the exe should we
+# place the stack?
+my $TX_STACK_OFFSET_BEFORE_TEXT = 64 * 1024 * 1024;
+
+# and how big should the stack be?
+my $TX_STACK_SIZE = 8 * 1024 * 1024;
+
+
+# string -> bool
+sub is_dota_or_doto($)
+{
+ my ($str) = @_;
+ if ($str =~ /.\.a$/ || $str =~ /.\.o$/) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
# expect at least: alt-load-address gcc -o foo bar.o
die "Not enough arguments"
my $ala = $ARGV[0];
# check for plausible-ish alt load address
-die "Bogus alt-load address"
+die "Bogus alt-load address (1)"
if (length($ala) < 3 || index($ala, "0x") != 0);
-# The cc invokation to do the final link
-my $cc = $ARGV[1];
+die "Bogus alt-load address (2)"
+ if ($ala !~ /^0x[0-9a-fA-F]+$/);
+
+
+# get hold of the outfile name (following "-o")
+my $outname = "";
+
+foreach my $n (2 .. $#ARGV - 1) {
+ my $str = $ARGV[$n];
+ if ($str eq "-o" && $outname eq "") {
+ $outname = $ARGV[$n + 1];
+ }
+}
+
+die "Can't find '-o outfilename' in command line"
+ if ($outname eq "");
+
+
+# get hold of the string following "-arch"
+my $archstr = "";
+
+foreach my $n (2 .. $#ARGV - 1) {
+ my $str = $ARGV[$n];
+ if ($str eq "-arch" && $archstr eq "") {
+ $archstr = $ARGV[$n + 1];
+ }
+}
+
+die "Can't find '-arch archstr' in command line"
+ if ($archstr eq "");
+
+
+# build the command line
+my $cmd = "/usr/bin/ld";
-# and the 'restargs' are argv[2 ..]
+$cmd = "$cmd -static";
+$cmd = "$cmd -arch $archstr";
+$cmd = "$cmd -macosx_version_min 10.5";
+$cmd = "$cmd -o $outname";
+$cmd = "$cmd -u __start -e __start";
-# so, build up the complete command here:
-# 'cc' 'restargs'
+my $stack_addr = Math::BigInt->new( $ala ) - $TX_STACK_OFFSET_BEFORE_TEXT;
+my $stack_addr_str = $stack_addr->as_hex();
+my $stack_size_str = Math::BigInt::as_hex($TX_STACK_SIZE);
-my $cmd="$cc";
+$cmd = "$cmd -image_base $ala";
+$cmd = "$cmd -stack_addr $stack_addr_str";
+$cmd = "$cmd -stack_size $stack_size_str";
-# Add the rest of the parameters
foreach my $n (2 .. $#ARGV) {
- $cmd = "$cmd $ARGV[$n]";
+ my $str = $ARGV[$n];
+ if (is_dota_or_doto($str)) {
+ $cmd = "$cmd $str";
+ }
}
#print "link_tool_exe_darwin: $cmd\n";
# the tool executable) to be loaded at that address.
#
# Unfortunately there's no standard way to do 'static link at
-# alternative address', so this program handles the per-platform
-# hoop-jumping.
-#
+# alternative address', so these link_tool_exe_*.in scripts handle
+# the per-platform hoop-jumping.
#
# What we get passed here is:
# first arg
}
# endif
- //--------------------------------------------------------------
- // Darwin only: munmap address-space-filling segments
- // (oversized pagezero or stack)
- // p: none
- //--------------------------------------------------------------
- // DDD: comments from Greg Parker why these address-space-filling segments
- // are necessary:
- //
- // The memory maps are there to make sure that Valgrind's copies of libc
- // and dyld load in a non-default location, so that the inferior's own
- // libc and dyld do load in the default locations. (The kernel performs
- // the work of loading several things as described by the executable's
- // load commands, including the executable itself, dyld, the main
- // thread's stack, and the page-zero segment.) There might be a way to
- // fine-tune it so the maps are smaller but still do the job.
- //
- // The post-launch mmap behavior can be cleaned up - looks like we don't
- // unmap as much as we should - which would improve post-launch
- // performance.
- //
- // Hmm, there might be an extra-clever way to give Valgrind a custom
- // MH_DYLINKER that performs the "bootloader" work of loading dyld in an
- // acceptable place and then unloading itself. Then no mmaps would be
- // needed. I'll have to think about that one.
- //
- // [I can't work out where the address-space-filling segments are
- // created in the first place. --njn]
- //
-#if defined(VGO_darwin)
-# if VG_WORDSIZE == 4
- VG_(do_syscall2)(__NR_munmap, 0x00000000, 0xf0000000);
-# else
- // open up client space
- VG_(do_syscall2)(__NR_munmap, 0x100000000, 0x700000000000-0x100000000);
- // open up client stack and dyld
- VG_(do_syscall2)(__NR_munmap, 0x7fff5c000000, 0x4000000);
-# endif
-#endif
-
//--------------------------------------------------------------
// Ensure we're on a plausible stack.
// p: logging
//--------------------------------------------------------------
-#if defined(VGO_darwin)
- // Darwin doesn't use the interim stack.
-#else
VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
{ HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
HChar* limHi = limLo + sizeof(VG_(interim_stack));
VG_(debugLog)(0, "main", " Cannot continue. Sorry.\n");
VG_(exit)(1);
}
-#endif
//--------------------------------------------------------------
// Start up the address space manager, and determine the
// approximate location of the client's stack
- // p: logging, plausible-stack, darwin-munmap
+ // p: logging, plausible-stack
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Starting the address space manager\n");
vg_assert(VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 65536);
#elif defined(VGO_darwin)
+/*
+ Memory layout established by kernel:
+
+ 0(%esp) argc
+ 4(%esp) argv[0]
+ ...
+ argv[argc-1]
+ NULL
+ envp[0]
+ ...
+ envp[n]
+ NULL
+ executable name (presumably, a pointer to it)
+ NULL
+
+ Ditto in the 64-bit case, except all offsets from SP are obviously
+ twice as large.
+*/
+
+/* The kernel hands control to _start, which extracts the initial
+ stack pointer and calls onwards to _start_in_C_darwin. This also
+ switches to the new stack. */
+#if defined(VGP_x86_darwin)
+asm("\n"
+ ".text\n"
+ ".align 2,0x90\n"
+ "\t.globl __start\n"
+ "__start:\n"
+ /* set up the new stack in %eax */
+ "\tmovl $_vgPlain_interim_stack, %eax\n"
+ "\taddl $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
+ "\taddl $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %eax\n"
+ "\tsubl $16, %eax\n"
+ "\tandl $~15, %eax\n"
+ /* install it, and collect the original one */
+ "\txchgl %eax, %esp\n"
+ /* call _start_in_C_darwin, passing it the startup %esp */
+ "\tpushl %eax\n"
+ "\tcall __start_in_C_darwin\n"
+ "\tint $3\n"
+ "\tint $3\n"
+);
+#elif defined(VGP_amd64_darwin)
+asm("\n"
+ ".text\n"
+ "\t.globl __start\n"
+ ".align 3,0x90\n"
+ "__start:\n"
+ /* set up the new stack in %rdi */
+ "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
+ "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
+ "\taddq $"VG_STRINGIFY(VG_STACK_ACTIVE_SZB)", %rdi\n"
+ "\tandq $~15, %rdi\n"
+ /* install it, and collect the original one */
+ "\txchgq %rdi, %rsp\n"
+ /* call _start_in_C_darwin, passing it the startup %rsp */
+ "\tcall __start_in_C_darwin\n"
+ "\tint $3\n"
+ "\tint $3\n"
+);
+#endif
+
void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
// skip check
return VG_(memset)(s,c,n);
}
-/* _start in m_start-<arch>-darwin.S calls _start_in_C_darwin(). */
-
/* Avoid compiler warnings: this fn _is_ used, but labelling it
'static' causes gcc to complain it isn't. */
void _start_in_C_darwin ( UWord* pArgc );
void _start_in_C_darwin ( UWord* pArgc )
{
Int r;
- Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
+ Int argc = *(Int *)pArgc; // not pArgc[0] on LP64
HChar** argv = (HChar**)&pArgc[1];
HChar** envp = (HChar**)&pArgc[1+argc+1];
#endif
+////////////////////////////////////////////////////////////////
+
+/* For static linking on x86-darwin, we need to supply our own 64-bit
+ integer division code, else the link dies thusly:
+
+ ld_classic: Undefined symbols:
+ ___udivdi3
+ ___umoddi3
+*/
+#if defined(VGP_x86_darwin)
+
+/* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
+ (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
+ division. Cobbled together from
+
+ http://www.hackersdelight.org/HDcode/divlu.c
+ http://www.hackersdelight.org/HDcode/divls.c
+ http://www.hackersdelight.org/HDcode/newCode/divDouble.c
+
+ The code from those three files is covered by the following license,
+ as it appears at:
+
+ http://www.hackersdelight.org/permissions.htm
+
+ You are free to use, copy, and distribute any of the code on
+ this web site, whether modified by you or not. You need not give
+ attribution. This includes the algorithms (some of which appear
+ in Hacker's Delight), the Hacker's Assistant, and any code
+ submitted by readers. Submitters implicitly agree to this.
+*/
+
+/* Long division, unsigned (64/32 ==> 32).
+ This procedure performs unsigned "long division" i.e., division of a
+64-bit unsigned dividend by a 32-bit unsigned divisor, producing a
+32-bit quotient. In the overflow cases (divide by 0, or quotient
+exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
+value).
+ The dividend is u1 and u0, with u1 being the most significant word.
+The divisor is parameter v. The value returned is the quotient.
+ Max line length is 57, to fit in hacker.book. */
+
+static Int nlz32(UInt x)
+{
+ Int n;
+ if (x == 0) return(32);
+ n = 0;
+ if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
+ if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
+ if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
+ if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
+ if (x <= 0x7FFFFFFF) {n = n + 1;}
+ return n;
+}
+
+/* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
+ division as a primitive. */
+static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
+{
+ const UInt b = 65536; // Number base (16 bits).
+ UInt un1, un0, // Norm. dividend LSD's.
+ vn1, vn0, // Norm. divisor digits.
+ q1, q0, // Quotient digits.
+ un32, un21, un10, // Dividend digit pairs.
+ rhat; // A remainder.
+ Int s; // Shift amount for norm.
+
+ if (u1 >= v) { // If overflow, set rem.
+ if (r != NULL) // to an impossible value,
+ *r = 0xFFFFFFFF; // and return the largest
+ return 0xFFFFFFFF;} // possible quotient.
+
+ s = nlz32(v); // 0 <= s <= 31.
+ v = v << s; // Normalize divisor.
+ vn1 = v >> 16; // Break divisor up into
+ vn0 = v & 0xFFFF; // two 16-bit digits.
+
+ un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
+ un10 = u0 << s; // Shift dividend left.
+
+ un1 = un10 >> 16; // Break right half of
+ un0 = un10 & 0xFFFF; // dividend into two digits.
+
+ q1 = un32/vn1; // Compute the first
+ rhat = un32 - q1*vn1; // quotient digit, q1.
+ again1:
+ if (q1 >= b || q1*vn0 > b*rhat + un1) {
+ q1 = q1 - 1;
+ rhat = rhat + vn1;
+ if (rhat < b) goto again1;}
+
+ un21 = un32*b + un1 - q1*v; // Multiply and subtract.
+
+ q0 = un21/vn1; // Compute the second
+ rhat = un21 - q0*vn1; // quotient digit, q0.
+ again2:
+ if (q0 >= b || q0*vn0 > b*rhat + un0) {
+ q0 = q0 - 1;
+ rhat = rhat + vn1;
+ if (rhat < b) goto again2;}
+
+ if (r != NULL) // If remainder is wanted,
+ *r = (un21*b + un0 - q0*v) >> s; // return it.
+ return q1*b + q0;
+}
+
+
+/* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
+ as a primitive. */
+static Int divls(Int u1, UInt u0, Int v, Int *r)
+{
+ Int q, uneg, vneg, diff, borrow;
+
+ uneg = u1 >> 31; // -1 if u < 0.
+ if (uneg) { // Compute the absolute
+ u0 = -u0; // value of the dividend u.
+ borrow = (u0 != 0);
+ u1 = -u1 - borrow;}
+
+ vneg = v >> 31; // -1 if v < 0.
+ v = (v ^ vneg) - vneg; // Absolute value of v.
+
+ if ((UInt)u1 >= (UInt)v) goto overflow;
+
+ q = divlu2(u1, u0, v, (UInt *)r);
+
+ diff = uneg ^ vneg; // Negate q if signs of
+ q = (q ^ diff) - diff; // u and v differed.
+ if (uneg && r != NULL)
+ *r = -*r;
+
+ if ((diff ^ q) < 0 && q != 0) { // If overflow,
+ overflow: // set remainder
+ if (r != NULL) // to an impossible value,
+ *r = 0x80000000; // and return the largest
+ q = 0x80000000;} // possible neg. quotient.
+ return q;
+}
+
+
+
+/* This file contains a program for doing 64/64 ==> 64 division, on a
+machine that does not have that instruction but that does have
+instructions for "long division" (64/32 ==> 32). Code for unsigned
+division is given first, followed by a simple program for doing the
+signed version by using the unsigned version.
+ These programs are useful in implementing "long long" (64-bit)
+arithmetic on a machine that has the long division instruction. It will
+work on 64- and 32-bit machines, provided the compiler implements long
+long's (64-bit integers). It is desirable that the machine have the
+Count Leading Zeros instruction.
+ In the GNU world, these programs are known as __divdi3 and __udivdi3,
+and similar names are used here.
+ This material is not in HD, but may be in a future edition.
+Max line length is 57, to fit in hacker.book. */
+
+
+static Int nlz64(ULong x)
+{
+ Int n;
+ if (x == 0) return(64);
+ n = 0;
+ if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
+ if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
+ if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n + 8; x = x << 8;}
+ if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n + 4; x = x << 4;}
+ if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n + 2; x = x << 2;}
+ if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n + 1;}
+ return n;
+}
+
+// ---------------------------- udivdi3 --------------------------------
+
+ /* The variables u0, u1, etc. take on only 32-bit values, but they
+ are declared long long to avoid some compiler warning messages and to
+ avoid some unnecessary EXTRs that the compiler would put in, to
+ convert long longs to ints.
+
+ First the procedure takes care of the case in which the divisor is a
+ 32-bit quantity. There are two subcases: (1) If the left half of the
+ dividend is less than the divisor, one execution of DIVU is all that
+ is required (overflow is not possible). (2) Otherwise it does two
+ divisions, using the grade school method, with variables used as
+ suggested below.
+
+ q1 q0
+ ________
+ v) u1 u0
+ q1*v
+ ____
+ k u0 */
+
+/* These macros must be used with arguments of the appropriate type
+(unsigned long long for DIVU and long long for DIVS. They are
+simulations of the presumed machines ops. I.e., they look at only the
+low-order 32 bits of the divisor, they return garbage if the division
+overflows, and they return garbage in the high-order half of the
+quotient doubleword.
+ In practice, these would be replaced with uses of the machine's DIVU
+and DIVS instructions (e.g., by using the GNU "asm" facility). */
+
+static UInt DIVU ( ULong u, UInt v )
+{
+ UInt uHi = (UInt)(u >> 32);
+ UInt uLo = (UInt)u;
+ return divlu2(uHi, uLo, v, NULL);
+}
+
+static Int DIVS ( Long u, Int v )
+{
+ Int uHi = (Int)(u >> 32);
+ UInt uLo = (UInt)u;
+ return divls(uHi, uLo, v, NULL);
+}
+
+/* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
+ division as a primitive. */
+static ULong udivdi3(ULong u, ULong v)
+{
+ ULong u0, u1, v1, q0, q1, k, n;
+
+ if (v >> 32 == 0) { // If v < 2**32:
+ if (u >> 32 < v) // If u/v cannot overflow,
+ return DIVU(u, v) // just do one division.
+ & 0xFFFFFFFF;
+ else { // If u/v would overflow:
+ u1 = u >> 32; // Break u up into two
+ u0 = u & 0xFFFFFFFF; // halves.
+ q1 = DIVU(u1, v) // First quotient digit.
+ & 0xFFFFFFFF;
+ k = u1 - q1*v; // First remainder, < v.
+ q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
+ & 0xFFFFFFFF;
+ return (q1 << 32) + q0;
+ }
+ }
+ // Here v >= 2**32.
+ n = nlz64(v); // 0 <= n <= 31.
+ v1 = (v << n) >> 32; // Normalize the divisor
+ // so its MSB is 1.
+ u1 = u >> 1; // To ensure no overflow.
+ q1 = DIVU(u1, v1) // Get quotient from
+ & 0xFFFFFFFF; // divide unsigned insn.
+ q0 = (q1 << n) >> 31; // Undo normalization and
+ // division of u by 2.
+ if (q0 != 0) // Make q0 correct or
+ q0 = q0 - 1; // too small by 1.
+ if ((u - q0*v) >= v)
+ q0 = q0 + 1; // Now q0 is correct.
+ return q0;
+}
+
+
+// ----------------------------- divdi3 --------------------------------
+
+/* This routine presumes that smallish cases (those which can be done in
+one execution of DIVS) are common. If this is not the case, the test for
+this case should be deleted.
+ Note that the test for when DIVS can be used is not entirely
+accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
+whereas if could be (if u is sufficiently small in magnitude). */
+
+// ------------------------------ cut ----------------------------------
+
+static ULong my_llabs ( Long x )
+{
+ ULong t = x >> 63;
+ return (x ^ t) - t;
+}
+
+/* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
+ as a primitive. */
+static Long divdi3(Long u, Long v)
+{
+ ULong au, av;
+ Long q, t;
+ au = my_llabs(u);
+ av = my_llabs(v);
+ if (av >> 31 == 0) { // If |v| < 2**31 and
+ // if (v << 32 >> 32 == v) { // If v is in range and
+ if (au < av << 31) { // |u|/|v| cannot
+ q = DIVS(u, v); // overflow, use DIVS.
+ return (q << 32) >> 32;
+ }
+ }
+ q = udivdi3(au,av); // Invoke udivdi3.
+ t = (u ^ v) >> 63; // If u, v have different
+ return (q ^ t) - t; // signs, negate q.
+}
+
+// ---------------------------- end cut --------------------------------
+
+ULong __udivdi3 (ULong u, ULong v)
+{
+ return udivdi3(u,v);
+}
+
+Long __divdi3 (Long u, Long v)
+{
+ return divdi3(u,v);
+}
+
+ULong __umoddi3 (ULong u, ULong v)
+{
+ ULong q = __udivdi3(u, v);
+ ULong r = u - q * v;
+ return r;
+}
+
+Long __moddi3 (Long u, Long v)
+{
+ Long q = __divdi3(u, v);
+ Long r = u - q * v;
+ return r;
+}
+
+#endif
+
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
# elif defined(VGP_ppc64_aix5)
/* nothing so far */
-# elif defined(VGO_darwin)
+# elif defined(VGP_x86_darwin)
/* If we're using memcheck, use these intercepts right from
the start, otherwise dyld makes a lot of noise. */
if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
add_hardwired_spec("dyld", "strcmp",
- (Addr)&VG_(darwin_REDIR_FOR_strcmp), NULL);
+ (Addr)&VG_(x86_darwin_REDIR_FOR_strcmp), NULL);
add_hardwired_spec("dyld", "strlen",
- (Addr)&VG_(darwin_REDIR_FOR_strlen), NULL);
+ (Addr)&VG_(x86_darwin_REDIR_FOR_strlen), NULL);
add_hardwired_spec("dyld", "strcat",
- (Addr)&VG_(darwin_REDIR_FOR_strcat), NULL);
+ (Addr)&VG_(x86_darwin_REDIR_FOR_strcat), NULL);
add_hardwired_spec("dyld", "strcpy",
- (Addr)&VG_(darwin_REDIR_FOR_strcpy), NULL);
+ (Addr)&VG_(x86_darwin_REDIR_FOR_strcpy), NULL);
add_hardwired_spec("dyld", "strlcat",
- (Addr)&VG_(darwin_REDIR_FOR_strlcat), NULL);
-# if defined(VGP_amd64_darwin)
+ (Addr)&VG_(x86_darwin_REDIR_FOR_strlcat), NULL);
+ }
+
+# elif defined(VGP_amd64_darwin)
+ /* If we're using memcheck, use these intercepts right from
+ the start, otherwise dyld makes a lot of noise. */
+ if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
+ add_hardwired_spec("dyld", "strcmp",
+ (Addr)&VG_(amd64_darwin_REDIR_FOR_strcmp), NULL);
+ add_hardwired_spec("dyld", "strlen",
+ (Addr)&VG_(amd64_darwin_REDIR_FOR_strlen), NULL);
+ add_hardwired_spec("dyld", "strcat",
+ (Addr)&VG_(amd64_darwin_REDIR_FOR_strcat), NULL);
+ add_hardwired_spec("dyld", "strcpy",
+ (Addr)&VG_(amd64_darwin_REDIR_FOR_strcpy), NULL);
+ add_hardwired_spec("dyld", "strlcat",
+ (Addr)&VG_(amd64_darwin_REDIR_FOR_strlcat), NULL);
// DDD: #warning fixme rdar://6166275
add_hardwired_spec("dyld", "arc4random",
- (Addr)&VG_(darwin_REDIR_FOR_arc4random), NULL);
-# endif
+ (Addr)&VG_(amd64_darwin_REDIR_FOR_arc4random), NULL);
}
# else
#include "pub_core_sigframe.h" /* self */
+/* Cheap-ass hack copied from ppc32-aix5 code, just to get started.
+ Produce a frame with layout entirely of our own choosing. */
+
+/* This module creates and removes signal frames for signal deliveries
+ on amd64-darwin. Kludgey; the machine state ought to be saved in a
+ ucontext and retrieved from it later, so the handler can modify it
+ and return. However .. for now .. just stick the vex guest state
+ in the frame and snarf it again later.
+
+ Also, don't bother with creating siginfo and ucontext in the
+ handler, although do point them somewhere non-faulting.
+
+ Frame should have a 16-aligned size, just in case that turns out to
+ be important for Darwin. (be conservative)
+*/
+struct hacky_sigframe {
+ /* first word looks like a call to a 3-arg amd64-ELF function */
+ ULong returnAddr;
+ UChar lower_guardzone[512]; // put nothing here
+ VexGuestAMD64State gst;
+ VexGuestAMD64State gshadow1;
+ VexGuestAMD64State gshadow2;
+ vki_siginfo_t fake_siginfo;
+ struct vki_ucontext fake_ucontext;
+ UInt magicPI;
+ UInt sigNo_private;
+ vki_sigset_t mask; // saved sigmask; restore when hdlr returns
+ UInt __pad[2];
+ UChar upper_guardzone[512]; // put nothing here
+ // and don't zero it, since that might overwrite the client's
+ // stack redzone, at least on archs which have one
+};
+
+
+/* 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 )
+{
+ ThreadId tid = tst->tid;
+ /* For tracking memory events, indicate the entire frame has been
+ allocated. Except, don't mess with the area which
+ overlaps the previous frame's redzone. */
+ /* XXX is the following call really right? compared with the
+ amd64-linux version, this doesn't appear to handle the redzone
+ in the same way. */
+ VG_TRACK( new_mem_stack_signal,
+ addr - VG_STACK_REDZONE_SZB, size, tid );
+ return True;
+}
+
+
+/* Create a signal frame for thread 'tid'. Make a 3-arg frame
+ regardless of whether the client originally requested a 1-arg
+ version (no SA_SIGINFO) or a 3-arg one (SA_SIGINFO) since in the
+ former case, the amd64 calling conventions will simply cause the
+ extra 2 args to be ignored (inside the handler). (We hope!) */
void VG_(sigframe_create) ( ThreadId tid,
Addr sp_top_of_frame,
const vki_siginfo_t *siginfo,
const vki_sigset_t *mask,
void *restorer )
{
- I_die_here;
+ ThreadState* tst;
+ Addr rsp;
+ struct hacky_sigframe* frame;
+ Int sigNo = siginfo->si_signo;
+
+ vg_assert(VG_IS_16_ALIGNED(sizeof(struct hacky_sigframe)));
+
+ sp_top_of_frame &= ~0xfUL;
+ rsp = sp_top_of_frame - sizeof(struct hacky_sigframe);
+
+ tst = VG_(get_ThreadState)(tid);
+ if (!extend(tst, rsp, sp_top_of_frame - rsp))
+ return;
+
+ vg_assert(VG_IS_16_ALIGNED(rsp));
+
+ frame = (struct hacky_sigframe *) rsp;
+
+ /* clear it (very conservatively) (why so conservatively??) */
+ VG_(memset)(&frame->lower_guardzone, 0, 512);
+ VG_(memset)(&frame->gst, 0, sizeof(VexGuestAMD64State));
+ VG_(memset)(&frame->gshadow1, 0, sizeof(VexGuestAMD64State));
+ VG_(memset)(&frame->gshadow2, 0, sizeof(VexGuestAMD64State));
+ VG_(memset)(&frame->fake_siginfo, 0, sizeof(frame->fake_siginfo));
+ VG_(memset)(&frame->fake_ucontext, 0, sizeof(frame->fake_ucontext));
+
+ /* save stuff in frame */
+ frame->gst = tst->arch.vex;
+ frame->gshadow1 = tst->arch.vex_shadow1;
+ frame->gshadow2 = tst->arch.vex_shadow2;
+ frame->sigNo_private = sigNo;
+ frame->mask = tst->sig_mask;
+ frame->magicPI = 0x31415927;
+
+ /* Minimally fill in the siginfo and ucontext. Note, utter
+ lameness prevails. Be underwhelmed, be very underwhelmed. */
+ frame->fake_siginfo.si_signo = sigNo;
+ frame->fake_siginfo.si_code = siginfo->si_code;
+
+ /* Set up stack pointer */
+ vg_assert(rsp == (Addr)&frame->returnAddr);
+ VG_(set_SP)(tid, rsp);
+ VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(ULong));
+
+ /* Set up program counter */
+ VG_(set_IP)(tid, (ULong)handler);
+ VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_INSTR_PTR, sizeof(ULong));
+
+ /* Set up RA and args for the frame */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
+ (Addr)frame, 1*sizeof(ULong) );
+ frame->returnAddr = (ULong)&VG_(amd64_darwin_SUBST_FOR_sigreturn);
+
+ /* XXX should tell the tool that these regs got written */
+ tst->arch.vex.guest_RDI = (ULong) sigNo;
+ tst->arch.vex.guest_RSI = (Addr) &frame->fake_siginfo;/* oh well */
+ tst->arch.vex.guest_RDX = (Addr) &frame->fake_ucontext; /* oh well */
+
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+ (Addr)frame, 1*sizeof(ULong) );
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+ (Addr)&frame->fake_siginfo, sizeof(frame->fake_siginfo));
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
+ (Addr)&frame->fake_ucontext, sizeof(frame->fake_ucontext));
+
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg,
+ "sigframe_create (thread %d): next EIP=%#lx, next ESP=%#lx",
+ tid, (Addr)handler, (Addr)frame );
}
+/* Remove a signal frame from thread 'tid's stack, and restore the CPU
+ state from it. Note, isRT is irrelevant here. */
void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
{
- I_die_here;
+ ThreadState *tst;
+ Addr rsp;
+ Int sigNo;
+ struct hacky_sigframe* frame;
+
+ vg_assert(VG_(is_valid_tid)(tid));
+ tst = VG_(get_ThreadState)(tid);
+
+ /* Check that the stack frame looks valid */
+ rsp = VG_(get_SP)(tid);
+
+ /* why -8 ? because the signal handler's return will have popped
+ the return address of the stack; and the return address is the
+ lowest-addressed element of hacky_sigframe. */
+ frame = (struct hacky_sigframe*)(rsp - 8);
+ vg_assert(frame->magicPI == 0x31415927);
+ vg_assert(VG_IS_16_ALIGNED(frame));
+
+ /* restore the entire guest state, and shadows, from the
+ frame. Note, as per comments above, this is a kludge - should
+ restore it from saved ucontext. Oh well. */
+ tst->arch.vex = frame->gst;
+ tst->arch.vex_shadow1 = frame->gshadow1;
+ tst->arch.vex_shadow2 = frame->gshadow2;
+ tst->sig_mask = frame->mask;
+ tst->tmp_sig_mask = frame->mask;
+ sigNo = frame->sigNo_private;
+
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg,
+ "sigframe_destroy (thread %d): valid magic; next RIP=%#llx",
+ tid, tst->arch.vex.guest_RIP);
+
+ VG_TRACK( die_mem_stack_signal,
+ (Addr)frame - VG_STACK_REDZONE_SZB,
+ sizeof(struct hacky_sigframe) );
+
+ /* tell the tools */
+ VG_TRACK( post_deliver_signal, tid, sigNo );
}
#endif // defined(VGP_amd64_darwin)
vki_sigset_t mask; // saved sigmask; restore when hdlr returns
UInt __pad[1];
UChar upper_guardzone[512]; // put nothing here
+ // and don't zero it, since that might overwrite the client's
+ // stack redzone, at least on archs which have one
};
amd64-linux version, this doesn't appear to handle the redzone
in the same way. */
VG_TRACK( new_mem_stack_signal,
- addr, size - VG_STACK_REDZONE_SZB, tid );
+ addr - VG_STACK_REDZONE_SZB, size, tid );
return True;
}
tid, tst->arch.vex.guest_EIP);
VG_TRACK( die_mem_stack_signal,
- (Addr)frame,
- sizeof(struct hacky_sigframe) - VG_STACK_REDZONE_SZB );
+ (Addr)frame - VG_STACK_REDZONE_SZB,
+ sizeof(struct hacky_sigframe) );
/* tell the tools */
VG_TRACK( post_deliver_signal, tid, sigNo );
UWord scclass ) {
I_die_here;
}
- static inline Addr VG_UCONTEXT_LINK_REG( void* ucV ) {
- return 0; /* No, really. We have no LRs today. */
- }
- static inline Addr VG_UCONTEXT_FRAME_PTR( void* ucV ) {
+ static inline
+ void VG_UCONTEXT_TO_UnwindStartRegs( UnwindStartRegs* srP,
+ void* ucV ) {
I_die_here;
}
/* Get the old host action */
ret = VG_(sigaction)(i, NULL, &sa);
-# if defined(VGP_x86_darwin)
+# if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
/* apparently we may not even ask about the disposition of these
signals, let alone change them */
if (ret != 0 && (i == VKI_SIGKILL || i == VKI_SIGSTOP))
+++ /dev/null
-
-/*--------------------------------------------------------------------*/
-/*--- Darwin amd64 bootstrap. m_start-amd64-darwin.S ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2007 Apple Inc.
- Greg Parker gparker@apple.com
-
- 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.
-*/
-
-#if defined(VGP_amd64_darwin)
-
-#include "pub_core_basics_asm.h"
-
- .text
- .align 3,0x90
-Ldyld_stub_binding_helper:
- pushq %r11
- leaq ___dso_handle(%rip), %r11
- pushq %r11
- jmpq *Ldyld_lazy_symbol_binding_entry_point(%rip)
-
- .dyld
- .align 3
-Ldyld_lazy_symbol_binding_entry_point:
- .quad 0
- .quad 0
- .quad 0
- .quad 0
- .quad 0
- .quad Ldyld_stub_binding_helper
- .quad 0
-
-
- // Memory layout established by kernel:
- //
- // 0
- // executable_name
- // 0
- // envp[n]
- // ...
- // envp[0]
- // 0
- // argv[argc-1]
- // ...
- // sp+8-> argv[0]
- // sp -> argc
-
- .text
- .align 3,0x90
- .globl __start
-__start:
- movq %rsp, %rdi // save &argc
- andq $-16, %rsp // align stack
- pushq $0 // push NULL "return address" for backtraces
- pushq $0 // push fake saved ebp and align stack
- movq %rsp, %rbp // save frame pointer
- call __start_in_C_darwin // __start_in_C_darwin(&argc)
-
- // should not reach here
- int $3
- int $3
-
-#endif // defined(VGP_amd64_darwin)
-
-/*--------------------------------------------------------------------*/
-/*--- end ---*/
-/*--------------------------------------------------------------------*/
+++ /dev/null
-
-/*--------------------------------------------------------------------*/
-/*--- Darwin x86 bootstrap. m_start-x86-darwin.S ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2007 Apple Inc.
- Greg Parker gparker@apple.com
-
- 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.
-*/
-
-#if defined(VGP_x86_darwin)
-
-#include "pub_core_basics_asm.h"
-
- .text
- .align 2,0x90
-Ldyld_stub_binding_helper:
- pushl $__mh_execute_header
- jmpl *Ldyld_lazy_symbol_binding_entry_point
-
- .dyld
- .align 2
-Ldyld_lazy_symbol_binding_entry_point:
- .long 0
- .long 0
- .long 0
- .long 0
- .long 0
- .long Ldyld_stub_binding_helper
- .long 0
-
-
- // Memory layout established by kernel:
- //
- // 0
- // executable_name
- // 0
- // envp[n]
- // ...
- // envp[0]
- // 0
- // argv[argc-1]
- // ...
- // sp+4-> argv[0]
- // sp -> argc
-
- .text
- .align 2,0x90
- .globl __start
-__start:
- movl %esp, %eax // save &argc
- andl $-16, %esp // align stack
- pushl $0 // push NULL "return address" for backtraces
- pushl $0 // push fake saved ebp
- movl %esp, %ebp // save frame pointer
- pushl $0 // align stack
- pushl %eax // start_in_C_darwin(&argc)
- call __start_in_C_darwin
-
- // should not reach here
- int $3
- int $3
-
-#endif // defined(VGP_x86_darwin)
-
-/*--------------------------------------------------------------------*/
-/*--- end ---*/
-/*--------------------------------------------------------------------*/
// 369
// 370
// 371
-// 372
+DECL_TEMPLATE(darwin, __thread_selfid); // 372
// 373
// 374
// 375
// NYI __mac_mount 424
// NYI __mac_get_mount 425
// NYI __mac_getfsstat 426
+DECL_TEMPLATE(darwin, fsgetpath); // 427
+// NYI audit_session_self 428
+// NYI audit_session_join 429
// Mach message helpers
DECL_TEMPLATE(darwin, host_info);
DECL_TEMPLATE(darwin, mach_port_get_refs);
DECL_TEMPLATE(darwin, mach_port_mod_refs);
DECL_TEMPLATE(darwin, mach_port_get_set_status);
+DECL_TEMPLATE(darwin, mach_port_move_member);
DECL_TEMPLATE(darwin, mach_port_destroy);
DECL_TEMPLATE(darwin, mach_port_request_notification);
DECL_TEMPLATE(darwin, mach_port_insert_right);
+DECL_TEMPLATE(darwin, mach_port_extract_right);
DECL_TEMPLATE(darwin, mach_port_get_attributes);
DECL_TEMPLATE(darwin, mach_port_set_attributes);
DECL_TEMPLATE(darwin, mach_port_insert_member);
DECL_TEMPLATE(darwin, thread_suspend);
DECL_TEMPLATE(darwin, thread_get_state);
DECL_TEMPLATE(darwin, thread_policy);
+DECL_TEMPLATE(darwin, thread_policy_set);
DECL_TEMPLATE(darwin, thread_info);
DECL_TEMPLATE(darwin, bootstrap_register);
DECL_TEMPLATE(darwin, bootstrap_look_up);
VexGuestAMD64State *vex;
Addr stack;
SizeT stacksize;
+ vki_sigset_t blockall;
+
+ /* When we enter here we hold no lock (!), so we better acquire it
+ pronto. Why do we hold no lock? Because (presumably) the only
+ way to get here is as a result of a SfMayBlock syscall
+ "workq_ops(WQOPS_THREAD_RETURN)", which will have dropped the
+ lock. At least that's clear for the 'reuse' case. The
+ non-reuse case? Dunno, perhaps it's a new thread the kernel
+ pulled out of a hat. In any case we still need to take a
+ lock. */
+ VG_(acquire_BigLock_LL)("wqthread_hijack");
+
+ /* Start the thread with all signals blocked. VG_(scheduler) will
+ set the mask correctly when we finally get there. */
+ VG_(sigfillset)(&blockall);
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, NULL);
if (reuse) {
// This thread already exists; we're merely re-entering
if (reuse) {
// Continue V's thread back in the scheduler.
// The client thread is of course in another location entirely.
+
+ /* Drop the lock before going into
+ ML_(wqthread_continue_NORETURN). The latter will immediately
+ attempt to reacquire it in non-LL mode, which is a bit
+ wasteful but I don't think is harmful. A better solution
+ would be to not drop the lock but instead "upgrade" it from a
+ LL lock to a full lock, but that's too much like hard work
+ right now. */
+ VG_(release_BigLock_LL)("wqthread_hijack(1)");
ML_(wqthread_continue_NORETURN)(tst->tid);
}
else {
VG_(am_do_sync_check)("after", "wqthread_hijack", 0);
// Go!
+ /* Same comments as the 'release' in the then-clause.
+ start_thread_NORETURN calls run_thread_NORETURN calls
+ thread_wrapper which acquires the lock before continuing.
+ Let's hope nothing non-thread-local happens until that point.
+
+ DDD: I think this is plain wrong .. if we get to
+ thread_wrapper not holding the lock, and someone has recycled
+ this thread slot in the meantime, we're hosed. Is that
+ possible, though? */
+ VG_(release_BigLock_LL)("wqthread_hijack(2)");
call_on_new_stack_0_1(tst->os_state.valgrind_stack_init_SP, 0,
start_thread_NORETURN, (Word)tst);
}
#include <mach/mach.h>
#include <mach/mach_vm.h>
#include <semaphore.h>
-#include <sys/acl.h> /* struct kauth_filesec */
/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
#define msgh_request_port msgh_remote_port
{
PRINT("futimes ( %ld, %#lx )", ARG1,ARG2);
PRE_REG_READ2(long, "futimes", int, fd, struct timeval *, tvp);
- if (ARG2 != 0) {
+ if (!ML_(fd_allowed)(ARG1, "futimes", tid, False)) {
+ SET_STATUS_Failure( VKI_EBADF );
+ } else if (ARG2 != 0) {
PRE_timeval_READ( "futimes(tvp[0])", ARG2 );
PRE_timeval_READ( "futimes(tvp[1])", ARG2+sizeof(struct vki_timeval) );
}
{
PRINT("kdebug_trace(%ld, %ld, %ld, %ld, %ld, %ld)",
ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+ /*
+ Don't check anything - some clients pass fewer arguments.
PRE_REG_READ6(long, "kdebug_trace",
int,"code", int,"arg1", int,"arg2",
int,"arg3", int,"arg4", int,"arg5");
- // GrP fixme anything else?
+ */
}
is just way wrong. [The trouble is with the size, which depends on a
non-trival kernel computation] */
PRE_MEM_READ( "fchmod_extended(xsecurity)", ARG5,
- sizeof(struct kauth_filesec) );
+ sizeof(struct vki_kauth_filesec) );
}
PRE(chmod_extended)
is just way wrong. [The trouble is with the size, which depends on a
non-trival kernel computation] */
PRE_MEM_READ( "chmod_extended(xsecurity)", ARG5,
- sizeof(struct kauth_filesec) );
+ sizeof(struct vki_kauth_filesec) );
}
} attrspec;
static const attrspec commonattr[] = {
// This order is important.
+#if DARWIN_VERS >= DARWIN_10_6
+ { ATTR_CMN_RETURNED_ATTRS, sizeof(attribute_set_t) },
+#endif
{ ATTR_CMN_NAME, -1 },
{ ATTR_CMN_DEVID, sizeof(dev_t) },
{ ATTR_CMN_FSID, sizeof(fsid_t) },
{ ATTR_CMN_NAMEDATTRLIST, -1 },
{ ATTR_CMN_FLAGS, sizeof(uint32_t) },
{ ATTR_CMN_USERACCESS, sizeof(uint32_t) },
+ { ATTR_CMN_EXTENDED_SECURITY, -1 },
+ { ATTR_CMN_UUID, sizeof(guid_t) },
+ { ATTR_CMN_GRPUUID, sizeof(guid_t) },
{ ATTR_CMN_FILEID, sizeof(uint64_t) },
{ ATTR_CMN_PARENTID, sizeof(uint64_t) },
+#if DARWIN_VERS >= DARWIN_10_6
+ { ATTR_CMN_FULLPATH, -1 },
+#endif
{ 0, 0 }
};
static const attrspec volattr[] = {
{ ATTR_VOL_MOUNTEDDEVICE, -1 },
{ ATTR_VOL_ENCODINGSUSED, sizeof(uint64_t) },
{ ATTR_VOL_CAPABILITIES, sizeof(vol_capabilities_attr_t) },
+#if DARWIN_VERS >= DARWIN_10_6
+ { ATTR_VOL_UUID, sizeof(uuid_t) },
+#endif
{ ATTR_VOL_ATTRIBUTES, sizeof(vol_attributes_attr_t) },
{ 0, 0 }
};
d = attrBuf;
dend = d + attrBufSize;
+#if DARWIN_VERS >= DARWIN_10_6
+ // ATTR_CMN_RETURNED_ATTRS tells us what's really here, if set
+ if (a[0] & ATTR_CMN_RETURNED_ATTRS) {
+ // fixme range check this?
+ a[0] &= ~ATTR_CMN_RETURNED_ATTRS;
+ fn(tid, d, sizeof(attribute_set_t));
+ VG_(memcpy)(a, d, sizeof(a));
+ }
+#endif
+
for (g = 0; g < 5; g++) {
for (i = 0; attrdefs[g][i].attrBit; i++) {
uint32_t bit = attrdefs[g][i].attrBit;
POST(getattrlist)
{
if (ARG4 > sizeof(vki_uint32_t)) {
- // attrBuf is uint32_t bytes written followed by attr data
+ // attrBuf is uint32_t size followed by attr data
vki_uint32_t *sizep = (vki_uint32_t *)ARG3;
POST_MEM_WRITE(ARG3, sizeof(vki_uint32_t));
- scan_attrlist(tid, (struct vki_attrlist *)ARG2, sizep+1, *sizep, &get1attr);
+ if (ARG5 & FSOPT_REPORT_FULLSIZE) {
+ // *sizep is bytes required for return value, including *sizep
+ } else {
+ // *sizep is actual bytes returned, including *sizep
+ }
+ scan_attrlist(tid, (struct vki_attrlist *)ARG2, sizep+1, MIN(*sizep, ARG4), &get1attr);
}
}
POST_MEM_WRITE(ARG3, p - (char *)ARG3);
- PRINT("got %d records, %d/%lu bytes\n", count, p-(char *)ARG3, ARG4);
+ PRINT("got %d records, %ld/%lu bytes\n", count, p-(char *)ARG3, ARG4);
+}
+
+
+PRE(fsgetpath)
+{
+#if VG_WORDSIZE == 4
+ PRINT("fsgetpath(%#lx, %ld, %#lx {%lu,%lu}, %llu)",
+ ARG1, ARG2, ARG3, ((unsigned int *)ARG3)[0], ((unsigned int *)ARG3)[1], LOHI64(ARG4, ARG5));
+ PRE_REG_READ5(ssize_t, "fsgetpath",
+ void*,"buf", size_t,"bufsize",
+ fsid_t *,"fsid",
+ vki_uint32_t, "objid_low32", vki_uint32_t, "objid_high32");
+#else
+ PRINT("fsgetpath(%#lx, %ld, %#lx {%u,%u}, %llu)",
+ ARG1, ARG2, ARG3, ((unsigned int *)ARG3)[0], ((unsigned int *)ARG3)[1], ARG4);
+ PRE_REG_READ4(ssize_t, "fsgetpath",
+ void*,"buf", size_t,"bufsize",
+ fsid_t *,"fsid", uint64_t,"objid");
+#endif
+ PRE_MEM_READ("fsgetpath(fsid)", ARG3, sizeof(fsid_t));
+ PRE_MEM_WRITE("fsgetpath(buf)", ARG1, ARG2);
+}
+
+POST(fsgetpath)
+{
+ POST_MEM_WRITE(ARG1, RES);
}
case VKI_A_SETCLASS:
case VKI_A_SETPMASK:
case VKI_A_SETFSIZE:
+#if DARWIN_VERS >= DARWIN_10_6
+ case VKI_A_SENDTRIGGER:
+#endif
// kernel reads data..data+length
PRE_MEM_READ("auditon(data)", ARG2, ARG3);
break;
case VKI_A_GETCLASS:
case VKI_A_GETPINFO:
case VKI_A_GETPINFO_ADDR:
+#if DARWIN_VERS >= DARWIN_10_6
+ case VKI_A_GETSINFO_ADDR:
+#endif
// kernel reads and writes data..data+length
// GrP fixme be precise about what gets read and written
PRE_MEM_READ("auditon(data)", ARG2, ARG3);
case VKI_A_SETCLASS:
case VKI_A_SETPMASK:
case VKI_A_SETFSIZE:
+#if DARWIN_VERS >= DARWIN_10_6
+ case VKI_A_SENDTRIGGER:
+#endif
// kernel reads data..data+length
break;
case VKI_A_GETCLASS:
case VKI_A_GETPINFO:
case VKI_A_GETPINFO_ADDR:
+#if DARWIN_VERS >= DARWIN_10_6
+ case VKI_A_GETSINFO_ADDR:
+#endif
// kernel reads and writes data..data+length
// GrP fixme be precise about what gets read and written
POST_MEM_WRITE(ARG2, ARG3);
}
+PRE(mach_port_move_member)
+{
+#pragma pack(4)
+ typedef struct {
+ mach_msg_header_t Head;
+ NDR_record_t NDR;
+ mach_port_name_t member;
+ mach_port_name_t after;
+ } Request;
+#pragma pack()
+
+ Request *req = (Request *)ARG1;
+
+ PRINT("mach_port_move_member(%s, %s, %s)",
+ name_for_port(MACH_REMOTE),
+ name_for_port(req->member),
+ name_for_port(req->after));
+ /*
+ MACH_ARG(mach_port_move_member.member) = req->member;
+ MACH_ARG(mach_port_move_member.after) = req->after;
+ */
+ AFTER = POST_FN(mach_port_move_member);
+}
+
+POST(mach_port_move_member)
+{
+#pragma pack(4)
+ typedef struct {
+ mach_msg_header_t Head;
+ NDR_record_t NDR;
+ kern_return_t RetCode;
+ mach_msg_trailer_t trailer;
+ } Reply;
+#pragma pack()
+
+ Reply *reply = (Reply *)ARG1;
+
+ if (!reply->RetCode) {
+ // fixme port set tracker?
+ } else {
+ PRINT("mig return %d", reply->RetCode);
+ }
+}
+
+
PRE(mach_port_destroy)
{
#pragma pack(4)
}
+PRE(mach_port_extract_right)
+{
+#pragma pack(4)
+ typedef struct {
+ mach_msg_header_t Head;
+ NDR_record_t NDR;
+ mach_port_name_t name;
+ mach_msg_type_name_t msgt_name;
+ } Request;
+#pragma pack()
+
+ Request *req = (Request *)ARG1;
+
+ PRINT("mach_port_extract_right(%s, %s, %d)",
+ name_for_port(MACH_REMOTE),
+ name_for_port(req->name), req->msgt_name);
+
+ AFTER = POST_FN(mach_port_extract_right);
+
+ // fixme port tracker?
+}
+
+POST(mach_port_extract_right)
+{
+ // fixme import_complex_message handles the returned result, right?
+}
+
+
PRE(mach_port_get_attributes)
{
#pragma pack(4)
// GrP fixme semaphore destroy needed when thread creation fails
// GrP fixme probably other cleanup too
+ // GrP fixme spinlocks might be good enough?
// DDD: I'm not at all sure this is the right spot for this. It probably
// should be in pthread_hijack instead, just before the call to
}
-POST(thread_policy)
-{
-}
-
PRE(thread_policy)
{
mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
AFTER = POST_FN(thread_policy);
}
+POST(thread_policy)
+{
+}
+
+
+PRE(thread_policy_set)
+{
+ mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
+
+ PRINT("thread_policy_set(%s, ...)", name_for_port(mh->msgh_request_port));
+
+ AFTER = POST_FN(thread_policy_set);
+}
+
+POST(thread_policy_set)
+{
+}
+
PRE(thread_info)
{
case 3211:
CALL_PRE(mach_port_get_set_status);
return;
+ case 3212:
+ CALL_PRE(mach_port_move_member);
+ return;
case 3213:
CALL_PRE(mach_port_request_notification);
return;
case 3214:
CALL_PRE(mach_port_insert_right);
return;
+ case 3215:
+ CALL_PRE(mach_port_extract_right);
+ return;
case 3217:
CALL_PRE(mach_port_get_attributes);
return;
case 3616:
CALL_PRE(thread_policy);
return;
+ case 3617:
+ CALL_PRE(thread_policy_set);
+ return;
default:
// unknown message to a thread
VG_(printf)("UNKNOWN thread message [id %d, to %s, reply 0x%x]\n",
POST(mach_msg_unhandled)
{
- ML_(sync_mappings)("after", "mach_msg_unhandled", 0);
+ ML_(sync_mappings)("after", "mach_msg_receive (unhandled)", 0);
}
}
+#if DARWIN_VERS <= DARWIN_10_5
PRE(__semwait_signal)
{
- /* args: int cond_sem, int mutex_sem,
- int timeout, int relative,
- time_t tv_sec, time_t tv_nsec */
+ /* 10.5 args: int cond_sem, int mutex_sem,
+ int timeout, int relative,
+ time_t tv_sec, time_t tv_nsec */
PRINT("__semwait_signal(wait %s, signal %s, %ld, %ld, %lds:%ldns)",
name_for_port(ARG1), name_for_port(ARG2), ARG3, ARG4, ARG5, ARG6);
PRE_REG_READ6(long, "__semwait_signal",
*flags |= SfMayBlock;
}
+#else
+PRE(__semwait_signal)
+{
+ /* 10.5 args: int cond_sem, int mutex_sem,
+ int timeout, int relative,
+ const timespec *ts */
+ PRINT("__semwait_signal(wait %s, signal %s, %ld, %ld, %#lx)",
+ name_for_port(ARG1), name_for_port(ARG2), ARG3, ARG4, ARG5);
+ PRE_REG_READ5(int, "__semwait_signal",
+ int,cond_sem, int,mutex_sem,
+ int,timeout, int,relative,
+ const struct vki_timespec *,ts);
+
+ if (ARG5) PRE_MEM_READ ("__semwait_signal(ts)",
+ ARG5, sizeof(struct vki_timespec));
+
+ *flags |= SfMayBlock;
+}
+#endif
+PRE(__thread_selfid)
+{
+ PRINT("__thread_selfid ()");
+ PRE_REG_READ0(vki_uint64_t, "__thread_selfid");
+}
+
PRE(task_for_pid)
{
PRINT("task_for_pid(%s, %ld, %#lx)", name_for_port(ARG1), ARG2, ARG3);
MACX_(__NR_sigreturn, sigreturn),
// _____(__NR_chud),
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(186)), // ???
+#if DARWIN_VERS >= DARWIN_10_6
+// _____(__NR_fdatasync),
+#else
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(187)), // ???
+#endif
GENXY(__NR_stat, sys_newstat),
GENXY(__NR_fstat, sys_newfstat),
GENXY(__NR_lstat, sys_newlstat),
// _____(__NR_ATPgetreq),
// _____(__NR_ATPgetrsp),
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(213)), // Reserved for AppleTalk
+#if DARWIN_VERS >= DARWIN_10_6
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(214)), // old kqueue_from_portset_np
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(215)), // old kqueue_portset_np
+#else
// _____(__NR_kqueue_from_portset_np),
// _____(__NR_kqueue_portset_np),
+#endif
// _____(__NR_mkcomplex),
// _____(__NR_statv),
// _____(__NR_lstatv),
// _____(__NR_searchfs),
GENX_(__NR_delete, sys_unlink),
// _____(__NR_copyfile),
+#if DARWIN_VERS >= DARWIN_10_6
+// _____(__NR_fgetattrlist),
+// _____(__NR_fsetattrlist),
+#else
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(228)), // ??
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(229)), // ??
+#endif
GENXY(__NR_poll, sys_poll),
MACX_(__NR_watchevent, watchevent),
MACXY(__NR_waitevent, waitevent),
MACXY(__NR_fsctl, fsctl),
MACX_(__NR_initgroups, initgroups),
MACXY(__NR_posix_spawn, posix_spawn),
+#if DARWIN_VERS >= DARWIN_10_6
+// _____(__NR_ffsctl),
+#else
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(245)), // ???
+#endif
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(246)), // ???
// _____(__NR_nfsclnt),
// _____(__NR_fhopen),
// _____(__NR_identitysvc),
// _____(__NR_shared_region_check_np),
// _____(__NR_shared_region_map_np),
+#if DARWIN_VERS >= DARWIN_10_6
+// _____(__NR_vm_pressure_monitor),
+#else
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(296)), // old load_shared_file
+#endif
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(297)), // old reset_shared_file
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(298)), // old new_system_shared_regions
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(299)), // old shared_region_map_file_np
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(300)), // old shared_region_make_private_np
-// _____(__NR___pthread_mutex_destroy),
-// _____(__NR___pthread_mutex_init),
-// _____(__NR___pthread_mutex_lock),
-// _____(__NR___pthread_mutex_trylock),
-// _____(__NR___pthread_mutex_unlock),
-// _____(__NR___pthread_cond_init),
-// _____(__NR___pthread_cond_destroy),
-// _____(__NR___pthread_cond_broadcast),
-// _____(__NR___pthread_cond_signal),
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(301)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(302)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(303)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(304)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(305)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(306)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(307)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(308)), // ???
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(309)), // ???
// _____(__NR_getsid),
// _____(__NR_settid_with_pid),
-// _____(__NR___pthread_cond_timedwait),
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(312)), // ???
// _____(__NR_aio_fsync),
MACXY(__NR_aio_return, aio_return),
MACX_(__NR_aio_suspend, aio_suspend),
MACXY(__NR_aio_read, aio_read),
MACX_(__NR_aio_write, aio_write),
// _____(__NR_lio_listio), // 320
-// _____(__NR___pthread_cond_wait),
+ _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(321)), // ???
// _____(__NR_iopolicysys),
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(323)), // ???
// _____(__NR_mlockall),
MACX_(__NR_bsdthread_terminate, bsdthread_terminate),
MACXY(__NR_kqueue, kqueue),
MACXY(__NR_kevent, kevent),
-// _____(__NR_lchown),
+ GENX_(__NR_lchown, sys_lchown),
// _____(__NR_stack_snapshot),
MACX_(__NR_bsdthread_register, bsdthread_register),
MACX_(__NR_workq_open, workq_open),
MACXY(__NR_workq_ops, workq_ops),
+#if DARWIN_VERS >= DARWIN_10_6
+// _____(__NR_kevent64),
+#else
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(369)), // ???
+#endif
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(370)), // ???
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(371)), // ???
+#if DARWIN_VERS >= DARWIN_10_6
+ MACX_(__NR___thread_selfid, __thread_selfid),
+#else
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(372)), // ???
+#endif
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(373)), // ???
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(374)), // ???
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(375)), // ???
// _____(__NR___mac_mount),
// _____(__NR___mac_get_mount),
// _____(__NR___mac_getfsstat),
+#if DARWIN_VERS >= DARWIN_10_6
+ MACXY(__NR_fsgetpath, fsgetpath),
+// _____(__NR_audit_session_self),
+// _____(__NR_audit_session_join),
+#endif
+
// _____(__NR_MAXSYSCALL)
MACX_(__NR_DARWIN_FAKE_SIGRETURN, FAKE_SIGRETURN)
};
int $0x80
ud2
-.globl VG_(darwin_REDIR_FOR_strlen)
-VG_(darwin_REDIR_FOR_strlen):
+.globl VG_(x86_darwin_REDIR_FOR_strlen)
+VG_(x86_darwin_REDIR_FOR_strlen):
movl 4(%esp), %edx
movl %edx, %eax
jmp 1f
subl %edx, %eax
ret
-.globl VG_(darwin_REDIR_FOR_strcat)
-VG_(darwin_REDIR_FOR_strcat):
+.globl VG_(x86_darwin_REDIR_FOR_strcat)
+VG_(x86_darwin_REDIR_FOR_strcat):
pushl %esi
movl 8(%esp), %esi
movl 12(%esp), %ecx
ret
-.globl VG_(darwin_REDIR_FOR_strcmp)
-VG_(darwin_REDIR_FOR_strcmp):
+.globl VG_(x86_darwin_REDIR_FOR_strcmp)
+VG_(x86_darwin_REDIR_FOR_strcmp):
movl 4(%esp), %edx
movl 8(%esp), %ecx
jmp 1f
ret
-.globl VG_(darwin_REDIR_FOR_strcpy)
-VG_(darwin_REDIR_FOR_strcpy):
+.globl VG_(x86_darwin_REDIR_FOR_strcpy)
+VG_(x86_darwin_REDIR_FOR_strcpy):
pushl %ebp
movl %esp, %ebp
pushl %esi
leave
ret
-.globl VG_(darwin_REDIR_FOR_strlcat)
-VG_(darwin_REDIR_FOR_strlcat):
+.globl VG_(x86_darwin_REDIR_FOR_strlcat)
+VG_(x86_darwin_REDIR_FOR_strlcat):
pushl %ebp
movl %esp, %ebp
pushl %edi
3:
movl 12(%ebp), %eax
movl %eax, (%esp)
- call VG_(darwin_REDIR_FOR_strlen)
+ call VG_(x86_darwin_REDIR_FOR_strlen)
jmp 7f
4:
cmpl $1, %esi
.globl VG_(trampoline_stuff_start)
VG_(trampoline_stuff_start):
-.globl VG_(darwin_REDIR_FOR_strlen)
-VG_(darwin_REDIR_FOR_strlen):
+.globl VG_(amd64_darwin_SUBST_FOR_sigreturn)
+VG_(amd64_darwin_SUBST_FOR_sigreturn):
+ /* XXX does this need to have any special form? (cf x86-linux
+ version) */
+ movq $ __NR_DARWIN_FAKE_SIGRETURN, %rax
+ syscall
+ ud2
+
+.globl VG_(amd64_darwin_REDIR_FOR_strlen)
+VG_(amd64_darwin_REDIR_FOR_strlen):
movq %rdi, %rax
jmp 1f
0:
subq %rdi, %rax
ret
-.globl VG_(darwin_REDIR_FOR_strcat)
-VG_(darwin_REDIR_FOR_strcat):
+.globl VG_(amd64_darwin_REDIR_FOR_strcat)
+VG_(amd64_darwin_REDIR_FOR_strcat):
movq %rdi, %rdx
jmp 1f
0:
ret
-.globl VG_(darwin_REDIR_FOR_strcmp)
-VG_(darwin_REDIR_FOR_strcmp):
+.globl VG_(amd64_darwin_REDIR_FOR_strcmp)
+VG_(amd64_darwin_REDIR_FOR_strcmp):
jmp 1f
0:
incq %rdi
subl %edx, %eax
ret
-.globl VG_(darwin_REDIR_FOR_strcpy)
-VG_(darwin_REDIR_FOR_strcpy):
+.globl VG_(amd64_darwin_REDIR_FOR_strcpy)
+VG_(amd64_darwin_REDIR_FOR_strcpy):
pushq %rbp
movq %rdi, %rdx
movq %rsp, %rbp
movq %rdi, %rax
ret
-.globl VG_(darwin_REDIR_FOR_strlcat)
-VG_(darwin_REDIR_FOR_strlcat):
+.globl VG_(amd64_darwin_REDIR_FOR_strlcat)
+VG_(amd64_darwin_REDIR_FOR_strlcat):
pushq %rbp
leaq (%rdx,%rdi), %rax
movq %rdi, %rcx
jmp 6f
3:
movq %rsi, %rdi
- call VG_(darwin_REDIR_FOR_strlen)
+ call VG_(amd64_darwin_REDIR_FOR_strlen)
jmp 7f
4:
cmpq $1, %rdi
leave
ret
-.globl VG_(darwin_REDIR_FOR_arc4random)
-VG_(darwin_REDIR_FOR_arc4random):
+.globl VG_(amd64_darwin_REDIR_FOR_arc4random)
+VG_(amd64_darwin_REDIR_FOR_arc4random):
/* not very random, hope dyld won't mind */
movq $0x76616c6772696e64, %rax
ret
VG_(printf)("%s", str);
}
-static void check_mmap(SysRes res, Addr base, SizeT len)
+static void check_mmap(SysRes res, Addr base, SizeT len, HChar* who)
{
if (sr_isError(res)) {
- VG_(printf)("valgrind: mmap(0x%llx, %lld) failed in UME.\n",
- (ULong)base, (Long)len);
+ VG_(printf)("valgrind: mmap(0x%llx, %lld) failed in UME (%s).\n",
+ (ULong)base, (Long)len, who);
VG_(exit)(1);
}
}
// GrP fixme mark __UNIXSTACK as SF_STACK
+ // Don't honour the client's request to map PAGEZERO. Why not?
+ // Because when the kernel loaded the valgrind tool executable,
+ // it will have mapped pagezero itself. So further attempts
+ // to map it when loading the client are guaranteed to fail.
+#if VG_WORDSIZE == 4
+ if (segcmd->vmaddr == 0 && 0 == VG_(strcmp)(segcmd->segname, SEG_PAGEZERO)) {
+ if (segcmd->vmsize != 0x1000) {
+ print("bad executable (__PAGEZERO is not 4 KB)\n");
+ return -1;
+ }
+ return 0;
+ }
+#endif
#if VG_WORDSIZE == 8
if (segcmd->vmaddr == 0 && 0 == VG_(strcmp)(segcmd->segname, SEG_PAGEZERO)) {
if (segcmd->vmsize != 0x100000000) {
vmsize = VG_PGROUNDUP(segcmd->vmsize);
if (filesize > 0) {
addr = (Addr)segcmd->vmaddr;
+ VG_(debugLog)(2, "ume", "mmap fixed (file) (%#lx, %lu)\n", addr, filesize);
res = VG_(am_mmap_named_file_fixed_client)(addr, filesize, prot, fd,
offset + segcmd->fileoff,
filename);
- check_mmap(res, addr, filesize);
+ check_mmap(res, addr, filesize, "load_segment1");
}
// Zero-fill the remainder of the segment, if any
// page-aligned part
SizeT length = vmsize - filesize;
addr = (Addr)(filesize + segcmd->vmaddr);
+ VG_(debugLog)(2, "ume", "mmap fixed (anon) (%#lx, %lu)\n", addr, length);
res = VG_(am_mmap_anon_fixed_client)(addr, length, prot);
- check_mmap(res, addr, length);
+ check_mmap(res, addr, length, "load_segment2");
}
return 0;
SysRes res;
res = VG_(am_mmap_anon_fixed_client)(stackbase, stacksize, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC);
- check_mmap(res, stackbase, stacksize);
+ check_mmap(res, stackbase, stacksize, "load_unixthread1");
if (out_stack_start) *out_stack_start = (vki_uint8_t *)stackbase;
} else {
// custom stack - mapped via __UNIXTHREAD segment
extern void VG_(ppc64_aix5_do_preloads_then_start_client);
#endif
-#if defined(VGO_darwin)
+#if defined(VGP_x86_darwin)
extern void VG_(x86_darwin_SUBST_FOR_sigreturn);
-extern SizeT VG_(darwin_REDIR_FOR_strlen)( void* );
-extern SizeT VG_(darwin_REDIR_FOR_strcmp)( void*, void* );
-extern void* VG_(darwin_REDIR_FOR_strcat)( void*, void * );
-extern char* VG_(darwin_REDIR_FOR_strcpy)( char *s1, char *s2 );
-extern SizeT VG_(darwin_REDIR_FOR_strlcat)( char *s1, const char *s2, SizeT size );
-extern UInt VG_(darwin_REDIR_FOR_arc4random)( void );
+extern SizeT VG_(x86_darwin_REDIR_FOR_strlen)( void* );
+extern SizeT VG_(x86_darwin_REDIR_FOR_strcmp)( void*, void* );
+extern void* VG_(x86_darwin_REDIR_FOR_strcat)( void*, void * );
+extern char* VG_(x86_darwin_REDIR_FOR_strcpy)( char *s1, char *s2 );
+extern SizeT VG_(x86_darwin_REDIR_FOR_strlcat)( char *s1, const char *s2,
+ SizeT size );
+#endif
+
+#if defined(VGP_amd64_darwin)
+extern void VG_(amd64_darwin_SUBST_FOR_sigreturn);
+extern SizeT VG_(amd64_darwin_REDIR_FOR_strlen)( void* );
+extern SizeT VG_(amd64_darwin_REDIR_FOR_strcmp)( void*, void* );
+extern void* VG_(amd64_darwin_REDIR_FOR_strcat)( void*, void * );
+extern char* VG_(amd64_darwin_REDIR_FOR_strcpy)( char *s1, char *s2 );
+extern SizeT VG_(amd64_darwin_REDIR_FOR_strlcat)( char *s1, const char *s2,
+ SizeT size );
+extern UInt VG_(amd64_darwin_REDIR_FOR_arc4random)( void );
#endif
#endif // __PUB_CORE_TRAMPOLINE_H
Darwin arc4random (rdar://6166275)
------------------------------------------------------------------ */
-#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random)(void);
int VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random)(void)
{
- static FILE *rnd = 0;
+ static int rnd = -1;
int result;
- if (!rnd) rnd = fopen("/dev/random", "r");
-
- fread(&result, sizeof(result), 1, rnd);
+ if (rnd < 0) rnd = open("/dev/random", O_RDONLY);
+
+ read(rnd, &result, sizeof(result));
return result;
}
+
+# DRD suppressions for Darwin 9.x / Mac OS X 10.5 Leopard
+
#
# Suppression patterns for dyld, the dynamic loader.
#
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
drd_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(drd_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(drd_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
drd_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(drd_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(drd_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
}
usleep(1000);
}
- printf("T=%d: non_zero_received=%d\n",
- (int)pthread_self(), non_zero_received);
+ printf("T=%ld: non_zero_received=%d\n",
+ (size_t)pthread_self(), non_zero_received);
}
void Run() {
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
exp_bbv_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(exp_bbv_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(exp_bbv_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
exp_bbv_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(exp_bbv_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(exp_bbv_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
exp_ptrcheck_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(exp_ptrcheck_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(exp_ptrcheck_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
exp_ptrcheck_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(exp_ptrcheck_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(exp_ptrcheck_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
helgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(helgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(helgrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
helgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(helgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(helgrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
typedef struct eventreq vki_eventreq;
+#include <sys/acl.h>
+
+#define vki_kauth_filesec kauth_filesec
+
+
#include <sys/ptrace.h>
#define VKI_PTRACE_TRACEME PT_TRACE_ME
#define VKI_A_GETPINFO_ADDR A_GETPINFO_ADDR
#define VKI_A_GETKAUDIT A_GETKAUDIT
#define VKI_A_SETKAUDIT A_SETKAUDIT
+#if DARWIN_VERS >= DARWIN_10_6
+#define VKI_A_SENDTRIGGER A_SENDTRIGGER
+#define VKI_A_GETSINFO_ADDR A_GETSINFO_ADDR
+#endif
#include <sys/aio.h>
#define __VKI_SCNUMS_DARWIN_H
+// need DARWIN_10_x definitions
+#include "config.h"
+
// osfmk/mach/i386/syscall_sw.h
// There are two syscall number encodings in Darwin.
#define __NR_sigreturn VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(184)
#define __NR_chud VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(185)
/* 186 */
+#if DARWIN_VERS >= DARWIN_10_6
+#define __NR_fdatasync VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(187)
+#else
/* 187 */
+#endif
#define __NR_stat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(188)
#define __NR_fstat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(189)
#define __NR_lstat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(190)
#define __NR_ATPgetreq VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(211)
#define __NR_ATPgetrsp VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(212)
/* 213 Reserved for AppleTalk */
-#define __NR_kqueue_from_portset_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(214)
-#define __NR_kqueue_portset_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(215)
+#if DARWIN_VERS >= DARWIN_10_6
+ /* 214 old kqueue_from_portset_np*/
+ /* 215 old kqueue_portset_np*/
+#else
+#define __NR_kqueue_from_portset_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(214)
+#define __NR_kqueue_portset_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(215)
+#endif
#define __NR_mkcomplex VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(216)
#define __NR_statv VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(217)
#define __NR_lstatv VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(218)
#define __NR_setattrlist VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(221)
#define __NR_getdirentriesattr VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(222)
#define __NR_exchangedata VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(223)
- /* 224 checkuseraccess */
+ /* 224 old checkuseraccess */
#define __NR_searchfs VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(225)
#define __NR_delete VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(226)
#define __NR_copyfile VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(227)
+#if DARWIN_VERS >= DARWIN_10_6
+#define __NR_fgetattrlist VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(228)
+#define __NR_fsetattrlist VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(229)
+#else
/* 228 */
/* 229 */
+#endif
#define __NR_poll VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(230)
#define __NR_watchevent VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(231)
#define __NR_waitevent VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(232)
#define __NR_fsctl VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(242)
#define __NR_initgroups VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(243)
#define __NR_posix_spawn VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(244)
+#if DARWIN_VERS >= DARWIN_10_6
+#define __NR_ffsctl VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(245)
+#else
/* 245 */
+#endif
/* 246 */
#define __NR_nfsclnt VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(247)
#define __NR_fhopen VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(248)
#define __NR_identitysvc VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(293)
#define __NR_shared_region_check_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(294)
#define __NR_shared_region_map_np VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(295)
+#if DARWIN_VERS >= DARWIN_10_6
+#define __NR_vm_pressure_monitor VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(296)
+#else
/* 296 old load_shared_file */
+#endif
/* 297 old reset_shared_file */
/* 298 old new_system_shared_regions */
/* 299 old shared_region_map_file_np */
/* 300 old shared_region_make_private_np */
-#define __NR___pthread_mutex_destroy VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(301)
-#define __NR___pthread_mutex_init VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(302)
-#define __NR___pthread_mutex_lock VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(303)
-#define __NR___pthread_mutex_trylock VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(304)
-#define __NR___pthread_mutex_unlock VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(305)
-#define __NR___pthread_cond_init VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(306)
-#define __NR___pthread_cond_destroy VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(307)
-#define __NR___pthread_cond_broadcast VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(308)
-#define __NR___pthread_cond_signal VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(309)
+ /* 301 */
+ /* 302 */
+ /* 303 */
+ /* 304 */
+ /* 305 */
+ /* 306 */
+ /* 307 */
+ /* 308 */
+ /* 309 */
#define __NR_getsid VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(310)
#define __NR_settid_with_pid VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(311)
-#define __NR___pthread_cond_timedwait VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(312)
+ /* 312 */
#define __NR_aio_fsync VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(313)
#define __NR_aio_return VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(314)
#define __NR_aio_suspend VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(315)
#define __NR_aio_read VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(318)
#define __NR_aio_write VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(319)
#define __NR_lio_listio VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(320)
-#define __NR___pthread_cond_wait VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(321)
+ /* 321 */
#define __NR_iopolicysys VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(322)
/* 323 */
#define __NR_mlockall VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(324)
#define __NR_bsdthread_register VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(366)
#define __NR_workq_open VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(367)
#define __NR_workq_ops VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(368)
+#if DARWIN_VERS >= DARWIN_10_6
+#define __NR_kevent64 VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(369)
+#else
/* 369 */
+#endif
/* 370 */
/* 371 */
+#if DARWIN_VERS >= DARWIN_10_6
+#define __NR___thread_selfid VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(372) // was UX64
+#else
/* 372 */
+#endif
/* 373 */
/* 374 */
/* 375 */
#define __NR___mac_mount VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(424)
#define __NR___mac_get_mount VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(425)
#define __NR___mac_getfsstat VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(426)
+#if DARWIN_VERS >= DARWIN_10_6
+#define __NR_fsgetpath VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(427)
+#define __NR_audit_session_self VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(428)
+#define __NR_audit_session_join VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(429)
+#endif
+
+#if DARWIN_VERS < DARWIN_10_6
#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(427)
+#elif DARWIN_VERSION < DARWIN_10_7
+#define __NR_MAXSYSCALL VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(430)
+#else
+#error unknown darwin version
+#endif
#define __NR_DARWIN_FAKE_SIGRETURN (1 + __NR_MAXSYSCALL)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
lackey_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(lackey_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(lackey_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
lackey_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(lackey_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(lackey_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
massif_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(massif_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(massif_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
massif_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(massif_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(massif_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
memcheck_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(memcheck_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(memcheck_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
memcheck_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(memcheck_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(memcheck_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)
if VGCONF_PLATFORMS_INCLUDE_X86_LINUX
SUBDIRS += x86-linux
endif
+if VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX
+SUBDIRS += amd64-linux
+endif
-DIST_SUBDIRS = x86 amd64 linux darwin x86-linux .
+DIST_SUBDIRS = x86 amd64 linux darwin x86-linux amd64-linux .
dist_noinst_SCRIPTS = \
filter_addressable \
--- /dev/null
+
+include $(top_srcdir)/Makefile.tool-tests.am
+
+dist_noinst_SCRIPTS = \
+ filter_stderr
+
+noinst_HEADERS = scalar.h
+
+EXTRA_DIST = \
+ defcaexpr.vgtest defcaexpr.stderr.exp \
+ int3-x86.vgtest int3-x86.stderr.exp int3-x86.stdout.exp
+
+check_PROGRAMS = \
+ defcaexpr \
+ int3-amd64
+
+
+AM_CFLAGS += @FLAG_M32@ $(FLAG_MMMX) $(FLAG_MSSE)
+AM_CXXFLAGS += @FLAG_M32@ $(FLAG_MMMX) $(FLAG_MSSE)
+AM_CCASFLAGS += @FLAG_M32@
+
xor-undef-amd64.stderr.exp xor-undef-amd64.stdout.exp \
xor-undef-amd64.vgtest
-check_PROGRAMS = bt_everything bug132146 fxsave-amd64 \
- xor-undef-amd64
+check_PROGRAMS = \
+ bt_everything \
+ bug132146 \
+ fxsave-amd64 \
+ more_x87_fp \
+ sse_memory \
+ xor-undef-amd64
-# DDD: not sure if these ones should work on Darwin or not... if not, should
-# be moved into amd64-linux/.
+# DDD: these should be moved into amd64-linux/.
if ! VGCONF_OS_IS_DARWIN
check_PROGRAMS += \
defcfaexpr \
- int3-amd64 \
- more_x87_fp \
- sse_memory
+ int3-amd64
endif
AM_CFLAGS += @FLAG_M64@
-
Conditional jump or move depends on uninitialised value(s)
at 0x........: main (xor-undef-amd64.c:17)
Conditional jump or move depends on uninitialised value(s)
at 0x........: main (xor-undef-amd64.c:117)
-
-HEAP SUMMARY:
- in use at exit: 0 bytes in 0 blocks
- total heap usage: 1 allocs, 1 frees, 48 bytes allocated
-
-For a detailed leak analysis, rerun with: --leak-check=full
-
-For counts of detected and suppressed errors, rerun with: -v
-Use --track-origins=yes to see where uninitialised values come from
-ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
prog: xor-undef-amd64
+vgopts: -q
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
none_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_PRI@ \
$(LINK) \
$(none_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS) \
$(none_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS)
$(TOOL_LDFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
none_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LINK = \
$(top_builddir)/coregrind/link_tool_exe_@VGCONF_OS@ \
- @VALT_LOAD_ADDRESS@ \
+ @VALT_LOAD_ADDRESS_SEC@ \
$(LINK) \
$(none_@VGCONF_ARCH_SEC@_@VGCONF_OS@_CFLAGS) \
$(none_@VGCONF_ARCH_SEC@_@VGCONF_OS@_LDFLAGS)