-
-
Save pgoodman/251ed56fc0786b1eb870 to your computer and use it in GitHub Desktop.
GDB commands for printing Granary's internal `arch::Instruction` structures as x86-like instructions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# print-xed-reg | |
# | |
# Prints out a XED register, given the value of the register in `$arg0`. | |
define print-xed-reg | |
set $__r = (xed_reg_enum_t) $arg0 | |
python None ; \ | |
m = gdb.execute("p $__r", from_tty=True, to_string=True) ; \ | |
m = re.sub(r"^\$.*= XED_REG_", "", m) ; \ | |
gdb.write(m.strip("\n")) ; | |
end | |
# print-xed-iform | |
# | |
# Prints out an instruction's IFORM, where `$arg0` is interpreted as a | |
# `xed_iform_enum_t`. | |
define print-xed-iform | |
set $__iform = (xed_iform_enum_t) $arg0 | |
python None ; \ | |
m = gdb.execute("p $__iform", from_tty=True, to_string=True) ; \ | |
m = re.sub(r"^\$.*= XED_IFORM_", "", m) ; \ | |
gdb.write(m.strip("\n")) ; | |
end | |
# print-virt-reg | |
# | |
# Interprets `$arg0` as a `VirtualRegister` and prints it. | |
define print-virt-reg | |
set language c++ | |
set $__vr = (granary::VirtualRegister) $arg0 | |
if VR_KIND_ARCH_FIXED == $__vr.kind | |
print-xed-reg $__vr.reg_num | |
end | |
if VR_KIND_ARCH_GPR == $__vr.kind | |
set $__r = $__vr.reg_num + XED_REG_RAX | |
if XED_REG_RSP <= $__r | |
set $__r = $__r + 1 | |
end | |
if 0x3 == $__vr.byte_mask | |
set $__r = $__r - (XED_REG_RAX - XED_REG_AX) | |
end | |
if 0xF == $__vr.byte_mask | |
set $__r = $__r - (XED_REG_RAX - XED_REG_EAX) | |
end | |
if 0x1 == $__vr.byte_mask | |
set $__r = $__r + (XED_REG_AL - XED_REG_RAX) | |
end | |
if 0x2 == $__vr.byte_mask | |
set $__r = $__r + (XED_REG_AH - XED_REG_RAX) | |
end | |
print-xed-reg $__r | |
end | |
if VR_KIND_VIRTUAL_GPR == $__vr.kind || VR_KIND_VIRTUAL_STACK == $__vr.kind | |
printf "%%%u", $__vr.reg_num | |
end | |
if VR_KIND_VIRTUAL_SLOT == $__vr.kind | |
printf "SLOT:%u", $__vr.reg_num | |
end | |
end | |
# print-arch-operand | |
# | |
# Prints the `arch::Operand` structure pointed to by `$arg0`. | |
define print-arch-operand | |
set language c++ | |
set $__o = (granary::arch::Operand *) $arg0 | |
if XED_ENCODER_OPERAND_TYPE_BRDISP == $__o->type | |
printf "0x%lx", $__o->addr.as_uint | |
end | |
# Memory operand | |
if XED_ENCODER_OPERAND_TYPE_MEM == $__o->type | |
printf "[" | |
# Segment displacement. Usually `XED_REG_DS`. | |
if XED_REG_INVALID != $__o->segment && XED_REG_DS != $__o->segment | |
print-xed-reg $__o->segment | |
printf ":" | |
end | |
# Compound base + index * scale + displacement memory operand. | |
if $__o->is_compound | |
set $__pplus = 0 | |
if XED_REG_INVALID != $__o->mem.reg_base | |
print-xed-reg $__o->mem.reg_base | |
set $__pplus = 1 | |
end | |
if XED_REG_INVALID != $__o->mem.reg_index | |
if $__pplus | |
printf " + " | |
end | |
print-xed-reg $__o->mem.reg_index | |
printf " * %u", $__o->mem.scale | |
set $__pplus = 1 | |
end | |
if 0 != $__o->mem.disp | |
if $__pplus | |
printf " + " | |
end | |
printf "%d", $__o->mem.disp | |
end | |
# Dereference of a register memory operand | |
else | |
print-virt-reg $__o->reg | |
end | |
printf "]" | |
end | |
# Print out a virtual register. | |
if XED_ENCODER_OPERAND_TYPE_REG == $__o->type || \ | |
XED_ENCODER_OPERAND_TYPE_SEG0 == $__o->type || \ | |
XED_ENCODER_OPERAND_TYPE_SEG1 == $__o->type | |
print-virt-reg $__o->reg | |
end | |
# Print out an immediate operand | |
if XED_ENCODER_OPERAND_TYPE_IMM0 == $__o->type || \ | |
XED_ENCODER_OPERAND_TYPE_IMM1 == $__o->type || \ | |
XED_ENCODER_OPERAND_TYPE_SIMM0 == $__o->type | |
if 0 > $__o->imm.as_int | |
printf "-0x%lx", -$__o->imm.as_int | |
else | |
printf "0x%lx", $__o->imm.as_int | |
end | |
end | |
# Print out some kind of pointer. | |
if XED_ENCODER_OPERAND_TYPE_PTR == $__o->type | |
printf "[" | |
if XED_REG_INVALID != $__o->segment && XED_REG_DS != $__o->segment | |
print-xed-reg $__o->segment | |
printf ":" | |
end | |
if $__o->is_annot_encoded_pc | |
printf "return address" | |
else | |
if 0 > $__o->addr.as_int | |
printf "-0x%lx", -$__o->addr.as_int | |
else | |
printf "0x%lx", $__o->addr.as_int | |
end | |
end | |
printf "]" | |
end | |
end | |
# print-arch-instr-inline | |
# | |
# Interprets `$arg0` as being a pointer to an `arch::Instruction` structure, and | |
# prints the structure. | |
# | |
# Note: This function does not print a trialing new line character. | |
define print-arch-instr-inline | |
set language c++ | |
set $__in = (granary::arch::Instruction *) $arg0 | |
print-xed-iform $__in->iform | |
printf " " | |
set $__op_num = 0 | |
while $__op_num < $__in->num_explicit_ops | |
if 0 < $__op_num | |
printf ", " | |
end | |
print-arch-operand &($__in->ops[$__op_num]) | |
set $__op_num = $__op_num + 1 | |
end | |
end | |
# print-arch-instr | |
# | |
# Interprets `$arg0` as being a pointer to an `arch::Instruction` structure, and | |
# prints the structure. | |
define print-arch-instr | |
print-arch-instr-inline $arg0 | |
printf "\n" | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(gdb) print-arch-instr &($12->instruction) | |
MOV_MEMv_GPRv [SLOT:0], R15 | |
(gdb) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment