Skip to content

Instantly share code, notes, and snippets.

@pgoodman
Created August 14, 2014 18:02
Show Gist options
  • Save pgoodman/251ed56fc0786b1eb870 to your computer and use it in GitHub Desktop.
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.
# 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
(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