qemu/target/i386/gdbstub.c
<<
>>
Prefs
   1/*
   2 * x86 gdb server stub
   3 *
   4 * Copyright (c) 2003-2005 Fabrice Bellard
   5 * Copyright (c) 2013 SUSE LINUX Products GmbH
   6 *
   7 * This library is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU Lesser General Public
   9 * License as published by the Free Software Foundation; either
  10 * version 2.1 of the License, or (at your option) any later version.
  11 *
  12 * This library is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * Lesser General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public
  18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20#include "qemu/osdep.h"
  21#include "cpu.h"
  22#include "include/gdbstub/helpers.h"
  23
  24#ifdef TARGET_X86_64
  25static const int gpr_map[16] = {
  26    R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP,
  27    8, 9, 10, 11, 12, 13, 14, 15
  28};
  29#else
  30#define gpr_map gpr_map32
  31#endif
  32static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
  33
  34/*
  35 * Keep these in sync with assignment to
  36 * gdb_num_core_regs in target/i386/cpu.c
  37 * and with the machine description
  38 */
  39
  40/*
  41 * SEG: 6 segments, plus fs_base, gs_base, kernel_gs_base
  42 */
  43
  44/*
  45 * general regs ----->  8 or 16
  46 */
  47#define IDX_NB_IP       1
  48#define IDX_NB_FLAGS    1
  49#define IDX_NB_SEG      (6 + 3)
  50#define IDX_NB_CTL      6
  51#define IDX_NB_FP       16
  52/*
  53 * fpu regs ----------> 8 or 16
  54 */
  55#define IDX_NB_MXCSR    1
  56/*
  57 *          total ----> 8+1+1+9+6+16+8+1=50 or 16+1+1+9+6+16+16+1=66
  58 */
  59
  60#define IDX_IP_REG      CPU_NB_REGS
  61#define IDX_FLAGS_REG   (IDX_IP_REG + IDX_NB_IP)
  62#define IDX_SEG_REGS    (IDX_FLAGS_REG + IDX_NB_FLAGS)
  63#define IDX_CTL_REGS    (IDX_SEG_REGS + IDX_NB_SEG)
  64#define IDX_FP_REGS     (IDX_CTL_REGS + IDX_NB_CTL)
  65#define IDX_XMM_REGS    (IDX_FP_REGS + IDX_NB_FP)
  66#define IDX_MXCSR_REG   (IDX_XMM_REGS + CPU_NB_REGS)
  67
  68#define IDX_CTL_CR0_REG     (IDX_CTL_REGS + 0)
  69#define IDX_CTL_CR2_REG     (IDX_CTL_REGS + 1)
  70#define IDX_CTL_CR3_REG     (IDX_CTL_REGS + 2)
  71#define IDX_CTL_CR4_REG     (IDX_CTL_REGS + 3)
  72#define IDX_CTL_CR8_REG     (IDX_CTL_REGS + 4)
  73#define IDX_CTL_EFER_REG    (IDX_CTL_REGS + 5)
  74
  75#ifdef TARGET_X86_64
  76#define GDB_FORCE_64 1
  77#else
  78#define GDB_FORCE_64 0
  79#endif
  80
  81static int gdb_read_reg_cs64(uint32_t hflags, GByteArray *buf, target_ulong val)
  82{
  83    if ((hflags & HF_CS64_MASK) || GDB_FORCE_64) {
  84        return gdb_get_reg64(buf, val);
  85    }
  86    return gdb_get_reg32(buf, val);
  87}
  88
  89static int gdb_write_reg_cs64(uint32_t hflags, uint8_t *buf, target_ulong *val)
  90{
  91    if (hflags & HF_CS64_MASK) {
  92        *val = ldq_p(buf);
  93        return 8;
  94    }
  95    *val = ldl_p(buf);
  96    return 4;
  97}
  98
  99int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 100{
 101    X86CPU *cpu = X86_CPU(cs);
 102    CPUX86State *env = &cpu->env;
 103
 104    uint64_t tpr;
 105
 106    /* N.B. GDB can't deal with changes in registers or sizes in the middle
 107       of a session. So if we're in 32-bit mode on a 64-bit cpu, still act
 108       as if we're on a 64-bit cpu. */
 109
 110    if (n < CPU_NB_REGS) {
 111        if (TARGET_LONG_BITS == 64) {
 112            if (env->hflags & HF_CS64_MASK) {
 113                return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]);
 114            } else if (n < CPU_NB_REGS32) {
 115                return gdb_get_reg64(mem_buf,
 116                                     env->regs[gpr_map[n]] & 0xffffffffUL);
 117            } else {
 118                return gdb_get_regl(mem_buf, 0);
 119            }
 120        } else {
 121            return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
 122        }
 123    } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
 124        int st_index = n - IDX_FP_REGS;
 125        int r_index = (st_index + env->fpstt) % 8;
 126        floatx80 *fp = &env->fpregs[r_index].d;
 127        int len = gdb_get_reg64(mem_buf, cpu_to_le64(fp->low));
 128        len += gdb_get_reg16(mem_buf, cpu_to_le16(fp->high));
 129        return len;
 130    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
 131        n -= IDX_XMM_REGS;
 132        if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) {
 133            return gdb_get_reg128(mem_buf,
 134                                  env->xmm_regs[n].ZMM_Q(1),
 135                                  env->xmm_regs[n].ZMM_Q(0));
 136        }
 137    } else {
 138        switch (n) {
 139        case IDX_IP_REG:
 140            if (TARGET_LONG_BITS == 64) {
 141                if (env->hflags & HF_CS64_MASK) {
 142                    return gdb_get_reg64(mem_buf, env->eip);
 143                } else {
 144                    return gdb_get_reg64(mem_buf, env->eip & 0xffffffffUL);
 145                }
 146            } else {
 147                return gdb_get_reg32(mem_buf, env->eip);
 148            }
 149        case IDX_FLAGS_REG:
 150            return gdb_get_reg32(mem_buf, env->eflags);
 151
 152        case IDX_SEG_REGS:
 153            return gdb_get_reg32(mem_buf, env->segs[R_CS].selector);
 154        case IDX_SEG_REGS + 1:
 155            return gdb_get_reg32(mem_buf, env->segs[R_SS].selector);
 156        case IDX_SEG_REGS + 2:
 157            return gdb_get_reg32(mem_buf, env->segs[R_DS].selector);
 158        case IDX_SEG_REGS + 3:
 159            return gdb_get_reg32(mem_buf, env->segs[R_ES].selector);
 160        case IDX_SEG_REGS + 4:
 161            return gdb_get_reg32(mem_buf, env->segs[R_FS].selector);
 162        case IDX_SEG_REGS + 5:
 163            return gdb_get_reg32(mem_buf, env->segs[R_GS].selector);
 164        case IDX_SEG_REGS + 6:
 165            return gdb_read_reg_cs64(env->hflags, mem_buf, env->segs[R_FS].base);
 166        case IDX_SEG_REGS + 7:
 167            return gdb_read_reg_cs64(env->hflags, mem_buf, env->segs[R_GS].base);
 168
 169        case IDX_SEG_REGS + 8:
 170#ifdef TARGET_X86_64
 171            return gdb_read_reg_cs64(env->hflags, mem_buf, env->kernelgsbase);
 172#else
 173            return gdb_get_reg32(mem_buf, 0);
 174#endif
 175
 176        case IDX_FP_REGS + 8:
 177            return gdb_get_reg32(mem_buf, env->fpuc);
 178        case IDX_FP_REGS + 9:
 179            return gdb_get_reg32(mem_buf, (env->fpus & ~0x3800) |
 180                                          (env->fpstt & 0x7) << 11);
 181        case IDX_FP_REGS + 10:
 182            return gdb_get_reg32(mem_buf, 0); /* ftag */
 183        case IDX_FP_REGS + 11:
 184            return gdb_get_reg32(mem_buf, 0); /* fiseg */
 185        case IDX_FP_REGS + 12:
 186            return gdb_get_reg32(mem_buf, 0); /* fioff */
 187        case IDX_FP_REGS + 13:
 188            return gdb_get_reg32(mem_buf, 0); /* foseg */
 189        case IDX_FP_REGS + 14:
 190            return gdb_get_reg32(mem_buf, 0); /* fooff */
 191        case IDX_FP_REGS + 15:
 192            return gdb_get_reg32(mem_buf, 0); /* fop */
 193
 194        case IDX_MXCSR_REG:
 195            update_mxcsr_from_sse_status(env);
 196            return gdb_get_reg32(mem_buf, env->mxcsr);
 197
 198        case IDX_CTL_CR0_REG:
 199            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[0]);
 200        case IDX_CTL_CR2_REG:
 201            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[2]);
 202        case IDX_CTL_CR3_REG:
 203            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[3]);
 204        case IDX_CTL_CR4_REG:
 205            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[4]);
 206        case IDX_CTL_CR8_REG:
 207#ifndef CONFIG_USER_ONLY
 208            tpr = cpu_get_apic_tpr(cpu->apic_state);
 209#else
 210            tpr = 0;
 211#endif
 212            return gdb_read_reg_cs64(env->hflags, mem_buf, tpr);
 213
 214        case IDX_CTL_EFER_REG:
 215            return gdb_read_reg_cs64(env->hflags, mem_buf, env->efer);
 216        }
 217    }
 218    return 0;
 219}
 220
 221static int x86_cpu_gdb_load_seg(X86CPU *cpu, X86Seg sreg, uint8_t *mem_buf)
 222{
 223    CPUX86State *env = &cpu->env;
 224    uint16_t selector = ldl_p(mem_buf);
 225
 226    if (selector != env->segs[sreg].selector) {
 227#if defined(CONFIG_USER_ONLY)
 228        cpu_x86_load_seg(env, sreg, selector);
 229#else
 230        unsigned int limit, flags;
 231        target_ulong base;
 232
 233        if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
 234            int dpl = (env->eflags & VM_MASK) ? 3 : 0;
 235            base = selector << 4;
 236            limit = 0xffff;
 237            flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
 238                    DESC_A_MASK | (dpl << DESC_DPL_SHIFT);
 239        } else {
 240            if (!cpu_x86_get_descr_debug(env, selector, &base, &limit,
 241                                         &flags)) {
 242                return 4;
 243            }
 244        }
 245        cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags);
 246#endif
 247    }
 248    return 4;
 249}
 250
 251int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 252{
 253    X86CPU *cpu = X86_CPU(cs);
 254    CPUX86State *env = &cpu->env;
 255    target_ulong tmp;
 256    int len;
 257
 258    /* N.B. GDB can't deal with changes in registers or sizes in the middle
 259       of a session. So if we're in 32-bit mode on a 64-bit cpu, still act
 260       as if we're on a 64-bit cpu. */
 261
 262    if (n < CPU_NB_REGS) {
 263        if (TARGET_LONG_BITS == 64) {
 264            if (env->hflags & HF_CS64_MASK) {
 265                env->regs[gpr_map[n]] = ldtul_p(mem_buf);
 266            } else if (n < CPU_NB_REGS32) {
 267                env->regs[gpr_map[n]] = ldtul_p(mem_buf) & 0xffffffffUL;
 268            }
 269            return sizeof(target_ulong);
 270        } else if (n < CPU_NB_REGS32) {
 271            n = gpr_map32[n];
 272            env->regs[n] &= ~0xffffffffUL;
 273            env->regs[n] |= (uint32_t)ldl_p(mem_buf);
 274            return 4;
 275        }
 276    } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
 277        floatx80 *fp = (floatx80 *) &env->fpregs[n - IDX_FP_REGS];
 278        fp->low = le64_to_cpu(* (uint64_t *) mem_buf);
 279        fp->high = le16_to_cpu(* (uint16_t *) (mem_buf + 8));
 280        return 10;
 281    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
 282        n -= IDX_XMM_REGS;
 283        if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) {
 284            env->xmm_regs[n].ZMM_Q(0) = ldq_p(mem_buf);
 285            env->xmm_regs[n].ZMM_Q(1) = ldq_p(mem_buf + 8);
 286            return 16;
 287        }
 288    } else {
 289        switch (n) {
 290        case IDX_IP_REG:
 291            if (TARGET_LONG_BITS == 64) {
 292                if (env->hflags & HF_CS64_MASK) {
 293                    env->eip = ldq_p(mem_buf);
 294                } else {
 295                    env->eip = ldq_p(mem_buf) & 0xffffffffUL;
 296                }
 297                return 8;
 298            } else {
 299                env->eip &= ~0xffffffffUL;
 300                env->eip |= (uint32_t)ldl_p(mem_buf);
 301                return 4;
 302            }
 303        case IDX_FLAGS_REG:
 304            env->eflags = ldl_p(mem_buf);
 305            return 4;
 306
 307        case IDX_SEG_REGS:
 308            return x86_cpu_gdb_load_seg(cpu, R_CS, mem_buf);
 309        case IDX_SEG_REGS + 1:
 310            return x86_cpu_gdb_load_seg(cpu, R_SS, mem_buf);
 311        case IDX_SEG_REGS + 2:
 312            return x86_cpu_gdb_load_seg(cpu, R_DS, mem_buf);
 313        case IDX_SEG_REGS + 3:
 314            return x86_cpu_gdb_load_seg(cpu, R_ES, mem_buf);
 315        case IDX_SEG_REGS + 4:
 316            return x86_cpu_gdb_load_seg(cpu, R_FS, mem_buf);
 317        case IDX_SEG_REGS + 5:
 318            return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf);
 319        case IDX_SEG_REGS + 6:
 320            return gdb_write_reg_cs64(env->hflags, mem_buf, &env->segs[R_FS].base);
 321        case IDX_SEG_REGS + 7:
 322            return gdb_write_reg_cs64(env->hflags, mem_buf, &env->segs[R_GS].base);
 323        case IDX_SEG_REGS + 8:
 324#ifdef TARGET_X86_64
 325            return gdb_write_reg_cs64(env->hflags, mem_buf, &env->kernelgsbase);
 326#endif
 327            return 4;
 328
 329        case IDX_FP_REGS + 8:
 330            cpu_set_fpuc(env, ldl_p(mem_buf));
 331            return 4;
 332        case IDX_FP_REGS + 9:
 333            tmp = ldl_p(mem_buf);
 334            env->fpstt = (tmp >> 11) & 7;
 335            env->fpus = tmp & ~0x3800;
 336            return 4;
 337        case IDX_FP_REGS + 10: /* ftag */
 338            return 4;
 339        case IDX_FP_REGS + 11: /* fiseg */
 340            return 4;
 341        case IDX_FP_REGS + 12: /* fioff */
 342            return 4;
 343        case IDX_FP_REGS + 13: /* foseg */
 344            return 4;
 345        case IDX_FP_REGS + 14: /* fooff */
 346            return 4;
 347        case IDX_FP_REGS + 15: /* fop */
 348            return 4;
 349
 350        case IDX_MXCSR_REG:
 351            cpu_set_mxcsr(env, ldl_p(mem_buf));
 352            return 4;
 353
 354        case IDX_CTL_CR0_REG:
 355            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 356#ifndef CONFIG_USER_ONLY
 357            cpu_x86_update_cr0(env, tmp);
 358#endif
 359            return len;
 360
 361        case IDX_CTL_CR2_REG:
 362            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 363#ifndef CONFIG_USER_ONLY
 364            env->cr[2] = tmp;
 365#endif
 366            return len;
 367
 368        case IDX_CTL_CR3_REG:
 369            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 370#ifndef CONFIG_USER_ONLY
 371            cpu_x86_update_cr3(env, tmp);
 372#endif
 373            return len;
 374
 375        case IDX_CTL_CR4_REG:
 376            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 377#ifndef CONFIG_USER_ONLY
 378            cpu_x86_update_cr4(env, tmp);
 379#endif
 380            return len;
 381
 382        case IDX_CTL_CR8_REG:
 383            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 384#ifndef CONFIG_USER_ONLY
 385            cpu_set_apic_tpr(cpu->apic_state, tmp);
 386#endif
 387            return len;
 388
 389        case IDX_CTL_EFER_REG:
 390            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 391#ifndef CONFIG_USER_ONLY
 392            cpu_load_efer(env, tmp);
 393#endif
 394            return len;
 395        }
 396    }
 397    /* Unrecognised register.  */
 398    return 0;
 399}
 400