Skip to content

Commit 3ba9e74

Browse files
committed
Merge branch 'junghee/arm64-unsigned-data' into 'main'
ARM64: Fix a bug in computing jump-table targets See merge request rewriting/ddisasm!1237
2 parents e2bac3d + 6b80c58 commit 3ba9e74

8 files changed

Lines changed: 118 additions & 24 deletions

File tree

examples/arm64_asm_examples/ex_switch1/src.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ main:
2121
.L0:
2222
adrp x0, .s_zero
2323
add x0, x0, :lo12:.s_zero
24-
b .L_exit
24+
b .L_print
2525
.L1:
2626
adrp x0, .s_one
2727
add x0, x0, :lo12:.s_one
28-
b .L_exit
28+
b .L_print
2929
.L2:
3030
adrp x0, .s_two
3131
add x0, x0, :lo12:.s_two
32-
b .L_exit
32+
b .L_print
3333
.L3:
3434
adrp x0, .s_three
3535
add x0, x0, :lo12:.s_three

examples/arm64_asm_examples/ex_switch2/src.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ main:
2222
nop
2323
adrp x0, .s_zero
2424
add x0, x0, :lo12:.s_zero
25-
b .L_exit
25+
b .L_print
2626
.L1:
2727
adrp x0, .s_one
2828
add x0, x0, :lo12:.s_one
29-
b .L_exit
29+
b .L_print
3030
.L2:
3131
adrp x0, .s_two
3232
add x0, x0, :lo12:.s_two
33-
b .L_exit
33+
b .L_print
3434
.L3:
3535
adrp x0, .s_three
3636
add x0, x0, :lo12:.s_three

examples/arm64_asm_examples/ex_switch3/src.s

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ main:
2020
cmp w0, #3
2121
b.hi .L_exit
2222

