xref: /llvm-project/bolt/test/X86/linux-alt-instruction.s (revision 6e8a1a45a783c13e4cd19bfd20b7a56cab6f7d81)
1# REQUIRES: system-linux
2
3## Check that BOLT correctly parses the Linux kernel .altinstructions section
4## and annotates alternative instructions.
5
6# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
7# RUN: %clang %cflags -nostdlib %t.o -o %t.exe \
8# RUN:   -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
9# RUN: llvm-bolt %t.exe --print-cfg --alt-inst-feature-size=2 -o %t.out \
10# RUN:   | FileCheck %s
11
12## Older kernels used to have padlen field in alt_instr. Check compatibility.
13
14# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --defsym PADLEN=1 \
15# RUN:   %s -o %t.padlen.o
16# RUN: %clang %cflags -nostdlib %t.padlen.o -o %t.padlen.exe \
17# RUN:   -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
18# RUN: llvm-bolt %t.padlen.exe --print-cfg --alt-inst-has-padlen -o %t.padlen.out \
19# RUN:   | FileCheck %s
20
21## Check with a larger size of "feature" field in alt_instr.
22
23# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \
24# RUN:   --defsym FEATURE_SIZE_4=1 %s -o %t.fs4.o
25# RUN: %clang %cflags -nostdlib %t.fs4.o -o %t.fs4.exe \
26# RUN:   -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
27# RUN: llvm-bolt %t.fs4.exe --print-cfg --alt-inst-feature-size=4 -o %t.fs4.out \
28# RUN:   | FileCheck %s
29
30## Check that out-of-bounds read is handled properly.
31
32# RUN: not llvm-bolt %t.fs4.exe --alt-inst-feature-size=2 -o %t.fs4.out
33
34## Check that BOLT automatically detects structure fields in .altinstructions.
35
36# RUN: llvm-bolt %t.exe --print-cfg -o %t.out | FileCheck %s
37# RUN: llvm-bolt %t.exe --print-cfg -o %t.padlen.out | FileCheck %s
38# RUN: llvm-bolt %t.exe --print-cfg -o %t.fs4.out | FileCheck %s
39
40# CHECK:      BOLT-INFO: Linux kernel binary detected
41# CHECK:      BOLT-INFO: parsed 3 alternative instruction entries
42
43  .text
44  .globl _start
45  .type _start, %function
46_start:
47# CHECK: Binary Function "_start"
48.L0:
49  rdtsc
50# CHECK:      rdtsc
51# CHECK-SAME: AltInst: 1
52# CHECK-SAME: AltInst2: 2
53# CHECK-SAME: AltInst3: 3
54  nop
55# CHECK-NEXT: nop
56# CHECK-SAME: AltInst: 1
57# CHECK-SAME: AltInst2: 2
58# CHECK-SAME: AltInst3: 3
59  nop
60  nop
61.L1:
62  ret
63  .size _start, .-_start
64
65  .section .altinstr_replacement,"ax",@progbits
66.A0:
67  lfence
68  rdtsc
69.A1:
70  rdtscp
71.A2:
72  pushf
73  pop %rax
74.Ae:
75
76## Alternative instruction info.
77  .section .altinstructions,"a",@progbits
78
79  .long .L0 - .   # org instruction
80  .long .A0 - .   # alt instruction
81.ifdef FEATURE_SIZE_4
82  .long 0x72      # feature flags
83.else
84  .word 0x72      # feature flags
85.endif
86  .byte .L1 - .L0 # org size
87  .byte .A1 - .A0 # alt size
88.ifdef PADLEN
89  .byte 0
90.endif
91
92  .long .L0 - .   # org instruction
93  .long .A1 - .   # alt instruction
94.ifdef FEATURE_SIZE_4
95  .long 0x3b      # feature flags
96.else
97  .word 0x3b      # feature flags
98.endif
99  .byte .L1 - .L0 # org size
100  .byte .A2 - .A1 # alt size
101.ifdef PADLEN
102  .byte 0
103.endif
104
105  .long .L0 - .   # org instruction
106  .long .A2 - .   # alt instruction
107.ifdef FEATURE_SIZE_4
108  .long 0x110     # feature flags
109.else
110  .word 0x110     # feature flags
111.endif
112  .byte .L1 - .L0 # org size
113  .byte .Ae - .A2 # alt size
114.ifdef PADLEN
115  .byte 0
116.endif
117
118## ORC unwind for "pushf; pop %rax" alternative sequence.
119  .section .orc_unwind,"a",@progbits
120  .align 4
121  .section .orc_unwind_ip,"a",@progbits
122  .align 4
123
124  .section .orc_unwind
125  .2byte 8
126  .2byte 0
127  .2byte 0x205
128  .section .orc_unwind_ip
129  .long _start - .
130
131  .section .orc_unwind
132  .2byte 16
133  .2byte 0
134  .2byte 0x205
135  .section .orc_unwind_ip
136  .long .L0 + 1 - .
137
138  .section .orc_unwind
139  .2byte 8
140  .2byte 0
141  .2byte 0x205
142  .section .orc_unwind_ip
143  .long .L0 + 2 - .
144
145## Linux kernel version
146  .rodata
147  .align 16
148  .globl linux_banner
149  .type  linux_banner, @object
150linux_banner:
151  .string  "Linux version 6.6.61\n"
152  .size  linux_banner, . - linux_banner
153
154## Fake Linux Kernel sections.
155  .section __ksymtab,"a",@progbits
156  .section __ksymtab_gpl,"a",@progbits
157