disas: Add print_insn to disassemble info

Add the print_insn pointer to the disassemble info structure. This is
to prepare for QOMification support, where a QOM CPU hook function will
be responsible for setting the print_insn() function. Add this function
to the existing struct to consolidate such that only the one struct
needs to be passed to the new QOM API.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
Peter Crosthwaite 2015-06-23 20:57:32 -07:00 committed by Andreas Färber
parent 691b9572e3
commit 2de295c544
2 changed files with 39 additions and 35 deletions

68
disas.c
View File

@ -201,7 +201,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
target_ulong pc; target_ulong pc;
int count; int count;
CPUDebug s; CPUDebug s;
int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
INIT_DISASSEMBLE_INFO(s.info, out, fprintf); INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
@ -224,7 +223,7 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
} else { } else {
s.info.mach = bfd_mach_i386_i386; s.info.mach = bfd_mach_i386_i386;
} }
print_insn = print_insn_i386; s.info.print_insn = print_insn_i386;
#elif defined(TARGET_ARM) #elif defined(TARGET_ARM)
if (flags & 4) { if (flags & 4) {
/* We might not be compiled with the A64 disassembler /* We might not be compiled with the A64 disassembler
@ -232,12 +231,12 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
* fall through to the default print_insn_od case. * fall through to the default print_insn_od case.
*/ */
#if defined(CONFIG_ARM_A64_DIS) #if defined(CONFIG_ARM_A64_DIS)
print_insn = print_insn_arm_a64; s.info.print_insn = print_insn_arm_a64;
#endif #endif
} else if (flags & 1) { } else if (flags & 1) {
print_insn = print_insn_thumb1; s.info.print_insn = print_insn_thumb1;
} else { } else {
print_insn = print_insn_arm; s.info.print_insn = print_insn_arm;
} }
if (flags & 2) { if (flags & 2) {
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
@ -247,7 +246,7 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
#endif #endif
} }
#elif defined(TARGET_SPARC) #elif defined(TARGET_SPARC)
print_insn = print_insn_sparc; s.info.print_insn = print_insn_sparc;
#ifdef TARGET_SPARC64 #ifdef TARGET_SPARC64
s.info.mach = bfd_mach_sparc_v9b; s.info.mach = bfd_mach_sparc_v9b;
#endif #endif
@ -266,49 +265,49 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
#endif #endif
} }
s.info.disassembler_options = (char *)"any"; s.info.disassembler_options = (char *)"any";
print_insn = print_insn_ppc; s.info.print_insn = print_insn_ppc;
#elif defined(TARGET_M68K) #elif defined(TARGET_M68K)
print_insn = print_insn_m68k; s.info.print_insn = print_insn_m68k;
#elif defined(TARGET_MIPS) #elif defined(TARGET_MIPS)
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
print_insn = print_insn_big_mips; s.info.print_insn = print_insn_big_mips;
#else #else
print_insn = print_insn_little_mips; s.info.print_insn = print_insn_little_mips;
#endif #endif
#elif defined(TARGET_SH4) #elif defined(TARGET_SH4)
s.info.mach = bfd_mach_sh4; s.info.mach = bfd_mach_sh4;
print_insn = print_insn_sh; s.info.print_insn = print_insn_sh;
#elif defined(TARGET_ALPHA) #elif defined(TARGET_ALPHA)
s.info.mach = bfd_mach_alpha_ev6; s.info.mach = bfd_mach_alpha_ev6;
print_insn = print_insn_alpha; s.info.print_insn = print_insn_alpha;
#elif defined(TARGET_CRIS) #elif defined(TARGET_CRIS)
if (flags != 32) { if (flags != 32) {
s.info.mach = bfd_mach_cris_v0_v10; s.info.mach = bfd_mach_cris_v0_v10;
print_insn = print_insn_crisv10; s.info.print_insn = print_insn_crisv10;
} else { } else {
s.info.mach = bfd_mach_cris_v32; s.info.mach = bfd_mach_cris_v32;
print_insn = print_insn_crisv32; s.info.print_insn = print_insn_crisv32;
} }
#elif defined(TARGET_S390X) #elif defined(TARGET_S390X)
s.info.mach = bfd_mach_s390_64; s.info.mach = bfd_mach_s390_64;
print_insn = print_insn_s390; s.info.print_insn = print_insn_s390;
#elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MICROBLAZE)
s.info.mach = bfd_arch_microblaze; s.info.mach = bfd_arch_microblaze;
print_insn = print_insn_microblaze; s.info.print_insn = print_insn_microblaze;
#elif defined(TARGET_MOXIE) #elif defined(TARGET_MOXIE)
s.info.mach = bfd_arch_moxie; s.info.mach = bfd_arch_moxie;
print_insn = print_insn_moxie; s.info.print_insn = print_insn_moxie;
#elif defined(TARGET_LM32) #elif defined(TARGET_LM32)
s.info.mach = bfd_mach_lm32; s.info.mach = bfd_mach_lm32;
print_insn = print_insn_lm32; s.info.print_insn = print_insn_lm32;
#endif #endif
if (print_insn == NULL) { if (s.info.print_insn == NULL) {
print_insn = print_insn_od_target; s.info.print_insn = print_insn_od_target;
} }
for (pc = code; size > 0; pc += count, size -= count) { for (pc = code; size > 0; pc += count, size -= count) {
fprintf(out, "0x" TARGET_FMT_lx ": ", pc); fprintf(out, "0x" TARGET_FMT_lx ": ", pc);
count = print_insn(pc, &s.info); count = s.info.print_insn(pc, &s.info);
#if 0 #if 0
{ {
int i; int i;
@ -452,7 +451,6 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
{ {
int count, i; int count, i;
CPUDebug s; CPUDebug s;
int (*print_insn)(bfd_vma pc, disassemble_info *info);
INIT_DISASSEMBLE_INFO(s.info, (FILE *)mon, monitor_fprintf); INIT_DISASSEMBLE_INFO(s.info, (FILE *)mon, monitor_fprintf);
@ -476,13 +474,13 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
} else { } else {
s.info.mach = bfd_mach_i386_i386; s.info.mach = bfd_mach_i386_i386;
} }
print_insn = print_insn_i386; s.info.print_insn = print_insn_i386;
#elif defined(TARGET_ARM) #elif defined(TARGET_ARM)
print_insn = print_insn_arm; s.info.print_insn = print_insn_arm;
#elif defined(TARGET_ALPHA) #elif defined(TARGET_ALPHA)
print_insn = print_insn_alpha; s.info.print_insn = print_insn_alpha;
#elif defined(TARGET_SPARC) #elif defined(TARGET_SPARC)
print_insn = print_insn_sparc; s.info.print_insn = print_insn_sparc;
#ifdef TARGET_SPARC64 #ifdef TARGET_SPARC64
s.info.mach = bfd_mach_sparc_v9b; s.info.mach = bfd_mach_sparc_v9b;
#endif #endif
@ -500,27 +498,27 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
if ((flags >> 16) & 1) { if ((flags >> 16) & 1) {
s.info.endian = BFD_ENDIAN_LITTLE; s.info.endian = BFD_ENDIAN_LITTLE;
} }
print_insn = print_insn_ppc; s.info.print_insn = print_insn_ppc;
#elif defined(TARGET_M68K) #elif defined(TARGET_M68K)
print_insn = print_insn_m68k; s.info.print_insn = print_insn_m68k;
#elif defined(TARGET_MIPS) #elif defined(TARGET_MIPS)
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
print_insn = print_insn_big_mips; s.info.print_insn = print_insn_big_mips;
#else #else
print_insn = print_insn_little_mips; s.info.print_insn = print_insn_little_mips;
#endif #endif
#elif defined(TARGET_SH4) #elif defined(TARGET_SH4)
s.info.mach = bfd_mach_sh4; s.info.mach = bfd_mach_sh4;
print_insn = print_insn_sh; s.info.print_insn = print_insn_sh;
#elif defined(TARGET_S390X) #elif defined(TARGET_S390X)
s.info.mach = bfd_mach_s390_64; s.info.mach = bfd_mach_s390_64;
print_insn = print_insn_s390; s.info.print_insn = print_insn_s390;
#elif defined(TARGET_MOXIE) #elif defined(TARGET_MOXIE)
s.info.mach = bfd_arch_moxie; s.info.mach = bfd_arch_moxie;
print_insn = print_insn_moxie; s.info.print_insn = print_insn_moxie;
#elif defined(TARGET_LM32) #elif defined(TARGET_LM32)
s.info.mach = bfd_mach_lm32; s.info.mach = bfd_mach_lm32;
print_insn = print_insn_lm32; s.info.print_insn = print_insn_lm32;
#else #else
monitor_printf(mon, "0x" TARGET_FMT_lx monitor_printf(mon, "0x" TARGET_FMT_lx
": Asm output not supported on this arch\n", pc); ": Asm output not supported on this arch\n", pc);
@ -529,7 +527,7 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
for(i = 0; i < nb_insn; i++) { for(i = 0; i < nb_insn; i++) {
monitor_printf(mon, "0x" TARGET_FMT_lx ": ", pc); monitor_printf(mon, "0x" TARGET_FMT_lx ": ", pc);
count = print_insn(pc, &s.info); count = s.info.print_insn(pc, &s.info);
monitor_printf(mon, "\n"); monitor_printf(mon, "\n");
if (count < 0) if (count < 0)
break; break;

View File

@ -313,6 +313,11 @@ typedef struct disassemble_info {
void (*print_address_func) void (*print_address_func)
(bfd_vma addr, struct disassemble_info *info); (bfd_vma addr, struct disassemble_info *info);
/* Function called to print an instruction. The function is architecture
* specific.
*/
int (*print_insn)(bfd_vma addr, struct disassemble_info *info);
/* Function called to determine if there is a symbol at the given ADDR. /* Function called to determine if there is a symbol at the given ADDR.
If there is, the function returns 1, otherwise it returns 0. If there is, the function returns 1, otherwise it returns 0.
This is used by ports which support an overlay manager where This is used by ports which support an overlay manager where
@ -463,6 +468,7 @@ int generic_symbol_at_address(bfd_vma, struct disassemble_info *);
(INFO).read_memory_func = buffer_read_memory, \ (INFO).read_memory_func = buffer_read_memory, \
(INFO).memory_error_func = perror_memory, \ (INFO).memory_error_func = perror_memory, \
(INFO).print_address_func = generic_print_address, \ (INFO).print_address_func = generic_print_address, \
(INFO).print_insn = NULL, \
(INFO).symbol_at_address_func = generic_symbol_at_address, \ (INFO).symbol_at_address_func = generic_symbol_at_address, \
(INFO).flags = 0, \ (INFO).flags = 0, \
(INFO).bytes_per_line = 0, \ (INFO).bytes_per_line = 0, \