qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

gdbstub.c (16659B)


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