brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · c84551a Raw
133 lines · plain
1## Check cases when the first PIC jump table entries of one function can be2## interpreted as valid last entries of the previous function.3 4## Conditions to trigger the bug:  Function A and B have jump tables that5## are adjacent in memory. We run in lite relocation mode. Function B6## is not disassembled because it does not have profile. Function A7## triggers a special conditional that forced BOLT to rewrite its jump8## table in-place (instead of moving it) because it is marked as9## non-simple (in this case, containing unknown control flow). The10## first entry of B's jump table (a PIC offset) happens to be a valid11## address inside A when added to A's jump table base address. In this12## case, BOLT could overwrite B's jump table, corrupting it, thinking13## the first entry of it is actually part of A's jump table.14 15# REQUIRES: system-linux16 17# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \18# RUN:   %s -o %t.o19# RUN: link_fdata %s %t.o %t.fdata20# RUN: llvm-strip --strip-unneeded %t.o21# RUN: ld.lld %t.o -o %t.exe -q -T %S/Inputs/jt-pic-linkerscript.ld22# RUN: llvm-bolt %t.exe -relocs -o %t.out -data %t.fdata \23# RUN:     -lite=124# RUN: llvm-readelf -S %t.out | FileCheck --check-prefix=CHECK %s25# The output binary is runnable, but we check for test success with26# readelf. This is another way to check this bug:27# COM: %t.out28 29## BOLT needs to create a new rodata section, indicating that it30## successfully moved the jump table in _start.31# CHECK: [{{.*}}] .bolt.org.rodata32 33  .globl _start34  .type _start, %function35_start:36  .cfi_startproc37# FDATA: 0 [unknown] 0 1 _start 0 0 138  push    %rbp39  mov     %rsp, %rbp40  mov     0x8(%rbp), %rdi41  cmpq    $3, %rdi42  ja      .L543  jmp     .L644## Unreachable code, here to mark this function as non-simple45## (containing unknown control flow) with a stray indirect jmp46  jmp     *%rax47.L6:48  decq    %rdi49  leaq    .LJT1(%rip), %rcx50  movslq  (%rcx, %rdi, 4), %rax51  addq    %rcx, %rax52  jmp     *%rax53.L1:54  leaq    str1(%rip), %rsi55  jmp     .L456.L2:57  leaq    str2(%rip), %rsi58  jmp     .L459.L3:60  leaq    str3(%rip), %rsi61  jmp     .L462.L5:63  leaq    str4(%rip), %rsi64.L4:65  movq    $1, %rdi66  movq    $10, %rdx67  movq    $1, %rax68  syscall69  mov     0x8(%rbp), %rdi70  decq    %rdi71  callq   func_b72  movq    %rax, %rdi73  movq    $231, %rax74  syscall75  pop     %rbp76  ret77  .cfi_endproc78  .size _start, .-_start79 80  .globl func_b81  .type func_b, %function82func_b:83  .cfi_startproc84  push    %rbp85  mov     %rsp, %rbp86  cmpq    $3, %rdi87  ja      .L2_688# FT89  leaq    .LJT2(%rip), %rcx90  movslq  (%rcx, %rdi, 4), %rax91  addq    %rcx, %rax92  jmp     *%rax93.L2_1:94  movq    $0, %rax95  jmp     .L2_596.L2_2:97  movq    $1, %rax98  jmp     .L2_599.L2_3:100  movq    $2, %rax101  jmp     .L2_5102.L2_4:103  movq    $3, %rax104  jmp     .L2_5105.L2_6:106  movq    $-1, %rax107.L2_5:108  popq    %rbp109  ret110  .cfi_endproc111  .size func_b, .-func_b112 113  .rodata114str1: .asciz "Message 1\n"115str2: .asciz "Message 2\n"116str3: .asciz "Message 3\n"117str4: .asciz "Highrange\n"118## Special case where the first .LJT2 entry is a valid offset of119## _start when interpreted with .LJT1 as a base address.120.LJT1:121  .long .L1-.LJT1122  .long .L2-.LJT1123  .long .L3-.LJT1124  .long .L3-.LJT1125  .long .L3-.LJT1126  .long .L3-.LJT1127  .long .L3-.LJT1128.LJT2:129  .long .L2_1-.LJT2130  .long .L2_2-.LJT2131  .long .L2_3-.LJT2132  .long .L2_4-.LJT2133