[valgrind-variant] r129 committed - Merge with trunk Valgrind r12307 VEX r2233

3 views
Skip to first unread message

valgrind...@googlecode.com

unread,
Dec 14, 2011, 3:39:50 AM12/14/11
to valgrind-var...@googlegroups.com
Revision: 129
Author: sams...@google.com
Date: Wed Dec 14 00:38:07 2011
Log: Merge with trunk Valgrind r12307 VEX r2233
http://code.google.com/p/valgrind-variant/source/detail?r=129

Added:
/trunk/valgrind/auxprogs/update-demangler
/trunk/valgrind/coregrind/m_scheduler/priv_sched-lock-impl.h
/trunk/valgrind/coregrind/m_scheduler/priv_sched-lock.h
/trunk/valgrind/coregrind/m_scheduler/sched-lock-generic.c
/trunk/valgrind/coregrind/m_scheduler/sched-lock.c
/trunk/valgrind/coregrind/m_scheduler/ticket-lock-linux.c
/trunk/valgrind/drd/tests/annotate_smart_pointer2.stderr.exp
/trunk/valgrind/drd/tests/annotate_trace_memory.c
/trunk/valgrind/drd/tests/annotate_trace_memory.stderr.exp-32bit
/trunk/valgrind/drd/tests/annotate_trace_memory.stderr.exp-64bit
/trunk/valgrind/drd/tests/annotate_trace_memory_xml.stderr.exp-32bit
/trunk/valgrind/drd/tests/annotate_trace_memory_xml.stderr.exp-64bit
/trunk/valgrind/drd/tests/annotate_trace_memory_xml.vgtest
/trunk/valgrind/drd/tests/pth_barrier_thr_cr.c
/trunk/valgrind/drd/tests/std_thread.cpp
/trunk/valgrind/drd/tests/std_thread.stderr.exp
/trunk/valgrind/drd/tests/std_thread.vgtest
/trunk/valgrind/none/tests/allexec.c
/trunk/valgrind/none/tests/allexec32.stderr.exp
/trunk/valgrind/none/tests/allexec32.stdout.exp
/trunk/valgrind/none/tests/allexec32.vgtest
/trunk/valgrind/none/tests/allexec64.stderr.exp
/trunk/valgrind/none/tests/allexec64.stdout.exp
/trunk/valgrind/none/tests/allexec64.vgtest
/trunk/valgrind/none/tests/allexec_prepare_prereq
/trunk/valgrind/none/tests/amd64/allexec.c
/trunk/valgrind/none/tests/arm/allexec.c
/trunk/valgrind/none/tests/ppc32/allexec.c
/trunk/valgrind/none/tests/ppc64/allexec.c
/trunk/valgrind/none/tests/s390x/allexec.c
/trunk/valgrind/none/tests/x86/allexec.c
Deleted:
/trunk/valgrind/drd/tests/annotate_trace_memory.stderr.exp
Modified:
/trunk/valgrind/NEWS
/trunk/valgrind/VEX/priv/host_ppc_isel.c
/trunk/valgrind/auxprogs/Makefile.am
/trunk/valgrind/configure.in
/trunk/valgrind/coregrind/Makefile.am
/trunk/valgrind/coregrind/m_demangle/ansidecl.h
/trunk/valgrind/coregrind/m_demangle/cp-demangle.c
/trunk/valgrind/coregrind/m_demangle/cp-demangle.h
/trunk/valgrind/coregrind/m_demangle/cplus-dem.c
/trunk/valgrind/coregrind/m_demangle/demangle.c
/trunk/valgrind/coregrind/m_demangle/demangle.h
/trunk/valgrind/coregrind/m_demangle/dyn-string.c
/trunk/valgrind/coregrind/m_demangle/dyn-string.h
/trunk/valgrind/coregrind/m_main.c
/trunk/valgrind/coregrind/m_options.c
/trunk/valgrind/coregrind/m_scheduler/scheduler.c
/trunk/valgrind/coregrind/pub_core_options.h
/trunk/valgrind/drd/drd.h
/trunk/valgrind/drd/drd_barrier.c
/trunk/valgrind/drd/drd_barrier.h
/trunk/valgrind/drd/drd_basics.h
/trunk/valgrind/drd/drd_bitmap.c
/trunk/valgrind/drd/drd_bitmap.h
/trunk/valgrind/drd/drd_bitmap2_node.c
/trunk/valgrind/drd/drd_clientobj.c
/trunk/valgrind/drd/drd_clientobj.h
/trunk/valgrind/drd/drd_clientreq.c
/trunk/valgrind/drd/drd_clientreq.h
/trunk/valgrind/drd/drd_cond.c
/trunk/valgrind/drd/drd_cond.h
/trunk/valgrind/drd/drd_darwin_intercepts.c
/trunk/valgrind/drd/drd_error.c
/trunk/valgrind/drd/drd_error.h
/trunk/valgrind/drd/drd_hb.c
/trunk/valgrind/drd/drd_hb.h
/trunk/valgrind/drd/drd_load_store.c
/trunk/valgrind/drd/drd_load_store.h
/trunk/valgrind/drd/drd_main.c
/trunk/valgrind/drd/drd_malloc_wrappers.c
/trunk/valgrind/drd/drd_malloc_wrappers.h
/trunk/valgrind/drd/drd_mutex.c
/trunk/valgrind/drd/drd_mutex.h
/trunk/valgrind/drd/drd_pthread_intercepts.c
/trunk/valgrind/drd/drd_qtcore_intercepts.c
/trunk/valgrind/drd/drd_rwlock.c
/trunk/valgrind/drd/drd_rwlock.h
/trunk/valgrind/drd/drd_segment.c
/trunk/valgrind/drd/drd_segment.h
/trunk/valgrind/drd/drd_semaphore.c
/trunk/valgrind/drd/drd_semaphore.h
/trunk/valgrind/drd/drd_strmem_intercepts.c
/trunk/valgrind/drd/drd_suppression.c
/trunk/valgrind/drd/drd_suppression.h
/trunk/valgrind/drd/drd_thread.c
/trunk/valgrind/drd/drd_thread.h
/trunk/valgrind/drd/drd_thread_bitmap.h
/trunk/valgrind/drd/drd_vc.c
/trunk/valgrind/drd/drd_vc.h
/trunk/valgrind/drd/pub_drd_bitmap.h
/trunk/valgrind/drd/tests/Makefile.am
/trunk/valgrind/drd/tests/annotate_hb_err.c
/trunk/valgrind/drd/tests/annotate_hb_race.c
/trunk/valgrind/drd/tests/annotate_hbefore.vgtest
/trunk/valgrind/drd/tests/annotate_smart_pointer.cpp
/trunk/valgrind/drd/tests/annotate_trace_memory.vgtest
/trunk/valgrind/drd/tests/free_is_write.c
/trunk/valgrind/drd/tests/pth_cleanup_handler.c
/trunk/valgrind/drd/tests/unified_annotations.h
/trunk/valgrind/helgrind/tests/annotate_hbefore.vgtest
/trunk/valgrind/none/tests/Makefile.am
/trunk/valgrind/none/tests/amd64/Makefile.am
/trunk/valgrind/none/tests/arm/Makefile.am
/trunk/valgrind/none/tests/cmdline1.stdout.exp
/trunk/valgrind/none/tests/cmdline2.stdout.exp
/trunk/valgrind/none/tests/ppc32/Makefile.am
/trunk/valgrind/none/tests/ppc64/Makefile.am
/trunk/valgrind/none/tests/s390x/Makefile.am
/trunk/valgrind/none/tests/x86/Makefile.am

