------------------------------------------------------------------- Guide to multiple architecture support ------------------------------------------------------------------- What is achieved ~~~~~~~~~~~~~~~~ Valgrind supports systems where binaries for more than one architecture can be run. The current arrangements build: - single-arch support on x86 and ppc32 systems - dual-arch support on amd64 and ppc64 systems To support this the valgrind build system can now build multiple versions of the coregrind library and of VEX, and then build and link multiple versions of each tool. A central notion is that of 'primary' vs 'secondary' platforms. The system is built in its entirety for the primary platform, including performance and regression suites and all auxiliary programs. For dual-arch systems, the primary platform is amd64 and ppc64 respectively. On dual-arch systems, there is a 'secondary' target - x86 and ppc32 respectively. The tools are built again for the secondary target, and the 'valgrind' launcher program can handle executables for either the primary or secondary target. However, the regression and performance tests and everything else is not rebuilt for the secondary target. On single-arch systems, there is no secondary target. How the build system does that ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The keys to understanding this are in: - configure.in - Makefile.flags.am - <tool>/tests/Makefile.am - <tool>/tests/<arch>/Makefile.am - perf/Makefile.am The configure script inspects the CPU. It then sets VGCONF_PLATFORM_PRI_CAPS to be the primary target VGCONF_PLATFORM_SEC_CAPS to be the secondary target, if any It also sets one (single-arch build) or two (dual-arch build) of the following: VGCONF_PLATFORMS_INCLUDE_X86_LINUX VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX ... On an amd64 system both VGCONF_PLATFORMS_INCLUDE_X86_LINUX and VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX will be true so that two versions of all the tools will be built. Similarly on a ppc64 system both VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX and VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX will be defined (unless --enable-only32bit or --enable-only64bit is used). For the amd64 example, the coregrind libraries will be named: libcoregrind_x86_linux.a libcoregrind_amd64_linux.a and the VEX libraries: libvex_x86_linux.a libvex_amd64_linux.a Each tool will then be built twice, along with any preload library for the tool and the core preload libraries. At install time one subdirectory will be created in the valgrind library directory for each supported platforms and the tools and shared objects will be installed in the appropriate place. On amd64 the result will be: <prefix>/lib/valgrind <prefix>/lib/valgrind/default.supp <prefix>/lib/valgrind/glibc-2.4.supp <prefix>/lib/valgrind/hp2ps <prefix>/lib/valgrind/amd64-linux <prefix>/lib/valgrind/amd64-linux/vgpreload_core.so <prefix>/lib/valgrind/amd64-linux/vgpreload_massif.so <prefix>/lib/valgrind/amd64-linux/cachegrind <prefix>/lib/valgrind/amd64-linux/memcheck <prefix>/lib/valgrind/amd64-linux/helgrind <prefix>/lib/valgrind/amd64-linux/massif <prefix>/lib/valgrind/amd64-linux/vgpreload_memcheck.so <prefix>/lib/valgrind/amd64-linux/lackey <prefix>/lib/valgrind/amd64-linux/none <prefix>/lib/valgrind/amd64-linux/vgpreload_helgrind.so <prefix>/lib/valgrind/xfree-3.supp <prefix>/lib/valgrind/x86-linux <prefix>/lib/valgrind/x86-linux/vgpreload_core.so <prefix>/lib/valgrind/x86-linux/vgpreload_massif.so <prefix>/lib/valgrind/x86-linux/cachegrind <prefix>/lib/valgrind/x86-linux/memcheck <prefix>/lib/valgrind/x86-linux/helgrind <prefix>/lib/valgrind/x86-linux/massif <prefix>/lib/valgrind/x86-linux/vgpreload_memcheck.so <prefix>/lib/valgrind/x86-linux/lackey <prefix>/lib/valgrind/x86-linux/none <prefix>/lib/valgrind/x86-linux/vgpreload_helgrind.so <prefix>/lib/valgrind/glibc-2.3.supp <prefix>/lib/valgrind/xfree-4.supp <prefix>/lib/valgrind/glibc-2.2.supp The launcher program (ie the valgrind binary itself) is always built as a program for the primary target (so a 64 bit program on amd64 and ppc64) but will peek at the program which it is being asked to run and decide which of the possible tools to run taking both the requested tool and the format of the program being run into account. Because the execv system call is now routed back through the launcher it is also possible to exec an x86 program from an amd64 program and vice versa. Ditto ppc32 and ppc64. Rules for Makefile.am hacking ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In places where compilation should happen twice (on a dual-arch system), the decision about which directories and flags to use is guarded by the VGCONF_PLATFORMS_INCLUDE_* symbols. But there are also places where building must only happen once, for the primary architecture. These places are (at least): * the launcher, valgrind.c * all the architecture-independent regression tests * the performance tests * optionally, auxilary programs like hp2ps and valgrind-listener In order to do that, we need to know what flags to use to build for the primary target, and in particular whether to hand -m32 or -m64 to gcc. This is where Makefile.flags.am comes in. At the bottom of that file are defined AM_CPPFLAGS_PRI, AM_CFLAGS_PRI and AM_CCASFLAGS_PRI that must be used for compiling for the primary architecture. For example, look in coregrind/Makefile.am, and you will see these flag-sets being used to build the launcher (valgrind). Also at the bottom of Makefile.flags.am, AM_FLAG_M3264_PRI is defined. This gives the -m32/-m64 flag needed to build for the primary target. That flag is also contained within AM_CFLAGS_PRI -- AM_FLAG_M3264_PRI merely facilitates getting hold of it without the surrounding gunk. This leads to the final complication: building the regression tests. Most of them are architecture-neutral and so should be built for the primary target. The /test/ Makefile.am's duly include AM_FLAG_M3264_PRI in the compilation invokations, and you should ensure you preserve that when adding more tests. However, there are some arch-specific test directories (eg, none/tests/ppc32, etc). In each of these, we implicitly 'know' whether -m32 or -m64 is the right thing to specify. So instead of messing with AM_FLAG_M3264_PRI, these directories merely specific @FLAG_M32@ or @FLAG_M64@ directly. (These two symbols are also automagically set up by configure.in. Do not use -m32 and -m64 directly - older compilers barf on them). Another reason not to use -m32 and -m64 directly is that they are called -maix32 and -maix64 on AIX; once again this is taken care of properly if you use @FLAG_M32@ and @FLAG_M64@ instead.