Dual architecture support - this commit is a major rework of the build
system that allows multiple copies of valgrind to be built so that we
can build both x86 and amd64 versions of the tools on amd64 machines.

The launcher is then modified to look at the program being run and
decide which tool to use to run it.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5027 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/Makefile.am b/Makefile.am
index 2f95718..6a0e9cd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,10 +31,23 @@
 incincdir = $(includedir)/valgrind
 nodist_incinc_HEADERS = $(VEX_PUBLIC_HDRS)
 
-BUILT_SOURCES  = default.supp valgrind.pc valt_load_address.lds
-CLEANFILES     = valt_load_address.lds
+BUILT_SOURCES  = default.supp valgrind.pc
+CLEANFILES     = 
 DISTCLEANFILES = default.supp
 
+if VG_X86_LINUX
+BUILT_SOURCES += valt_load_address_x86_linux.lds
+CLEANFILES += valt_load_address_x86_linux.lds
+endif
+if VG_AMD64_LINUX
+BUILT_SOURCES += valt_load_address_amd64_linux.lds
+CLEANFILES += valt_load_address_amd64_linux.lds
+endif
+if VG_PPC32_LINUX
+BUILT_SOURCES += valt_load_address_ppc32_linux.lds
+CLEANFILES += valt_load_address_ppc32_linux.lds
+endif
+
 default.supp: $(SUPP_FILES)
 
 ## Preprend @PERL@ because tests/vg_regtest isn't executable
@@ -161,10 +174,23 @@
 #
 # So we search for the line with a hex value "+ SIZEOF_HEADERS", and replace
 # all the hex values in that line with "valt_load_address".
-valt_load_address.lds: Makefile
-	$(CC) -Wl,--verbose -nostdlib 2>&1 | sed \
+valt_load_address_x86_linux.lds: Makefile
+	$(CC) @FLAG_M32@ -Wl,--verbose -nostdlib 2>&1 | sed \
 		-e '1,/^=====\+$$/d' \
 		-e '/^=====\+$$/d' \
 		-e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \
 	|| rm -f $@
 
+valt_load_address_amd64_linux.lds: Makefile
+	$(CC) -m64 -Wl,--verbose -nostdlib 2>&1 | sed \
+		-e '1,/^=====\+$$/d' \
+		-e '/^=====\+$$/d' \
+		-e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \
+	|| rm -f $@
+
+valt_load_address_ppc32_linux.lds: Makefile
+	$(CC) -Wl,--verbose -nostdlib 2>&1 | sed \
+		-e '1,/^=====\+$$/d' \
+		-e '/^=====\+$$/d' \
+		-e '/\. = 0x[0-9A-Fa-f]\+ + SIZEOF_HEADERS/s/0x[0-9A-Fa-f]\+/valt_load_address/g' > $@ \
+	|| rm -f $@
diff --git a/Makefile.core.am b/Makefile.core.am
index 1859e0c..69ca62e 100644
--- a/Makefile.core.am
+++ b/Makefile.core.am
@@ -1,19 +1,42 @@
-add_includes = -I$(top_srcdir)/coregrind \
+add_includes_x86_linux = -I$(top_srcdir)/coregrind \
 		-I$(top_srcdir) \
-		-I$(top_srcdir)/coregrind/$(VG_ARCH) \
-		-I$(top_srcdir)/coregrind/$(VG_OS) \
-		-I$(top_srcdir)/coregrind/$(VG_PLATFORM) \
+		-I$(top_srcdir)/coregrind/x86 \
+		-I$(top_srcdir)/coregrind/linux \
+		-I$(top_srcdir)/coregrind/x86-linux \
 		-I$(top_srcdir)/include \
 		-I@VEX_DIR@/pub \
-		-DVGA_$(VG_ARCH)=1 \
-		-DVGO_$(VG_OS)=1 \
-		-DVGP_$(VG_ARCH)_$(VG_OS)=1
+		-DVG_PLATFORM="\"x86-linux\"" \
+		-DVGA_x86=1 \
+		-DVGO_linux=1 \
+		-DVGP_x86_linux=1
 
-BASE_AM_CFLAGS = @ARCH_CORE_AM_CFLAGS@ -Wmissing-prototypes -Winline -Wall -Wshadow -O -g
+add_includes_amd64_linux = -I$(top_srcdir)/coregrind \
+		-I$(top_srcdir) \
+		-I$(top_srcdir)/coregrind/amd64 \
+		-I$(top_srcdir)/coregrind/linux \
+		-I$(top_srcdir)/coregrind/amd64-linux \
+		-I$(top_srcdir)/include \
+		-I@VEX_DIR@/pub \
+		-DVG_PLATFORM="\"amd64-linux\"" \
+		-DVGA_amd64=1 \
+		-DVGO_linux=1 \
+		-DVGP_amd64_linux=1
 
-PIC_AM_CFLAGS = $(BASE_AM_CFLAGS) -fpic -fno-omit-frame-pointer
+add_includes_ppc32_linux = -I$(top_srcdir)/coregrind \
+		-I$(top_srcdir) \
+		-I$(top_srcdir)/coregrind/ppc32 \
+		-I$(top_srcdir)/coregrind/linux \
+		-I$(top_srcdir)/coregrind/ppc32-linux \
+		-I$(top_srcdir)/include \
+		-I@VEX_DIR@/pub \
+		-DVG_PLATFORM="\"ppc32-linux\"" \
+		-DVGA_ppc32=1 \
+		-DVGO_linux=1 \
+		-DVGP_ppc32_linux=1
 
-AM_CPPFLAGS = $(add_includes)
-AM_CFLAGS = $(WERROR) $(BASE_AM_CFLAGS)
-AM_CCASFLAGS = $(add_includes) @ARCH_CORE_AM_CCASFLAGS@ -Wa,-gstabs
+include $(top_srcdir)/Makefile.flags.am
 
+PRELOAD_LDFLAGS_COMMON = -shared -Wl,-z,interpose,-z,initfirst
+PRELOAD_LDFLAGS_X86_LINUX = $(PRELOAD_LDFLAGS_COMMON) @FLAG_M32@
+PRELOAD_LDFLAGS_AMD64_LINUX = $(PRELOAD_LDFLAGS_COMMON) -m64
+PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON)
diff --git a/Makefile.flags.am b/Makefile.flags.am
new file mode 100644
index 0000000..283fa38
--- /dev/null
+++ b/Makefile.flags.am
@@ -0,0 +1,21 @@
+AM_CFLAGS_BASE = -Wmissing-prototypes -Winline -Wall -Wshadow -O -g
+
+AM_CFLAGS_PIC = -fpic -fno-omit-frame-pointer
+
+AM_CPPFLAGS_X86_LINUX = $(add_includes_x86_linux)
+AM_CFLAGS_X86_LINUX = $(WERROR) @FLAG_M32@ @PREFERRED_STACK_BOUNDARY@ $(AM_CFLAGS_BASE)
+AM_CCASFLAGS_X86_LINUX = $(add_includes_x86_linux) @FLAG_M32@ -g
+
+AM_CPPFLAGS_AMD64_LINUX = $(add_includes_amd64_linux)
+AM_CFLAGS_AMD64_LINUX = $(WERROR) -m64 -fomit-frame-pointer @PREFERRED_STACK_BOUNDARY@ $(AM_CFLAGS_BASE)
+AM_CCASFLAGS_AMD64_LINUX = $(add_includes_amd64_linux) -m64 -g
+
+AM_CPPFLAGS_PPC32_LINUX = $(add_includes_ppc32_linux)
+AM_CFLAGS_PPC32_LINUX = $(WERROR) -fpic $(AM_CFLAGS_BASE)
+AM_CCASFLAGS_PPC32_LINUX = $(add_includes_ppc32_linux) -Wa,-maltivec -g
+
+PLATFORM = $(shell echo @VG_PLATFORM@ | tr '[a-z-]' '[A-Z_]')
+
+$(eval AM_CPPFLAGS = $(value AM_CPPFLAGS_$(PLATFORM)))
+$(eval AM_CFLAGS = $(value AM_CFLAGS_$(PLATFORM)))
+$(eval AM_CCASFLAGS = $(value AM_CCASFLAGS_$(PLATFORM)))
diff --git a/Makefile.install.am b/Makefile.install.am
new file mode 100644
index 0000000..34c5615
--- /dev/null
+++ b/Makefile.install.am
@@ -0,0 +1,7 @@
+install-exec-local:
+	for f in $(noinst_PROGRAMS); do \
+	  p=`echo $$f | sed -e 's/^[^-]*-//' -e 's/\..*$$//'`; \
+	  n=`echo $$f | sed -e 's/-[^-]\{1,\}-[^-.]\{1,\}//'`; \
+	  $(mkinstalldirs) $(DESTDIR)$(valdir)/$$p; \
+	  $(INSTALL_PROGRAM) $$f $(DESTDIR)$(valdir)/$$p/$$n; \
+	done
diff --git a/Makefile.tool-flags.am b/Makefile.tool-flags.am
index 7e1517e..25100b9 100644
--- a/Makefile.tool-flags.am
+++ b/Makefile.tool-flags.am
@@ -1,10 +1,19 @@
-add_includes = -I$(top_srcdir)/include \
+add_includes_x86_linux = -I$(top_srcdir)/include \
 		-I@VEX_DIR@/pub \
