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 "exec/gdbstub.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        floatx80 *fp = (floatx80 *) &env->fpregs[n - IDX_FP_REGS];
 125        int len = gdb_get_reg64(mem_buf, cpu_to_le64(fp->low));
 126        len += gdb_get_reg16(mem_buf, cpu_to_le16(fp->high));
 127        return len;
 128    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
 129        n -= IDX_XMM_REGS;
 130        if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) {
 131            return gdb_get_reg128(mem_buf,
 132                                  env->xmm_regs[n].ZMM_Q(0),
 133                                  env->xmm_regs[n].ZMM_Q(1));
 134        }
 135    } else {
 136        switch (n) {
 137        case IDX_IP_REG:
 138            if (TARGET_LONG_BITS == 64) {
 139                if (env->hflags & HF_CS64_MASK) {
 140                    return gdb_get_reg64(mem_buf, env->eip);
 141                } else {
 142                    return gdb_get_reg64(mem_buf, env->eip & 0xffffffffUL);
 143                }
 144            } else {
 145                return gdb_get_reg32(mem_buf, env->eip);
 146            }
 147        case IDX_FLAGS_REG:
 148            return gdb_get_reg32(mem_buf, env->eflags);
 149
 150        case IDX_SEG_REGS:
 151            return gdb_get_reg32(mem_buf, env->segs[R_CS].selector);
 152        case IDX_SEG_REGS + 1:
 153            return gdb_get_reg32(mem_buf, env->segs[R_SS].selector);
 154        case IDX_SEG_REGS + 2:
 155            return gdb_get_reg32(mem_buf, env->segs[R_DS].selector);
 156        case IDX_SEG_REGS + 3:
 157            return gdb_get_reg32(mem_buf, env->segs[R_ES].selector);
 158        case IDX_SEG_REGS + 4:
 159            return gdb_get_reg32(mem_buf, env->segs[R_FS].selector);
 160        case IDX_SEG_REGS + 5:
 161            return gdb_get_reg32(mem_buf, env->segs[R_GS].selector);
 162        case IDX_SEG_REGS + 6:
 163            return gdb_read_reg_cs64(env->hflags, mem_buf, env->segs[R_FS].base);
 164        case IDX_SEG_REGS + 7:
 165            return gdb_read_reg_cs64(env->hflags, mem_buf, env->segs[R_GS].base);
 166
 167        case IDX_SEG_REGS + 8:
 168#ifdef TARGET_X86_64
 169            return gdb_read_reg_cs64(env->hflags, mem_buf, env->kernelgsbase);
 170#else
 171            return gdb_get_reg32(mem_buf, 0);
 172#endif
 173
 174        case IDX_FP_REGS + 8:
 175            return gdb_get_reg32(mem_buf, env->fpuc);
 176        case IDX_FP_REGS + 9:
 177            return gdb_get_reg32(mem_buf, (env->fpus & ~0x3800) |
 178                                          (env->fpstt & 0x7) << 11);
 179        case IDX_FP_REGS + 10:
 180            return gdb_get_reg32(mem_buf, 0); /* ftag */
 181        case IDX_FP_REGS + 11:
 182            return gdb_get_reg32(mem_buf, 0); /* fiseg */
 183        case IDX_FP_REGS + 12:
 184            return gdb_get_reg32(mem_buf, 0); /* fioff */
 185        case IDX_FP_REGS + 13:
 186            return gdb_get_reg32(mem_buf, 0); /* foseg */
 187        case IDX_FP_REGS + 14:
 188            return gdb_get_reg32(mem_buf, 0); /* fooff */
 189        case IDX_FP_REGS + 15:
 190            return gdb_get_reg32(mem_buf, 0); /* fop */
 191
 192        case IDX_MXCSR_REG:
 193            update_mxcsr_from_sse_status(env);
 194            return gdb_get_reg32(mem_buf, env->mxcsr);
 195
 196        case IDX_CTL_CR0_REG:
 197            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[0]);
 198        case IDX_CTL_CR2_REG:
 199            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[2]);
 200        case IDX_CTL_CR3_REG:
 201            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[3]);
 202        case IDX_CTL_CR4_REG:
 203            return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[4]);
 204        case IDX_CTL_CR8_REG:
 205#ifndef CONFIG_USER_ONLY
 206            tpr = cpu_get_apic_tpr(cpu->apic_state);
 207#else
 208            tpr = 0;
 209#endif
 210            return gdb_read_reg_cs64(env->hflags, mem_buf, tpr);
 211
 212        case IDX_CTL_EFER_REG:
 213            return gdb_read_reg_cs64(env->hflags, mem_buf, env->efer);
 214        }
 215    }
 216    return 0;
 217}
 218
 219static int x86_cpu_gdb_load_seg(X86CPU *cpu, X86Seg sreg, uint8_t *mem_buf)
 220{
 221    CPUX86State *env = &cpu->env;
 222    uint16_t selector = ldl_p(mem_buf);
 223
 224    if (selector != env->segs[sreg].selector) {
 225#if defined(CONFIG_USER_ONLY)
 226        cpu_x86_load_seg(env, sreg, selector);
 227#else
 228        unsigned int limit, flags;
 229        target_ulong base;
 230
 231        if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
 232            int dpl = (env->eflags & VM_MASK) ? 3 : 0;
 233            base = selector << 4;
 234            limit = 0xffff;
 235            flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
 236                    DESC_A_MASK | (dpl << DESC_DPL_SHIFT);
 237        } else {
 238            if (!cpu_x86_get_descr_debug(env, selector, &base, &limit,
 239                                         &flags)) {
 240                return 4;
 241            }
 242        }
 243        cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags);
 244#endif
 245    }
 246    return 4;
 247}
 248
 249int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 250{
 251    X86CPU *cpu = X86_CPU(cs);
 252    CPUX86State *env = &cpu->env;
 253    target_ulong tmp;
 254    int len;
 255
 256    /* N.B. GDB can't deal with changes in registers or sizes in the middle
 257       of a session. So if we're in 32-bit mode on a 64-bit cpu, still act
 258       as if we're on a 64-bit cpu. */
 259
 260    if (n < CPU_NB_REGS) {
 261        if (TARGET_LONG_BITS == 64) {
 262            if (env->hflags & HF_CS64_MASK) {
 263                env->regs[gpr_map[n]] = ldtul_p(mem_buf);
 264            } else if (n < CPU_NB_REGS32) {
 265                env->regs[gpr_map[n]] = ldtul_p(mem_buf) & 0xffffffffUL;
 266            }
 267            return sizeof(target_ulong);
 268        } else if (n < CPU_NB_REGS32) {
 269            n = gpr_map32[n];
 270            env->regs[n] &= ~0xffffffffUL;
 271            env->regs[n] |= (uint32_t)ldl_p(mem_buf);
 272            return 4;
 273        }
 274    } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
 275        floatx80 *fp = (floatx80 *) &env->fpregs[n - IDX_FP_REGS];
 276        fp->low = le64_to_cpu(* (uint64_t *) mem_buf);
 277        fp->high = le16_to_cpu(* (uint16_t *) (mem_buf + 8));
 278        return 10;
 279    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
 280        n -= IDX_XMM_REGS;
 281        if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) {
 282            env->xmm_regs[n].ZMM_Q(0) = ldq_p(mem_buf);
 283            env->xmm_regs[n].ZMM_Q(1) = ldq_p(mem_buf + 8);
 284            return 16;
 285        }
 286    } else {
 287        switch (n) {
 288        case IDX_IP_REG:
 289            if (TARGET_LONG_BITS == 64) {
 290                if (env->hflags & HF_CS64_MASK) {
 291                    env->eip = ldq_p(mem_buf);
 292                } else {
 293                    env->eip = ldq_p(mem_buf) & 0xffffffffUL;
 294                }
 295                return 8;
 296            } else {
 297                env->eip &= ~0xffffffffUL;
 298                env->eip |= (uint32_t)ldl_p(mem_buf);
 299                return 4;
 300            }
 301        case IDX_FLAGS_REG:
 302            env->eflags = ldl_p(mem_buf);
 303            return 4;
 304
 305        case IDX_SEG_REGS:
 306            return x86_cpu_gdb_load_seg(cpu, R_CS, mem_buf);
 307        case IDX_SEG_REGS + 1:
 308            return x86_cpu_gdb_load_seg(cpu, R_SS, mem_buf);
 309        case IDX_SEG_REGS + 2:
 310            return x86_cpu_gdb_load_seg(cpu, R_DS, mem_buf);
 311        case IDX_SEG_REGS + 3:
 312            return x86_cpu_gdb_load_seg(cpu, R_ES, mem_buf);
 313        case IDX_SEG_REGS + 4:
 314            return x86_cpu_gdb_load_seg(cpu, R_FS, mem_buf);
 315        case IDX_SEG_REGS + 5:
 316            return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf);
 317        case IDX_SEG_REGS + 6:
 318            return gdb_write_reg_cs64(env->hflags, mem_buf, &env->segs[R_FS].base);
 319        case IDX_SEG_REGS + 7:
 320            return gdb_write_reg_cs64(env->hflags, mem_buf, &env->segs[R_GS].base);
 321        case IDX_SEG_REGS + 8:
 322#ifdef TARGET_X86_64
 323            return gdb_write_reg_cs64(env->hflags, mem_buf, &env->kernelgsbase);
 324#endif
 325            return 4;
 326
 327        case IDX_FP_REGS + 8:
 328            cpu_set_fpuc(env, ldl_p(mem_buf));
 329            return 4;
 330        case IDX_FP_REGS + 9:
 331            tmp = ldl_p(mem_buf);
 332            env->fpstt = (tmp >> 11) & 7;
 333            env->fpus = tmp & ~0x3800;
 334            return 4;
 335        case IDX_FP_REGS + 10: /* ftag */
 336            return 4;
 337        case IDX_FP_REGS + 11: /* fiseg */
 338            return 4;
 339        case IDX_FP_REGS + 12: /* fioff */
 340            return 4;
 341        case IDX_FP_REGS + 13: /* foseg */
 342            return 4;
 343        case IDX_FP_REGS + 14: /* fooff */
 344            return 4;
 345        case IDX_FP_REGS + 15: /* fop */
 346            return 4;
 347
 348        case IDX_MXCSR_REG:
 349            cpu_set_mxcsr(env, ldl_p(mem_buf));
 350            return 4;
 351
 352        case IDX_CTL_CR0_REG:
 353            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 354#ifndef CONFIG_USER_ONLY
 355            cpu_x86_update_cr0(env, tmp);
 356#endif
 357            return len;
 358
 359        case IDX_CTL_CR2_REG:
 360            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 361#ifndef CONFIG_USER_ONLY
 362            env->cr[2] = tmp;
 363#endif
 364            return len;
 365
 366        case IDX_CTL_CR3_REG:
 367            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 368#ifndef CONFIG_USER_ONLY
 369            cpu_x86_update_cr3(env, tmp);
 370#endif
 371            return len;
 372
 373        case IDX_CTL_CR4_REG:
 374            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 375#ifndef CONFIG_USER_ONLY
 376            cpu_x86_update_cr4(env, tmp);
 377#endif
 378            return len;
 379
 380        case IDX_CTL_CR8_REG:
 381            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 382#ifndef CONFIG_USER_ONLY
 383            cpu_set_apic_tpr(cpu->apic_state, tmp);
 384#endif
 385            return len;
 386
 387        case IDX_CTL_EFER_REG:
 388            len = gdb_write_reg_cs64(env->hflags, mem_buf, &tmp);
 389#ifndef CONFIG_USER_ONLY
 390            cpu_load_efer(env, tmp);
 391#endif
 392            return len;
 393        }
 394    }
 395    /* Unrecognised register.  */
 396    return 0;
 397}
 398