Home | History | Annotate | Download | only in internals
      1 (for general information
      2   about gdbserver, read coregrind/m_gdbserver/README_DEVELOPERS
      3   about gdbserver tests, read gdbserver_tests/README_DEVELOPERS).
      4 
      5 ARM thumb and gdbserver
      6 -----------------------
      7 
      8 When executing thumb code, the ARM cpu program counter value is
      9 not equal to the address of the instruction being executed: the fact
     10 that the instruction being executed is a thumb instruction is
     11 encoded in the bit0 of the program counter.
     12 For more information about this, see VEX/pub/libvex_guest_arm.h.
     13 
     14 This additional bit set in the ARM guest_IP caused some difficulties
     15 at several places in the gdbserver code.
     16 
     17 
     18 * breakpoint handling:
     19   gdbsrv code detects that a breakpoint is reached
     20   by comparing the current guest_IP with the breakpoint addresses given
     21   by gdb. As gdb is giving breakpoints without the thumb bit set,
     22   the gdbsrv code has to ensure breakpoint comparisons are done without
     23   the thumb bit.
     24   => the breakpoints are stored in the gdbserver breakpoints hash table
     25   without the thumb bit.
     26   => when the guest_IP is compared with these breakpoints, the thumb bit
     27   must be masked.
     28 
     29 * Thumb bit in IstMark:
     30   When instrumenting a SB for gdbserver, a PUT of the current instruction
     31   address is done to the IP, to ensure that the gdbserver helper call
     32   sees the correct IP. This PUT must be done with the thumb bit set,
     33   as this value will be given back to gdb. gdb uses the thumb bit a.o.
     34   to guess the next program counter after this instruction.
     35   Such a guess is needed for gdb commands such as next/step/...
     36   If the thumb bit is not properly set, these commands are not working.
     37   As gdbserver instrumentation code uses the IstMark to find the IP
     38   of the instruction being instrumented, the thumb bit must be accessible
     39   or found. Multiple approaches were tried (see below) before the
     40   current one (which is to have a field Delta in IstMark which encodes
     41   the thumb bit).
     42 
     43 * Thumb bit in extents
     44   When a breakpoint is placed at an instruction, the translation for this
     45   instruction must be discarded to have the SB re-instrumented for gdbserver.
     46   At least at this moment (r2155/r11786), the extents for ARM/thumb blocks
     47   contains addresses with the thumb bit set. It is not clear that this is
     48   a good thing: extents should preferrably reference the real address range of
     49   instructions, not an adress range which can be "off by one" due to the
     50   fact that the instruction is a thumb instruction.
     51  
     52   Due to this "off by one", gdbserver is discarding a range of two bytes
     53   to ensure it is not sensitive to the presence (or not) of the thumb
     54   bit in the range being discarded.
     55 
     56 * Handling of monitor vg.translate
     57   When the translation is requested, the thumb bit must be properly set
     58   in the address, as this bit is used by the Valgrind translator
     59   to decide to decode in ARM or in thumb mode.
     60   The monitor command guesses the thumb bit based on the debug information.
     61 
     62 * gdb 7.0 is buggy with thumb code
     63   The logic of gdb to guess the next PC in thumb code is not working
     64   properly in version gdb 7.0. Several gdbserver tests are disabled
     65   on ARM if gdb version is < 7.1.
     66 
     67 * The (historical) list of difficulties encountered is the following:
     68   - initially, IstMark contained the thumb bit in the addr.
     69     This caused the breakpoints to not work (comparison between
     70     gdb address and gdbserver failed).
     71     (see breakpoint handling above).
     72   - A change was done to mask the thumb bit in the IstMark
     73     This made breakpoints work, but then gdb next/step/... was then failing
     74     (see Thumb bit in IstMark above).
     75   - So, it was needed to have the thumb bit when instrumenting an
     76     IstMark. 3 solutions were looked at:
     77      * use the debug info : this solution was discarded as often debug
     78        info does not allow a 100% correct solution. debug info is acceptable
     79        for vg.translate (which is only for internal valgrind debugging),
     80        but is better not used for 'end user functionnality'.
     81      * Derive the thumb bit for a SB from the extent address.
     82        This was discarded as this implies that an SB cannot mix thumb
     83        and ARM code. This implied to disable chasing at transition between
     84        ARM/thumb code, which potentially decreases performance.
     85        Also, it would oblige to keep the thumb bit in the extents, which
     86        seems not nice.
     87      * the final solution implemented was to add a Delta fied in IstMark.
     88        This Delta field gives the delta to add to the IstMark addr field
     89        to obtain the guest_IP : for thumb code, this field is 1,
     90        and is 0 for ARM code and for all other architectures.
     91