-		-DVGA_$(VG_ARCH)=1 \
-		-DVGO_$(VG_OS)=1 \
-		-DVGP_$(VG_ARCH)_$(VG_OS)=1
+		-DVGA_x86=1 \
+		-DVGO_linux=1 \
+		-DVGP_x86_linux=1
 
-AM_CPPFLAGS = $(add_includes)
-AM_CFLAGS = $(WERROR) -Wmissing-prototypes -Winline -Wall -Wshadow -O -g @ARCH_TOOL_AM_CFLAGS@
-AM_CCASFLAGS = $(add_includes)
+add_includes_amd64_linux = -I$(top_srcdir)/include \
+		-I@VEX_DIR@/pub \
+		-DVGA_amd64=1 \
+		-DVGO_linux=1 \
+		-DVGP_amd64_linux=1
 
+add_includes_ppc32_linux = -I$(top_srcdir)/include \
+		-I@VEX_DIR@/pub \
+		-DVGA_ppc32=1 \
+		-DVGO_linux=1 \
+		-DVGP_ppc32_linux=1
+
+include $(top_srcdir)/Makefile.flags.am
diff --git a/Makefile.tool-inplace.am b/Makefile.tool-inplace.am
index 75d4991..203b6cc 100644
--- a/Makefile.tool-inplace.am
+++ b/Makefile.tool-inplace.am
@@ -1,4 +1,8 @@
 all-local:
-	mkdir -p $(inplacedir)
-	-rm -f $(addprefix $(inplacedir)/,$(val_PROGRAMS))
-	ln -f -s $(addprefix ../$(subdir)/,$(val_PROGRAMS)) $(inplacedir)
+	for f in $(noinst_PROGRAMS); do \
+	  p=`echo $$f | sed -e 's/^[^-]*-//' -e 's/\..*$$//'`; \
+	  n=`echo $$f | sed -e 's/-[^-]\{1,\}-[^-.]\{1,\}//'`; \
+	  mkdir -p $(inplacedir)/$$p; \
+	  rm -f $(inplacedir)/$$p/$$n; \
+	  ln -f -s ../../$(subdir)/$$f $(inplacedir)/$$p/$$n; \
+	done
diff --git a/Makefile.tool.am b/Makefile.tool.am
index 3d7e9fb..b990df1 100644
--- a/Makefile.tool.am
+++ b/Makefile.tool.am
@@ -2,29 +2,79 @@
 SUBDIRS = . tests docs
 
 include $(top_srcdir)/Makefile.all.am
+include $(top_srcdir)/Makefile.install.am
 include $(top_srcdir)/Makefile.tool-flags.am
 include $(top_srcdir)/Makefile.tool-inplace.am
 
-LIBREPLACEMALLOC = $(top_builddir)/coregrind/libreplacemalloc_toolpreload.a
+LIBREPLACEMALLOC_X86_LINUX = \
+	$(top_builddir)/coregrind/libreplacemalloc_toolpreload_x86_linux.a
 
-COREGRIND_LIBS = \
-	$(top_builddir)/coregrind/libcoregrind.a \
-	@VEX_DIR@/libvex.a
+LIBREPLACEMALLOC_AMD64_LINUX = \
+	$(top_builddir)/coregrind/libreplacemalloc_toolpreload_amd64_linux.a
+
+LIBREPLACEMALLOC_PPC32_LINUX = \
+	$(top_builddir)/coregrind/libreplacemalloc_toolpreload_ppc32_linux.a
+
+COREGRIND_LIBS_X86_LINUX = \
+	$(top_builddir)/coregrind/libcoregrind_x86_linux.a \
+	@VEX_DIR@/libvex_x86_linux.a
+
+COREGRIND_LIBS_AMD64_LINUX = \
+	$(top_builddir)/coregrind/libcoregrind_amd64_linux.a \
+	@VEX_DIR@/libvex_amd64_linux.a
+
+COREGRIND_LIBS_PPC32_LINUX = \
+	$(top_builddir)/coregrind/libcoregrind_ppc32_linux.a \
+	@VEX_DIR@/libvex_ppc32_linux.a
 
 ##.PHONY:  @VEX_DIR@/libvex.a
 
-@VEX_DIR@/libvex.a: @VEX_DIR@/priv/main/vex_svnversion.h
-	$(MAKE) -C @VEX_DIR@ CC="$(CC)" libvex.a EXTRA_CFLAGS="@ARCH_CORE_AM_CFLAGS@"
+@VEX_DIR@/libvex_x86_linux.a: @VEX_DIR@/priv/main/vex_svnversion.h
+	$(MAKE) -C @VEX_DIR@ CC="$(CC)" libvex_x86_linux.a EXTRA_CFLAGS="$(AM_CFLAGS_X86_LINUX)"
+
+@VEX_DIR@/libvex_amd64_linux.a: @VEX_DIR@/priv/main/vex_svnversion.h
+	$(MAKE) -C @VEX_DIR@ CC="$(CC)" libvex_amd64_linux.a EXTRA_CFLAGS="$(AM_CFLAGS_AMD64_LINUX)"
+
+@VEX_DIR@/libvex_ppc32_linux.a: @VEX_DIR@/priv/main/vex_svnversion.h
+	$(MAKE) -C @VEX_DIR@ CC="$(CC)" libvex_ppc32_linux.a EXTRA_CFLAGS="$(AM_CFLAGS_PPC32_LINUX)"
 
 @VEX_DIR@/priv/main/vex_svnversion.h:
 	$(MAKE) -C @VEX_DIR@ CC="$(CC)" version
 
-## Nb: do not call this variables "TOOL_LINKADD" and "TOOL_LDFLAGS" -- that
-## makes automake think we are building something called "TOOLS".
-TOOL_LINKADD = $(COREGRIND_LIBS) -lgcc
-TOOL_LINKFLAGS = \
-	-static \
+TOOL_LDADD_COMMON = -lgcc
+TOOL_LDFLAGS_COMMON = -static \
 	-Wl,-defsym,valt_load_address=@VALT_LOAD_ADDRESS@ \
-	-Wl,-T,$(top_builddir)/valt_load_address.lds \
 	-nodefaultlibs -nostartfiles -u _start
 
