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

cpu-dump.c (20020B)


      1/*
      2 *  i386 CPU dump to FILE
      3 *
      4 *  Copyright (c) 2003 Fabrice Bellard
      5 *
      6 * This library is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "qemu/osdep.h"
     21#include "cpu.h"
     22#include "qemu/qemu-print.h"
     23#ifndef CONFIG_USER_ONLY
     24#include "hw/i386/apic_internal.h"
     25#endif
     26
     27/***********************************************************/
     28/* x86 debug */
     29
     30static const char *cc_op_str[CC_OP_NB] = {
     31    "DYNAMIC",
     32    "EFLAGS",
     33
     34    "MULB",
     35    "MULW",
     36    "MULL",
     37    "MULQ",
     38
     39    "ADDB",
     40    "ADDW",
     41    "ADDL",
     42    "ADDQ",
     43
     44    "ADCB",
     45    "ADCW",
     46    "ADCL",
     47    "ADCQ",
     48
     49    "SUBB",
     50    "SUBW",
     51    "SUBL",
     52    "SUBQ",
     53
     54    "SBBB",
     55    "SBBW",
     56    "SBBL",
     57    "SBBQ",
     58
     59    "LOGICB",
     60    "LOGICW",
     61    "LOGICL",
     62    "LOGICQ",
     63
     64    "INCB",
     65    "INCW",
     66    "INCL",
     67    "INCQ",
     68
     69    "DECB",
     70    "DECW",
     71    "DECL",
     72    "DECQ",
     73
     74    "SHLB",
     75    "SHLW",
     76    "SHLL",
     77    "SHLQ",
     78
     79    "SARB",
     80    "SARW",
     81    "SARL",
     82    "SARQ",
     83
     84    "BMILGB",
     85    "BMILGW",
     86    "BMILGL",
     87    "BMILGQ",
     88
     89    "ADCX",
     90    "ADOX",
     91    "ADCOX",
     92
     93    "CLR",
     94};
     95
     96static void
     97cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f,
     98                       const char *name, struct SegmentCache *sc)
     99{
    100#ifdef TARGET_X86_64
    101    if (env->hflags & HF_CS64_MASK) {
    102        qemu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
    103                     sc->selector, sc->base, sc->limit,
    104                     sc->flags & 0x00ffff00);
    105    } else
    106#endif
    107    {
    108        qemu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
    109                     (uint32_t)sc->base, sc->limit,
    110                     sc->flags & 0x00ffff00);
    111    }
    112
    113    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
    114        goto done;
    115
    116    qemu_fprintf(f, " DPL=%d ",
    117                 (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
    118    if (sc->flags & DESC_S_MASK) {
    119        if (sc->flags & DESC_CS_MASK) {
    120            qemu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
    121                         ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
    122            qemu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
    123                         (sc->flags & DESC_R_MASK) ? 'R' : '-');
    124        } else {
    125            qemu_fprintf(f, (sc->flags & DESC_B_MASK
    126                             || env->hflags & HF_LMA_MASK)
    127                         ? "DS  " : "DS16");
    128            qemu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
    129                         (sc->flags & DESC_W_MASK) ? 'W' : '-');
    130        }
    131        qemu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
    132    } else {
    133        static const char *sys_type_name[2][16] = {
    134            { /* 32 bit mode */
    135                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
    136                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
    137                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
    138                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
    139            },
    140            { /* 64 bit mode */
    141                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
    142                "Reserved", "Reserved", "Reserved", "Reserved",
    143                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
    144                "Reserved", "IntGate64", "TrapGate64"
    145            }
    146        };
    147        qemu_fprintf(f, "%s",
    148                     sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
    149                     [(sc->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT]);
    150    }
    151done:
    152    qemu_fprintf(f, "\n");
    153}
    154
    155#ifndef CONFIG_USER_ONLY
    156
    157/* ARRAY_SIZE check is not required because
    158 * DeliveryMode(dm) has a size of 3 bit.
    159 */
    160static inline const char *dm2str(uint32_t dm)
    161{
    162    static const char *str[] = {
    163        "Fixed",
    164        "...",
    165        "SMI",
    166        "...",
    167        "NMI",
    168        "INIT",
    169        "...",
    170        "ExtINT"
    171    };
    172    return str[dm];
    173}
    174
    175static void dump_apic_lvt(const char *name, uint32_t lvt, bool is_timer)
    176{
    177    uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
    178    qemu_printf("%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
    179                name, lvt,
    180                lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
    181                lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
    182                lvt & APIC_LVT_MASKED ? "masked" : "",
    183                lvt & APIC_LVT_DELIV_STS ? "pending" : "",
    184                !is_timer ?
    185                    "" : lvt & APIC_LVT_TIMER_PERIODIC ?
    186                            "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
    187                                            "tsc-deadline" : "one-shot",
    188                dm2str(dm));
    189    if (dm != APIC_DM_NMI) {
    190        qemu_printf(" (vec %u)\n", lvt & APIC_VECTOR_MASK);
    191    } else {
    192        qemu_printf("\n");
    193    }
    194}
    195
    196/* ARRAY_SIZE check is not required because
    197 * destination shorthand has a size of 2 bit.
    198 */
    199static inline const char *shorthand2str(uint32_t shorthand)
    200{
    201    const char *str[] = {
    202        "no-shorthand", "self", "all-self", "all"
    203    };
    204    return str[shorthand];
    205}
    206
    207static inline uint8_t divider_conf(uint32_t divide_conf)
    208{
    209    uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
    210
    211    return divide_val == 7 ? 1 : 2 << divide_val;
    212}
    213
    214static inline void mask2str(char *str, uint32_t val, uint8_t size)
    215{
    216    while (size--) {
    217        *str++ = (val >> size) & 1 ? '1' : '0';
    218    }
    219    *str = 0;
    220}
    221
    222#define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
    223
    224static void dump_apic_icr(APICCommonState *s, CPUX86State *env)
    225{
    226    uint32_t icr = s->icr[0], icr2 = s->icr[1];
    227    uint8_t dest_shorthand = \
    228        (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
    229    bool logical_mod = icr & APIC_ICR_DEST_MOD;
    230    char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
    231    uint32_t dest_field;
    232    bool x2apic;
    233
    234    qemu_printf("ICR\t 0x%08x %s %s %s %s\n",
    235                icr,
    236                logical_mod ? "logical" : "physical",
    237                icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
    238                icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
    239                shorthand2str(dest_shorthand));
    240
    241    qemu_printf("ICR2\t 0x%08x", icr2);
    242    if (dest_shorthand != 0) {
    243        qemu_printf("\n");
    244        return;
    245    }
    246    x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
    247    dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
    248
    249    if (!logical_mod) {
    250        if (x2apic) {
    251            qemu_printf(" cpu %u (X2APIC ID)\n", dest_field);
    252        } else {
    253            qemu_printf(" cpu %u (APIC ID)\n",
    254                        dest_field & APIC_LOGDEST_XAPIC_ID);
    255        }
    256        return;
    257    }
    258
    259    if (s->dest_mode == 0xf) { /* flat mode */
    260        mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
    261        qemu_printf(" mask %s (APIC ID)\n", apic_id_str);
    262    } else if (s->dest_mode == 0) { /* cluster mode */
    263        if (x2apic) {
    264            mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
    265            qemu_printf(" cluster %u mask %s (X2APIC ID)\n",
    266                        dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
    267        } else {
    268            mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
    269            qemu_printf(" cluster %u mask %s (APIC ID)\n",
    270                        dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
    271        }
    272    }
    273}
    274
    275static void dump_apic_interrupt(const char *name, uint32_t *ireg_tab,
    276                                uint32_t *tmr_tab)
    277{
    278    int i, empty = true;
    279
    280    qemu_printf("%s\t ", name);
    281    for (i = 0; i < 256; i++) {
    282        if (apic_get_bit(ireg_tab, i)) {
    283            qemu_printf("%u%s ", i,
    284                        apic_get_bit(tmr_tab, i) ? "(level)" : "");
    285            empty = false;
    286        }
    287    }
    288    qemu_printf("%s\n", empty ? "(none)" : "");
    289}
    290
    291void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
    292{
    293    X86CPU *cpu = X86_CPU(cs);
    294    APICCommonState *s = APIC_COMMON(cpu->apic_state);
    295    if (!s) {
    296        qemu_printf("local apic state not available\n");
    297        return;
    298    }
    299    uint32_t *lvt = s->lvt;
    300
    301    qemu_printf("dumping local APIC state for CPU %-2u\n\n",
    302                CPU(cpu)->cpu_index);
    303    dump_apic_lvt("LVT0", lvt[APIC_LVT_LINT0], false);
    304    dump_apic_lvt("LVT1", lvt[APIC_LVT_LINT1], false);
    305    dump_apic_lvt("LVTPC", lvt[APIC_LVT_PERFORM], false);
    306    dump_apic_lvt("LVTERR", lvt[APIC_LVT_ERROR], false);
    307    dump_apic_lvt("LVTTHMR", lvt[APIC_LVT_THERMAL], false);
    308    dump_apic_lvt("LVTT", lvt[APIC_LVT_TIMER], true);
    309
    310    qemu_printf("Timer\t DCR=0x%x (divide by %u) initial_count = %u"
    311                " current_count = %u\n",
    312                s->divide_conf & APIC_DCR_MASK,
    313                divider_conf(s->divide_conf),
    314                s->initial_count, apic_get_current_count(s));
    315
    316    qemu_printf("SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
    317                s->spurious_vec,
    318                s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
    319                s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
    320                s->spurious_vec & APIC_VECTOR_MASK);
    321
    322    dump_apic_icr(s, &cpu->env);
    323
    324    qemu_printf("ESR\t 0x%08x\n", s->esr);
    325
    326    dump_apic_interrupt("ISR", s->isr, s->tmr);
    327    dump_apic_interrupt("IRR", s->irr, s->tmr);
    328
    329    qemu_printf("\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
    330                s->arb_id, s->tpr, s->dest_mode, s->log_dest);
    331    if (s->dest_mode == 0) {
    332        qemu_printf("(cluster %u: id %u)",
    333                    s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
    334                    s->log_dest & APIC_LOGDEST_XAPIC_ID);
    335    }
    336    qemu_printf(" PPR 0x%02x\n", apic_get_ppr(s));
    337}
    338#else
    339void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
    340{
    341}
    342#endif /* !CONFIG_USER_ONLY */
    343
    344#define DUMP_CODE_BYTES_TOTAL    50
    345#define DUMP_CODE_BYTES_BACKWARD 20
    346
    347void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags)
    348{
    349    X86CPU *cpu = X86_CPU(cs);
    350    CPUX86State *env = &cpu->env;
    351    int eflags, i, nb;
    352    char cc_op_name[32];
    353    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
    354
    355    eflags = cpu_compute_eflags(env);
    356#ifdef TARGET_X86_64
    357    if (env->hflags & HF_CS64_MASK) {
    358        qemu_fprintf(f, "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
    359                     "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
    360                     "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
    361                     "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
    362                     "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
    363                     env->regs[R_EAX],
    364                     env->regs[R_EBX],
    365                     env->regs[R_ECX],
    366                     env->regs[R_EDX],
    367                     env->regs[R_ESI],
    368                     env->regs[R_EDI],
    369                     env->regs[R_EBP],
    370                     env->regs[R_ESP],
    371                     env->regs[8],
    372                     env->regs[9],
    373                     env->regs[10],
    374                     env->regs[11],
    375                     env->regs[12],
    376                     env->regs[13],
    377                     env->regs[14],
    378                     env->regs[15],
    379                     env->eip, eflags,
    380                     eflags & DF_MASK ? 'D' : '-',
    381                     eflags & CC_O ? 'O' : '-',
    382                     eflags & CC_S ? 'S' : '-',
    383                     eflags & CC_Z ? 'Z' : '-',
    384                     eflags & CC_A ? 'A' : '-',
    385                     eflags & CC_P ? 'P' : '-',
    386                     eflags & CC_C ? 'C' : '-',
    387                     env->hflags & HF_CPL_MASK,
    388                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
    389                     (env->a20_mask >> 20) & 1,
    390                     (env->hflags >> HF_SMM_SHIFT) & 1,
    391                     cs->halted);
    392    } else
    393#endif
    394    {
    395        qemu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
    396                     "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
    397                     "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
    398                     (uint32_t)env->regs[R_EAX],
    399                     (uint32_t)env->regs[R_EBX],
    400                     (uint32_t)env->regs[R_ECX],
    401                     (uint32_t)env->regs[R_EDX],
    402                     (uint32_t)env->regs[R_ESI],
    403                     (uint32_t)env->regs[R_EDI],
    404                     (uint32_t)env->regs[R_EBP],
    405                     (uint32_t)env->regs[R_ESP],
    406                     (uint32_t)env->eip, eflags,
    407                     eflags & DF_MASK ? 'D' : '-',
    408                     eflags & CC_O ? 'O' : '-',
    409                     eflags & CC_S ? 'S' : '-',
    410                     eflags & CC_Z ? 'Z' : '-',
    411                     eflags & CC_A ? 'A' : '-',
    412                     eflags & CC_P ? 'P' : '-',
    413                     eflags & CC_C ? 'C' : '-',
    414                     env->hflags & HF_CPL_MASK,
    415                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
    416                     (env->a20_mask >> 20) & 1,
    417                     (env->hflags >> HF_SMM_SHIFT) & 1,
    418                     cs->halted);
    419    }
    420
    421    for(i = 0; i < 6; i++) {
    422        cpu_x86_dump_seg_cache(env, f, seg_name[i], &env->segs[i]);
    423    }
    424    cpu_x86_dump_seg_cache(env, f, "LDT", &env->ldt);
    425    cpu_x86_dump_seg_cache(env, f, "TR", &env->tr);
    426
    427#ifdef TARGET_X86_64
    428    if (env->hflags & HF_LMA_MASK) {
    429        qemu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
    430                     env->gdt.base, env->gdt.limit);
    431        qemu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
    432                     env->idt.base, env->idt.limit);
    433        qemu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
    434                     (uint32_t)env->cr[0],
    435                     env->cr[2],
    436                     env->cr[3],
    437                     (uint32_t)env->cr[4]);
    438        for(i = 0; i < 4; i++)
    439            qemu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
    440        qemu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
    441                     env->dr[6], env->dr[7]);
    442    } else
    443#endif
    444    {
    445        qemu_fprintf(f, "GDT=     %08x %08x\n",
    446                     (uint32_t)env->gdt.base, env->gdt.limit);
    447        qemu_fprintf(f, "IDT=     %08x %08x\n",
    448                     (uint32_t)env->idt.base, env->idt.limit);
    449        qemu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
    450                     (uint32_t)env->cr[0],
    451                     (uint32_t)env->cr[2],
    452                     (uint32_t)env->cr[3],
    453                     (uint32_t)env->cr[4]);
    454        for(i = 0; i < 4; i++) {
    455            qemu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
    456        }
    457        qemu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
    458                     env->dr[6], env->dr[7]);
    459    }
    460    if (flags & CPU_DUMP_CCOP) {
    461        if ((unsigned)env->cc_op < CC_OP_NB)
    462            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
    463        else
    464            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
    465#ifdef TARGET_X86_64
    466        if (env->hflags & HF_CS64_MASK) {
    467            qemu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
    468                         env->cc_src, env->cc_dst,
    469                         cc_op_name);
    470        } else
    471#endif
    472        {
    473            qemu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
    474                         (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
    475                         cc_op_name);
    476        }
    477    }
    478    qemu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
    479    if (flags & CPU_DUMP_FPU) {
    480        int fptag;
    481        const uint64_t avx512_mask = XSTATE_OPMASK_MASK | \
    482                                     XSTATE_ZMM_Hi256_MASK | \
    483                                     XSTATE_Hi16_ZMM_MASK | \
    484                                     XSTATE_YMM_MASK | XSTATE_SSE_MASK,
    485                       avx_mask = XSTATE_YMM_MASK | XSTATE_SSE_MASK;
    486        fptag = 0;
    487        for(i = 0; i < 8; i++) {
    488            fptag |= ((!env->fptags[i]) << i);
    489        }
    490        update_mxcsr_from_sse_status(env);
    491        qemu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
    492                     env->fpuc,
    493                     (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
    494                     env->fpstt,
    495                     fptag,
    496                     env->mxcsr);
    497        for(i=0;i<8;i++) {
    498            CPU_LDoubleU u;
    499            u.d = env->fpregs[i].d;
    500            qemu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
    501                         i, u.l.lower, u.l.upper);
    502            if ((i & 1) == 1)
    503                qemu_fprintf(f, "\n");
    504            else
    505                qemu_fprintf(f, " ");
    506        }
    507
    508        if ((env->xcr0 & avx512_mask) == avx512_mask) {
    509            /* XSAVE enabled AVX512 */
    510            for (i = 0; i < NB_OPMASK_REGS; i++) {
    511                qemu_fprintf(f, "Opmask%02d=%016"PRIx64"%s", i,
    512                             env->opmask_regs[i], ((i & 3) == 3) ? "\n" : " ");
    513            }
    514
    515            nb = (env->hflags & HF_CS64_MASK) ? 32 : 8;
    516            for (i = 0; i < nb; i++) {
    517                qemu_fprintf(f, "ZMM%02d=%016"PRIx64" %016"PRIx64" %016"PRIx64
    518                             " %016"PRIx64" %016"PRIx64" %016"PRIx64
    519                             " %016"PRIx64" %016"PRIx64"\n",
    520                             i,
    521                             env->xmm_regs[i].ZMM_Q(7),
    522                             env->xmm_regs[i].ZMM_Q(6),
    523                             env->xmm_regs[i].ZMM_Q(5),
    524                             env->xmm_regs[i].ZMM_Q(4),
    525                             env->xmm_regs[i].ZMM_Q(3),
    526                             env->xmm_regs[i].ZMM_Q(2),
    527                             env->xmm_regs[i].ZMM_Q(1),
    528                             env->xmm_regs[i].ZMM_Q(0));
    529            }
    530        } else if ((env->xcr0 & avx_mask)  == avx_mask) {
    531            /* XSAVE enabled AVX */
    532            nb = env->hflags & HF_CS64_MASK ? 16 : 8;
    533            for (i = 0; i < nb; i++) {
    534                qemu_fprintf(f, "YMM%02d=%016"PRIx64" %016"PRIx64" %016"PRIx64
    535                             " %016"PRIx64"\n", i,
    536                             env->xmm_regs[i].ZMM_Q(3),
    537                             env->xmm_regs[i].ZMM_Q(2),
    538                             env->xmm_regs[i].ZMM_Q(1),
    539                             env->xmm_regs[i].ZMM_Q(0));
    540            }
    541        } else { /* SSE and below cases */
    542            nb = env->hflags & HF_CS64_MASK ? 16 : 8;
    543            for (i = 0; i < nb; i++) {
    544                qemu_fprintf(f, "XMM%02d=%016"PRIx64" %016"PRIx64"%s",
    545                             i,
    546                             env->xmm_regs[i].ZMM_Q(1),
    547                             env->xmm_regs[i].ZMM_Q(0),
    548                             (i & 1) ? "\n" : " ");
    549            }
    550        }
    551    }
    552    if (flags & CPU_DUMP_CODE) {
    553        target_ulong base = env->segs[R_CS].base + env->eip;
    554        target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
    555        uint8_t code;
    556        char codestr[3];
    557
    558        qemu_fprintf(f, "Code=");
    559        for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
    560            if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
    561                snprintf(codestr, sizeof(codestr), "%02x", code);
    562            } else {
    563                snprintf(codestr, sizeof(codestr), "??");
    564            }
    565            qemu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
    566                         i == offs ? "<" : "", codestr, i == offs ? ">" : "");
    567        }
    568        qemu_fprintf(f, "\n");
    569    }
    570}