=======================================
--- /dev/null
+++ /trunk/valgrind/auxprogs/update-demangler Wed Dec 14 00:38:07 2011
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+set -e
+
+#---------------------------------------------------------------------
+# This quick and dirty script assists in updating the C++ demangler
+# machinery in coregrind/m_demangle.
+# The script will check out
+# - old and new revisions of the C++ demangler related files from GCC
+# - m_demangle from valgrind's trunk.
+# It will assemble
+# - a patch file with local changes that were applied to the C++
+# demangler to make it work within valgrind
+# - a directory new_m_demangle whose contents should be copied to
+# m_demangle in valgrind trunk
+# The patch will *not* be applied automacially.
+#---------------------------------------------------------------------
+
+# You need to modify these revision numbers for your update.
+old_gcc_revision=r141363 # the revision of the previous update
+new_gcc_revision=r181975 # the revision for this update
+
+# Unless the organization of demangler related files has changed, no
+# changes below this line should be necessary.
+
+# Setup a temp directory
+DIR=/tmp/demangle
+
+rm -rf $DIR
+mkdir -p $DIR
+
+cd $DIR
+
+echo "Updating the demangler in $DIR"
+
+# 1) Check out files from old GCC revision
+echo "Checking out GCC files @ $old_gcc_revision"
+
+mkdir gcc-$old_gcc_revision
+cd gcc-$old_gcc_revision
+svn co -$old_gcc_revision svn://gcc.gnu.org/svn/gcc/trunk/libiberty
libiberty > /dev/null
+svn co -$old_gcc_revision svn://gcc.gnu.org/svn/gcc/trunk/include
include > /dev/null
+rm -rf libiberty/.svn
+rm -rf include/.svn
+cd ..
+
+# 2) Assemble the ones we need in $DIR/$old_gcc_revision
+mkdir $old_gcc_revision
+cd $old_gcc_revision
+cp ../gcc-$old_gcc_revision/include/ansidecl.h .
+cp ../gcc-$old_gcc_revision/include/demangle.h .
+cp ../gcc-$old_gcc_revision/include/dyn-string.h .
+cp ../gcc-$old_gcc_revision/include/safe-ctype.h .
+cp ../gcc-$old_gcc_revision/libiberty/cp-demangle.c .
+cp ../gcc-$old_gcc_revision/libiberty/cp-demangle.h .
+cp ../gcc-$old_gcc_revision/libiberty/cplus-dem.c .
+cp ../gcc-$old_gcc_revision/libiberty/dyn-string.c .
+cp ../gcc-$old_gcc_revision/libiberty/safe-ctype.c .
+cd ..
+
+# 3) Check out files from new GCC revision
+
+echo "Checking out GCC files @ $new_gcc_revision"
+mkdir gcc-$new_gcc_revision
+cd gcc-$new_gcc_revision
+svn co -$new_gcc_revision svn://gcc.gnu.org/svn/gcc/trunk/libiberty
libiberty > /dev/null
+svn co -$new_gcc_revision svn://gcc.gnu.org/svn/gcc/trunk/include
include > /dev/null
+rm -rf libiberty/.svn
+rm -rf include/.svn
+cd ..
+
+# 4) Assemble the ones we need in $DIR/$new_gcc_revision
+
+mkdir $new_gcc_revision
+cd $new_gcc_revision
+cp ../gcc-$new_gcc_revision/include/ansidecl.h .
+cp ../gcc-$new_gcc_revision/include/demangle.h .
+cp ../gcc-$new_gcc_revision/include/dyn-string.h .
+cp ../gcc-$new_gcc_revision/include/safe-ctype.h .
+cp ../gcc-$new_gcc_revision/libiberty/cp-demangle.c .
+cp ../gcc-$new_gcc_revision/libiberty/cp-demangle.h .
+cp ../gcc-$new_gcc_revision/libiberty/cplus-dem.c .
+cp ../gcc-$new_gcc_revision/libiberty/dyn-string.c .
+cp ../gcc-$new_gcc_revision/libiberty/safe-ctype.c .
+cd ..
+
+# 5) Check out valgrind coregrind/m_demangle into old_m_demangle
+echo "Checking out coregrind/m_demangle"
+svn co svn://svn.valgrind.org/valgrind/trunk/coregrind/m_demangle
old_m_demangle > /dev/null
+rm -rf old_m_demangle/.svn
+
+# 6) Create new_m_demangle
+cp -rp old_m_demangle new_m_demangle
+cp -rp $new_gcc_revision/*.[ch] new_m_demangle
+
+# 7) Compare files from previous GCC revision against old_m_demangle
+# (This gets us the changes we made to the demangler).
+echo "Creating patch"
+set +e
+diff -r -u $old_gcc_revision old_m_demangle > our-changes
+echo "Patch file 'our-changes' created"
+
+# 7) See how the patch would apply
+echo "Attempting to apply the patch (but not actualy doing it)."
+cd new_m_demangle
+patch --dry -p1 < ../our-changes
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_scheduler/priv_sched-lock-impl.h Wed Dec 14
00:38:07 2011
@@ -0,0 +1,51 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Private scheduler lock header. priv_sched-lock-impl.h ---*/
+/*--- ---*/
+/*--- Scheduler lock implementation details. ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2011 Bart Van Assche <bvana...@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 __PRIV_SCHED_LOCK_IMPL_H
+#define __PRIV_SCHED_LOCK_IMPL_H
+
+struct sched_lock_ops {
+ const Char *(*get_sched_lock_name)(void);
+ struct sched_lock *(*create_sched_lock)(void);
+ void (*destroy_sched_lock)(struct sched_lock *p);
+ int (*get_sched_lock_owner)(struct sched_lock *p);
+ void (*acquire_sched_lock)(struct sched_lock *p);
+ void (*release_sched_lock)(struct sched_lock *p);
+};
+
+extern const struct sched_lock_ops ML_(generic_sched_lock_ops);
+extern const struct sched_lock_ops ML_(linux_ticket_lock_ops);
+
+#endif // __PRIV_SCHED_LOCK_IMPL_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_scheduler/priv_sched-lock.h Wed Dec 14
00:38:07 2011
@@ -0,0 +1,51 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Private scheduler lock header. priv_sched-lock.h ---*/
+/*--- ---*/
+/*--- Scheduler lock API. ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2011 Bart Van Assche <bvana...@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 __PRIV_SCHED_LOCK_H
+#define __PRIV_SCHED_LOCK_H
+
+struct sched_lock;
+
+enum SchedLockType { sched_lock_generic, sched_lock_ticket };
+
+Bool ML_(set_sched_lock_impl)(const enum SchedLockType t);
+const Char *ML_(get_sched_lock_name)(void);
+struct sched_lock *ML_(create_sched_lock)(void);
+void ML_(destroy_sched_lock)(struct sched_lock *p);
+int ML_(get_sched_lock_owner)(struct sched_lock *p);
+void ML_(acquire_sched_lock)(struct sched_lock *p);
+void ML_(release_sched_lock)(struct sched_lock *p);
+
+#endif // __PRIV_SCHED_LOCK_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_scheduler/sched-lock-generic.c Wed Dec 14
00:38:07 2011
@@ -0,0 +1,87 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Generic scheduler lock implementation sched-lock-generic.c ---*/
+/*--- ---*/
+/*--- This implementation does not guarantee fair scheduling on ---*/
+/*--- multicore systems but is sufficient to make the Valgrind ---*/
+/*--- scheduler work reasonably. ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2011 Bart Van Assche <bvana...@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_tool_mallocfree.h"
+#include "priv_sema.h"
+#include "priv_sched-lock.h"
+#include "priv_sched-lock-impl.h"
+
+struct sched_lock {
+ vg_sema_t sema;
+};
+
+static const Char *get_sched_lock_name(void)
+{
+ return "generic";
+}
+
+static struct sched_lock *create_sched_lock(void)
+{
+ struct sched_lock *p;
+
+ p = VG_(malloc)("sched_lock", sizeof(*p));
+ if (p)
+ ML_(sema_init)(&p->sema);
+ return p;
+}
+
+static void destroy_sched_lock(struct sched_lock *p)
+{
+ ML_(sema_deinit)(&p->sema);
+ VG_(free)(p);
+}
+
+static int get_sched_lock_owner(struct sched_lock *p)
+{
+ return p->sema.owner_lwpid;
+}
+
+static void acquire_sched_lock(struct sched_lock *p)
+{
+ ML_(sema_down)(&p->sema, False);
+}
+
+static void release_sched_lock(struct sched_lock *p)
+{
+ ML_(sema_up)(&p->sema, False);
+}
+
+const struct sched_lock_ops ML_(generic_sched_lock_ops) = {
+ .get_sched_lock_name = get_sched_lock_name,
+ .create_sched_lock = create_sched_lock,
+ .destroy_sched_lock = destroy_sched_lock,
+ .get_sched_lock_owner = get_sched_lock_owner,
+ .acquire_sched_lock = acquire_sched_lock,
+ .release_sched_lock = release_sched_lock,
+};
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_scheduler/sched-lock.c Wed Dec 14 00:38:07
2011
@@ -0,0 +1,96 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Scheduler lock support functions sched-lock.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2011 Bart Van Assche <bvana...@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 "config.h"
+#include "pub_core_basics.h"
+#include "pub_tool_libcbase.h"
+#include "pub_tool_mallocfree.h"
+#include "priv_sema.h"
+#include "priv_sched-lock.h"
+#include "priv_sched-lock-impl.h"
+
+static struct sched_lock_ops const *sched_lock_ops =
+ &ML_(generic_sched_lock_ops);
+
+static struct sched_lock_ops const *const sched_lock_impl[] = {
+ [sched_lock_generic] = &ML_(generic_sched_lock_ops),
+#ifdef ENABLE_LINUX_TICKET_LOCK
+ [sched_lock_ticket] = &ML_(linux_ticket_lock_ops),
+#endif
+};
+
+/**
+ * Define which scheduler lock implementation to use.
+ *
+ * @param[in] t Scheduler lock type.
+ *
+ * @return True if and only if this function succeeded.
+ *
+ * @note Must be called before any other sched_lock*() function is invoked.
+ */
+Bool ML_(set_sched_lock_impl)(const enum SchedLockType t)
+{
+ struct sched_lock_ops const *p = NULL;
+
+ if ((unsigned)t < sizeof(sched_lock_impl)/sizeof(sched_lock_impl[0]))
+ p = sched_lock_impl[t];
+ if (p)
+ sched_lock_ops = p;
+ return !!p;
+}
+
+const Char *ML_(get_sched_lock_name)(void)
+{
+ return (sched_lock_ops->get_sched_lock_name)();
+}
+
+struct sched_lock *ML_(create_sched_lock)(void)
+{
+ return (sched_lock_ops->create_sched_lock)();
+}
+
+void ML_(destroy_sched_lock)(struct sched_lock *p)
+{
+ return (sched_lock_ops->destroy_sched_lock)(p);
+}
+
+int ML_(get_sched_lock_owner)(struct sched_lock *p)
+{
+ return (sched_lock_ops->get_sched_lock_owner)(p);
+}
+
+void ML_(acquire_sched_lock)(struct sched_lock *p)
+{
+ return (sched_lock_ops->acquire_sched_lock)(p);
+}
+
+void ML_(release_sched_lock)(struct sched_lock *p)
+{
+ return (sched_lock_ops->release_sched_lock)(p);
+}
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_scheduler/ticket-lock-linux.c Wed Dec 14
00:38:07 2011
@@ -0,0 +1,185 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Linux ticket lock implementation ticket-lock-linux.c ---*/
+/*--- ---*/
+/*--- Guarantees fair scheduling even if multiple threads are ---*/
+/*--- runnable at the same time on a multicore system. Has been ---*/
+/*--- observed to cause a slow-down compared to the generic ---*/
+/*--- scheduler lock with CPU frequency scaling enabled. Makes ---*/
+/*--- Valgrind slightly faster if CPU frequency scaling has been ---*/
+/*--- disabled. See also http://bugs.kde.org/show_bug.cgi?id=270006---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2011 Bart Van Assche <bvana...@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_libcassert.h"
+#include "pub_core_libcbase.h" // VG_(memset)()
+#include "pub_core_libcprint.h"
+#include "pub_core_syscall.h"
+#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h" // __NR_futex
+#include "pub_tool_libcproc.h"
+#include "pub_tool_mallocfree.h"
+#include "pub_tool_threadstate.h"
+#include "priv_sched-lock.h"
+#include "priv_sched-lock-impl.h"
+
+#define TL_FUTEX_COUNT_LOG2 4
+#define TL_FUTEX_COUNT (1U << TL_FUTEX_COUNT_LOG2)
+#define TL_FUTEX_MASK (TL_FUTEX_COUNT - 1)
+
+struct sched_lock {
+ volatile unsigned head;
+ volatile unsigned tail;
+ volatile unsigned futex[TL_FUTEX_COUNT];
+ int owner;
+};
+
+#if 1
+static Bool s_debug;
+#else
+static Bool s_debug = True;
+#endif
+
+static const Char *get_sched_lock_name(void)
+{
+ return "ticket lock";
+}
+
+static struct sched_lock *create_sched_lock(void)
+{
+ struct sched_lock *p;
+
+ p = VG_(malloc)("sched_lock", sizeof(*p));
+ if (p) {
+ // The futex syscall requires that a futex takes four bytes.
+ vg_assert(sizeof(p->futex[0]) == 4);
+
+ p->head = 0;
+ p->tail = 0;
+ VG_(memset)((void*)p->futex, 0, sizeof(p->futex));
+ p->owner = 0;
+ }
+ return p;
+}
+
+static void destroy_sched_lock(struct sched_lock *p)
+{
+ VG_(free)(p);
+}
+
+static int get_sched_lock_owner(struct sched_lock *p)
+{
+ return p->owner;
+}
+
+/*
+ * Acquire ticket lock. Increment the tail of the queue and use the
original
+ * value as the ticket value. Wait until the head of the queue equals the
+ * ticket value. The futex used to wait depends on the ticket value in
order
+ * to avoid that all threads get woken up every time a ticket lock is
+ * released. That last effect is sometimes called the "thundering herd"
+ * effect.
+ *
+ * See also Nick Piggin, x86: FIFO ticket spinlocks, Linux kernel mailing
list
+ * (http://lkml.org/lkml/2007/11/1/125) for more info.
+ */
+static void acquire_sched_lock(struct sched_lock *p)
+{
+ unsigned ticket, futex_value;
+ volatile unsigned *futex;
+ SysRes sres;
+
+ ticket = __sync_fetch_and_add(&p->tail, 1);
+ futex = &p->futex[ticket & TL_FUTEX_MASK];
+ if (s_debug)
+ VG_(printf)("[%d/%d] acquire: ticket %d\n", VG_(getpid)(),
+ VG_(gettid)(), ticket);
+ for (;;) {
+ futex_value = *futex;
+ if (ticket == p->head)
+ break;
+ if (s_debug)
+ VG_(printf)("[%d/%d] acquire: ticket %d - waiting until"
+ " futex[%ld] != %d\n", VG_(getpid)(),
+ VG_(gettid)(), ticket, (long)(futex - p->futex),
+ futex_value);
+ sres = VG_(do_syscall3)(__NR_futex, (UWord)futex,
+ VKI_FUTEX_WAIT | VKI_FUTEX_PRIVATE_FLAG,
+ futex_value);
+ if (sr_isError(sres) && sres._val != VKI_EAGAIN) {
+ VG_(printf)("futex_wait() returned error code %ld\n", sres._val);
+ vg_assert(False);
+ }
+ }
+ vg_assert(p->owner == 0);
+ p->owner = VG_(gettid)();
+}
+
+/*
+ * Release a ticket lock by incrementing the head of the queue. Only
generate
+ * a thread wakeup signal if at least one thread is waiting. If the queue
tail
+ * matches the wakeup_ticket value, no threads have to be woken up.
+ *
+ * Note: tail will only be read after head has been incremented since both
are
+ * declared as volatile and since the __sync...() functions imply a memory
+ * barrier.
+ */
+static void release_sched_lock(struct sched_lock *p)
+{
+ unsigned wakeup_ticket, futex_value;
+ volatile unsigned *futex;
+ SysRes sres;
+
+ vg_assert(p->owner != 0);
+ p->owner = 0;
+ wakeup_ticket = __sync_fetch_and_add(&p->head, 1) + 1;
+ if (p->tail != wakeup_ticket) {
+ futex = &p->futex[wakeup_ticket & TL_FUTEX_MASK];
+ futex_value = __sync_fetch_and_add(futex, 1);
+ if (s_debug)
+ VG_(printf)("[%d/%d] release: waking up ticket %d (futex[%ld]
= %d)"
+ "\n", VG_(getpid)(), VG_(gettid)(), wakeup_ticket,
+ (long)(futex - p->futex), futex_value);
+ sres = VG_(do_syscall3)(__NR_futex, (UWord)futex,
+ VKI_FUTEX_WAKE | VKI_FUTEX_PRIVATE_FLAG,
+ 0x7fffffff);
+ vg_assert(!sr_isError(sres));
+ } else {
+ if (s_debug)
+ VG_(printf)("[%d/%d] release: no thread is waiting for
ticket %d\n",
+ VG_(getpid)(), VG_(gettid)(), wakeup_ticket);
+ }
+}
+
+const struct sched_lock_ops ML_(linux_ticket_lock_ops) = {
+ .get_sched_lock_name = get_sched_lock_name,
+ .create_sched_lock = create_sched_lock,
+ .destroy_sched_lock = destroy_sched_lock,
+ .get_sched_lock_owner = get_sched_lock_owner,
+ .acquire_sched_lock = acquire_sched_lock,
+ .release_sched_lock = release_sched_lock,
+};
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/annotate_smart_pointer2.stderr.exp Wed Dec 14
00:38:07 2011
@@ -0,0 +1,13 @@
+
+Conflicting store by thread x at 0x........ size 4
+ at 0x........: counter::~counter() (annotate_smart_pointer.cpp:?)
+ by 0x........: smart_ptr<counter>::set(counter*, AtomicInt32*)
(annotate_smart_pointer.cpp:?)
+ by 0x........: smart_ptr<counter>::operator=(counter*)
(annotate_smart_pointer.cpp:?)
+ by 0x........: main (annotate_smart_pointer.cpp:?)
+Address 0x........ is at offset ... from 0x......... Allocation context:
+ at 0x........: ...operator new... (vg_replace_malloc.c:...)
+ by 0x........: main (annotate_smart_pointer.cpp:?)
+
+Done.
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/annotate_trace_memory.c Wed Dec 14 00:38:07
2011
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <inttypes.h>
+#include "../../drd/drd.h"
+
+volatile float f;
+volatile double d;
+volatile int8_t i8;
+volatile int16_t i16;
+volatile int32_t i32;
+volatile int64_t i64;
+
+int main(int argc, char** argv)
+{
+ DRD_TRACE_VAR(f);
+ DRD_TRACE_VAR(d);
+ DRD_TRACE_VAR(i8);
+ DRD_TRACE_VAR(i16);
+ DRD_TRACE_VAR(i32);
+ DRD_TRACE_VAR(i64);
+
+ fprintf(stderr, "float\n");
+ f = 1;
+ f += 2;
+ fprintf(stderr, "double\n");
+ d = 3;
+ d += 4;
+ fprintf(stderr, "uint8_t\n");
+ i8 = 5;
+ i8 += 6;
+ fprintf(stderr, "uint16_t\n");
+ i16 = 7;
+ i16++;
+ fprintf(stderr, "uint32_t\n");
+ i32 = 8;
+ __sync_add_and_fetch(&i32, 1);
+ fprintf(stderr, "uint64_t\n");
+ i64 = 9;
+ __sync_add_and_fetch(&i64, 0x12345678ULL);
+
+ DRD_STOP_TRACE_VAR(f);
+ DRD_STOP_TRACE_VAR(d);
+ DRD_STOP_TRACE_VAR(i8);
+ DRD_STOP_TRACE_VAR(i16);
+ DRD_STOP_TRACE_VAR(i32);
+ DRD_STOP_TRACE_VAR(i64);
+
+ fprintf(stderr, "Done.\n");
+ return 0;
+}
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/annotate_trace_memory.stderr.exp-32bit Wed
Dec 14 00:38:07 2011
@@ -0,0 +1,50 @@
+
+float
+store 0x........ size 4 val 1065353216/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 4 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 4 val 1077936128/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+double
+store 0x........ size 8 val 4613937818241073152/0x........ (thread x /
vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 8 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 8 val 4619567317775286272/0x........ (thread x /
vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint8_t
+store 0x........ size 1 val 5/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 1 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 1 val 11/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint16_t
+store 0x........ size 2 val 7/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 2 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 2 val 8/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint32_t
+store 0x........ size 4 val 8/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 4 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 4 val 9/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint64_t
+store 0x........ size 4 val 9/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 4 val 0/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 4 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 4 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 4 val 305419905/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+Done.
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/annotate_trace_memory.stderr.exp-64bit Wed
Dec 14 00:38:07 2011
@@ -0,0 +1,46 @@
+
+float
+store 0x........ size 4 val 1065353216/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 4 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 4 val 1077936128/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+double
+store 0x........ size 8 val 4613937818241073152/0x........ (thread x /
vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 8 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 8 val 4619567317775286272/0x........ (thread x /
vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint8_t
+store 0x........ size 1 val 5/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 1 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 1 val 11/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint16_t
+store 0x........ size 2 val 7/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 2 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 2 val 8/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint32_t
+store 0x........ size 4 val 8/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 4 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 4 val 9/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+uint64_t
+store 0x........ size 8 val 9/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+load 0x........ size 8 (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+store 0x........ size 8 val 305419905/0x........ (thread x / vc ...)
+ at 0x........: main (annotate_trace_memory.c:?)
+Done.
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/annotate_trace_memory_xml.stderr.exp-32bit
Wed Dec 14 00:38:07 2011
@@ -0,0 +1,290 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+ <line>...</line>
+ <line>...</line>
+ <line>...</line>
+ <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+ <vargv>...</vargv>
+ <argv>
+ <exe>./annotate_trace_memory</exe>
+ </argv>
+</args>
+
+<status>
+ <state>RUNNING</state>
+ <time>...</time>
+</status>
+
+float
+ <trace><text>store 0x........ size 4 val 1065353216/0x........ (thread x
/ vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 4 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 4 val 1077936128/0x........ (thread x
/ vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+double
+ <trace><text>store 0x........ size 8 val 4613937818241073152/0x........
(thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 8 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 8 val 4619567317775286272/0x........
(thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint8_t
+ <trace><text>store 0x........ size 1 val 5/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 1 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 1 val 11/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint16_t
+ <trace><text>store 0x........ size 2 val 7/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 2 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 2 val 8/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint32_t
+ <trace><text>store 0x........ size 4 val 8/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 4 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 4 val 9/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint64_t
+ <trace><text>store 0x........ size 4 val 9/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 4 val 0/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 4 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 4 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 4 val 305419905/0x........ (thread x
/ vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+Done.
+
+<status>
+ <state>FINISHED</state>
+ <time>...</time>
+</status>
+
+<errorcounts>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/annotate_trace_memory_xml.stderr.exp-64bit
Wed Dec 14 00:38:07 2011
@@ -0,0 +1,266 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>drd</protocoltool>
+
+<preamble>
+ <line>...</line>
+ <line>...</line>
+ <line>...</line>
+ <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>drd</tool>
+
+<args>
+ <vargv>...</vargv>
+ <argv>
+ <exe>./annotate_trace_memory</exe>
+ </argv>
+</args>
+
+<status>
+ <state>RUNNING</state>
+ <time>...</time>
+</status>
+
+float
+ <trace><text>store 0x........ size 4 val 1065353216/0x........ (thread x
/ vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 4 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 4 val 1077936128/0x........ (thread x
/ vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+double
+ <trace><text>store 0x........ size 8 val 4613937818241073152/0x........
(thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 8 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 8 val 4619567317775286272/0x........
(thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint8_t
+ <trace><text>store 0x........ size 1 val 5/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 1 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 1 val 11/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint16_t
+ <trace><text>store 0x........ size 2 val 7/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 2 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 2 val 8/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint32_t
+ <trace><text>store 0x........ size 4 val 8/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 4 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 4 val 9/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+uint64_t
+ <trace><text>store 0x........ size 8 val 9/0x........ (thread x /
vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>load 0x........ size 8 (thread x / vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+ <trace><text>store 0x........ size 8 val 305419905/0x........ (thread x
/ vc ...)</text>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>annotate_trace_memory.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ </trace>
+Done.
+
+<status>
+ <state>FINISHED</state>
+ <time>...</time>
+</status>
+
+<errorcounts>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/annotate_trace_memory_xml.vgtest Wed Dec 14
00:38:07 2011
@@ -0,0 +1,4 @@
+prereq: test -e annotate_trace_memory && ./supported_libpthread
+vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no
--num-callers=2 --xml=yes --xml-fd=2
+prog: annotate_trace_memory
+stderr_filter: ./filter_xml_and_thread_no
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/pth_barrier_thr_cr.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,58 @@
+/*
+ * Test program that triggers pthread_barrier_wait() where each
+ * pthread_barrier_wait() call is invoked by another thread. This is the
only
+ * test program that triggers the code guarded by if (q->thread_finished)
in
+ * DRD_(barrier_pre_wait)().
+ */
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static pthread_barrier_t* s_barrier;
+
+static void* thread(void* arg)
+{
+ write(STDOUT_FILENO, ".", 1);
+ pthread_barrier_wait(s_barrier);
+ return NULL;
+}
+
+int main(int argc, char** argv)
+{
+ pthread_t *tid;
+ int barriers = argc > 1 ? atoi(argv[1]) : 20;
+ int barrier_participants = 2;
+ int thread_count = barriers * barrier_participants;
+ int res, i;
+
+ s_barrier = malloc(sizeof(*s_barrier));
+ res = pthread_barrier_init(s_barrier, NULL, barrier_participants);
+ assert(res == 0);
+
+ tid = malloc(thread_count * sizeof(*tid));
+ assert(tid);
+ for (i = 0; i < thread_count; i++) {
+ res = pthread_create(&tid[i], NULL, thread, NULL);
+ assert(res == 0);
+ }
+ for (i = 0; i < thread_count; i++) {
+ res = pthread_join(tid[i], NULL);
+ assert(res == 0);
+ }
+ free(tid);
+
+ res = pthread_barrier_destroy(s_barrier);
+ assert(res == 0);
+ free(s_barrier);
+ s_barrier = NULL;
+
+ write(STDOUT_FILENO, "\n", 1);
+ fprintf(stderr, "Done.\n");
+
+ return 0;
+}
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/std_thread.cpp Wed Dec 14 00:38:07 2011
@@ -0,0 +1,23 @@
+// Test whether no race conditions are reported on std::thread. Note: since
+// the implementation of std::thread uses the shared pointer
implementation,
+// that implementation has to be annotated in order to avoid false
positives.
+// See also http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html for
more
+// information.
+
+#include "../../drd/drd.h"
+#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(addr) \
+ ANNOTATE_HAPPENS_BEFORE(addr)
+#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(addr) \
+ ANNOTATE_HAPPENS_AFTER(addr)
+#define _GLIBCXX_EXTERN_TEMPLATE -1
+
+#include <iostream>
+#include <thread>
+
+int main(int argc, char** argv)
+{
+ std::thread t( []() { } );
+ t.join();
+ std::cerr << "Done.\n";
+ return 0;
+}
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/std_thread.stderr.exp Wed Dec 14 00:38:07 2011
@@ -0,0 +1,4 @@
+
+Done.
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
=======================================
--- /dev/null
+++ /trunk/valgrind/drd/tests/std_thread.vgtest Wed Dec 14 00:38:07 2011
@@ -0,0 +1,4 @@
+prereq: false && test -e std_thread && ./supported_libpthread
+vgopts: --check-stack-var=yes --show-confl-seg=no
+prog: std_thread
+stderr_filter: filter_stderr
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,50 @@
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+extern char **environ;
+
+#define S(...) (fprintf(stdout, __VA_ARGS__),fflush(stdout))
+#define FORKEXECWAIT(exec_call) do { \
+ int status;\
+ pid_t child = fork(); \
+ if (child == 0) {exec_call; perror ("exec failed");} \
+ else if (child == -1) perror ("cannot fork\n"); \
+ else if (child != wait (&status)) perror ("error waiting child"); \
+ else S("child exited\n"); \
+ } while (0)
+
+void test_allexec (char *exec)
+{
+ FORKEXECWAIT (execlp(exec, exec, NULL));
+ FORKEXECWAIT (execlp(exec, exec, "constant_arg1", "constant_arg2",
NULL));
+ FORKEXECWAIT (execve(exec, NULL, environ));
+}
+
+
+/* If a single argument "exec" is given, will execute itself
+ (in bi-arch, a 32 bit and 64 bit variant) via various exec system calls.
+ Note that this test can only be run after the prerequisite have been
+ prepared by allexec_prepare_prereq, which will a.o. make links
+ for the allexec32 and allexec64 executables. On single arch build,
+ these links points to the same executable to ensure this test works
+ everywhere the same.
+ No arguments or more arguments means just print its args. */
+int main(int argc, char **argv, char **envp)
+{
+ if ( (argc == 2) && (strcmp (argv[1], "exec") == 0)) {
+ S("%s will exec ./allexec32\n", argv[0]);
+ test_allexec ("./allexec32");
+ S("%s will exec ./allexec64\n", argv[0]);
+ test_allexec ("./allexec64");
+ } else {
+ int i;
+ S("program exec-ed:");
+ for (i = 0; i < argc; i++) S(" %s", argv[i]);
+ S("\n");
+ }
+ return 0;
+}
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec32.stderr.exp Wed Dec 14 00:38:07 2011
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec32.stdout.exp Wed Dec 14 00:38:07 2011
@@ -0,0 +1,14 @@
+./allexec32 will exec ./allexec32
+program exec-ed: ./allexec32
+child exited
+program exec-ed: ./allexec32 constant_arg1 constant_arg2
+child exited
+program exec-ed: ./allexec32
+child exited
+./allexec32 will exec ./allexec64
+program exec-ed: ./allexec64
+child exited
+program exec-ed: ./allexec64 constant_arg1 constant_arg2
+child exited
+program exec-ed: ./allexec64
+child exited
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec32.vgtest Wed Dec 14 00:38:07 2011
@@ -0,0 +1,4 @@
+prog: allexec32
+args: exec
+vgopts: --trace-children=yes
+prereq: ./allexec_prepare_prereq
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec64.stderr.exp Wed Dec 14 00:38:07 2011
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec64.stdout.exp Wed Dec 14 00:38:07 2011
@@ -0,0 +1,14 @@
+./allexec64 will exec ./allexec32
+program exec-ed: ./allexec32
+child exited
+program exec-ed: ./allexec32 constant_arg1 constant_arg2
+child exited
+program exec-ed: ./allexec32
+child exited
+./allexec64 will exec ./allexec64
+program exec-ed: ./allexec64
+child exited
+program exec-ed: ./allexec64 constant_arg1 constant_arg2
+child exited
+program exec-ed: ./allexec64
+child exited
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec64.vgtest Wed Dec 14 00:38:07 2011
@@ -0,0 +1,4 @@
+prog: allexec64
+args: exec
+vgopts: --trace-children=yes
+prereq: ./allexec_prepare_prereq
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/allexec_prepare_prereq Wed Dec 14 00:38:07
2011
@@ -0,0 +1,36 @@
+#! /bin/sh
+
+# prepare the hard or soft link allexec32 and allexec64
+# On 'single arch' compiled Valgrind, allexec32 and allexec64 will point
+# to the same executable.
+# On 'bi-arch', they will point respectively to the executable compiled
+# for the revelant arch.
+# This allows to test the various exec system calls the same way.
+
+
+pair()
+{
+ if ../../tests/arch_test $1 || ../../tests/arch_test $2
+ then
+ if ../../tests/arch_test $1
+ then
+ ln -f $1/allexec allexec32
+ else
+ ln -f -s allexec64 allexec32
+ fi
+ if ../../tests/arch_test $2
+ then
+ ln -f $2/allexec allexec64
+ else
+ ln -f -s allexec32 allexec64
+ fi
+ fi
+}
+
+
+pair x86 amd64
+pair ppc32 ppc64
+pair s390x_unexisting_in_32bits s390x
+pair arm arm_unexisting_in_64bits
+
+exit 0
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/amd64/allexec.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,1 @@
+link ../allexec.c
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/arm/allexec.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,1 @@
+link ../allexec.c
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/ppc32/allexec.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,1 @@
+link ../allexec.c
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/ppc64/allexec.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,1 @@
+link ../allexec.c
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/s390x/allexec.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,1 @@
+link ../allexec.c
=======================================
--- /dev/null
+++ /trunk/valgrind/none/tests/x86/allexec.c Wed Dec 14 00:38:07 2011
@@ -0,0 +1,1 @@
+link ../allexec.c
=======================================
--- /trunk/valgrind/drd/tests/annotate_trace_memory.stderr.exp Mon Jun 7
07:06:05 2010
+++ /dev/null
@@ -1,20 +0,0 @@
-
-FLAGS [phb=1, fm=0]
-test01: positive
-store 0x........ size 4 (thread x / vc ...)
- at 0x........: test01::Worker() (tsan_unittest.cpp:?)
- by 0x........: MyThread::ThreadBody(MyThread*)
(tsan_thread_wrappers_pthread.h:?)
-store 0x........ size 4 (thread x / vc ...)
- at 0x........: test01::Parent() (tsan_unittest.cpp:?)
- by 0x........: test01::Run() (tsan_unittest.cpp:?)
-Conflicting store by thread x at 0x........ size 4
- at 0x........: test01::Parent() (tsan_unittest.cpp:?)
- by 0x........: test01::Run() (tsan_unittest.cpp:?)
-Allocation context: BSS section of tsan_unittest
-
-load 0x........ size 4 (thread x / vc ...)
- at 0x........: test01::Run() (tsan_unittest.cpp:?)
- by 0x........: main (tsan_unittest.cpp:?)
- GLOB=2
-
-ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
=======================================
--- /trunk/valgrind/NEWS Mon Dec 12 00:02:05 2011
+++ /trunk/valgrind/NEWS Wed Dec 14 00:38:07 2011
@@ -1,6 +1,14 @@
Release 3.7.1 (????)
~~~~~~~~~~~~~~~~~~~~

+* ================== PLATFORM CHANGES =================
+
+* ==================== TOOL CHANGES ====================
+
+* ==================== OTHER CHANGES ====================
+
+* The C++ demangler has been updated so as to work well with C++
+ compiled by even the most recent g++'s.

* ==================== FIXED BUGS ====================

@@ -16,6 +24,7 @@
where XXXXXX is the bug number as listed below.

286374 Running cachegrind with --branch-sim=yes on 64-bit PowerPC program
fails
+283413 Fix wrong sanity check

=======================================
--- /trunk/valgrind/VEX/priv/host_ppc_isel.c Tue Oct 25 09:11:36 2011
+++ /trunk/valgrind/VEX/priv/host_ppc_isel.c Wed Dec 14 00:38:07 2011
@@ -1698,13 +1698,16 @@
return rLo; /* similar stupid comment to the above ... */
}
break;
+ case Iop_1Uto64:
case Iop_1Uto32:
- case Iop_1Uto8: {
- HReg r_dst = newVRegI(env);
- PPCCondCode cond = iselCondCode(env, e->Iex.Unop.arg);
- addInstr(env, PPCInstr_Set(cond,r_dst));
- return r_dst;
- }
+ case Iop_1Uto8:
+ if ((op_unop != Iop_1Uto64) || mode64) {
+ HReg r_dst = newVRegI(env);
+ PPCCondCode cond = iselCondCode(env, e->Iex.Unop.arg);
+ addInstr(env, PPCInstr_Set(cond,r_dst));
+ return r_dst;
+ }
+ break;
case Iop_1Sto8:
case Iop_1Sto16:
case Iop_1Sto32: {
=======================================
--- /trunk/valgrind/auxprogs/Makefile.am Mon Dec 12 00:02:05 2011
+++ /trunk/valgrind/auxprogs/Makefile.am Wed Dec 14 00:38:07 2011
@@ -7,6 +7,7 @@
gsl16test \
gsl19test \
nightly-build-summary \
+ update-demangler \
posixtestsuite-1.5.1-diff-results

EXTRA_DIST = \
=======================================
--- /trunk/valgrind/configure.in Mon Dec 12 00:02:05 2011
+++ /trunk/valgrind/configure.in Wed Dec 14 00:38:07 2011
@@ -1646,10 +1646,12 @@
]], [[
return FUTEX_WAIT;
]])], [
+ac_have_usable_linux_futex_h=yes
AC_DEFINE([HAVE_USABLE_LINUX_FUTEX_H], 1,
[Define to 1 if you have a usable <linux/futex.h> header file.])
AC_MSG_RESULT([yes])
], [
+ac_have_usable_linux_futex_h=no
AC_MSG_RESULT([no])
])

@@ -1889,8 +1891,9 @@
AM_CONDITIONAL([HAVE_OPENMP], [test x$ac_have_openmp = xyes])


-# does this compiler have built-in functions for atomic memory access ?
-AC_MSG_CHECKING([if gcc supports __sync_bool_compare_and_swap])
+# does this compiler have built-in functions for atomic memory access for
the
+# primary target ?
+AC_MSG_CHECKING([if gcc supports __sync_add_and_fetch for the primary
target])

safe_CFLAGS=$CFLAGS
CFLAGS="$mflag_primary"
@@ -1900,20 +1903,51 @@
return (__sync_bool_compare_and_swap(&variable, 1, 2)
&& __sync_add_and_fetch(&variable, 1) ? 1 : 0)
]])], [
- ac_have_builtin_atomic=yes
+ ac_have_builtin_atomic_primary=yes
AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Define to 1 if gcc supports
__sync_bool_compare_and_swap() and __sync_add_and_fetch()])
+ AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Define to 1 if gcc supports
__sync_bool_compare_and_swap() and __sync_add_and_fetch() for the primary
target])
], [
- ac_have_builtin_atomic=no
+ ac_have_builtin_atomic_primary=no
AC_MSG_RESULT([no])
])

CFLAGS=$safe_CFLAGS

-AM_CONDITIONAL([HAVE_BUILTIN_ATOMIC], [test x$ac_have_builtin_atomic =
xyes])
+AM_CONDITIONAL([HAVE_BUILTIN_ATOMIC],
+ [test x$ac_have_builtin_atomic_primary = xyes])
+
+
+# does this compiler have built-in functions for atomic memory access for
the
+# secondary target ?
+
+if test x$VGCONF_PLATFORM_SEC_CAPS != x; then
+
+AC_MSG_CHECKING([if gcc supports __sync_add_and_fetch for the secondary
target])
+
+safe_CFLAGS=$CFLAGS
+CFLAGS="$mflag_secondary"
+
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
+ int variable = 1;
+ return (__sync_add_and_fetch(&variable, 1) ? 1 : 0)
+]])], [
+ ac_have_builtin_atomic_secondary=yes
+ AC_MSG_RESULT([yes])
+], [
+ ac_have_builtin_atomic_secondary=no
+ AC_MSG_RESULT([no])
+])
+
+CFLAGS=$safe_CFLAGS
+
+fi
+
+AM_CONDITIONAL([HAVE_BUILTIN_ATOMIC_SECONDARY],
+ [test x$ac_have_builtin_atomic_secondary = xyes])
+

