Home | History | Annotate | Download | only in vbit-test
      1 vbit-test
      2 
      3 The program tests the effect of an undefined input bit to an IROp on the
      4 definedness of the result of that operation. It also checks that only those
      5 bits in the result are undefined that we expect to be undefined. That way
      6 we can detect false positives (there are bits in the result that are
      7 undefined but shouldn't) and false negatives (there are defined bits in
      8 the result that should be undefined).
      9 
     10 By design, the tester will always be in-synch with the list of IROps
     11 in libvex_ir.h. Addition / removel of IROps will cause a compile or
     12 runtime error of the tester and thusly will not go unnoticed.
     13 
     14 
     15 How it works
     16 ------------
     17 The underlying idea is to
     18 (1) use VALGRIND_SET_VBITS to set the V-bits of the operands of an IROp
     19 (2) execute that IROp
     20 (3) use VALGRIND_GET_VBITS to obtain the V-bits of the result
     21 (4) compare the result against our expectation
     22 Do that for all IROps and for all input bits of their operands.
     23 For all this to work, the tester must run under the auspices of memcheck.
     24 
     25 The key step here is #2. To "execute an IROp" we need to inject some
     26 IR into the the superblock. This is accomplished by adding a new "special
     27 instruction" that is supported by all frontends. During the decoding step
     28 that instruction will be recognised and a suitable piece of IR will be
     29 inserted (function vex_inject_ir does just that). What is "suitable" depends
     30 on the IROp at hand and its operands. We need to know the addresses of
     31 those operands, their types and, trivially, which IROp we want to execute.
     32 This information is collected in the IR Injection Control Block (IRICB).
     33 To get the IRICB to VEX we use the new client request 
     34 VG_USERREQ__VEX_INIT_FOR_IRI.
     35 
     36 
     37 Invocation
     38 ----------
     39 Use   vbit-test --help   to obtain list of supported command line flags.
     40 
     41 
     42 Source code overview
     43 --------------------
     44 main.c
     45 Contains the main loop that iterates over all IROps in libvex_ir.h.
     46 Depending on the number of operands one of the functions test_unary,
     47 test_binary, etc. will be invoked to run all tests for that opreator.
     48 
     49 irops.c
     50 List of IROps. For each operator it defines how undefined input bits
     51 influence the output (result) and whether the operator is supported on a
     52 given architecture.
     53 
     54 util.c
     55 Miscellaneous convenience functions. It also includes sizeof_irtype and
     56 typeof_primop which were imported from VEX/priv/ir_defs.c.
     57 
     58 unary.c
     59 The function test_unary_op is the work horse. It iterates over all input
     60 bits of the single operand. For each such bit, the corresponding V-bit will
     61 be set to undefined, the IROps is executed and the resulting V-bits will
     62 be compared against the expected result.
     63 The function check_result_for_unary will check the V-bits for correctness.
     64 
     65 binary.c, ternary.c, qernary.c
     66 Like unary.c...
     67 
     68 valgrind.c
     69 The main function there is valgrind_execute_test. It will 
     70 (1) set the V-bits of the operands using the VALGRIND_SET_VBITS mechanism,
     71 (2) inject IR into the current IRSB to exacute a single IROp, and
     72 (3) obtain the V-bits of the result using the VALGRIND_GET_VBITS mechanism.
     73 The addresses of the operands and the result, as well as they V-bit vectors
     74 are stored in the test_data_t structure.
     75 
     76 <valgrind>/VEX/priv/ir_inject.c
     77 The file provides the function vex_inject_ir which will inject a piece of
     78 IR into the current IRSB based on the information provided in the IRICB.
     79 That code snippet will perform a single IR operation
     80 
     81 <valgrind>/include/valgrind.h
     82 Defines the macro VALGRIND_VEX_INJECT_IR for all architectures.
     83 Also defines a new client request VG_USERREQ__VEX_INIT_FOR_IRI.
     84 
     85 
     86 Adding a new IROp
     87 -----------------
     88 The following steps are needed
     89 (1) Add the operator to irops.c
     90 (2) If the operator propagates undefinedness from input to output in a new
     91     way:
     92     (a) Add a new enumerator to undef_t and document it there.
     93     (b) Add a new case in function check_result_for_XYZ depending on the
     94         arity of the operator. The code snippet there is supposed to check
     95         that the result matches what we expect.
     96 
     97 
     98 Status
     99 ------
    100 vbit-test has been tested on x86-64, ppc64, s390x, and mips32.
    101 There is support for other architectures in valgrind.h and guest_ARCH_toIR.c
    102 but it has not been tested. 
    103