NAME=agfj resolv reloc symbols
FILE=bins/elf/ls
CMDS=<<EOF
aa 2> /dev/null
aac 2> /dev/null
sf loc.0000f190
agfj~reloc.free
EOF
EXPECT=<<EOF
[{"name":"loc.0000f190","offset":61840,"ninstr":7,"nargs":0,"nlocals":0,"size":23,"stack":8,"type":"loc","blocks":[{"offset":61840,"size":23,"ops":[{"offset":61840,"esil":"rbx,8,rsp,-,=[8],8,rsp,-=","refptr":false,"fcn_addr":61840,"fcn_last":61862,"size":1,"opcode":"push rbx","disasm":"push rbx","bytes":"53","family":"cpu","type":"rpush","reloc":false,"type_num":268435468,"type2_num":0,"flags":["loc.0000f190"],"xrefs":[{"addr":53124,"type":"DATA"},{"addr":54437,"type":"CODE"}]},{"offset":61841,"esil":"rdi,rbx,=","refptr":false,"fcn_addr":61840,"fcn_last":61860,"size":3,"opcode":"mov rbx, rdi","disasm":"mov rbx, rdi","bytes":"4889fb","family":"cpu","type":"mov","reloc":false,"type_num":9,"type2_num":0},{"offset":61844,"esil":"rdi,[8],rdi,=","refptr":true,"fcn_addr":61840,"fcn_last":61860,"size":3,"opcode":"mov rdi, qword [rdi]","disasm":"mov rdi, qword [rdi]","bytes":"488b3f","family":"cpu","type":"mov","reloc":false,"type_num":9,"type2_num":0},{"offset":61847,"ptr":138400,"esil":"0x12b03,rip,+,[8],rip,8,rsp,-=,rsp,=[8],rip,=","refptr":true,"fcn_addr":61840,"fcn_last":61857,"size":6,"opcode":"call qword [rip + 0x12b03]","disasm":"call qword [reloc.free]","bytes":"ff15032b0100","family":"cpu","type":"ircall","reloc":false,"type_num":402653188,"type2_num":0,"refs":[{"addr":138400,"type":"CALL"}]},{"offset":61853,"esil":"rbx,rdi,=","refptr":false,"fcn_addr":61840,"fcn_last":61860,"size":3,"opcode":"mov rdi, rbx","disasm":"mov rdi, rbx","bytes":"4889df","family":"cpu","type":"mov","reloc":false,"type_num":9,"type2_num":0},{"offset":61856,"esil":"rsp,[8],rbx,=,8,rsp,+=","refptr":false,"fcn_addr":61840,"fcn_last":61862,"size":1,"opcode":"pop rbx","disasm":"pop rbx","bytes":"5b","family":"cpu","type":"pop","reloc":false,"type_num":14,"type2_num":0},{"offset":61857,"ptr":138400,"esil":"0x12af9,rip,+,[8],rip,=","refptr":true,"fcn_addr":61840,"fcn_last":61857,"size":6,"opcode":"jmp qword [rip + 0x12af9]","disasm":"jmp qword [reloc.free]","bytes":"ff25f92a0100","family":"cpu","type":"irjmp","reloc":false,"type_num":402653186,"type2_num":0,"refs":[{"addr":138400,"type":"DATA"}]}]}]}]
EOF
RUN

NAME=agfJ
FILE=-
CMDS=<<EOF
e asm.arch=x86
e asm.bits=64
s 0x42
wx 00004883f80074060000000000000000c3
af
agfJ
EOF
EXPECT=<<EOF
[{"name":"fcn.00000042","offset":66,"ninstr":8,"nargs":0,"nlocals":0,"size":17,"stack":0,"type":"fcn","blocks":[{"offset":66,"size":8,"jump":80,"fail":74,"ops":[{"offset":66,"text":"17: fcn.00000042 ();"},{"offset":66,"text":"     0000           add byte [rax], al"},{"offset":68,"text":"     4883f800       cmp rax, 0"},{"offset":72,"arrow":80,"text":"     7406           je 0x50"}]},{"offset":74,"size":6,"jump":80,"ops":[{"offset":74,"text":"     0000           add byte [rax], al"},{"offset":76,"text":"     0000           add byte [rax], al"},{"offset":78,"text":"     0000           add byte [rax], al"}]},{"offset":80,"size":3,"ops":[{"offset":80,"text":"     0000           add byte [rax], al"},{"offset":82,"text":"     c3             ret"}]}]}]
EOF
RUN