# does g++ have built-in functions for atomic memory access ?
-AC_MSG_CHECKING([if g++ supports __sync_bool_compare_and_swap])
+AC_MSG_CHECKING([if g++ supports __sync_add_and_fetch])

safe_CXXFLAGS=$CXXFLAGS
CXXFLAGS="$mflag_primary"
@@ -1937,6 +1971,70 @@

AM_CONDITIONAL([HAVE_BUILTIN_ATOMIC_CXX], [test
x$ac_have_builtin_atomic_cxx = xyes])

+
+if test x$ac_have_usable_linux_futex_h = xyes \
+ -a x$ac_have_builtin_atomic_primary = xyes; then
+ ac_enable_linux_ticket_lock_primary=yes
+fi
+AM_CONDITIONAL([ENABLE_LINUX_TICKET_LOCK_PRIMARY],
+ [test x$ac_enable_linux_ticket_lock_primary = xyes])
+
+if test x$VGCONF_PLATFORM_SEC_CAPS != x \
+ -a x$ac_have_usable_linux_futex_h = xyes \
+ -a x$ac_have_builtin_atomic_secondary = xyes; then
+ ac_enable_linux_ticket_lock_secondary=yes
+fi
+AM_CONDITIONAL([ENABLE_LINUX_TICKET_LOCK_SECONDARY],
+ [test x$ac_enable_linux_ticket_lock_secondary = xyes])
+
+
+# does libstdc++ support annotating shared pointers ?
+AC_MSG_CHECKING([if libstdc++ supports annotating shared pointers])
+
+safe_CXXFLAGS=$CFLAGS
+CXXFLAGS="-std=c++0x"
+
+AC_LANG_PUSH(C++)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include <memory>
+]], [[
+ std::shared_ptr<int> p
+]])], [
+ ac_have_shared_ptr=yes
+], [
+ ac_have_shared_ptr=no
+])
+if test x$ac_have_shared_ptr = xyes; then
+ # If compilation of the program below fails because of a syntax error
+ # triggered by substituting one of the annotation macros then that
+ # means that libstdc++ supports these macros.
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(a) (a)----
+ #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(a) (a)----
+ #include <memory>
+ ]], [[
+ std::shared_ptr<int> p
+ ]])], [
+ ac_have_shared_pointer_annotation=no
+ AC_MSG_RESULT([no])
+ ], [
+ ac_have_shared_pointer_annotation=yes
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_SHARED_POINTER_ANNOTATION, 1,
+ [Define to 1 if libstd++ supports annotating shared
pointers])
+ ])
+else
+ ac_have_shared_pointer_annotation=no
+ AC_MSG_RESULT([no])
+fi
+AC_LANG_POP(C++)
+
+CXXFLAGS=$safe_CXXFLAGS
+
+AM_CONDITIONAL([HAVE_SHARED_POINTER_ANNOTATION],
+ [test x$ac_have_shared_pointer_annotation = xyes])
+
+

