NAME=fe
FILE==
CMDS=<<EOF
f foo @ 123
fe foo;%% echo hello
fe bar;%% echo world
EOF
EXPECT=<<EOF
hello
EOF
RUN

NAME=fs-fd-flags-visibility
FILE==
CMDS=<<EOF
fs jeje
f hidden
fs jojo
f visible
fd
fl
EOF
EXPECT=<<EOF
visible
0x00000000 1 visible
EOF
RUN

NAME=f command with space
FILE==
CMDS=<<EOF
f foobar @ 0x1000
fl
EOF
EXPECT=<<EOF
0x00001000 1 foobar
EOF
RUN

NAME=no flags
FILE==
CMDS=f
EXPECT=<<EOF
EOF
RUN

NAME=no flags*
FILE==
CMDS=f*
EXPECT=<<EOF
EOF
RUN

NAME=1: fs *
FILE=bins/elf/analysis/main
CMDS=<<EOF
fs *
fsl~?^*
EOF
EXPECT=<<EOF
0
EOF
RUN

NAME=2: fs *
FILE=bins/elf/analysis/main
CMDS=<<EOF
fs *
fsl~?*
EOF
EXPECT=<<EOF
9
EOF
RUN

NAME=3: fs *
FILE=malloc://1024
CMDS=<<EOF
fs-*
fs flagspace_1
f flag_in_fs1
fs flagspace_2
f flag_in_fs2
fs *
fl
EOF
EXPECT=<<EOF
0x00000000 1 flag_in_fs1
0x00000000 1 flag_in_fs2
EOF
RUN

NAME=fs test_flagspace
FILE=bins/elf/analysis/main
CMDS=<<EOF
fs test_flagspace
fsl~?test_flagspace
EOF
EXPECT=<<EOF
1
EOF
RUN

NAME=fs- test_flagspace
FILE=bins/elf/analysis/main
CMDS=<<EOF
fs test_flagspace
fs- test_flagspace
fsl~?test_flagspace
EOF
EXPECT=<<EOF
0
EOF
RUN

NAME=fs-* test_flagspace
FILE=bins/elf/analysis/main
CMDS=<<EOF
fs-*
fsl~?0
EOF
EXPECT=<<EOF
0
EOF
RUN

NAME=fsm
FILE=bins/elf/analysis/main
CMDS=<<EOF
fs-*
fs test
fsm @ str.Hello_World
fsl
EOF
EXPECT=<<EOF
    1 * test
EOF
RUN

NAME=fsr
FILE=bins/elf/analysis/main
CMDS=<<EOF
fs-*
fs test
fsr test2
fsl
EOF
EXPECT=<<EOF
    0 * test2
EOF
RUN

NAME=fr
FILE=malloc://1024
CMDS=<<EOF
f blah
fr blah bloh
fl
EOF
EXPECT=<<EOF
0x00000000 1 bloh
EOF
RUN

NAME=fm
FILE=malloc://1024
CMDS=<<EOF
f blah
fm 0x10
fl
EOF
EXPECT=<<EOF
0x00000010 1 blah
EOF
RUN

NAME=fL
FILE=malloc://1024
CMDS=<<EOF
f blah 0x0000000a
fL 0x00000003 @ blah
fL
f- blah
f test 12 @ 33
fl
fL 333 @ test
fl
EOF
EXPECT=<<EOF
0x00000003
0x00000021 12 test
0x00000021 333 test
EOF
RUN

NAME=flj
FILE=malloc://1024
CMDS=<<EOF
f blah 0x0000000a @ 0x0000000b
f bloh 0x00000003 @ 0x00000002
flj
EOF
EXPECT=<<EOF
[{"name":"bloh","realname":"bloh","size":3,"offset":2},{"name":"blah","realname":"blah","size":10,"offset":11}]
EOF
RUN

NAME=flj shows demangled symbols
FILE=bins/elf/demangle-test-cpp
CMDS=<<EOF
aaa
flj~{214}
EOF
EXPECT=<<EOF
{"name":"reloc.operator_delete_void","realname":"operator delete(void*)","size":8,"offset":16432}
EOF
RUN