NAME=agfdm correct jump tables
FILE=-
CMDS=<<EOF
e asm.arch=x86
e asm.bits=64
s 0x100
wx 42000000000000004e000000000000005a00000000000000660000000000000072000000000000007e00000000000000
s 0x10
wx 554889e5897dfcc745f8000000008b45fc89c14889ca4883ea0548894df00f8756000000488b45f0488b0cc500010000ffe1c745f800000000e943000000c745f801000000e937000000c745f802000000e92b000000c745f803000000e91f000000c745f804000000e913000000c745f805000000e907000000c745f8ffffffff8b45f85dc3
af
agfdm
EOF
EXPECT=<<EOF
digraph code {
	graph [bgcolor=azure fontsize=8 fontname="Courier" splines="ortho"];
	node [fillcolor=gray style=filled shape=box];
	edge [arrowhead="normal"];
        "0x00000010" -> "0x0000008a" [color="#13a10e"];
        "0x00000010" -> "0x00000034" [color="#c50f1f"];
        "0x0000008a" -> "0x00000091" [color="#3a96dd"];
        "0x00000034" -> "0x00000042" [color="#3a96dd"];
        "0x00000034" -> "0x0000004e" [color="#3a96dd"];
        "0x00000034" -> "0x0000005a" [color="#3a96dd"];
        "0x00000034" -> "0x00000066" [color="#3a96dd"];
        "0x00000034" -> "0x00000072" [color="#3a96dd"];
        "0x00000034" -> "0x0000007e" [color="#3a96dd"];
        "0x00000042" -> "0x00000091" [color="#3a96dd"];
        "0x0000004e" -> "0x00000091" [color="#3a96dd"];
        "0x0000005a" -> "0x00000091" [color="#3a96dd"];
        "0x00000066" -> "0x00000091" [color="#3a96dd"];
        "0x00000072" -> "0x00000091" [color="#3a96dd"];
        "0x0000007e" -> "0x00000091" [color="#3a96dd"];
}
EOF
RUN

NAME=agfm basic mermaid output
FILE=bins/elf/ls
CMDS=<<EOF
s sym._obstack_newchunk
af
agfm
EOF
EXPECT=<<EOF
stateDiagram-v2
  state "[0x15cc0] sym._obstack_newchunk" as _0x15cc0
  state "[0x15d06]" as _0x15d06
  state "[0x15d12]" as _0x15d12
  state "[0x15d29]" as _0x15d29
  state "[0x15d67]" as _0x15d67
  state "[0x15d7e]" as _0x15d7e
  state "[0x15da0]" as _0x15da0
  state "[0x15db5]" as _0x15db5
  state "[0x15dc9]" as _0x15dc9
  state "[0x15dd0]" as _0x15dd0
  state "[0x15dd5]" as _0x15dd5
  state "[0x15dda]" as _0x15dda
  state "[0x15de3]" as _0x15de3
  state "[0x15df0]" as _0x15df0
  state "[0x15df6]" as _0x15df6
  _0x15cc0 --> _0x15db5: true
  _0x15cc0 --> _0x15d06: false
  _0x15d06 --> _0x15db5: true
  _0x15d06 --> _0x15d12: false
  _0x15d12 --> _0x15db5: true
  _0x15d12 --> _0x15d29: false
  _0x15d29 --> _0x15d7e: true
  _0x15d29 --> _0x15d67: false
  _0x15d67 --> _0x15da0: true
  _0x15d67 --> _0x15d7e: false
  _0x15da0 --> _0x15d7e
  _0x15db5 --> _0x15df6: true
  _0x15db5 --> _0x15dc9: false
  _0x15dc9 --> _0x15dd0
  _0x15dd0 --> _0x15dda: true
  _0x15dd0 --> _0x15dd5: false
  _0x15dd5 --> _0x15df0: true
  _0x15dd5 --> _0x15dda: false
  _0x15dda --> _0x15dd0: true
  _0x15dda --> _0x15de3: false
EOF
RUN