+TOOL_LDADD_X86_LINUX = $(COREGRIND_LIBS_X86_LINUX) $(TOOL_LDADD_COMMON)
+TOOL_LDFLAGS_X86_LINUX = \
+	$(TOOL_LDFLAGS_COMMON) @FLAG_M32@ \
+	-Wl,-T,$(top_builddir)/valt_load_address_x86_linux.lds
+
+TOOL_LDADD_AMD64_LINUX = $(COREGRIND_LIBS_AMD64_LINUX) $(TOOL_LDADD_COMMON)
+TOOL_LDFLAGS_AMD64_LINUX = \
+	$(TOOL_LDFLAGS_COMMON) -m64 \
+	-Wl,-T,$(top_builddir)/valt_load_address_amd64_linux.lds
+
+TOOL_LDADD_PPC32_LINUX = $(COREGRIND_LIBS_PPC32_LINUX) $(TOOL_LDADD_COMMON)
+TOOL_LDFLAGS_PPC32_LINUX = \
+	$(TOOL_LDFLAGS_COMMON) \
+	-Wl,-T,$(top_builddir)/valt_load_address_ppc32_linux.lds
+
+PRELOAD_LDFLAGS_COMMON = -shared -Wl,-z,interpose,-z,initfirst
+PRELOAD_LDFLAGS_X86_LINUX = $(PRELOAD_LDFLAGS_COMMON) @FLAG_M32@
+PRELOAD_LDFLAGS_AMD64_LINUX = $(PRELOAD_LDFLAGS_COMMON) -m64
+PRELOAD_LDFLAGS_PPC32_LINUX = $(PRELOAD_LDFLAGS_COMMON)
+
+LIBREPLACEMALLOC_LDFLAGS_X86_LINUX = \
+	-Wl,--whole-archive \
+	$(LIBREPLACEMALLOC_X86_LINUX) \
+	-Wl,--no-whole-archive
+LIBREPLACEMALLOC_LDFLAGS_AMD64_LINUX = \
+	-Wl,--whole-archive \
+	$(LIBREPLACEMALLOC_AMD64_LINUX) \
+	-Wl,--no-whole-archive
+LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX = \
+	-Wl,--whole-archive \
+	$(LIBREPLACEMALLOC_PPC32_LINUX) \
+	-Wl,--no-whole-archive
diff --git a/addrcheck/Makefile.am b/addrcheck/Makefile.am
index 676903e..84c51a9 100644
--- a/addrcheck/Makefile.am
+++ b/addrcheck/Makefile.am
@@ -1,9 +1,9 @@
 include $(top_srcdir)/Makefile.tool.am
 
 # include memcheck/ for mac_shared.h
-AM_CPPFLAGS += -I$(top_srcdir)/memcheck
+#AM_CPPFLAGS += -I$(top_srcdir)/memcheck
 
-val_PROGRAMS = vgtool_addrcheck.so vgpreload_addrcheck.so
+noinst_PROGRAMS = vgtool_addrcheck.so vgpreload_addrcheck.so
 
 vgtool_addrcheck_so_SOURCES = ac_main.c
 vgtool_addrcheck_so_LDFLAGS = -shared
diff --git a/cachegrind/Makefile.am b/cachegrind/Makefile.am
index 71fc8c4..863c12b 100644
--- a/cachegrind/Makefile.am
+++ b/cachegrind/Makefile.am
@@ -2,16 +2,41 @@
 
 bin_SCRIPTS = cg_annotate
 
-# Remember to include all the arch-specific files in the distribution.
-EXTRA_DIST = \
-	cg_sim.c \
-	$(addsuffix .c,$(addprefix cg-,$(VG_ARCH_ALL)))
+noinst_HEADERS = cg_arch.h cg_sim.c
 
-noinst_HEADERS = cg_arch.h
+noinst_PROGRAMS = 
+if VG_X86_LINUX
+noinst_PROGRAMS += cachegrind-x86-linux
+endif
+if VG_AMD64_LINUX
+noinst_PROGRAMS += cachegrind-amd64-linux
+endif
+if VG_PPC32_LINUX
+noinst_PROGRAMS += cachegrind-ppc32-linux
+endif
 
-val_PROGRAMS = cachegrind
+CACHEGRIND_SOURCES_COMMON = cg_main.c
+CACHEGRIND_SOURCES_X86 = cg-x86.c
+CACHEGRIND_SOURCES_AMD64 = cg-amd64.c
+CACHEGRIND_SOURCES_PPC32 = cg-ppc32.c
 
-cachegrind_SOURCES      = cg_main.c cg-@VG_ARCH@.c
-cachegrind_DEPENDENCIES = $(COREGRIND_LIBS)
-cachegrind_LDADD        = $(TOOL_LINKADD)
-cachegrind_LDFLAGS      = $(TOOL_LINKFLAGS)
+cachegrind_x86_linux_SOURCES      = $(CACHEGRIND_SOURCES_COMMON) $(CACHEGRIND_SOURCES_X86)
+cachegrind_x86_linux_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+cachegrind_x86_linux_CFLAGS       = $(AM_CFLAGS_X86_LINUX)
+cachegrind_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX)
+cachegrind_x86_linux_LDADD        = $(TOOL_LDADD_X86_LINUX)
+cachegrind_x86_linux_LDFLAGS      = $(TOOL_LDFLAGS_X86_LINUX)
+
+cachegrind_amd64_linux_SOURCES      = $(CACHEGRIND_SOURCES_COMMON) $(CACHEGRIND_SOURCES_AMD64)
+cachegrind_amd64_linux_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+cachegrind_amd64_linux_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX)
+cachegrind_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX)
+cachegrind_amd64_linux_LDADD        = $(TOOL_LDADD_AMD64_LINUX)
+cachegrind_amd64_linux_LDFLAGS      = $(TOOL_LDFLAGS_AMD64_LINUX)
+
+cachegrind_ppc32_linux_SOURCES      = $(CACHEGRIND_SOURCES_COMMON) $(CACHEGRIND_SOURCES_PPC32)
+cachegrind_ppc32_linux_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+cachegrind_ppc32_linux_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX)
+cachegrind_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
+cachegrind_ppc32_linux_LDADD        = $(TOOL_LDADD_PPC32_LINUX)
+cachegrind_ppc32_linux_LDFLAGS      = $(TOOL_LDFLAGS_PPC32_LINUX)
diff --git a/configure.in b/configure.in
index 9e802bf..d275191 100644
--- a/configure.in
+++ b/configure.in
@@ -112,9 +112,6 @@
 AC_SUBST(VG_ARCH_ALL)
 VG_ARCH_ALL="amd64 ppc32 x86"
 AC_SUBST(VALT_LOAD_ADDRESS)
-AC_SUBST(ARCH_CORE_AM_CFLAGS)
-AC_SUBST(ARCH_TOOL_AM_CFLAGS)
-AC_SUBST(ARCH_CORE_AM_CCASFLAGS)
 
 case "${host_cpu}" in
      i?86) 
@@ -122,9 +119,6 @@
         VG_ARCH="x86"
         valt_load_address_normal="0xb0000000"
         valt_load_address_inner="0xa0000000"
-        ARCH_CORE_AM_CFLAGS="@FLAG_M32@ @PREFERRED_STACK_BOUNDARY@"
-        ARCH_TOOL_AM_CFLAGS="@FLAG_M32@ @PREFERRED_STACK_BOUNDARY@"
-        ARCH_CORE_AM_CCASFLAGS="@FLAG_M32@"
         ;;
 
      x86_64) 
@@ -135,15 +129,6 @@
         # a problem.
         valt_load_address_normal="0x70000000"
         valt_load_address_inner="0x60000000"
-        ARCH_CORE_AM_CFLAGS="-m64 -fomit-frame-pointer @PREFERRED_STACK_BOUNDARY@" 
-        # XXX: need to use -fpic, otherwise when linking tools I get this error
-        # message:
-        #   relocation R_X86_64_32 can not be used when making a shared object;
-        #   recompile with -fPIC
-        #
-        # I don't understand...  --njn
-        ARCH_TOOL_AM_CFLAGS="-m64 -fomit-frame-pointer @PREFERRED_STACK_BOUNDARY@ -fpic"
-        ARCH_CORE_AM_CCASFLAGS="-m64"
         ;;
 
      powerpc*)
@@ -151,9 +136,6 @@
         VG_ARCH="ppc32"
         valt_load_address_normal="0x70000000"
         valt_load_address_inner="0x60000000"
-        ARCH_CORE_AM_CFLAGS=""
-        ARCH_TOOL_AM_CFLAGS="-fpic"
-        ARCH_CORE_AM_CCASFLAGS="-Wa,-maltivec"
         ;;
 
      *) 
@@ -238,6 +220,10 @@
         ;;
 esac
 