#----------------------------------------------------------------------------
# Ok. We're done checking.

#----------------------------------------------------------------------------
=======================================
--- /trunk/valgrind/coregrind/Makefile.am Mon Dec 12 00:02:05 2011
+++ /trunk/valgrind/coregrind/Makefile.am Wed Dec 14 00:38:07 2011
@@ -214,6 +214,8 @@
m_initimg/priv_initimg_pathscan.h \
m_initimg/simple_huffman.c \
m_scheduler/priv_sema.h \
+ m_scheduler/priv_sched-lock.h \
+ m_scheduler/priv_sched-lock-impl.h \
m_syswrap/priv_types_n_macros.h \
m_syswrap/priv_syswrap-generic.h \
m_syswrap/priv_syswrap-linux.h \
@@ -327,6 +329,8 @@
m_replacemalloc/replacemalloc_core.c \
m_scheduler/scheduler.c \
m_scheduler/sema.c \
+ m_scheduler/sched-lock.c \
+ m_scheduler/sched-lock-generic.c \
m_sigframe/sigframe-x86-linux.c \
m_sigframe/sigframe-amd64-linux.c \
m_sigframe/sigframe-ppc32-linux.c \
@@ -371,6 +375,13 @@
$(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
libcoregrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_CCASFLAGS = \
$(AM_CCASFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
+if ENABLE_LINUX_TICKET_LOCK_PRIMARY
+libcoregrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_SOURCES += \
+ m_scheduler/ticket-lock-linux.c
+libcoregrind_@VGCONF_ARCH_PRI@_@VGCONF_OS@_a_CFLAGS += \
+ -DENABLE_LINUX_TICKET_LOCK
+endif
+
if VGCONF_HAVE_PLATFORM_SEC
libcoregrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_SOURCES = \
$(COREGRIND_SOURCES_COMMON)
@@ -382,6 +393,12 @@
$(AM_CFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
libcoregrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_CCASFLAGS = \
$(AM_CCASFLAGS_@VGCONF_PLATFORM_SEC_CAPS@)
+if ENABLE_LINUX_TICKET_LOCK_SECONDARY
+libcoregrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_SOURCES += \
+ m_scheduler/ticket-lock-linux.c
+libcoregrind_@VGCONF_ARCH_SEC@_@VGCONF_OS@_a_CFLAGS += \
+ -DENABLE_LINUX_TICKET_LOCK
+endif
endif


#----------------------------------------------------------------------------
=======================================
--- /trunk/valgrind/coregrind/m_demangle/ansidecl.h Mon Jun 7 07:06:05 2010
+++ /trunk/valgrind/coregrind/m_demangle/ansidecl.h Wed Dec 14 00:38:07 2011
@@ -1,5 +1,6 @@
/* ANSI and traditional C compatability macros
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
Free Software Foundation, Inc.
This file is part of the GNU C Library.

@@ -114,6 +115,10 @@
#ifndef _ANSIDECL_H
#define _ANSIDECL_H 1

+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Every source file includes this file,
so they will all get the switch for lint. */
/* LINTLIBRARY */
@@ -136,7 +141,7 @@
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#endif /* GCC_VERSION */

-#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined
(_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) &&
defined(__cplusplus))
+#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) ||
(defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
/* All known AIX compilers implement these things (but don't always
define __STDC__). The RISC/OS MIPS compiler defines these things
in SVR4 mode, but does not define __STDC__. */
@@ -173,7 +178,7 @@
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
it too, but it's not in C89. */
#undef inline
-#if __STDC_VERSION__ > 199901L
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) ||
(defined(__SUNPRO_C) && defined(__C99FEATURES__))
/* it's a keyword */
#else
# if GCC_VERSION >= 2007
@@ -256,14 +261,23 @@
# endif /* GNUC >= 2.96 */
#endif /* ATTRIBUTE_MALLOC */

-/* Attributes on labels were valid as of gcc 2.93. */
+/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
+ g++ an attribute on a label must be followed by a semicolon. */
#ifndef ATTRIBUTE_UNUSED_LABEL
-# if (!defined (__cplusplus) && GCC_VERSION >= 2093)
-# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# ifndef __cplusplus
+# if GCC_VERSION >= 2093
+# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# else
+# define ATTRIBUTE_UNUSED_LABEL
+# endif
# else
-# define ATTRIBUTE_UNUSED_LABEL
-# endif /* !__cplusplus && GNUC >= 2.93 */
-#endif /* ATTRIBUTE_UNUSED_LABEL */
+# if GCC_VERSION >= 4005
+# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
+# else
+# define ATTRIBUTE_UNUSED_LABEL
+# endif
+# endif
+#endif

#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
@@ -390,4 +404,31 @@
#define __extension__
#endif

+/* This is used to declare a const variable which should be visible
+ outside of the current compilation unit. Use it as
+ EXPORTED_CONST int i = 1;
+ This is because the semantics of const are different in C and C++.
+ "extern const" is permitted in C but it looks strange, and gcc
+ warns about it when -Wc++-compat is not used. */
+#ifdef __cplusplus
+#define EXPORTED_CONST extern const
+#else
+#define EXPORTED_CONST const
+#endif
+
+/* Be conservative and only use enum bitfields with C++ or GCC.
+ FIXME: provide a complete autoconf test for buggy enum bitfields. */
+
+#ifdef __cplusplus
+#define ENUM_BITFIELD(TYPE) enum TYPE
+#elif (GCC_VERSION > 2000)
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ansidecl.h */
=======================================
--- /trunk/valgrind/coregrind/m_demangle/cp-demangle.c Mon Jun 7 07:06:05
2010
+++ /trunk/valgrind/coregrind/m_demangle/cp-demangle.c Wed Dec 14 00:38:07
2011
@@ -1,5 +1,5 @@
/* Demangler for g++ V3 ABI.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Written by Ian Lance Taylor <i...@wasabisystems.com>.

@@ -293,8 +293,6 @@
enum { D_PRINT_BUFFER_LENGTH = 256 };
struct d_print_info
{
- /* The options passed to the demangler. */
- int options;
/* Fixed-length allocated buffer for demangled data, flushed to the
callback with a NUL termination once full. */
char buf[D_PRINT_BUFFER_LENGTH];
@@ -317,6 +315,8 @@
/* The current index into any template argument packs we are using
for printing. */
int pack_index;
+ /* Number of d_print_flush calls so far. */
+ unsigned long int flush_count;
};

#ifdef CP_DEMANGLE_DEBUG
@@ -334,6 +334,9 @@
static struct demangle_component *
d_make_name (struct d_info *, const char *, int);

+static struct demangle_component *
+d_make_demangle_mangled_name (struct d_info *, const char *);
+
static struct demangle_component *
d_make_builtin_type (struct d_info *,
const struct demangle_builtin_type_info *);
@@ -404,6 +407,8 @@

static struct demangle_component *d_array_type (struct d_info *);

+static struct demangle_component *d_vector_type (struct d_info *);
+
static struct demangle_component *
d_pointer_to_member_type (struct d_info *);

@@ -423,6 +428,13 @@

static int d_discriminator (struct d_info *);

+static struct demangle_component *d_lambda (struct d_info *);
+
+static struct demangle_component *d_unnamed_type (struct d_info *);
+
+static struct demangle_component *
+d_clone_suffix (struct d_info *, struct demangle_component *);
+
static int
d_add_substitution (struct d_info *, struct demangle_component *);

@@ -440,7 +452,7 @@
d_growable_string_callback_adapter (const char *, size_t, void *);

static void
-d_print_init (struct d_print_info *, int, demangle_callbackref, void *);
+d_print_init (struct d_print_info *, demangle_callbackref, void *);

static inline void d_print_error (struct d_print_info *);

@@ -458,32 +470,32 @@
static inline char d_last_char (struct d_print_info *);

static void
-d_print_comp (struct d_print_info *, const struct demangle_component *);
+d_print_comp (struct d_print_info *, int, const struct demangle_component
*);

static void
d_print_java_identifier (struct d_print_info *, const char *, int);

static void
-d_print_mod_list (struct d_print_info *, struct d_print_mod *, int);
+d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int);

