Home | History | Annotate | Download | only in m_gdbserver
      1 /* Low level interface to valgrind, for the remote server for GDB integrated
      2    in valgrind.
      3    Copyright (C) 2011
      4    Free Software Foundation, Inc.
      5 
      6    This file is part of VALGRIND.
      7    It has been inspired from a file from gdbserver in gdb 6.6.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 2 of the License, or
     12    (at your option) any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program; if not, write to the Free Software
     21    Foundation, Inc., 51 Franklin Street, Fifth Floor,
     22    Boston, MA 02110-1301, USA.  */
     23 
     24 #include "server.h"
     25 #include "target.h"
     26 #include "regdef.h"
     27 #include "regcache.h"
     28 
     29 #include "pub_core_machine.h"
     30 #include "pub_core_debuginfo.h"
     31 #include "pub_core_threadstate.h"
     32 #include "pub_core_transtab.h"
     33 #include "pub_core_gdbserver.h"
     34 
     35 #include "valgrind_low.h"
     36 
     37 #include "libvex_guest_mips64.h"
     38 
     39 static struct reg regs[] = {
     40    { "r0", 0, 64 },
     41    { "r1", 64, 64 },
     42    { "r2", 128, 64 },
     43    { "r3", 192, 64 },
     44    { "r4", 256, 64 },
     45    { "r5", 320, 64 },
     46    { "r6", 384, 64 },
     47    { "r7", 448, 64 },
     48    { "r8", 512, 64 },
     49    { "r9", 576, 64 },
     50    { "r10", 640, 64 },
     51    { "r11", 704, 64 },
     52    { "r12", 768, 64 },
     53    { "r13", 832, 64 },
     54    { "r14", 896, 64 },
     55    { "r15", 960, 64 },
     56    { "r16", 1024, 64 },
     57    { "r17", 1088, 64 },
     58    { "r18", 1152, 64 },
     59    { "r19", 1216, 64 },
     60    { "r20", 1280, 64 },
     61    { "r21", 1344, 64 },
     62    { "r22", 1408, 64 },
     63    { "r23", 1472, 64 },
     64    { "r24", 1536, 64 },
     65    { "r25", 1600, 64 },
     66    { "r26", 1664, 64 },
     67    { "r27", 1728, 64 },
     68    { "r28", 1792, 64 },
     69    { "r29", 1856, 64 },
     70    { "r30", 1920, 64 },
     71    { "r31", 1984, 64 },
     72    { "status", 2048, 64 },
     73    { "lo", 2112, 64 },
     74    { "hi", 2176, 64 },
     75    { "badvaddr", 2240, 64 },
     76    { "cause", 2304, 64 },
     77    { "pc", 2368, 64 },
     78    { "f0", 2432, 64 },
     79    { "f1", 2496, 64 },
     80    { "f2", 2560, 64 },
     81    { "f3", 2624, 64 },
     82    { "f4", 2688, 64 },
     83    { "f5", 2752, 64 },
     84    { "f6", 2816, 64 },
     85    { "f7", 2880, 64 },
     86    { "f8", 2944, 64 },
     87    { "f9", 3008, 64 },
     88    { "f10", 3072, 64 },
     89    { "f11", 3136, 64 },
     90    { "f12", 3200, 64 },
     91    { "f13", 3264, 64 },
     92    { "f14", 3328, 64 },
     93    { "f15", 3392, 64 },
     94    { "f16", 3456, 64 },
     95    { "f17", 3520, 64 },
     96    { "f18", 3584, 64 },
     97    { "f19", 3648, 64 },
     98    { "f20", 3712, 64 },
     99    { "f21", 3776, 64 },
    100    { "f22", 3840, 64 },
    101    { "f23", 3904, 64 },
    102    { "f24", 3968, 64 },
    103    { "f25", 4032, 64 },
    104    { "f26", 4096, 64 },
    105    { "f27", 4160, 64 },
    106    { "f28", 4224, 64 },
    107    { "f29", 4288, 64 },
    108    { "f30", 4352, 64 },
    109    { "f31", 4416, 64 },
    110    { "fcsr", 4480, 64 },
    111    { "fir", 4544, 64 },
    112    { "restart", 4608, 64 }
    113 };
    114 
    115 
    116 #define num_regs (sizeof (regs) / sizeof (regs[0]))
    117 
    118 static const char *expedite_regs[] = { "r29", "pc", 0 };
    119 
    120 static
    121 CORE_ADDR get_pc (void)
    122 {
    123    unsigned long pc;
    124 
    125    collect_register_by_name ("pc", &pc);
    126 
    127    dlog(1, "stop pc is %p\n", (void *) pc);
    128    return pc;
    129 }
    130 
    131 static
    132 void set_pc (CORE_ADDR newpc)
    133 {
    134    Bool mod;
    135    supply_register_by_name ("pc", &newpc, &mod);
    136    if (mod)
    137       dlog(1, "set pc to %p\n", C2v (newpc));
    138    else
    139       dlog(1, "set pc not changed %p\n", C2v (newpc));
    140 }
    141 
    142 /* These are the fields of 32 bit mips instructions. */
    143 #define itype_op(x) (x >> 26)
    144 #define itype_rs(x) ((x >> 21) & 0x1f)
    145 #define itype_rt(x) ((x >> 16) & 0x1f)
    146 #define rtype_funct(x) (x & 0x3f)
    147 
    148 /* Do a endian load of a 32-bit word, regardless of the
    149    endianness of the underlying host. */
    150 static inline UInt getUInt(UChar * p)
    151 {
    152    UInt w = 0;
    153 #if defined (_MIPSEL)
    154    w = (w << 8) | p[3];
    155    w = (w << 8) | p[2];
    156    w = (w << 8) | p[1];
    157    w = (w << 8) | p[0];
    158 #elif defined (_MIPSEB)
    159    w = (w << 8) | p[0];
    160    w = (w << 8) | p[1];
    161    w = (w << 8) | p[2];
    162    w = (w << 8) | p[3];
    163 #endif
    164    return w;
    165 }
    166 
    167 /* Return non-zero if the ADDR instruction has a branch delay slot
    168    (i.e. it is a jump or branch instruction). */
    169 static UInt
    170 mips_instruction_has_delay_slot (Addr addr)
    171 {
    172    UInt op, rs, rt;
    173    UInt inst = getUInt((UChar *)addr);
    174 
    175    op = itype_op (inst);
    176    if ((inst & 0xe0000000) != 0) {
    177       rs = itype_rs (inst);
    178       rt = itype_rt (inst);
    179       return (op >> 2 == 5        /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx  */
    180               || op == 29         /* JALX: bits 011101  */
    181               || (op == 17
    182                   && (rs == 8     /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000  */
    183                       || (rs == 9 && (rt & 0x2) == 0)
    184                                   /* BC1ANY2F, BC1ANY2T: bits 010001 01001  */
    185                       || (rs == 10 && (rt & 0x2) == 0))));
    186                                   /* BC1ANY4F, BC1ANY4T: bits 010001 01010  */
    187    } else
    188       switch (op & 0x07) {        /* extract bits 28,27,26  */
    189          case 0:                  /* SPECIAL  */
    190             op = rtype_funct (inst);
    191          return (op == 8          /* JR  */
    192                  || op == 9);     /* JALR  */
    193          break;                   /* end SPECIAL  */
    194          case 1:                  /* REGIMM  */
    195             rs = itype_rs (inst);
    196             rt = itype_rt (inst); /* branch condition  */
    197             return ((rt & 0xc) == 0
    198                                   /* BLTZ, BLTZL, BGEZ, BGEZL: bits 000xx  */
    199                                   /* BLTZAL, BLTZALL, BGEZAL, BGEZALL: 100xx  */
    200                     || ((rt & 0x1e) == 0x1c && rs == 0));
    201                                   /* BPOSGE32, BPOSGE64: bits 1110x  */
    202             break;                /* end REGIMM  */
    203          default:                 /* J, JAL, BEQ, BNE, BLEZ, BGTZ  */
    204             return 1;
    205             break;
    206    }
    207 }
    208 
    209 /* Move the breakpoint at BPADDR out of any branch delay slot by shifting
    210    it backwards if necessary.  Return the address of the new location.  */
    211 static Addr mips_adjust_breakpoint_address (Addr pc)
    212 {
    213    Addr prev_addr;
    214    Addr boundary;
    215    Addr func_addr;
    216    Addr bpaddr = pc;
    217    Addr mask = (Addr)0xffffffffffffffffULL;
    218    int segsize;
    219    PtrdiffT offset;
    220 
    221    /* Calculate the starting address of the MIPS memory segment pc is in. */
    222    if (bpaddr & 0x80000000)  /* kernel segment */
    223       segsize = 29;
    224    else
    225       segsize = 31;          /* user segment */
    226    mask <<= segsize;
    227    boundary = pc & mask;
    228 
    229    /* Make sure we don't scan back before the beginning of the current
    230       function, since we may fetch constant data or insns that look like
    231       a jump. */
    232    if (VG_(get_inst_offset_in_function) (bpaddr, &offset)) {
    233       func_addr = bpaddr - offset;
    234       if (func_addr > boundary && func_addr <= bpaddr)
    235          boundary = func_addr;
    236    }
    237 
    238    if (bpaddr == boundary)
    239       return bpaddr;
    240    /* If the previous instruction has a branch delay slot, we have
    241       to move the breakpoint to the branch instruction. */
    242    prev_addr = bpaddr - 4;
    243    if (mips_instruction_has_delay_slot (prev_addr))
    244       bpaddr = prev_addr;
    245 
    246    return bpaddr;
    247 }
    248 
    249 /* store registers in the guest state (gdbserver_to_valgrind)
    250    or fetch register from the guest state (valgrind_to_gdbserver). */
    251 static
    252 void transfer_register (ThreadId tid, int abs_regno, void * buf,
    253                         transfer_direction dir, int size, Bool *mod)
    254 {
    255    ThreadState* tst = VG_(get_ThreadState)(tid);
    256    int set = abs_regno / num_regs;
    257    int regno = abs_regno % num_regs;
    258    *mod = False;
    259 
    260    VexGuestMIPS64State* mips1 = (VexGuestMIPS64State*) get_arch (set, tst);
    261 
    262    switch (regno) {
    263    case 0:  VG_(transfer) (&mips1->guest_r0,  buf, dir, size, mod); break;
    264    case 1:  VG_(transfer) (&mips1->guest_r1,  buf, dir, size, mod); break;
    265    case 2:  VG_(transfer) (&mips1->guest_r2,  buf, dir, size, mod); break;
    266    case 3:  VG_(transfer) (&mips1->guest_r3,  buf, dir, size, mod); break;
    267    case 4:  VG_(transfer) (&mips1->guest_r4,  buf, dir, size, mod); break;
    268    case 5:  VG_(transfer) (&mips1->guest_r5,  buf, dir, size, mod); break;
    269    case 6:  VG_(transfer) (&mips1->guest_r6,  buf, dir, size, mod); break;
    270    case 7:  VG_(transfer) (&mips1->guest_r7,  buf, dir, size, mod); break;
    271    case 8:  VG_(transfer) (&mips1->guest_r8,  buf, dir, size, mod); break;
    272    case 9:  VG_(transfer) (&mips1->guest_r9,  buf, dir, size, mod); break;
    273    case 10: VG_(transfer) (&mips1->guest_r10,  buf, dir, size, mod); break;
    274    case 11: VG_(transfer) (&mips1->guest_r11,  buf, dir, size, mod); break;
    275    case 12: VG_(transfer) (&mips1->guest_r12, buf, dir, size, mod); break;
    276    case 13: VG_(transfer) (&mips1->guest_r13, buf, dir, size, mod); break;
    277    case 14: VG_(transfer) (&mips1->guest_r14, buf, dir, size, mod); break;
    278    case 15: VG_(transfer) (&mips1->guest_r15, buf, dir, size, mod); break;
    279    case 16: VG_(transfer) (&mips1->guest_r16, buf, dir, size, mod); break;
    280    case 17: VG_(transfer) (&mips1->guest_r17, buf, dir, size, mod); break;
    281    case 18: VG_(transfer) (&mips1->guest_r18,  buf, dir, size, mod); break;
    282    case 19: VG_(transfer) (&mips1->guest_r19,  buf, dir, size, mod); break;
    283    case 20: VG_(transfer) (&mips1->guest_r20,  buf, dir, size, mod); break;
    284    case 21: VG_(transfer) (&mips1->guest_r21,  buf, dir, size, mod); break;
    285    case 22: VG_(transfer) (&mips1->guest_r22,  buf, dir, size, mod); break;
    286    case 23: VG_(transfer) (&mips1->guest_r23,  buf, dir, size, mod); break;
    287    case 24: VG_(transfer) (&mips1->guest_r24,  buf, dir, size, mod); break;
    288    case 25: VG_(transfer) (&mips1->guest_r25,  buf, dir, size, mod); break;
    289    case 26: VG_(transfer) (&mips1->guest_r26,  buf, dir, size, mod); break;
    290    case 27: VG_(transfer) (&mips1->guest_r27,  buf, dir, size, mod); break;
    291    case 28: VG_(transfer) (&mips1->guest_r28, buf, dir, size, mod); break;
    292    case 29: VG_(transfer) (&mips1->guest_r29, buf, dir, size, mod); break;
    293    case 30: VG_(transfer) (&mips1->guest_r30, buf, dir, size, mod); break;
    294    case 31: VG_(transfer) (&mips1->guest_r31, buf, dir, size, mod); break;
    295    case 32: *mod = False; break; // GDBTD???? VEX { "status", 1024, 64 }
    296    case 33: VG_(transfer) (&mips1->guest_LO, buf, dir, size, mod); break;
    297    case 34: VG_(transfer) (&mips1->guest_HI, buf, dir, size, mod); break;
    298    case 35: *mod = False; break; // GDBTD???? VEX { "badvaddr", 1120, 64 },
    299    case 36: *mod = False; break; // GDBTD???? VEX { "cause", 1152, 64 },
    300    case 37:
    301       /* If a breakpoint is set on the instruction in a branch delay slot,
    302          GDB gets confused.  When the breakpoint is hit, the PC isn't on
    303          the instruction in the branch delay slot, the PC will point to
    304          the branch instruction. */
    305       mips1->guest_PC = mips_adjust_breakpoint_address(mips1->guest_PC);
    306       VG_(transfer) (&mips1->guest_PC,  buf, dir, size, mod);
    307       break;
    308    case 38: VG_(transfer) (&mips1->guest_f0,  buf, dir, size, mod); break;
    309    case 39: VG_(transfer) (&mips1->guest_f1,  buf, dir, size, mod); break;
    310    case 40: VG_(transfer) (&mips1->guest_f2,  buf, dir, size, mod); break;
    311    case 41: VG_(transfer) (&mips1->guest_f3,  buf, dir, size, mod); break;
    312    case 42: VG_(transfer) (&mips1->guest_f4,  buf, dir, size, mod); break;
    313    case 43: VG_(transfer) (&mips1->guest_f5,  buf, dir, size, mod); break;
    314    case 44: VG_(transfer) (&mips1->guest_f6,  buf, dir, size, mod); break;
    315    case 45: VG_(transfer) (&mips1->guest_f7, buf, dir, size, mod); break;
    316    case 46: VG_(transfer) (&mips1->guest_f8, buf, dir, size, mod); break;
    317    case 47: VG_(transfer) (&mips1->guest_f9, buf, dir, size, mod); break;
    318    case 48: VG_(transfer) (&mips1->guest_f10, buf, dir, size, mod); break;
    319    case 49: VG_(transfer) (&mips1->guest_f11, buf, dir, size, mod); break;
    320    case 50: VG_(transfer) (&mips1->guest_f12, buf, dir, size, mod); break;
    321    case 51: VG_(transfer) (&mips1->guest_f13,  buf, dir, size, mod); break;
    322    case 52: VG_(transfer) (&mips1->guest_f14,  buf, dir, size, mod); break;
    323    case 53: VG_(transfer) (&mips1->guest_f15,  buf, dir, size, mod); break;
    324    case 54: VG_(transfer) (&mips1->guest_f16,  buf, dir, size, mod); break;
    325    case 55: VG_(transfer) (&mips1->guest_f17,  buf, dir, size, mod); break;
    326    case 56: VG_(transfer) (&mips1->guest_f18,  buf, dir, size, mod); break;
    327    case 57: VG_(transfer) (&mips1->guest_f19, buf, dir, size, mod); break;
    328    case 58: VG_(transfer) (&mips1->guest_f20, buf, dir, size, mod); break;
    329    case 59: VG_(transfer) (&mips1->guest_f21, buf, dir, size, mod); break;
    330    case 60: VG_(transfer) (&mips1->guest_f22, buf, dir, size, mod); break;
    331    case 61: VG_(transfer) (&mips1->guest_f23, buf, dir, size, mod); break;
    332    case 62: VG_(transfer) (&mips1->guest_f24,  buf, dir, size, mod); break;
    333    case 63: VG_(transfer) (&mips1->guest_f25,  buf, dir, size, mod); break;
    334    case 64: VG_(transfer) (&mips1->guest_f26,  buf, dir, size, mod); break;
    335    case 65: VG_(transfer) (&mips1->guest_f27,  buf, dir, size, mod); break;
    336    case 66: VG_(transfer) (&mips1->guest_f28,  buf, dir, size, mod); break;
    337    case 67: VG_(transfer) (&mips1->guest_f29,  buf, dir, size, mod); break;
    338    case 68: VG_(transfer) (&mips1->guest_f30, buf, dir, size, mod); break;
    339    case 69: VG_(transfer) (&mips1->guest_f31, buf, dir, size, mod); break;
    340    case 70: VG_(transfer) (&mips1->guest_FCSR, buf, dir, size, mod); break;
    341    case 71: VG_(transfer) (&mips1->guest_FIR, buf, dir, size, mod); break;
    342    case 72: *mod = False; break; // GDBTD???? VEX{ "restart", 2304, 64 },
    343    default: VG_(printf)("regno: %d\n", regno); vg_assert(0);
    344    }
    345 }
    346 
    347 static
    348 const char* target_xml (Bool shadow_mode)
    349 {
    350    if (shadow_mode) {
    351       return "mips64-linux-valgrind.xml";
    352    } else {
    353       return "mips64-linux.xml";
    354    }
    355 }
    356 
    357 static CORE_ADDR** target_get_dtv (ThreadState *tst)
    358 {
    359    VexGuestMIPS64State* mips64 = (VexGuestMIPS64State*)&tst->arch.vex;
    360    // mips64 dtv location similar to ppc64
    361    return (CORE_ADDR**)((CORE_ADDR)mips64->guest_ULR
    362                         - 0x7000 - sizeof(CORE_ADDR));
    363 }
    364 
    365 static struct valgrind_target_ops low_target = {
    366    num_regs,
    367    regs,
    368    29, //sp = r29, which is register offset 29 in regs
    369    transfer_register,
    370    get_pc,
    371    set_pc,
    372    "mips64",
    373    target_xml,
    374    target_get_dtv
    375 };
    376 
    377 void mips64_init_architecture (struct valgrind_target_ops *target)
    378 {
    379    *target = low_target;
    380    set_register_cache (regs, num_regs);
    381    gdbserver_expedite_regs = expedite_regs;
    382 }
    383