You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
2.8 KiB
61 lines
2.8 KiB
4 months ago
|
Extending the disassembler
|
||
|
==========================
|
||
|
|
||
|
The output of the disassembler can be extended and customized. This may be
|
||
|
useful for example to add comments and annotations to the disassembly, print
|
||
|
aliases for register names, or add an offset to disassembled addresses.
|
||
|
|
||
|
The general procedure to achieve this is to create a sub-class of
|
||
|
`Disassembler` and override the appropriate virtual functions.
|
||
|
|
||
|
The `Disassembler` class provides virtual methods that implement how specific
|
||
|
disassembly elements are printed. See
|
||
|
[src/aarch64/disasm-aarch64.h](/src/aarch64/disasm-aarch64.h) for details.
|
||
|
These include functions like:
|
||
|
|
||
|
virtual void AppendRegisterNameToOutput(const Instruction* instr,
|
||
|
const CPURegister& reg);
|
||
|
virtual void AppendPCRelativeOffsetToOutput(const Instruction* instr,
|
||
|
int64_t offset);
|
||
|
virtual void AppendCodeRelativeAddressToOutput(const Instruction* instr,
|
||
|
const void* addr);
|
||
|
virtual void AppendCodeRelativeCodeAddressToOutput(const Instruction* instr,
|
||
|
const void* addr);
|
||
|
|
||
|
They can be overridden for example to use different register names and annotate
|
||
|
code addresses.
|
||
|
|
||
|
More complex modifications can be performed by overriding the visitor functions
|
||
|
of the disassembler. The VIXL `Decoder` uses a visitor pattern implementation,
|
||
|
so the `Disassembler` (as a sub-class of `DecoderVisitor`) must provide a
|
||
|
visitor function for each sub-type of instructions. The complete list of
|
||
|
visitors is defined by the macro `VISITOR_LIST` in
|
||
|
[src/aarch64/decoder-aarch64.h](/src/aarch64/decoder-aarch64.h).
|
||
|
|
||
|
The [/examples/custom-disassembler.h](/examples/custom-disassembler.h) and
|
||
|
[/examples/custom-disassembler.cc](/examples/custom-disassembler.cc) example
|
||
|
files show how the methods can be overridden to use different register names,
|
||
|
map code addresses, annotate code addresses, and add comments:
|
||
|
|
||
|
VIXL disasm 0x7fff04cb05e0: add x10, x16, x17
|
||
|
custom disasm -0x8: add x10, ip0, ip1 // add/sub to x10
|
||
|
|
||
|
VIXL disasm 0x7fff04cb05e4: cbz x10, #+0x28 (addr 0x7fff04cb060c)
|
||
|
custom disasm -0x4: cbz x10, #+0x28 (addr 0x24 ; label: somewhere)
|
||
|
|
||
|
VIXL disasm 0x7fff04cb05e8: add x11, x16, x17
|
||
|
custom disasm 0x0: add x11, ip0, ip1
|
||
|
|
||
|
VIXL disasm 0x7fff04cb05ec: add w5, w6, w30
|
||
|
custom disasm 0x4: add w5, w6, w30
|
||
|
|
||
|
VIXL disasm 0x7fff04cb05f0: tbz w10, #2, #-0x10 (addr 0x7fff04cb05e0)
|
||
|
custom disasm 0x8: tbz w10, #2, #-0x10 (addr -0x8)
|
||
|
|
||
|
|
||
|
One can refer to the implementation of visitor functions for the `Disassembler`
|
||
|
(in [src/aarch64/disasm-aarch64.cc](/src/aarch64/disasm-aarch64.cc)) or even
|
||
|
for the `Simulator`
|
||
|
(in [src/aarch64/simulator-aarch64.cc](/src/aarch64/simulator-aarch64.cc))
|
||
|
to see how to extract information from instructions.
|