NAME=fd
FILE=malloc://1024
CMDS=<<EOF
f a
fd @ 0x100
EOF
EXPECT=<<EOF
a + 256
EOF
RUN

NAME=fd. with flags
FILE=malloc://1024
CMDS=<<EOF
wx 9090909090909090
f+ flag1 @ 0x5
f+ flag2 @ 0x5
f+ flag3 @ 0x5
fd. @ 0x5
EOF
EXPECT=<<EOF
flag1
flag2
flag3
EOF
RUN

NAME=fd with realname
FILE=malloc://1024
CMDS=<<EOF
f pingas @ 0x42
fN pingas "Snooping as usual I see..."
e asm.flags.real=0
fd @ 0x42
fd @ 0x1337
e asm.flags.real=1
fd @ 0x42
fd @ 0x1337
EOF
EXPECT=<<EOF
pingas
pingas + 4853
Snooping as usual I see...
Snooping as usual I see... + 4853
EOF
RUN

NAME=fC
FILE=malloc://1024
CMDS=<<EOF
f a
fC a blabla
pd 0x100~?blabla
EOF
EXPECT=<<EOF
1
EOF
RUN

NAME=fb
FILE=malloc://1024
CMDS=<<EOF
fb 0x100
f a
fl
EOF
EXPECT=<<EOF
0x00000100 1 a
EOF
RUN

NAME=fb2
FILE=malloc://1024
CMDS=<<EOF
f+ a.0
f+ a.1
f+ a.2
fb 0x100 a.*
fl
EOF
EXPECT=<<EOF
0x00000100 1 a.0
0x00000100 1 a.1
0x00000100 1 a.2
EOF
RUN

NAME=f-*
FILE=malloc://1024
CMDS=<<EOF
f a
f-*
fl
EOF
EXPECT=<<EOF
EOF
RUN

NAME=f.
FILE=bins/elf/analysis/main
CMDS=<<EOF
aaa
f. blah
f.l
s 0
echo outside
f.
EOF
EXPECT=<<EOF
0x00400410 blah   [entry0 + 0]
outside
EOF
RUN

NAME=f.lj
FILE=bins/elf/analysis/main
ARGS=-e log.level=4
CMDS=<<EOF
af
f. patata
f.lj
s 0
echo outside
f.l
echo all
f.l*j
EOF
EXPECT=<<EOF
[{"patata":4195344}]
outside
all
["entry0":{"patata":4195344}]
EOF
EXPECT_ERR=<<EOF
WARNING: Neither hash nor gnu_hash exist. Falling back to heuristics for deducing the number of dynamic symbols...
WARNING: Neither hash nor gnu_hash exist. Falling back to heuristics for deducing the number of dynamic symbols...
WARNING: Neither hash nor gnu_hash exist. Falling back to heuristics for deducing the number of dynamic symbols...
ERROR: Cannot find function at 0x0 offset
EOF
RUN

NAME=f.-
FILE=bins/elf/analysis/main
ARGS=-e log.level=4
CMDS=<<EOF
af
f. patata
f.l
f.- patata
f.l
EOF
EXPECT=<<EOF
0x00400410 patata   [entry0 + 0]
EOF
EXPECT_ERR=<<EOF
WARNING: Neither hash nor gnu_hash exist. Falling back to heuristics for deducing the number of dynamic symbols...
WARNING: Neither hash nor gnu_hash exist. Falling back to heuristics for deducing the number of dynamic symbols...
WARNING: Neither hash nor gnu_hash exist. Falling back to heuristics for deducing the number of dynamic symbols...
EOF
RUN

NAME=f. display
FILE=bins/elf/analysis/main
CMDS=<<EOF
aaa
e asm.arch=x86
e asm.bytes=true
e asm.bits=32
s entry0
e asm.offset=false
e asm.functions=false
e asm.comments=false
f-*
f. blah
pd 1
EOF
EXPECT=<<EOF
           .blah:
               31ed           xor   ebp, ebp         ; start.S:67
EOF
RUN