+AM_CONDITIONAL(VG_X86_LINUX, test x$VG_PLATFORM = xx86-linux -o x$VG_PLATFORM = xamd64-linux)
+AM_CONDITIONAL(VG_AMD64_LINUX, test x$VG_PLATFORM = xamd64-linux)
+AM_CONDITIONAL(VG_PPC32_LINUX, test x$VG_PLATFORM = xppc32-linux)
+
 AC_SUBST(DEFAULT_SUPP)
 
 glibc=""
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 9e4ae81..b614071 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -1,29 +1,40 @@
 include $(top_srcdir)/Makefile.all.am
 include $(top_srcdir)/Makefile.core.am
+include $(top_srcdir)/Makefile.install.am
 
-AM_CPPFLAGS += -DVG_LIBDIR="\"$(valdir)"\" \
+AM_CPPFLAGS_X86_LINUX += -DVG_LIBDIR="\"$(valdir)"\" \
+		-DKICKSTART_BASE=@KICKSTART_BASE@
+AM_CPPFLAGS_AMD64_LINUX += -DVG_LIBDIR="\"$(valdir)"\" \
+		-DKICKSTART_BASE=@KICKSTART_BASE@
+AM_CPPFLAGS_PPC32_LINUX += -DVG_LIBDIR="\"$(valdir)"\" \
 		-DKICKSTART_BASE=@KICKSTART_BASE@
 
 default.supp: $(SUPP_FILES)
 
-noinst_LIBRARIES = \
-    libcoregrind.a \
-    libreplacemalloc_toolpreload.a
+noinst_LIBRARIES =
+if VG_X86_LINUX
+noinst_LIBRARIES += libcoregrind_x86_linux.a libreplacemalloc_toolpreload_x86_linux.a
+endif
+if VG_AMD64_LINUX
+noinst_LIBRARIES += libcoregrind_amd64_linux.a libreplacemalloc_toolpreload_amd64_linux.a
+endif
+if VG_PPC32_LINUX
+noinst_LIBRARIES += libcoregrind_ppc32_linux.a libreplacemalloc_toolpreload_ppc32_linux.a
+endif
 
 bin_PROGRAMS = \
 	valgrind
 
-val_PROGRAMS = \
-	vgpreload_core.so
-
-# Remember to include all the arch-specific files in the distribution.
-EXTRA_DIST = \
-        $(addsuffix .c,$(addprefix m_coredump/coredump-,$(VG_PLATFORM_ALL))) \
-        $(addsuffix .S,$(addprefix m_dispatch/dispatch-,$(VG_PLATFORM_ALL))) \
-        $(addsuffix .c,$(addprefix m_sigframe/sigframe-,$(VG_PLATFORM_ALL))) \
-        $(addsuffix .S,$(addprefix m_syswrap/syscall-,$(VG_PLATFORM_ALL))) \
-        $(addsuffix .c,$(addprefix m_syswrap/syswrap-,$(VG_OS_ALL))) \
-        $(addsuffix .c,$(addprefix m_syswrap/syswrap-,$(VG_PLATFORM_ALL)))
+noinst_PROGRAMS =
+if VG_X86_LINUX
+noinst_PROGRAMS += vgpreload_core-x86-linux.so
+endif
+if VG_AMD64_LINUX
+noinst_PROGRAMS += vgpreload_core-amd64-linux.so
+endif
+if VG_PPC32_LINUX
+noinst_PROGRAMS += vgpreload_core-ppc32-linux.so
+endif
 
 noinst_HEADERS = \
 	coregrind.h		\
@@ -97,7 +108,7 @@
 	launcher.c \
 	m_debuglog.c
 
-libcoregrind_a_SOURCES = \
+COREGRIND_SOURCES_COMMON = \
 	m_commandline.c \
 	m_cpuid.S \
 	m_clientstate.c \
@@ -133,8 +144,6 @@
 	m_ume.c \
 	m_aspacemgr/read_procselfmaps.c \
 	m_aspacemgr/aspacemgr.c \
-	m_coredump/coredump-elf.c \
-	m_coredump/coredump-@VG_PLATFORM@.c \
 	m_debuginfo/dwarf.c \
 	m_debuginfo/stabs.c \
 	m_debuginfo/symtab.c \
@@ -144,35 +153,92 @@
 	m_demangle/demangle.c \
 	m_demangle/dyn-string.c \
 	m_demangle/safe-ctype.c \
-	m_dispatch/dispatch-@VG_PLATFORM@.S \
 	m_replacemalloc/replacemalloc_core.c \
 	m_scheduler/scheduler.c \
 	m_scheduler/sema.c \
-	m_sigframe/sigframe-@VG_PLATFORM@.c \
-	m_syswrap/syscall-@VG_PLATFORM@.S \
 	m_syswrap/syswrap-generic.c \
-	m_syswrap/syswrap-@VG_OS@.c \
-	m_syswrap/syswrap-@VG_OS@-variants.c \
-	m_syswrap/syswrap-@VG_PLATFORM@.c \
 	m_syswrap/syswrap-main.c
 
-libreplacemalloc_toolpreload_a_SOURCES = m_replacemalloc/vg_replace_malloc.c
-libreplacemalloc_toolpreload_a_CFLAGS = $(PIC_AM_CFLAGS)
+COREGRIND_LINUX_SOURCE = \
+	m_coredump/coredump-elf.c \
+	m_syswrap/syswrap-linux.c \
+	m_syswrap/syswrap-linux-variants.c
 
-m_dispatch/dispatch-@VG_PLATFORM@.S: libvex_guest_offsets.h
-m_syswrap/syscall-@VG_PLATFORM@.S:   libvex_guest_offsets.h
-m_syswrap/syswrap-main.c: 	     libvex_guest_offsets.h
+libcoregrind_x86_linux_a_SOURCES = \
+	$(COREGRIND_SOURCES_COMMON) \
+	$(COREGRIND_LINUX_SOURCE) \
+	m_coredump/coredump-x86-linux.c \
+	m_dispatch/dispatch-x86-linux.S \
+	m_sigframe/sigframe-x86-linux.c \
+	m_syswrap/syscall-x86-linux.S \
+	m_syswrap/syswrap-x86-linux.c
+
+libcoregrind_x86_linux_a_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
+libcoregrind_x86_linux_a_CFLAGS = $(AM_CFLAGS_X86_LINUX)
+libcoregrind_x86_linux_a_CCASFLAGS = $(AM_CCASFLAGS_X86_LINUX)
+
+libcoregrind_amd64_linux_a_SOURCES = \
+	$(COREGRIND_SOURCES_COMMON) \
+	$(COREGRIND_LINUX_SOURCE) \
+	m_coredump/coredump-amd64-linux.c \
+	m_dispatch/dispatch-amd64-linux.S \
+	m_sigframe/sigframe-amd64-linux.c \
+	m_syswrap/syscall-amd64-linux.S \
+	m_syswrap/syswrap-amd64-linux.c
+
+libcoregrind_amd64_linux_a_CPPFLAGS = $(AM_CPPFLAGS_AMD64_LINUX)
+libcoregrind_amd64_linux_a_CFLAGS = $(AM_CFLAGS_AMD64_LINUX)
+libcoregrind_amd64_linux_a_CCASFLAGS = $(AM_CCASFLAGS_AMD64_LINUX)
+
+libcoregrind_ppc32_linux_a_SOURCES = \
+	$(COREGRIND_SOURCES_COMMON) \
+	$(COREGRIND_LINUX_SOURCE) \
+	m_coredump/coredump-ppc32-linux.c \
+	m_dispatch/dispatch-ppc32-linux.S \
+	m_sigframe/sigframe-ppc32-linux.c \
+	m_syswrap/syscall-ppc32-linux.S \
+	m_syswrap/syswrap-ppc32-linux.c
+
+libcoregrind_ppc32_linux_a_CPPFLAGS = $(AM_CPPFLAGS_PPC32_LINUX)
+libcoregrind_ppc32_linux_a_CFLAGS = $(AM_CFLAGS_PPC32_LINUX)
+libcoregrind_ppc32_linux_a_CCASFLAGS = $(AM_CCASFLAGS_PPC32_LINUX)
+
+libreplacemalloc_toolpreload_x86_linux_a_SOURCES = m_replacemalloc/vg_replace_malloc.c
+libreplacemalloc_toolpreload_x86_linux_a_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
+libreplacemalloc_toolpreload_x86_linux_a_CFLAGS = $(AM_CFLAGS_X86_LINUX) -fpic -fno-omit-frame-pointer
+
+libreplacemalloc_toolpreload_amd64_linux_a_SOURCES = m_replacemalloc/vg_replace_malloc.c
+libreplacemalloc_toolpreload_amd64_linux_a_CPPFLAGS = $(AM_CPPFLAGS_AMD64_LINUX)
+libreplacemalloc_toolpreload_amd64_linux_a_CFLAGS = $(AM_CFLAGS_AMD64_LINUX) -fpic -fno-omit-frame-pointer
+
+libreplacemalloc_toolpreload_ppc32_linux_a_SOURCES = m_replacemalloc/vg_replace_malloc.c
+libreplacemalloc_toolpreload_ppc32_linux_a_CPPFLAGS = $(AM_CPPFLAGS_PPC32_LINUX)
+libreplacemalloc_toolpreload_ppc32_linux_a_CFLAGS = $(AM_CFLAGS_PPC32_LINUX) -fpic -fno-omit-frame-pointer
+
+m_dispatch/dispatch-x86-linux.S:	 libvex_guest_offsets.h
+m_dispatch/dispatch-amd64-linux.S:	 libvex_guest_offsets.h
+m_dispatch/dispatch-ppc32-linux.S:	 libvex_guest_offsets.h
+m_syswrap/syscall-x86-linux.S:		 libvex_guest_offsets.h
+m_syswrap/syscall-amd64-linux.S:	 libvex_guest_offsets.h
+m_syswrap/syscall-ppc32-linux.S:	 libvex_guest_offsets.h
+m_syswrap/syswrap-main.c: 		 libvex_guest_offsets.h
 
 libvex_guest_offsets.h:
 	$(MAKE) -C @VEX_DIR@ pub/libvex_guest_offsets.h
 
