diff --git a/import.log b/import.log
index 4232194..86ef795 100644
--- a/import.log
+++ b/import.log
@@ -1 +1,2 @@
 valgrind-3_4_0-1:HEAD:valgrind-3.4.0-1.src.rpm:1234005462
+valgrind-3_5_0-15_fc14:HEAD:valgrind-3.5.0-15.fc14.src.rpm:1270651054
diff --git a/valgrind-3.5.0-DW_OP_mod.patch b/valgrind-3.5.0-DW_OP_mod.patch
new file mode 100644
index 0000000..0df7c05
--- /dev/null
+++ b/valgrind-3.5.0-DW_OP_mod.patch
@@ -0,0 +1,20 @@
+--- valgrind/coregrind/m_debuginfo/d3basics.c.jj	2010-01-20 09:46:56.000000000 +0100
++++ valgrind/coregrind/m_debuginfo/d3basics.c	2010-01-20 09:52:33.000000000 +0100
+@@ -770,12 +770,12 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+             PUSH(sw1);
+             break;
+          case DW_OP_mod:
+-            POP(sw2);
+-            if (sw2 == 0)
++            POP(uw2);
++            if (uw2 == 0)
+                FAIL("evaluate_Dwarf3_Expr: division by zero");
+-            POP(sw1);
+-            sw1 %= sw2;
+-            PUSH(sw1);
++            POP(uw1);
++            uw1 %= uw2;
++            PUSH(uw1);
+             break;
+ #define BINARY(name, op, s) \
+          case DW_OP_##name:		\
diff --git a/valgrind-3.5.0-adjtimex.patch b/valgrind-3.5.0-adjtimex.patch
new file mode 100644
index 0000000..37c36e7
--- /dev/null
+++ b/valgrind-3.5.0-adjtimex.patch
@@ -0,0 +1,49 @@
+--- valgrind-3.5.0/include/vki/vki-linux.h	(revision 10968)
++++ valgrind-3.5.0/include/vki/vki-linux.h	(revision 10969)
+@@ -283,8 +283,11 @@ struct vki_timex {
+ #define VKI_ADJ_ESTERROR		0x0008	/* estimated time error */
+ #define VKI_ADJ_STATUS			0x0010	/* clock status */
+ #define VKI_ADJ_TIMECONST		0x0020	/* pll time constant */
++#define VKI_ADJ_TAI			0x0080	/* set TAI offset */
+ #define VKI_ADJ_TICK			0x4000	/* tick value */
++#define VKI_ADJ_ADJTIME			0x8000	/* switch between adjtime/adjtimex modes */
+ //#define VKI_ADJ_OFFSET_SINGLESHOT	0x8001	/* old-fashioned adjtime */
++#define VKI_ADJ_OFFSET_READONLY		0x2000	/* read-only adjtime */
+ 
+ //----------------------------------------------------------------------
+ // From linux-2.6.8.1/include/linux/times.h
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-linux.c	(revision 10968)
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-linux.c	(revision 10969)
+@@ -623,18 +623,23 @@ PRE(sys_adjtimex)
+    PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
+    PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
+ 
+-#define ADJX(bit,field) 				\
+-   if (tx->modes & bit)					\
++#define ADJX(bits,field) 				\
++   if (tx->modes & (bits))                              \
+       PRE_MEM_READ( "adjtimex(timex->"#field")",	\
+ 		    (Addr)&tx->field, sizeof(tx->field))
+ 
+-   ADJX(VKI_ADJ_OFFSET, offset);
+-   ADJX(VKI_ADJ_FREQUENCY, freq);
+-   ADJX(VKI_ADJ_MAXERROR, maxerror);
+-   ADJX(VKI_ADJ_ESTERROR, esterror);
+-   ADJX(VKI_ADJ_STATUS, status);
+-   ADJX(VKI_ADJ_TIMECONST, constant);
+-   ADJX(VKI_ADJ_TICK, tick);
++   if (tx->modes & VKI_ADJ_ADJTIME) {
++      if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
++         PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
++   } else {
++      ADJX(VKI_ADJ_OFFSET, offset);
++      ADJX(VKI_ADJ_FREQUENCY, freq);
++      ADJX(VKI_ADJ_MAXERROR, maxerror);
++      ADJX(VKI_ADJ_ESTERROR, esterror);
++      ADJX(VKI_ADJ_STATUS, status);
++      ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
++      ADJX(VKI_ADJ_TICK, tick);
++   }
+ #undef ADJX
+ 
+    PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
diff --git a/valgrind-3.5.0-amd64-adcsbb.patch b/valgrind-3.5.0-amd64-adcsbb.patch
new file mode 100644
index 0000000..c59b83b
--- /dev/null
+++ b/valgrind-3.5.0-amd64-adcsbb.patch
@@ -0,0 +1,486 @@
+--- valgrind/VEX/priv/guest_amd64_toIR.c.jj	2009-10-21 22:46:40.000000000 +0200
++++ valgrind/VEX/priv/guest_amd64_toIR.c	2009-10-27 20:33:43.000000000 +0100
+@@ -14278,18 +14278,20 @@ DisResult disInstr_AMD64_WRK ( 
+       if (haveF2orF3(pfx)) goto decode_failure;
+       delta = dis_op_imm_A( 1, True, Iop_Add8, True, delta, "adc" );
+       break;
+-//.. //--    case 0x15: /* ADC Iv, eAX */
+-//.. //--       delta = dis_op_imm_A( sz, ADC, True, delta, "adc" );
+-//.. //--       break;
++   case 0x15: /* ADC Iv, eAX */
++      if (haveF2orF3(pfx)) goto decode_failure;
++      delta = dis_op_imm_A( sz, True, Iop_Add8, True, delta, "adc" );
++      break;
+ 
+    case 0x1C: /* SBB Ib, AL */
+       if (haveF2orF3(pfx)) goto decode_failure;
+       delta = dis_op_imm_A( 1, True, Iop_Sub8, True, delta, "sbb" );
+       break;
+-//.. //--    case 0x1D: /* SBB Iv, eAX */
+-//.. //--       delta = dis_op_imm_A( sz, SBB, True, delta, "sbb" );
+-//.. //--       break;
+-//.. //-- 
++   case 0x1D: /* SBB Iv, eAX */
++      if (haveF2orF3(pfx)) goto decode_failure;
++      delta = dis_op_imm_A( sz, True, Iop_Sub8, True, delta, "sbb" );
++      break;
++
+    case 0x24: /* AND Ib, AL */
+       if (haveF2orF3(pfx)) goto decode_failure;
+       delta = dis_op_imm_A( 1, False, Iop_And8, True, delta, "and" );
+@@ -14364,9 +14366,10 @@ DisResult disInstr_AMD64_WRK ( 
+       delta = dis_op2_E_G ( vbi, pfx, True, Iop_Add8, True, sz, delta, "adc" );
+       break;
+ 
+-//.. //--    case 0x1A: /* SBB Eb,Gb */
+-//.. //--       delta = dis_op2_E_G ( sorb, True, SBB, True, 1, delta, "sbb" );
+-//.. //--       break;
++   case 0x1A: /* SBB Eb,Gb */
++      if (haveF2orF3(pfx)) goto decode_failure;
++      delta = dis_op2_E_G ( vbi, pfx, True, Iop_Sub8, True, 1, delta, "sbb" );
++      break;
+    case 0x1B: /* SBB Ev,Gv */
+       if (haveF2orF3(pfx)) goto decode_failure;
+       delta = dis_op2_E_G ( vbi, pfx, True, Iop_Sub8, True, sz, delta, "sbb" );
+--- valgrind/none/tests/x86/sbbmisc.stdout.exp.jj	2009-10-09 12:52:02.000000000 +0200
++++ valgrind/none/tests/x86/sbbmisc.stdout.exp	2009-10-27 20:50:15.000000000 +0100
+@@ -5,3 +5,6 @@ r4 = 11 10
+ r5 = -11 -12
+ r6 = -69 -68
+ r7 = -113 -112
++r8 = 104 105
++r9 = -14982 -14981
++r10 = -267879790 -267879789
+--- valgrind/none/tests/x86/sbbmisc.c.jj	2009-10-09 12:52:02.000000000 +0200
++++ valgrind/none/tests/x86/sbbmisc.c	2009-10-27 20:48:00.000000000 +0100
+@@ -140,7 +140,58 @@ VG_SYM(adc_eb_gb_2) ":\n"
+ "\tret\n"
+ );
+ 
++extern void adc_ib_al ( void );
++asm("\n"
++VG_SYM(adc_ib_al) ":\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tclc\n"
++"\tadcb $5, %al\n"
++"\tmovb %al, " VG_SYM(out_b1) "\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tstc\n"
++"\tadcb $5, %al\n"
++"\tmovb %al, " VG_SYM(out_b2) "\n"
+ 
++"\tret\n"
++);
++
++
++extern void adc_iw_ax ( void );
++asm("\n"
++VG_SYM(adc_iw_ax) ":\n"
++
++"\tmovw " VG_SYM(in_w) ", %ax\n"
++"\tclc\n"
++"\tadcw $555, %ax\n"
++"\tmovw %ax, " VG_SYM(out_w1) "\n"
++
++"\tmovw " VG_SYM(in_w) ", %ax\n"
++"\tstc\n"
++"\tadcw $555, %ax\n"
++"\tmovw %ax, " VG_SYM(out_w2) "\n"
++
++"\tret\n"
++);
++
++
++extern void adc_il_eax ( void );
++asm("\n"
++VG_SYM(adc_il_eax) ":\n"
++
++"\tmovl " VG_SYM(in_l) ", %eax\n"
++"\tclc\n"
++"\tadcl $555666, %eax\n"
++"\tmovl %eax, " VG_SYM(out_l1) "\n"
++
++"\tmovl " VG_SYM(in_l) ", %eax\n"
++"\tstc\n"
++"\tadcl $555666, %eax\n"
++"\tmovl %eax, " VG_SYM(out_l2) "\n"
++
++"\tret\n"
++);
+ 
+ 
+ int main ( void )
+@@ -177,5 +228,17 @@ int main ( void )
+    adc_eb_gb_2();
+    printf("r7 = %d %d\n", (int)out_b1, (int)out_b2);
+ 
++   in_b = 99;
++   adc_ib_al();
++   printf("r8 = %d %d\n", (int)out_b1, (int)out_b2);
++
++   in_w = 49999;
++   adc_iw_ax();
++   printf("r9 = %d %d\n", (int)out_w1, (int)out_w2);
++
++   in_l = 0xF0000000;
++   adc_il_eax();
++   printf("r10 = %d %d\n", (int)out_l1, (int)out_l2);
++
+    return 0;
+ }
+--- valgrind/none/tests/amd64/sbbmisc.vgtest.jj	2009-10-27 20:50:44.000000000 +0100
++++ valgrind/none/tests/amd64/sbbmisc.vgtest	2009-10-09 12:52:02.000000000 +0200
+@@ -0,0 +1 @@
++prog: sbbmisc
+--- valgrind/none/tests/amd64/sbbmisc.stdout.exp.jj	2009-10-27 20:50:41.000000000 +0100
++++ valgrind/none/tests/amd64/sbbmisc.stdout.exp	2009-10-27 20:50:15.000000000 +0100
+@@ -0,0 +1,10 @@
++r1 = 94 93
++r2 = -16092 -16093
++r3 = -268991122 -268991123
++r4 = 11 10
++r5 = -11 -12
++r6 = -69 -68
++r7 = -113 -112
++r8 = 104 105
++r9 = -14982 -14981
++r10 = -267879790 -267879789
+--- valgrind/none/tests/amd64/Makefile.am.jj	2009-10-09 12:52:01.000000000 +0200
++++ valgrind/none/tests/amd64/Makefile.am	2009-10-27 20:55:27.000000000 +0100
+@@ -43,6 +43,7 @@ EXTRA_DIST = \
+ 	redundantRexW.vgtest redundantRexW.stdout.exp \
+ 	redundantRexW.stderr.exp \
+ 	smc1.stderr.exp smc1.stdout.exp smc1.vgtest \
++	sbbmisc.stderr.exp sbbmisc.stdout.exp sbbmisc.vgtest \
+ 	shrld.stderr.exp shrld.stdout.exp shrld.vgtest \
+ 	ssse3_misaligned.stderr.exp ssse3_misaligned.stdout.exp \
+ 	ssse3_misaligned.vgtest \
+@@ -58,6 +59,7 @@ check_PROGRAMS = \
+ 	rcl-amd64 \
+ 	redundantRexW \
+ 	smc1 \
++	sbbmisc \
+ 	nibz_bennee_mmap
+ if BUILD_SSSE3_TESTS
+  check_PROGRAMS += ssse3_misaligned
+--- valgrind/none/tests/amd64/Makefile.in.jj	2009-10-09 12:52:33.000000000 +0200
++++ valgrind/none/tests/amd64/Makefile.in	2009-10-27 20:56:47.000000000 +0100
+@@ -53,8 +53,8 @@ DIST_COMMON = $(dist_noinst_SCRIPTS) $(s
+ check_PROGRAMS = amd64locked$(EXEEXT) bug127521-64$(EXEEXT) \
+ 	bug132813-amd64$(EXEEXT) bug132918$(EXEEXT) clc$(EXEEXT) \
+ 	$(am__EXEEXT_3) rcl-amd64$(EXEEXT) redundantRexW$(EXEEXT) \
+-	smc1$(EXEEXT) nibz_bennee_mmap$(EXEEXT) $(am__EXEEXT_4) \
+-	$(am__EXEEXT_5)
++	smc1$(EXEEXT) sbbmisc$(EXEEXT) nibz_bennee_mmap$(EXEEXT) \
++	$(am__EXEEXT_4) $(am__EXEEXT_5)
+ @BUILD_SSSE3_TESTS_TRUE@am__append_3 = ssse3_misaligned
+ 
+ # DDD: these need to be made to work on Darwin like the x86/ ones were.
+@@ -169,6 +169,9 @@ slahf_amd64_LDADD = $(LDADD)
+ smc1_SOURCES = smc1.c
+ smc1_OBJECTS = smc1.$(OBJEXT)
+ smc1_LDADD = $(LDADD)
++sbbmisc_SOURCES = sbbmisc.c
++sbbmisc_OBJECTS = sbbmisc.$(OBJEXT)
++sbbmisc_LDADD = $(LDADD)
+ ssse3_misaligned_SOURCES = ssse3_misaligned.c
+ ssse3_misaligned_OBJECTS = ssse3_misaligned.$(OBJEXT)
+ ssse3_misaligned_LDADD = $(LDADD)
+@@ -186,7 +189,7 @@ SOURCES = amd64locked.c bug127521-64.c b
+ 	$(insn_mmx_SOURCES) $(insn_sse_SOURCES) $(insn_sse2_SOURCES) \
+ 	$(insn_sse3_SOURCES) $(insn_ssse3_SOURCES) jrcxz.c looper.c \
+ 	loopnel.c nibz_bennee_mmap.c rcl-amd64.c redundantRexW.c \
+-	shrld.c slahf-amd64.c smc1.c ssse3_misaligned.c
++	shrld.c slahf-amd64.c smc1.c sbbmisc.c ssse3_misaligned.c
+ DIST_SOURCES = amd64locked.c bug127521-64.c bug132813-amd64.c \
+ 	bug132918.c bug137714-amd64.c bug156404-amd64.c clc.c \
+ 	faultstatus.c fcmovnu.c fxtract.c $(insn_basic_SOURCES) \
+@@ -194,7 +197,7 @@ DIST_SOURCES = amd64locked.c bug127521-6
+ 	$(insn_sse2_SOURCES) $(insn_sse3_SOURCES) \
+ 	$(insn_ssse3_SOURCES) jrcxz.c looper.c loopnel.c \
+ 	nibz_bennee_mmap.c rcl-amd64.c redundantRexW.c shrld.c \
+-	slahf-amd64.c smc1.c ssse3_misaligned.c
++	slahf-amd64.c smc1.c sbbmisc.c ssse3_misaligned.c
+ ETAGS = etags
+ CTAGS = ctags
+ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+@@ -548,6 +551,7 @@ EXTRA_DIST = \
+ 	redundantRexW.vgtest redundantRexW.stdout.exp \
+ 	redundantRexW.stderr.exp \
+ 	smc1.stderr.exp smc1.stdout.exp smc1.vgtest \
++	sbbmisc.stderr.exp sbbmisc.stdout.exp sbbmisc.vgtest \
+ 	shrld.stderr.exp shrld.stdout.exp shrld.vgtest \
+ 	ssse3_misaligned.stderr.exp ssse3_misaligned.stdout.exp \
+ 	ssse3_misaligned.vgtest \
+@@ -688,6 +692,9 @@ slahf-amd64$(EXEEXT): $(slahf_amd64_OBJE
+ smc1$(EXEEXT): $(smc1_OBJECTS) $(smc1_DEPENDENCIES) 
+ 	@rm -f smc1$(EXEEXT)
+ 	$(LINK) $(smc1_LDFLAGS) $(smc1_OBJECTS) $(smc1_LDADD) $(LIBS)
++sbbmisc$(EXEEXT): $(sbbmisc_OBJECTS) $(sbbmisc_DEPENDENCIES) 
++	@rm -f sbbmisc$(EXEEXT)
++	$(LINK) $(sbbmisc_LDFLAGS) $(sbbmisc_OBJECTS) $(sbbmisc_LDADD) $(LIBS)
+ ssse3_misaligned$(EXEEXT): $(ssse3_misaligned_OBJECTS) $(ssse3_misaligned_DEPENDENCIES) 
+ 	@rm -f ssse3_misaligned$(EXEEXT)
+ 	$(LINK) $(ssse3_misaligned_LDFLAGS) $(ssse3_misaligned_OBJECTS) $(ssse3_misaligned_LDADD) $(LIBS)
+@@ -724,6 +731,7 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shrld.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slahf-amd64.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smc1.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sbbmisc.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssse3_misaligned.Po@am__quote@
+ 
+ .c.o:
+--- valgrind/none/tests/amd64/sbbmisc.c.jj	2009-10-27 20:50:36.000000000 +0100
++++ valgrind/none/tests/amd64/sbbmisc.c	2009-10-27 20:51:57.000000000 +0100
+@@ -0,0 +1,244 @@
++#include "tests/asm.h"
++#include <stdio.h>
++
++char in_b, out_b1, out_b2, in_b2;
++
++short in_w, out_w1, out_w2;
++
++int in_l, out_l1, out_l2;
++
++extern void sbb_ib_al ( void );
++asm("\n"
++VG_SYM(sbb_ib_al) ":\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tclc\n"
++"\tsbbb $5, %al\n"
++"\tmovb %al, " VG_SYM(out_b1) "\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tstc\n"
++"\tsbbb $5, %al\n"
++"\tmovb %al, " VG_SYM(out_b2) "\n"
++
++"\tretq\n"
++);
++
++
++extern void sbb_iw_ax ( void );
++asm("\n"
++VG_SYM(sbb_iw_ax) ":\n"
++
++"\tmovw " VG_SYM(in_w) ", %ax\n"
++"\tclc\n"
++"\tsbbw $555, %ax\n"
++"\tmovw %ax, " VG_SYM(out_w1) "\n"
++
++"\tmovw " VG_SYM(in_w) ", %ax\n"
++"\tstc\n"
++"\tsbbw $555, %ax\n"
++"\tmovw %ax, " VG_SYM(out_w2) "\n"
++
++"\tretq\n"
++);
++
++
++extern void sbb_il_eax ( void );
++asm("\n"
++VG_SYM(sbb_il_eax) ":\n"
++
++"\tmovl " VG_SYM(in_l) ", %eax\n"
++"\tclc\n"
++"\tsbbl $555666, %eax\n"
++"\tmovl %eax, " VG_SYM(out_l1) "\n"
++
++"\tmovl " VG_SYM(in_l) ", %eax\n"
++"\tstc\n"
++"\tsbbl $555666, %eax\n"
++"\tmovl %eax, " VG_SYM(out_l2) "\n"
++
++"\tretq\n"
++);
++
++
++extern void sbb_eb_gb ( void );
++asm("\n"
++VG_SYM(sbb_eb_gb) ":\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tclc\n"
++"\tsbbb " VG_SYM(in_b2) ", %al\n"
++"\tmovb %al, " VG_SYM(out_b1) "\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tstc\n"
++"\tsbbb " VG_SYM(in_b2) ", %al\n"
++"\tmovb %al, " VG_SYM(out_b2) "\n"
++
++"\tretq\n"
++);
++
++
++extern void sbb_eb_gb_2 ( void );
++asm("\n"
++VG_SYM(sbb_eb_gb_2) ":\n"
++"\tpushq %rcx\n"
++
++"\tmovb " VG_SYM(in_b) ", %cl\n"
++"\tmovb " VG_SYM(in_b2) ", %dh\n"
++"\tclc\n"
++"\tsbbb %dh,%cl\n"
++"\tmovb %cl, " VG_SYM(out_b1) "\n"
++
++"\tmovb " VG_SYM(in_b) ", %cl\n"
++"\tmovb " VG_SYM(in_b2) ", %dh\n"
++"\tstc\n"
++"\tsbbb %dh,%cl\n"
++"\tmovb %cl, " VG_SYM(out_b2) "\n"
++
++"\tpopq %rcx\n"
++"\tretq\n"
++);
++
++
++extern void adc_eb_gb ( void );
++asm("\n"
++VG_SYM(adc_eb_gb) ":\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tclc\n"
++"\tadcb " VG_SYM(in_b2) ", %al\n"
++"\tmovb %al, " VG_SYM(out_b1) "\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tstc\n"
++"\tadcb " VG_SYM(in_b2) ", %al\n"
++"\tmovb %al, " VG_SYM(out_b2) "\n"
++
++"\tretq\n"
++);
++
++
++extern void adc_eb_gb_2 ( void );
++asm("\n"
++VG_SYM(adc_eb_gb_2) ":\n"
++"\tpushq %rcx\n"
++
++"\tmovb " VG_SYM(in_b) ", %cl\n"
++"\tmovb " VG_SYM(in_b2) ", %dh\n"
++"\tclc\n"
++"\tadcb %dh,%cl\n"
++"\tmovb %cl, " VG_SYM(out_b1) "\n"
++
++"\tmovb " VG_SYM(in_b) ", %cl\n"
++"\tmovb " VG_SYM(in_b2) ", %dh\n"
++"\tstc\n"
++"\tadcb %dh,%cl\n"
++"\tmovb %cl, " VG_SYM(out_b2) "\n"
++
++"\tpopq %rcx\n"
++"\tretq\n"
++);
++
++extern void adc_ib_al ( void );
++asm("\n"
++VG_SYM(adc_ib_al) ":\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tclc\n"
++"\tadcb $5, %al\n"
++"\tmovb %al, " VG_SYM(out_b1) "\n"
++
++"\tmovb " VG_SYM(in_b) ", %al\n"
++"\tstc\n"
++"\tadcb $5, %al\n"
++"\tmovb %al, " VG_SYM(out_b2) "\n"
++
++"\tretq\n"
++);
++
++
++extern void adc_iw_ax ( void );
++asm("\n"
++VG_SYM(adc_iw_ax) ":\n"
++
++"\tmovw " VG_SYM(in_w) ", %ax\n"
++"\tclc\n"
++"\tadcw $555, %ax\n"
++"\tmovw %ax, " VG_SYM(out_w1) "\n"
++
++"\tmovw " VG_SYM(in_w) ", %ax\n"
++"\tstc\n"
++"\tadcw $555, %ax\n"
++"\tmovw %ax, " VG_SYM(out_w2) "\n"
++
++"\tretq\n"
++);
++
++
++extern void adc_il_eax ( void );
++asm("\n"
++VG_SYM(adc_il_eax) ":\n"
++
++"\tmovl " VG_SYM(in_l) ", %eax\n"
++"\tclc\n"
++"\tadcl $555666, %eax\n"
++"\tmovl %eax, " VG_SYM(out_l1) "\n"
++
++"\tmovl " VG_SYM(in_l) ", %eax\n"
++"\tstc\n"
++"\tadcl $555666, %eax\n"
++"\tmovl %eax, " VG_SYM(out_l2) "\n"
++
++"\tretq\n"
++);
++
++
++int main ( void )
++{
++   in_b = 99;
++   sbb_ib_al();
++   printf("r1 = %d %d\n", (int)out_b1, (int)out_b2);
++
++   in_w = 49999;
++   sbb_iw_ax();
++   printf("r2 = %d %d\n", (int)out_w1, (int)out_w2);
++
++   in_l = 0xF0000000;
++   sbb_il_eax();
++   printf("r3 = %d %d\n", (int)out_l1, (int)out_l2);
++
++   in_b = 99;
++   in_b2 = 88;
++   sbb_eb_gb();
++   printf("r4 = %d %d\n", (int)out_b1, (int)out_b2);
++
++   in_b = 66;
++   in_b2 = 77;
++   sbb_eb_gb_2();
++   printf("r5 = %d %d\n", (int)out_b1, (int)out_b2);
++
++   in_b = 99;
++   in_b2 = 88;
++   adc_eb_gb();
++   printf("r6 = %d %d\n", (int)out_b1, (int)out_b2);
++
++   in_b = 66;
++   in_b2 = 77;
++   adc_eb_gb_2();
++   printf("r7 = %d %d\n", (int)out_b1, (int)out_b2);
++
++   in_b = 99;
++   adc_ib_al();
++   printf("r8 = %d %d\n", (int)out_b1, (int)out_b2);
++
++   in_w = 49999;
++   adc_iw_ax();
++   printf("r9 = %d %d\n", (int)out_w1, (int)out_w2);
++
++   in_l = 0xF0000000;
++   adc_il_eax();
++   printf("r10 = %d %d\n", (int)out_l1, (int)out_l2);
++
++   return 0;
++}
+--- valgrind/none/tests/amd64/sbbmisc.stderr.exp.jj	2009-10-27 20:50:39.000000000 +0100
++++ valgrind/none/tests/amd64/sbbmisc.stderr.exp	2009-10-09 12:52:02.000000000 +0200
+@@ -0,0 +1,2 @@
++
++
diff --git a/valgrind-3.5.0-amd64-loopnel.patch b/valgrind-3.5.0-amd64-loopnel.patch
new file mode 100644
index 0000000..4754674
--- /dev/null
+++ b/valgrind-3.5.0-amd64-loopnel.patch
@@ -0,0 +1,151 @@
+--- valgrind/VEX/priv/guest_amd64_toIR.c.jj	2009-10-09 12:52:07.000000000 +0200
++++ valgrind/VEX/priv/guest_amd64_toIR.c	2009-10-21 22:46:40.000000000 +0200
+@@ -14011,17 +14011,19 @@ DisResult disInstr_AMD64_WRK ( 
+    case 0xE1: /* LOOPE  disp8: decrement count, jump if count != 0 && ZF==1 */
+    case 0xE2: /* LOOP   disp8: decrement count, jump if count != 0 */
+     { /* The docs say this uses rCX as a count depending on the
+-         address size override, not the operand one.  Since we don't
+-         handle address size overrides, I guess that means RCX. */
++         address size override, not the operand one.  */
+       IRExpr* zbit  = NULL;
+       IRExpr* count = NULL;
+       IRExpr* cond  = NULL;
+       HChar*  xtra  = NULL;
+ 
+-      if (have66orF2orF3(pfx) || haveASO(pfx)) goto decode_failure;
++      if (have66orF2orF3(pfx)) goto decode_failure;
+       d64 = guest_RIP_bbstart+delta+1 + getSDisp8(delta);
+       delta++;
+-      putIReg64(R_RCX, binop(Iop_Sub64, getIReg64(R_RCX), mkU64(1)));
++      if (haveASO (pfx))
++         putIReg32(R_RCX, binop(Iop_Sub32, getIReg32(R_RCX), mkU32(1)));
++      else
++         putIReg64(R_RCX, binop(Iop_Sub64, getIReg64(R_RCX), mkU64(1)));
+ 
+       count = getIReg64(R_RCX);
+       cond = binop(Iop_CmpNE64, count, mkU64(0));
+--- valgrind/none/tests/amd64/loopnel.c.jj	2009-10-22 09:42:36.000000000 +0200
++++ valgrind/none/tests/amd64/loopnel.c	2009-10-22 09:43:07.000000000 +0200
+@@ -0,0 +1,11 @@
++#include <stdio.h>
++
++int
++main (void)
++{
++  long rcx = 0x200000005UL;
++  long rax = 5UL;
++  asm volatile ("1: addq $1, %0; loopnel 1b" : "+a" (rax), "+c" (rcx) : : "cc");
++  printf ("%ld %ld\n", rax, rcx);
++  return 0;
++}
+--- valgrind/none/tests/amd64/loopnel.vgtest.jj	2009-10-22 09:43:54.000000000 +0200
++++ valgrind/none/tests/amd64/loopnel.vgtest	2009-10-22 09:43:59.000000000 +0200
+@@ -0,0 +1 @@
++prog: loopnel
+--- valgrind/none/tests/amd64/loopnel.stdout.exp.jj	2009-10-22 09:43:28.000000000 +0200
++++ valgrind/none/tests/amd64/loopnel.stdout.exp	2009-10-22 09:43:24.000000000 +0200
+@@ -0,0 +1 @@
++10 0
+--- valgrind/none/tests/amd64/loopnel.stderr.exp.jj	2009-10-22 09:43:40.000000000 +0200
++++ valgrind/none/tests/amd64/loopnel.stderr.exp	2009-08-19 15:37:15.000000000 +0200
+@@ -0,0 +1,2 @@
++
++
+--- valgrind/none/tests/amd64/Makefile.am.jj	2009-08-19 15:37:15.000000000 +0200
++++ valgrind/none/tests/amd64/Makefile.am	2009-10-22 09:44:53.000000000 +0200
+@@ -37,6 +37,7 @@ EXTRA_DIST = \
+ 	insn_ssse3.stdout.exp insn_ssse3.stderr.exp insn_ssse3.vgtest \
+ 	jrcxz.stderr.exp jrcxz.stdout.exp jrcxz.vgtest \
+ 	looper.stderr.exp looper.stdout.exp looper.vgtest \
++	loopnel.stderr.exp loopnel.stdout.exp loopnel.vgtest \
+ 	nibz_bennee_mmap.stderr.exp nibz_bennee_mmap.stdout.exp \
+ 	nibz_bennee_mmap.vgtest \
+ 	rcl-amd64.vgtest rcl-amd64.stdout.exp rcl-amd64.stderr.exp \
+@@ -72,6 +73,7 @@ if ! VGCONF_OS_IS_DARWIN
+ 	fcmovnu \
+ 	fxtract \
+ 	looper \
++	loopnel \
+ 	jrcxz \
+ 	shrld \
+ 	slahf-amd64
+--- valgrind/none/tests/amd64/Makefile.in.jj	2009-08-19 15:43:22.000000000 +0200
++++ valgrind/none/tests/amd64/Makefile.in	2009-10-22 09:46:44.000000000 +0200
+@@ -65,6 +65,7 @@ check_PROGRAMS = amd64locked$(EXEEXT) bu
+ @VGCONF_OS_IS_DARWIN_FALSE@	fcmovnu \
+ @VGCONF_OS_IS_DARWIN_FALSE@	fxtract \
+ @VGCONF_OS_IS_DARWIN_FALSE@	looper \
++@VGCONF_OS_IS_DARWIN_FALSE@	loopnel \
+ @VGCONF_OS_IS_DARWIN_FALSE@	jrcxz \
+ @VGCONF_OS_IS_DARWIN_FALSE@	shrld \
+ @VGCONF_OS_IS_DARWIN_FALSE@	slahf-amd64
+@@ -87,8 +88,9 @@ am__EXEEXT_3 = insn_basic$(EXEEXT) insn_
+ @VGCONF_OS_IS_DARWIN_FALSE@	bug156404-amd64$(EXEEXT) \
+ @VGCONF_OS_IS_DARWIN_FALSE@	faultstatus$(EXEEXT) \
+ @VGCONF_OS_IS_DARWIN_FALSE@	fcmovnu$(EXEEXT) fxtract$(EXEEXT) \
+-@VGCONF_OS_IS_DARWIN_FALSE@	looper$(EXEEXT) jrcxz$(EXEEXT) \
+-@VGCONF_OS_IS_DARWIN_FALSE@	shrld$(EXEEXT) slahf-amd64$(EXEEXT)
++@VGCONF_OS_IS_DARWIN_FALSE@	looper$(EXEEXT) loopnel$(EXEEXT) \
++@VGCONF_OS_IS_DARWIN_FALSE@	jrcxz$(EXEEXT) shrld$(EXEEXT) \
++@VGCONF_OS_IS_DARWIN_FALSE@	slahf-amd64$(EXEEXT)
+ amd64locked_SOURCES = amd64locked.c
+ amd64locked_OBJECTS = amd64locked-amd64locked.$(OBJEXT)
+ amd64locked_LDADD = $(LDADD)
+@@ -146,6 +148,9 @@ jrcxz_LDADD = $(LDADD)
+ looper_SOURCES = looper.c
+ looper_OBJECTS = looper.$(OBJEXT)
+ looper_LDADD = $(LDADD)
++loopnel = loopnel.c
++loopnel_OBJECTS = loopnel.$(OBJEXT)
++loopnel_LDADD = $(LDADD)
+ nibz_bennee_mmap_SOURCES = nibz_bennee_mmap.c
+ nibz_bennee_mmap_OBJECTS = nibz_bennee_mmap.$(OBJEXT)
+ nibz_bennee_mmap_LDADD = $(LDADD)
+@@ -180,16 +185,16 @@ SOURCES = amd64locked.c bug127521-64.c b
+ 	fcmovnu.c fxtract.c $(insn_basic_SOURCES) $(insn_fpu_SOURCES) \
+ 	$(insn_mmx_SOURCES) $(insn_sse_SOURCES) $(insn_sse2_SOURCES) \
+ 	$(insn_sse3_SOURCES) $(insn_ssse3_SOURCES) jrcxz.c looper.c \
+-	nibz_bennee_mmap.c rcl-amd64.c redundantRexW.c shrld.c \
+-	slahf-amd64.c smc1.c ssse3_misaligned.c
++	loopnel.c nibz_bennee_mmap.c rcl-amd64.c redundantRexW.c \
++	shrld.c slahf-amd64.c smc1.c ssse3_misaligned.c
+ DIST_SOURCES = amd64locked.c bug127521-64.c bug132813-amd64.c \
+ 	bug132918.c bug137714-amd64.c bug156404-amd64.c clc.c \
+ 	faultstatus.c fcmovnu.c fxtract.c $(insn_basic_SOURCES) \
+ 	$(insn_fpu_SOURCES) $(insn_mmx_SOURCES) $(insn_sse_SOURCES) \
+ 	$(insn_sse2_SOURCES) $(insn_sse3_SOURCES) \
+-	$(insn_ssse3_SOURCES) jrcxz.c looper.c nibz_bennee_mmap.c \
+-	rcl-amd64.c redundantRexW.c shrld.c slahf-amd64.c smc1.c \
+-	ssse3_misaligned.c
++	$(insn_ssse3_SOURCES) jrcxz.c looper.c loopnel.c \
++	nibz_bennee_mmap.c rcl-amd64.c redundantRexW.c shrld.c \
++	slahf-amd64.c smc1.c ssse3_misaligned.c
+ ETAGS = etags
+ CTAGS = ctags
+ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+@@ -536,6 +541,7 @@ EXTRA_DIST = \
+ 	insn_ssse3.stdout.exp insn_ssse3.stderr.exp insn_ssse3.vgtest \
+ 	jrcxz.stderr.exp jrcxz.stdout.exp jrcxz.vgtest \
+ 	looper.stderr.exp looper.stdout.exp looper.vgtest \
++	loopnel.stderr.exp loopnel.stdout.exp loopnel.vgtest \
+ 	nibz_bennee_mmap.stderr.exp nibz_bennee_mmap.stdout.exp \
+ 	nibz_bennee_mmap.vgtest \
+ 	rcl-amd64.vgtest rcl-amd64.stdout.exp rcl-amd64.stderr.exp \
+@@ -661,6 +667,9 @@ jrcxz$(EXEEXT): $(jrcxz_OBJECTS) $(jrcxz
+ looper$(EXEEXT): $(looper_OBJECTS) $(looper_DEPENDENCIES) 
+ 	@rm -f looper$(EXEEXT)
+ 	$(LINK) $(looper_LDFLAGS) $(looper_OBJECTS) $(looper_LDADD) $(LIBS)
++loopnel$(EXEEXT): $(loopnel_OBJECTS) $(loopnel_DEPENDENCIES) 
++	@rm -f loopnel$(EXEEXT)
++	$(LINK) $(loopnel_LDFLAGS) $(loopnel_OBJECTS) $(loopnel_LDADD) $(LIBS)
+ nibz_bennee_mmap$(EXEEXT): $(nibz_bennee_mmap_OBJECTS) $(nibz_bennee_mmap_DEPENDENCIES) 
+ 	@rm -f nibz_bennee_mmap$(EXEEXT)
+ 	$(LINK) $(nibz_bennee_mmap_LDFLAGS) $(nibz_bennee_mmap_OBJECTS) $(nibz_bennee_mmap_LDADD) $(LIBS)
+@@ -708,6 +717,7 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insn_ssse3.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jrcxz.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/looper.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loopnel.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nibz_bennee_mmap.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcl-amd64.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redundantRexW.Po@am__quote@
diff --git a/valgrind-3.5.0-dwarf3.patch b/valgrind-3.5.0-dwarf3.patch
new file mode 100644
index 0000000..a3f660b
--- /dev/null
+++ b/valgrind-3.5.0-dwarf3.patch
@@ -0,0 +1,832 @@
+--- valgrind/coregrind/m_debuginfo/readdwarf.c.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/readdwarf.c	2009-10-21 13:18:25.000000000 +0200
+@@ -37,6 +37,7 @@
+ #include "pub_core_libcprint.h"
+ #include "pub_core_options.h"
+ #include "pub_core_xarray.h"
++#include "pub_core_tooliface.h"    /* VG_(needs) */
+ #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
+ #include "priv_d3basics.h"
+ #include "priv_tytypes.h"
+@@ -3446,23 +3447,37 @@ static CIE the_CIEs[N_CIEs];
+ 
+ 
+ void ML_(read_callframe_info_dwarf3)
+-        ( /*OUT*/struct _DebugInfo* di, UChar* ehframe_image )
++        ( /*OUT*/struct _DebugInfo* di, UChar* frame_image, SizeT frame_size,
++          Bool for_eh )
+ {
+    Int    nbytes;
+    HChar* how = NULL;
+    Int    n_CIEs = 0;
+-   UChar* data = ehframe_image;
++   UChar* data = frame_image;
++   UWord  ehframe_cfsis = 0;   
+ 
+ #  if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+-   /* These targets don't use CFI-based stack unwinding. */
+-   return;
++   if (!VG_(needs).var_info /* the tool requires it */   
++       && !VG_(clo_read_var_info) /* the user asked for it */) {
++      /* These targets don't use CFI-based stack unwinding, but still might
++         need it for DW_OP_call_frame_cfa support. */
++      return;
++   }
+ #  endif
+ 
++   /* If we are reading .debug_frame after .eh_frame has been read, only
++      add FDEs which weren't covered in .eh_frame.  To be able to quickly
++      search the FDEs, the records must be sorted.  */
++   if ( ! for_eh && di->ehframe_size && di->cfsi_used ) {
++      ML_(canonicaliseCFI) ( di );
++      ehframe_cfsis = di->cfsi_used;
++   }
++
+    if (di->trace_cfi) {
+       VG_(printf)("\n-----------------------------------------------\n");
+       VG_(printf)("CFI info: szB %ld, _avma %#lx, _image %p\n",
+-                  di->ehframe_size, di->ehframe_avma,
+-                  ehframe_image );
++                  frame_size, for_eh ? di->ehframe_avma : 0,
++                  frame_image );
+       VG_(printf)("CFI info: name %s\n",
+                   di->filename );
+    }
+@@ -3495,11 +3510,11 @@ void ML_(read_callframe_info_dwarf3)
+       Bool   dw64;
+ 
+       /* Are we done? */
+-      if (data == ehframe_image + di->ehframe_size)
++      if (data == frame_image + frame_size)
+          return;
+ 
+       /* Overshot the end?  Means something is wrong */
+-      if (data > ehframe_image + di->ehframe_size) {
++      if (data > frame_image + frame_size) {
+          how = "overran the end of .eh_frame";
+          goto bad;
+       }
+@@ -3509,9 +3524,9 @@ void ML_(read_callframe_info_dwarf3)
+ 
+       ciefde_start = data;
+       if (di->trace_cfi) 
+-         VG_(printf)("\ncie/fde.start   = %p (ehframe_image + 0x%lx)\n", 
++         VG_(printf)("\ncie/fde.start   = %p (frame_image + 0x%lx)\n", 
+                      ciefde_start,
+-                     ciefde_start - ehframe_image + 0UL);
++                     ciefde_start - frame_image + 0UL);
+ 
+       ciefde_len = (ULong) read_UInt(data); data += sizeof(UInt);
+       if (di->trace_cfi) 
+@@ -3524,7 +3539,7 @@ void ML_(read_callframe_info_dwarf3)
+       if (ciefde_len == 0) {
+          if (di->ddump_frames)
+             VG_(printf)("%08lx ZERO terminator\n\n",
+-                        ((Addr)ciefde_start) - ((Addr)ehframe_image));
++                        ((Addr)ciefde_start) - ((Addr)frame_image));
+          return;
+       }
+ 
+@@ -3550,8 +3565,10 @@ void ML_(read_callframe_info_dwarf3)
+       if (di->trace_cfi) 
+          VG_(printf)("cie.pointer     = %lld\n", cie_pointer);
+ 
+-      /* If cie_pointer is zero, we've got a CIE; else it's an FDE. */
+-      if (cie_pointer == 0) {
++      /* If cie_pointer is zero for .eh_frame or all ones for .debug_frame,
++         we've got a CIE; else it's an FDE. */
++      if (cie_pointer == (for_eh ? 0ULL
++                          : dw64 ? 0xFFFFFFFFFFFFFFFFULL : 0xFFFFFFFFULL)) {
+ 
+          Int    this_CIE;
+          UChar  cie_version;
+@@ -3575,11 +3592,11 @@ void ML_(read_callframe_info_dwarf3)
+ 
+ 	 /* Record its offset.  This is how we will find it again
+             later when looking at an FDE. */
+-         the_CIEs[this_CIE].offset = (ULong)(ciefde_start - ehframe_image);
++         the_CIEs[this_CIE].offset = (ULong)(ciefde_start - frame_image);
+ 
+          if (di->ddump_frames)
+             VG_(printf)("%08lx %08lx %08lx CIE\n",
+-                        ((Addr)ciefde_start) - ((Addr)ehframe_image),
++                        ((Addr)ciefde_start) - ((Addr)frame_image),
+                         (Addr)ciefde_len,
+                         (Addr)(UWord)cie_pointer );
+ 
+@@ -3623,8 +3640,13 @@ void ML_(read_callframe_info_dwarf3)
+             VG_(printf)("  Data alignment factor: %d\n",
+                         (Int)the_CIEs[this_CIE].data_a_f);
+ 
+-         the_CIEs[this_CIE].ra_reg = (Int)read_UChar(data); 
+-         data += sizeof(UChar);
++         if (cie_version == 1) {
++            the_CIEs[this_CIE].ra_reg = (Int)read_UChar(data); 
++            data += sizeof(UChar);
++         } else {
++            the_CIEs[this_CIE].ra_reg = read_leb128( data, &nbytes, 0);
++            data += nbytes;
++         }
+          if (di->trace_cfi) 
+             VG_(printf)("cie.ra_reg      = %d\n", 
+                         the_CIEs[this_CIE].ra_reg);
+@@ -3702,7 +3724,7 @@ void ML_(read_callframe_info_dwarf3)
+ 	 }
+ 
+          if (the_CIEs[this_CIE].ilen < 0
+-             || the_CIEs[this_CIE].ilen > di->ehframe_size) {
++             || the_CIEs[this_CIE].ilen > frame_size) {
+             how = "implausible # cie initial insns";
+             goto bad;
+          }
+@@ -3717,8 +3739,8 @@ void ML_(read_callframe_info_dwarf3)
+          if (di->trace_cfi || di->ddump_frames) {
+             AddressDecodingInfo adi;
+             adi.encoding      = the_CIEs[this_CIE].address_encoding;
+-            adi.ehframe_image = ehframe_image;
+-            adi.ehframe_avma  = di->ehframe_avma;
++            adi.ehframe_image = frame_image;
++            adi.ehframe_avma  = for_eh ? di->ehframe_avma : 0;
+             adi.text_bias     = di->text_debug_bias;
+             show_CF_instructions( the_CIEs[this_CIE].instrs, 
+                                   the_CIEs[this_CIE].ilen, &adi,
+@@ -3747,9 +3769,12 @@ void ML_(read_callframe_info_dwarf3)
+             cie_pointer bytes back from here. */
+ 
+          /* re sizeof(UInt) / sizeof(ULong), matches XXX above. */
+-         look_for = (data - (dw64 ? sizeof(ULong) : sizeof(UInt)) 
+-                          - ehframe_image) 
+-                    - cie_pointer;
++         if (for_eh)
++            look_for = (data - (dw64 ? sizeof(ULong) : sizeof(UInt)) 
++                             - frame_image) 
++                       - cie_pointer;
++         else
++            look_for = cie_pointer;
+ 
+          for (cie = 0; cie < n_CIEs; cie++) {
+             if (0) VG_(printf)("look for %lld   %lld\n",
+@@ -3764,8 +3789,8 @@ void ML_(read_callframe_info_dwarf3)
+ 	 }
+ 
+          adi.encoding      = the_CIEs[cie].address_encoding;
+-         adi.ehframe_image = ehframe_image;
+-         adi.ehframe_avma  = di->ehframe_avma;
++         adi.ehframe_image = frame_image;
++         adi.ehframe_avma  = for_eh ? di->ehframe_avma : 0;
+          adi.text_bias     = di->text_debug_bias;
+          fde_initloc = read_encoded_Addr(&nbytes, &adi, data);
+          data += nbytes;
+@@ -3773,8 +3798,8 @@ void ML_(read_callframe_info_dwarf3)
+             VG_(printf)("fde.initloc     = %#lx\n", fde_initloc);
+ 
+          adi.encoding      = the_CIEs[cie].address_encoding & 0xf;
+-         adi.ehframe_image = ehframe_image;
+-         adi.ehframe_avma  = di->ehframe_avma;
++         adi.ehframe_image = frame_image;
++         adi.ehframe_avma  = for_eh ? di->ehframe_avma : 0;
+          adi.text_bias     = di->text_debug_bias;
+ 
+          /* WAS (incorrectly):
+@@ -3800,7 +3825,7 @@ void ML_(read_callframe_info_dwarf3)
+ 
+          if (di->ddump_frames)
+             VG_(printf)("%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
+-                        ((Addr)ciefde_start) - ((Addr)ehframe_image),
++                        ((Addr)ciefde_start) - ((Addr)frame_image),
+                         (Addr)ciefde_len,
+                         (Addr)(UWord)cie_pointer,
+                         (Addr)look_for, 
+@@ -3827,16 +3852,43 @@ void ML_(read_callframe_info_dwarf3)
+             VG_(printf)("fde.ilen        = %d\n", (Int)fde_ilen);
+ 	 }
+ 
+-         if (fde_ilen < 0 || fde_ilen > di->ehframe_size) {
++         if (fde_ilen < 0 || fde_ilen > frame_size) {
+             how = "implausible # fde insns";
+             goto bad;
+          }
+ 
+ 	 data += fde_ilen;
+ 
++         if (ehframe_cfsis) {
++            Addr a_mid_lo, a_mid_hi;
++            Word mid, size, 
++                 lo = 0, 
++                 hi = ehframe_cfsis-1;
++            while (True) {
++               /* current unsearched space is from lo to hi, inclusive. */
++               if (lo > hi) break; /* not found */
++               mid      = (lo + hi) / 2;
++               a_mid_lo = di->cfsi[mid].base;
++               size     = di->cfsi[mid].len;
++               a_mid_hi = a_mid_lo + size - 1;
++               vg_assert(a_mid_hi >= a_mid_lo);
++               if (fde_initloc + fde_arange <= a_mid_lo) {
++                  hi = mid-1; continue;
++               }
++               if (fde_initloc > a_mid_hi) { lo = mid+1; continue; }
++               break;
++            }
++
++            /* The range this .debug_frame FDE covers has been already
++               covered in .eh_frame section.  Don't add it from .debug_frame
++               section again.  */            
++            if (lo <= hi)
++               continue;
++         }
++
+          adi.encoding      = the_CIEs[cie].address_encoding;
+-         adi.ehframe_image = ehframe_image;
+-         adi.ehframe_avma  = di->ehframe_avma;
++         adi.ehframe_image = frame_image;
++         adi.ehframe_avma  = for_eh ? di->ehframe_avma : 0;
+          adi.text_bias     = di->text_debug_bias;
+ 
+          if (di->trace_cfi)
+--- valgrind/coregrind/m_debuginfo/priv_readdwarf.h.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/priv_readdwarf.h	2009-10-21 11:51:38.000000000 +0200
+@@ -62,7 +62,7 @@ void ML_(read_debuginfo_dwarf1) ( struct
+    -------------------- */
+ extern
+ void ML_(read_callframe_info_dwarf3)
+-    ( /*OUT*/struct _DebugInfo* di, UChar* ehframe );
++    ( /*OUT*/struct _DebugInfo* di, UChar* frame, SizeT sz, Bool for_eh );
+ 
+ 
+ #endif /* ndef __PRIV_READDWARF_H */
+--- valgrind/coregrind/m_debuginfo/priv_d3basics.h.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/priv_d3basics.h	2009-10-21 10:49:47.000000000 +0200
+@@ -522,6 +522,9 @@ typedef enum
+     DW_OP_form_tls_address = 0x9b,
+     DW_OP_call_frame_cfa = 0x9c,
+     DW_OP_bit_piece = 0x9d,
++    /* DWARF 4 extensions.  */
++    DW_OP_implicit_value = 0x9e,
++    DW_OP_stack_value = 0x9f,
+     /* GNU extensions.  */
+     DW_OP_GNU_push_tls_address = 0xe0,
+     /* HP extensions.  */
+@@ -596,12 +599,13 @@ typedef
+ 
+ /* This describes the result of evaluating a DWARF3 expression.
+    GXR_Failure: failed; .word is an asciiz string summarising why
++   GXR_Addr:    evaluated to an address of the object, in .word
+    GXR_Value:   evaluated to a value, in .word
+    GXR_RegNo:   evaluated to a DWARF3 register number, in .word
+ */
+ typedef
+    struct { 
+-      enum { GXR_Failure, GXR_Value, GXR_RegNo } kind;
++      enum { GXR_Failure, GXR_Addr, GXR_Value, GXR_RegNo } kind;
+       UWord word;
+    }
+    GXResult;
+@@ -644,6 +648,10 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+    covered by the guard is also ignored. */
+ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di );
+ 
++/* Compute CFA for IP/SP/FP.  */
++Addr ML_(get_CFA) (Addr ip, Addr sp, Addr fp,
++                   Addr min_accessible, Addr max_accessible);
++
+ #endif /* ndef __PRIV_D3BASICS_H */
+ 
+ /*--------------------------------------------------------------------*/
+--- valgrind/coregrind/m_debuginfo/readelf.c.jj	2009-10-21 10:49:47.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/readelf.c	2009-10-21 11:52:12.000000000 +0200
+@@ -1688,6 +1688,7 @@ Bool ML_(read_elf_debug_info) ( struct _
+       UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
+       UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
+       UChar*     debug_loc_img    = NULL; /* .debug_loc    (dwarf2) */
++      UChar*     debug_frame_img  = NULL; /* .debug_frame  (dwarf2) */
+       UChar*     dwarf1d_img      = NULL; /* .debug        (dwarf1) */
+       UChar*     dwarf1l_img      = NULL; /* .line         (dwarf1) */
+       UChar*     ehframe_img      = NULL; /* .eh_frame     (dwarf2) */
+@@ -1707,6 +1708,7 @@ Bool ML_(read_elf_debug_info) ( struct _
+       SizeT      debug_str_sz    = 0;
+       SizeT      debug_ranges_sz = 0;
+       SizeT      debug_loc_sz    = 0;
++      SizeT      debug_frame_sz  = 0;
+       SizeT      dwarf1d_sz      = 0;
+       SizeT      dwarf1l_sz      = 0;
+       SizeT      ehframe_sz      = 0;
+@@ -1764,6 +1766,7 @@ Bool ML_(read_elf_debug_info) ( struct _
+          FIND(".debug_str",     debug_str_sz,    debug_str_img)
+          FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
+          FIND(".debug_loc",     debug_loc_sz,    debug_loc_img)
++         FIND(".debug_frame",   debug_frame_sz,  debug_frame_img)
+ 
+          FIND(".debug",         dwarf1d_sz,      dwarf1d_img)
+          FIND(".line",          dwarf1l_sz,      dwarf1l_img)
+@@ -1956,6 +1959,8 @@ Bool ML_(read_elf_debug_info) ( struct _
+                FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz, 
+                                                                debug_ranges_img)
+                FIND(need_dwarf2, ".debug_loc",    debug_loc_sz,  debug_loc_img)
++               FIND(need_dwarf2, ".debug_frame",  debug_frame_sz,
++                                                               debug_frame_img)
+                FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
+                FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
+ 
+@@ -1996,7 +2001,11 @@ Bool ML_(read_elf_debug_info) ( struct _
+       /* Read .eh_frame (call-frame-info) if any */
+       if (ehframe_img) {
+          vg_assert(ehframe_sz == di->ehframe_size);
+-         ML_(read_callframe_info_dwarf3)( di, ehframe_img );
++         ML_(read_callframe_info_dwarf3)( di, ehframe_img, ehframe_sz, True );
++      }
++      if (debug_frame_sz) {
++         ML_(read_callframe_info_dwarf3)( di, debug_frame_img,
++                                          debug_frame_sz, False );
+       }
+ 
+       /* Read the stabs and/or dwarf2 debug information, if any.  It
+--- valgrind/coregrind/m_debuginfo/priv_storage.h.jj	2009-10-21 10:49:47.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/priv_storage.h	2009-10-21 12:45:31.000000000 +0200
+@@ -649,6 +649,8 @@ extern void ML_(addVar)( struct _DebugIn
+    this after finishing adding entries to these tables. */
+ extern void ML_(canonicaliseTables) ( struct _DebugInfo* di );
+ 
++extern void ML_(canonicaliseCFI) ( struct _DebugInfo* di );
++
+ /* ------ Searching ------ */
+ 
+ /* Find a symbol-table index containing the specified pointer, or -1
+--- valgrind/coregrind/m_debuginfo/storage.c.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/storage.c	2009-10-21 12:44:16.000000000 +0200
+@@ -1435,7 +1435,7 @@ static Int compare_DiCfSI ( void* va, vo
+    return 0;
+ }
+ 
+-static void canonicaliseCFI ( struct _DebugInfo* di )
++void ML_(canonicaliseCFI) ( struct _DebugInfo* di )
+ {
+    Word  i, j;
+    const Addr minAvma = 0;
+@@ -1528,7 +1528,7 @@ void ML_(canonicaliseTables) ( struct _D
+ {
+    canonicaliseSymtab ( di );
+    canonicaliseLoctab ( di );
+-   canonicaliseCFI ( di );
++   ML_(canonicaliseCFI) ( di );
+    canonicaliseVarInfo ( di );
+ }
+ 
+--- valgrind/coregrind/m_debuginfo/d3basics.c.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/d3basics.c	2009-10-21 13:40:50.000000000 +0200
+@@ -443,7 +443,7 @@ static Bool bias_address( Addr* a, const
+ 
+ 
+ /* Evaluate a standard DWARF3 expression.  See detailed description in
+-   priv_d3basics.h. */
++   priv_d3basics.h.  Doesn't handle DW_OP_piece/DW_OP_bit_piece yet.  */
+ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, 
+                                      GExpr* fbGX, RegSummary* regs,
+                                      const DebugInfo* di,
+@@ -482,8 +482,8 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+    Addr     stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */
+    GXResult fbval, res;
+    Addr     a1;
+-   Word     sw1;
+-   UWord    uw1;
++   Word     sw1, sw2;
++   UWord    uw1, uw2;
+    Bool     ok;
+ 
+    sp = -1;
+@@ -568,12 +568,15 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+             switch (fbval.kind) {
+                case GXR_Failure:
+                   return fbval; /* propagate failure */
+-               case GXR_Value:
++               case GXR_Addr:
+                   a1 = fbval.word; break; /* use as-is */
+                case GXR_RegNo:
+                   ok = get_Dwarf_Reg( &a1, fbval.word, regs );
+                   if (!ok) return fbval; /* propagate failure */
+                   break;
++               case GXR_Value:
++                  FAIL("evaluate_Dwarf3_Expr: DW_OP_{implicit,stack}_value "
++                       "in DW_AT_frame_base");
+                default:
+                   vg_assert(0);
+             }
+@@ -599,11 +602,23 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+             a1 += sw1;
+             PUSH( a1 );
+             break;
++         case DW_OP_bregx:
++            if (!regs)
++               FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info");
++            a1 = 0;
++            uw1 = (UWord)read_leb128U( &expr );
++            if (!get_Dwarf_Reg( &a1, uw1, regs ))
++               FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_bregx reg value");
++            sw1 = (Word)read_leb128S( &expr );
++            a1 += sw1;
++            PUSH( a1 );
++            break;
+          /* As per comment on DW_OP_breg*, the following denote that
+             the value in question is in a register, not in memory.  So
+             we simply return failure. (iow, the expression is
+             malformed). */
+          case DW_OP_reg0 ... DW_OP_reg31:
++         case DW_OP_regx:
+             FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* "
+                  "whilst evaluating for a value");
+             break;
+@@ -637,6 +652,229 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+                     "address not valid for client");
+             }
+             break;
++         case DW_OP_deref_size:
++            POP(uw1);
++            uw2 = *expr++;
++            if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2,
++                                             VKI_PROT_READ )) {
++               switch (uw2) {
++                 case 1: uw1 = *(UChar*)uw1; break;
++                 case 2: uw1 = *(UShort*)uw1; break;
++                 case 4: uw1 = *(UInt*)uw1; break;
++                 case 8: uw1 = *(ULong*)uw1; break;
++                 default:
++                    FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
++                         "DW_OP_deref_size size");
++               }
++               PUSH(uw1);
++            } else {
++               FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref_size: "
++                    "address not valid for client");
++            }
++            break;
++         case DW_OP_lit0 ... DW_OP_lit31:
++            PUSH(opcode - DW_OP_lit0);
++            break;
++         case DW_OP_const1u:
++	    uw1 = *expr++;
++	    PUSH(uw1);
++            break;
++         case DW_OP_const2u:
++	    uw1 = *(UShort *)expr;
++	    expr += 2;
++	    PUSH(uw1);
++	    break;
++         case DW_OP_const4u:
++	    uw1 = *(UInt *)expr;
++	    expr += 4;
++	    PUSH(uw1);
++	    break;
++         case DW_OP_const8u:
++	    uw1 = *(ULong *)expr;
++	    expr += 8;
++	    PUSH(uw1);
++	    break;
++         case DW_OP_constu:
++            uw1 = read_leb128U( &expr );
++            PUSH(uw1);
++            break;
++         case DW_OP_const1s:
++	    uw1 = *(Char *) expr;
++	    expr++;
++	    PUSH(uw1);
++            break;
++         case DW_OP_const2s:
++	    uw1 = *(Short *)expr;
++	    expr += 2;
++	    PUSH(uw1);
++	    break;
++         case DW_OP_const4s:
++	    uw1 = *(Int *)expr;
++	    expr += 4;
++	    PUSH(uw1);
++	    break;
++         case DW_OP_const8s:
++	    uw1 = *(Long *)expr;
++	    expr += 8;
++	    PUSH(uw1);
++	    break;
++         case DW_OP_consts:
++            uw1 = read_leb128S( &expr );
++            PUSH(uw1);
++            break;
++         case DW_OP_dup:
++	    POP(uw1);
++	    PUSH(uw1);
++	    PUSH(uw1);
++	    break;
++	 case DW_OP_drop:
++	    POP(uw1);
++	    break;
++         case DW_OP_over:
++            uw1 = 1;
++            goto do_pick;
++	 case DW_OP_pick:
++	    uw1 = *expr++;
++         do_pick:
++            if (sp < (Int) uw1)
++               FAIL("evaluate_Dwarf3_Expr: stack underflow");
++            uw1 = stack[sp - uw1];
++            PUSH(uw1);
++            break;
++         case DW_OP_swap:
++            if (sp < 1)
++               FAIL("evaluate_Dwarf3_Expr: stack underflow");
++            uw1 = stack[sp];
++            stack[sp] = stack[sp - 1];
++            stack[sp - 1] = uw1;
++            break;
++         case DW_OP_rot:
++            if (sp < 2)
++               FAIL("evaluate_Dwarf3_Expr: stack underflow");
++            uw1 = stack[sp];
++            stack[sp] = stack[sp - 1];
++            stack[sp - 1] = stack[sp - 2];
++            stack[sp - 2] = uw1;
++            break;
++         case DW_OP_abs:
++            POP(sw1);
++            if (sw1 < 0)
++               sw1 = -sw1;
++            PUSH(sw1);
++            break;
++         case DW_OP_div:
++            POP(sw2);
++            if (sw2 == 0)
++               FAIL("evaluate_Dwarf3_Expr: division by zero");
++            POP(sw1);
++            sw1 /= sw2;
++            PUSH(sw1);
++            break;
++         case DW_OP_mod:
++            POP(sw2);
++            if (sw2 == 0)
++               FAIL("evaluate_Dwarf3_Expr: division by zero");
++            POP(sw1);
++            sw1 %= sw2;
++            PUSH(sw1);
++            break;
++#define BINARY(name, op, s) \
++         case DW_OP_##name:		\
++            POP(s##w2);			\
++            POP(s##w1);			\
++            s##w1 = s##w1 op s##w2;	\
++            PUSH(s##w1);		\
++            break
++#define UNARY(name, op, s) \
++         case DW_OP_##name:		\
++            POP(s##w1);			\
++            s##w1 = op s##w1;		\
++            PUSH(s##w1);		\
++            break
++         BINARY (and, &, u);
++         BINARY (minus, -, u);
++         BINARY (mul, *, u);
++         UNARY (neg, -, u);
++         UNARY (not, ~, u);
++         BINARY (or, |, u);
++         BINARY (plus, +, u);
++         BINARY (shl, <<, u);
++         BINARY (shr, >>, u);
++         BINARY (shra, >>, s);
++         BINARY (xor, ^, u);
++         BINARY (le, <=, s);
++         BINARY (lt, <, s);
++         BINARY (ge, >=, s);
++         BINARY (gt, >, s);
++         BINARY (ne, !=, u);
++         BINARY (eq, ==, u);
++#undef UNARY
++#undef BINARY
++         case DW_OP_skip:
++            sw1 = *(Short *)expr;
++            expr += 2;
++            if (sw1 < 0 && expr < limit - exprszB - sw1)
++               FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
++            expr += sw1;
++            break;
++         case DW_OP_bra:
++            sw1 = *(Short *)expr;
++            expr += 2;
++            if (sw1 < 0 && expr < limit - exprszB - sw1)
++               FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
++            POP(uw1);
++            if (uw1)
++               expr += sw1;
++            break;
++         case DW_OP_nop:
++            break;
++         case DW_OP_call_frame_cfa:
++            if (!regs)
++               FAIL("evaluate_Dwarf3_Expr: DW_OP_call_frame_cfa but no reg info");
++            uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
++            if (!uw1)
++               FAIL("evaluate_Dwarf3_Expr: Could not resolve "
++                    "DW_OP_call_frame_cfa");
++            PUSH(uw1);
++            break;
++         case DW_OP_implicit_value:
++            sw1 = (Word)read_leb128S( &expr );
++            uw1 = 0;
++            switch (sw1) {
++               case 1:
++                  uw1 = *(UChar *) expr;
++                  expr += 1;
++                  break;
++               case 2:
++                  uw1 = *(UShort *) expr;
++                  expr += 2;
++                  break;
++               case 4:
++                  uw1 = *(UInt *) expr;
++                  expr += 4;
++                  break;
++               case 8:
++                  uw1 = *(ULong *) expr;
++                  expr += 8;
++                  break;
++               default:
++                  FAIL("evaluate_Dwarf3_Expr: Unhandled "
++                       "DW_OP_implicit_value size");
++            }
++            if (expr != limit)
++               FAIL("evaluate_Dwarf3_Expr: DW_OP_implicit_value "
++                    "does not terminate expression");
++            res.word = uw1;
++            res.kind = GXR_Value;
++            return res;
++         case DW_OP_stack_value:
++            POP (uw1);
++            res.word = uw1;
++            res.kind = GXR_Value;
++            if (expr != limit)
++               FAIL("evaluate_Dwarf3_Expr: DW_OP_stack_value "
++                    "does not terminate expression");
++            break;
+          default:
+             if (!VG_(clo_xml))
+                VG_(message)(Vg_DebugMsg, 
+@@ -650,7 +888,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+ 
+    vg_assert(sp >= 0 && sp < N_EXPR_STACK);
+    res.word = stack[sp];
+-   res.kind = GXR_Value;
++   res.kind = GXR_Addr;
+    return res;
+  
+ #  undef POP
+@@ -829,12 +1067,15 @@ GXResult ML_(evaluate_trivial_GX)( GExpr
+          if (!badness)
+             badness = "trivial GExpr denotes register (2)";
+       }
+-      else {
++      else if (0) {
+          VG_(printf)(" ML_(evaluate_trivial_GX): unhandled:\n   ");
+          ML_(pp_GX)( gx );
+          VG_(printf)("\n");
+          tl_assert(0);
+       }
++      else
++         if (!badness)
++            badness = "non-trivial GExpr";
+ 
+       VG_(addToXA)( results, &thisResult );
+ 
+@@ -884,7 +1125,7 @@ GXResult ML_(evaluate_trivial_GX)( GExpr
+ 
+    /* Well, we have success.  All subexpressions evaluated, and 
+       they all agree.  Hurrah. */
+-   res.kind = GXR_Value;
++   res.kind = GXR_Addr;
+    res.word = (UWord)mul->ul; /* NB: narrowing from ULong */
+    VG_(deleteXA)( results );
+    return res;
+@@ -896,6 +1137,8 @@ void ML_(pp_GXResult) ( GXResult res )
+    switch (res.kind) {
+       case GXR_Failure:
+          VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break;
++      case GXR_Addr:
++         VG_(printf)("GXR_Addr(0x%lx)", res.word); break;
+       case GXR_Value:
+          VG_(printf)("GXR_Value(0x%lx)", res.word); break;
+       case GXR_RegNo:
+--- valgrind/coregrind/m_debuginfo/debuginfo.c.jj	2009-10-21 10:49:47.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/debuginfo.c	2009-10-21 10:49:47.000000000 +0200
+@@ -2003,6 +2003,62 @@ static void cfsi_cache__invalidate ( voi
+ }
+ 
+ 
++Addr ML_(get_CFA) (Addr ip, Addr sp, Addr fp,
++                   Addr min_accessible, Addr max_accessible )
++{
++   Bool       ok;
++   DebugInfo* di;
++   DiCfSI*    cfsi = NULL;
++   Addr       cfa;
++   CfiExprEvalContext eec;
++   UWord hash = ip % N_CFSI_CACHE;
++   CFSICacheEnt* ce = &cfsi_cache[hash];
++
++   if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
++      /* found an entry in the cache .. */
++   } else {
++      /* not found in cache.  Search and update. */
++      ce->ip = ip;
++      find_DiCfSI( &ce->di, &ce->ix, ip );
++   }
++
++   if (UNLIKELY(ce->di == (DebugInfo*)1)) {
++      /* no DiCfSI for this address */
++      return 0;
++   } else {
++      /* found a DiCfSI for this address */
++      di = ce->di;
++      cfsi = &di->cfsi[ ce->ix ];
++   }
++
++   if (UNLIKELY(cfsi == NULL))
++      return 0; /* no info.  Nothing we can do. */
++
++   /* Compute the CFA. */
++   cfa = 0;
++   switch (cfsi->cfa_how) {
++      case CFIC_SPREL: 
++         cfa = cfsi->cfa_off + sp;
++         break;
++      case CFIC_FPREL: 
++         cfa = cfsi->cfa_off + fp;
++         break;
++      case CFIC_EXPR: 
++         eec.ipHere = ip;
++         eec.spHere = sp;
++         eec.fpHere = fp;
++         eec.min_accessible = min_accessible;
++         eec.max_accessible = max_accessible;
++         ok = True;
++         cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok );
++         if (!ok) return 0;
++         break;
++      default: 
++         vg_assert(0);
++   }
++   return cfa;
++}
++
+ /* The main function for DWARF2/3 CFI-based stack unwinding.
+    Given an IP/SP/FP triple, produce the IP/SP/FP values for the
+    previous frame, if possible. */
+@@ -2346,7 +2402,7 @@ static Bool data_address_is_in_var ( /*O
+       VG_(printf)("\n");
+    }
+ 
+-   if (res.kind == GXR_Value 
++   if (res.kind == GXR_Addr 
+        && res.word <= data_addr
+        && data_addr < res.word + var_szB) {
+       *offset = data_addr - res.word;
+@@ -3057,7 +3113,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
+    vg_assert(res_sp_6k.kind == res_fp_6k.kind);
+    vg_assert(res_sp_6k.kind == res_fp_7k.kind);
+ 
+-   if (res_sp_6k.kind == GXR_Value) {
++   if (res_sp_6k.kind == GXR_Addr) {
+       StackBlock block;
+       GXResult res;
+       UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
+@@ -3074,7 +3130,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
+          regs.sp = regs.fp = 0;
+          regs.ip = ip;
+          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
+-         tl_assert(res.kind == GXR_Value);
++         tl_assert(res.kind == GXR_Addr);
+          if (debug)
+          VG_(printf)("   %5ld .. %5ld (sp) %s\n",
+                      res.word, res.word + ((UWord)mul.ul) - 1, var->name);
+@@ -3093,7 +3149,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
+          regs.sp = regs.fp = 0;
+          regs.ip = ip;
+          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
+-         tl_assert(res.kind == GXR_Value);
++         tl_assert(res.kind == GXR_Addr);
+          if (debug)
+          VG_(printf)("   %5ld .. %5ld (FP) %s\n",
+                      res.word, res.word + ((UWord)mul.ul) - 1, var->name);
+@@ -3308,7 +3364,7 @@ void* /* really, XArray* of GlobalBlock 
+             res = ML_(evaluate_trivial_GX)( var->gexpr, di );
+ 
+             /* Not a constant address => not interesting */
+-            if (res.kind != GXR_Value) {
++            if (res.kind != GXR_Addr) {
+                if (0) VG_(printf)("FAIL\n");
+                continue;
+             }
+--- valgrind/coregrind/m_debuginfo/tytypes.c.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/tytypes.c	2009-10-21 10:49:47.000000000 +0200
+@@ -766,7 +766,7 @@ XArray* /*UChar*/ ML_(describe_type)( /*
+                   ML_(pp_GXResult)(res);
+                   VG_(printf)("\n");
+                }
+-               if (res.kind != GXR_Value)
++               if (res.kind != GXR_Addr)
+                   continue;
+                mul = ML_(sizeOfType)( tyents, field->Te.Field.typeR );
+                if (mul.b != True)
diff --git a/valgrind-3.5.0-dwarf4.patch b/valgrind-3.5.0-dwarf4.patch
new file mode 100644
index 0000000..f82c626
--- /dev/null
+++ b/valgrind-3.5.0-dwarf4.patch
@@ -0,0 +1,537 @@
+--- valgrind/coregrind/m_debuginfo/readdwarf.c.jj	2010-04-07 11:10:52.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/readdwarf.c	2010-04-07 12:34:56.000000000 +0200
+@@ -1,6 +1,6 @@
+ 
+ /*--------------------------------------------------------------------*/
+-/*--- Read DWARF1/2/3 debug info.                      readdwarf.c ---*/
++/*--- Read DWARF1/2/3/4 debug info.                    readdwarf.c ---*/
+ /*--------------------------------------------------------------------*/
+ 
+ /*
+@@ -139,6 +139,7 @@ typedef struct
+   UShort li_version;
+   ULong  li_header_length;
+   UChar  li_min_insn_length;
++  UChar  li_max_ops_per_insn;
+   UChar  li_default_is_stmt;
+   Int    li_line_base;
+   UChar  li_line_range;
+@@ -182,7 +183,8 @@ enum dwarf_line_number_x_ops
+   {
+     DW_LNE_end_sequence = 1,
+     DW_LNE_set_address = 2,
+-    DW_LNE_define_file = 3
++    DW_LNE_define_file = 3,
++    DW_LNE_set_discriminator = 4
+   };
+ 
+ typedef struct
+@@ -199,7 +201,8 @@ typedef struct
+   UInt  column;
+   Int   is_stmt;
+   Int   basic_block;
+-  Int   end_sequence;
++  UChar end_sequence;
++  UChar op_index;
+ } LineSMR;
+ 
+ 
+@@ -302,6 +305,7 @@ void reset_state_machine ( Int is_stmt )
+    state_machine_regs.is_stmt = is_stmt;
+    state_machine_regs.basic_block = 0;
+    state_machine_regs.end_sequence = 0;
++   state_machine_regs.op_index = 0;
+ }
+ 
+ /* Look up a directory name, or return NULL if unknown. */
+@@ -393,6 +397,7 @@ Word process_extended_line_op( struct _D
+       case DW_LNE_set_address:
+          adr = *((Addr *)data);
+          state_machine_regs.address = adr;
++         state_machine_regs.op_index = 0;
+          if (di->ddump_line)
+             VG_(printf)("  Extended opcode %d: set Address to 0x%lx\n",
+                         (Int)op_code, (Addr)adr);
+@@ -411,6 +416,11 @@ Word process_extended_line_op( struct _D
+             VG_(printf)("  DWARF2-line: set_address\n");
+          break;
+ 
++      case DW_LNE_set_discriminator:
++         read_leb128 (data, & bytes_read, 0);
++         data += bytes_read;
++         break;
++
+       default:
+          if (di->ddump_line)
+             VG_(printf)("process_extended_line_op:default\n");
+@@ -513,9 +523,9 @@ void read_dwarf2_lineblock ( struct _Deb
+       VG_(printf)("  DWARF Version:               %d\n", 
+                   (Int)info.li_version);
+ 
+-   if (info.li_version != 2 && info.li_version != 3) {
++   if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4) {
+       ML_(symerr)(di, True,
+-                  "Only DWARF version 2 and 3 line info "
++                  "Only DWARF version 2, 3 and 4 line info "
+                   "is currently supported.");
+       goto out;
+    }
+@@ -533,6 +543,20 @@ void read_dwarf2_lineblock ( struct _Deb
+       VG_(printf)("  Minimum Instruction Length:  %d\n", 
+                   (Int)info.li_min_insn_length);
+ 
++   if (info.li_version >= 4) {
++      info.li_max_ops_per_insn = * ((UChar *)external);
++      if (info.li_max_ops_per_insn == 0) {
++         ML_(symerr)(di, True,
++                     "Invalid Maximum Ops Per Insn in line info.");
++         goto out;
++      }
++      external += 1;
++      if (di->ddump_line)
++         VG_(printf)("  Maximum Ops Per Insn:        %d\n", 
++                  (Int)info.li_max_ops_per_insn);
++   } else
++      info.li_max_ops_per_insn = 1;
++
+    info.li_default_is_stmt = * ((UChar *)external);
+    external += 1;
+    if (di->ddump_line)
+@@ -714,10 +738,18 @@ void read_dwarf2_lineblock ( struct _Deb
+ 
+          Int advAddr;
+          op_code -= info.li_opcode_base;
+-         adv      = (op_code / info.li_line_range) 
+-                       * info.li_min_insn_length;
+-         advAddr = adv;
+-         state_machine_regs.address += adv;
++         adv      = (op_code / info.li_line_range);
++         if (info.li_max_ops_per_insn == 1) {
++            adv *= info.li_min_insn_length;
++            advAddr = adv;
++            state_machine_regs.address += adv;
++         } else {
++            advAddr = ((state_machine_regs.op_index + adv)
++                       / info.li_max_ops_per_insn) * info.li_min_insn_length;
++            state_machine_regs.address += advAddr;
++            state_machine_regs.op_index = (state_machine_regs.op_index + adv)
++                                          % info.li_max_ops_per_insn;
++         }
+ 
+          if (0) VG_(printf)("smr.a += %#x\n", adv );
+          adv = (op_code % info.li_line_range) + info.li_line_base;
+@@ -800,10 +832,19 @@ void read_dwarf2_lineblock ( struct _Deb
+             break;
+ 
+          case DW_LNS_advance_pc:
+-            adv = info.li_min_insn_length 
+-                     * read_leb128 (data, & bytes_read, 0);
++            adv = read_leb128 (data, & bytes_read, 0);
+             data += bytes_read;
+-            state_machine_regs.address += adv;
++            if (info.li_max_ops_per_insn == 1) {
++               adv *= info.li_min_insn_length;
++               state_machine_regs.address += adv;
++            } else {
++               state_machine_regs.address
++                 += ((state_machine_regs.op_index + adv)
++                     / info.li_max_ops_per_insn) * info.li_min_insn_length;
++               state_machine_regs.op_index
++                 = (state_machine_regs.op_index + adv)
++                   % info.li_max_ops_per_insn;
++            }
+             if (0) VG_(printf)("smr.a += %#x\n", adv );
+             if (di->ddump_line)
+                VG_(printf)("  Advance PC by %d to 0x%lx\n", 
+@@ -851,9 +892,18 @@ void read_dwarf2_lineblock ( struct _Deb
+             break;
+ 
+          case DW_LNS_const_add_pc:
+-            adv = (((255 - info.li_opcode_base) / info.li_line_range)
+-                   * info.li_min_insn_length);
+-            state_machine_regs.address += adv;
++            adv = ((255 - info.li_opcode_base) / info.li_line_range);
++            if (info.li_max_ops_per_insn == 1) {
++               adv *= info.li_min_insn_length;
++               state_machine_regs.address += adv;
++            } else {
++               state_machine_regs.address
++                 += ((state_machine_regs.op_index + adv)
++                     / info.li_max_ops_per_insn) * info.li_min_insn_length;
++               state_machine_regs.op_index
++                 = (state_machine_regs.op_index + adv)
++                   % info.li_max_ops_per_insn;
++            }
+             if (0) VG_(printf)("smr.a += %#x\n", adv );
+             if (di->ddump_line)
+                VG_(printf)("  Advance PC by constant %d to 0x%lx\n", 
+@@ -865,6 +915,7 @@ void read_dwarf2_lineblock ( struct _Deb
+             adv = *((UShort *)data);
+             data += 2;
+             state_machine_regs.address += adv;
++            state_machine_regs.op_index = 0;
+             if (0) VG_(printf)("smr.a += %#x\n", adv );
+             if (di->ddump_line)
+                VG_(printf)("  DWARF2-line: fixed_advance_pc\n");
+@@ -979,7 +1030,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn
+    blklen = read_initial_length_field( p, &ui->dw64 );
+    p += ui->dw64 ? 12 : 4;
+ 
+-   /* version should be 2 */
++   /* version should be 2, 3 or 4 */
+    ver = *((UShort*)p);
+    p += 2;
+ 
+@@ -1066,7 +1117,11 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn
+             case 0x08: /* FORM_string */    sval = (Char*)p; 
+                                             p += VG_(strlen)((Char*)p) + 1; break;
+             case 0x0b: /* FORM_data1 */     cval = *p; p++; break;
+-            
++            case 0x17: /* FORM_sec_offset */if (ui->dw64) {
++                                               cval = *((ULong*)p); p += 8; break;
++                                            }
++                                            cval = *((UInt*)p); p += 4; break;
++
+             /* TODO : Following ones just skip data - implement if you need */
+             case 0x01: /* FORM_addr */      p += addr_size; break;
+             case 0x03: /* FORM_block2 */    p += *((UShort*)p) + 2; break;
+@@ -1085,7 +1140,10 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn
+             case 0x13: /* FORM_ref4 */      p += 4; break;
+             case 0x14: /* FORM_ref8 */      p += 8; break;
+             case 0x15: /* FORM_ref_udata */ read_leb128U( &p ); break;
+-            
++            case 0x18: /* FORM_exprloc */   p += read_leb128U( &p ); break;
++            case 0x19: /* FORM_flag_present */break;
++            case 0x20: /* FORM_ref_sig8 */  p += 8; break;
++
+             default:
+                VG_(printf)( "### unhandled dwarf2 abbrev form code 0x%x\n", form );
+                break;
+@@ -1163,9 +1221,9 @@ void ML_(read_debuginfo_dwarf3)
+ 
+       /* version should be 2 */
+       ver = *((UShort*)( block_img + blklen_len ));
+-      if ( ver != 2 && ver != 3 ) {
++      if ( ver != 2 && ver != 3 && ver != 4 ) {
+          ML_(symerr)( di, True,
+-                      "Ignoring non-Dwarf2/3 block in .debug_info" );
++                      "Ignoring non-Dwarf2/3/4 block in .debug_info" );
+          continue;
+       }
+       
+@@ -3705,8 +3763,8 @@ void ML_(read_callframe_info_dwarf3)
+             VG_(printf)("cie.version     = %d\n", (Int)cie_version);
+          if (di->ddump_frames)
+             VG_(printf)("  Version:               %d\n", (Int)cie_version);
+-         if (cie_version != 1 && cie_version != 3) {
+-            how = "unexpected CIE version (not 1 nor 3)";
++         if (cie_version != 1 && cie_version != 3 && cie_version != 4) {
++            how = "unexpected CIE version (not 1 nor 3 nor 4)";
+             goto bad;
+          }
+ 
+@@ -3722,6 +3780,19 @@ void ML_(read_callframe_info_dwarf3)
+             cie_augmentation += 2;
+          }
+ 
++         if (cie_version >= 4) {
++            if (read_UChar(data) != sizeof(Addr)) {
++               how = "unexpected address size";
++               goto bad;
++            }
++            data += sizeof(UChar);
++            if (read_UChar(data) != 0) {
++               how = "unexpected non-zero segment size";
++               goto bad;
++            }
++            data += sizeof(UChar);
++         }
++
+          the_CIEs[this_CIE].code_a_f = read_leb128( data, &nbytes, 0);
+          data += nbytes;
+          if (di->trace_cfi) 
+--- valgrind/coregrind/m_debuginfo/readdwarf3.c.jj	2010-04-07 11:10:52.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/readdwarf3.c	2010-04-07 12:48:07.000000000 +0200
+@@ -1,6 +1,6 @@
+ 
+ /*--------------------------------------------------------------------*/
+-/*--- Read DWARF3 ".debug_info" sections (DIE trees).              ---*/
++/*--- Read DWARF3/4 ".debug_info" sections (DIE trees).            ---*/
+ /*---                                                 readdwarf3.c ---*/
+ /*--------------------------------------------------------------------*/
+ 
+@@ -387,7 +387,7 @@ typedef
+       void (*barf)( HChar* ) __attribute__((noreturn));
+       /* Is this 64-bit DWARF ? */
+       Bool   is_dw64;
+-      /* Which DWARF version ?  (2 or 3) */
++      /* Which DWARF version ?  (2, 3 or 4) */
+       UShort version;
+       /* Length of this Compilation Unit, as stated in the
+          .unit_length :: InitialLength field of the CU Header.
+@@ -805,8 +805,8 @@ void parse_CU_Header ( /*OUT*/CUConst* c
+ 
+    /* version */
+    cc->version = get_UShort( c );
+-   if (cc->version != 2 && cc->version != 3)
+-      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3" );
++   if (cc->version != 2 && cc->version != 3 && cc->version != 4)
++      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
+    TRACE_D3("   Version:       %d\n", (Int)cc->version );
+ 
+    /* debug_abbrev_offset */
+@@ -984,11 +984,21 @@ void get_Form_contents ( /*OUT*/ULong* c
+          *ctsSzB = 8;
+          TRACE_D3("%llu", *cts);
+          break;
++      case DW_FORM_sec_offset:
++         *cts = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
++         *ctsSzB = cc->is_dw64 ? 8 : 4;
++         TRACE_D3("%llu", *cts);
++         break;
+       case DW_FORM_sdata:
+          *cts = (ULong)(Long)get_SLEB128(c);
+          *ctsSzB = 8;
+          TRACE_D3("%lld", (Long)*cts);
+          break;
++      case DW_FORM_udata:
++         *cts = (ULong)(Long)get_ULEB128(c);
++         *ctsSzB = 8;
++         TRACE_D3("%llu", (Long)*cts);
++         break;
+       case DW_FORM_addr:
+          /* note, this is a hack.  DW_FORM_addr is defined as getting
+             a word the size of the target machine as defined by the
+@@ -1055,6 +1065,22 @@ void get_Form_contents ( /*OUT*/ULong* c
+          *ctsMemSzB = 1 + (ULong)VG_(strlen)(str);
+          break;
+       }
++      case DW_FORM_ref1: {
++         UChar  u8 = get_UChar(c);
++         UWord res = cc->cu_start_offset + (UWord)u8;
++         *cts = (ULong)res;
++         *ctsSzB = sizeof(UWord);
++         TRACE_D3("<%lx>", res);
++         break;
++      }
++      case DW_FORM_ref2: {
++         UShort  u16 = get_UShort(c);
++         UWord res = cc->cu_start_offset + (UWord)u16;
++         *cts = (ULong)res;
++         *ctsSzB = sizeof(UWord);
++         TRACE_D3("<%lx>", res);
++         break;
++      }
+       case DW_FORM_ref4: {
+          UInt  u32 = get_UInt(c);
+          UWord res = cc->cu_start_offset + (UWord)u32;
+@@ -1063,6 +1089,22 @@ void get_Form_contents ( /*OUT*/ULong* c
+          TRACE_D3("<%lx>", res);
+          break;
+       }
++      case DW_FORM_ref8: {
++         ULong  u64 = get_ULong(c);
++         UWord res = cc->cu_start_offset + (UWord)u64;
++         *cts = (ULong)res;
++         *ctsSzB = sizeof(UWord);
++         TRACE_D3("<%lx>", res);
++         break;
++      }
++      case DW_FORM_ref_udata: {
++         ULong  u64 = get_ULEB128(c);
++         UWord res = cc->cu_start_offset + (UWord)u64;
++         *cts = (ULong)res;
++         *ctsSzB = sizeof(UWord);
++         TRACE_D3("<%lx>", res);
++         break;
++      }
+       case DW_FORM_flag: {
+          UChar u8 = get_UChar(c);
+          TRACE_D3("%u", (UInt)u8);
+@@ -1070,6 +1112,11 @@ void get_Form_contents ( /*OUT*/ULong* c
+          *ctsSzB = 1;
+          break;
+       }
++      case DW_FORM_flag_present:
++         TRACE_D3("1");
++         *cts = 1;
++         *ctsSzB = 1;
++         break;
+       case DW_FORM_block1: {
+          ULong  u64b;
+          ULong  u64 = (ULong)get_UChar(c);
+@@ -1096,6 +1143,50 @@ void get_Form_contents ( /*OUT*/ULong* c
+          *ctsMemSzB = (UWord)u64;
+          break;
+       }
++      case DW_FORM_block4: {
++         ULong  u64b;
++         ULong  u64 = (ULong)get_UInt(c);
++         UChar* block = get_address_of_Cursor(c);
++         TRACE_D3("%llu byte block: ", u64);
++         for (u64b = u64; u64b > 0; u64b--) {
++            UChar u8 = get_UChar(c);
++            TRACE_D3("%x ", (UInt)u8);
++         }
++         *cts = (ULong)(UWord)block;
++         *ctsMemSzB = (UWord)u64;
++         break;
++      }
++      case DW_FORM_exprloc:
++      case DW_FORM_block: {
++         ULong  u64b;
++         ULong  u64 = (ULong)get_ULEB128(c);
++         UChar* block = get_address_of_Cursor(c);
++         TRACE_D3("%llu byte block: ", u64);
++         for (u64b = u64; u64b > 0; u64b--) {
++            UChar u8 = get_UChar(c);
++            TRACE_D3("%x ", (UInt)u8);
++         }
++         *cts = (ULong)(UWord)block;
++         *ctsMemSzB = (UWord)u64;
++         break;
++      }
++      case DW_FORM_ref_sig8: {
++         ULong  u64b;
++         UChar* block = get_address_of_Cursor(c);
++         TRACE_D3("8 byte signature: ");
++         for (u64b = 8; u64b > 0; u64b--) {
++            UChar u8 = get_UChar(c);
++            TRACE_D3("%x ", (UInt)u8);
++         }
++         *cts = (ULong)(UWord)block;
++         *ctsMemSzB = 8;
++         break;
++      }
++      case DW_FORM_indirect:
++         get_Form_contents (cts, ctsSzB, ctsMemSzB, cc, c, td3,
++                            (DW_FORM)get_ULEB128(c));
++         return;
++
+       default:
+          VG_(printf)(
+             "get_Form_contents: unhandled %d (%s) at <%lx>\n",
+@@ -1322,11 +1413,13 @@ void read_filename_table( /*MOD*/D3VarPa
+       get_Initial_Length( &is_dw64, &c,
+            "read_filename_table: invalid initial-length field" );
+    version = get_UShort( &c );
+-   if (version != 2 && version != 3)
+-     cc->barf("read_filename_table: Only DWARF version 2 and 3 line info "
++   if (version != 2 && version != 3 && version != 4)
++     cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
+               "is currently supported.");
+    /*header_length              = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
+    /*minimum_instruction_length = */ get_UChar( &c );
++   if (version >= 4)
++      /*maximum_operations_per_insn = */ get_UChar( &c );
+    /*default_is_stmt            = */ get_UChar( &c );
+    /*line_base                  = (Char)*/ get_UChar( &c );
+    /*line_range                 = */ get_UChar( &c );
+@@ -2025,7 +2118,7 @@ static void parse_type_DIE ( /*MOD*/XArr
+             case DW_LANG_C89: case DW_LANG_C:
+             case DW_LANG_C_plus_plus: case DW_LANG_ObjC:
+             case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC:
+-            case DW_LANG_Upc:
++            case DW_LANG_Upc: case DW_LANG_C99:
+                parser->language = 'C'; break;
+             case DW_LANG_Fortran77: case DW_LANG_Fortran90:
+             case DW_LANG_Fortran95:
+@@ -2033,8 +2126,8 @@ static void parse_type_DIE ( /*MOD*/XArr
+             case DW_LANG_Ada83: case DW_LANG_Cobol74:
+             case DW_LANG_Cobol85: case DW_LANG_Pascal83:
+             case DW_LANG_Modula2: case DW_LANG_Java:
+-            case DW_LANG_C99: case DW_LANG_Ada95:
+-            case DW_LANG_PLI: case DW_LANG_D:
++            case DW_LANG_Ada95: case DW_LANG_PLI:
++            case DW_LANG_D: case DW_LANG_Python:
+             case DW_LANG_Mips_Assembler:
+                parser->language = '?'; break;
+             default:
+--- valgrind/coregrind/m_debuginfo/priv_d3basics.h.jj	2010-04-07 11:10:52.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/priv_d3basics.h	2010-04-07 11:50:45.000000000 +0200
+@@ -104,6 +104,10 @@ typedef enum 
+     DW_TAG_imported_unit = 0x3d,
+     DW_TAG_condition = 0x3f,
+     DW_TAG_shared_type = 0x40,
++    /* DWARF 4.  */
++    DW_TAG_type_unit = 0x41,
++    DW_TAG_rvalue_reference_type = 0x42,
++    DW_TAG_template_alias = 0x43,
+     /* SGI/MIPS Extensions.  */
+     DW_TAG_MIPS_loop = 0x4081,
+     /* HP extensions.  See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .  */
+@@ -158,6 +162,8 @@ typedef enum dwarf_source_language
+     DW_LANG_ObjC_plus_plus = 0x0011,
+     DW_LANG_UPC = 0x0012,
+     DW_LANG_D = 0x0013,
++    /* DWARF 4.  */
++    DW_LANG_Python = 0x0014,
+     /* MIPS.  */
+     DW_LANG_Mips_Assembler = 0x8001,
+     /* UPC.  */
+@@ -188,7 +194,12 @@ typedef enum
+     DW_FORM_ref4 = 0x13,
+     DW_FORM_ref8 = 0x14,
+     DW_FORM_ref_udata = 0x15,
+-    DW_FORM_indirect = 0x16
++    DW_FORM_indirect = 0x16,
++    /* DWARF 4 values.  */
++    DW_FORM_sec_offset = 0x17,
++    DW_FORM_exprloc = 0x18,
++    DW_FORM_flag_present = 0x19,
++    DW_FORM_ref_sig8 = 0x20
+   }
+   DW_FORM;
+ 
+@@ -285,6 +296,13 @@ typedef enum
+     DW_AT_elemental     = 0x66,
+     DW_AT_pure          = 0x67,
+     DW_AT_recursive     = 0x68,
++    /* DWARF 4 values.  */
++    DW_AT_signature       = 0x69,
++    DW_AT_main_subprogram = 0x6a,
++    DW_AT_data_bit_offset = 0x6b,
++    DW_AT_const_expr      = 0x6c,
++    DW_AT_enum_class      = 0x6d,
++    DW_AT_linkage_name    = 0x6e,
+     /* SGI/MIPS extensions.  */
+     DW_AT_MIPS_fde = 0x2001,
+     DW_AT_MIPS_loop_begin = 0x2002,
+--- valgrind/coregrind/m_debuginfo/d3basics.c.jj	2010-04-07 11:10:52.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/d3basics.c	2010-04-07 11:50:45.000000000 +0200
+@@ -124,6 +124,10 @@ HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
+       case DW_TAG_imported_unit:      return "DW_TAG_imported_unit";
+       case DW_TAG_condition:          return "DW_TAG_condition";
+       case DW_TAG_shared_type:        return "DW_TAG_shared_type";
++      /* DWARF 4.  */
++      case DW_TAG_type_unit:          return "DW_TAG_type_unit";
++      case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
++      case DW_TAG_template_alias:     return "DW_TAG_template_alias";
+       /* SGI/MIPS Extensions.  */
+       case DW_TAG_MIPS_loop:          return "DW_TAG_MIPS_loop";
+       /* HP extensions.  See:
+@@ -172,6 +176,10 @@ HChar* ML_(pp_DW_FORM) ( DW_FORM form )
+       case DW_FORM_ref8:      return "DW_FORM_ref8";
+       case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
+       case DW_FORM_indirect:  return "DW_FORM_indirect";
++      case DW_FORM_sec_offset:return "DW_FORM_sec_offset";
++      case DW_FORM_exprloc:   return "DW_FORM_exprloc";
++      case DW_FORM_flag_present:return "DW_FORM_flag_present";
++      case DW_FORM_ref_sig8:  return "DW_FORM_ref_sig8";
+       default:                return "DW_FORM_???";
+    }
+ }
+@@ -269,6 +277,13 @@ HChar* ML_(pp_DW_AT) ( DW_AT attr )
+       case DW_AT_elemental: return "DW_AT_elemental";
+       case DW_AT_pure: return "DW_AT_pure";
+       case DW_AT_recursive: return "DW_AT_recursive";
++      /* DWARF 4 values.  */
++      case DW_AT_signature: return "DW_AT_signature";
++      case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
++      case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
++      case DW_AT_const_expr: return "DW_AT_const_expr";
++      case DW_AT_enum_class: return "DW_AT_enum_class";
++      case DW_AT_linkage_name: return "DW_AT_linkage_name";
+       /* SGI/MIPS extensions.  */
+       /* case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; */
+       /* DW_AT_MIPS_fde == DW_AT_HP_unmodifiable */
diff --git a/valgrind-3.5.0-dynbss.patch b/valgrind-3.5.0-dynbss.patch
new file mode 100644
index 0000000..a93c28f
--- /dev/null
+++ b/valgrind-3.5.0-dynbss.patch
@@ -0,0 +1,93 @@
+--- valgrind-3.5.0/coregrind/m_debuginfo/readelf.c.jj	2009-12-02 05:38:20.000000000 -0500
++++ valgrind-3.5.0/coregrind/m_debuginfo/readelf.c	2009-12-02 06:50:44.061404000 -0500
+@@ -1062,6 +1062,8 @@ Bool ML_(read_elf_debug_info) ( struct _
+    Bool          res, ok;
+    SysRes        fd, sres;
+    Word          i;
++   Bool          dynbss_present = False;
++   Bool          sdynbss_present = False;
+ 
+    /* Image addresses for the ELF file we're working with. */
+    Addr          oimage   = 0;
+@@ -1476,8 +1478,40 @@ Bool ML_(read_elf_debug_info) ( struct _
+          }
+       }
+ 
++      if (0 == VG_(strcmp)(name, ".dynbss")) {
++         if (inrw && size > 0 && !di->bss_present) {
++            dynbss_present = True;
++            di->bss_present = True;
++            di->bss_svma = svma;
++            di->bss_avma = svma + rw_bias;
++            di->bss_size = size;
++            di->bss_bias = rw_bias;
++            di->bss_debug_svma = svma;
++            di->bss_debug_bias = rw_bias;
++            TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n",
++                         di->bss_svma,
++                         di->bss_svma + di->bss_size - 1);
++            TRACE_SYMTAB("acquiring .dynbss avma = %#lx .. %#lx\n",
++                         di->bss_avma,
++                         di->bss_avma + di->bss_size - 1);
++            TRACE_SYMTAB("acquiring .dynbss bias = %#lx\n", di->bss_bias);
++         }
++      }
++
+       /* Accept .bss where mapped as rw (data), even if zero-sized */
+       if (0 == VG_(strcmp)(name, ".bss")) {
++         if (inrw && size > 0 && dynbss_present) {
++            vg_assert(di->bss_present);
++            dynbss_present = False;
++            vg_assert(di->bss_svma + di->bss_size == svma);
++            di->bss_size += size;
++            TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
++                         svma, svma + size - 1);
++            TRACE_SYMTAB("acquiring .bss avma = %#lx .. %#lx\n",
++                         svma + rw_bias, svma + rw_bias + size - 1);
++            TRACE_SYMTAB("acquiring .bss bias = %#lx\n", di->bss_bias);
++         } else
++
+          if (inrw && size >= 0 && !di->bss_present) {
+             di->bss_present = True;
+             di->bss_svma = svma;
+@@ -1529,8 +1563,40 @@ Bool ML_(read_elf_debug_info) ( struct _
+          }
+       }
+ 
++      if (0 == VG_(strcmp)(name, ".sdynbss")) {
++         if (inrw && size >= 0 && !di->sbss_present) {
++            sdynbss_present = True;
++            di->sbss_present = True;
++            di->sbss_svma = svma;
++            di->sbss_avma = svma + rw_bias;
++            di->sbss_size = size;
++            di->sbss_bias = rw_bias;
++            di->sbss_debug_svma = svma;
++            di->sbss_debug_bias = rw_bias;
++            TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n",
++                         di->sbss_svma,
++                         di->sbss_svma + di->sbss_size - 1);
++            TRACE_SYMTAB("acquiring .sdynbss avma = %#lx .. %#lx\n",
++                         di->sbss_avma,
++                         di->sbss_avma + di->sbss_size - 1);
++            TRACE_SYMTAB("acquiring .sdynbss bias = %#lx\n", di->sbss_bias);
++         }
++      }
++
+       /* Accept .sbss where mapped as rw (data) */
+       if (0 == VG_(strcmp)(name, ".sbss")) {
++         if (inrw && size > 0 && sdynbss_present) {
++            vg_assert(di->sbss_present);
++            sdynbss_present = False;
++            vg_assert(di->sbss_svma + di->sbss_size == svma);
++            di->sbss_size += size;
++            TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
++                         svma, svma + size - 1);
++            TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n",
++                         svma + rw_bias, svma + rw_bias + size - 1);
++            TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias);
++         } else
++
+          if (inrw && size > 0 && !di->sbss_present) {
+             di->sbss_present = True;
+             di->sbss_svma = svma;
diff --git a/valgrind-3.5.0-glibc-2.11.patch b/valgrind-3.5.0-glibc-2.11.patch
new file mode 100644
index 0000000..6f4a219
--- /dev/null
+++ b/valgrind-3.5.0-glibc-2.11.patch
@@ -0,0 +1,115 @@
+--- valgrind/configure.in.jj	2009-08-19 15:37:48.000000000 +0200
++++ valgrind/configure.in	2009-11-04 08:37:09.820077680 +0100
+@@ -656,6 +656,16 @@ AC_EGREP_CPP([GLIBC_210], [
+ ],
+ GLIBC_VERSION="2.10")
+ 
++AC_EGREP_CPP([GLIBC_211], [
++#include <features.h>
++#ifdef __GNU_LIBRARY__
++ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 11)
++  GLIBC_211
++ #endif
++#endif
++],
++GLIBC_VERSION="2.11")
++
+ AC_EGREP_CPP([AIX5_LIBC], [
+ #include <standards.h>
+ #if defined(_AIXVERSION_510) || defined(_AIXVERSION_520) || defined(_AIXVERSION_530)
+@@ -742,6 +752,13 @@ case "${GLIBC_VERSION}" in
+ 	DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ 	DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ 	;;
++     2.11)
++	AC_MSG_RESULT(2.11 family)
++	AC_DEFINE([GLIBC_2_11], 1, [Define to 1 if you're using glibc 2.11.x])
++	DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
++	DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
++	DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
++	;;
+      aix5)
+ 	AC_MSG_RESULT(AIX 5.1 or 5.2 or 5.3)
+ 	AC_DEFINE([AIX5_LIBC], 1, [Define to 1 if you're using AIX 5.1 or 5.2 or 5.3])
+@@ -755,7 +772,7 @@ case "${GLIBC_VERSION}" in
+ 
+      *)
+ 	AC_MSG_RESULT(unsupported version)
+-	AC_MSG_ERROR([Valgrind requires glibc version 2.2 - 2.10])
++	AC_MSG_ERROR([Valgrind requires glibc version 2.2 - 2.11])
+ 	AC_MSG_ERROR([or AIX 5.1 or 5.2 or 5.3 GLIBC_VERSION])
+ 	AC_MSG_ERROR([or Darwin libc])
+ 	;;
+--- valgrind/config.h.in.jj	2009-08-19 15:39:05.000000000 +0200
++++ valgrind/config.h.in	2009-11-04 08:38:36.051072661 +0100
+@@ -15,6 +15,9 @@
+ /* Define to 1 if you're using glibc 2.10.x */
+ #undef GLIBC_2_10
+ 
++/* Define to 1 if you're using glibc 2.11.x */
++#undef GLIBC_2_11
++
+ /* Define to 1 if you're using glibc 2.2.x */
+ #undef GLIBC_2_2
+ 
+--- valgrind/configure.jj	2009-08-19 15:44:07.000000000 +0200
++++ valgrind/configure	2009-11-04 08:38:08.421433252 +0100
+@@ -5025,6 +5025,28 @@ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ 
++#include <features.h>
++#ifdef __GNU_LIBRARY__
++ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 11)
++  GLIBC_211
++ #endif
++#endif
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "GLIBC_211" >/dev/null 2>&1; then
++  GLIBC_VERSION="2.11"
++fi
++rm -f conftest*
++
++
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++
+ #include <standards.h>
+ #if defined(_AIXVERSION_510) || defined(_AIXVERSION_520) || defined(_AIXVERSION_530)
+   AIX5_LIBC
+@@ -5174,6 +5196,18 @@ _ACEOF
+ 	DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ 	DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ 	;;
++     2.11)
++	echo "$as_me:$LINENO: result: 2.11 family" >&5
++echo "${ECHO_T}2.11 family" >&6
++
++cat >>confdefs.h <<\_ACEOF
++#define GLIBC_2_11 1
++_ACEOF
++
++	DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
++	DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
++	DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
++	;;
+      aix5)
+ 	echo "$as_me:$LINENO: result: AIX 5.1 or 5.2 or 5.3" >&5
+ echo "${ECHO_T}AIX 5.1 or 5.2 or 5.3" >&6
+@@ -5198,8 +5232,8 @@ _ACEOF
+      *)
+ 	echo "$as_me:$LINENO: result: unsupported version" >&5
+ echo "${ECHO_T}unsupported version" >&6
+-	{ { echo "$as_me:$LINENO: error: Valgrind requires glibc version 2.2 - 2.10" >&5
+-echo "$as_me: error: Valgrind requires glibc version 2.2 - 2.10" >&2;}
++	{ { echo "$as_me:$LINENO: error: Valgrind requires glibc version 2.2 - 2.11" >&5
++echo "$as_me: error: Valgrind requires glibc version 2.2 - 2.11" >&2;}
+    { (exit 1); exit 1; }; }
+ 	{ { echo "$as_me:$LINENO: error: or AIX 5.1 or 5.2 or 5.3 GLIBC_VERSION" >&5
+ echo "$as_me: error: or AIX 5.1 or 5.2 or 5.3 GLIBC_VERSION" >&2;}
diff --git a/valgrind-3.5.0-helgrind-race-supp.patch b/valgrind-3.5.0-helgrind-race-supp.patch
new file mode 100644
index 0000000..2fe5e07
--- /dev/null
+++ b/valgrind-3.5.0-helgrind-race-supp.patch
@@ -0,0 +1,15 @@
+--- valgrind/glibc-2.34567-NPTL-helgrind.supp.jj	2009-08-19 15:37:48.000000000 +0200
++++ valgrind/glibc-2.34567-NPTL-helgrind.supp	2009-10-21 16:46:31.000000000 +0200
+@@ -88,6 +88,12 @@
+    obj:/lib*/libpthread-2.*so*
+ }
+ {
++   helgrind-glibc2X-102a
++   Helgrind:Race
++   fun:mythread_wrapper
++   obj:*vgpreload_helgrind*.so
++}
++{
+    helgrind-glibc2X-103
+    Helgrind:Race
+    fun:pthread_cond_*@@GLIBC_2.*
diff --git a/valgrind-3.5.0-i686-nops.patch b/valgrind-3.5.0-i686-nops.patch
new file mode 100644
index 0000000..acb0d68
--- /dev/null
+++ b/valgrind-3.5.0-i686-nops.patch
@@ -0,0 +1,39 @@
+--- valgrind/VEX/priv/guest_x86_toIR.c.jj	2010-04-07 01:25:15.000000000 +0200
++++ valgrind/VEX/priv/guest_x86_toIR.c	2010-04-07 09:13:57.000000000 +0200
+@@ -7919,15 +7919,27 @@ DisResult disInstr_X86_WRK (
+          delta += 5;
+          goto decode_success;
+       }
+-      /* don't barf on recent binutils padding 
+-         66 2e 0f 1f 84 00 00 00 00 00   nopw %cs:0x0(%eax,%eax,1) */
+-      if (code[0] == 0x66
+-          && code[1] == 0x2E && code[2] == 0x0F && code[3] == 0x1F 
+-          && code[4] == 0x84 && code[5] == 0x00 && code[6] == 0x00
+-          && code[7] == 0x00 && code[8] == 0x00 && code[9] == 0x00 ) {
+-         DIP("nopw %%cs:0x0(%%eax,%%eax,1)\n");
+-         delta += 10;
+-         goto decode_success;
++      /* Don't barf on recent binutils padding 
++         66 2e 0f 1f 84 00 00 00 00 00			nopw %cs:0x0(%eax,%eax,1)
++         66 66 2e 0f 1f 84 00 00 00 00 00		nopw %cs:0x0(%eax,%eax,1)
++         66 66 66 2e 0f 1f 84 00 00 00 00 00		nopw %cs:0x0(%eax,%eax,1)
++         66 66 66 66 2e 0f 1f 84 00 00 00 00 00		nopw %cs:0x0(%eax,%eax,1)
++         66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00	nopw %cs:0x0(%eax,%eax,1) */
++      if (code[0] == 0x66) {
++	 Int data16_cnt;
++	 for (data16_cnt = 1; data16_cnt < 6; data16_cnt++)
++	    if (code[data16_cnt] != 0x66)
++	       break;
++
++	 if (code[data16_cnt] == 0x2E && code[data16_cnt + 1] == 0x0F
++	     && code[data16_cnt + 2] == 0x1F && code[data16_cnt + 3] == 0x84
++	     && code[data16_cnt + 4] == 0x00 && code[data16_cnt + 5] == 0x00
++	     && code[data16_cnt + 6] == 0x00 && code[data16_cnt + 7] == 0x00
++	     && code[data16_cnt + 8] == 0x00 ) {
++	    DIP("nopw %%cs:0x0(%%eax,%%eax,1)\n");
++	    delta += 9 + data16_cnt;
++	    goto decode_success;
++	 }
+       }
+    }       
+ 
diff --git a/valgrind-3.5.0-ifunc.patch b/valgrind-3.5.0-ifunc.patch
new file mode 100644
index 0000000..0161152
--- /dev/null
+++ b/valgrind-3.5.0-ifunc.patch
@@ -0,0 +1,513 @@
+--- valgrind/memcheck/mc_replace_strmem.c	(revision 10919)
++++ valgrind/memcheck/mc_replace_strmem.c	(revision 10923)
+@@ -116,6 +116,7 @@ Bool is_overlap ( void* dst, const void*
+ STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
+ STRRCHR(VG_Z_LIBC_SONAME,   rindex)
+ #if defined(VGO_linux)
++STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
+ STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
+ #elif defined(VGO_darwin)
+ STRRCHR(VG_Z_DYLD,          strrchr)
+@@ -140,6 +141,7 @@ STRRCHR(VG_Z_DYLD,          rindex)
+ STRCHR(VG_Z_LIBC_SONAME,          strchr)
+ STRCHR(VG_Z_LIBC_SONAME,          index)
+ #if defined(VGO_linux)
++STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
+ STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
+ STRCHR(VG_Z_LD_LINUX_SO_2,        index)
+ STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
+@@ -172,7 +174,9 @@ STRCHR(VG_Z_DYLD,                 index)
+    }
+ 
+ STRCAT(VG_Z_LIBC_SONAME, strcat)
+-
++#if defined(VGO_linux)
++STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
++#endif
+ 
+ #define STRNCAT(soname, fnname) \
+    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+@@ -257,6 +261,9 @@ STRLCAT(VG_Z_DYLD,        strlcat)
+    }
+ 
+ STRNLEN(VG_Z_LIBC_SONAME, strnlen)
++#if defined(VGO_linux)
++STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
++#endif
+    
+ 
+ // Note that this replacement often doesn't get used because gcc inlines
+@@ -274,6 +281,7 @@ STRNLEN(VG_Z_LIBC_SONAME, strnlen)
+ 
+ STRLEN(VG_Z_LIBC_SONAME,          strlen)
+ #if defined(VGO_linux)
++STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
+ STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
+ STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
+ #endif
+@@ -301,7 +309,9 @@ STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen
+    }
+ 
+ STRCPY(VG_Z_LIBC_SONAME, strcpy)
+-#if defined(VGO_darwin)
++#if defined(VGO_linux)
++STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
++#elif defined(VGO_darwin)
+ STRCPY(VG_Z_DYLD,        strcpy)
+ #endif
+ 
+@@ -327,7 +337,9 @@ STRCPY(VG_Z_DYLD,        strcpy)
+    }
+ 
+ STRNCPY(VG_Z_LIBC_SONAME, strncpy)
+-#if defined(VGO_darwin)
++#if defined(VGO_linux)
++STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
++#elif defined(VGO_darwin)
+ STRNCPY(VG_Z_DYLD,        strncpy)
+ #endif
+ 
+@@ -384,7 +396,9 @@ STRLCPY(VG_Z_DYLD,        strlcpy)
+    }
+ 
+ STRNCMP(VG_Z_LIBC_SONAME, strncmp)
+-#if defined(VGO_darwin)
++#if defined(VGO_linux)
++STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
++#elif defined(VGO_darwin)
+ STRNCMP(VG_Z_DYLD,        strncmp)
+ #endif
+ 
+@@ -411,6 +425,7 @@ STRNCMP(VG_Z_DYLD,        strncmp)
+ 
+ STRCMP(VG_Z_LIBC_SONAME,          strcmp)
+ #if defined(VGO_linux)
++STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
+ STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
+ STRCMP(VG_Z_LD64_SO_1,            strcmp)
+ #endif
+@@ -557,6 +572,7 @@ MEMCMP(VG_Z_DYLD,        bcmp)
+ 
+ STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
+ #if defined(VGO_linux)
++STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
+ STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
+ STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
+ #elif defined(VGO_darwin)
+@@ -709,7 +725,9 @@ GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, str
+    }
+ 
+ GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
+-
++#if defined (VGO_linux)
++GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
++#endif
+ 
+ /* glibc variant of strcpy that checks the dest is big enough.
+    Copied from glibc-2.5/debug/test-strcpy_chk.c. */
+--- valgrind/include/pub_tool_debuginfo.h	(revision 10919)
++++ valgrind/include/pub_tool_debuginfo.h	(revision 10923)
+@@ -212,7 +212,8 @@ void VG_(DebugInfo_syms_getidx)  ( const
+                                    /*OUT*/Addr*   tocptr,
+                                    /*OUT*/UInt*   size,
+                                    /*OUT*/HChar** name,
+-                                   /*OUT*/Bool*   isText );
++                                   /*OUT*/Bool*   isText,
++                                   /*OUT*/Bool*   isIFunc );
+ 
+ /* A simple enumeration to describe the 'kind' of various kinds of
+    segments that arise from the mapping of object files. */
+--- valgrind/coregrind/vg_preloaded.c	(revision 10919)
++++ valgrind/coregrind/vg_preloaded.c	(revision 10923)
+@@ -47,12 +47,12 @@
+ #include "pub_core_debuginfo.h"  // Needed for pub_core_redir.h
+ #include "pub_core_redir.h"      // For VG_NOTIFY_ON_LOAD
+ 
++#if defined(VGO_linux) || defined(VGO_aix5)
++
+ /* ---------------------------------------------------------------------
+    Hook for running __libc_freeres once the program exits.
+    ------------------------------------------------------------------ */
+ 
+-#if defined(VGO_linux) || defined(VGO_aix5)
+-
+ void VG_NOTIFY_ON_LOAD(freeres)( void );
+ void VG_NOTIFY_ON_LOAD(freeres)( void )
+ {
+@@ -68,6 +68,31 @@ void VG_NOTIFY_ON_LOAD(freeres)( void )
+    *(int *)0 = 'x';
+ }
+ 
++/* ---------------------------------------------------------------------
++   Wrapper for indirect functions which need to be redirected.
++   ------------------------------------------------------------------ */
++
++void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void);
++void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void)
++{
++    OrigFn fn;
++    Addr result = 0;
++    int res;
++
++    /* Call the original indirect function and get it's result */
++    VALGRIND_GET_ORIG_FN(fn);
++    CALL_FN_W_v(result, fn);
++
++    /* Ask the valgrind core running on the real CPU (as opposed to this
++       code which runs on the emulated CPU) to update the redirection that
++       led to this function. This client request eventually gives control to
++       the function VG_(redir_add_ifunc_target) in m_redir.c  */
++    VALGRIND_DO_CLIENT_REQUEST(res, 0,
++                               VG_USERREQ__ADD_IFUNC_TARGET,
++                               fn.nraddr, result, 0, 0, 0);
++    return result;
++}
++
+ #elif defined(VGO_darwin)
+ 
+ /* ---------------------------------------------------------------------
+--- valgrind/coregrind/pub_core_clreq.h	(revision 10919)
++++ valgrind/coregrind/pub_core_clreq.h	(revision 10923)
+@@ -50,6 +50,9 @@ typedef
+       /* Internal equivalent of VALGRIND_PRINTF . */
+       VG_USERREQ__INTERNAL_PRINTF   = 0x3103,
+ 
++      /* Add a target for an indirect function redirection. */
++      VG_USERREQ__ADD_IFUNC_TARGET  = 0x3104,
++
+    } Vg_InternalClientRequest;
+ 
+ // Function for printing from code within Valgrind, but which runs on the
+--- valgrind/coregrind/m_debuginfo/debuginfo.c	(revision 10919)
++++ valgrind/coregrind/m_debuginfo/debuginfo.c	(revision 10923)
+@@ -3435,14 +3435,16 @@ void VG_(DebugInfo_syms_getidx) ( const 
+                                   /*OUT*/Addr*   tocptr,
+                                   /*OUT*/UInt*   size,
+                                   /*OUT*/HChar** name,
+-                                  /*OUT*/Bool*   isText )
++                                  /*OUT*/Bool*   isText,
++                                  /*OUT*/Bool*   isIFunc )
+ {
+    vg_assert(idx >= 0 && idx < si->symtab_used);
+-   if (avma)   *avma   = si->symtab[idx].addr;
+-   if (tocptr) *tocptr = si->symtab[idx].tocptr;
+-   if (size)   *size   = si->symtab[idx].size;
+-   if (name)   *name   = (HChar*)si->symtab[idx].name;
+-   if (isText) *isText = si->symtab[idx].isText;
++   if (avma)    *avma    = si->symtab[idx].addr;
++   if (tocptr)  *tocptr  = si->symtab[idx].tocptr;
++   if (size)    *size    = si->symtab[idx].size;
++   if (name)    *name    = (HChar*)si->symtab[idx].name;
++   if (isText)  *isText  = si->symtab[idx].isText;
++   if (isIFunc) *isIFunc = si->symtab[idx].isIFunc;
+ }
+ 
+ 
+--- valgrind/coregrind/m_debuginfo/readelf.c	(revision 10919)
++++ valgrind/coregrind/m_debuginfo/readelf.c	(revision 10923)
+@@ -214,7 +214,8 @@ Bool get_elf_symbol_info ( 
+                                   used on entry */
+         Bool*  from_opd_out,   /* ppc64-linux only: did we deref an
+                                   .opd entry? */
+-        Bool*  is_text_out     /* is this a text symbol? */
++        Bool*  is_text_out,    /* is this a text symbol? */
++        Bool*  is_ifunc        /* is this a  STT_GNU_IFUNC function ?*/
+      )
+ {
+    Bool plausible;
+@@ -232,6 +233,7 @@ Bool get_elf_symbol_info ( 
+    *sym_size_out   = (Int)sym->st_size;
+    *sym_tocptr_out = 0; /* unknown/inapplicable */
+    *from_opd_out   = False;
++   *is_ifunc       = False;
+ 
+    /* Figure out if we're interested in the symbol.  Firstly, is it of
+       the right flavour?  */
+@@ -243,6 +245,9 @@ Bool get_elf_symbol_info ( 
+         &&
+         (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC 
+          || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
++#ifdef STT_GNU_IFUNC
++         || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
++#endif
+         );
+ 
+    /* Work out the svma and bias for each section as it will appear in
+@@ -325,6 +330,14 @@ Bool get_elf_symbol_info ( 
+       *sym_avma_out += text_bias;
+    }
+ 
++#  ifdef STT_GNU_IFUNC
++   /* Check for indirect functions. */
++   if (*is_text_out
++       && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
++       *is_ifunc = True;
++   }
++#  endif
++
+ #  if defined(VGP_ppc64_linux)
+    /* Allow STT_NOTYPE in the very special case where we're running on
+       ppc64-linux and the symbol is one which the .opd-chasing hack
+@@ -570,7 +583,7 @@ void read_elf_symtab__normal( 
+    Char      *sym_name, *sym_name_really;
+    Int        sym_size;
+    Addr       sym_tocptr;
+-   Bool       from_opd, is_text;
++   Bool       from_opd, is_text, is_ifunc;
+    DiSym      risym;
+    ElfXX_Sym *sym;
+ 
+@@ -602,13 +615,14 @@ void read_elf_symtab__normal( 
+                               &sym_avma_really,
+                               &sym_size,
+                               &sym_tocptr,
+-                              &from_opd, &is_text)) {
++                              &from_opd, &is_text, &is_ifunc)) {
+ 
+-         risym.addr   = sym_avma_really;
+-         risym.size   = sym_size;
+-         risym.name   = ML_(addStr) ( di, sym_name_really, -1 );
+-         risym.tocptr = sym_tocptr;
+-         risym.isText = is_text;
++         risym.addr    = sym_avma_really;
++         risym.size    = sym_size;
++         risym.name    = ML_(addStr) ( di, sym_name_really, -1 );
++         risym.tocptr  = sym_tocptr;
++         risym.isText  = is_text;
++         risym.isIFunc = is_ifunc;
+          vg_assert(risym.name != NULL);
+          vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */
+          ML_(addSym) ( di, &risym );
+@@ -646,6 +660,7 @@ typedef
+       Int        size;
+       Bool       from_opd;
+       Bool       is_text;
++      Bool       is_ifunc;
+    }
+    TempSym;
+ 
+@@ -671,7 +686,7 @@ void read_elf_symtab__ppc64_linux( 
+    Char       *sym_name, *sym_name_really;
+    Int         sym_size;
+    Addr        sym_tocptr;
+-   Bool        from_opd, modify_size, modify_tocptr, is_text;
++   Bool        from_opd, modify_size, modify_tocptr, is_text, is_ifunc;
+    DiSym       risym;
+    ElfXX_Sym  *sym;
+    OSet       *oset;
+@@ -713,7 +728,7 @@ void read_elf_symtab__ppc64_linux( 
+                               &sym_avma_really,
+                               &sym_size,
+                               &sym_tocptr,
+-                              &from_opd, &is_text)) {
++                              &from_opd, &is_text, &is_ifunc)) {
+ 
+          /* Check if we've seen this (name,addr) key before. */
+          key.addr = sym_avma_really;
+@@ -785,6 +800,7 @@ void read_elf_symtab__ppc64_linux( 
+             elem->size     = sym_size;
+             elem->from_opd = from_opd;
+             elem->is_text  = is_text;
++            elem->is_ifunc = is_ifunc;
+             VG_(OSetGen_Insert)(oset, elem);
+             if (di->trace_symtab) {
+                VG_(printf)("   to-oset [%4ld]:          "
+@@ -808,11 +824,12 @@ void read_elf_symtab__ppc64_linux( 
+    VG_(OSetGen_ResetIter)( oset );
+ 
+    while ( (elem = VG_(OSetGen_Next)(oset)) ) {
+-      risym.addr   = elem->key.addr;
+-      risym.size   = elem->size;
+-      risym.name   = ML_(addStr) ( di, elem->key.name, -1 );
+-      risym.tocptr = elem->tocptr;
+-      risym.isText = elem->is_text;
++      risym.addr    = elem->key.addr;
++      risym.size    = elem->size;
++      risym.name    = ML_(addStr) ( di, elem->key.name, -1 );
++      risym.tocptr  = elem->tocptr;
++      risym.isText  = elem->is_text;
++      risym.isIFunc = elem->is_ifunc;
+       vg_assert(risym.name != NULL);
+ 
+       ML_(addSym) ( di, &risym );
+--- valgrind/coregrind/m_debuginfo/priv_storage.h	(revision 10919)
++++ valgrind/coregrind/m_debuginfo/priv_storage.h	(revision 10923)
+@@ -48,15 +48,16 @@
+ /* A structure to hold an ELF/XCOFF symbol (very crudely). */
+ typedef 
+    struct { 
+-      Addr  addr;   /* lowest address of entity */
+-      Addr  tocptr; /* ppc64-linux only: value that R2 should have */
+-      UChar *name;  /* name */
++      Addr  addr;    /* lowest address of entity */
++      Addr  tocptr;  /* ppc64-linux only: value that R2 should have */
++      UChar *name;   /* name */
+       // XXX: this could be shrunk (on 32-bit platforms) by using 31 bits for
+       // the size and 1 bit for the isText.  If you do this, make sure that
+       // all assignments to isText use 0 or 1 (or True or False), and that a
+       // positive number larger than 1 is never used to represent True.
+-      UInt  size;   /* size in bytes */
++      UInt  size;    /* size in bytes */
+       Bool  isText;
++      Bool  isIFunc; /* symbol is an indirect function? */
+    }
+    DiSym;
+ 
+--- valgrind/coregrind/m_redir.c	(revision 10919)
++++ valgrind/coregrind/m_redir.c	(revision 10923)
+@@ -268,12 +268,15 @@ typedef
+       TopSpec* parent_spec; /* the TopSpec which supplied the Spec */
+       TopSpec* parent_sym;  /* the TopSpec which supplied the symbol */
+       Bool     isWrap;      /* wrap or replacement? */
++      Bool     isIFunc;     /* indirect function? */
+    }
+    Active;
+ 
+ /* The active set is a fast lookup table */
+ static OSet* activeSet = NULL;
+ 
++/* Wrapper routine for indirect functions */
++static Addr iFuncWrapper;
+ 
+ /*------------------------------------------------------------*/
+ /*--- FWDses                                               ---*/
+@@ -350,8 +353,8 @@ void VG_(redir_notify_new_DebugInfo)( De
+ 
+    nsyms = VG_(DebugInfo_syms_howmany)( newsi );
+    for (i = 0; i < nsyms; i++) {
+-      VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, 
+-                                            NULL, &sym_name, &isText );
++      VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc,
++                                  NULL, &sym_name, &isText, NULL );
+       ok = VG_(maybe_Z_demangle)( sym_name, demangled_sopatt, N_DEMANGLED,
+                                   demangled_fnpatt, N_DEMANGLED, &isWrap );
+       /* ignore data symbols */
+@@ -388,8 +391,8 @@ void VG_(redir_notify_new_DebugInfo)( De
+ 
+    if (check_ppcTOCs) {
+       for (i = 0; i < nsyms; i++) {
+-         VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, 
+-                                               NULL, &sym_name, &isText );
++         VG_(DebugInfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc,
++                                     NULL, &sym_name, &isText, NULL );
+          ok = isText
+               && VG_(maybe_Z_demangle)( 
+                     sym_name, demangled_sopatt, N_DEMANGLED,
+@@ -470,6 +473,30 @@ void VG_(redir_notify_new_DebugInfo)( De
+ 
+ #undef N_DEMANGLED
+ 
++/* Add a new target for an indirect function. Adds a new redirection
++   for the indirection function with address old_from that redirects
++   the ordinary function with address new_from to the target address
++   of the original redirection. */
++
++void VG_(redir_add_ifunc_target)( Addr old_from, Addr new_from )
++{
++    Active *old, new;
++
++    old = VG_(OSetGen_Lookup)(activeSet, &old_from);
++    vg_assert(old);
++    vg_assert(old->isIFunc);
++
++    new = *old;
++    new.from_addr = new_from;
++    new.isIFunc = False;
++    maybe_add_active (new);
++
++    if (VG_(clo_trace_redir)) {
++       VG_(message)( Vg_DebugMsg,
++                     "Adding redirect for indirect function 0x%llx from 0x%llx -> 0x%llx\n",
++                     (ULong)old_from, (ULong)new_from, (ULong)new.to_addr );
++    }
++}
+ 
+ /* Do one element of the basic cross product: add to the active set,
+    all matches resulting from comparing all the given specs against
+@@ -487,7 +514,7 @@ void generate_and_add_actives ( 
+      )
+ {
+    Spec*  sp;
+-   Bool   anyMark, isText;
++   Bool   anyMark, isText, isIFunc;
+    Active act;
+    Int    nsyms, i;
+    Addr   sym_addr;
+@@ -513,7 +540,7 @@ void generate_and_add_actives ( 
+    nsyms = VG_(DebugInfo_syms_howmany)( di );
+    for (i = 0; i < nsyms; i++) {
+       VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL, NULL,
+-                                         &sym_name, &isText );
++                                  &sym_name, &isText, &isIFunc );
+ 
+       /* ignore data symbols */
+       if (!isText)
+@@ -539,6 +566,7 @@ void generate_and_add_actives ( 
+             act.parent_spec = parent_spec;
+             act.parent_sym  = parent_sym;
+             act.isWrap      = sp->isWrap;
++            act.isIFunc     = isIFunc;
+             sp->done = True;
+             maybe_add_active( act );
+          }
+@@ -780,7 +808,9 @@ Addr VG_(redir_do_lookup) ( Addr orig, B
+ 
+    vg_assert(r->to_addr != 0);
+    if (isWrap)
+-      *isWrap = r->isWrap;
++      *isWrap = r->isWrap || r->isIFunc;
++   if (r->isIFunc)
++      return iFuncWrapper;
+    return r->to_addr;
+ }
+ 
+@@ -800,6 +830,7 @@ static void add_hardwired_active ( Addr 
+    act.parent_spec = NULL;
+    act.parent_sym  = NULL;
+    act.isWrap      = False;
++   act.isIFunc     = False;
+    maybe_add_active( act );
+ }
+ 
+@@ -1096,6 +1127,8 @@ void handle_maybe_load_notifier( const U
+ 
+    if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(freeres))) == 0)
+       VG_(client___libc_freeres_wrapper) = addr;
++   else if (VG_(strcmp)(symbol, VG_STRINGIFY(VG_NOTIFY_ON_LOAD(ifunc_wrapper))) == 0)
++      iFuncWrapper = addr;
+    else
+       vg_assert2(0, "unrecognised load notification function: %s", symbol);
+ }
+--- valgrind/coregrind/pub_core_redir.h	(revision 10919)
++++ valgrind/coregrind/pub_core_redir.h	(revision 10923)
+@@ -58,6 +58,8 @@ extern void VG_(redir_notify_delete_Debu
+ /* Initialise the module, and load initial "hardwired" redirects. */
+ extern void VG_(redir_initialise)( void );
+ 
++/* Notify the module of a new target for an indirect function. */
++extern void VG_(redir_add_ifunc_target)( Addr old_from, Addr new_from );
+ 
+ //--------------------------------------------------------------------
+ // Queries
+--- valgrind/coregrind/m_scheduler/scheduler.c	(revision 10919)
++++ valgrind/coregrind/m_scheduler/scheduler.c	(revision 10923)
+@@ -89,6 +89,7 @@
+ #include "pub_core_debuginfo.h"     // VG_(di_notify_pdb_debuginfo)
+ #include "priv_sema.h"
+ #include "pub_core_scheduler.h"     // self
++#include "pub_core_redir.h"
+ 
+ 
+ /* ---------------------------------------------------------------------
+@@ -1399,6 +1400,11 @@ void do_client_request ( ThreadId tid )
+             SET_CLREQ_RETVAL( tid, count );
+          break; }
+ 
++      case VG_USERREQ__ADD_IFUNC_TARGET: {
++         VG_(redir_add_ifunc_target)( arg[1], arg[2] );
++         SET_CLREQ_RETVAL( tid, 0);
++         break; }
++
+       case VG_USERREQ__PRINTF_BACKTRACE: {
+          Int count =
+             VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], (void*)arg[2] );
diff --git a/valgrind-3.5.0-inotify-init1.patch b/valgrind-3.5.0-inotify-init1.patch
new file mode 100644
index 0000000..21e5772
--- /dev/null
+++ b/valgrind-3.5.0-inotify-init1.patch
@@ -0,0 +1,112 @@
+commit 4b8a2fd25a4227f0b1411bee12add2d5c887c6a2
+Author: Dodji Seketeli <dodji@redhat.com>
+Date:   Mon Oct 5 13:45:38 2009 +0200
+
+    Add a wrapper for inotify_init1 (vgbz #202315)
+    
+    	* coregrind/m_syswrap/priv_syswrap-linux.h: Declare the
+    	sys_inotify_init1 wrapper.
+    	* coregrind/m_syswrap/syswrap-linux.c: Add pre/post handlers for
+    	the sys_inotify_init1 syscall.
+    	* coregrind/m_syswrap/syswrap-amd64-linux.c: Insert the
+    	sys_inotify_init1 wrapper in the wrappers table for the amd64 arch.
+    	* coregrind/m_syswrap/syswrap-x86-linux.c: Likewise for the x86_32
+    	arch.
+
+diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h
+index fed3ba6..894678d 100644
+--- a/coregrind/m_syswrap/priv_syswrap-linux.h
++++ b/coregrind/m_syswrap/priv_syswrap-linux.h
+@@ -116,6 +116,7 @@ DECL_TEMPLATE(linux, sys_set_mempolicy);
+ DECL_TEMPLATE(linux, sys_get_mempolicy);
+ 
+ DECL_TEMPLATE(linux, sys_inotify_init);
++DECL_TEMPLATE(linux, sys_inotify_init1);
+ DECL_TEMPLATE(linux, sys_inotify_add_watch);
+ DECL_TEMPLATE(linux, sys_inotify_rm_watch);
+ 
+diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
+index 605d844..bb28073 100644
+--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
++++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
+@@ -1374,8 +1374,8 @@ const SyscallTableEntry ML_(syscall_table)[] = {
+    LINX_(__NR_eventfd2,          sys_eventfd2),         // 290
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
+    //   (__NR_dup3,              sys_ni_syscall)        // 292
+-   LINXY(__NR_pipe2,             sys_pipe2)             // 293
+-   //   (__NR_inotify_init1,     sys_ni_syscall)        // 294
++   LINXY(__NR_pipe2,             sys_pipe2),            // 293
++   LINXY(__NR_inotify_init1,     sys_inotify_init1),     // 294
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
+index 7f81262..895bc54 100644
+--- a/coregrind/m_syswrap/syswrap-linux.c
++++ b/coregrind/m_syswrap/syswrap-linux.c
+@@ -1526,6 +1526,24 @@ POST(sys_inotify_init)
+    }
+ }
+ 
++PRE(sys_inotify_init1)
++{
++   PRINT("sys_inotify_init ( %ld )", ARG1);
++   PRE_REG_READ1(long, "inotify_init", int, flag);
++}
++
++POST(sys_inotify_init1)
++{
++   vg_assert(SUCCESS);
++   if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
++      VG_(close)(RES);
++      SET_STATUS_Failure( VKI_EMFILE );
++   } else {
++      if (VG_(clo_track_fds))
++         ML_(record_fd_open_nameless) (tid, RES);
++   }
++}
++
+ PRE(sys_inotify_add_watch)
+ {
+    PRINT( "sys_inotify_add_watch ( %ld, %#lx, %lx )", ARG1,ARG2,ARG3);
+diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
+index 90eb512..180e36b 100644
+--- a/coregrind/m_syswrap/syswrap-x86-linux.c
++++ b/coregrind/m_syswrap/syswrap-x86-linux.c
+@@ -2253,8 +2253,8 @@ const SyscallTableEntry ML_(syscall_table)[] = {
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),     // 329
+ 
+    //   (__NR_dup3,              sys_ni_syscall)        // 330
+-   LINXY(__NR_pipe2,             sys_pipe2)             // 331
+-   //   (__NR_inotify_init1,     sys_ni_syscall)        // 332
++   LINXY(__NR_pipe2,             sys_pipe2),            // 331
++   LINX_(__NR_inotify_init1,     sys_inotify_init1)     // 332
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc32-linux.c.jj	2009-10-09 12:52:04.000000000 +0200
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc32-linux.c	2009-10-12 16:14:33.000000000 +0200
+@@ -1866,8 +1866,8 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_eventfd2,          sys_eventfd2),         // 314
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
+    //   (__NR_dup3,              sys_ni_syscall)        // 316
+-   LINXY(__NR_pipe2,             sys_pipe2)             // 317
+-   //   (__NR_inotify_init1,     sys_ni_syscall)        // 318
++   LINXY(__NR_pipe2,             sys_pipe2),            // 317
++   LINX_(__NR_inotify_init1,     sys_inotify_init1)     // 318
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc64-linux.c.jj	2009-10-09 12:52:04.000000000 +0200
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc64-linux.c	2009-10-12 16:14:55.000000000 +0200
+@@ -1506,8 +1506,8 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_eventfd2,          sys_eventfd2),         // 314
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
+    //   (__NR_dup3,              sys_ni_syscall)        // 316
+-   LINXY(__NR_pipe2,             sys_pipe2)             // 317
+-   //   (__NR_inotify_init1,     sys_ni_syscall)        // 318
++   LINXY(__NR_pipe2,             sys_pipe2),            // 317
++   LINX_(__NR_inotify_init1,     sys_inotify_init1)     // 318
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
diff --git a/valgrind-3.5.0-mmap-mprotect.patch b/valgrind-3.5.0-mmap-mprotect.patch
new file mode 100644
index 0000000..668cb05
--- /dev/null
+++ b/valgrind-3.5.0-mmap-mprotect.patch
@@ -0,0 +1,15 @@
+Temporarily revert a Darwin specific change that broke mmap PROT_NONE followed by
+mprotect PROT_READ|PROT_WRITE.
+http://bugs.kde.org/show_bug.cgi?id=210268
+
+--- valgrind-3.5.0/memcheck/mc_main.c.jj	2009-10-09 12:51:59.000000000 +0200
++++ valgrind-3.5.0/memcheck/mc_main.c	2009-10-12 17:13:26.000000000 +0200
+@@ -3705,7 +3705,7 @@ static
+ void mc_new_mem_mmap ( Addr a, SizeT len, Bool rr, Bool ww, Bool xx,
+                        ULong di_handle )
+ {
+-   if (rr || ww || xx)
++   if (1 || rr || ww || xx)
+       MC_(make_mem_defined)(a, len);
+    else
+       MC_(make_mem_noaccess)(a, len);
diff --git a/valgrind-3.5.0-pkgconfig.patch b/valgrind-3.5.0-pkgconfig.patch
new file mode 100644
index 0000000..bcb1ef6
--- /dev/null
+++ b/valgrind-3.5.0-pkgconfig.patch
@@ -0,0 +1,10 @@
+--- valgrind/valgrind.pc.in.jj	2009-10-09 12:52:05.000000000 +0200
++++ valgrind/valgrind.pc.in	2010-01-20 10:17:40.000000000 +0100
+@@ -11,6 +11,6 @@ Name: Valgrind
+ Description: A dynamic binary instrumentation framework
+ Version: @VERSION@
+ Requires:
+-Libs: -L${libdir}/valgrind/@VGCONF_ARCH_PRI@-@VGCONF_OS@ -lcoregrind -lvex -lgcc
++Libs: -L${libdir}/valgrind -lcoregrind-@VGCONF_ARCH_PRI@-@VGCONF_OS@ -lvex-@VGCONF_ARCH_PRI@-@VGCONF_OS@ -lgcc
+ Cflags: -I${includedir}
+ 
diff --git a/valgrind-3.5.0-ppc-dwarf3.patch b/valgrind-3.5.0-ppc-dwarf3.patch
new file mode 100644
index 0000000..d9187c5
--- /dev/null
+++ b/valgrind-3.5.0-ppc-dwarf3.patch
@@ -0,0 +1,85 @@
+--- valgrind/coregrind/m_debuginfo/d3basics.c.jj	2009-10-22 17:40:55.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/d3basics.c	2009-10-23 15:44:21.948199235 +0200
+@@ -387,12 +387,8 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr* 
+    if (regno == 7/*RSP*/) { *a = regs->sp; return True; }
+ #  elif defined(VGP_ppc32_linux)
+    if (regno == 1/*SP*/) { *a = regs->sp; return True; }
+-   if (regno == 31) return False;
+-   vg_assert(0);
+ #  elif defined(VGP_ppc64_linux)
+    if (regno == 1/*SP*/) { *a = regs->sp; return True; }
+-   if (regno == 31) return False;
+-   vg_assert(0);
+ #  elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+    vg_assert(0); /* this function should never be called */
+ #  else
+@@ -831,7 +827,12 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh
+          case DW_OP_call_frame_cfa:
+             if (!regs)
+                FAIL("evaluate_Dwarf3_Expr: DW_OP_call_frame_cfa but no reg info");
++#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
++            /* Valgrind on ppc32/ppc64 currently doesn't use unwind info.  */
++            uw1 = *(Addr *)(regs->sp);
++#else
+             uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
++#endif
+             if (!uw1)
+                FAIL("evaluate_Dwarf3_Expr: Could not resolve "
+                     "DW_OP_call_frame_cfa");
+--- valgrind/coregrind/m_debuginfo/readdwarf.c.jj	2009-10-22 17:40:55.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/readdwarf.c	2009-10-23 15:42:17.979217217 +0200
+@@ -1778,11 +1778,11 @@ void ML_(read_debuginfo_dwarf1) ( 
+ #elif defined(VGP_ppc32_linux)
+ #  define FP_REG         1
+ #  define SP_REG         1
+-#  define RA_REG_DEFAULT 8     // CAB: What's a good default ?
++#  define RA_REG_DEFAULT 65
+ #elif defined(VGP_ppc64_linux)
+ #  define FP_REG         1
+ #  define SP_REG         1
+-#  define RA_REG_DEFAULT 8     // CAB: What's a good default ?
++#  define RA_REG_DEFAULT 65
+ #elif defined(VGP_x86_darwin)
+ #  define FP_REG         5
+ #  define SP_REG         4
+@@ -1796,7 +1796,11 @@ void ML_(read_debuginfo_dwarf1) ( 
+ #endif
+ 
+ /* the number of regs we are prepared to unwind */
+-#define N_CFI_REGS 20
++#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
++# define N_CFI_REGS 72
++#else
++# define N_CFI_REGS 20
++#endif
+ 
+ /* Instructions for the automaton */
+ enum dwarf_cfa_primary_ops
+@@ -3422,12 +3426,8 @@ void ML_(read_callframe_info_dwarf3)
+    UWord  ehframe_cfsis = 0;   
+ 
+ #  if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+-   if (!VG_(needs).var_info /* the tool requires it */   
+-       && !VG_(clo_read_var_info) /* the user asked for it */) {
+-      /* These targets don't use CFI-based stack unwinding, but still might
+-         need it for DW_OP_call_frame_cfa support. */
+-      return;
+-   }
++   /* These targets don't use CFI-based stack unwinding.  */
++   return;
+ #  endif
+ 
+    /* If we are reading .debug_frame after .eh_frame has been read, only
+--- valgrind/coregrind/m_stacktrace.c.jj	2009-08-19 15:37:47.000000000 +0200
++++ valgrind/coregrind/m_stacktrace.c	2009-10-23 14:57:08.734338026 +0200
+@@ -430,9 +430,9 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId 
+ #           endif
+ 
+             if (0 == ip || 1 == ip) break;
+-            fp = (((UWord*)fp)[0]);
+             if (sps) sps[i] = fp; /* NB. not sp */
+             if (fps) fps[i] = fp;
++            fp = (((UWord*)fp)[0]);
+             ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
+             if (debug)
+                VG_(printf)("     ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
diff --git a/valgrind-3.5.0-ppc-tests.patch b/valgrind-3.5.0-ppc-tests.patch
new file mode 100644
index 0000000..f0119ba
--- /dev/null
+++ b/valgrind-3.5.0-ppc-tests.patch
@@ -0,0 +1,34 @@
+--- valgrind/none/tests/ppc32/jm-insns.c.jj	2009-10-09 12:52:01.000000000 +0200
++++ valgrind/none/tests/ppc32/jm-insns.c	2009-10-20 17:25:32.000000000 +0200
+@@ -210,10 +210,10 @@ typedef uint64_t  HWord_t;
+ 
+ 
+ /* XXXX these must all be callee-save regs! */
+-register double f14 __asm__ ("f14");
+-register double f15 __asm__ ("f15");
+-register double f16 __asm__ ("f16");
+-register double f17 __asm__ ("f17");
++register double f14 __asm__ ("fr14");
++register double f15 __asm__ ("fr15");
++register double f16 __asm__ ("fr16");
++register double f17 __asm__ ("fr17");
+ register HWord_t r14 __asm__ ("r14");
+ register HWord_t r15 __asm__ ("r15");
+ register HWord_t r16 __asm__ ("r16");
+--- valgrind/none/tests/ppc64/jm-insns.c.jj	2009-10-09 12:52:01.000000000 +0200
++++ valgrind/none/tests/ppc64/jm-insns.c	2009-10-20 17:25:32.000000000 +0200
+@@ -210,10 +210,10 @@ typedef uint64_t  HWord_t;
+ 
+ 
+ /* XXXX these must all be callee-save regs! */
+-register double f14 __asm__ ("f14");
+-register double f15 __asm__ ("f15");
+-register double f16 __asm__ ("f16");
+-register double f17 __asm__ ("f17");
++register double f14 __asm__ ("fr14");
++register double f15 __asm__ ("fr15");
++register double f16 __asm__ ("fr16");
++register double f17 __asm__ ("fr17");
+ register HWord_t r14 __asm__ ("r14");
+ register HWord_t r15 __asm__ ("r15");
+ register HWord_t r16 __asm__ ("r16");
diff --git a/valgrind-3.5.0-pr40659.patch b/valgrind-3.5.0-pr40659.patch
new file mode 100644
index 0000000..e5fc3bd
--- /dev/null
+++ b/valgrind-3.5.0-pr40659.patch
@@ -0,0 +1,163 @@
+--- valgrind/coregrind/m_debuginfo/tytypes.c.jj	2009-10-14 15:00:07.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/tytypes.c	2009-10-14 16:28:39.000000000 +0200
+@@ -98,10 +98,15 @@ void ML_(pp_TyEnt)( TyEnt* te )
+                      te->Te.Atom.value, te->Te.Atom.name);
+          break;
+       case Te_Field:
+-         VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,loc=%p,\"%s\")",
+-                     te->Te.Field.typeR, te->Te.Field.nLoc,
+-                     te->Te.Field.loc,
+-                     te->Te.Field.name ? te->Te.Field.name : (UChar*)"");
++         if (te->Te.Field.nLoc == -1)
++            VG_(printf)("Te_Field(ty=0x%05lx,pos.offset=%ld,\"%s\")",
++                        te->Te.Field.typeR, te->Te.Field.pos.offset,
++                        te->Te.Field.name ? te->Te.Field.name : (UChar*)"");
++         else
++            VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,pos.loc=%p,\"%s\")",
++                        te->Te.Field.typeR, te->Te.Field.nLoc,
++                        te->Te.Field.pos.loc,
++                        te->Te.Field.name ? te->Te.Field.name : (UChar*)"");
+          break;
+       case Te_Bound:
+          VG_(printf)("Te_Bound[");
+@@ -476,7 +481,9 @@ Word ML_(TyEnt__cmp_by_all_except_cuOff)
+       if (r != 0) return r;
+       r = UWord__cmp(te1->Te.Field.nLoc, te2->Te.Field.nLoc);
+       if (r != 0) return r;
+-      r = Bytevector__cmp(te1->Te.Field.loc, te2->Te.Field.loc,
++      if (te1->Te.Field.nLoc == -1)
++         return Long__cmp(te1->Te.Field.pos.offset, te2->Te.Field.pos.offset);
++      r = Bytevector__cmp(te1->Te.Field.pos.loc, te2->Te.Field.pos.loc,
+                           te1->Te.Field.nLoc);
+       return r;
+    case Te_Bound:
+@@ -568,7 +575,8 @@ void ML_(TyEnt__make_EMPTY) ( TyEnt* te 
+          break;
+       case Te_Field:
+          if (te->Te.Field.name) ML_(dinfo_free)(te->Te.Field.name);
+-         if (te->Te.Field.loc) ML_(dinfo_free)(te->Te.Field.loc);
++         if (te->Te.Field.nLoc > 0 && te->Te.Field.pos.loc)
++            ML_(dinfo_free)(te->Te.Field.pos.loc);
+          break;
+       case Te_Bound:
+          break;
+@@ -747,24 +755,30 @@ XArray* /*UChar*/ ML_(describe_type)( /*
+                field = ML_(TyEnts__index_by_cuOff)(tyents, NULL, fieldR);
+                vg_assert(field);
+                vg_assert(field->tag == Te_Field);
+-               vg_assert(field->Te.Field.loc);
+-               vg_assert(field->Te.Field.nLoc > 0);
+-               /* Re data_bias in this call, we should really send in
+-                  a legitimate value.  But the expression is expected
+-                  to be a constant expression, evaluation of which
+-                  will not need to use DW_OP_addr and hence we can
+-                  avoid the trouble of plumbing the data bias through
+-                  to this point (if, indeed, it has any meaning; from
+-                  which DebugInfo would we take the data bias? */
+-               res = ML_(evaluate_Dwarf3_Expr)(
+-                       field->Te.Field.loc, field->Te.Field.nLoc,
+-                       NULL/*fbGX*/, NULL/*RegSummary*/,
+-                       0/*data_bias*/,
+-                       True/*push_initial_zero*/);
+-               if (0) {
+-                  VG_(printf)("QQQ ");
+-                  ML_(pp_GXResult)(res);
+-                  VG_(printf)("\n");
++               vg_assert(field->Te.Field.nLoc < 0
++                         || (field->Te.Field.nLoc > 0
++                             && field->Te.Field.pos.loc));
++               if (field->Te.Field.nLoc == -1) {
++                  res.kind = GXR_Addr;
++                  res.word = field->Te.Field.pos.offset;
++               } else {
++                  /* Re data_bias in this call, we should really send in
++                     a legitimate value.  But the expression is expected
++                     to be a constant expression, evaluation of which
++                     will not need to use DW_OP_addr and hence we can
++                     avoid the trouble of plumbing the data bias through
++                     to this point (if, indeed, it has any meaning; from
++                     which DebugInfo would we take the data bias? */
++                   res =  ML_(evaluate_Dwarf3_Expr)(
++                          field->Te.Field.pos.loc, field->Te.Field.nLoc,
++                          NULL/*fbGX*/, NULL/*RegSummary*/,
++                          0/*data_bias*/,
++                          True/*push_initial_zero*/);
++                  if (0) {
++                     VG_(printf)("QQQ ");
++                     ML_(pp_GXResult)(res);
++                     VG_(printf)("\n");
++                  }
+                }
+                if (res.kind != GXR_Addr)
+                   continue;
+--- valgrind/coregrind/m_debuginfo/priv_tytypes.h.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/priv_tytypes.h	2009-10-14 15:49:52.000000000 +0200
+@@ -78,8 +78,13 @@ typedef
+          struct {
+             UChar* name;  /* in mallocville */
+             UWord  typeR; /* should be Te_TyXXXX */
+-            UChar* loc;   /* location expr, in mallocville */
+-            UWord  nLoc;  /* number of bytes in .loc */
++            union {
++               UChar* loc;   /* location expr, in mallocville */
++               Word offset;  /* or offset from the beginning of containing
++                                entity */
++            } pos;
++            Word  nLoc;  /* number of bytes in .pos.loc if >= 0, or -1
++                            if .pos.offset should be used instead */
+             Bool   isStruct;
+          } Field;
+          struct {
+--- valgrind/coregrind/m_debuginfo/readdwarf3.c.jj	2009-08-19 15:37:44.000000000 +0200
++++ valgrind/coregrind/m_debuginfo/readdwarf3.c	2009-10-14 16:25:51.000000000 +0200
+@@ -2356,9 +2356,16 @@ static void parse_type_DIE ( /*MOD*/XArr
+          if (attr == DW_AT_type && ctsSzB > 0) {
+             fieldE.Te.Field.typeR = (UWord)cts;
+          }
+-         if (attr == DW_AT_data_member_location && ctsMemSzB > 0) {
++         /* There are 2 different cases for DW_AT_data_member_location.
++            If it is a constant class attribute, it contains byte offset
++            from the beginning of the containing entity.
++            Otherwise it is a location expression.  */
++         if (attr == DW_AT_data_member_location && ctsSzB > 0) {
++            fieldE.Te.Field.nLoc = -1;
++            fieldE.Te.Field.pos.offset = cts;
++         } else if (attr == DW_AT_data_member_location && ctsMemSzB > 0) {
+             fieldE.Te.Field.nLoc = (UWord)ctsMemSzB;
+-            fieldE.Te.Field.loc
++            fieldE.Te.Field.pos.loc
+                = ML_(dinfo_memdup)( "di.readdwarf3.ptD.member.2",
+                                     (UChar*)(UWord)cts, 
+                                     (SizeT)fieldE.Te.Field.nLoc );
+@@ -2385,13 +2392,14 @@ static void parse_type_DIE ( /*MOD*/XArr
+       vg_assert(fieldE.Te.Field.name);
+       if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF)
+          goto bad_DIE;
+-      if (fieldE.Te.Field.loc) {
++      if (fieldE.Te.Field.nLoc) {
+          if (!parent_is_struct) {
+             /* If this is a union type, pretend we haven't seen the data
+                member location expression, as it is by definition
+                redundant (it must be zero). */
+-            ML_(dinfo_free)(fieldE.Te.Field.loc);
+-            fieldE.Te.Field.loc  = NULL;
++            if (fieldE.Te.Field.nLoc > 0)
++               ML_(dinfo_free)(fieldE.Te.Field.pos.loc);
++            fieldE.Te.Field.pos.loc = NULL;
+             fieldE.Te.Field.nLoc = 0;
+          }
+          /* Record this child in the parent */
+@@ -2616,10 +2624,10 @@ static void parse_type_DIE ( /*MOD*/XArr
+    /* For union members, Expr should be absent */
+    if (0) VG_(printf)("YYYY Acquire Field\n");
+    vg_assert(fieldE.tag == Te_Field);
+-   vg_assert( (fieldE.Te.Field.nLoc > 0 && fieldE.Te.Field.loc != NULL)
+-              || (fieldE.Te.Field.nLoc == 0 && fieldE.Te.Field.loc == NULL) );
++   vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL);
++   vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL);
+    if (fieldE.Te.Field.isStruct) {
+-      vg_assert(fieldE.Te.Field.nLoc > 0);
++      vg_assert(fieldE.Te.Field.nLoc != 0);
+    } else {
+       vg_assert(fieldE.Te.Field.nLoc == 0);
+    }
diff --git a/valgrind-3.5.0-preadv.patch b/valgrind-3.5.0-preadv.patch
new file mode 100644
index 0000000..9c2a63d
--- /dev/null
+++ b/valgrind-3.5.0-preadv.patch
@@ -0,0 +1,154 @@
+--- valgrind/coregrind/m_syswrap/syswrap-amd64-linux.c.jj	2009-10-27 22:07:26.000000000 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-amd64-linux.c	2009-10-28 09:24:57.307058551 +0100
+@@ -1377,8 +1377,8 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_pipe2,             sys_pipe2),            // 293
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
+ 
+-   //   (__NR_preadv,            sys_ni_syscall)        // 295
+-   //   (__NR_pwritev,           sys_ni_syscall)        // 296
++   LINXY(__NR_preadv,            sys_preadv),           // 295
++   LINX_(__NR_pwritev,           sys_pwritev),          // 296
+    //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 297
+    LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 298
+ };
+--- valgrind/coregrind/m_syswrap/syswrap-x86-linux.c.jj	2009-10-27 22:07:26.000000000 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-x86-linux.c	2009-10-28 09:24:08.631308771 +0100
+@@ -2255,8 +2255,8 @@ const SyscallTableEntry ML_(syscall_tabl
+    //   (__NR_dup3,              sys_ni_syscall)        // 330
+    LINXY(__NR_pipe2,             sys_pipe2),            // 331
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 332
+-   //   (__NR_preadv,            sys_ni_syscall)        // 333
+-   //   (__NR_pwritev,           sys_ni_syscall)        // 334
++   LINXY(__NR_preadv,            sys_preadv),           // 333
++   LINX_(__NR_pwritev,           sys_pwritev),          // 334
+ 
+    //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 335
+    LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 336
+--- valgrind/coregrind/m_syswrap/syswrap-ppc64-linux.c.jj	2009-10-27 22:07:26.000000000 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-ppc64-linux.c	2009-10-28 09:28:43.563071713 +0100
+@@ -1508,9 +1508,9 @@ const SyscallTableEntry ML_(syscall_tabl
+    //   (__NR_dup3,              sys_ni_syscall)        // 316
+    LINXY(__NR_pipe2,             sys_pipe2),            // 317
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
+-   LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 319
+-   //   (__NR_preadv,            sys_ni_syscall)        // 320
+-   //   (__NR_pwritev,           sys_ni_syscall)        // 321
++   LINXY(__NR_perf_counter_open, sys_perf_counter_open),// 319
++   LINXY(__NR_preadv,            sys_preadv),           // 320
++   LINX_(__NR_pwritev,           sys_pwritev)           // 321
+    //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 322
+ };
+ 
+--- valgrind/coregrind/m_syswrap/syswrap-linux.c.jj	2009-10-27 22:07:26.000000000 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-linux.c	2009-10-28 09:40:32.276183692 +0100
+@@ -3009,6 +3009,83 @@ PRE(sys_faccessat)
+    PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
+ }
+ 
++PRE(sys_preadv)
++{
++   Int i;
++   struct vki_iovec * vec;
++   ULong off = (ULong)ARG4;
++#if VG_WORDSIZE == 4
++   off |= (ULong)ARG5 << 32;
++#endif
++   *flags |= SfMayBlock;
++   PRINT("sys_preadv ( %ld, %#lx, %llu, %llu )",ARG1,ARG2,(ULong)ARG3,off);
++   PRE_REG_READ5(ssize_t, "preadv",
++                 unsigned long, fd, const struct iovec *, vector,
++                 unsigned long, count, unsigned long, off_lo,
++                 unsigned long, off_hi);
++   if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
++      SET_STATUS_Failure( VKI_EBADF );
++   } else {
++      PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
++
++      if (ARG2 != 0) {
++         /* ToDo: don't do any of the following if the vector is invalid */
++         vec = (struct vki_iovec *)ARG2;
++         for (i = 0; i < (Int)ARG3; i++)
++            PRE_MEM_WRITE( "preadv(vector[...])",
++                           (Addr)vec[i].iov_base, vec[i].iov_len );
++      }
++   }
++}
++
++POST(sys_preadv)
++{
++   vg_assert(SUCCESS);
++   if (RES > 0) {
++      Int i;
++      struct vki_iovec * vec = (struct vki_iovec *)ARG2;
++      Int remains = RES;
++
++      /* RES holds the number of bytes read. */
++      for (i = 0; i < (Int)ARG3; i++) {
++	 Int nReadThisBuf = vec[i].iov_len;
++	 if (nReadThisBuf > remains) nReadThisBuf = remains;
++	 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
++	 remains -= nReadThisBuf;
++	 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
++      }
++   }
++}
++
++PRE(sys_pwritev)
++{
++   Int i;
++   struct vki_iovec * vec;
++   ULong off = (ULong)ARG4;
++#if VG_WORDSIZE == 4
++   off |= (ULong)ARG5 << 32;
++#endif
++   *flags |= SfMayBlock;
++   PRINT("sys_pwritev ( %ld, %#lx, %llu, %llu )",ARG1,ARG2,(ULong)ARG3,off);
++   PRE_REG_READ5(ssize_t, "pwritev",
++                 unsigned long, fd, const struct iovec *, vector,
++                 unsigned long, count, unsigned long, off_lo,
++                 unsigned long, off_hi);
++   if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
++      SET_STATUS_Failure( VKI_EBADF );
++   } else {
++      PRE_MEM_READ( "pwritev(vector)", 
++		     ARG2, ARG3 * sizeof(struct vki_iovec) );
++      if (ARG2 != 0) {
++         /* ToDo: don't do any of the following if the vector is invalid */
++         vec = (struct vki_iovec *)ARG2;
++         for (i = 0; i < (Int)ARG3; i++)
++            PRE_MEM_READ( "pwritev(vector[...])",
++                           (Addr)vec[i].iov_base, vec[i].iov_len );
++      }
++   }
++}
++
+ /* ---------------------------------------------------------------------
+    key retention service wrappers
+    ------------------------------------------------------------------ */
+--- valgrind/coregrind/m_syswrap/priv_syswrap-linux.h.jj	2009-10-27 22:07:26.000000000 +0100
++++ valgrind/coregrind/m_syswrap/priv_syswrap-linux.h	2009-10-28 09:22:42.735058008 +0100
+@@ -163,6 +163,9 @@ DECL_TEMPLATE(linux, sys_fchmodat);
+ DECL_TEMPLATE(linux, sys_faccessat);
+ DECL_TEMPLATE(linux, sys_utimensat);
+ 
++DECL_TEMPLATE(linux, sys_preadv);
++DECL_TEMPLATE(linux, sys_pwritev);
++
+ DECL_TEMPLATE(linux, sys_add_key);
+ DECL_TEMPLATE(linux, sys_request_key);
+ DECL_TEMPLATE(linux, sys_keyctl);
+--- valgrind/coregrind/m_syswrap/syswrap-ppc32-linux.c.jj	2009-10-27 22:07:26.000000000 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-ppc32-linux.c	2009-10-28 09:28:12.173183524 +0100
+@@ -1868,9 +1868,9 @@ const SyscallTableEntry ML_(syscall_tabl
+    //   (__NR_dup3,              sys_ni_syscall)        // 316
+    LINXY(__NR_pipe2,             sys_pipe2),            // 317
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
+-   LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 319
+-   //   (__NR_preadv,            sys_ni_syscall)        // 320
+-   //   (__NR_pwritev,           sys_ni_syscall)        // 321
++   LINXY(__NR_perf_counter_open, sys_perf_counter_open),// 319
++   LINXY(__NR_preadv,            sys_preadv),           // 320
++   LINX_(__NR_pwritev,           sys_pwritev)           // 321
+    //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 322
+ };
+ 
diff --git a/valgrind-3.5.0-stat_h.patch b/valgrind-3.5.0-stat_h.patch
new file mode 100644
index 0000000..2b9304e
--- /dev/null
+++ b/valgrind-3.5.0-stat_h.patch
@@ -0,0 +1,48 @@
+--- valgrind/include/vki/vki-amd64-linux.h.jj	2009-08-19 09:37:07.000000000 -0400
++++ valgrind/include/vki/vki-amd64-linux.h	2010-01-20 04:41:52.662552000 -0500
+@@ -310,6 +310,9 @@ struct vki_stat {
+ 	long		st_blksize;
+ 	long		st_blocks;	/* Number 512-byte blocks allocated. */
+ 
++#undef st_atime
++#undef st_mtime
++#undef st_ctime
+ 	unsigned long	st_atime;
+ 	unsigned long 	st_atime_nsec; 
+ 	unsigned long	st_mtime;
+--- valgrind/include/vki/vki-x86-linux.h.jj	2009-08-19 09:37:07.000000000 -0400
++++ valgrind/include/vki/vki-x86-linux.h	2010-01-20 04:42:19.649995000 -0500
+@@ -348,6 +348,9 @@ struct vki_stat {
+ 	unsigned long  st_size;
+ 	unsigned long  st_blksize;
+ 	unsigned long  st_blocks;
++#undef st_atime
++#undef st_mtime
++#undef st_ctime
+ 	unsigned long  st_atime;
+ 	unsigned long  st_atime_nsec;
+ 	unsigned long  st_mtime;
+--- valgrind/include/vki/vki-ppc32-linux.h.jj	2009-08-19 09:37:07.000000000 -0400
++++ valgrind/include/vki/vki-ppc32-linux.h	2010-01-20 04:42:44.861651000 -0500
+@@ -392,6 +392,9 @@ struct vki_stat {
+    long			st_size;
+    unsigned long	st_blksize;
+    unsigned long	st_blocks;
++#undef st_atime
++#undef st_mtime
++#undef st_ctime
+    unsigned long	st_atime;
+    unsigned long	st_atime_nsec;
+    unsigned long	st_mtime;
+--- valgrind/include/vki/vki-ppc64-linux.h.jj	2009-08-19 09:37:07.000000000 -0400
++++ valgrind/include/vki/vki-ppc64-linux.h	2010-01-20 04:43:05.579922000 -0500
+@@ -428,6 +428,9 @@ struct vki_stat {
+   long            st_size;
+   unsigned long   st_blksize;
+   unsigned long   st_blocks;
++#undef st_atime
++#undef st_mtime
++#undef st_ctime
+   unsigned long   st_atime;
+   unsigned long   st_atime_nsec;
+   unsigned long   st_mtime;
diff --git a/valgrind-3.5.0-syscalls.patch b/valgrind-3.5.0-syscalls.patch
new file mode 100644
index 0000000..1bdb06f
--- /dev/null
+++ b/valgrind-3.5.0-syscalls.patch
@@ -0,0 +1,240 @@
+--- valgrind/coregrind/m_syswrap/priv_syswrap-linux.h	2009-10-27 21:31:49.852433085 +0100
++++ valgrind/coregrind/m_syswrap/priv_syswrap-linux.h	2009-10-27 21:25:05.000000000 +0100
+@@ -47,6 +47,7 @@ extern SysRes ML_(do_fork_clone) ( Threa
+ DECL_TEMPLATE(linux, sys_mount);
+ DECL_TEMPLATE(linux, sys_oldumount);
+ DECL_TEMPLATE(linux, sys_umount);
++DECL_TEMPLATE(linux, sys_perf_counter_open);
+ 
+ // POSIX, but various sub-cases differ between Linux and Darwin.
+ DECL_TEMPLATE(linux, sys_fcntl);
+--- valgrind/coregrind/m_syswrap/syswrap-amd64-linux.c	2009-10-27 21:31:49.852433085 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-amd64-linux.c	2009-10-27 21:25:05.000000000 +0100
+@@ -1375,7 +1375,12 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
+    //   (__NR_dup3,              sys_ni_syscall)        // 292
+    LINXY(__NR_pipe2,             sys_pipe2),            // 293
+-   LINXY(__NR_inotify_init1,     sys_inotify_init1),     // 294
++   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
++
++   //   (__NR_preadv,            sys_ni_syscall)        // 295
++   //   (__NR_pwritev,           sys_ni_syscall)        // 296
++   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 297
++   LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 298
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+--- valgrind/coregrind/m_syswrap/syswrap-linux.c	2009-10-27 21:31:49.853433112 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-linux.c	2009-10-27 21:25:05.000000000 +0100
+@@ -2410,6 +2410,30 @@ PRE(sys_stime)
+    PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
+ }
+ 
++PRE(sys_perf_counter_open)
++{
++   PRINT("sys_perf_counter_open ( %#lx, %ld, %ld, %ld, %ld )",
++         ARG1,ARG2,ARG3,ARG4,ARG5);
++   PRE_REG_READ5(long, "perf_counter_open",
++                 struct vki_perf_counter_attr *, attr,
++                 vki_pid_t, pid, int, cpu, int, group_fd,
++                 unsigned long, flags);
++   PRE_MEM_READ( "perf_counter_open(attr)",
++                 ARG1, sizeof(struct vki_perf_counter_attr) );
++}
++
++POST(sys_perf_counter_open)
++{
++   vg_assert(SUCCESS);
++   if (!ML_(fd_allowed)(RES, "perf_counter_open", tid, True)) {
++      VG_(close)(RES);
++      SET_STATUS_Failure( VKI_EMFILE );
++   } else {
++      if (VG_(clo_track_fds))
++         ML_(record_fd_open_nameless)(tid, RES);
++   }
++}
++
+ /* ---------------------------------------------------------------------
+    utime wrapper
+    ------------------------------------------------------------------ */
+--- valgrind/coregrind/m_syswrap/syswrap-ppc32-linux.c	2009-10-27 21:31:49.855432715 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-ppc32-linux.c	2009-10-27 21:25:05.000000000 +0100
+@@ -1867,7 +1867,11 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
+    //   (__NR_dup3,              sys_ni_syscall)        // 316
+    LINXY(__NR_pipe2,             sys_pipe2),            // 317
+-   LINX_(__NR_inotify_init1,     sys_inotify_init1)     // 318
++   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
++   LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 319
++   //   (__NR_preadv,            sys_ni_syscall)        // 320
++   //   (__NR_pwritev,           sys_ni_syscall)        // 321
++   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 322
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+--- valgrind/coregrind/m_syswrap/syswrap-ppc64-linux.c	2009-10-27 21:31:49.855432715 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-ppc64-linux.c	2009-10-27 21:25:05.000000000 +0100
+@@ -1191,10 +1191,10 @@ const SyscallTableEntry ML_(syscall_tabl
+    GENX_(__NR_rename,            sys_rename),             //  38
+    GENX_(__NR_mkdir,             sys_mkdir),              //  39
+ 
+-// _____(__NR_rmdir,             sys_rmdir),              //  40
++   GENX_(__NR_rmdir,             sys_rmdir),              //  40
+    GENXY(__NR_dup,               sys_dup),                //  41
+    LINXY(__NR_pipe,              sys_pipe),               //  42
+-   GENXY(__NR_times,             sys_times),              // 43
++   GENXY(__NR_times,             sys_times),              //  43
+ // _____(__NR_prof,              sys_prof),               //  44
+ 
+    GENX_(__NR_brk,               sys_brk),                //  45
+@@ -1355,7 +1355,7 @@ const SyscallTableEntry ML_(syscall_tabl
+ 
+ // _____(__NR_rt_sigpending,     sys_rt_sigpending),      // 175
+    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),    // 176
+-// _____(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),    // 177
++   LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),    // 177
+ // _____(__NR_rt_sigsuspend,     sys_rt_sigsuspend),      // 178
+    GENXY(__NR_pread64,           sys_pread64),            // 179
+ 
+@@ -1507,7 +1507,11 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
+    //   (__NR_dup3,              sys_ni_syscall)        // 316
+    LINXY(__NR_pipe2,             sys_pipe2),            // 317
+-   LINX_(__NR_inotify_init1,     sys_inotify_init1)     // 318
++   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
++   LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 319
++   //   (__NR_preadv,            sys_ni_syscall)        // 320
++   //   (__NR_pwritev,           sys_ni_syscall)        // 321
++   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 322
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+--- valgrind/coregrind/m_syswrap/syswrap-x86-linux.c	2009-10-27 21:31:49.854432906 +0100
++++ valgrind/coregrind/m_syswrap/syswrap-x86-linux.c	2009-10-27 21:25:05.000000000 +0100
+@@ -2254,7 +2254,12 @@ const SyscallTableEntry ML_(syscall_tabl
+ 
+    //   (__NR_dup3,              sys_ni_syscall)        // 330
+    LINXY(__NR_pipe2,             sys_pipe2),            // 331
+-   LINX_(__NR_inotify_init1,     sys_inotify_init1)     // 332
++   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 332
++   //   (__NR_preadv,            sys_ni_syscall)        // 333
++   //   (__NR_pwritev,           sys_ni_syscall)        // 334
++
++   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 335
++   LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 336
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+--- valgrind/include/vki/vki-linux.h	2009-08-19 15:37:07.000000000 +0200
++++ valgrind/include/vki/vki-linux.h	2009-10-27 21:50:13.000000000 +0100
+@@ -2570,6 +2570,57 @@ struct	vki_iwreq 
+ 	union	vki_iwreq_data	u;
+ };
+ 
++/*--------------------------------------------------------------------*/
++// From linux-2.6.31.5/include/linux/perf_counter.h
++/*--------------------------------------------------------------------*/
++
++struct vki_perf_counter_attr {
++
++	/*
++	 * Major type: hardware/software/tracepoint/etc.
++	 */
++	__vki_u32			type;
++
++	/*
++	 * Size of the attr structure, for fwd/bwd compat.
++	 */
++	__vki_u32			size;
++
++	/*
++	 * Type specific configuration information.
++	 */
++	__vki_u64			config;
++
++	union {
++		__vki_u64		sample_period;
++		__vki_u64		sample_freq;
++	};
++
++	__vki_u64			sample_type;
++	__vki_u64			read_format;
++
++	__vki_u64			disabled       :  1, /* off by default        */
++					inherit	       :  1, /* children inherit it   */
++					pinned	       :  1, /* must always be on PMU */
++					exclusive      :  1, /* only group on PMU     */
++					exclude_user   :  1, /* don't count user      */
++					exclude_kernel :  1, /* ditto kernel          */
++					exclude_hv     :  1, /* ditto hypervisor      */
++					exclude_idle   :  1, /* don't count when idle */
++					mmap           :  1, /* include mmap data     */
++					comm	       :  1, /* include comm data     */
++					freq           :  1, /* use freq, not period  */
++					inherit_stat   :  1, /* per task counts       */
++					enable_on_exec :  1, /* next exec enables     */
++					task           :  1, /* trace fork/exit       */
++
++					__reserved_1   : 50;
++
++	__vki_u32			wakeup_events;	/* wakeup every n events */
++	__vki_u32			__reserved_2;
++
++	__vki_u64			__reserved_3;
++};
+ 
+ #endif // __VKI_LINUX_H
+ 
+--- valgrind/include/vki/vki-scnums-amd64-linux.h	2009-08-19 15:37:07.000000000 +0200
++++ valgrind/include/vki/vki-scnums-amd64-linux.h	2009-10-27 21:50:13.000000000 +0100
+@@ -376,6 +376,10 @@
+ #define __NR_dup3               292
+ #define __NR_pipe2              293
+ #define __NR_inotify_init1      294
++#define __NR_preadv             295
++#define __NR_pwritev            296
++#define __NR_rt_tgsigqueueinfo  297
++#define __NR_perf_counter_open  298
+ 
+ #endif /* __VKI_SCNUMS_AMD64_LINUX_H */
+ 
+--- valgrind/include/vki/vki-scnums-ppc32-linux.h	2009-08-19 15:37:07.000000000 +0200
++++ valgrind/include/vki/vki-scnums-ppc32-linux.h	2009-10-27 21:50:13.000000000 +0100
+@@ -361,6 +361,10 @@
+ #define __NR_dup3               316
+ #define __NR_pipe2              317
+ #define __NR_inotify_init1      318
++#define __NR_perf_counter_open  319
++#define __NR_preadv             320
++#define __NR_pwritev            321
++#define __NR_rt_tgsigqueueinfo  322
+ 
+ #endif /* __VKI_SCNUMS_PPC32_LINUX_H */
+ 
+--- valgrind/include/vki/vki-scnums-ppc64-linux.h	2009-08-19 15:37:07.000000000 +0200
++++ valgrind/include/vki/vki-scnums-ppc64-linux.h	2009-10-27 21:50:13.000000000 +0100
+@@ -353,6 +353,10 @@
+ #define __NR_dup3               316
+ #define __NR_pipe2              317
+ #define __NR_inotify_init1      318
++#define __NR_perf_counter_open  319
++#define __NR_preadv             320
++#define __NR_pwritev            321
++#define __NR_rt_tgsigqueueinfo  322
+ 
+ #endif /* __VKI_SCNUMS_PPC64_LINUX_H */
+ 
+diff -upr valgrind/include/vki/vki-scnums-x86-linux.h valgrind/include/vki/vki-scnums-x86-linux.h
+--- valgrind/include/vki/vki-scnums-x86-linux.h	2009-08-19 15:37:07.000000000 +0200
++++ valgrind/include/vki/vki-scnums-x86-linux.h	2009-10-27 21:50:13.000000000 +0100
+@@ -367,6 +367,10 @@
+ #define __NR_dup3               330
+ #define __NR_pipe2              331
+ #define __NR_inotify_init1      332
++#define __NR_preadv             333
++#define __NR_pwritev            334
++#define __NR_rt_tgsigqueueinfo  335
++#define __NR_perf_counter_open  336
+ 
+ #endif /* __VKI_SCNUMS_X86_LINUX_H */
+ 
diff --git a/valgrind-3.5.0-syscalls2.patch b/valgrind-3.5.0-syscalls2.patch
new file mode 100644
index 0000000..cd49889
--- /dev/null
+++ b/valgrind-3.5.0-syscalls2.patch
@@ -0,0 +1,743 @@
+--- valgrind-3.5.0/exp-ptrcheck/h_main.c.jj	2009-08-19 09:36:41.000000000 -0400
++++ valgrind-3.5.0/exp-ptrcheck/h_main.c	2009-12-02 05:39:08.460491000 -0500
+@@ -2312,6 +2312,9 @@ static void setup_post_syscall_table ( v
+       ADD(0, __NR_open);
+       ADD(0, __NR_personality);
+       ADD(0, __NR_pipe);
++#     if defined(__NR_pipe2)
++      ADD(0, __NR_pipe2);
++#     endif
+       ADD(0, __NR_poll);
+       ADD(0, __NR_prctl);
+       ADD(0, __NR_pread64);
+--- valgrind-3.5.0/include/vki/vki-scnums-amd64-linux.h.jj	2009-12-02 05:38:21.260705000 -0500
++++ valgrind-3.5.0/include/vki/vki-scnums-amd64-linux.h	2009-12-02 05:39:08.468495000 -0500
+@@ -369,7 +369,7 @@
+ #define __NR_fallocate		285
+ #define __NR_timerfd_settime	286
+ #define __NR_timerfd_gettime	287
+-#define __NR_paccept            288
++#define __NR_accept4            288
+ #define __NR_signalfd4          289
+ #define __NR_eventfd2           290
+ #define __NR_epoll_create1      291
+--- valgrind-3.5.0/include/vki/vki-linux.h.jj	2009-12-02 05:38:21.255714000 -0500
++++ valgrind-3.5.0/include/vki/vki-linux.h	2009-12-02 05:39:08.489513000 -0500
+@@ -277,14 +277,14 @@ struct vki_timex {
+ 	int  :32; int  :32; int  :32; int  :32;
+ };
+ 
+-//#define ADJ_OFFSET		0x0001	/* time offset */
+-#define ADJ_FREQUENCY		0x0002	/* frequency offset */
+-#define ADJ_MAXERROR		0x0004	/* maximum time error */
+-#define ADJ_ESTERROR		0x0008	/* estimated time error */
+-#define ADJ_STATUS		0x0010	/* clock status */
+-#define ADJ_TIMECONST		0x0020	/* pll time constant */
+-#define ADJ_TICK		0x4000	/* tick value */
+-//#define ADJ_OFFSET_SINGLESHOT	0x8001	/* old-fashioned adjtime */
++#define VKI_ADJ_OFFSET			0x0001	/* time offset */
++#define VKI_ADJ_FREQUENCY		0x0002	/* frequency offset */
++#define VKI_ADJ_MAXERROR		0x0004	/* maximum time error */
++#define VKI_ADJ_ESTERROR		0x0008	/* estimated time error */
++#define VKI_ADJ_STATUS			0x0010	/* clock status */
++#define VKI_ADJ_TIMECONST		0x0020	/* pll time constant */
++#define VKI_ADJ_TICK			0x4000	/* tick value */
++//#define VKI_ADJ_OFFSET_SINGLESHOT	0x8001	/* old-fashioned adjtime */
+ 
+ //----------------------------------------------------------------------
+ // From linux-2.6.8.1/include/linux/times.h
+@@ -525,6 +525,7 @@ typedef struct vki_sigevent {
+ #define VKI_SYS_GETSOCKOPT	15	/* sys_getsockopt(2)		*/
+ #define VKI_SYS_SENDMSG		16	/* sys_sendmsg(2)		*/
+ #define VKI_SYS_RECVMSG		17	/* sys_recvmsg(2)		*/
++#define VKI_SYS_ACCEPT4		18	/* sys_accept4(2)		*/
+ 
+ enum vki_sock_type {
+ 	VKI_SOCK_STREAM	= 1,
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc64-linux.c.jj	2009-12-02 05:38:21.300710000 -0500
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc64-linux.c	2009-12-02 05:41:28.121027000 -0500
+@@ -484,6 +484,13 @@ PRE(sys_socketcall)
+       break;
+    }
+ 
++   case VKI_SYS_ACCEPT4: {
++     /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
++      PRE_MEM_READ( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
++      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
++      break;
++   }
++
+    case VKI_SYS_SENDTO:
+      /* int sendto(int s, const void *msg, int len,
+                     unsigned int flags,
+@@ -629,7 +636,9 @@ POST(sys_socketcall)
+     break;
+ 
+   case VKI_SYS_ACCEPT:
++  case VKI_SYS_ACCEPT4:
+     /* int accept(int s, struct sockaddr *addr, int *addrlen); */
++    /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
+     r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
+ 				      ARG2_0, ARG2_1, ARG2_2 );
+     SET_STATUS_from_SysRes(r);
+@@ -1276,7 +1285,7 @@ const SyscallTableEntry ML_(syscall_tabl
+ // _____(__NR_olduname,          sys_olduname),           // 109
+ 
+ // _____(__NR_iopl,              sys_iopl),               // 110
+-// _____(__NR_vhangup,           sys_vhangup),            // 111
++   LINX_(__NR_vhangup,           sys_vhangup),            // 111
+ // _____(__NR_idle,              sys_idle),               // 112
+ // _____(__NR_vm86,              sys_vm86),               // 113
+    GENXY(__NR_wait4,             sys_wait4),              // 114
+@@ -1291,7 +1300,7 @@ const SyscallTableEntry ML_(syscall_tabl
+ // _____(__NR_setdomainname,     sys_setdomainname),      // 121
+    GENXY(__NR_uname,             sys_newuname),           // 122
+ // _____(__NR_modify_ldt,        sys_modify_ldt),         // 123
+-// _____(__NR_adjtimex,          sys_adjtimex),           // 124
++   LINXY(__NR_adjtimex,          sys_adjtimex),           // 124
+ 
+    GENXY(__NR_mprotect,          sys_mprotect),           // 125
+ // _____(__NR_sigprocmask,       sys_sigprocmask),        // 126
+@@ -1336,7 +1345,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
+ 
+    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
+-// _____(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),  // 161
++   LINXY(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161
+    GENXY(__NR_nanosleep,         sys_nanosleep),          // 162
+    GENX_(__NR_mremap,            sys_mremap),             // 163
+ // _____(__NR_setresuid,         sys_setresuid),          // 164
+@@ -1497,7 +1506,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_signalfd,          sys_signalfd),          // 305
+    LINXY(__NR_timerfd_create,    sys_timerfd_create),    // 306
+    LINX_(__NR_eventfd,           sys_eventfd),           // 307
+-//   LINX_(__NR_sync_file_range2,   sys_ni_syscall),       // 308
++   LINX_(__NR_sync_file_range2,  sys_sync_file_range2),  // 308
+    LINX_(__NR_fallocate,         sys_fallocate),         // 309
+ //   LINXY(__NR_subpage_prot,       sys_ni_syscall),       // 310
+    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 311
+@@ -1505,13 +1514,13 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_signalfd4,         sys_signalfd4),        // 313
+    LINX_(__NR_eventfd2,          sys_eventfd2),         // 314
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
+-   //   (__NR_dup3,              sys_ni_syscall)        // 316
++   LINXY(__NR_dup3,              sys_dup3),             // 316
+    LINXY(__NR_pipe2,             sys_pipe2),            // 317
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
+    LINXY(__NR_perf_counter_open, sys_perf_counter_open),// 319
+    LINXY(__NR_preadv,            sys_preadv),           // 320
+-   LINX_(__NR_pwritev,           sys_pwritev)           // 321
+-   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 322
++   LINX_(__NR_pwritev,           sys_pwritev),          // 321
++   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-linux.c.jj	2009-12-02 05:38:21.316709000 -0500
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-linux.c	2009-12-02 05:55:43.388291000 -0500
+@@ -378,8 +378,18 @@ SysRes ML_(do_fork_clone) ( ThreadId tid
+ #define PRE(name)       DEFN_PRE_TEMPLATE(linux, name)
+ #define POST(name)      DEFN_POST_TEMPLATE(linux, name)
+ 
+-// Combine two 32-bit values into a 64-bit value
+-#define LOHI64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
++// Macros to support 64-bit syscall args split into two 32 bit values
++#if defined(VG_LITTLEENDIAN)
++#define MERGE64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
++#define MERGE64_FIRST(name) name##_low
++#define MERGE64_SECOND(name) name##_high
++#elif defined(VG_BIGENDIAN)
++#define MERGE64(hi,lo)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
++#define MERGE64_FIRST(name) name##_high
++#define MERGE64_SECOND(name) name##_low
++#else
++#error Unknown endianness
++#endif
+ 
+ /* ---------------------------------------------------------------------
+    *mount wrappers
+@@ -605,34 +615,34 @@ POST(sys_llseek)
+       POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
+ }
+ 
+-//zz PRE(sys_adjtimex, 0)
+-//zz {
+-//zz    struct vki_timex *tx = (struct vki_timex *)ARG1;
+-//zz    PRINT("sys_adjtimex ( %p )", ARG1);
+-//zz    PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
+-//zz    PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
+-//zz 
+-#if 0 //zz  (avoiding warnings about multi-line comments)
+-zz #define ADJX(bit,field) 				\
+-zz    if (tx->modes & bit)					\
+-zz       PRE_MEM_READ( "adjtimex(timex->"#field")",	\
+-zz 		    (Addr)&tx->field, sizeof(tx->field))
+-#endif
+-//zz    ADJX(ADJ_FREQUENCY, freq);
+-//zz    ADJX(ADJ_MAXERROR, maxerror);
+-//zz    ADJX(ADJ_ESTERROR, esterror);
+-//zz    ADJX(ADJ_STATUS, status);
+-//zz    ADJX(ADJ_TIMECONST, constant);
+-//zz    ADJX(ADJ_TICK, tick);
+-//zz #undef ADJX
+-//zz    
+-//zz    PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
+-//zz }
+-//zz 
+-//zz POST(sys_adjtimex)
+-//zz {
+-//zz    POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
+-//zz }
++PRE(sys_adjtimex)
++{
++   struct vki_timex *tx = (struct vki_timex *)ARG1;
++   PRINT("sys_adjtimex ( %#lx )", ARG1);
++   PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
++   PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
++
++#define ADJX(bit,field) 				\
++   if (tx->modes & bit)					\
++      PRE_MEM_READ( "adjtimex(timex->"#field")",	\
++		    (Addr)&tx->field, sizeof(tx->field))
++
++   ADJX(VKI_ADJ_OFFSET, offset);
++   ADJX(VKI_ADJ_FREQUENCY, freq);
++   ADJX(VKI_ADJ_MAXERROR, maxerror);
++   ADJX(VKI_ADJ_ESTERROR, esterror);
++   ADJX(VKI_ADJ_STATUS, status);
++   ADJX(VKI_ADJ_TIMECONST, constant);
++   ADJX(VKI_ADJ_TICK, tick);
++#undef ADJX
++
++   PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
++}
++
++POST(sys_adjtimex)
++{
++   POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
++}
+ 
+ PRE(sys_ioperm)
+ {
+@@ -1167,14 +1177,24 @@ POST(sys_eventfd2)
+    }
+ }
+ 
+-// 64-bit version.
+ PRE(sys_fallocate)
+ {
+    *flags |= SfMayBlock;
++#if VG_WORDSIZE == 4
++   PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
++         ARG1, ARG2, MERGE64(ARG3,ARG4), MERGE64(ARG5,ARG6));
++   PRE_REG_READ6(long, "fallocate",
++                 int, fd, int, mode,
++                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
++                 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
++#elif VG_WORDSIZE == 8
+    PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
+          ARG1, ARG2, (Long)ARG3, (Long)ARG4);
+    PRE_REG_READ4(long, "fallocate",
+                  int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
++#else
++#  error Unexpected word size
++#endif
+    if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
+       SET_STATUS_Failure( VKI_EBADF );
+ }
+@@ -1286,19 +1306,19 @@ POST(sys_tgkill)
+ PRE(sys_fadvise64)
+ {
+    PRINT("sys_fadvise64 ( %ld, %lld, %lu, %ld )",
+-         ARG1, LOHI64(ARG2,ARG3), ARG4, ARG5);
++         ARG1, MERGE64(ARG2,ARG3), ARG4, ARG5);
+    PRE_REG_READ5(long, "fadvise64",
+-                 int, fd, vki_u32, offset_low, vki_u32, offset_high,
++                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
+                  vki_size_t, len, int, advice);
+ }
+ 
+ PRE(sys_fadvise64_64)
+ {
+    PRINT("sys_fadvise64_64 ( %ld, %lld, %lld, %ld )",
+-         ARG1, LOHI64(ARG2,ARG3), LOHI64(ARG4,ARG5), ARG6);
++         ARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), ARG6);
+    PRE_REG_READ6(long, "fadvise64_64",
+-                 int, fd, vki_u32, offset_low, vki_u32, offset_high,
+-                 vki_u32, len_low, vki_u32, len_high, int, advice);
++                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
++                 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
+ }
+ 
+ /* ---------------------------------------------------------------------
+@@ -2271,6 +2291,21 @@ PRE(sys_sched_get_priority_min)
+    PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
+ }
+ 
++PRE(sys_sched_rr_get_interval)
++{
++   PRINT("sys_sched_rr_get_interval ( %ld, %#lx )", ARG1, ARG2);
++   PRE_REG_READ2(int, "sched_rr_get_interval",
++                 vki_pid_t, pid,
++                 struct vki_timespec *, tp);
++   PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
++                 ARG2, sizeof(struct vki_timespec));
++}
++
++POST(sys_sched_rr_get_interval)
++{
++   POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
++}
++
+ PRE(sys_sched_setaffinity)
+ {
+    PRINT("sched_setaffinity ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
+@@ -2364,6 +2399,21 @@ POST(sys_pipe2)
+    }
+ }
+ 
++PRE(sys_dup3)
++{
++   PRINT("sys_dup3 ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
++   PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
++   if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
++      SET_STATUS_Failure( VKI_EBADF );
++}
++
++POST(sys_dup3)
++{
++   vg_assert(SUCCESS);
++   if (VG_(clo_track_fds))
++      ML_(record_fd_open_named)(tid, RES);
++}
++
+ PRE(sys_quotactl)
+ {
+    PRINT("sys_quotactl (0x%lx, %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3, ARG4);
+@@ -2394,15 +2444,50 @@ POST(sys_waitid)
+ PRE(sys_sync_file_range)
+ {
+    *flags |= SfMayBlock;
+-   PRINT("sys_sync_file_range ( %ld, %ld, %ld, %ld )",
+-         ARG1,ARG2,ARG3,ARG4);
++#if VG_WORDSIZE == 4
++   PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
++         ARG1,MERGE64(ARG2,ARG3),MERGE64(ARG4,ARG5),ARG6);
++   PRE_REG_READ6(long, "sync_file_range",
++                 int, fd,
++                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
++                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
++                 unsigned int, flags);
++#elif VG_WORDSIZE == 8
++   PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
++         ARG1,(Long)ARG2,(Long)ARG3,ARG4);
+    PRE_REG_READ4(long, "sync_file_range",
+                  int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
+                  unsigned int, flags);
++#else
++#  error Unexpected word size
++#endif
+    if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
+       SET_STATUS_Failure( VKI_EBADF );
+ }
+ 
++PRE(sys_sync_file_range2)
++{
++   *flags |= SfMayBlock;
++#if VG_WORDSIZE == 4
++   PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
++         ARG1,ARG2,MERGE64(ARG3,ARG4),MERGE64(ARG5,ARG6));
++   PRE_REG_READ6(long, "sync_file_range2",
++                 int, fd, unsigned int, flags,
++                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
++                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
++#elif VG_WORDSIZE == 8
++   PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
++         ARG1,ARG2,(Long)ARG3,(Long)ARG4);
++   PRE_REG_READ4(long, "sync_file_range2",
++                 int, fd, unsigned int, flags,
++                 vki_loff_t, offset, vki_loff_t, nbytes);
++#else
++#  error Unexpected word size
++#endif
++   if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
++      SET_STATUS_Failure( VKI_EBADF );
++}
++
+ PRE(sys_stime)
+ {
+    PRINT("sys_stime ( %#lx )", ARG1);
+@@ -2684,6 +2769,21 @@ POST(sys_rt_sigqueueinfo)
+       SET_STATUS_Failure( VKI_EINVAL );
+ }
+ 
++PRE(sys_rt_tgsigqueueinfo)
++{
++   PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#lx)", ARG1, ARG2, ARG3, ARG4);
++   PRE_REG_READ4(long, "rt_tgsigqueueinfo",
++                 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
++   if (ARG3 != 0)
++      PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
++}
++
++POST(sys_rt_tgsigqueueinfo)
++{
++   if (!ML_(client_signal_OK)(ARG3))
++      SET_STATUS_Failure( VKI_EINVAL );
++}
++
+ // XXX: x86-specific?  The kernel prototypes for the different archs are
+ //      hard to decipher.
+ PRE(sys_rt_sigsuspend)
+@@ -3299,9 +3399,9 @@ PRE(sys_delete_module)
+ PRE(sys_lookup_dcookie)
+ {
+    PRINT("sys_lookup_dcookie (0x%llx, %#lx, %ld)",
+-         LOHI64(ARG1,ARG2), ARG3, ARG4);
++         MERGE64(ARG1,ARG2), ARG3, ARG4);
+    PRE_REG_READ4(long, "lookup_dcookie",
+-                 vki_u32, cookie_low32, vki_u32, cookie_high32,
++                 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
+                  char *, buf, vki_size_t, len);
+    PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
+ }
+--- valgrind-3.5.0/coregrind/m_syswrap/priv_syswrap-linux.h.jj	2009-12-02 05:38:21.321704000 -0500
++++ valgrind-3.5.0/coregrind/m_syswrap/priv_syswrap-linux.h	2009-12-02 05:39:08.583466000 -0500
+@@ -165,6 +165,7 @@ DECL_TEMPLATE(linux, sys_utimensat);
+ 
+ DECL_TEMPLATE(linux, sys_preadv);
+ DECL_TEMPLATE(linux, sys_pwritev);
++DECL_TEMPLATE(linux, sys_dup3);
+ 
+ DECL_TEMPLATE(linux, sys_add_key);
+ DECL_TEMPLATE(linux, sys_request_key);
+@@ -214,7 +215,7 @@ DECL_TEMPLATE(linux, sys_sched_getschedu
+ DECL_TEMPLATE(linux, sys_sched_yield);
+ DECL_TEMPLATE(linux, sys_sched_get_priority_max);
+ DECL_TEMPLATE(linux, sys_sched_get_priority_min);
+-//DECL_TEMPLATE(linux, sys_sched_rr_get_interval);    // not yet encountered
++DECL_TEMPLATE(linux, sys_sched_rr_get_interval);
+ DECL_TEMPLATE(linux, sys_sched_setaffinity);
+ DECL_TEMPLATE(linux, sys_sched_getaffinity);
+ 
+@@ -242,10 +243,12 @@ DECL_TEMPLATE(linux, sys_rt_sigprocmask)
+ DECL_TEMPLATE(linux, sys_rt_sigpending);
+ DECL_TEMPLATE(linux, sys_rt_sigtimedwait);
+ DECL_TEMPLATE(linux, sys_rt_sigqueueinfo);
++DECL_TEMPLATE(linux, sys_rt_tgsigqueueinfo);
+ DECL_TEMPLATE(linux, sys_rt_sigsuspend);
+ 
+ // Linux-specific?
+ DECL_TEMPLATE(linux, sys_sync_file_range);
++DECL_TEMPLATE(linux, sys_sync_file_range2);
+ DECL_TEMPLATE(linux, sys_stime);  /* maybe generic?  I'm not sure */
+ 
+ // Linux specific (kernel modules)
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-amd64-linux.c.jj	2009-12-02 05:38:21.283699000 -0500
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-amd64-linux.c	2009-12-02 05:39:08.602453000 -0500
+@@ -349,6 +349,7 @@ DECL_TEMPLATE(amd64_linux, sys_setsockop
+ DECL_TEMPLATE(amd64_linux, sys_getsockopt);
+ DECL_TEMPLATE(amd64_linux, sys_connect);
+ DECL_TEMPLATE(amd64_linux, sys_accept);
++DECL_TEMPLATE(amd64_linux, sys_accept4);
+ DECL_TEMPLATE(amd64_linux, sys_sendto);
+ DECL_TEMPLATE(amd64_linux, sys_recvfrom);
+ DECL_TEMPLATE(amd64_linux, sys_sendmsg);
+@@ -684,6 +685,23 @@ POST(sys_accept)
+    SET_STATUS_from_SysRes(r);
+ }
+ 
++PRE(sys_accept4)
++{
++   *flags |= SfMayBlock;
++   PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
++   PRE_REG_READ4(long, "accept4",
++                 int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
++   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
++}
++POST(sys_accept4)
++{
++   SysRes r;
++   vg_assert(SUCCESS);
++   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
++                                         ARG1,ARG2,ARG3);
++   SET_STATUS_from_SysRes(r);
++}
++
+ PRE(sys_sendto)
+ {
+    *flags |= SfMayBlock;
+@@ -1200,20 +1218,20 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145 
+    LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146 
+    LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147 
+-   //LINX?(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148 
++   LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148 
+    GENX_(__NR_mlock,                   sys_mlock),                   // 149 
+ 
+    GENX_(__NR_munlock,           sys_munlock),        // 150 
+    GENX_(__NR_mlockall,          sys_mlockall),       // 151 
+    LINX_(__NR_munlockall,        sys_munlockall),     // 152 
+-   //   (__NR_vhangup,           sys_vhangup),        // 153 
++   LINX_(__NR_vhangup,           sys_vhangup),        // 153 
+    //   (__NR_modify_ldt,        sys_modify_ldt),     // 154 
+ 
+    //   (__NR_pivot_root,        sys_pivot_root),     // 155 
+    LINXY(__NR__sysctl,           sys_sysctl),         // 156 
+    LINXY(__NR_prctl,             sys_prctl),          // 157 
+    PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158 
+-   //   (__NR_adjtimex,          sys_adjtimex),       // 159 
++   LINXY(__NR_adjtimex,          sys_adjtimex),       // 159 
+ 
+    GENX_(__NR_setrlimit,         sys_setrlimit),      // 160 
+    GENX_(__NR_chroot,            sys_chroot),         // 161 
+@@ -1368,18 +1386,18 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_fallocate,         sys_fallocate),        // 285
+    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
+    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
+-   //   (__NR_paccept,           sys_ni_syscall)        // 288
++   PLAXY(__NR_accept4,           sys_accept4),          // 288
+    LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
+ 
+    LINX_(__NR_eventfd2,          sys_eventfd2),         // 290
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
+-   //   (__NR_dup3,              sys_ni_syscall)        // 292
++   LINXY(__NR_dup3,              sys_dup3),             // 292
+    LINXY(__NR_pipe2,             sys_pipe2),            // 293
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
+ 
+    LINXY(__NR_preadv,            sys_preadv),           // 295
+    LINX_(__NR_pwritev,           sys_pwritev),          // 296
+-   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 297
++   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
+    LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 298
+ };
+ 
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-generic.c.jj	2009-08-19 09:37:42.000000000 -0400
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-generic.c	2009-12-02 05:39:08.627429000 -0500
+@@ -2091,11 +2091,17 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid
+ #define PRE(name)      DEFN_PRE_TEMPLATE(generic, name)
+ #define POST(name)     DEFN_POST_TEMPLATE(generic, name)
+ 
+-#if VG_WORDSIZE == 4
+-// Combine two 32-bit values into a 64-bit value
+-// Always use with low-numbered arg first (e.g. LOHI64(ARG1,ARG2) )
+-// GrP fixme correct for ppc-linux?
+-#define LOHI64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
++// Macros to support 64-bit syscall args split into two 32 bit values
++#if defined(VG_LITTLEENDIAN)
++#define MERGE64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
++#define MERGE64_FIRST(name) name##_low
++#define MERGE64_SECOND(name) name##_high
++#elif defined(VG_BIGENDIAN)
++#define MERGE64(hi,lo)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
++#define MERGE64_FIRST(name) name##_high
++#define MERGE64_SECOND(name) name##_low
++#else
++#error Unknown endianness
+ #endif
+ 
+ PRE(sys_exit)
+@@ -2346,10 +2352,10 @@ PRE(sys_pwrite64)
+    *flags |= SfMayBlock;
+ #if VG_WORDSIZE == 4
+    PRINT("sys_pwrite64 ( %ld, %#lx, %llu, %lld )",
+-         ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
++         ARG1, ARG2, (ULong)ARG3, MERGE64(ARG4,ARG5));
+    PRE_REG_READ5(ssize_t, "pwrite64",
+                  unsigned int, fd, const char *, buf, vki_size_t, count,
+-                 vki_u32, offset_low32, vki_u32, offset_high32);
++                 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
+ #elif VG_WORDSIZE == 8
+    PRINT("sys_pwrite64 ( %ld, %#lx, %llu, %lld )",
+          ARG1, ARG2, (ULong)ARG3, (Long)ARG4);
+@@ -2405,10 +2411,10 @@ PRE(sys_pread64)
+    *flags |= SfMayBlock;
+ #if VG_WORDSIZE == 4
+    PRINT("sys_pread64 ( %ld, %#lx, %llu, %lld )",
+-         ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
++         ARG1, ARG2, (ULong)ARG3, MERGE64(ARG4,ARG5));
+    PRE_REG_READ5(ssize_t, "pread64",
+                  unsigned int, fd, char *, buf, vki_size_t, count,
+-                 vki_u32, offset_low32, vki_u32, offset_high32);
++                 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
+ #elif VG_WORDSIZE == 8
+    PRINT("sys_pread64 ( %ld, %#lx, %llu, %lld )",
+          ARG1, ARG2, (ULong)ARG3, (Long)ARG4);
+@@ -2966,10 +2972,10 @@ PRE(sys_ftruncate64)
+ {
+    *flags |= SfMayBlock;
+ #if VG_WORDSIZE == 4
+-   PRINT("sys_ftruncate64 ( %ld, %lld )", ARG1, LOHI64(ARG2,ARG3));
++   PRINT("sys_ftruncate64 ( %ld, %lld )", ARG1, MERGE64(ARG2,ARG3));
+    PRE_REG_READ3(long, "ftruncate64",
+                  unsigned int, fd,
+-                 UWord, length_low32, UWord, length_high32);
++                 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
+ #else
+    PRINT("sys_ftruncate64 ( %ld, %lld )", ARG1, (Long)ARG2);
+    PRE_REG_READ2(long, "ftruncate64",
+@@ -2981,10 +2987,10 @@ PRE(sys_truncate64)
+ {
+    *flags |= SfMayBlock;
+ #if VG_WORDSIZE == 4
+-   PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)LOHI64(ARG2, ARG3));
++   PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)MERGE64(ARG2, ARG3));
+    PRE_REG_READ3(long, "truncate64",
+                  const char *, path,
+-                 UWord, length_low32, UWord, length_high32);
++                 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
+ #else
+    PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)ARG2);
+    PRE_REG_READ2(long, "truncate64",
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-x86-linux.c.jj	2009-12-02 05:38:21.292713000 -0500
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-x86-linux.c	2009-12-02 05:39:08.655406000 -0500
+@@ -1475,6 +1475,13 @@ PRE(sys_socketcall)
+       break;
+    }
+ 
++   case VKI_SYS_ACCEPT4: {
++      /*int accept(int s, struct sockaddr *add, int *addrlen, int flags)*/
++      PRE_MEM_READ( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
++      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
++      break;
++   }
++
+    case VKI_SYS_SENDTO:
+       /* int sendto(int s, const void *msg, int len, 
+                     unsigned int flags, 
+@@ -1620,7 +1627,9 @@ POST(sys_socketcall)
+       break;
+ 
+    case VKI_SYS_ACCEPT:
++   case VKI_SYS_ACCEPT4:
+       /* int accept(int s, struct sockaddr *addr, int *addrlen); */
++      /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
+      r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES), 
+                                             ARG2_0, ARG2_1, ARG2_2 );
+      SET_STATUS_from_SysRes(r);
+@@ -2001,8 +2010,8 @@ const SyscallTableEntry ML_(syscall_tabl
+ //zz    //   (__NR_setdomainname,     sys_setdomainname),  // 121 */*(?)
+    GENXY(__NR_uname,             sys_newuname),       // 122
+    PLAX_(__NR_modify_ldt,        sys_modify_ldt),     // 123
+-//zz    LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
+-//zz 
++   LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
++
+    GENXY(__NR_mprotect,          sys_mprotect),       // 125
+    LINXY(__NR_sigprocmask,       sys_sigprocmask),    // 126
+ //zz    // Nb: create_module() was removed 2.4-->2.6
+@@ -2048,7 +2057,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
+ 
+    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
+-//zz    //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
++   LINXY(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161
+    GENXY(__NR_nanosleep,         sys_nanosleep),      // 162
+    GENX_(__NR_mremap,            sys_mremap),         // 163
+    LINX_(__NR_setresuid,         sys_setresuid16),    // 164
+@@ -2244,7 +2253,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_signalfd,          sys_signalfd),         // 321
+    LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 322
+    LINX_(__NR_eventfd,           sys_eventfd),          // 323
+-   //LINX_(__NR_fallocate,         sys_fallocate),        // 324
++   LINX_(__NR_fallocate,         sys_fallocate),        // 324
+ 
+    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 325
+    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 326
+@@ -2252,13 +2261,13 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_eventfd2,          sys_eventfd2),         // 328
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),     // 329
+ 
+-   //   (__NR_dup3,              sys_ni_syscall)        // 330
++   LINXY(__NR_dup3,              sys_dup3),             // 330
+    LINXY(__NR_pipe2,             sys_pipe2),            // 331
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 332
+    LINXY(__NR_preadv,            sys_preadv),           // 333
+    LINX_(__NR_pwritev,           sys_pwritev),          // 334
+ 
+-   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 335
++   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 335
+    LINXY(__NR_perf_counter_open, sys_perf_counter_open) // 336
+ };
+ 
+--- valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc32-linux.c.jj	2009-12-02 05:38:21.331695000 -0500
++++ valgrind-3.5.0/coregrind/m_syswrap/syswrap-ppc32-linux.c	2009-12-02 05:43:30.802905000 -0500
+@@ -457,6 +457,13 @@ PRE(sys_socketcall)
+       break;
+    }
+ 
++   case VKI_SYS_ACCEPT4: {
++     /* int accept(int s, struct sockaddr *addr, int *addrlen, int args); */
++      PRE_MEM_READ( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
++      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
++      break;
++   }
++
+    case VKI_SYS_SENDTO:
+      /* int sendto(int s, const void *msg, int len,
+                     unsigned int flags,
+@@ -602,6 +609,7 @@ POST(sys_socketcall)
+     break;
+ 
+   case VKI_SYS_ACCEPT:
++  case VKI_SYS_ACCEPT4:
+     /* int accept(int s, struct sockaddr *addr, int *addrlen); */
+     r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
+ 				      ARG2_0, ARG2_1, ARG2_2 );
+@@ -1629,7 +1637,7 @@ const SyscallTableEntry ML_(syscall_tabl
+ //..    //   (__NR_olduname,          sys_uname),             // 109 -- obsolete
+ //.. 
+ //..    GENX_(__NR_iopl,              sys_iopl),              // 110
+-//..    LINX_(__NR_vhangup,           sys_vhangup),           // 111
++   LINX_(__NR_vhangup,           sys_vhangup),           // 111
+ //..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
+ //..    //   (__NR_vm86old,           sys_vm86old),           // 113 x86/Linux-only
+    GENXY(__NR_wait4,             sys_wait4),             // 114
+@@ -1644,8 +1652,8 @@ const SyscallTableEntry ML_(syscall_tabl
+ //..    //   (__NR_setdomainname,     sys_setdomainname),     // 121 */*(?)
+    GENXY(__NR_uname,             sys_newuname),          // 122
+ //..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
+-//..    LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
+-//.. 
++   LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
++
+    GENXY(__NR_mprotect,          sys_mprotect),          // 125
+    LINXY(__NR_sigprocmask,       sys_sigprocmask),       // 126
+    GENX_(__NR_create_module,     sys_ni_syscall),        // 127
+@@ -1690,7 +1698,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
+ 
+    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
+-//..    //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
++   LINXY(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161
+    GENXY(__NR_nanosleep,         sys_nanosleep),         // 162
+    GENX_(__NR_mremap,            sys_mremap),            // 163
+    LINX_(__NR_setresuid,         sys_setresuid),         // 164
+@@ -1857,21 +1865,21 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINXY(__NR_signalfd,          sys_signalfd),          // 305
+    LINXY(__NR_timerfd_create,    sys_timerfd_create),    // 306
+    LINX_(__NR_eventfd,           sys_eventfd),           // 307
+-//   LINX_(__NR_sync_file_range2,   sys_ni_syscall),       // 308
+-//   LINX_(__NR_fallocate,         sys_fallocate),         // 309
++   LINX_(__NR_sync_file_range2,  sys_sync_file_range2),  // 308
++   LINX_(__NR_fallocate,         sys_fallocate),         // 309
+ //   LINXY(__NR_subpage_prot,       sys_ni_syscall),       // 310
+    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 311
+    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 312
+    LINXY(__NR_signalfd4,         sys_signalfd4),        // 313
+    LINX_(__NR_eventfd2,          sys_eventfd2),         // 314
+    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
+-   //   (__NR_dup3,              sys_ni_syscall)        // 316
++   LINXY(__NR_dup3,              sys_dup3),             // 316
+    LINXY(__NR_pipe2,             sys_pipe2),            // 317
+    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
+    LINXY(__NR_perf_counter_open, sys_perf_counter_open),// 319
+    LINXY(__NR_preadv,            sys_preadv),           // 320
+-   LINX_(__NR_pwritev,           sys_pwritev)           // 321
+-   //   (__NR_rt_tgsigqueueinfo, sys_ni_syscall)        // 322
++   LINX_(__NR_pwritev,           sys_pwritev),          // 321
++   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
+ };
+ 
+ const UInt ML_(syscall_table_size) = 
diff --git a/valgrind-3.5.0-syscalls3.patch b/valgrind-3.5.0-syscalls3.patch
new file mode 100644
index 0000000..07cdc47
--- /dev/null
+++ b/valgrind-3.5.0-syscalls3.patch
@@ -0,0 +1,142 @@
+--- valgrind/coregrind/m_syswrap/syswrap-linux.c	(revision 10964)
++++ valgrind/coregrind/m_syswrap/syswrap-linux.c	(revision 11100)
+@@ -2567,6 +2588,29 @@ POST(sys_perf_counter_open)
+    }
+ }
+ 
++PRE(sys_getcpu)
++{
++   PRINT("sys_getcpu ( %#lx, %#lx, %#lx )" , ARG1,ARG2,ARG3);
++   PRE_REG_READ3(int, "getcpu", 
++                 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
++   if (ARG1 != 0)
++      PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
++   if (ARG2 != 0)
++      PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
++   if (ARG3 != 0)
++      PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
++}
++
++POST(sys_getcpu)
++{
++   if (ARG1 != 0)
++      POST_MEM_WRITE( ARG1, sizeof(unsigned) );
++   if (ARG2 != 0)
++      POST_MEM_WRITE( ARG2, sizeof(unsigned) );
++   if (ARG3 != 0)
++      POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
++}
++
+ /* ---------------------------------------------------------------------
+    utime wrapper
+    ------------------------------------------------------------------ */
+@@ -3453,6 +3497,30 @@ PRE(sys_delete_module)
+ }
+ 
+ /* ---------------------------------------------------------------------
++   splice wrappers
++   ------------------------------------------------------------------ */
++
++PRE(sys_splice)
++{
++   *flags |= SfMayBlock;
++   PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %ld, %ld )",
++         ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
++   PRE_REG_READ6(int32_t, "splice",
++                 int, fd_in, vki_loff_t *, off_in,
++                 int, fd_out, vki_loff_t *, off_out,
++                 vki_size_t, len, unsigned int, flags);
++   if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
++       !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
++      SET_STATUS_Failure( VKI_EBADF );
++   } else {
++      if (ARG2 != 0)
++         PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
++      if (ARG4 != 0)
++         PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
++   }
++}
++
++/* ---------------------------------------------------------------------
+    oprofile-related wrappers
+    ------------------------------------------------------------------ */
+ 
+--- valgrind/coregrind/m_syswrap/priv_syswrap-linux.h	(revision 10964)
++++ valgrind/coregrind/m_syswrap/priv_syswrap-linux.h	(revision 11100)
+@@ -166,6 +166,8 @@ DECL_TEMPLATE(linux, sys_utimensat);
+ DECL_TEMPLATE(linux, sys_preadv);
+ DECL_TEMPLATE(linux, sys_pwritev);
+ DECL_TEMPLATE(linux, sys_dup3);
++DECL_TEMPLATE(linux, sys_getcpu);
++DECL_TEMPLATE(linux, sys_splice);
+ 
+ DECL_TEMPLATE(linux, sys_add_key);
+ DECL_TEMPLATE(linux, sys_request_key);
+--- valgrind/coregrind/m_syswrap/syswrap-amd64-linux.c	(revision 10964)
++++ valgrind/coregrind/m_syswrap/syswrap-amd64-linux.c	(revision 11100)
+@@ -1371,7 +1382,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
+    LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
+ 
+-//   LINX_(__NR_splice,            sys_ni_syscall),       // 275
++   LINX_(__NR_splice,            sys_splice),           // 275
+ //   LINX_(__NR_tee,               sys_ni_syscall),       // 276
+    LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
+ //   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 278
+--- valgrind/coregrind/m_syswrap/syswrap-x86-linux.c	(revision 10964)
++++ valgrind/coregrind/m_syswrap/syswrap-x86-linux.c	(revision 11100)
+@@ -2240,13 +2251,13 @@ const SyscallTableEntry ML_(syscall_tabl
+ //   LINX_(__NR_unshare,		 sys_unshare),          // 310
+    LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 311
+    LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 312
+-//   LINX_(__NR_splice,            sys_ni_syscall),       // 313
++   LINX_(__NR_splice,            sys_splice),           // 313
+    LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 314
+ 
+ //   LINX_(__NR_tee,               sys_ni_syscall),       // 315
+ //   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 316
+ //   LINX_(__NR_move_pages,        sys_ni_syscall),       // 317
+-//   LINX_(__NR_getcpu,            sys_ni_syscall),       // 318
++   LINXY(__NR_getcpu,            sys_getcpu),           // 318
+    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 319
+ 
+    LINX_(__NR_utimensat,         sys_utimensat),        // 320
+--- valgrind/coregrind/m_syswrap/syswrap-ppc32-linux.c	(revision 10964)
++++ valgrind/coregrind/m_syswrap/syswrap-ppc32-linux.c	(revision 11100)
+@@ -1859,7 +1870,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_set_robust_list,   sys_set_robust_list),   // 299
+    LINXY(__NR_get_robust_list,   sys_get_robust_list),   // 300
+ //   LINX_(__NR_move_pages,        sys_ni_syscall),        // 301
+-//   LINX_(__NR_getcpu,            sys_ni_syscall),        // 302
++   LINXY(__NR_getcpu,            sys_getcpu),            // 302
+    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
+    LINX_(__NR_utimensat,         sys_utimensat),         // 304
+    LINXY(__NR_signalfd,          sys_signalfd),          // 305
+--- valgrind/coregrind/m_syswrap/syswrap-ppc64-linux.c	(revision 10964)
++++ valgrind/coregrind/m_syswrap/syswrap-ppc64-linux.c	(revision 11100)
+@@ -1500,7 +1511,7 @@ const SyscallTableEntry ML_(syscall_tabl
+    LINX_(__NR_set_robust_list,   sys_set_robust_list),    // 299
+    LINXY(__NR_get_robust_list,   sys_get_robust_list),    // 300
+ //   LINX_(__NR_move_pages,        sys_ni_syscall),        // 301
+-//   LINX_(__NR_getcpu,            sys_ni_syscall),        // 302
++   LINXY(__NR_getcpu,            sys_getcpu),            // 302
+    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
+    LINX_(__NR_utimensat,         sys_utimensat),         // 304
+    LINXY(__NR_signalfd,          sys_signalfd),          // 305
+--- valgrind/include/vki/vki-linux.h	(revision 10964)
++++ valgrind/include/vki/vki-linux.h	(revision 11100)
+@@ -2627,6 +2635,14 @@ struct vki_perf_counter_attr {
+ 	__vki_u64			__reserved_3;
+ };
+ 
++/*--------------------------------------------------------------------*/
++// From linux-2.6.32.4/include/linux/getcpu.h
++/*--------------------------------------------------------------------*/
++
++struct vki_getcpu_cache {
++	unsigned long blob[128 / sizeof(long)];
++};
++
+ #endif // __VKI_LINUX_H
+ 
+ /*--------------------------------------------------------------------*/
diff --git a/valgrind.spec b/valgrind.spec
index 7ea0243..2188bef 100644
--- a/valgrind.spec
+++ b/valgrind.spec
@@ -1,12 +1,34 @@
 Summary: Tool for finding memory management bugs in programs
 Name: valgrind
 Version: 3.5.0
-Release: 1
+Release: 15%{?dist}
 Epoch: 1
 Source0: http://www.valgrind.org/downloads/valgrind-%{version}.tar.bz2
 Patch1: valgrind-3.5.0-cachegrind-improvements.patch
 Patch2: valgrind-3.5.0-openat.patch
 Patch3: valgrind-3.5.0-glibc-2.10.1.patch
+Patch4: valgrind-3.5.0-ifunc.patch
+Patch5: valgrind-3.5.0-inotify-init1.patch
+Patch6: valgrind-3.5.0-mmap-mprotect.patch
+Patch7: valgrind-3.5.0-dwarf3.patch
+Patch8: valgrind-3.5.0-pr40659.patch
+Patch9: valgrind-3.5.0-helgrind-race-supp.patch
+Patch10: valgrind-3.5.0-ppc-tests.patch
+Patch11: valgrind-3.5.0-amd64-loopnel.patch
+Patch12: valgrind-3.5.0-ppc-dwarf3.patch
+Patch13: valgrind-3.5.0-amd64-adcsbb.patch
+Patch14: valgrind-3.5.0-syscalls.patch
+Patch15: valgrind-3.5.0-preadv.patch
+Patch16: valgrind-3.5.0-glibc-2.11.patch
+Patch17: valgrind-3.5.0-syscalls2.patch
+Patch18: valgrind-3.5.0-dynbss.patch
+Patch19: valgrind-3.5.0-adjtimex.patch
+Patch20: valgrind-3.5.0-DW_OP_mod.patch
+Patch21: valgrind-3.5.0-pkgconfig.patch
+Patch22: valgrind-3.5.0-stat_h.patch
+Patch23: valgrind-3.5.0-i686-nops.patch
+Patch24: valgrind-3.5.0-dwarf4.patch
+Patch25: valgrind-3.5.0-syscalls3.patch
 License: GPLv2
 URL: http://www.valgrind.org/
 Group: Development/Debuggers
@@ -16,7 +38,7 @@ Obsoletes: valgrind-callgrind
 # Ensure glibc{,-devel} is installed for both multilib arches
 BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so
 %endif
-BuildRequires: glibc-devel >= 2.10
+BuildRequires: glibc-devel >= 2.11
 ExclusiveArch: %{ix86} x86_64 ppc ppc64
 %ifarch %{ix86}
 %define valarch x86
@@ -63,13 +85,35 @@ or valgrind plugins.
 %patch1 -p1
 %patch2 -p1
 %patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
 
 %build
 %ifarch x86_64 ppc64
 # Ugly hack - libgcc 32-bit package might not be installed
 mkdir -p libgcc/32
-touch libgcc/32/libgcc_s.a
-touch libgcc/libgcc_s_32.a
+ar r libgcc/32/libgcc_s.a
+ar r libgcc/libgcc_s_32.a
 %configure CC="gcc -B `pwd`/libgcc/" GDB=%{_bindir}/gdb
 %else
 %configure GDB=%{_bindir}/gdb
@@ -95,13 +139,6 @@ int main (int argc, char *const argv[])
 EOF
 gcc $RPM_OPT_FLAGS -o close_fds close_fds.c
 
-for i in `find . -type f \( -name *-amd64-linux -o -name *-x86-linux -o -name *-ppc*-linux \)`; do
-  case "`file $i`" in
-    *ELF*executable*statically\ linked*)
-      objcopy -R .debug_loc -R .debug_frame -R .debug_ranges $i
-  esac
-done
-
 # XXX pth_cancel2 hangs on x86_64
 echo 'int main (void) { return 0; }' > none/tests/pth_cancel2.c
 
@@ -155,6 +192,61 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/pkgconfig/*
 
 %changelog
+* Wed Apr  7 2010 Jakub Jelinek <jakub@redhat.com> 3.5.0-15
+- handle i686 nopw insns with more than one data16 prefix (#574889)
+- DWARF4 support
+- handle getcpu and splice syscalls
+
+* Wed Jan 20 2010 Jakub Jelinek <jakub@redhat.com> 3.5.0-14
+- fix build against latest glibc headers
+
+* Wed Jan 20 2010 Jakub Jelinek <jakub@redhat.com> 3.5.0-13
+- DW_OP_mod is unsigned modulus instead of signed
+- fix up valgrind.pc (#551277)
+
+* Mon Dec 21 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-12
+- don't require offset field to be set in adjtimex's
+  ADJ_OFFSET_SS_READ mode (#545866)
+
+* Wed Dec  2 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-10
+- add handling of a bunch of recent syscalls and fix some
+  other syscall wrappers (Dodji Seketeli)
+- handle prelink created split of .bss into .dynbss and .bss
+  and similarly for .sbss and .sdynbss (#539874)
+
+* Wed Nov  4 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-9
+- rebuilt against glibc 2.11
+- use upstream version of the ifunc support
+
+* Wed Oct 28 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-8
+- add preadv/pwritev syscall support
+
+* Tue Oct 27 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-7
+- add perf_counter_open syscall support (#531271)
+- add handling of some sbb/adc insn forms on x86_64 (KDE#211410)
+
+* Fri Oct 23 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-6
+- ppc and ppc64 fixes
+
+* Thu Oct 22 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-5
+- add emulation of 0x67 prefixed loop* insns on x86_64 (#530165)
+
+* Wed Oct 21 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-4
+- handle reading of .debug_frame in addition to .eh_frame
+- ignore unknown DWARF3 expressions in evaluate_trivial_GX
+- suppress helgrind race errors in helgrind's own mythread_wrapper
+- fix compilation of x86 tests on x86_64 and ppc tests
+
+* Wed Oct 14 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-3
+- handle many more DW_OP_* ops that GCC now uses
+- handle the more compact form of DW_AT_data_member_location
+- don't strip .debug_loc etc. from valgrind binaries
+
+* Mon Oct 12 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-2
+- add STT_GNU_IFUNC support (Dodji Seketeli, #518247)
+- wrap inotify_init1 syscall (Dodji Seketeli, #527198)
+- fix mmap/mprotect handling in memcheck (KDE#210268)
+
 * Fri Aug 21 2009 Jakub Jelinek <jakub@redhat.com> 3.5.0-1
 - update to 3.5.0