NAME=Set/get
FILE==
CMDS=<<EOF
f cat
f+ rimmer 12
f lister 32 @ 666
f+ kryten 32 @ 666
f+ skutter 1 @ 12
fl
EOF
EXPECT=<<EOF
0x00000000 1 cat
0x00000000 12 rimmer
0x0000000c 1 skutter
0x0000029a 32 lister
0x0000029a 32 kryten
EOF
RUN

NAME=flags (JSON)
FILE==
CMDS=<<EOF
# Add flags.
f cat
f+ rimmer 12
f lister 32 @ 666
f+ kryten 32 @ 666
f+ skutter 1 @ 12
flj
EOF
EXPECT=<<EOF
[{"name":"cat","realname":"cat","size":1,"offset":0},{"name":"rimmer","realname":"rimmer","size":12,"offset":0},{"name":"skutter","realname":"skutter","size":1,"offset":12},{"name":"lister","realname":"lister","size":32,"offset":666},{"name":"kryten","realname":"kryten","size":32,"offset":666}]
EOF
RUN

NAME=flag alias
FILE==
CMDS=<<EOF
fa foo bar+3
f bar @ 3
%v foo
EOF
EXPECT=<<EOF
0x6
EOF
RUN

NAME=flag alias infinite check
FILE==
CMDS=<<EOF
fa foo foo+3
%v foo
EOF
EXPECT=<<EOF
0x3
EOF
RUN

NAME=rename flags from bin
FILE=bins/elf/analysis/main
CMDS=<<EOF
fl~sym.__libc_csu_init
fr sym.__libc_csu_init newname
fl~sym.__libc_csu_init
fl~newname
EOF
EXPECT=<<EOF
0x00400520 137 sym.__libc_csu_init
0x00400520 137 newname
EOF
RUN

NAME=f and f+ behavior
FILE==
CMDS=<<EOF
f foo 10
f bar 20
f cow 10
f low 20
fl~?
f-*
f+ foo 10
f+ bar 20
f+ cow 10
f+ low 20
fl~?
f-*
f foo @ 10
f bar @ 20
f cow @ 10
f low @ 20
fl~?
f-*
f+ foo @ 10
f+ bar @ 20
f+ cow @ 10
f+ low @ 20
fl~?
EOF
EXPECT=<<EOF
1
4
2
4
EOF
RUN

NAME=dup flags with filter
FILE=bins/elf/ifunc_rel64
CMDS=fl~obj._IO_helper_jumps
EXPECT=<<EOF
0x0049ad40 168 obj._IO_helper_jumps
0x0049b680 168 obj._IO_helper_jumps_0x49b680
EOF
RUN

NAME=flag renaming and reusing the old name for something new
FILE=malloc://1024
CMDS=<<EOF
f blah @ 0x100
fr blah bloh
f blah @ 0x200
fl
EOF
EXPECT=<<EOF
0x00000100 1 bloh
0x00000200 1 blah
EOF
RUN

NAME=base64 armored flags
FILE=malloc://1024
CMDS=<<EOF
f direct1 1 verbatim @ 0
f direct2 1 base64:ImJhc2U2NCBhcm1vcmVkIg== @ 16
f indirect @ 32
fC indirect base64:d29ya3MgdG9v
fl*
flj
EOF
EXPECT=<<EOF
fs *
f direct1 1 0x00000000 base64:dmVyYmF0aW0=
fs *
f direct2 1 0x00000010 base64:ImJhc2U2NCBhcm1vcmVkIg==
fs *
f indirect 1 0x00000020 base64:d29ya3MgdG9v
[{"name":"direct1","realname":"direct1","size":1,"offset":0,"comment":"verbatim"},{"name":"direct2","realname":"direct2","size":1,"offset":16,"comment":"\"base64 armored\""},{"name":"indirect","realname":"indirect","size":1,"offset":32,"comment":"works too"}]
EOF
RUN

NAME=f base64:NotB64=100
FILE=malloc://1024
CMDS=<<EOF
f base64:NotB64 @ 100
fl
EOF
EXPECT=<<EOF
0x00000064 1 base64:NotB64
EOF
RUN