static void
-d_print_mod (struct d_print_info *, const struct demangle_component *);
+d_print_mod (struct d_print_info *, int, const struct demangle_component
*);

static void
-d_print_function_type (struct d_print_info *,
+d_print_function_type (struct d_print_info *, int,
const struct demangle_component *,
struct d_print_mod *);

static void
-d_print_array_type (struct d_print_info *,
+d_print_array_type (struct d_print_info *, int,
const struct demangle_component *,
struct d_print_mod *);

static void
-d_print_expr_op (struct d_print_info *, const struct demangle_component *);
+d_print_expr_op (struct d_print_info *, int, const struct
demangle_component *);

static void
-d_print_cast (struct d_print_info *, const struct demangle_component *);
+d_print_cast (struct d_print_info *, int, const struct demangle_component
*);

static int d_demangle_callback (const char *, int,
demangle_callbackref, void *);
@@ -588,6 +600,12 @@
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
printf ("hidden alias\n");
break;
+ case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
+ printf ("transaction clone\n");
+ break;
+ case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
+ printf ("non-transaction clone\n");
+ break;
case DEMANGLE_COMPONENT_RESTRICT:
printf ("restrict\n");
break;
@@ -636,6 +654,9 @@
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
printf ("pointer to member type\n");
break;
+ case DEMANGLE_COMPONENT_FIXED_TYPE:
+ printf ("fixed-point type\n");
+ break;
case DEMANGLE_COMPONENT_ARGLIST:
printf ("argument list\n");
break;
@@ -731,8 +752,8 @@
{
if (p == NULL
|| name == NULL
- || (kind < gnu_v3_complete_object_ctor
- && kind > gnu_v3_complete_object_allocating_ctor))
+ || (int) kind < gnu_v3_complete_object_ctor
+ || (int) kind > gnu_v3_object_ctor_group)
return 0;
p->type = DEMANGLE_COMPONENT_CTOR;
p->u.s_ctor.kind = kind;
@@ -750,8 +771,8 @@
{
if (p == NULL
|| name == NULL
- || (kind < gnu_v3_deleting_dtor
- && kind > gnu_v3_base_object_dtor))
+ || (int) kind < gnu_v3_deleting_dtor
+ || (int) kind > gnu_v3_object_dtor_group)
return 0;
p->type = DEMANGLE_COMPONENT_DTOR;
p->u.s_dtor.kind = kind;
@@ -804,6 +825,8 @@
case DEMANGLE_COMPONENT_LITERAL:
case DEMANGLE_COMPONENT_LITERAL_NEG:
case DEMANGLE_COMPONENT_COMPOUND_NAME:
+ case DEMANGLE_COMPONENT_VECTOR_TYPE:
+ case DEMANGLE_COMPONENT_CLONE:
if (left == NULL || right == NULL)
return NULL;
break;
@@ -821,6 +844,8 @@
case DEMANGLE_COMPONENT_GUARD:
case DEMANGLE_COMPONENT_REFTEMP:
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
+ case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
+ case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
@@ -831,6 +856,8 @@
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
case DEMANGLE_COMPONENT_DECLTYPE:
case DEMANGLE_COMPONENT_PACK_EXPANSION:
+ case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
+ case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
if (left == NULL)
return NULL;
break;
@@ -869,6 +896,17 @@
}
return p;
}
+
+/* Add a new demangle mangled name component. */
+
+static struct demangle_component *
+d_make_demangle_mangled_name (struct d_info *di, const char *s)
+{
+ if (d_peek_char (di) != '_' || d_peek_next_char (di) != 'Z')
+ return d_make_name (di, s, strlen (s));
+ d_advance (di, 2);
+ return d_encoding (di, 0);
+}

/* Add a new name component. */

@@ -931,6 +969,20 @@
return NULL;
return p;
}
+
+static struct demangle_component *
+d_make_default_arg (struct d_info *di, int num,
+ struct demangle_component *sub)
+{
+ struct demangle_component *p = d_make_empty (di);
+ if (p)
+ {
+ p->type = DEMANGLE_COMPONENT_DEFAULT_ARG;
+ p->u.s_unary_num.num = num;
+ p->u.s_unary_num.sub = sub;
+ }
+ return p;
+}

/* Add a new constructor component. */

@@ -975,6 +1027,22 @@
}
return p;
}
+
+/* Add a new function parameter. */
+
+static struct demangle_component *
+d_make_function_param (struct d_info *di, long i)
+{
+ struct demangle_component *p;
+
+ p = d_make_empty (di);
+ if (p != NULL)
+ {
+ p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
+ p->u.s_number.number = i;
+ }
+ return p;
+}

/* Add a new standard substitution component. */

@@ -993,7 +1061,7 @@
return p;
}

-/* <mangled-name> ::= _Z <encoding>
+/* <mangled-name> ::= _Z <encoding> [<clone-suffix>]*

TOP_LEVEL is non-zero when called at the top level. */

@@ -1001,11 +1069,28 @@
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *di, int top_level)
{
- if (! d_check_char (di, '_'))
+ struct demangle_component *p;
+
+ if (! d_check_char (di, '_')
+ /* Allow missing _ if not at toplevel to work around a
+ bug in G++ abi-version=2 mangling; see the comment in
+ write_template_arg. */
+ && top_level)
return NULL;
if (! d_check_char (di, 'Z'))
return NULL;
- return d_encoding (di, top_level);
+ p = d_encoding (di, top_level);
+
+ /* If at top level and parsing parameters, check for a clone
+ suffix. */
+ if (top_level && (di->options & DMGL_PARAMS) != 0)
+ while (d_peek_char (di) == '.'
+ && (IS_LOWER (d_peek_next_char (di))
+ || d_peek_next_char (di) == '_'
+ || IS_DIGIT (d_peek_next_char (di))))
+ p = d_clone_suffix (di, p);
+
+ return p;
}

/* Return whether a function should have a return type. The argument
@@ -1143,8 +1228,9 @@
return d_local_name (di);

case 'L':
+ case 'U':
return d_unqualified_name (di);
-
+
case 'S':
{
int subst;
@@ -1234,6 +1320,7 @@
/* <prefix> ::= <prefix> <unqualified-name>
::= <template-prefix> <template-args>
::= <template-param>
+ ::= <decltype>
::=
::= <substitution>

@@ -1262,10 +1349,20 @@
<template-param> here. */

comb_type = DEMANGLE_COMPONENT_QUAL_NAME;
- if (IS_DIGIT (peek)
+ if (peek == 'D')
+ {
+ char peek2 = d_peek_next_char (di);
+ if (peek2 == 'T' || peek2 == 't')
+ /* Decltype. */
+ dc = cplus_demangle_type (di);
+ else
+ /* Destructor name. */
+ dc = d_unqualified_name (di);
+ }
+ else if (IS_DIGIT (peek)
|| IS_LOWER (peek)
|| peek == 'C'
- || peek == 'D'
+ || peek == 'U'
|| peek == 'L')
dc = d_unqualified_name (di);
else if (peek == 'S')
@@ -1281,6 +1378,16 @@
dc = d_template_param (di);
else if (peek == 'E')
return ret;
+ else if (peek == 'M')
+ {
+ /* Initializer scope for a lambda. We don't need to represent
+ this; the normal code will just treat the variable as a type
+ scope, which gives appropriate output. */
+ if (ret == NULL)
+ return NULL;
+ d_advance (di, 1);
+ continue;
+ }
else
return NULL;

@@ -1337,6 +1444,18 @@
return NULL;
return ret;
}
+ else if (peek == 'U')
+ {
+ switch (d_peek_next_char (di))
+ {
+ case 'l':
+ return d_lambda (di);
+ case 't':
+ return d_unnamed_type (di);
+ default:
+ return NULL;
+ }
+ }
else
return NULL;
}
@@ -1389,6 +1508,20 @@
peek = d_peek_char (di);
}
}
+
+/* Like d_number, but returns a demangle_component. */
+
+static struct demangle_component *
+d_number_component (struct d_info *di)
+{
+ struct demangle_component *ret = d_make_empty (di);
+ if (ret)
+ {
+ ret->type = DEMANGLE_COMPONENT_NUMBER;
+ ret->u.s_number.number = d_number (di);
+ }
+ return ret;
+}

/* identifier ::= <(unqualified source code identifier)> */

@@ -1493,6 +1626,8 @@
{ "rs", NL (">>"), 2 },
{ "st", NL ("sizeof "), 1 },
{ "sz", NL ("sizeof "), 1 },
+ { "at", NL ("alignof "), 1 },
+ { "az", NL ("alignof "), 1 },
{ NULL, NULL, 0, 0 }
};

@@ -1650,6 +1785,8 @@
::= GR <name>
::= GA <encoding>
::= Gr <resource name>
+ ::= GTt <encoding>
+ ::= GTn <encoding>
*/

static struct demangle_component *
@@ -1734,12 +1871,32 @@
return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL);

case 'R':
- return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, d_name (di),
- NULL);
+ {
+ struct demangle_component *name = d_name (di);
+ return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, name,
+ d_number_component (di));
+ }

case 'A':
return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS,
d_encoding (di, 0), NULL);
+
+ case 'T':
+ switch (d_next_char (di))
+ {
+ case 'n':
+ return d_make_comp (di, DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
+ d_encoding (di, 0), NULL);
+ default:
+ /* ??? The proposal is that other letters (such as 'h') stand
+ for different variants of transaction cloning, such as
+ compiling directly for hardware transaction support. But
+ they still should all be transactional clones of some sort
+ so go ahead and call them that. */
+ case 't':
+ return d_make_comp (di, DEMANGLE_COMPONENT_TRANSACTION_CLONE,
+ d_encoding (di, 0), NULL);
+ }

case 'r':
return d_java_resource (di);
@@ -1824,6 +1981,9 @@
case '3':
kind = gnu_v3_complete_object_allocating_ctor;
break;
+ case '5':
+ kind = gnu_v3_object_ctor_group;
+ break;
default:
return NULL;
}
@@ -1846,6 +2006,9 @@
case '2':
kind = gnu_v3_base_object_dtor;
break;
+ case '5':
+ kind = gnu_v3_object_dtor_group;
+ break;
default:
return NULL;
}
@@ -1916,6 +2079,8 @@
/* 29 */ { NL ("half"), NL ("half"), D_PRINT_FLOAT },
/* 30 */ { NL ("char16_t"), NL ("char16_t"), D_PRINT_DEFAULT },
/* 31 */ { NL ("char32_t"), NL ("char32_t"), D_PRINT_DEFAULT },
+ /* 32 */ { NL ("decltype(nullptr)"), NL ("decltype(nullptr)"),
+ D_PRINT_DEFAULT },
};

