2 * i386 CPU dump to FILE
4 * Copyright (c) 2003 Fabrice Bellard
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.
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.
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/>.
20 #include "qemu/osdep.h"
22 #include "qemu/qemu-print.h"
23 #ifndef CONFIG_USER_ONLY
24 #include "hw/i386/apic_internal.h"
27 /***********************************************************/
30 static const char *cc_op_str
[CC_OP_NB
] = {
31 [CC_OP_DYNAMIC
] = "DYNAMIC",
33 [CC_OP_EFLAGS
] = "EFLAGS",
34 [CC_OP_ADCX
] = "ADCX",
35 [CC_OP_ADOX
] = "ADOX",
36 [CC_OP_ADCOX
] = "ADCOX",
38 [CC_OP_MULB
] = "MULB",
39 [CC_OP_MULW
] = "MULW",
40 [CC_OP_MULL
] = "MULL",
41 [CC_OP_MULQ
] = "MULQ",
43 [CC_OP_ADDB
] = "ADDB",
44 [CC_OP_ADDW
] = "ADDW",
45 [CC_OP_ADDL
] = "ADDL",
46 [CC_OP_ADDQ
] = "ADDQ",
48 [CC_OP_ADCB
] = "ADCB",
49 [CC_OP_ADCW
] = "ADCW",
50 [CC_OP_ADCL
] = "ADCL",
51 [CC_OP_ADCQ
] = "ADCQ",
53 [CC_OP_SUBB
] = "SUBB",
54 [CC_OP_SUBW
] = "SUBW",
55 [CC_OP_SUBL
] = "SUBL",
56 [CC_OP_SUBQ
] = "SUBQ",
58 [CC_OP_SBBB
] = "SBBB",
59 [CC_OP_SBBW
] = "SBBW",
60 [CC_OP_SBBL
] = "SBBL",
61 [CC_OP_SBBQ
] = "SBBQ",
63 [CC_OP_LOGICB
] = "LOGICB",
64 [CC_OP_LOGICW
] = "LOGICW",
65 [CC_OP_LOGICL
] = "LOGICL",
66 [CC_OP_LOGICQ
] = "LOGICQ",
68 [CC_OP_INCB
] = "INCB",
69 [CC_OP_INCW
] = "INCW",
70 [CC_OP_INCL
] = "INCL",
71 [CC_OP_INCQ
] = "INCQ",
73 [CC_OP_DECB
] = "DECB",
74 [CC_OP_DECW
] = "DECW",
75 [CC_OP_DECL
] = "DECL",
76 [CC_OP_DECQ
] = "DECQ",
78 [CC_OP_SHLB
] = "SHLB",
79 [CC_OP_SHLW
] = "SHLW",
80 [CC_OP_SHLL
] = "SHLL",
81 [CC_OP_SHLQ
] = "SHLQ",
83 [CC_OP_SARB
] = "SARB",
84 [CC_OP_SARW
] = "SARW",
85 [CC_OP_SARL
] = "SARL",
86 [CC_OP_SARQ
] = "SARQ",
88 [CC_OP_BMILGB
] = "BMILGB",
89 [CC_OP_BMILGW
] = "BMILGW",
90 [CC_OP_BMILGL
] = "BMILGL",
91 [CC_OP_BMILGQ
] = "BMILGQ",
93 [CC_OP_POPCNT
] = "POPCNT",
98 cpu_x86_dump_seg_cache(CPUX86State
*env
, FILE *f
,
99 const char *name
, struct SegmentCache
*sc
)
102 if (env
->hflags
& HF_CS64_MASK
) {
103 qemu_fprintf(f
, "%-3s=%04x %016" PRIx64
" %08x %08x", name
,
104 sc
->selector
, sc
->base
, sc
->limit
,
105 sc
->flags
& 0x00ffff00);
109 qemu_fprintf(f
, "%-3s=%04x %08x %08x %08x", name
, sc
->selector
,
110 (uint32_t)sc
->base
, sc
->limit
,
111 sc
->flags
& 0x00ffff00);
114 if (!(env
->hflags
& HF_PE_MASK
) || !(sc
->flags
& DESC_P_MASK
))
117 qemu_fprintf(f
, " DPL=%d ",
118 (sc
->flags
& DESC_DPL_MASK
) >> DESC_DPL_SHIFT
);
119 if (sc
->flags
& DESC_S_MASK
) {
120 if (sc
->flags
& DESC_CS_MASK
) {
121 qemu_fprintf(f
, (sc
->flags
& DESC_L_MASK
) ? "CS64" :
122 ((sc
->flags
& DESC_B_MASK
) ? "CS32" : "CS16"));
123 qemu_fprintf(f
, " [%c%c", (sc
->flags
& DESC_C_MASK
) ? 'C' : '-',
124 (sc
->flags
& DESC_R_MASK
) ? 'R' : '-');
126 qemu_fprintf(f
, (sc
->flags
& DESC_B_MASK
127 || env
->hflags
& HF_LMA_MASK
)
129 qemu_fprintf(f
, " [%c%c", (sc
->flags
& DESC_E_MASK
) ? 'E' : '-',
130 (sc
->flags
& DESC_W_MASK
) ? 'W' : '-');
132 qemu_fprintf(f
, "%c]", (sc
->flags
& DESC_A_MASK
) ? 'A' : '-');
134 static const char *sys_type_name
[2][16] = {
136 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
137 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
138 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
139 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
142 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
143 "Reserved", "Reserved", "Reserved", "Reserved",
144 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
145 "Reserved", "IntGate64", "TrapGate64"
148 qemu_fprintf(f
, "%s",
149 sys_type_name
[(env
->hflags
& HF_LMA_MASK
) ? 1 : 0]
150 [(sc
->flags
& DESC_TYPE_MASK
) >> DESC_TYPE_SHIFT
]);
153 qemu_fprintf(f
, "\n");
156 #ifndef CONFIG_USER_ONLY
158 /* ARRAY_SIZE check is not required because
159 * DeliveryMode(dm) has a size of 3 bit.
161 static inline const char *dm2str(uint32_t dm
)
163 static const char *str
[] = {
176 static void dump_apic_lvt(const char *name
, uint32_t lvt
, bool is_timer
)
178 uint32_t dm
= (lvt
& APIC_LVT_DELIV_MOD
) >> APIC_LVT_DELIV_MOD_SHIFT
;
179 qemu_printf("%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
181 lvt
& APIC_LVT_INT_POLARITY
? "active-lo" : "active-hi",
182 lvt
& APIC_LVT_LEVEL_TRIGGER
? "level" : "edge",
183 lvt
& APIC_LVT_MASKED
? "masked" : "",
184 lvt
& APIC_LVT_DELIV_STS
? "pending" : "",
186 "" : lvt
& APIC_LVT_TIMER_PERIODIC
?
187 "periodic" : lvt
& APIC_LVT_TIMER_TSCDEADLINE
?
188 "tsc-deadline" : "one-shot",
190 if (dm
!= APIC_DM_NMI
) {
191 qemu_printf(" (vec %u)\n", lvt
& APIC_VECTOR_MASK
);
197 /* ARRAY_SIZE check is not required because
198 * destination shorthand has a size of 2 bit.
200 static inline const char *shorthand2str(uint32_t shorthand
)
202 const char *str
[] = {
203 "no-shorthand", "self", "all-self", "all"
205 return str
[shorthand
];
208 static inline uint8_t divider_conf(uint32_t divide_conf
)
210 uint8_t divide_val
= ((divide_conf
& 0x8) >> 1) | (divide_conf
& 0x3);
212 return divide_val
== 7 ? 1 : 2 << divide_val
;
215 static inline void mask2str(char *str
, uint32_t val
, uint8_t size
)
218 *str
++ = (val
>> size
) & 1 ? '1' : '0';
223 #define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
225 static void dump_apic_icr(APICCommonState
*s
, CPUX86State
*env
)
227 uint32_t icr
= s
->icr
[0], icr2
= s
->icr
[1];
228 uint8_t dest_shorthand
= \
229 (icr
& APIC_ICR_DEST_SHORT
) >> APIC_ICR_DEST_SHORT_SHIFT
;
230 bool logical_mod
= icr
& APIC_ICR_DEST_MOD
;
231 char apic_id_str
[MAX_LOGICAL_APIC_ID_MASK_SIZE
+ 1];
235 qemu_printf("ICR\t 0x%08x %s %s %s %s\n",
237 logical_mod
? "logical" : "physical",
238 icr
& APIC_ICR_TRIGGER_MOD
? "level" : "edge",
239 icr
& APIC_ICR_LEVEL
? "assert" : "de-assert",
240 shorthand2str(dest_shorthand
));
242 qemu_printf("ICR2\t 0x%08x", icr2
);
243 if (dest_shorthand
!= 0) {
247 x2apic
= env
->features
[FEAT_1_ECX
] & CPUID_EXT_X2APIC
;
248 dest_field
= x2apic
? icr2
: icr2
>> APIC_ICR_DEST_SHIFT
;
252 qemu_printf(" cpu %u (X2APIC ID)\n", dest_field
);
254 qemu_printf(" cpu %u (APIC ID)\n",
255 dest_field
& APIC_LOGDEST_XAPIC_ID
);
260 if (s
->dest_mode
== 0xf) { /* flat mode */
261 mask2str(apic_id_str
, icr2
>> APIC_ICR_DEST_SHIFT
, 8);
262 qemu_printf(" mask %s (APIC ID)\n", apic_id_str
);
263 } else if (s
->dest_mode
== 0) { /* cluster mode */
265 mask2str(apic_id_str
, dest_field
& APIC_LOGDEST_X2APIC_ID
, 16);
266 qemu_printf(" cluster %u mask %s (X2APIC ID)\n",
267 dest_field
>> APIC_LOGDEST_X2APIC_SHIFT
, apic_id_str
);
269 mask2str(apic_id_str
, dest_field
& APIC_LOGDEST_XAPIC_ID
, 4);
270 qemu_printf(" cluster %u mask %s (APIC ID)\n",
271 dest_field
>> APIC_LOGDEST_XAPIC_SHIFT
, apic_id_str
);
276 static void dump_apic_interrupt(const char *name
, uint32_t *ireg_tab
,
281 qemu_printf("%s\t ", name
);
282 for (i
= 0; i
< 256; i
++) {
283 if (apic_get_bit(ireg_tab
, i
)) {
284 qemu_printf("%u%s ", i
,
285 apic_get_bit(tmr_tab
, i
) ? "(level)" : "");
289 qemu_printf("%s\n", empty
? "(none)" : "");
292 void x86_cpu_dump_local_apic_state(CPUState
*cs
, int flags
)
294 X86CPU
*cpu
= X86_CPU(cs
);
295 APICCommonState
*s
= APIC_COMMON(cpu
->apic_state
);
297 qemu_printf("local apic state not available\n");
300 uint32_t *lvt
= s
->lvt
;
302 qemu_printf("dumping local APIC state for CPU %-2u\n\n",
303 CPU(cpu
)->cpu_index
);
304 dump_apic_lvt("LVT0", lvt
[APIC_LVT_LINT0
], false);
305 dump_apic_lvt("LVT1", lvt
[APIC_LVT_LINT1
], false);
306 dump_apic_lvt("LVTPC", lvt
[APIC_LVT_PERFORM
], false);
307 dump_apic_lvt("LVTERR", lvt
[APIC_LVT_ERROR
], false);
308 dump_apic_lvt("LVTTHMR", lvt
[APIC_LVT_THERMAL
], false);
309 dump_apic_lvt("LVTT", lvt
[APIC_LVT_TIMER
], true);
311 qemu_printf("Timer\t DCR=0x%x (divide by %u) initial_count = %u"
312 " current_count = %u\n",
313 s
->divide_conf
& APIC_DCR_MASK
,
314 divider_conf(s
->divide_conf
),
315 s
->initial_count
, apic_get_current_count(s
));
317 qemu_printf("SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
319 s
->spurious_vec
& APIC_SPURIO_ENABLED
? "enabled" : "disabled",
320 s
->spurious_vec
& APIC_SPURIO_FOCUS
? "on" : "off",
321 s
->spurious_vec
& APIC_VECTOR_MASK
);
323 dump_apic_icr(s
, &cpu
->env
);
325 qemu_printf("ESR\t 0x%08x\n", s
->esr
);
327 dump_apic_interrupt("ISR", s
->isr
, s
->tmr
);
328 dump_apic_interrupt("IRR", s
->irr
, s
->tmr
);
330 qemu_printf("\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
331 s
->arb_id
, s
->tpr
, s
->dest_mode
, s
->log_dest
);
332 if (s
->dest_mode
== 0) {
333 qemu_printf("(cluster %u: id %u)",
334 s
->log_dest
>> APIC_LOGDEST_XAPIC_SHIFT
,
335 s
->log_dest
& APIC_LOGDEST_XAPIC_ID
);
337 qemu_printf(" PPR 0x%02x\n", apic_get_ppr(s
));
340 #endif /* !CONFIG_USER_ONLY */
342 #define DUMP_CODE_BYTES_TOTAL 50
343 #define DUMP_CODE_BYTES_BACKWARD 20
345 void x86_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
347 X86CPU
*cpu
= X86_CPU(cs
);
348 CPUX86State
*env
= &cpu
->env
;
351 static const char *seg_name
[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
353 eflags
= cpu_compute_eflags(env
);
355 if (env
->hflags
& HF_CS64_MASK
) {
356 qemu_fprintf(f
, "RAX=%016" PRIx64
" RBX=%016" PRIx64
" RCX=%016" PRIx64
" RDX=%016" PRIx64
"\n"
357 "RSI=%016" PRIx64
" RDI=%016" PRIx64
" RBP=%016" PRIx64
" RSP=%016" PRIx64
"\n"
358 "R8 =%016" PRIx64
" R9 =%016" PRIx64
" R10=%016" PRIx64
" R11=%016" PRIx64
"\n"
359 "R12=%016" PRIx64
" R13=%016" PRIx64
" R14=%016" PRIx64
" R15=%016" PRIx64
"\n"
360 "RIP=%016" PRIx64
" RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
378 eflags
& DF_MASK
? 'D' : '-',
379 eflags
& CC_O
? 'O' : '-',
380 eflags
& CC_S
? 'S' : '-',
381 eflags
& CC_Z
? 'Z' : '-',
382 eflags
& CC_A
? 'A' : '-',
383 eflags
& CC_P
? 'P' : '-',
384 eflags
& CC_C
? 'C' : '-',
385 env
->hflags
& HF_CPL_MASK
,
386 (env
->hflags
>> HF_INHIBIT_IRQ_SHIFT
) & 1,
387 (env
->a20_mask
>> 20) & 1,
388 (env
->hflags
>> HF_SMM_SHIFT
) & 1,
393 qemu_fprintf(f
, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
394 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
395 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
396 (uint32_t)env
->regs
[R_EAX
],
397 (uint32_t)env
->regs
[R_EBX
],
398 (uint32_t)env
->regs
[R_ECX
],
399 (uint32_t)env
->regs
[R_EDX
],
400 (uint32_t)env
->regs
[R_ESI
],
401 (uint32_t)env
->regs
[R_EDI
],
402 (uint32_t)env
->regs
[R_EBP
],
403 (uint32_t)env
->regs
[R_ESP
],
404 (uint32_t)env
->eip
, eflags
,
405 eflags
& DF_MASK
? 'D' : '-',
406 eflags
& CC_O
? 'O' : '-',
407 eflags
& CC_S
? 'S' : '-',
408 eflags
& CC_Z
? 'Z' : '-',
409 eflags
& CC_A
? 'A' : '-',
410 eflags
& CC_P
? 'P' : '-',
411 eflags
& CC_C
? 'C' : '-',
412 env
->hflags
& HF_CPL_MASK
,
413 (env
->hflags
>> HF_INHIBIT_IRQ_SHIFT
) & 1,
414 (env
->a20_mask
>> 20) & 1,
415 (env
->hflags
>> HF_SMM_SHIFT
) & 1,
419 for(i
= 0; i
< 6; i
++) {
420 cpu_x86_dump_seg_cache(env
, f
, seg_name
[i
], &env
->segs
[i
]);
422 cpu_x86_dump_seg_cache(env
, f
, "LDT", &env
->ldt
);
423 cpu_x86_dump_seg_cache(env
, f
, "TR", &env
->tr
);
426 if (env
->hflags
& HF_LMA_MASK
) {
427 qemu_fprintf(f
, "GDT= %016" PRIx64
" %08x\n",
428 env
->gdt
.base
, env
->gdt
.limit
);
429 qemu_fprintf(f
, "IDT= %016" PRIx64
" %08x\n",
430 env
->idt
.base
, env
->idt
.limit
);
431 qemu_fprintf(f
, "CR0=%08x CR2=%016" PRIx64
" CR3=%016" PRIx64
" CR4=%08x\n",
432 (uint32_t)env
->cr
[0],
435 (uint32_t)env
->cr
[4]);
436 for(i
= 0; i
< 4; i
++)
437 qemu_fprintf(f
, "DR%d=%016" PRIx64
" ", i
, env
->dr
[i
]);
438 qemu_fprintf(f
, "\nDR6=%016" PRIx64
" DR7=%016" PRIx64
"\n",
439 env
->dr
[6], env
->dr
[7]);
443 qemu_fprintf(f
, "GDT= %08x %08x\n",
444 (uint32_t)env
->gdt
.base
, env
->gdt
.limit
);
445 qemu_fprintf(f
, "IDT= %08x %08x\n",
446 (uint32_t)env
->idt
.base
, env
->idt
.limit
);
447 qemu_fprintf(f
, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
448 (uint32_t)env
->cr
[0],
449 (uint32_t)env
->cr
[2],
450 (uint32_t)env
->cr
[3],
451 (uint32_t)env
->cr
[4]);
452 for(i
= 0; i
< 4; i
++) {
453 qemu_fprintf(f
, "DR%d=" TARGET_FMT_lx
" ", i
, env
->dr
[i
]);
455 qemu_fprintf(f
, "\nDR6=" TARGET_FMT_lx
" DR7=" TARGET_FMT_lx
"\n",
456 env
->dr
[6], env
->dr
[7]);
458 if (flags
& CPU_DUMP_CCOP
) {
459 if ((unsigned)env
->cc_op
< CC_OP_NB
)
460 snprintf(cc_op_name
, sizeof(cc_op_name
), "%s", cc_op_str
[env
->cc_op
]);
462 snprintf(cc_op_name
, sizeof(cc_op_name
), "[%d]", env
->cc_op
);
464 if (env
->hflags
& HF_CS64_MASK
) {
465 qemu_fprintf(f
, "CCS=%016" PRIx64
" CCD=%016" PRIx64
" CCO=%s\n",
466 env
->cc_src
, env
->cc_dst
,
471 qemu_fprintf(f
, "CCS=%08x CCD=%08x CCO=%s\n",
472 (uint32_t)env
->cc_src
, (uint32_t)env
->cc_dst
,
476 qemu_fprintf(f
, "EFER=%016" PRIx64
"\n", env
->efer
);
477 if (flags
& CPU_DUMP_FPU
) {
479 const uint64_t avx512_mask
= XSTATE_OPMASK_MASK
| \
480 XSTATE_ZMM_Hi256_MASK
| \
481 XSTATE_Hi16_ZMM_MASK
| \
482 XSTATE_YMM_MASK
| XSTATE_SSE_MASK
,
483 avx_mask
= XSTATE_YMM_MASK
| XSTATE_SSE_MASK
;
485 for(i
= 0; i
< 8; i
++) {
486 fptag
|= ((!env
->fptags
[i
]) << i
);
488 update_mxcsr_from_sse_status(env
);
489 qemu_fprintf(f
, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
491 (env
->fpus
& ~0x3800) | (env
->fpstt
& 0x7) << 11,
497 u
.d
= env
->fpregs
[i
].d
;
498 qemu_fprintf(f
, "FPR%d=%016" PRIx64
" %04x",
499 i
, u
.l
.lower
, u
.l
.upper
);
501 qemu_fprintf(f
, "\n");
503 qemu_fprintf(f
, " ");
506 if ((env
->xcr0
& avx512_mask
) == avx512_mask
) {
507 /* XSAVE enabled AVX512 */
508 for (i
= 0; i
< NB_OPMASK_REGS
; i
++) {
509 qemu_fprintf(f
, "Opmask%02d=%016"PRIx64
"%s", i
,
510 env
->opmask_regs
[i
], ((i
& 3) == 3) ? "\n" : " ");
513 nb
= (env
->hflags
& HF_CS64_MASK
) ? 32 : 8;
514 for (i
= 0; i
< nb
; i
++) {
515 qemu_fprintf(f
, "ZMM%02d=%016"PRIx64
" %016"PRIx64
" %016"PRIx64
516 " %016"PRIx64
" %016"PRIx64
" %016"PRIx64
517 " %016"PRIx64
" %016"PRIx64
"\n",
519 env
->xmm_regs
[i
].ZMM_Q(7),
520 env
->xmm_regs
[i
].ZMM_Q(6),
521 env
->xmm_regs
[i
].ZMM_Q(5),
522 env
->xmm_regs
[i
].ZMM_Q(4),
523 env
->xmm_regs
[i
].ZMM_Q(3),
524 env
->xmm_regs
[i
].ZMM_Q(2),
525 env
->xmm_regs
[i
].ZMM_Q(1),
526 env
->xmm_regs
[i
].ZMM_Q(0));
528 } else if ((env
->xcr0
& avx_mask
) == avx_mask
) {
529 /* XSAVE enabled AVX */
530 nb
= env
->hflags
& HF_CS64_MASK
? 16 : 8;
531 for (i
= 0; i
< nb
; i
++) {
532 qemu_fprintf(f
, "YMM%02d=%016"PRIx64
" %016"PRIx64
" %016"PRIx64
533 " %016"PRIx64
"\n", i
,
534 env
->xmm_regs
[i
].ZMM_Q(3),
535 env
->xmm_regs
[i
].ZMM_Q(2),
536 env
->xmm_regs
[i
].ZMM_Q(1),
537 env
->xmm_regs
[i
].ZMM_Q(0));
539 } else { /* SSE and below cases */
540 nb
= env
->hflags
& HF_CS64_MASK
? 16 : 8;
541 for (i
= 0; i
< nb
; i
++) {
542 qemu_fprintf(f
, "XMM%02d=%016"PRIx64
" %016"PRIx64
"%s",
544 env
->xmm_regs
[i
].ZMM_Q(1),
545 env
->xmm_regs
[i
].ZMM_Q(0),
546 (i
& 1) ? "\n" : " ");
550 if (flags
& CPU_DUMP_CODE
) {
551 target_ulong base
= env
->segs
[R_CS
].base
+ env
->eip
;
552 target_ulong offs
= MIN(env
->eip
, DUMP_CODE_BYTES_BACKWARD
);
556 qemu_fprintf(f
, "Code=");
557 for (i
= 0; i
< DUMP_CODE_BYTES_TOTAL
; i
++) {
558 if (cpu_memory_rw_debug(cs
, base
- offs
+ i
, &code
, 1, 0) == 0) {
559 snprintf(codestr
, sizeof(codestr
), "%02x", code
);
561 snprintf(codestr
, sizeof(codestr
), "??");
563 qemu_fprintf(f
, "%s%s%s%s", i
> 0 ? " " : "",
564 i
== offs
? "<" : "", codestr
, i
== offs
? ">" : "");
566 qemu_fprintf(f
, "\n");