-vgpreload_core_so_SOURCES = vg_preloaded.c
-vgpreload_core_so_CFLAGS = $(AM_CFLAGS) -fpic
-vgpreload_core_so_LDADD = -ldl
-vgpreload_core_so_LDFLAGS = \
-	-shared \
-	-Wl,--soname,vgpreload_core.so \
-	-Wl,-z,initfirst
+VGPRELOAD_CORE_SOURCES_COMMON = vg_preloaded.c
+
+vgpreload_core_x86_linux_so_SOURCES = $(VGPRELOAD_CORE_SOURCES_COMMON)
+vgpreload_core_x86_linux_so_CFLAGS = $(AM_CFLAGS_X86_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_core_x86_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_X86_LINUX)
+
+vgpreload_core_amd64_linux_so_SOURCES = $(VGPRELOAD_CORE_SOURCES_COMMON)
+vgpreload_core_amd64_linux_so_CFLAGS = $(AM_CFLAGS_AMD64_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_core_amd64_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_AMD64_LINUX)
+
+vgpreload_core_ppc32_linux_so_SOURCES = $(VGPRELOAD_CORE_SOURCES_COMMON)
+vgpreload_core_ppc32_linux_so_CFLAGS = $(AM_CFLAGS_PPC32_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_core_ppc32_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_PPC32_LINUX)
 
 clean-local:
 	$(MAKE) -C @VEX_DIR@ CC="$(CC)" clean
@@ -180,10 +246,10 @@
 MANUAL_DEPS = $(noinst_HEADERS) $(include_HEADERS)
 
 all-local:
-	mkdir -p $(inplacedir)
-	for i in $(val_PROGRAMS); do \
-		to=$(inplacedir)/$$i; \
-		rm -f $$$to; \
-		ln -sf ../$(subdir)/$$i $$to; \
+	for f in $(noinst_PROGRAMS); do \
+	  p=`echo $$f | sed -e 's/^[^-]*-//' -e 's/\..*$$//'`; \
+	  n=`echo $$f | sed -e 's/-[^-]\{1,\}-[^-.]\{1,\}//'`; \
+	  mkdir -p $(inplacedir)/$$p; \
+	  rm -f $(inplacedir)/$$p/$$n; \
+	  ln -f -s ../../$(subdir)/$$f $(inplacedir)/$$p/$$n; \
 	done
-
diff --git a/coregrind/launcher.c b/coregrind/launcher.c
index 8140491..08a1792 100644
--- a/coregrind/launcher.c
+++ b/coregrind/launcher.c
@@ -32,27 +32,134 @@
    and so it doesn't have to conform to Valgrind's arcane rules on
    no-glibc-usage etc. */
 
+#include <assert.h>
+#include <ctype.h>
+#include <elf.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/mman.h>
+#include <sys/user.h>
 #include <unistd.h>
-#include <assert.h>
 
 #include "pub_core_debuglog.h"
 #include "pub_core_libcproc.h"  // For VALGRIND_LIB, VALGRIND_LAUNCHER
+#include "pub_core_ume.h"
 
 
 
 #define PATH_MAX 4096 /* POSIX refers to this a lot but I dunno
                          where it is defined */
 
-static void barf ( char* str )
+/* Report fatal errors */
+static void barf ( const char *format, ... )
 {
-   fprintf(stderr, "valgrind: Cannot continue: %s\n", str );
+   va_list vargs;
+
+   va_start(vargs, format);
+   fprintf(stderr, "valgrind: Cannot continue: ");
+   vfprintf(stderr, format, vargs);
+   fprintf(stderr, "\n");
+   va_end(vargs);
+
    exit(1);
 }
 
