Skip to content

Commit

Permalink
disas: Fix printing of addresses in disassembly
Browse files Browse the repository at this point in the history
In our disassembly code, the bfd_vma type is always 64 bits,
even if the target's virtual address width is only 32 bits. This
means that when we print out addresses we need to truncate them
to 32 bits, to avoid odd output which has incorrectly sign-extended
a value to 64 bits, for instance this ARM example:
    0x80479a60:  e59f4088     ldr  r4, [pc, qemu#136]  ; 0xffffffff80479a4f

(It would also be possible to truncate before passing the address
to info->print_address_func(), but truncating in the final print
function is the same approach that binutils takes to this problem.)

Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Andreas Färber <[email protected]>
Signed-off-by: Blue Swirl <[email protected]>
  • Loading branch information
pm215 authored and blueswirl committed Jul 14, 2012
1 parent fabaaf1 commit 636bd28
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions disas.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ generic_print_address (bfd_vma addr, struct disassemble_info *info)
(*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
}

/* Print address in hex, truncated to the width of a target virtual address. */
static void
generic_print_target_address(bfd_vma addr, struct disassemble_info *info)
{
uint64_t mask = ~0ULL >> (64 - TARGET_VIRT_ADDR_SPACE_BITS);
generic_print_address(addr & mask, info);
}

/* Print address in hex, truncated to the width of a host virtual address. */
static void
generic_print_host_address(bfd_vma addr, struct disassemble_info *info)
{
uint64_t mask = ~0ULL >> (64 - (sizeof(void *) * 8));
generic_print_address(addr & mask, info);
}

/* Just return the given address. */

int
Expand Down Expand Up @@ -154,6 +170,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
disasm_info.read_memory_func = target_read_memory;
disasm_info.buffer_vma = code;
disasm_info.buffer_length = size;
disasm_info.print_address_func = generic_print_target_address;

#ifdef TARGET_WORDS_BIGENDIAN
disasm_info.endian = BFD_ENDIAN_BIG;
Expand Down Expand Up @@ -274,6 +291,7 @@ void disas(FILE *out, void *code, unsigned long size)
int (*print_insn)(bfd_vma pc, disassemble_info *info);

INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
disasm_info.print_address_func = generic_print_host_address;

disasm_info.buffer = code;
disasm_info.buffer_vma = (uintptr_t)code;
Expand Down Expand Up @@ -386,6 +404,7 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
monitor_disas_env = env;
monitor_disas_is_physical = is_physical;
disasm_info.read_memory_func = monitor_read_memory;
disasm_info.print_address_func = generic_print_target_address;

disasm_info.buffer_vma = pc;

Expand Down

0 comments on commit 636bd28

Please sign in to comment.