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 (15927B)


      1/*
      2 * ARM 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 "internals.h"
     23#include "exec/gdbstub.h"
     24
     25typedef struct RegisterSysregXmlParam {
     26    CPUState *cs;
     27    GString *s;
     28    int n;
     29} RegisterSysregXmlParam;
     30
     31/* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
     32   whatever the target description contains.  Due to a historical mishap
     33   the FPA registers appear in between core integer regs and the CPSR.
     34   We hack round this by giving the FPA regs zero size when talking to a
     35   newer gdb.  */
     36
     37int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
     38{
     39    ARMCPU *cpu = ARM_CPU(cs);
     40    CPUARMState *env = &cpu->env;
     41
     42    if (n < 16) {
     43        /* Core integer register.  */
     44        return gdb_get_reg32(mem_buf, env->regs[n]);
     45    }
     46    if (n < 24) {
     47        /* FPA registers.  */
     48        if (gdb_has_xml) {
     49            return 0;
     50        }
     51        return gdb_get_zeroes(mem_buf, 12);
     52    }
     53    switch (n) {
     54    case 24:
     55        /* FPA status register.  */
     56        if (gdb_has_xml) {
     57            return 0;
     58        }
     59        return gdb_get_reg32(mem_buf, 0);
     60    case 25:
     61        /* CPSR, or XPSR for M-profile */
     62        if (arm_feature(env, ARM_FEATURE_M)) {
     63            return gdb_get_reg32(mem_buf, xpsr_read(env));
     64        } else {
     65            return gdb_get_reg32(mem_buf, cpsr_read(env));
     66        }
     67    }
     68    /* Unknown register.  */
     69    return 0;
     70}
     71
     72int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
     73{
     74    ARMCPU *cpu = ARM_CPU(cs);
     75    CPUARMState *env = &cpu->env;
     76    uint32_t tmp;
     77
     78    tmp = ldl_p(mem_buf);
     79
     80    /* Mask out low bit of PC to workaround gdb bugs.  This will probably
     81       cause problems if we ever implement the Jazelle DBX extensions.  */
     82    if (n == 15) {
     83        tmp &= ~1;
     84    }
     85
     86    if (n < 16) {
     87        /* Core integer register.  */
     88        if (n == 13 && arm_feature(env, ARM_FEATURE_M)) {
     89            /* M profile SP low bits are always 0 */
     90            tmp &= ~3;
     91        }
     92        env->regs[n] = tmp;
     93        return 4;
     94    }
     95    if (n < 24) { /* 16-23 */
     96        /* FPA registers (ignored).  */
     97        if (gdb_has_xml) {
     98            return 0;
     99        }
    100        return 12;
    101    }
    102    switch (n) {
    103    case 24:
    104        /* FPA status register (ignored).  */
    105        if (gdb_has_xml) {
    106            return 0;
    107        }
    108        return 4;
    109    case 25:
    110        /* CPSR, or XPSR for M-profile */
    111        if (arm_feature(env, ARM_FEATURE_M)) {
    112            /*
    113             * Don't allow writing to XPSR.Exception as it can cause
    114             * a transition into or out of handler mode (it's not
    115             * writeable via the MSR insn so this is a reasonable
    116             * restriction). Other fields are safe to update.
    117             */
    118            xpsr_write(env, tmp, ~XPSR_EXCP);
    119        } else {
    120            cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
    121        }
    122        return 4;
    123    }
    124    /* Unknown register.  */
    125    return 0;
    126}
    127
    128static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
    129{
    130    ARMCPU *cpu = env_archcpu(env);
    131    int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
    132
    133    /* VFP data registers are always little-endian.  */
    134    if (reg < nregs) {
    135        return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg));
    136    }
    137    if (arm_feature(env, ARM_FEATURE_NEON)) {
    138        /* Aliases for Q regs.  */
    139        nregs += 16;
    140        if (reg < nregs) {
    141            uint64_t *q = aa32_vfp_qreg(env, reg - 32);
    142            return gdb_get_reg128(buf, q[0], q[1]);
    143        }
    144    }
    145    switch (reg - nregs) {
    146    case 0:
    147        return gdb_get_reg32(buf, vfp_get_fpscr(env));
    148    }
    149    return 0;
    150}
    151
    152static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
    153{
    154    ARMCPU *cpu = env_archcpu(env);
    155    int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
    156
    157    if (reg < nregs) {
    158        *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
    159        return 8;
    160    }
    161    if (arm_feature(env, ARM_FEATURE_NEON)) {
    162        nregs += 16;
    163        if (reg < nregs) {
    164            uint64_t *q = aa32_vfp_qreg(env, reg - 32);
    165            q[0] = ldq_le_p(buf);
    166            q[1] = ldq_le_p(buf + 8);
    167            return 16;
    168        }
    169    }
    170    switch (reg - nregs) {
    171    case 0:
    172        vfp_set_fpscr(env, ldl_p(buf));
    173        return 4;
    174    }
    175    return 0;
    176}
    177
    178static int vfp_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
    179{
    180    switch (reg) {
    181    case 0:
    182        return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]);
    183    case 1:
    184        return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]);
    185    }
    186    return 0;
    187}
    188
    189static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
    190{
    191    switch (reg) {
    192    case 0:
    193        env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf);
    194        return 4;
    195    case 1:
    196        env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30);
    197        return 4;
    198    }
    199    return 0;
    200}
    201
    202/**
    203 * arm_get/set_gdb_*: get/set a gdb register
    204 * @env: the CPU state
    205 * @buf: a buffer to copy to/from
    206 * @reg: register number (offset from start of group)
    207 *
    208 * We return the number of bytes copied
    209 */
    210
    211static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
    212{
    213    ARMCPU *cpu = env_archcpu(env);
    214    const ARMCPRegInfo *ri;
    215    uint32_t key;
    216
    217    key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg];
    218    ri = get_arm_cp_reginfo(cpu->cp_regs, key);
    219    if (ri) {
    220        if (cpreg_field_is_64bit(ri)) {
    221            return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
    222        } else {
    223            return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
    224        }
    225    }
    226    return 0;
    227}
    228
    229static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
    230{
    231    return 0;
    232}
    233
    234static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
    235                                       ARMCPRegInfo *ri, uint32_t ri_key,
    236                                       int bitsize, int regnum)
    237{
    238    g_string_append_printf(s, "<reg name=\"%s\"", ri->name);
    239    g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
    240    g_string_append_printf(s, " regnum=\"%d\"", regnum);
    241    g_string_append_printf(s, " group=\"cp_regs\"/>");
    242    dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key;
    243    dyn_xml->num++;
    244}
    245
    246static void arm_register_sysreg_for_xml(gpointer key, gpointer value,
    247                                        gpointer p)
    248{
    249    uint32_t ri_key = *(uint32_t *)key;
    250    ARMCPRegInfo *ri = value;
    251    RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p;
    252    GString *s = param->s;
    253    ARMCPU *cpu = ARM_CPU(param->cs);
    254    CPUARMState *env = &cpu->env;
    255    DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_sysreg_xml;
    256
    257    if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) {
    258        if (arm_feature(env, ARM_FEATURE_AARCH64)) {
    259            if (ri->state == ARM_CP_STATE_AA64) {
    260                arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64,
    261                                           param->n++);
    262            }
    263        } else {
    264            if (ri->state == ARM_CP_STATE_AA32) {
    265                if (!arm_feature(env, ARM_FEATURE_EL3) &&
    266                    (ri->secure & ARM_CP_SECSTATE_S)) {
    267                    return;
    268                }
    269                if (ri->type & ARM_CP_64BIT) {
    270                    arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64,
    271                                               param->n++);
    272                } else {
    273                    arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32,
    274                                               param->n++);
    275                }
    276            }
    277        }
    278    }
    279}
    280
    281int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg)
    282{
    283    ARMCPU *cpu = ARM_CPU(cs);
    284    GString *s = g_string_new(NULL);
    285    RegisterSysregXmlParam param = {cs, s, base_reg};
    286
    287    cpu->dyn_sysreg_xml.num = 0;
    288    cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs));
    289    g_string_printf(s, "<?xml version=\"1.0\"?>");
    290    g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
    291    g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">");
    292    g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_xml, &param);
    293    g_string_append_printf(s, "</feature>");
    294    cpu->dyn_sysreg_xml.desc = g_string_free(s, false);
    295    return cpu->dyn_sysreg_xml.num;
    296}
    297
    298struct TypeSize {
    299    const char *gdb_type;
    300    int  size;
    301    const char sz, suffix;
    302};
    303
    304static const struct TypeSize vec_lanes[] = {
    305    /* quads */
    306    { "uint128", 128, 'q', 'u' },
    307    { "int128", 128, 'q', 's' },
    308    /* 64 bit */
    309    { "ieee_double", 64, 'd', 'f' },
    310    { "uint64", 64, 'd', 'u' },
    311    { "int64", 64, 'd', 's' },
    312    /* 32 bit */
    313    { "ieee_single", 32, 's', 'f' },
    314    { "uint32", 32, 's', 'u' },
    315    { "int32", 32, 's', 's' },
    316    /* 16 bit */
    317    { "ieee_half", 16, 'h', 'f' },
    318    { "uint16", 16, 'h', 'u' },
    319    { "int16", 16, 'h', 's' },
    320    /* bytes */
    321    { "uint8", 8, 'b', 'u' },
    322    { "int8", 8, 'b', 's' },
    323};
    324
    325
    326int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
    327{
    328    ARMCPU *cpu = ARM_CPU(cs);
    329    GString *s = g_string_new(NULL);
    330    DynamicGDBXMLInfo *info = &cpu->dyn_svereg_xml;
    331    g_autoptr(GString) ts = g_string_new("");
    332    int i, j, bits, reg_width = (cpu->sve_max_vq * 128);
    333    info->num = 0;
    334    g_string_printf(s, "<?xml version=\"1.0\"?>");
    335    g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
    336    g_string_append_printf(s, "<feature name=\"org.gnu.gdb.aarch64.sve\">");
    337
    338    /* First define types and totals in a whole VL */
    339    for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
    340        int count = reg_width / vec_lanes[i].size;
    341        g_string_printf(ts, "svev%c%c", vec_lanes[i].sz, vec_lanes[i].suffix);
    342        g_string_append_printf(s,
    343                               "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
    344                               ts->str, vec_lanes[i].gdb_type, count);
    345    }
    346    /*
    347     * Now define a union for each size group containing unsigned and
    348     * signed and potentially float versions of each size from 128 to
    349     * 8 bits.
    350     */
    351    for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) {
    352        const char suf[] = { 'q', 'd', 's', 'h', 'b' };
    353        g_string_append_printf(s, "<union id=\"svevn%c\">", suf[i]);
    354        for (j = 0; j < ARRAY_SIZE(vec_lanes); j++) {
    355            if (vec_lanes[j].size == bits) {
    356                g_string_append_printf(s, "<field name=\"%c\" type=\"svev%c%c\"/>",
    357                                       vec_lanes[j].suffix,
    358                                       vec_lanes[j].sz, vec_lanes[j].suffix);
    359            }
    360        }
    361        g_string_append(s, "</union>");
    362    }
    363    /* And now the final union of unions */
    364    g_string_append(s, "<union id=\"svev\">");
    365    for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) {
    366        const char suf[] = { 'q', 'd', 's', 'h', 'b' };
    367        g_string_append_printf(s, "<field name=\"%c\" type=\"svevn%c\"/>",
    368                               suf[i], suf[i]);
    369    }
    370    g_string_append(s, "</union>");
    371
    372    /* Finally the sve prefix type */
    373    g_string_append_printf(s,
    374                           "<vector id=\"svep\" type=\"uint8\" count=\"%d\"/>",
    375                           reg_width / 8);
    376
    377    /* Then define each register in parts for each vq */
    378    for (i = 0; i < 32; i++) {
    379        g_string_append_printf(s,
    380                               "<reg name=\"z%d\" bitsize=\"%d\""
    381                               " regnum=\"%d\" type=\"svev\"/>",
    382                               i, reg_width, base_reg++);
    383        info->num++;
    384    }
    385    /* fpscr & status registers */
    386    g_string_append_printf(s, "<reg name=\"fpsr\" bitsize=\"32\""
    387                           " regnum=\"%d\" group=\"float\""
    388                           " type=\"int\"/>", base_reg++);
    389    g_string_append_printf(s, "<reg name=\"fpcr\" bitsize=\"32\""
    390                           " regnum=\"%d\" group=\"float\""
    391                           " type=\"int\"/>", base_reg++);
    392    info->num += 2;
    393
    394    for (i = 0; i < 16; i++) {
    395        g_string_append_printf(s,
    396                               "<reg name=\"p%d\" bitsize=\"%d\""
    397                               " regnum=\"%d\" type=\"svep\"/>",
    398                               i, cpu->sve_max_vq * 16, base_reg++);
    399        info->num++;
    400    }
    401    g_string_append_printf(s,
    402                           "<reg name=\"ffr\" bitsize=\"%d\""
    403                           " regnum=\"%d\" group=\"vector\""
    404                           " type=\"svep\"/>",
    405                           cpu->sve_max_vq * 16, base_reg++);
    406    g_string_append_printf(s,
    407                           "<reg name=\"vg\" bitsize=\"64\""
    408                           " regnum=\"%d\" type=\"int\"/>",
    409                           base_reg++);
    410    info->num += 2;
    411    g_string_append_printf(s, "</feature>");
    412    cpu->dyn_svereg_xml.desc = g_string_free(s, false);
    413
    414    return cpu->dyn_svereg_xml.num;
    415}
    416
    417
    418const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
    419{
    420    ARMCPU *cpu = ARM_CPU(cs);
    421
    422    if (strcmp(xmlname, "system-registers.xml") == 0) {
    423        return cpu->dyn_sysreg_xml.desc;
    424    } else if (strcmp(xmlname, "sve-registers.xml") == 0) {
    425        return cpu->dyn_svereg_xml.desc;
    426    }
    427    return NULL;
    428}
    429
    430void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
    431{
    432    CPUState *cs = CPU(cpu);
    433    CPUARMState *env = &cpu->env;
    434
    435    if (arm_feature(env, ARM_FEATURE_AARCH64)) {
    436        /*
    437         * The lower part of each SVE register aliases to the FPU
    438         * registers so we don't need to include both.
    439         */
    440#ifdef TARGET_AARCH64
    441        if (isar_feature_aa64_sve(&cpu->isar)) {
    442            gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
    443                                     arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
    444                                     "sve-registers.xml", 0);
    445        } else {
    446            gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
    447                                     aarch64_fpu_gdb_set_reg,
    448                                     34, "aarch64-fpu.xml", 0);
    449        }
    450#endif
    451    } else {
    452        if (arm_feature(env, ARM_FEATURE_NEON)) {
    453            gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
    454                                     49, "arm-neon.xml", 0);
    455        } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
    456            gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
    457                                     33, "arm-vfp3.xml", 0);
    458        } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
    459            gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
    460                                     17, "arm-vfp.xml", 0);
    461        }
    462        if (!arm_feature(env, ARM_FEATURE_M)) {
    463            /*
    464             * A and R profile have FP sysregs FPEXC and FPSID that we
    465             * expose to gdb.
    466             */
    467            gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_sysreg,
    468                                     2, "arm-vfp-sysregs.xml", 0);
    469        }
    470    }
    471    gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
    472                             arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
    473                             "system-registers.xml", 0);
    474
    475}