287 lines · plain
1## This test checks that disassemble stage works properly2## JT with indirect branch3## 1) nop + adr pair instructions4## 2) sub + ldr pair instructions5## 3) adrp + ldr pair instructions6## 4) pic jt with relive offsets packed to 1-byte entry size7## 5) fixed indirect branch8## 6) normal jt9 10# REQUIRES: system-linux11 12# RUN: rm -rf %t && split-file %s %t13 14## Prepare binary (1)15# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %t/jt_nop_adr.s \16# RUN: -o %t/jt_nop_adr.o17# RUN: %clang %cflags --target=aarch64-unknown-linux %t/jt_nop_adr.o \18# RUN: -Wl,-q -Wl,-z,now, -Wl,-T,%t/within-adr-range.t -o %t/jt_nop_adr.exe19# RUN: llvm-objdump --no-show-raw-insn -d %t/jt_nop_adr.exe | FileCheck \20# RUN: --check-prefix=JT-RELAXED %s21 22# JT-RELAXED: <_start>:23# JT-RELAXED-NEXT: nop24# JT-RELAXED-NEXT: adr {{.*}}x325 26# RUN: llvm-bolt %t/jt_nop_adr.exe -o %t/jt_nop_adr.bolt -v 3 2>&1 | FileCheck \27# RUN: --check-prefix=JT-BOLT-RELAXED %s28 29# JT-BOLT-RELAXED: failed to match indirect branch30 31## This linker script ensures that .rodata and .text are sufficiently (<1M)32## close to each other so that the adrp + ldr pair can be relaxed to nop + adr.33#--- within-adr-range.t34SECTIONS {35 .rodata 0x1000: { *(.rodata) }36 .text 0x2000: { *(.text) }37 .rela.rodata : { *(.rela.rodata) }38}39 40## Prepare binary (2)41# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %t/jt_sub_ldr.s \42# RUN: -o %t/jt_sub_ldr.o43# RUN: %clang %cflags --target=aarch64-unknown-linux %t/jt_sub_ldr.o \44# RUN: -Wl,-q -Wl,-z,now -o %t/jt_sub_ldr.exe45# RUN: llvm-objdump --no-show-raw-insn -d %t/jt_sub_ldr.exe | FileCheck \46# RUN: --check-prefix=JT-SUB-LDR %s47 48# JT-SUB-LDR: <_start>:49# JT-SUB-LDR-NEXT: sub50# JT-SUB-LDR-NEXT: ldr51 52# RUN: llvm-bolt %t/jt_sub_ldr.exe -o %t/jt_sub_ldr.bolt -v 3 2>&1 | FileCheck \53# RUN: --check-prefix=JT-BOLT-SUBLDR %s54# JT-BOLT-SUBLDR: failed to match indirect branch55 56## Prepare binary (3)57# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %t/jt_adrp_ldr.s \58# RUN: -o %t/jt_adrp_ldr.o59# RUN: %clang %cflags --target=aarch64-unknown-linux %t/jt_adrp_ldr.o \60# RUN: -Wl,-q -Wl,-z,now -Wl,--no-relax -o %t/jt_adrp_ldr.exe61# RUN: llvm-objdump --no-show-raw-insn -d %t/jt_adrp_ldr.exe | FileCheck \62# RUN: --check-prefix=JT-ADRP-LDR %s63 64# JT-ADRP-LDR: <_start>:65# JT-ADRP-LDR-NEXT: adrp66# JT-ADRP-LDR-NEXT: ldr67 68# RUN: llvm-bolt %t/jt_adrp_ldr.exe -o %t/jt_adrp_ldr.bolt -v 3 2>&1 | FileCheck \69# RUN: --check-prefix=JT-BOLT-ADRP-LDR %s70# JT-BOLT-ADRP-LDR: failed to match indirect branch71 72## Prepare binary (4)73# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \74# RUN: --position-independent %t/jt_pic_with_relative_offset.s \75# RUN: -o %t/jt_pic_with_relative_offset.o76# RUN: %clang %cflags -fPIC -O0 %t/jt_pic_with_relative_offset.o \77# RUN: -o %t/jt_pic_with_relative_offset.exe -Wl,-q -Wl,--no-relax78# RUN: llvm-bolt %t/jt_pic_with_relative_offset.exe \79# RUN: -o %t/jt_pic_with_relative_offset.bolt -v 3 2>&1 | FileCheck \80# RUN: --check-prefix=JT-BOLT-JT-PIC-OFFSETS %s81 82# JT-BOLT-JT-PIC-OFFSETS: failed to match indirect branch83 84## Prepare binary (5)85# RUN: %clang %cflags %t/jt_fixed_branch.s -Wl,-q -Wl,--no-relax \86# RUN: -o %t/jt_fixed_branch.exe87 88# RUN: llvm-bolt %t/jt_fixed_branch.exe \89# RUN: -o %t/jt_fixed_branch.bolt -v 3 2>&1 | FileCheck \90# RUN: --check-prefix=JT-BOLT-FIXED-BR %s91 92# JT-BOLT-FIXED-BR: failed to match indirect branch93 94## Prepare binary (6)95# RUN: %clang %cflags -no-pie %t/jt_type_normal.c \96# RUN: -Wl,-q -Wl,-z,now -Wl,--no-relax \97# RUN: -o %t/jt_type_normal.exe98# RUN: llvm-objdump --no-show-raw-insn -d %t/jt_type_normal.exe | FileCheck \99# RUN: --check-prefix=JT-OBJDUMP-NORMAL %s100 101# JT-OBJDUMP-NORMAL: <handleOptionJumpTable>:102# JT-OBJDUMP-NORMAL: adrp103# JT-OBJDUMP-NORMAL-NEXT: add104# JT-OBJDUMP-NORMAL-NEXT: ldr105# JT-OBJDUMP-NORMAL-NEXT: blr106 107# RUN: llvm-bolt %t/jt_type_normal.exe --dyno-stats \108# RUN: -o %t/jt_type_normal.bolt -v 3 2>&1 | FileCheck \109# RUN: --check-prefix=JT-BOLT-NORMAL %s110 111# JT-BOLT-NORMAL: 0{{.*}}: indirect calls112 113#--- jt_nop_adr.s114 .globl _start115 .type _start, %function116_start:117 adrp x3, :got:jump_table118 ldr x3, [x3, #:got_lo12:jump_table]119 ldrh w3, [x3, x1, lsl #1]120 adr x1, test2_0121 add x3, x1, w3, sxth #2122 br x3123test2_0:124 ret125test2_1:126 ret127 128 .section .rodata,"a",@progbits129jump_table:130 .hword (test2_0-test2_0)>>2131 .hword (test2_1-test2_0)>>2132 133 134#--- jt_sub_ldr.s135 .globl _start136 .type _start, %function137_start:138 sub x1, x29, #0x4, lsl #12139 ldr x1, [x1, #14352]140 ldrh w1, [x1, w3, uxtw #1]141 adr x3, test2_0142 add x1, x3, w1, sxth #2143 br x1144test2_0:145 ret146test2_1:147 ret148 149 .section .rodata,"a",@progbits150jump_table:151 .hword (test2_0-test2_0)>>2152 .hword (test2_1-test2_0)>>2153 154 155#--- jt_adrp_ldr.s156 .globl _start157 .type _start, %function158_start:159 adrp x3, :got:jump_table160 ldr x3, [x3, #:got_lo12:jump_table]161 ldrh w3, [x3, x1, lsl #1]162 adr x1, test2_0163 add x3, x1, w3, sxth #2164 br x3165test2_0:166 ret167test2_1:168 ret169 170 .section .rodata,"a",@progbits171jump_table:172 .hword (test2_0-test2_0)>>2173 .hword (test2_1-test2_0)>>2174 175 176#--- jt_pic_with_relative_offset.s177.text178.global _start179_start:180 mov x4, 3 // index in jmp table where offset related to adr instr181 adrp x0, funcTableSym182 add x0, x0, #:lo12:funcTableSym183 ldrb w0, [x0, w4, uxtw #0]184 adr x2, .LBB1185 add x0, x2, w0, sxth #2186 br x0187 188.LBB1:189 bl funcA190 b .test_exit191 192.LBB2:193 bl funcB194 b .test_exit195 196.LBB3:197 bl funcC198 b .test_exit199 200.LBB4:201 bl funcD202 b .test_exit203 204.test_exit:205 mov x8, #93206 mov x0, #0207 svc #0208 209.global funcA210funcA:211 ret212 213.global funcB214funcB:215 ret216 217.global funcC218funcC:219 ret220 221.global funcD222funcD:223 ret224 225.section .rodata,"a",@progbits226.align 2227funcTableSym:228 .byte 0x00,0x02,0x04,0x06 // 1 - .LBB1, 3 - .LBB2229 230#--- jt_fixed_branch.s231 232.text233.global _start234_start:235 mov x0, x13236 mov x1, x4237 mov x0, x2238 movk x1, #0x0, lsl #48239 movk x1, #0x0, lsl #32240 movk x1, #0x0, lsl #16241 movk x1, #0x12242 stp x0, x1, [sp, #-16]!243 adrp x0, foo244 add x0, x0, #:lo12:foo245 br x0246 mov x8, #93247 mov x0, #0248 svc #0249 250.global foo251.type foo,%function252foo:253 mov x8, #9254 ret255.size foo,.-foo256 257#--- jt_type_normal.c258 259void __attribute__ ((noinline)) option0() {260}261 262void __attribute__ ((noinline)) option1() {263}264 265void __attribute__ ((noinline)) option2() {266}267 268void __attribute__ ((noinline)) option3() {269}270 271void __attribute__ ((noinline)) option4() {272}273 274void __attribute__ ((noinline)) option5() {275}276 277void (*jumpTable[6])() = { option0, option1, option2, option3, option4, option5 };278 279void __attribute__ ((noinline)) handleOptionJumpTable(int option) {280 jumpTable[option]();281}282 283int main(int argc, char *argv[]) {284 handleOptionJumpTable(argc);285 return 0;286}287