NAME=ft
FILE=bins/elf/analysis/main
CMDS=<<EOF
ftl
ftlj
ftll
ft bla "foo goo moo"
f+ foo
s main
f+ goo
ftl~bla
ftll
ftn bla
EOF
EXPECT=<<EOF
fs
env
string
threads
network
dylib
alloc
time
process
stdout
["fs":[],"env":[],"string":[],"threads":[],"network":[],"dylib":[],"alloc":[],"time":[],"process":[],"stdout":[]]
fs:
env:
string:
threads:
network:
dylib:
alloc:
time:
process:
stdout:
bla
fs:
dylib:
process:
stdout:
network:
alloc:
env:
string:
time:
bla:
0x00400410  foo
0x00400506  goo
threads:
0x00400410  foo
0x00400506  goo
EOF
RUN

NAME=fz
FILE==
CMDS=<<EOF
fzl
fzlj
fz bla
fzl
fzlj
fz.
sd +5
fz.
fz- bla
fzl
fz bla
fz-*
fzl
EOF
EXPECT=<<EOF

0x080  0x00000000  bla
[{"name":"bla","from":0,"to":0}]
bla ~
bla ~
EOF
RUN

NAME=flag list at
FILE==
CMDS=<<EOF
f blah 0x0000000a @ 0x0000000b
f bloh 0x00000003 @ 0x00000002
fl. @ 0x0000000b
fl.j @ 0x0000000b
fl.t @ 0x0000000b
fl.q @ 0x0000000b
fl. @ 0x00000002
fl.j @ 0x00000002
fl.t @ 0x00000002
fl.q @ 0x00000002
EOF
EXPECT=<<EOF
0x0000000b 10 blah
[{"name":"blah","realname":"blah","size":10,"offset":11}]
addr       size space name realname 
------------------------------------
0x0000000b 10         blah blah
blah
0x00000002 3 bloh
[{"name":"bloh","realname":"bloh","size":3,"offset":2}]
addr       size space name realname 
------------------------------------
0x00000002 3          bloh bloh
bloh
EOF
RUN

NAME=no useless flags at 0
FILE=bins/elf/ls
CMDS=<<EOF
fl. @ 0
EOF
EXPECT=<<EOF
0x00000000 13440 segment.LOAD0
0x00000000 0 segment.GNU_STACK
0x00000000 64 segment.ehdr
EOF
RUN

NAME=show the flag graph
FILE=bins/elf/ls
CMDS=<<EOF
fg section
EOF
EXPECT=<<EOF
        ..in
            terp
            it
        ..note.
               ABI_tag
               gnu.build_id
        ..g
           nu.
              hash
              version
           nu.version
           ot
        ..d
           yn
             s
              ym
              tr
             str
             amic
           ynstr
           ata
        ..r
           ela.dyn
           odata
        ..text
        ..fini
        ..eh_frame
        ..bss
EOF
RUN

NAME=pd shows real names and flag name in comments
FILE=bins/elf/demangle-test-cpp
CMDS=<<EOF
pd 1 @ 0x000011ef @e:asm.flags.real=true
pd 1 @ 0x000011ef @e:asm.flags.real=false
EOF
EXPECT=<<EOF
            0x000011ef      call  std::vector<int, std::allocator<int> >::vector() ; method.std::vector_int__std::allocator_int___.vector
            0x000011ef      call  method.std::vector_int__std::allocator_int___.vector
EOF
RUN

NAME=Unicode grapheme clusters in flags
FILE==
CMDS=<<EOF
e asm.arch=arm
e asm.bits=64
s 0x100
wx f80202a9
f flag_name
pd 1
fN flag_name "(🎈️)"
pd 1
e asm.flags.real=false
fl.
fl.j
e asm.flags.real=true
fl.
EOF
EXPECT=<<EOF
            ;-- flag_name:
            0x00000100      stp   x24, x0, [x23, 0x20]
            ;-- (🎈️):
            0x00000100      stp   x24, x0, [x23, 0x20]
0x00000100 1 flag_name
[{"name":"flag_name","realname":"(🎈\ufe0f)","size":1,"offset":256}]
0x00000100 1 (🎈️)
EOF
RUN