23+
.jump:
2324
# split the loads across the jumptable to ensure that they are not
2425
# correctly symbolized unless the jumptable is correct.
2526
adrp x22, .s_zero
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CC=aarch64-linux-gnu-gcc
2+
EXEC=qemu-aarch64 -L /usr/aarch64-linux-gnu
3+
4+
TARGETS=ex out.txt
5+
6+
.PHONY: all clean check
7+
all: out.txt
8+
check: out.txt
9+
ex: src.s
10+
$(CC) $^ -o $@
11+
out.txt: ex
12+
$(EXEC) $^ > $@
13+
clean:
14+
rm -f $(TARGETS) *.gtirb
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Test switch with shift in indirect operand /w memory load of unsigned data
2+
3+
.arch armv8-a
4+
.file "src.s"
5+
.text
6+
.global main
7+
.type main, %function
8+
main:
9+
stp fp,lr,[sp,#-16]!
10+
mov fp,sp
11+
12+
adrp x22, .L_jumptable
13+
add x22,x22, :lo12:.L_jumptable
14+
15+
cmp w0,#3
16+
b.hi .L_exit
17+
18+
.jump:
19+
ldrh w0,[x22,x0, lsl #1]
20+
adr x1, .L0
21+
add x0,x1,x0, lsl #2
22+
br x0
23+
24+
.L0:
25+
adrp x0, .s_zero
26+
add x0, x0, :lo12:.s_zero
27+
b .L_print
28+
.L1:
29+
adrp x0, .s_one
30+
add x0, x0, :lo12:.s_one
31+
b .L_print
32+
.L2:
33+
adrp x0, .s_two
34+
add x0, x0, :lo12:.s_two
35+
b .L_print
36+
.L3:
37+
adrp x0, .s_three
38+
add x0, x0, :lo12:.s_three
39+
40+
.L_print:
41+
bl printf
42+
43+
.L_exit:
44+
ldp fp,lr,[sp],#16
45+
mov x0, #0
46+
ret
47+
48+
.L_exit2:
49+
ldp fp,lr,[sp],#16
50+
mov x0, #1
51+
ret
52+
53+
.L_jumptable:
54+
.short (.L0-.L0)/4
55+
.short (.L1-.L0)/4
56+
.short (.L2-.L0)/4
57+
.short (.L3-.L0)/4
58+
59+
.section .rodata
60+
.s_zero:
61+
.ascii "zero\n\0"
62+
.s_one:
63+
.ascii "one\n\0"
64+
.s_two:
65+
.ascii "two\n\0"
66+
.s_three:
67+
.ascii "three\n\0"

examples/arm64_asm_examples/ex_switch_limited_by_cmp/src.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ main:
2424
.L0:
2525
adrp x0, .s_zero
2626
add x0, x0, :lo12:.s_zero
27-
b .L_exit
27+
b .L_print
2828
.L1:
2929
adrp x0, .s_one
3030
add x0, x0, :lo12:.s_one
31-
b .L_exit
31+
b .L_print
3232
.L2:
3333
adrp x0, .s_two
3434
add x0, x0, :lo12:.s_two
35-
b .L_exit
35+
b .L_print
3636
.L3:
3737
adrp x0, .s_three
3838
add x0, x0, :lo12:.s_three

src/datalog/relative_jump_tables.dl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,8 @@ relative_jump_table_entry_target(EA,TableStart,Size,Reference,NewDest,Scale):-
329329
jump_table_signed(TableStart,Signed),
330330
(
331331
Signed = 0, data_uword(EA,Size,UDiff),
332-
Dest = Reference + UDiff
332+
Reference_unsigned = as(Reference,unsigned),
333+
Dest = as(Reference_unsigned + as(Scale,unsigned)*UDiff,address)
333334
;
334335
Signed = 1, data_word(EA,Size,SDiff),
335336
Reference_signed = as(Reference,number),

tests/cfg_test.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,24 +104,35 @@ def test_switch_limited_by_cmp(self):
104104
@unittest.skipUnless(
105105
platform.system() == "Linux", "This test is linux only."
106106
)
107-
def test_switch_limited_by_cmp_arm64(self):
107+
def test_switch_arm64(self):
108108
"""
109-
Ensure jump table propagation is limited by comparsions of the index
110-
register.
109+
Test jump-table construction in various cases
111110
"""
112-
binary = Path("ex")
113-
with cd(ex_arm64_asm_dir / "ex_switch_limited_by_cmp"):
114-
self.assertTrue(
115-
compile(
116-
"aarch64-linux-gnu-gcc", "aarch64-linux-gnu-g++", "-O0", []
111+
ex_info = [
112+
("ex_switch1", "main"),
113+
("ex_switch2", "main"),
114+
("ex_switch3", ".jump"),
115+
("ex_switch4", ".jump"),
116+
("ex_switch_limited_by_cmp", ".jump"),
117+
]
118+
for example, symbol in ex_info:
119+
binary = Path("ex")
120+
with cd(ex_arm64_asm_dir / example):
121+
self.assertTrue(
122+
compile(
123+
"aarch64-linux-gnu-gcc",
124+
"aarch64-linux-gnu-g++",
125+
"-O0",
126+
[],
127+
)
117128
)
118-
)
119-
ir_library = disassemble(binary).ir()
120-
m = ir_library.modules[0]
129+
ir_library = disassemble(binary).ir()
130+
m = ir_library.modules[0]
121131

122-
# check that the .jump has edges to only the four jump table entries
123-
jump_sym = next(m.symbols_named(".jump"))
124-
self.assertEqual(len(list(jump_sym.referent.outgoing_edges)), 4)
132+
# check that the symbol has edges to only the four jump table
133+
# entries
134+
jump_sym = next(m.symbols_named(symbol))
135+
self.assertEqual(len(list(jump_sym.referent.outgoing_edges)), 4)
125136

126137
@unittest.skipUnless(
127138
platform.system() == "Linux", "This test is linux only."

0 commit comments

Comments
 (0)