+/* Search the path for the client program */
+static const char *find_client(const char *clientname)
+{
+   static char fullname[PATH_MAX];
+   const char *path = getenv("PATH");
+   const char *colon;
+
+   while (path)
+   {
+      if ((colon = strchr(path, ':')) == NULL)
+      {
+         strcpy(fullname, path);
+         path = NULL;
+      }
+      else
+      {
+         memcpy(fullname, path, colon - path);
+         fullname[colon - path] = '\0';
+         path = colon + 1;
+      }
+
+      strcat(fullname, "/");
+      strcat(fullname, clientname);
+
+      if (access(fullname, R_OK|X_OK) == 0)
+         return fullname;
+   }
+
+   return clientname;
+}
+
+/* Examine the client and work out which platform it is for */
+static const char *select_platform(const char *clientname)
+{
+   int fd;
+   unsigned char *header;
+   const char *platform = NULL;
+
+   if (strchr(clientname, '/') == NULL)
+      clientname = find_client(clientname);
+
+   if ((fd = open(clientname, O_RDONLY)) < 0)
+      return NULL;
+   //   barf("open(%s): %s", clientname, strerror(errno));
+
+   if ((header = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
+      return NULL;
+   //   barf("mmap(%s): %s", clientname, strerror(errno));
+
+   close(fd);
+
+   if (header[0] == '#' && header[1] == '!') {
+      char *interp = (char *)header + 2;
+      char *interpend;
+
+      while (*interp == ' ' || *interp == '\t')
+         interp++;
+
+      for (interpend = interp; !isspace(*interpend); interpend++)
+         ;
+
+      *interpend = '\0';
+
+      platform = select_platform(interp);
+   } else if (memcmp(header, ELFMAG, SELFMAG) == 0 &&
+              header[EI_CLASS] == ELFCLASS32 &&
+              header[EI_DATA] == ELFDATA2LSB) {
+      const Elf32_Ehdr *ehdr = (Elf32_Ehdr *)header;
+
+      if (ehdr->e_machine == EM_386 &&
+          ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV) {
+         platform = "x86-linux";
+      } else if (ehdr->e_machine == EM_PPC &&
+                 ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV) {
+         platform = "ppc32-linux";
+      }
+   } else if (memcmp(header, ELFMAG, SELFMAG) == 0 &&
+              header[EI_CLASS] == ELFCLASS64 &&
+              header[EI_DATA] == ELFDATA2LSB) {
+      const Elf64_Ehdr *ehdr = (Elf64_Ehdr *)header;
+
+      if (ehdr->e_machine == EM_X86_64 &&
+          ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV) {
+         platform = "amd64-linux";
+      }
+   }
+
+   munmap(header, PAGE_SIZE);
+
+   return platform;
+}
+
 /* Where we expect to find all our aux files */
 static const char *valgrind_lib = VG_LIBDIR;
 
@@ -60,6 +167,8 @@
 {
    int i, j, loglevel, r;
    const char *toolname = NULL;
+   const char *clientname = NULL;
+   const char *platform;
    const char *cp;
    char *toolfile;
    char launcher_name[PATH_MAX+1];
@@ -71,10 +180,15 @@
       At the same time, look for the tool name. */
    loglevel = 0;
    for (i = 1; i < argc; i++) {
-      if (argv[i][0] != '-')
+      if (argv[i][0] != '-') {
+         clientname = argv[i];
          break;
-      if (0 == strcmp(argv[i], "--")) 
+      }
+      if (0 == strcmp(argv[i], "--")) {
+         if (i+1 < argc)
+            clientname = argv[i+1];
          break;
+      }
       if (0 == strcmp(argv[i], "-d")) 
          loglevel++;
       if (0 == strncmp(argv[i], "--tool=", 7)) 
@@ -94,6 +208,17 @@
       toolname = "memcheck";
    }
 
+   /* Work out what platform to use */
+   if (clientname == NULL) {
+      VG_(debugLog)(1, "launcher", "no client specified, defaulting platform to '%s'\n", VG_PLATFORM);
+      platform = VG_PLATFORM;
+   } else if ((platform = select_platform(clientname)) != NULL) {
+      VG_(debugLog)(1, "launcher", "selected platform '%s'\n", platform);
+   } else {
+      VG_(debugLog)(1, "launcher", "no platform detected, defaulting platform to '%s'\n", VG_PLATFORM);
+      platform = VG_PLATFORM;
+   }
+   
    /* Figure out the name of this executable (viz, the launcher), so
       we can tell stage2.  stage2 will use the name for recursive
       invokations of valgrind on child processes. */
@@ -137,17 +262,17 @@
       valgrind_lib = cp;
 
    /* Build the stage2 invokation, and execve it.  Bye! */
-   toolfile = malloc(strlen(valgrind_lib) + strlen(toolname) + 2);
+   toolfile = malloc(strlen(valgrind_lib) + strlen(toolname) + strlen(platform) + 3);
    if (toolfile == NULL)
       barf("malloc of toolfile failed.");
-   sprintf(toolfile, "%s/%s", valgrind_lib, toolname);
+   sprintf(toolfile, "%s/%s/%s", valgrind_lib, platform, toolname);
 
    VG_(debugLog)(1, "launcher", "launching %s\n", toolfile);
 
    execve(toolfile, argv, new_env);
 
-   fprintf(stderr, "valgrind: failed to start tool '%s': %s\n",
-                   toolname, strerror(errno));
+   fprintf(stderr, "valgrind: failed to start tool '%s' for platform '%s': %s\n",
+                   toolname, platform, strerror(errno));
 
    exit(1);
 }
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 962f25a..65f3396 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -104,7 +104,7 @@
 */
 static HChar** setup_client_env ( HChar** origenv, const HChar* toolname)
 {
-   HChar* preload_core_so = "vgpreload_core.so";
+   HChar* preload_core    = "vgpreload_core";
    HChar* ld_preload      = "LD_PRELOAD=";
    HChar* v_launcher      = VALGRIND_LAUNCHER "=";
    Int    ld_preload_len  = VG_(strlen)( ld_preload );
@@ -121,8 +121,8 @@
       paths.  We might not need the space for vgpreload_<tool>.so, but it
       doesn't hurt to over-allocate briefly.  The 16s are just cautious
       slop. */
-   Int preload_core_path_len = vglib_len + sizeof(preload_core_so) + 16;
-   Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname)   + 16;
+   Int preload_core_path_len = vglib_len + sizeof(preload_core) + sizeof(VG_PLATFORM) + 16;
+   Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname) + sizeof(VG_PLATFORM) + 16;
    Int preload_string_len    = preload_core_path_len + preload_tool_path_len;
    HChar* preload_string     = VG_(malloc)(preload_string_len);
    vg_assert(preload_string);
@@ -132,13 +132,13 @@
    preload_tool_path = VG_(malloc)(preload_tool_path_len);
    vg_assert(preload_tool_path);
    VG_(snprintf)(preload_tool_path, preload_tool_path_len,
-                 "%s/vgpreload_%s.so", VG_(libdir), toolname);
+                 "%s/%s/vgpreload_%s.so", VG_(libdir), VG_PLATFORM, toolname);
    if (VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/) == 0) {
-      VG_(snprintf)(preload_string, preload_string_len, "%s/%s:%s", 
-                    VG_(libdir), preload_core_so, preload_tool_path);
+      VG_(snprintf)(preload_string, preload_string_len, "%s/%s/%s.so:%s", 
+                    VG_(libdir), VG_PLATFORM, preload_core, preload_tool_path);
    } else {
-      VG_(snprintf)(preload_string, preload_string_len, "%s/%s", 
-                    VG_(libdir), preload_core_so);
+      VG_(snprintf)(preload_string, preload_string_len, "%s/%s/%s.so", 
+                    VG_(libdir), VG_PLATFORM, preload_core);
    }
    VG_(free)(preload_tool_path);
 
diff --git a/helgrind/Makefile.am b/helgrind/Makefile.am
index 320e276..469a55e 100644
--- a/helgrind/Makefile.am
+++ b/helgrind/Makefile.am
@@ -1,19 +1,63 @@
 include $(top_srcdir)/Makefile.tool.am
 
-val_PROGRAMS = vgtool_helgrind.so vgpreload_helgrind.so
+noinst_PROGRAMS = 
+if VG_X86_LINUX
+noinst_PROGRAMS += helgrind-x86-linux vgpreload_helgrind-x86-linux.so
+endif
+if VG_AMD64_LINUX
+noinst_PROGRAMS += helgrind-amd64-linux vgpreload_helgrind-amd64-linux.so
+endif
+if VG_PPC32_LINUX
+noinst_PROGRAMS += helgrind-ppc32-linux vgpreload_helgrind-ppc32-linux.so
+endif
 
-vgtool_helgrind_so_SOURCES = hg_main.c
-vgtool_helgrind_so_LDFLAGS = -shared
+vgpreload_helgrind_x86_linux_so_SOURCES      = 
+vgpreload_helgrind_x86_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+vgpreload_helgrind_x86_linux_so_CFLAGS       = $(AM_CFLAGS_X86_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_helgrind_x86_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_X86_LINUX)
+vgpreload_helgrind_x86_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_X86_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_X86_LINUX)
 
-vgpreload_helgrind_so_SOURCES = 
-vgpreload_helgrind_so_DEPENDENCIES = \
-	$(LIBREPLACEMALLOC)
-vgpreload_helgrind_so_LDFLAGS = -shared -Wl,-z,interpose,-z,initfirst \
-	-Wl,--whole-archive \
-	$(LIBREPLACEMALLOC) \
-	-Wl,--no-whole-archive
+vgpreload_helgrind_amd64_linux_so_SOURCES      = 
+vgpreload_helgrind_amd64_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+vgpreload_helgrind_amd64_linux_so_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_helgrind_amd64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_AMD64_LINUX)
+vgpreload_helgrind_amd64_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_AMD64_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_AMD64_LINUX)
+
+vgpreload_helgrind_ppc32_linux_so_SOURCES      = 
+vgpreload_helgrind_ppc32_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+vgpreload_helgrind_ppc32_linux_so_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_helgrind_ppc32_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC32_LINUX)
+vgpreload_helgrind_ppc32_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_PPC32_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX)
+
+HELGRIND_SOURCES_COMMON = hg_main.c
+
+helgrind_x86_linux_SOURCES      = $(HELGRIND_SOURCES_COMMON)
+helgrind_x86_linux_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+helgrind_x86_linux_CFLAGS       = $(AM_CFLAGS_X86_LINUX)
+helgrind_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX)
+helgrind_x86_linux_LDADD        = $(TOOL_LDADD_X86_LINUX)
+helgrind_x86_linux_LDFLAGS      = $(TOOL_LDFLAGS_X86_LINUX)
+
+helgrind_amd64_linux_SOURCES      = $(HELGRIND_SOURCES_COMMON)
+helgrind_amd64_linux_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+helgrind_amd64_linux_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX)
+helgrind_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX)
+helgrind_amd64_linux_LDADD        = $(TOOL_LDADD_AMD64_LINUX)
+helgrind_amd64_linux_LDFLAGS      = $(TOOL_LDFLAGS_AMD64_LINUX)
+
+helgrind_ppc32_linux_SOURCES      = $(HELGRIND_SOURCES_COMMON)
+helgrind_ppc32_linux_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+helgrind_ppc32_linux_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX)
+helgrind_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
+helgrind_ppc32_linux_LDADD        = $(TOOL_LDADD_PPC32_LINUX)
+helgrind_ppc32_linux_LDFLAGS      = $(TOOL_LDFLAGS_PPC32_LINUX)
 
 hgincludedir = $(includedir)/valgrind
 
 hginclude_HEADERS = helgrind.h