CP_STATIC_IF_GLIBCPP_V3
@@ -2130,6 +2295,34 @@
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
di->expansion += ret->u.s_builtin.type->len;
break;
+
+ case 'F':
+ /* Fixed point types. DF<int bits><length><fract bits><sat> */
+ ret = d_make_empty (di);
+ ret->type = DEMANGLE_COMPONENT_FIXED_TYPE;
+ if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di))))
+ /* For demangling we don't care about the bits. */
+ d_number (di);
+ ret->u.s_fixed.length = cplus_demangle_type (di);
+ if (ret->u.s_fixed.length == NULL)
+ return NULL;
+ d_number (di);
+ peek = d_next_char (di);
+ ret->u.s_fixed.sat = (peek == 's');
+ break;
+
+ case 'v':
+ ret = d_vector_type (di);
+ break;
+
+ case 'n':
+ /* decltype(nullptr) */
+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[32]);
+ di->expansion += ret->u.s_builtin.type->len;
+ break;
+
+ default:
+ return NULL;
}
break;

@@ -2152,8 +2345,10 @@
d_cv_qualifiers (struct d_info *di,
struct demangle_component **pret, int member_fn)
{
+ struct demangle_component **pstart;
char peek;

+ pstart = pret;
peek = d_peek_char (di);
while (peek == 'r' || peek == 'V' || peek == 'K')
{
@@ -2189,6 +2384,28 @@

peek = d_peek_char (di);
}
+
+ if (!member_fn && peek == 'F')
+ {
+ while (pstart != pret)
+ {
+ switch ((*pstart)->type)
+ {
+ case DEMANGLE_COMPONENT_RESTRICT:
+ (*pstart)->type = DEMANGLE_COMPONENT_RESTRICT_THIS;
+ break;
+ case DEMANGLE_COMPONENT_VOLATILE:
+ (*pstart)->type = DEMANGLE_COMPONENT_VOLATILE_THIS;
+ break;
+ case DEMANGLE_COMPONENT_CONST:
+ (*pstart)->type = DEMANGLE_COMPONENT_CONST_THIS;
+ break;
+ default:
+ break;
+ }
+ pstart = &d_left (*pstart);
+ }
+ }

return pret;
}
@@ -2214,50 +2431,30 @@
return ret;
}

-/* <bare-function-type> ::= [J]<type>+ */
+/* <type>+ */

static struct demangle_component *
-d_bare_function_type (struct d_info *di, int has_return_tipe)
-{
- struct demangle_component *return_type;
+d_parmlist (struct d_info *di)
+{
struct demangle_component *tl;
struct demangle_component **ptl;
- char peek;
-
- /* Detect special qualifier indicating that the first argument
- is the return type. */
- peek = d_peek_char (di);
- if (peek == 'J')
- {
- d_advance (di, 1);
- has_return_tipe = 1;
- }
-
- return_type = NULL;
+
tl = NULL;
ptl = &tl;
while (1)
{
struct demangle_component *type;

- peek = d_peek_char (di);
- if (peek == '\0' || peek == 'E')
+ char peek = d_peek_char (di);
+ if (peek == '\0' || peek == 'E' || peek == '.')
break;
type = cplus_demangle_type (di);
if (type == NULL)
return NULL;
- if (has_return_tipe)
- {
- return_type = type;
- has_return_tipe = 0;
- }
- else
- {
- *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
- if (*ptl == NULL)
- return NULL;
- ptl = &d_right (*ptl);
- }
+ *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
+ if (*ptl == NULL)
+ return NULL;
+ ptl = &d_right (*ptl);
}

/* There should be at least one parameter type besides the optional
@@ -2272,10 +2469,45 @@
&& d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID)
{
di->expansion -= d_left (tl)->u.s_builtin.type->len;
- tl = NULL;
+ d_left (tl) = NULL;
}

- return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, return_type,
tl);
+ return tl;
+}
+
+/* <bare-function-type> ::= [J]<type>+ */
+
+static struct demangle_component *
+d_bare_function_type (struct d_info *di, int has_return_tipe)
+{
+ struct demangle_component *return_type;
+ struct demangle_component *tl;
+ char peek;
+
+ /* Detect special qualifier indicating that the first argument
+ is the return type. */
+ peek = d_peek_char (di);
+ if (peek == 'J')
+ {
+ d_advance (di, 1);
+ has_return_tipe = 1;
+ }
+
+ if (has_return_tipe)
+ {
+ return_type = cplus_demangle_type (di);
+ if (return_type == NULL)
+ return NULL;
+ }
+ else
+ return_type = NULL;
+
+ tl = d_parmlist (di);
+ if (tl == NULL)
+ return NULL;
+
+ return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE,
+ return_type, tl);
}

/* <class-enum-type> ::= <name> */
@@ -2330,6 +2562,34 @@
return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
cplus_demangle_type (di));
}
+
+/* <vector-type> ::= Dv <number> _ <type>
+ ::= Dv _ <expression> _ <type> */
+
+static struct demangle_component *
+d_vector_type (struct d_info *di)
+{
+ char peek;
+ struct demangle_component *dim;
+
+ peek = d_peek_char (di);
+ if (peek == '_')
+ {
+ d_advance (di, 1);
+ dim = d_expression (di);
+ }
+ else
+ dim = d_number_component (di);
+
+ if (dim == NULL)
+ return NULL;
+
+ if (! d_check_char (di, '_'))
+ return NULL;
+
+ return d_make_comp (di, DEMANGLE_COMPONENT_VECTOR_TYPE, dim,
+ cplus_demangle_type (di));
+}

/* <pointer-to-member-type> ::= M <(class) type> <(member) type> */

@@ -2376,6 +2636,24 @@

return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
}
+
+/* <non-negative number> _ */
+
+static long
+d_compact_number (struct d_info *di)
+{
+ long num;
+ if (d_peek_char (di) == '_')
+ num = 0;
+ else if (d_peek_char (di) == 'n')
+ return -1;
+ else
+ num = d_number (di) + 1;
+
+ if (! d_check_char (di, '_'))
+ return -1;
+ return num;
+}

/* <template-param> ::= T_
::= T <(parameter-2 non-negative) number> _
@@ -2389,17 +2667,8 @@
if (! d_check_char (di, 'T'))
return NULL;

- if (d_peek_char (di) == '_')
- param = 0;
- else
- {
- param = d_number (di);
- if (param < 0)
- return NULL;
- param += 1;
- }
-
- if (! d_check_char (di, '_'))
+ param = d_compact_number (di);
+ if (param < 0)
return NULL;

++di->did_subs;
@@ -2560,17 +2829,43 @@
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
d_template_args (di)));
}
- else if (peek == 's' && d_peek_next_char (di) == 'T')
- {
- /* Just demangle a parameter placeholder as its type. */
+ else if (peek == 's' && d_peek_next_char (di) == 'p')
+ {
d_advance (di, 2);
- return cplus_demangle_type (di);
- }
- else if (IS_DIGIT (peek))
+ return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
+ d_expression (di), NULL);
+ }
+ else if (peek == 'f' && d_peek_next_char (di) == 'p')
+ {
+ /* Function parameter used in a late-specified return type. */
+ int index;
+ d_advance (di, 2);
+ if (d_peek_char (di) == 'T')
+ {
+ /* 'this' parameter. */
+ d_advance (di, 1);
+ index = 0;
+ }
+ else
+ {
+ index = d_compact_number (di) + 1;
+ if (index == 0)
+ return NULL;
+ }
+ return d_make_function_param (di, index);
+ }
+ else if (IS_DIGIT (peek)
+ || (peek == 'o' && d_peek_next_char (di) == 'n'))
{
/* We can get an unqualified name as an expression in the case of
- a dependent member access, i.e. decltype(T().i). */
- struct demangle_component *name = d_unqualified_name (di);
+ a dependent function call, i.e. decltype(f(t)). */
+ struct demangle_component *name;
+
+ if (peek == 'o')
+ /* operator-function-id, i.e. operator+(t). */
+ d_advance (di, 2);
+
+ name = d_unqualified_name (di);
if (name == NULL)
return NULL;
if (d_peek_char (di) == 'I')
@@ -2607,28 +2902,39 @@
args = op->u.s_extended_operator.args;
break;
case DEMANGLE_COMPONENT_CAST:
- if (d_peek_char (di) == 'v')
- /* T() encoded as an operand of void. */
- return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
- cplus_demangle_type (di));
- else
- args = 1;
+ args = 1;
break;
}

switch (args)
{
case 1:
- return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
- d_expression (di));
+ {
+ struct demangle_component *operand;
+ if (op->type == DEMANGLE_COMPONENT_CAST
+ && d_check_char (di, '_'))
+ operand = d_exprlist (di);
+ else
+ operand = d_expression (di);
+ return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
+ operand);
+ }
case 2:
{
struct demangle_component *left;
struct demangle_component *right;
+ const char *code = op->u.s_operator.op->code;

left = d_expression (di);
- if (!strcmp (op->u.s_operator.op->code, "cl"))
+ if (!strcmp (code, "cl"))
right = d_exprlist (di);
+ else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
+ {
+ right = d_unqualified_name (di);
+ if (d_peek_char (di) == 'I')
+ right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE,
+ right, d_template_args (di));
+ }
else
right = d_expression (di);

@@ -2671,7 +2977,9 @@

if (! d_check_char (di, 'L'))
return NULL;
- if (d_peek_char (di) == '_')
+ if (d_peek_char (di) == '_'
+ /* Workaround for G++ bug; see comment in write_template_arg. */
+ || d_peek_char (di) == 'Z')
ret = cplus_demangle_mangled_name (di, 0);
else
{
@@ -2749,10 +3057,31 @@
else
{
struct demangle_component *name;
+ int num = -1;
+
+ if (d_peek_char (di) == 'd')
+ {
+ /* Default argument scope: d <number> _. */
+ d_advance (di, 1);
+ num = d_compact_number (di);
+ if (num < 0)
+ return NULL;
+ }

name = d_name (di);
- if (! d_discriminator (di))
- return NULL;
+ if (name)
+ switch (name->type)
+ {
+ /* Lambdas and unnamed types have internal discriminators. */
+ case DEMANGLE_COMPONENT_LAMBDA:
+ case DEMANGLE_COMPONENT_UNNAMED_TYPE:
+ break;
+ default:
+ if (! d_discriminator (di))
+ return NULL;
+ }
+ if (num >= 0)
+ name = d_make_default_arg (di, num, name);
return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function,
name);
}
}
@@ -2775,6 +3104,102 @@
return 0;
return 1;
}
+
+/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ */
+
+static struct demangle_component *
+d_lambda (struct d_info *di)
+{
+ struct demangle_component *tl;
+ struct demangle_component *ret;
+ int num;
+
+ if (! d_check_char (di, 'U'))
+ return NULL;
+ if (! d_check_char (di, 'l'))
+ return NULL;
+
+ tl = d_parmlist (di);
+ if (tl == NULL)
+ return NULL;
+
+ if (! d_check_char (di, 'E'))
+ return NULL;
+
+ num = d_compact_number (di);
+ if (num < 0)
+ return NULL;
+
+ ret = d_make_empty (di);
+ if (ret)
+ {
+ ret->type = DEMANGLE_COMPONENT_LAMBDA;
+ ret->u.s_unary_num.sub = tl;
+ ret->u.s_unary_num.num = num;
+ }
+
+ if (! d_add_substitution (di, ret))
+ return NULL;
+
+ return ret;
+}
+
+/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
+
+static struct demangle_component *
+d_unnamed_type (struct d_info *di)
+{
+ struct demangle_component *ret;
+ long num;
+
+ if (! d_check_char (di, 'U'))
+ return NULL;
+ if (! d_check_char (di, 't'))
+ return NULL;
+
+ num = d_compact_number (di);
+ if (num < 0)
+ return NULL;
+
+ ret = d_make_empty (di);
+ if (ret)
+ {
+ ret->type = DEMANGLE_COMPONENT_UNNAMED_TYPE;
+ ret->u.s_number.number = num;
+ }
+
+ if (! d_add_substitution (di, ret))
+ return NULL;
+
+ return ret;
+}
+
+/* <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative
number> ]*
+*/
+
+static struct demangle_component *
+d_clone_suffix (struct d_info *di, struct demangle_component *encoding)
+{
+ const char *suffix = d_str (di);
+ const char *pend = suffix;
+ struct demangle_component *n;
+
+ if (*pend == '.' && (IS_LOWER (pend[1]) || pend[1] == '_'))
+ {
+ pend += 2;
+ while (IS_LOWER (*pend) || *pend == '_')
+ ++pend;
+ }
+ while (*pend == '.' && IS_DIGIT (pend[1]))
+ {
+ pend += 2;
+ while (IS_DIGIT (*pend))
+ ++pend;
+ }
+ d_advance (di, pend - suffix);
+ n = d_make_name (di, suffix, pend - suffix);
+ return d_make_comp (di, DEMANGLE_COMPONENT_CLONE, encoding, n);
+}

/* Add a new substitution. */

@@ -3003,14 +3428,15 @@
/* Initialize a print information structure. */

