cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

gdbstub.c (16248B)


      1/*
      2 * PowerPC 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#include "internal.h"
     24
     25static int ppc_gdb_register_len_apple(int n)
     26{
     27    switch (n) {
     28    case 0 ... 31:
     29        /* gprs */
     30        return 8;
     31    case 32 ... 63:
     32        /* fprs */
     33        return 8;
     34    case 64 ... 95:
     35        return 16;
     36    case 64 + 32: /* nip */
     37    case 65 + 32: /* msr */
     38    case 67 + 32: /* lr */
     39    case 68 + 32: /* ctr */
     40    case 70 + 32: /* fpscr */
     41        return 8;
     42    case 66 + 32: /* cr */
     43    case 69 + 32: /* xer */
     44        return 4;
     45    default:
     46        return 0;
     47    }
     48}
     49
     50static int ppc_gdb_register_len(int n)
     51{
     52    switch (n) {
     53    case 0 ... 31:
     54        /* gprs */
     55        return sizeof(target_ulong);
     56    case 32 ... 63:
     57        /* fprs */
     58        if (gdb_has_xml) {
     59            return 0;
     60        }
     61        return 8;
     62    case 66:
     63        /* cr */
     64    case 69:
     65        /* xer */
     66        return 4;
     67    case 64:
     68        /* nip */
     69    case 65:
     70        /* msr */
     71    case 67:
     72        /* lr */
     73    case 68:
     74        /* ctr */
     75        return sizeof(target_ulong);
     76    case 70:
     77        /* fpscr */
     78        if (gdb_has_xml) {
     79            return 0;
     80        }
     81        return sizeof(target_ulong);
     82    default:
     83        return 0;
     84    }
     85}
     86
     87/*
     88 * We need to present the registers to gdb in the "current" memory
     89 * ordering.  For user-only mode we get this for free;
     90 * TARGET_WORDS_BIGENDIAN is set to the proper ordering for the
     91 * binary, and cannot be changed.  For system mode,
     92 * TARGET_WORDS_BIGENDIAN is always set, and we must check the current
     93 * mode of the chip to see if we're running in little-endian.
     94 */
     95void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
     96{
     97#ifndef CONFIG_USER_ONLY
     98    if (!msr_le) {
     99        /* do nothing */
    100    } else if (len == 4) {
    101        bswap32s((uint32_t *)mem_buf);
    102    } else if (len == 8) {
    103        bswap64s((uint64_t *)mem_buf);
    104    } else if (len == 16) {
    105        bswap128s((Int128 *)mem_buf);
    106    } else {
    107        g_assert_not_reached();
    108    }
    109#endif
    110}
    111
    112/*
    113 * Old gdb always expects FP registers.  Newer (xml-aware) gdb only
    114 * expects whatever the target description contains.  Due to a
    115 * historical mishap the FP registers appear in between core integer
    116 * regs and PC, MSR, CR, and so forth.  We hack round this by giving
    117 * the FP regs zero size when talking to a newer gdb.
    118 */
    119
    120int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
    121{
    122    PowerPCCPU *cpu = POWERPC_CPU(cs);
    123    CPUPPCState *env = &cpu->env;
    124    uint8_t *mem_buf;
    125    int r = ppc_gdb_register_len(n);
    126
    127    if (!r) {
    128        return r;
    129    }
    130
    131    if (n < 32) {
    132        /* gprs */
    133        gdb_get_regl(buf, env->gpr[n]);
    134    } else if (n < 64) {
    135        /* fprs */
    136        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
    137    } else {
    138        switch (n) {
    139        case 64:
    140            gdb_get_regl(buf, env->nip);
    141            break;
    142        case 65:
    143            gdb_get_regl(buf, env->msr);
    144            break;
    145        case 66:
    146            {
    147                uint32_t cr = 0;
    148                int i;
    149                for (i = 0; i < 8; i++) {
    150                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
    151                }
    152                gdb_get_reg32(buf, cr);
    153                break;
    154            }
    155        case 67:
    156            gdb_get_regl(buf, env->lr);
    157            break;
    158        case 68:
    159            gdb_get_regl(buf, env->ctr);
    160            break;
    161        case 69:
    162            gdb_get_reg32(buf, env->xer);
    163            break;
    164        case 70:
    165            gdb_get_reg32(buf, env->fpscr);
    166            break;
    167        }
    168    }
    169    mem_buf = buf->data + buf->len - r;
    170    ppc_maybe_bswap_register(env, mem_buf, r);
    171    return r;
    172}
    173
    174int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
    175{
    176    PowerPCCPU *cpu = POWERPC_CPU(cs);
    177    CPUPPCState *env = &cpu->env;
    178    uint8_t *mem_buf;
    179    int r = ppc_gdb_register_len_apple(n);
    180
    181    if (!r) {
    182        return r;
    183    }
    184
    185    if (n < 32) {
    186        /* gprs */
    187        gdb_get_reg64(buf, env->gpr[n]);
    188    } else if (n < 64) {
    189        /* fprs */
    190        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
    191    } else if (n < 96) {
    192        /* Altivec */
    193        gdb_get_reg64(buf, n - 64);
    194        gdb_get_reg64(buf, 0);
    195    } else {
    196        switch (n) {
    197        case 64 + 32:
    198            gdb_get_reg64(buf, env->nip);
    199            break;
    200        case 65 + 32:
    201            gdb_get_reg64(buf, env->msr);
    202            break;
    203        case 66 + 32:
    204            {
    205                uint32_t cr = 0;
    206                int i;
    207                for (i = 0; i < 8; i++) {
    208                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
    209                }
    210                gdb_get_reg32(buf, cr);
    211                break;
    212            }
    213        case 67 + 32:
    214            gdb_get_reg64(buf, env->lr);
    215            break;
    216        case 68 + 32:
    217            gdb_get_reg64(buf, env->ctr);
    218            break;
    219        case 69 + 32:
    220            gdb_get_reg32(buf, env->xer);
    221            break;
    222        case 70 + 32:
    223            gdb_get_reg64(buf, env->fpscr);
    224            break;
    225        }
    226    }
    227    mem_buf = buf->data + buf->len - r;
    228    ppc_maybe_bswap_register(env, mem_buf, r);
    229    return r;
    230}
    231
    232int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
    233{
    234    PowerPCCPU *cpu = POWERPC_CPU(cs);
    235    CPUPPCState *env = &cpu->env;
    236    int r = ppc_gdb_register_len(n);
    237
    238    if (!r) {
    239        return r;
    240    }
    241    ppc_maybe_bswap_register(env, mem_buf, r);
    242    if (n < 32) {
    243        /* gprs */
    244        env->gpr[n] = ldtul_p(mem_buf);
    245    } else if (n < 64) {
    246        /* fprs */
    247        *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
    248    } else {
    249        switch (n) {
    250        case 64:
    251            env->nip = ldtul_p(mem_buf);
    252            break;
    253        case 65:
    254            ppc_store_msr(env, ldtul_p(mem_buf));
    255            break;
    256        case 66:
    257            {
    258                uint32_t cr = ldl_p(mem_buf);
    259                int i;
    260                for (i = 0; i < 8; i++) {
    261                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
    262                }
    263                break;
    264            }
    265        case 67:
    266            env->lr = ldtul_p(mem_buf);
    267            break;
    268        case 68:
    269            env->ctr = ldtul_p(mem_buf);
    270            break;
    271        case 69:
    272            env->xer = ldl_p(mem_buf);
    273            break;
    274        case 70:
    275            /* fpscr */
    276            ppc_store_fpscr(env, ldtul_p(mem_buf));
    277            break;
    278        }
    279    }
    280    return r;
    281}
    282int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
    283{
    284    PowerPCCPU *cpu = POWERPC_CPU(cs);
    285    CPUPPCState *env = &cpu->env;
    286    int r = ppc_gdb_register_len_apple(n);
    287
    288    if (!r) {
    289        return r;
    290    }
    291    ppc_maybe_bswap_register(env, mem_buf, r);
    292    if (n < 32) {
    293        /* gprs */
    294        env->gpr[n] = ldq_p(mem_buf);
    295    } else if (n < 64) {
    296        /* fprs */
    297        *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
    298    } else {
    299        switch (n) {
    300        case 64 + 32:
    301            env->nip = ldq_p(mem_buf);
    302            break;
    303        case 65 + 32:
    304            ppc_store_msr(env, ldq_p(mem_buf));
    305            break;
    306        case 66 + 32:
    307            {
    308                uint32_t cr = ldl_p(mem_buf);
    309                int i;
    310                for (i = 0; i < 8; i++) {
    311                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
    312                }
    313                break;
    314            }
    315        case 67 + 32:
    316            env->lr = ldq_p(mem_buf);
    317            break;
    318        case 68 + 32:
    319            env->ctr = ldq_p(mem_buf);
    320            break;
    321        case 69 + 32:
    322            env->xer = ldl_p(mem_buf);
    323            break;
    324        case 70 + 32:
    325            /* fpscr */
    326            ppc_store_fpscr(env, ldq_p(mem_buf));
    327            break;
    328        }
    329    }
    330    return r;
    331}
    332
    333#ifndef CONFIG_USER_ONLY
    334void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu)
    335{
    336    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
    337    CPUPPCState *env = &cpu->env;
    338    GString *xml;
    339    char *spr_name;
    340    unsigned int num_regs = 0;
    341    int i;
    342
    343    if (pcc->gdb_spr_xml) {
    344        return;
    345    }
    346
    347    xml = g_string_new("<?xml version=\"1.0\"?>");
    348    g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
    349    g_string_append(xml, "<feature name=\"org.qemu.power.spr\">");
    350
    351    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
    352        ppc_spr_t *spr = &env->spr_cb[i];
    353
    354        if (!spr->name) {
    355            continue;
    356        }
    357
    358        spr_name = g_ascii_strdown(spr->name, -1);
    359        g_string_append_printf(xml, "<reg name=\"%s\"", spr_name);
    360        g_free(spr_name);
    361
    362        g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS);
    363        g_string_append(xml, " group=\"spr\"/>");
    364
    365        /*
    366         * GDB identifies registers based on the order they are
    367         * presented in the XML. These ids will not match QEMU's
    368         * representation (which follows the PowerISA).
    369         *
    370         * Store the position of the current register description so
    371         * we can make the correspondence later.
    372         */
    373        spr->gdb_id = num_regs;
    374        num_regs++;
    375    }
    376
    377    g_string_append(xml, "</feature>");
    378
    379    pcc->gdb_num_sprs = num_regs;
    380    pcc->gdb_spr_xml = g_string_free(xml, false);
    381}
    382
    383const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
    384{
    385    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
    386
    387    if (strcmp(xml_name, "power-spr.xml") == 0) {
    388        return pcc->gdb_spr_xml;
    389    }
    390    return NULL;
    391}
    392#endif
    393
    394#if !defined(CONFIG_USER_ONLY)
    395static int gdb_find_spr_idx(CPUPPCState *env, int n)
    396{
    397    int i;
    398
    399    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
    400        ppc_spr_t *spr = &env->spr_cb[i];
    401
    402        if (spr->name && spr->gdb_id == n) {
    403            return i;
    404        }
    405    }
    406    return -1;
    407}
    408
    409static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
    410{
    411    int reg;
    412    int len;
    413
    414    reg = gdb_find_spr_idx(env, n);
    415    if (reg < 0) {
    416        return 0;
    417    }
    418
    419    len = TARGET_LONG_SIZE;
    420    gdb_get_regl(buf, env->spr[reg]);
    421    ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
    422    return len;
    423}
    424
    425static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
    426{
    427    int reg;
    428    int len;
    429
    430    reg = gdb_find_spr_idx(env, n);
    431    if (reg < 0) {
    432        return 0;
    433    }
    434
    435    len = TARGET_LONG_SIZE;
    436    ppc_maybe_bswap_register(env, mem_buf, len);
    437    env->spr[reg] = ldn_p(mem_buf, len);
    438
    439    return len;
    440}
    441#endif
    442
    443static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
    444{
    445    uint8_t *mem_buf;
    446    if (n < 32) {
    447        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
    448        mem_buf = gdb_get_reg_ptr(buf, 8);
    449        ppc_maybe_bswap_register(env, mem_buf, 8);
    450        return 8;
    451    }
    452    if (n == 32) {
    453        gdb_get_reg32(buf, env->fpscr);
    454        mem_buf = gdb_get_reg_ptr(buf, 4);
    455        ppc_maybe_bswap_register(env, mem_buf, 4);
    456        return 4;
    457    }
    458    return 0;
    459}
    460
    461static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
    462{
    463    if (n < 32) {
    464        ppc_maybe_bswap_register(env, mem_buf, 8);
    465        *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
    466        return 8;
    467    }
    468    if (n == 32) {
    469        ppc_maybe_bswap_register(env, mem_buf, 4);
    470        ppc_store_fpscr(env, ldl_p(mem_buf));
    471        return 4;
    472    }
    473    return 0;
    474}
    475
    476static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
    477{
    478    uint8_t *mem_buf;
    479
    480    if (n < 32) {
    481        ppc_avr_t *avr = cpu_avr_ptr(env, n);
    482        gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
    483        mem_buf = gdb_get_reg_ptr(buf, 16);
    484        ppc_maybe_bswap_register(env, mem_buf, 16);
    485        return 16;
    486    }
    487    if (n == 32) {
    488        gdb_get_reg32(buf, ppc_get_vscr(env));
    489        mem_buf = gdb_get_reg_ptr(buf, 4);
    490        ppc_maybe_bswap_register(env, mem_buf, 4);
    491        return 4;
    492    }
    493    if (n == 33) {
    494        gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
    495        mem_buf = gdb_get_reg_ptr(buf, 4);
    496        ppc_maybe_bswap_register(env, mem_buf, 4);
    497        return 4;
    498    }
    499    return 0;
    500}
    501
    502static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
    503{
    504    if (n < 32) {
    505        ppc_avr_t *avr = cpu_avr_ptr(env, n);
    506        ppc_maybe_bswap_register(env, mem_buf, 16);
    507        avr->VsrD(0) = ldq_p(mem_buf);
    508        avr->VsrD(1) = ldq_p(mem_buf + 8);
    509        return 16;
    510    }
    511    if (n == 32) {
    512        ppc_maybe_bswap_register(env, mem_buf, 4);
    513        ppc_store_vscr(env, ldl_p(mem_buf));
    514        return 4;
    515    }
    516    if (n == 33) {
    517        ppc_maybe_bswap_register(env, mem_buf, 4);
    518        env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
    519        return 4;
    520    }
    521    return 0;
    522}
    523
    524static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
    525{
    526    if (n < 32) {
    527#if defined(TARGET_PPC64)
    528        gdb_get_reg32(buf, env->gpr[n] >> 32);
    529        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
    530#else
    531        gdb_get_reg32(buf, env->gprh[n]);
    532#endif
    533        return 4;
    534    }
    535    if (n == 32) {
    536        gdb_get_reg64(buf, env->spe_acc);
    537        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
    538        return 8;
    539    }
    540    if (n == 33) {
    541        gdb_get_reg32(buf, env->spe_fscr);
    542        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
    543        return 4;
    544    }
    545    return 0;
    546}
    547
    548static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
    549{
    550    if (n < 32) {
    551#if defined(TARGET_PPC64)
    552        target_ulong lo = (uint32_t)env->gpr[n];
    553        target_ulong hi;
    554
    555        ppc_maybe_bswap_register(env, mem_buf, 4);
    556
    557        hi = (target_ulong)ldl_p(mem_buf) << 32;
    558        env->gpr[n] = lo | hi;
    559#else
    560        env->gprh[n] = ldl_p(mem_buf);
    561#endif
    562        return 4;
    563    }
    564    if (n == 32) {
    565        ppc_maybe_bswap_register(env, mem_buf, 8);
    566        env->spe_acc = ldq_p(mem_buf);
    567        return 8;
    568    }
    569    if (n == 33) {
    570        ppc_maybe_bswap_register(env, mem_buf, 4);
    571        env->spe_fscr = ldl_p(mem_buf);
    572        return 4;
    573    }
    574    return 0;
    575}
    576
    577static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
    578{
    579    if (n < 32) {
    580        gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
    581        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
    582        return 8;
    583    }
    584    return 0;
    585}
    586
    587static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
    588{
    589    if (n < 32) {
    590        ppc_maybe_bswap_register(env, mem_buf, 8);
    591        *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
    592        return 8;
    593    }
    594    return 0;
    595}
    596
    597gchar *ppc_gdb_arch_name(CPUState *cs)
    598{
    599#if defined(TARGET_PPC64)
    600    return g_strdup("powerpc:common64");
    601#else
    602    return g_strdup("powerpc:common");
    603#endif
    604}
    605
    606void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
    607{
    608    if (pcc->insns_flags & PPC_FLOAT) {
    609        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
    610                                 33, "power-fpu.xml", 0);
    611    }
    612    if (pcc->insns_flags & PPC_ALTIVEC) {
    613        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
    614                                 34, "power-altivec.xml", 0);
    615    }
    616    if (pcc->insns_flags & PPC_SPE) {
    617        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
    618                                 34, "power-spe.xml", 0);
    619    }
    620    if (pcc->insns_flags2 & PPC2_VSX) {
    621        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
    622                                 32, "power-vsx.xml", 0);
    623    }
    624#ifndef CONFIG_USER_ONLY
    625    gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
    626                             pcc->gdb_num_sprs, "power-spr.xml", 0);
    627#endif
    628}