-
diff --git a/lackey/Makefile.am b/lackey/Makefile.am
index a85a3db..b25f67a 100644
--- a/lackey/Makefile.am
+++ b/lackey/Makefile.am
@@ -1,8 +1,35 @@
 include $(top_srcdir)/Makefile.tool.am
 
-val_PROGRAMS = lackey
+noinst_PROGRAMS = 
+if VG_X86_LINUX
+noinst_PROGRAMS += lackey-x86-linux
+endif
+if VG_AMD64_LINUX
+noinst_PROGRAMS += lackey-amd64-linux
+endif
+if VG_PPC32_LINUX
+noinst_PROGRAMS += lackey-ppc32-linux
+endif
 
-lackey_SOURCES      = lk_main.c
-lackey_DEPENDENCIES = $(COREGRIND_LIBS)
-lackey_LDADD        = $(TOOL_LINKADD)
-lackey_LDFLAGS      = $(TOOL_LINKFLAGS)
+LACKEY_SOURCES_COMMON = lk_main.c
+
+lackey_x86_linux_SOURCES      = $(LACKEY_SOURCES_COMMON)
+lackey_x86_linux_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+lackey_x86_linux_CFLAGS       = $(AM_CFLAGS_X86_LINUX)
+lackey_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX)
+lackey_x86_linux_LDADD        = $(TOOL_LDADD_X86_LINUX)
+lackey_x86_linux_LDFLAGS      = $(TOOL_LDFLAGS_X86_LINUX)
+
+lackey_amd64_linux_SOURCES      = $(LACKEY_SOURCES_COMMON)
+lackey_amd64_linux_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+lackey_amd64_linux_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX)
+lackey_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX)
+lackey_amd64_linux_LDADD        = $(TOOL_LDADD_AMD64_LINUX)
+lackey_amd64_linux_LDFLAGS      = $(TOOL_LDFLAGS_AMD64_LINUX)
+
+lackey_ppc32_linux_SOURCES      = $(LACKEY_SOURCES_COMMON)
+lackey_ppc32_linux_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+lackey_ppc32_linux_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX)
+lackey_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
+lackey_ppc32_linux_LDADD        = $(TOOL_LDADD_PPC32_LINUX)
+lackey_ppc32_linux_LDFLAGS      = $(TOOL_LDFLAGS_PPC32_LINUX)
diff --git a/massif/Makefile.am b/massif/Makefile.am
index f922a4c..ca30d72 100644
--- a/massif/Makefile.am
+++ b/massif/Makefile.am
@@ -2,17 +2,60 @@
 
 SUBDIRS += hp2ps
 
-val_PROGRAMS = massif vgpreload_massif.so
+noinst_PROGRAMS = 
+if VG_X86_LINUX
+noinst_PROGRAMS += massif-x86-linux vgpreload_massif-x86-linux.so
+endif
+if VG_AMD64_LINUX
+noinst_PROGRAMS += massif-amd64-linux vgpreload_massif-amd64-linux.so
+endif
+if VG_PPC32_LINUX
+noinst_PROGRAMS += massif-ppc32-linux vgpreload_massif-ppc32-linux.so
+endif
 
-vgpreload_massif_so_SOURCES      = 
-vgpreload_massif_so_DEPENDENCIES = $(LIBREPLACEMALLOC)
-vgpreload_massif_so_LDFLAGS      = \
-	-shared -Wl,-z,interpose,-z,initfirst \
-	-Wl,--whole-archive \
-	$(LIBREPLACEMALLOC) \
-	-Wl,--no-whole-archive
+vgpreload_massif_x86_linux_so_SOURCES      = 
+vgpreload_massif_x86_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+vgpreload_massif_x86_linux_so_CFLAGS       = $(AM_CFLAGS_X86_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_massif_x86_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_X86_LINUX)
+vgpreload_massif_x86_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_X86_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_X86_LINUX)
 
-massif_SOURCES      = ms_main.c
-massif_DEPENDENCIES = $(COREGRIND_LIBS)
-massif_LDADD        = $(TOOL_LINKADD)
-massif_LDFLAGS 	    = $(TOOL_LINKFLAGS)
+vgpreload_massif_amd64_linux_so_SOURCES      = 
+vgpreload_massif_amd64_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+vgpreload_massif_amd64_linux_so_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_massif_amd64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_AMD64_LINUX)
+vgpreload_massif_amd64_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_AMD64_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_AMD64_LINUX)
+
+vgpreload_massif_ppc32_linux_so_SOURCES      = 
+vgpreload_massif_ppc32_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+vgpreload_massif_ppc32_linux_so_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX) $(AM_CFLAGS_PIC)
+vgpreload_massif_ppc32_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC32_LINUX)
+vgpreload_massif_ppc32_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_PPC32_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX)
+
+MASSIF_SOURCES_COMMON = ms_main.c
+
+massif_x86_linux_SOURCES      = $(MASSIF_SOURCES_COMMON)
+massif_x86_linux_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+massif_x86_linux_CFLAGS       = $(AM_CFLAGS_X86_LINUX)
+massif_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX)
+massif_x86_linux_LDADD        = $(TOOL_LDADD_X86_LINUX)
+massif_x86_linux_LDFLAGS      = $(TOOL_LDFLAGS_X86_LINUX)
+
+massif_amd64_linux_SOURCES      = $(MASSIF_SOURCES_COMMON)
+massif_amd64_linux_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+massif_amd64_linux_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX)
+massif_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX)
+massif_amd64_linux_LDADD        = $(TOOL_LDADD_AMD64_LINUX)
+massif_amd64_linux_LDFLAGS      = $(TOOL_LDFLAGS_AMD64_LINUX)
+
+massif_ppc32_linux_SOURCES      = $(MASSIF_SOURCES_COMMON)
+massif_ppc32_linux_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+massif_ppc32_linux_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX)
+massif_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
+massif_ppc32_linux_LDADD        = $(TOOL_LDADD_PPC32_LINUX)
+massif_ppc32_linux_LDFLAGS      = $(TOOL_LDFLAGS_PPC32_LINUX)
diff --git a/massif/hp2ps/Makefile.am b/massif/hp2ps/Makefile.am
index 1f51006..b8d5d8e 100644
--- a/massif/hp2ps/Makefile.am
+++ b/massif/hp2ps/Makefile.am
@@ -54,5 +54,7 @@
        TraceElement.h \
        Utilities.h
 
-include $(top_srcdir)/Makefile.tool-inplace.am
-
+all-local:
+	mkdir -p $(inplacedir)
+	-rm -f $(addprefix $(inplacedir)/,$(val_PROGRAMS))
+	ln -f -s $(addprefix ../$(subdir)/,$(val_PROGRAMS)) $(inplacedir)
diff --git a/memcheck/Makefile.am b/memcheck/Makefile.am
index cf25084..a47a8e5 100644
--- a/memcheck/Makefile.am
+++ b/memcheck/Makefile.am
@@ -1,27 +1,75 @@
 include $(top_srcdir)/Makefile.tool.am
 
-## Build Memcheck at a higher optimisation level
-AM_CFLAGS += -O2
+noinst_PROGRAMS = 
+if VG_X86_LINUX
+noinst_PROGRAMS += memcheck-x86-linux vgpreload_memcheck-x86-linux.so
+endif
+if VG_AMD64_LINUX
+noinst_PROGRAMS += memcheck-amd64-linux vgpreload_memcheck-amd64-linux.so
+endif
+if VG_PPC32_LINUX
+noinst_PROGRAMS += memcheck-ppc32-linux vgpreload_memcheck-ppc32-linux.so
+endif
 
