Home | History | Annotate | Download | only in internals
      1 -------------------------------------------------------------------
      2 Guide to multiple architecture support
      3 -------------------------------------------------------------------
      4 
      5 What is achieved
      6 ~~~~~~~~~~~~~~~~
      7 Valgrind supports systems where binaries for more than one
      8 architecture can be run.  The current arrangements build:
      9 
     10 - single-arch support on x86 and ppc32 systems
     11 - dual-arch support on amd64 and ppc64 systems
     12 
     13 To support this the valgrind build system can now build multiple
     14 versions of the coregrind library and of VEX, and then build and link
     15 multiple versions of each tool.
     16 
     17 A central notion is that of 'primary' vs 'secondary' platforms.  The
     18 system is built in its entirety for the primary platform, including
     19 performance and regression suites and all auxiliary programs.  For
     20 dual-arch systems, the primary platform is amd64 and ppc64
     21 respectively.
     22 
     23 On dual-arch systems, there is a 'secondary' target - x86 and ppc32 
     24 respectively.  The tools are built again for the secondary target, and
     25 the 'valgrind' launcher program can handle executables for either the 
     26 primary or secondary target.  However, the regression and performance
     27 tests and everything else is not rebuilt for the secondary target.
     28 
     29 On single-arch systems, there is no secondary target.
     30 
     31 
     32 How the build system does that
     33 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     34 The keys to understanding this are in:
     35 
     36 - configure.in
     37 - Makefile.flags.am
     38 - <tool>/tests/Makefile.am
     39 - <tool>/tests/<arch>/Makefile.am
     40 - perf/Makefile.am
     41 
     42 The configure script inspects the CPU.  It then sets
     43 
     44    VGCONF_PLATFORM_PRI_CAPS to be the primary target
     45    VGCONF_PLATFORM_SEC_CAPS to be the secondary target, if any
     46 
     47 It also sets one (single-arch build) or two (dual-arch build) of
     48 the following:
     49 
     50   VGCONF_PLATFORMS_INCLUDE_X86_LINUX
     51   VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX
     52   VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX
     53   VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX
     54   ...
     55 
     56 On an amd64 system both VGCONF_PLATFORMS_INCLUDE_X86_LINUX and
     57 VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX will be true so that two versions of
     58 all the tools will be built.  Similarly on a ppc64 system both
     59 VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX and
     60 VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX will be defined (unless
     61 --enable-only32bit or --enable-only64bit is used).  For the amd64 example,
     62  the coregrind libraries will be named:
     63 
     64   libcoregrind_x86_linux.a
     65   libcoregrind_amd64_linux.a
     66 
     67 and the VEX libraries:
     68 
     69   libvex_x86_linux.a
     70   libvex_amd64_linux.a
     71 
     72 Each tool will then be built twice, along with any preload library
     73 for the tool and the core preload libraries. At install time one
     74 subdirectory will be created in the valgrind library directory for
     75 each supported platforms and the tools and shared objects will be
     76 installed in the appropriate place. On amd64 the result will be:
     77 
     78   <prefix>/lib/valgrind
     79   <prefix>/lib/valgrind/default.supp
     80   <prefix>/lib/valgrind/glibc-2.4.supp
     81   <prefix>/lib/valgrind/hp2ps
     82   <prefix>/lib/valgrind/amd64-linux
     83   <prefix>/lib/valgrind/amd64-linux/vgpreload_core.so
     84   <prefix>/lib/valgrind/amd64-linux/vgpreload_massif.so
     85   <prefix>/lib/valgrind/amd64-linux/cachegrind
     86   <prefix>/lib/valgrind/amd64-linux/memcheck
     87   <prefix>/lib/valgrind/amd64-linux/helgrind
     88   <prefix>/lib/valgrind/amd64-linux/massif
     89   <prefix>/lib/valgrind/amd64-linux/vgpreload_memcheck.so
     90   <prefix>/lib/valgrind/amd64-linux/lackey
     91   <prefix>/lib/valgrind/amd64-linux/none
     92   <prefix>/lib/valgrind/amd64-linux/vgpreload_helgrind.so
     93   <prefix>/lib/valgrind/xfree-3.supp
     94   <prefix>/lib/valgrind/x86-linux
     95   <prefix>/lib/valgrind/x86-linux/vgpreload_core.so
     96   <prefix>/lib/valgrind/x86-linux/vgpreload_massif.so
     97   <prefix>/lib/valgrind/x86-linux/cachegrind
     98   <prefix>/lib/valgrind/x86-linux/memcheck
     99   <prefix>/lib/valgrind/x86-linux/helgrind
    100   <prefix>/lib/valgrind/x86-linux/massif
    101   <prefix>/lib/valgrind/x86-linux/vgpreload_memcheck.so
    102   <prefix>/lib/valgrind/x86-linux/lackey
    103   <prefix>/lib/valgrind/x86-linux/none
    104   <prefix>/lib/valgrind/x86-linux/vgpreload_helgrind.so
    105   <prefix>/lib/valgrind/glibc-2.3.supp
    106   <prefix>/lib/valgrind/xfree-4.supp
    107   <prefix>/lib/valgrind/glibc-2.2.supp
    108 
    109 The launcher program (ie the valgrind binary itself) is always built
    110 as a program for the primary target (so a 64 bit program on amd64 and
    111 ppc64) but will peek at the program which it is being asked to run and
    112 decide which of the possible tools to run taking both the requested
    113 tool and the format of the program being run into account.
    114 
    115 Because the execv system call is now routed back through the launcher
    116 it is also possible to exec an x86 program from an amd64 program and
    117 vice versa.  Ditto ppc32 and ppc64.
    118 
    119 
    120 Rules for Makefile.am hacking
    121 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    122 In places where compilation should happen twice (on a dual-arch
    123 system), the decision about which directories and flags to use is
    124 guarded by the VGCONF_PLATFORMS_INCLUDE_* symbols.
    125 
    126 But there are also places where building must only happen once,
    127 for the primary architecture.  These places are (at least):
    128 
    129 * the launcher, valgrind.c
    130 * all the architecture-independent regression tests
    131 * the performance tests
    132 * optionally, auxilary programs like hp2ps and valgrind-listener
    133 
    134 In order to do that, we need to know what flags to use to build for
    135 the primary target, and in particular whether to hand -m32 or -m64 to
    136 gcc.  This is where Makefile.flags.am comes in.
    137 
    138 At the bottom of that file are defined AM_CPPFLAGS_PRI, AM_CFLAGS_PRI
    139 and AM_CCASFLAGS_PRI that must be used for compiling for the primary
    140 architecture.  For example, look in coregrind/Makefile.am, and you
    141 will see these flag-sets being used to build the launcher (valgrind).
    142 
    143 Also at the bottom of Makefile.flags.am, AM_FLAG_M3264_PRI is defined.
    144 This gives the -m32/-m64 flag needed to build for the primary target.
    145 That flag is also contained within AM_CFLAGS_PRI -- AM_FLAG_M3264_PRI
    146 merely facilitates getting hold of it without the surrounding gunk.
    147 
    148 This leads to the final complication: building the regression tests.
    149 Most of them are architecture-neutral and so should be built for the
    150 primary target.  The /test/ Makefile.am's duly include
    151 AM_FLAG_M3264_PRI in the compilation invokations, and you should
    152 ensure you preserve that when adding more tests.
    153 
    154 However, there are some arch-specific test directories (eg,
    155 none/tests/ppc32, etc).  In each of these, we implicitly 'know'
    156 whether -m32 or -m64 is the right thing to specify.  So instead of
    157 messing with AM_FLAG_M3264_PRI, these directories merely specific
    158 @FLAG_M32@ or @FLAG_M64@ directly.  (These two symbols are also
    159 automagically set up by configure.in.  Do not use -m32 and -m64
    160 directly - older compilers barf on them).  Another reason not to
    161 use -m32 and -m64 directly is that they are called -maix32 and 
    162 -maix64 on AIX; once again this is taken care of properly if you
    163 use @FLAG_M32@ and @FLAG_M64@ instead.
    164