NAME=agfma basic mermaid output
FILE=bins/elf/ls
CMDS=<<EOF
s sym._obstack_newchunk
af
agfma
EOF
EXPECT=<<EOF
stateDiagram-v2
  state "[0x15cc0] sym._obstack_newchunk\npush r14\nxor eax, eax\npush r13\npush r12\npush rbp\npush rbx\nmov r13, qword ptr [rdi + 0x18]\nsub r13, qword ptr [rdi + 0x10]\nmov rbp, qword ptr [rdi + 8]\nadd rsi, r13\nmov rdx, r13\nsetb al\nadd rsi, qword ptr [rdi + 0x30]\nsetb cl\nshr rdx, 3\ncmp qword ptr [rdi], rsi\nlea rbx, [rsi + rdx + 0x64]\ncmovae rsi, qword ptr [rdi]\ncmp rsi, rbx\ncmovae rbx, rsi\ntest rax, rax\njne 0x15db5\n" as _0x15cc0
  state "[0x15d06]\nmovzx ecx, cl\ntest rcx, rcx\njne 0x15db5\n" as _0x15d06
  state "[0x15d12]\nmov rsi, rbx\nmov r12, rdi\ncall 0x15bb0\nmov r14, rax\ntest rax, rax\nje 0x15db5\n" as _0x15d12
  state "[0x15d29]\nlea rsi, [rax + rbx]\nmov qword ptr [r12 + 8], rax\nmov rdx, r13\nmov qword ptr [rax + 8], rbp\nmov qword ptr [r12 + 0x20], rsi\nmov qword ptr [rax], rsi\nmov rax, qword ptr [r12 + 0x30]\nmov rsi, qword ptr [r12 + 0x10]\nlea rbx, [r14 + rax + 0x10]\nnot rax\nand rbx, rax\nmov rdi, rbx\ncall qword ptr [rip + 0xc119]\ntest byte ptr [r12 + 0x50], 2\njne 0x15d7e\n" as _0x15d29
  state "[0x15d67]\nmov rax, qword ptr [r12 + 0x30]\nlea rdx, [rbp + rax + 0x10]\nnot rax\nand rax, rdx\ncmp qword ptr [r12 + 0x10], rax\nje 0x15da0\n" as _0x15d67
  state "[0x15d7e]\nadd r13, rbx\nmov qword ptr [r12 + 0x10], rbx\nmov qword ptr [r12 + 0x18], r13\nand byte ptr [r12 + 0x50], 0xfd\npop rbx\npop rbp\npop r12\npop r13\npop r14\nret\n" as _0x15d7e
  state "[0x15da0]\nmov rax, qword ptr [rbp + 8]\nmov rsi, rbp\nmov rdi, r12\nmov qword ptr [r14 + 8], rax\ncall 0x15bd0\njmp 0x15d7e\n" as _0x15da0
  state "[0x15db5]\ncall qword ptr [rip + 0xc4a5]\nnop dword ptr [rax + rax]\nmov rax, qword ptr [rdi + 8]\ntest rax, rax\nje 0x15df6\n" as _0x15db5
  state "[0x15dc9]\nnop dword ptr [rax]\n" as _0x15dc9
  state "[0x15dd0]\ncmp rsi, rax\njbe 0x15dda\n" as _0x15dd0
  state "[0x15dd5]\ncmp qword ptr [rax], rsi\njae 0x15df0\n" as _0x15dd5
  state "[0x15dda]\nmov rax, qword ptr [rax + 8]\ntest rax, rax\njne 0x15dd0\n" as _0x15dda
  state "[0x15de3]\nxor eax, eax\nret\n" as _0x15de3
  state "[0x15df0]\nmov eax, 1\nret\n" as _0x15df0
  state "[0x15df6]\nret\n" as _0x15df6
  _0x15cc0 --> _0x15db5: true
  _0x15cc0 --> _0x15d06: false
  _0x15d06 --> _0x15db5: true
  _0x15d06 --> _0x15d12: false
  _0x15d12 --> _0x15db5: true
  _0x15d12 --> _0x15d29: false
  _0x15d29 --> _0x15d7e: true
  _0x15d29 --> _0x15d67: false
  _0x15d67 --> _0x15da0: true
  _0x15d67 --> _0x15d7e: false
  _0x15da0 --> _0x15d7e
  _0x15db5 --> _0x15df6: true
  _0x15db5 --> _0x15dc9: false
  _0x15dc9 --> _0x15dd0
  _0x15dd0 --> _0x15dda: true
  _0x15dd0 --> _0x15dd5: false
  _0x15dd5 --> _0x15df0: true
  _0x15dd5 --> _0x15dda: false
  _0x15dda --> _0x15dd0: true
  _0x15dda --> _0x15de3: false
EOF
RUN

NAME=agfm on jump table
CMDS=<<EOF
e asm.arch=x86
e asm.bits=64
s 0x100
wx 42000000000000004e000000000000005a00000000000000660000000000000072000000000000007e00000000000000
s 0x10
wx 554889e5897dfcc745f8000000008b45fc89c14889ca4883ea0548894df00f8756000000488b45f0488b0cc500010000ffe1c745f800000000e943000000c745f801000000e937000000c745f802000000e92b000000c745f803000000e91f000000c745f804000000e913000000c745f805000000e907000000c745f8ffffffff8b45f85dc3
af
agfm
EOF
EXPECT=<<EOF
stateDiagram-v2
  state "[0x10] fcn.00000010" as _0x10
  state "[0x34]" as _0x34
  state "[0x42]" as _0x42
  state "[0x4e]" as _0x4e
  state "[0x5a]" as _0x5a
  state "[0x66]" as _0x66
  state "[0x72]" as _0x72
  state "[0x7e]" as _0x7e
  state "[0x8a]" as _0x8a
  state "[0x91]" as _0x91
  _0x10 --> _0x8a: true
  _0x10 --> _0x34: false
  _0x34 --> _0x42: Case 0
  _0x34 --> _0x4e: Case 1
  _0x34 --> _0x5a: Case 2
  _0x34 --> _0x66: Case 3
  _0x34 --> _0x72: Case 4
  _0x34 --> _0x7e: Case 5
  _0x42 --> _0x91
  _0x4e --> _0x91
  _0x5a --> _0x91
  _0x66 --> _0x91
  _0x72 --> _0x91
  _0x7e --> _0x91
  _0x8a --> _0x91
EOF
RUN
