[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / bolt / test / X86 / jump-table-pic-conflict.s
blobed3c77d49b6cc4620efa722e7766e434481beb11
1 # Check cases when the first PIC jump table entries of one function can be
2 # interpreted as valid last entries of the previous function.
4 # Conditions to trigger the bug: Function A and B have jump tables that
5 # are adjacent in memory. We run in lite relocation mode. Function B
6 # is not disassembled because it does not have profile. Function A
7 # triggers a special conditional that forced BOLT to rewrite its jump
8 # table in-place (instead of moving it) because it is marked as
9 # non-simple (in this case, containing unknown control flow). The
10 # first entry of B's jump table (a PIC offset) happens to be a valid
11 # address inside A when added to A's jump table base address. In this
12 # case, BOLT could overwrite B's jump table, corrupting it, thinking
13 # the first entry of it is actually part of A's jump table.
15 # REQUIRES: system-linux
17 # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \
18 # RUN: %s -o %t.o
19 # RUN: link_fdata %s %t.o %t.fdata
20 # RUN: llvm-strip --strip-unneeded %t.o
21 # RUN: ld.lld %t.o -o %t.exe -q -T %S/Inputs/jt-pic-linkerscript.ld
22 # RUN: llvm-bolt %t.exe -relocs -o %t.out -data %t.fdata \
23 # RUN: -lite=1
24 # RUN: llvm-readelf -S %t.out | FileCheck --check-prefix=CHECK %s
25 # The output binary is runnable, but we check for test success with
26 # readelf. This is another way to check this bug:
27 # COM: %t.out
29 # BOLT needs to create a new rodata section, indicating that it
30 # successfully moved the jump table in _start.
31 # CHECK: [{{.*}}] .bolt.org.rodata
33 .globl _start
34 .type _start, %function
35 _start:
36 .cfi_startproc
37 # FDATA: 0 [unknown] 0 1 _start 0 0 1
38 push %rbp
39 mov %rsp, %rbp
40 mov 0x8(%rbp), %rdi
41 cmpq $3, %rdi
42 ja .L5
43 jmp .L6
44 # Unreachable code, here to mark this function as non-simple
45 # (containing unknown control flow) with a stray indirect jmp
46 jmp *%rax
47 .L6:
48 decq %rdi
49 leaq .LJT1(%rip), %rcx
50 movslq (%rcx, %rdi, 4), %rax
51 addq %rcx, %rax
52 jmp *%rax
53 .L1:
54 leaq str1(%rip), %rsi
55 jmp .L4
56 .L2:
57 leaq str2(%rip), %rsi
58 jmp .L4
59 .L3:
60 leaq str3(%rip), %rsi
61 jmp .L4
62 .L5:
63 leaq str4(%rip), %rsi
64 .L4:
65 movq $1, %rdi
66 movq $10, %rdx
67 movq $1, %rax
68 syscall
69 mov 0x8(%rbp), %rdi
70 decq %rdi
71 callq func_b
72 movq %rax, %rdi
73 movq $231, %rax
74 syscall
75 pop %rbp
76 ret
77 .cfi_endproc
78 .size _start, .-_start
80 .globl func_b
81 .type func_b, %function
82 func_b:
83 .cfi_startproc
84 push %rbp
85 mov %rsp, %rbp
86 cmpq $3, %rdi
87 ja .L2_6
88 # FT
89 leaq .LJT2(%rip), %rcx
90 movslq (%rcx, %rdi, 4), %rax
91 addq %rcx, %rax
92 jmp *%rax
93 .L2_1:
94 movq $0, %rax
95 jmp .L2_5
96 .L2_2:
97 movq $1, %rax
98 jmp .L2_5
99 .L2_3:
100 movq $2, %rax
101 jmp .L2_5
102 .L2_4:
103 movq $3, %rax
104 jmp .L2_5
105 .L2_6:
106 movq $-1, %rax
107 .L2_5:
108 popq %rbp
110 .cfi_endproc
111 .size func_b, .-func_b
113 .rodata
114 str1: .asciz "Message 1\n"
115 str2: .asciz "Message 2\n"
116 str3: .asciz "Message 3\n"
117 str4: .asciz "Highrange\n"
118 # Special case where the first .LJT2 entry is a valid offset of
119 # _start when interpreted with .LJT1 as a base address.
120 .LJT1:
121 .long .L1-.LJT1
122 .long .L2-.LJT1
123 .long .L3-.LJT1
124 .long .L3-.LJT1
125 .long .L3-.LJT1
126 .long .L3-.LJT1
127 .long .L3-.LJT1
128 .LJT2:
129 .long .L2_1-.LJT2
130 .long .L2_2-.LJT2
131 .long .L2_3-.LJT2
132 .long .L2_4-.LJT2