static void
-d_print_init (struct d_print_info *dpi, int options,
- demangle_callbackref callback, void *opaque)
-{
- dpi->options = options;
+d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
+ void *opaque)
+{
dpi->len = 0;
dpi->last_char = '\0';
dpi->templates = NULL;
dpi->modifiers = NULL;
+ dpi->pack_index = 0;
+ dpi->flush_count = 0;

dpi->callback = callback;
dpi->opaque = opaque;
@@ -3040,6 +3466,7 @@
dpi->buf[dpi->len] = '\0';
dpi->callback (dpi->buf, dpi->len, dpi->opaque);
dpi->len = 0;
***The diff for this file has been truncated for email.***
=======================================
--- /trunk/valgrind/coregrind/m_demangle/cp-demangle.h Mon Jun 7 07:06:05
2010
+++ /trunk/valgrind/coregrind/m_demangle/cp-demangle.h Wed Dec 14 00:38:07
2011
@@ -1,5 +1,6 @@
/* Internal demangler interface for g++ V3 ABI.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation,
Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
+ Free Software Foundation, Inc.
Written by Ian Lance Taylor <i...@wasabisystems.com>.

This file is part of the libiberty library, which is part of GCC.
@@ -147,7 +148,7 @@
extern const struct demangle_operator_info cplus_demangle_operators[];
#endif

-#define D_BUILTIN_TYPE_COUNT (32)
+#define D_BUILTIN_TYPE_COUNT (33)

CP_STATIC_IF_GLIBCPP_V3
const struct demangle_builtin_type_info
=======================================
--- /trunk/valgrind/coregrind/m_demangle/cplus-dem.c Mon Jun 7 07:06:05
2010
+++ /trunk/valgrind/coregrind/m_demangle/cplus-dem.c Wed Dec 14 00:38:07
2011
@@ -1,6 +1,6 @@
/* Demangler for GNU C++
Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
Written by James Clark (j...@jclark.uucp)
Rewritten by Fred Fish (f...@cygnus.com) for ARM and Lucid demangling
Modified by Satish Pai (p...@apollo.hp.com) for HP demangling
@@ -80,8 +80,6 @@
#include "demangle.h"
#include "safe-ctype.h"

-static char *ada_demangle (const char *, int);
-
#define min(X,Y) (((X) < (Y)) ? (X) : (Y))

/* A value at least one greater than the maximum number of characters
@@ -495,8 +493,6 @@
static void
recursively_demangle (struct work_stuff *, const char **, string *, int);

-static void grow_vect (char **, size_t *, size_t, int);
-
/* Translate count to integer, consuming tokens in the process.
Conversion terminates on the first non-digit character.

@@ -889,126 +885,268 @@
}

if (GNAT_DEMANGLING)
- return ada_demangle(mangled,options);
+ return ada_demangle (mangled, options);

ret = internal_cplus_demangle (work, mangled);
squangle_mop_up (work);
return (ret);
}

-
-/* Assuming *OLD_VECT points to an array of *SIZE objects of size
- ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
- updating *OLD_VECT and *SIZE as necessary. */
-
-static void
-grow_vect (char **old_vect, size_t *size, size_t min_size, int
element_size)
-{
- if (*size < min_size)
- {
- *size *= 2;
- if (*size < min_size)
- *size = min_size;
- *old_vect = XRESIZEVAR (char, *old_vect, *size * element_size);
- }
-}
-
-/* Demangle ada names:
- 1. Discard final __{DIGIT}+ or ${DIGIT}+
- 2. Convert other instances of embedded "__" to `.'.
- 3. Discard leading _ada_.
- 4. Remove everything after first ___ if it is followed by 'X'.
- 5. Put symbols that should be suppressed in <...> brackets.
- The resulting string is valid until the next call of ada_demangle. */
-
-static char *
+/* Demangle ada names. The encoding is documented in
gcc/ada/exp_dbug.ads. */
+
+char *
ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
{
- int i, j;
int len0;
const char* p;
- char *demangled = NULL;
- int changed;
- size_t demangled_size = 0;
-
- changed = 0;
-
+ char *d;
+ char *demangled;
+
+ /* Discard leading _ada_, which is used for library level subprograms.
*/
if (strncmp (mangled, "_ada_", 5) == 0)
- {
- mangled += 5;
- changed = 1;
- }
-
- if (mangled[0] == '_' || mangled[0] == '<')
- goto Suppress;
-
- p = strstr (mangled, "___");
- if (p == NULL)
- len0 = strlen (mangled);
- else
- {
- if (p[3] == 'X')
- {
- len0 = p - mangled;
- changed = 1;
- }
+ mangled += 5;
+
+ /* All ada unit names are lower-case. */
+ if (!ISLOWER (mangled[0]))
+ goto unknown;
+
+ /* Most of the demangling will trivially remove chars. Operator names
+ may add one char but because they are always preceeded by '__' which
is
+ replaced by '.', they eventually never expand the size.
+ A few special names such as '___elabs' add a few chars (at most 7),
but
+ they occur only once. */
+ len0 = strlen (mangled) + 7 + 1;
+ demangled = XNEWVEC (char, len0);
+
+ d = demangled;
+ p = mangled;
+ while (1)
+ {
+ /* An entity names is expected. */
+ if (ISLOWER (*p))
+ {
+ /* An identifier, which is always lower case. */
+ do
+ *d++ = *p++;
+ while (ISLOWER(*p) || ISDIGIT (*p)
+ || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
+ }
+ else if (p[0] == 'O')
+ {
+ /* An operator name. */
+ static const char * const operators[][2] =
+ {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
+ {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
+ {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
+ {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
+ {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
+ {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
+ {"Oexpon", "**"}, {NULL, NULL}};
+ int k;
+
+ for (k = 0; operators[k][0] != NULL; k++)
+ {
+ size_t slen = strlen (operators[k][0]);
+ if (strncmp (p, operators[k][0], slen) == 0)
+ {
+ p += slen;
+ slen = strlen (operators[k][1]);
+ *d++ = '"';
+ memcpy (d, operators[k][1], slen);
+ d += slen;
+ *d++ = '"';
+ break;
+ }
+ }
+ /* Operator not found. */
+ if (operators[k][0] == NULL)
+ goto unknown;
+ }
else
- goto Suppress;
- }
-
- /* Make demangled big enough for possible expansion by operator name. */
- grow_vect (&demangled,
- &demangled_size, 2 * len0 + 1,
- sizeof (char));
-
- if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
- for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i
-= 1)
- ;
- if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
- {
- len0 = i - 1;
- changed = 1;
- }
- else if (mangled[i] == '$')
- {
- len0 = i;
- changed = 1;
- }
- }
-
- for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
- i += 1, j += 1)
- demangled[j] = mangled[i];
-
- while (i < len0)
- {
- if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
- {
- demangled[j] = '.';
- changed = 1;
- i += 2; j += 1;
- }
+ {
+ /* Not a GNAT encoding. */
+ goto unknown;
+ }
+
+ /* The name can be directly followed by some uppercase letters. */
+ if (p[0] == 'T' && p[1] == 'K')
+ {
+ /* Task stuff. */
+ if (p[2] == 'B' && p[3] == 0)
+ {
+ /* Subprogram for task body. */
+ break;
+ }
+ else if (p[2] == '_' && p[3] == '_')
+ {
+ /* Inner declarations in a task. */
+ p += 4;
+ *d++ = '.';
+ continue;
+ }
+ else
+ goto unknown;
+ }
+ if (p[0] == 'E' && p[1] == 0)
+ {
+ /* Exception name. */
+ goto unknown;
+ }
+ if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
+ {
+ /* Protected type subprogram. */
+ break;
+ }
+ if ((*p == 'N' || *p == 'S') && p[1] == 0)
+ {
+ /* Enumerated type name table. */
+ goto unknown;
+ }
+ if (p[0] == 'X')
+ {
+ /* Body nested. */
+ p++;
+ while (p[0] == 'n' || p[0] == 'b')
+ p++;
+ }
+ if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
+ {
+ /* Stream operations. */
+ const char *name;
+ switch (p[1])
+ {
+ case 'R':
+ name = "'Read";
+ break;
+ case 'W':
+ name = "'Write";
+ break;
+ case 'I':
+ name = "'Input";
+ break;
+ case 'O':
+ name = "'Output";
+ break;
+ default:
+ goto unknown;
+ }
+ p += 2;
+ strcpy (d, name);
+ d += strlen (name);
+ }
+ else if (p[0] == 'D')
+ {
+ /* Controlled type operation. */
+ const char *name;
+ switch (p[1])
+ {
+ case 'F':
+ name = ".Finalize";
+ break;
+ case 'A':
+ name = ".Adjust";
+ break;
+ default:
+ goto unknown;
+ }
+ strcpy (d, name);
+ d += strlen (name);
+ break;
+ }
+
+ if (p[0] == '_')
+ {
+ /* Separator. */
+ if (p[1] == '_')
+ {
+ /* Standard separator. Handled first. */
+ p += 2;
+
+ if (ISDIGIT (*p))
+ {
+ /* Overloading number. */
+ do
+ p++;
+ while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
+ if (*p == 'X')
+ {
+ p++;
+ while (p[0] == 'n' || p[0] == 'b')
+ p++;
+ }
+ }
+ else if (p[0] == '_' && p[1] != '_')
+ {
+ /* Special names. */
+ static const char * const special[][2] = {
+ { "_elabb", "'Elab_Body" },
+ { "_elabs", "'Elab_Spec" },
+ { "_size", "'Size" },
+ { "_alignment", "'Alignment" },
+ { "_assign", ".\":=\"" },
+ { NULL, NULL }
+ };
+ int k;
+
+ for (k = 0; special[k][0] != NULL; k++)
+ {
+ size_t slen = strlen (special[k][0]);
+ if (strncmp (p, special[k][0], slen) == 0)
+ {
+ p += slen;
+ slen = strlen (special[k][1]);
+ memcpy (d, special[k][1], slen);
+ d += slen;
+ break;
+ }
+ }
+ if (special[k][0] != NULL)
+ break;
+ else
+ goto unknown;
+ }
+ else
+ {
+ *d++ = '.';
+ continue;
+ }
+ }
+ else if (p[1] == 'B' || p[1] == 'E')
+ {
+ /* Entry Body or barrier Evaluation. */
+ p += 2;
+ while (ISDIGIT (*p))
+ p++;
+ if (p[0] == 's' && p[1] == 0)
+ break;
+ else
+ goto unknown;
+ }
+ else
+ goto unknown;
+ }
+
+ if (p[0] == '.' && ISDIGIT (p[1]))
+ {
+ /* Nested subprogram. */
+ p += 2;
+ while (ISDIGIT (*p))
+ p++;
+ }
+ if (*p == 0)
+ {
+ /* End of mangled name. */
+ break;
+ }
else
- {
- demangled[j] = mangled[i];
- i += 1; j += 1;
- }
- }
- demangled[j] = '\000';
-
- for (i = 0; demangled[i] != '\0'; i += 1)
- if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
- goto Suppress;
-
- if (! changed)
- return NULL;
- else
- return demangled;
-
- Suppress:
- grow_vect (&demangled,
- &demangled_size, strlen (mangled) + 3,
- sizeof (char));
+ goto unknown;
+ }
+ *d = 0;
+ return demangled;
+
+ unknown:
+ len0 = strlen (mangled);
+ demangled = XNEWVEC (char, len0 + 3);

if (mangled[0] == '<')
strcpy (demangled, mangled);
@@ -1190,8 +1328,7 @@
int i;

for (i = 0; i < work->ntmpl_args; i++)
- if (work->tmpl_argvec[i])
- free ((char*) work->tmpl_argvec[i]);
+ free ((char*) work->tmpl_argvec[i]);

free ((char*) work->tmpl_argvec);
work->tmpl_argvec = NULL;
=======================================
--- /trunk/valgrind/coregrind/m_demangle/demangle.c Tue Oct 25 09:11:36 2011
+++ /trunk/valgrind/coregrind/m_demangle/demangle.c Wed Dec 14 00:38:07 2011
@@ -75,13 +75,13 @@
impedance-match the libiberty code into our own framework.

The current code is from libiberty in the gcc tree, gcc svn
- r141363, dated 26 Oct 2008 (when the gcc trunk was in Stage 3
- leading up to a gcc-4.4 release). As of r141363, libiberty is LGPL
+ r181975, dated 12 Dec 2011 (when the gcc trunk was in Stage 3
+ leading up to a gcc-4.7 release). As of r141363, libiberty is LGPL
2.1, which AFAICT is compatible with "GPL 2 or later" and so is OK
for inclusion in Valgrind.

To update to a newer libiberty, it might be simplest to svn diff
- the gcc tree libibery against r141363 and then apply those diffs
+ the gcc tree libibery against r181975 and then apply those diffs
here. */

/* This is the main, standard demangler entry point. */
=======================================
--- /trunk/valgrind/coregrind/m_demangle/demangle.h Mon Jun 7 07:06:05 2010
+++ /trunk/valgrind/coregrind/m_demangle/demangle.h Wed Dec 14 00:38:07 2011
@@ -1,6 +1,6 @@
/* Defs for interface to demanglers.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
- 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
@@ -47,7 +47,13 @@
#define DMGL_VERBOSE (1 << 3) /* Include implementation details. */
#define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */
#define DMGL_RET_POSTFIX (1 << 5) /* Print function return types
(when
- present) after function
signature */
+ present) after function signature.
+ It applies only to the toplevel
+ function type. */
+#define DMGL_RET_DROP (1 << 6) /* Suppress printing function return
+ types, even if present. It applies
+ only to the toplevel function type.
+ */

#define DMGL_AUTO (1 << 8)
#define DMGL_GNU (1 << 9)
@@ -162,10 +168,14 @@
extern char*
java_demangle_v3 (const char *mangled);

+char *
+ada_demangle (const char *mangled, int options);
+
enum gnu_v3_ctor_kinds {
gnu_v3_complete_object_ctor = 1,
gnu_v3_base_object_ctor,
- gnu_v3_complete_object_allocating_ctor
+ gnu_v3_complete_object_allocating_ctor,
+ gnu_v3_object_ctor_group
};

/* Return non-zero iff NAME is the mangled form of a constructor name
@@ -179,7 +189,8 @@
enum gnu_v3_dtor_kinds {
gnu_v3_deleting_dtor = 1,
gnu_v3_complete_object_dtor,
- gnu_v3_base_object_dtor
+ gnu_v3_base_object_dtor,
+ gnu_v3_object_dtor_group
};

/* Return non-zero iff NAME is the mangled form of a destructor name
@@ -223,6 +234,8 @@
/* A template parameter. This holds a number, which is the template
parameter index. */
DEMANGLE_COMPONENT_TEMPLATE_PARAM,
+ /* A function parameter. This holds a number, which is the index. */
+ DEMANGLE_COMPONENT_FUNCTION_PARAM,
/* A constructor. This holds a name and the kind of
constructor. */
DEMANGLE_COMPONENT_CTOR,
@@ -321,6 +334,11 @@
and the right subtree is the member type. CV-qualifiers appear
on the latter. */
DEMANGLE_COMPONENT_PTRMEM_TYPE,
+ /* A fixed-point type. */
+ DEMANGLE_COMPONENT_FIXED_TYPE,
+ /* A vector type. The left subtree is the number of elements,
+ the right subtree is the element type. */
+ DEMANGLE_COMPONENT_VECTOR_TYPE,
/* An argument list. The left subtree is the current argument, and
the right subtree is either NULL or another ARGLIST node. */
DEMANGLE_COMPONENT_ARGLIST,
@@ -373,10 +391,31 @@
DEMANGLE_COMPONENT_COMPOUND_NAME,
/* A name formed by a single character. */
DEMANGLE_COMPONENT_CHARACTER,
+ /* A number. */
+ DEMANGLE_COMPONENT_NUMBER,
/* A decltype type. */
DEMANGLE_COMPONENT_DECLTYPE,
+ /* Global constructors keyed to name. */
+ DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS,
+ /* Global destructors keyed to name. */
+ DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS,
+ /* A lambda closure type. */
+ DEMANGLE_COMPONENT_LAMBDA,
+ /* A default argument scope. */
+ DEMANGLE_COMPONENT_DEFAULT_ARG,
+ /* An unnamed type. */
+ DEMANGLE_COMPONENT_UNNAMED_TYPE,
+ /* A transactional clone. This has one subtree, the encoding for
+ which it is providing alternative linkage. */
+ DEMANGLE_COMPONENT_TRANSACTION_CLONE,
+ /* A non-transactional clone entry point. In the i386/x86_64 abi,
+ the unmangled symbol of a tm_callable becomes a thunk and the
+ non-transactional function version is mangled thus. */
+ DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
/* A pack expansion. */
- DEMANGLE_COMPONENT_PACK_EXPANSION
+ DEMANGLE_COMPONENT_PACK_EXPANSION,
+ /* A cloned function. */
+ DEMANGLE_COMPONENT_CLONE
};

/* Types which are only used internally. */
@@ -421,6 +460,17 @@
struct demangle_component *name;
} s_extended_operator;

+ /* For DEMANGLE_COMPONENT_FIXED_TYPE. */
+ struct
+ {
+ /* The length, indicated by a C integer type name. */
+ struct demangle_component *length;
+ /* _Accum or _Fract? */
+ short accum;
+ /* Saturating or not? */
+ short sat;
+ } s_fixed;
+
/* For DEMANGLE_COMPONENT_CTOR. */
struct
{
@@ -455,10 +505,10 @@
int len;
} s_string;

- /* For DEMANGLE_COMPONENT_TEMPLATE_PARAM. */
+ /* For DEMANGLE_COMPONENT_*_PARAM. */
struct
{
- /* Template parameter index. */
+ /* Parameter index. */
long number;
} s_number;

@@ -477,6 +527,14 @@
struct demangle_component *right;
} s_binary;

+ struct
+ {
+ /* subtree, same place as d_left. */
+ struct demangle_component *sub;
+ /* integer. */
+ int num;
+ } s_unary_num;
+
} u;
};