-val_PROGRAMS = memcheck vgpreload_memcheck.so
+VGPRELOAD_MEMCHECK_SOURCES_COMMON = mac_replace_strmem.c
 
-vgpreload_memcheck_so_SOURCES      = mac_replace_strmem.c
-vgpreload_memcheck_so_DEPENDENCIES = $(LIBREPLACEMALLOC)
-vgpreload_memcheck_so_LDFLAGS      = \
-	-shared -Wl,-z,interpose,-z,initfirst \
-	-Wl,--whole-archive \
-	$(LIBREPLACEMALLOC) \
-	-Wl,--no-whole-archive
+vgpreload_memcheck_x86_linux_so_SOURCES      = $(VGPRELOAD_MEMCHECK_SOURCES_COMMON)
+vgpreload_memcheck_x86_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+vgpreload_memcheck_x86_linux_so_CFLAGS       = $(AM_CFLAGS_X86_LINUX) $(AM_CFLAGS_PIC) -O2
+vgpreload_memcheck_x86_linux_so_CCASFLAGS    = $(AM_CCASFLAGS_X86_LINUX)
+vgpreload_memcheck_x86_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_X86_LINUX)
+vgpreload_memcheck_x86_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_X86_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_X86_LINUX)
 
-memcheck_SOURCES = \
+vgpreload_memcheck_amd64_linux_so_SOURCES      = $(VGPRELOAD_MEMCHECK_SOURCES_COMMON)
+vgpreload_memcheck_amd64_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+vgpreload_memcheck_amd64_linux_so_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX) $(AM_CFLAGS_PIC) -O2
+vgpreload_memcheck_amd64_linux_so_CCASFLAGS    = $(AM_CCASFLAGS_AMD64_LINUX)
+vgpreload_memcheck_amd64_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_AMD64_LINUX)
+vgpreload_memcheck_amd64_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_AMD64_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_AMD64_LINUX)
+
+vgpreload_memcheck_ppc32_linux_so_SOURCES      = $(VGPRELOAD_MEMCHECK_SOURCES_COMMON)
+vgpreload_memcheck_ppc32_linux_so_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+vgpreload_memcheck_ppc32_linux_so_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX) $(AM_CFLAGS_PIC) -O2
+vgpreload_memcheck_ppc32_linux_so_CCASFLAGS    = $(AM_CCASFLAGS_PPC32_LINUX)
+vgpreload_memcheck_ppc32_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_PPC32_LINUX)
+vgpreload_memcheck_ppc32_linux_so_LDFLAGS      = \
+	$(PRELOAD_LDFLAGS_PPC32_LINUX) \
+	$(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX)
+
+MEMCHECK_SOURCES_COMMON = \
 	mac_leakcheck.c \
 	mac_malloc_wrappers.c \
 	mc_main.c \
 	mac_shared.c \
 	mc_translate.c
-memcheck_DEPENDENCIES = $(COREGRIND_LIBS)
-memcheck_LDADD        = $(TOOL_LINKADD)
-memcheck_LDFLAGS      = $(TOOL_LINKFLAGS)
+
+memcheck_x86_linux_SOURCES      = $(MEMCHECK_SOURCES_COMMON)
+memcheck_x86_linux_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+memcheck_x86_linux_CFLAGS       = $(AM_CFLAGS_X86_LINUX) -O2
+memcheck_x86_linux_CCASFLAGS    = $(AM_CCASFLAGS_X86_LINUX)
+memcheck_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX)
+memcheck_x86_linux_LDADD        = $(TOOL_LDADD_X86_LINUX)
+memcheck_x86_linux_LDFLAGS      = $(TOOL_LDFLAGS_X86_LINUX)
+
+memcheck_amd64_linux_SOURCES      = $(MEMCHECK_SOURCES_COMMON)
+memcheck_amd64_linux_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+memcheck_amd64_linux_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX) -O2
+memcheck_amd64_linux_CCASFLAGS    = $(AM_CCASFLAGS_AMD64_LINUX)
+memcheck_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX)
+memcheck_amd64_linux_LDADD        = $(TOOL_LDADD_AMD64_LINUX)
+memcheck_amd64_linux_LDFLAGS      = $(TOOL_LDFLAGS_AMD64_LINUX)
+
+memcheck_ppc32_linux_SOURCES      = $(MEMCHECK_SOURCES_COMMON)
+memcheck_ppc32_linux_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+memcheck_ppc32_linux_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX) -O2
+memcheck_ppc32_linux_CCASFLAGS    = $(AM_CCASFLAGS_PPC32_LINUX)
+memcheck_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
+memcheck_ppc32_linux_LDADD        = $(TOOL_LDADD_PPC32_LINUX)
+memcheck_ppc32_linux_LDFLAGS      = $(TOOL_LDFLAGS_PPC32_LINUX)
 
 mcincludedir = $(includedir)/valgrind
 
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index a60293e..8bf102a 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -140,9 +140,9 @@
 new_override_SOURCES 	= new_override.cpp
 
 # Valgrind unit self-tests
-hello_LDFLAGS		= -Wl,-defsym,valt_load_address=0x50000000 \
-			  -Wl,-T,$(top_builddir)/valt_load_address.lds
-hello_DEPENDENCIES 	= $(top_builddir)/valt_load_address.lds
+#hello_LDFLAGS		= -Wl,-defsym,valt_load_address=0x50000000 \
+#			  -Wl,-T,$(top_builddir)/valt_load_address.lds
+#hello_DEPENDENCIES 	= $(top_builddir)/valt_load_address.lds
 
 # vgtest_ume is not working
 #vgtest_ume_CFLAGS	= -DVGA_$(VG_ARCH) -DVGO_$(VG_OS)
diff --git a/none/Makefile.am b/none/Makefile.am
index 34d6b4c..01a501f 100644
--- a/none/Makefile.am
+++ b/none/Makefile.am
@@ -1,8 +1,35 @@
 include $(top_srcdir)/Makefile.tool.am
 
-val_PROGRAMS = none
+noinst_PROGRAMS = 
+if VG_X86_LINUX
+noinst_PROGRAMS += none-x86-linux
+endif
+if VG_AMD64_LINUX
+noinst_PROGRAMS += none-amd64-linux
+endif
+if VG_PPC32_LINUX
+noinst_PROGRAMS += none-ppc32-linux
+endif
 
-none_SOURCES      = nl_main.c
-none_DEPENDENCIES = $(COREGRIND_LIBS)
-none_LDADD        = $(TOOL_LINKADD)
-none_LDFLAGS      = $(TOOL_LINKFLAGS)
+NONE_SOURCES_COMMON = nl_main.c
+
+none_x86_linux_SOURCES      = $(NONE_SOURCES_COMMON)
+none_x86_linux_CPPFLAGS     = $(AM_CPPFLAGS_X86_LINUX)
+none_x86_linux_CFLAGS       = $(AM_CFLAGS_X86_LINUX)
+none_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX)
+none_x86_linux_LDADD        = $(TOOL_LDADD_X86_LINUX)
+none_x86_linux_LDFLAGS      = $(TOOL_LDFLAGS_X86_LINUX)
+
+none_amd64_linux_SOURCES      = $(NONE_SOURCES_COMMON)
+none_amd64_linux_CPPFLAGS     = $(AM_CPPFLAGS_AMD64_LINUX)
+none_amd64_linux_CFLAGS       = $(AM_CFLAGS_AMD64_LINUX)
+none_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX)
+none_amd64_linux_LDADD        = $(TOOL_LDADD_AMD64_LINUX)
+none_amd64_linux_LDFLAGS      = $(TOOL_LDFLAGS_AMD64_LINUX)
+
+none_ppc32_linux_SOURCES      = $(NONE_SOURCES_COMMON)
+none_ppc32_linux_CPPFLAGS     = $(AM_CPPFLAGS_PPC32_LINUX)
+none_ppc32_linux_CFLAGS       = $(AM_CFLAGS_PPC32_LINUX)
+none_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX)
+none_ppc32_linux_LDADD        = $(TOOL_LDADD_PPC32_LINUX)
+none_ppc32_linux_LDFLAGS      = $(TOOL_LDFLAGS_PPC32_LINUX)