=======================================
--- /trunk/valgrind/coregrind/m_demangle/dyn-string.c Mon Jun 7 07:06:05
2010
+++ /trunk/valgrind/coregrind/m_demangle/dyn-string.c Wed Dec 14 00:38:07
2011
@@ -349,7 +349,7 @@
return 1;
}

-/* Appends C to the end of DEST. Returns 1 on success. On failiure,
+/* Appends C to the end of DEST. Returns 1 on success. On failure,
if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */

int
=======================================
--- /trunk/valgrind/coregrind/m_demangle/dyn-string.h Mon Jun 7 07:06:05
2010
+++ /trunk/valgrind/coregrind/m_demangle/dyn-string.h Wed Dec 14 00:38:07
2011
@@ -1,5 +1,6 @@
/* An abstract string datatype.
- Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation,
Inc.
+ Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2009
+ Free Software Foundation, Inc.
Contributed by Mark Mitchell (ma...@markmitchell.com).

This file is part of GCC.
@@ -19,6 +20,12 @@
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */

+#ifndef DYN_STRING_H
+#define DYN_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif

typedef struct dyn_string
{
@@ -58,3 +65,9 @@
extern int dyn_string_append_char (dyn_string_t, int);
extern int dyn_string_substring (dyn_string_t, dyn_string_t, int, int);
extern int dyn_string_eq (dyn_string_t, dyn_string_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined (DYN_STRING_H) */
=======================================
--- /trunk/valgrind/coregrind/m_main.c Tue Oct 25 09:11:36 2011
+++ /trunk/valgrind/coregrind/m_main.c Wed Dec 14 00:38:07 2011
@@ -180,6 +180,7 @@
" --run-libc-freeres=no|yes free up glibc memory at exit on Linux?
[yes]\n"
" --sim-hints=hint1,hint2,... known hints:\n"
" lax-ioctls, enable-outer,
fuse-compatible [none]\n"
+" --fair-sched=no|yes|try schedule threads fairly on multicore
systems [no]\n"
" --kernel-variant=variant1,variant2,... known variants: bproc
[none]\n"
" handle non-standard kernel variants\n"
" --show-emwarns=no|yes show warnings about emulation limits?
[no]\n"
@@ -542,6 +543,17 @@
else if VG_BOOL_CLO(arg, "--trace-children",
VG_(clo_trace_children)) {}
else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
VG_(clo_child_silent_after_fork)) {}
+ else if VG_STR_CLO(arg, "--fair-sched", tmp_str) {
+ if (VG_(strcmp)(tmp_str, "yes") == 0)
+ VG_(clo_fair_sched) = enable_fair_sched;
+ else if (VG_(strcmp)(tmp_str, "try") == 0)
+ VG_(clo_fair_sched) = try_fair_sched;
+ else if (VG_(strcmp)(tmp_str, "no") == 0)
+ VG_(clo_fair_sched) = disable_fair_sched;
+ else
+ VG_(fmsg_bad_option)(arg, "");
+
+ }
else if VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched))
{}
else if VG_BOOL_CLO(arg, "--trace-signals",
VG_(clo_trace_signals)) {}
else if VG_BOOL_CLO(arg, "--trace-symtab",
VG_(clo_trace_symtab)) {}
=======================================
--- /trunk/valgrind/coregrind/m_options.c Mon Dec 12 00:02:05 2011
+++ /trunk/valgrind/coregrind/m_options.c Wed Dec 14 00:38:07 2011
@@ -90,6 +90,8 @@
Bool VG_(clo_debug_dump_line) = False;
Bool VG_(clo_debug_dump_frames) = False;
Bool VG_(clo_trace_redir) = False;
+enum FairSchedType
+ VG_(clo_fair_sched) = disable_fair_sched;
Bool VG_(clo_trace_sched) = False;
Bool VG_(clo_profile_heap) = False;
Int VG_(clo_dump_error) = 0;
=======================================
--- /trunk/valgrind/coregrind/m_scheduler/scheduler.c Wed Nov 2 02:32:38
2011
+++ /trunk/valgrind/coregrind/m_scheduler/scheduler.c Wed Dec 14 00:38:07
2011
@@ -89,7 +89,7 @@
#include "pub_core_translate.h" // For VG_(translate)()
#include "pub_core_transtab.h"
#include "pub_core_debuginfo.h" // VG_(di_notify_pdb_debuginfo)
-#include "priv_sema.h"
+#include "priv_sched-lock.h"
#include "pub_core_scheduler.h" // self
#include "pub_core_redir.h"

@@ -146,8 +146,10 @@
sanity_fast_count, sanity_slow_count );
}

-/* CPU semaphore, so that threads can run exclusively */
-static vg_sema_t the_BigLock;
+/*
+ * Mutual exclusion object used to serialize threads.
+ */
+static struct sched_lock *the_BigLock;

// Base address of the NaCl sandbox.
UWord nacl_head;
@@ -247,7 +249,7 @@
/* First, acquire the_BigLock. We can't do anything else safely
prior to this point. Even doing debug printing prior to this
point is, technically, wrong. */
- ML_(sema_down)(&the_BigLock, False/*not LL*/);
+ VG_(acquire_BigLock_LL)(NULL);

tst = VG_(get_ThreadState)(tid);

@@ -303,19 +305,31 @@

/* Release the_BigLock; this will reschedule any runnable
thread. */
- ML_(sema_up)(&the_BigLock, False/*not LL*/);
+ VG_(release_BigLock_LL)(NULL);
+}
+
+static void init_BigLock(void)
+{
+ vg_assert(!the_BigLock);
+ the_BigLock = ML_(create_sched_lock)();
+}
+
+static void deinit_BigLock(void)
+{
+ ML_(destroy_sched_lock)(the_BigLock);
+ the_BigLock = NULL;
}

/* See pub_core_scheduler.h for description */
void VG_(acquire_BigLock_LL) ( HChar* who )
{
- ML_(sema_down)(&the_BigLock, True/*LL*/);
+ ML_(acquire_sched_lock)(the_BigLock);
}

/* See pub_core_scheduler.h for description */
void VG_(release_BigLock_LL) ( HChar* who )
{
- ML_(sema_up)(&the_BigLock, True/*LL*/);
+ ML_(release_sched_lock)(the_BigLock);
}


@@ -337,7 +351,7 @@
if (VG_(clo_trace_sched))
print_sched_event(tid, "release lock in VG_(exit_thread)");

- ML_(sema_up)(&the_BigLock, False/*not LL*/);
+ VG_(release_BigLock_LL)(NULL);
}

/* If 'tid' is blocked in a syscall, send it SIGVGKILL so as to get it
@@ -524,9 +538,9 @@
}

/* re-init and take the sema */
- ML_(sema_deinit)(&the_BigLock);
- ML_(sema_init)(&the_BigLock);
- ML_(sema_down)(&the_BigLock, False/*not LL*/);
+ deinit_BigLock();
+ init_BigLock();
+ VG_(acquire_BigLock_LL)(NULL);
}


@@ -541,7 +555,21 @@

VG_(debugLog)(1,"sched","sched_init_phase1\n");

- ML_(sema_init)(&the_BigLock);
+ if (VG_(clo_fair_sched) != disable_fair_sched
+ && !ML_(set_sched_lock_impl)(sched_lock_ticket)
+ && VG_(clo_fair_sched) == enable_fair_sched)
+ {
+ VG_(printf)("Error: fair scheduling is not supported on this
system.\n");
+ VG_(exit)(1);
+ }
+
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_DebugMsg,
+ "Scheduler: using %s scheduler lock implementation.\n",
+ ML_(get_sched_lock_name)());
+ }
+
+ init_BigLock();

for (i = 0 /* NB; not 1 */; i < VG_N_THREADS; i++) {
/* Paranoia .. completely zero it out. */
@@ -1837,15 +1865,12 @@
bad = True;
}

-#if !defined(VGO_darwin)
- // GrP fixme
- if (lwpid != the_BigLock.owner_lwpid) {
+ if (lwpid != ML_(get_sched_lock_owner)(the_BigLock)) {
VG_(message)(Vg_DebugMsg,
"Thread (LWPID) %d doesn't own the_BigLock\n",
tid);
bad = True;
}
-#endif

/* Periodically show the state of all threads, for debugging
purposes. */
=======================================
--- /trunk/valgrind/coregrind/pub_core_options.h Tue Oct 25 09:11:36 2011
+++ /trunk/valgrind/coregrind/pub_core_options.h Wed Dec 14 00:38:07 2011
@@ -149,6 +149,9 @@
extern Bool VG_(clo_debug_dump_frames);
/* DEBUG: print redirection details? default: NO */
extern Bool VG_(clo_trace_redir);
+/* Enable fair scheduling on multicore systems? default: NO */
+enum FairSchedType { disable_fair_sched, enable_fair_sched, try_fair_sched
};
+extern enum FairSchedType VG_(clo_fair_sched);
/* DEBUG: print thread scheduling events? default: NO */
extern Bool VG_(clo_trace_sched);
/* DEBUG: do heap profiling? default: NO */
=======================================
--- /trunk/valgrind/drd/drd.h Tue Oct 25 09:11:36 2011
+++ /trunk/valgrind/drd/drd.h Wed Dec 14 00:38:07 2011
@@ -1,5 +1,3 @@
-/* -*- mode: C; c-basic-offset: 3; indent-tabs-mode: nil; -*- */
-
/*
----------------------------------------------------------------

@@ -87,13 +85,20 @@
&(x), sizeof(x), 0, 0, 0)

/**
- * Tell DRD to trace all memory accesses on the specified variable.
+ * Tell DRD to trace all memory accesses for the specified variable
* until the memory that was allocated for the variable is freed.
*/
#define DRD_TRACE_VAR(x) \
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_TRACE_ADDR, \
&(x), sizeof(x), 0, 0, 0)

+/**
+ * Tell DRD to stop tracing memory accesses for the specified variable.
+ */
+#define DRD_STOP_TRACE_VAR(x) \
+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_STOP_TRACE_ADDR, \
+ &(x), sizeof(x), 0, 0, 0)
+
/**
* @defgroup RaceDetectionAnnotations Data race detection annotations.
*
=======================================
***Additional files exist in this changeset.***

Reply all
Reply to author
Forward
0 new messages