1*11791ae7SSayhaan Siddiqui## This reproduces a bug when rewriting dynamic relocations in X86 as 2*11791ae7SSayhaan Siddiqui## BOLT incorrectly attributes R_X86_64_64 dynamic relocations 3*11791ae7SSayhaan Siddiqui## to the wrong section when the -jump-tables=move flag is used. We 4*11791ae7SSayhaan Siddiqui## expect the relocations to belong to the .bolt.org.rodata section but 5*11791ae7SSayhaan Siddiqui## it is attributed to a new .rodata section that only contains jump 6*11791ae7SSayhaan Siddiqui## table entries, created by BOLT. BOLT will only create this new .rodata 7*11791ae7SSayhaan Siddiqui## section if both -jump-tables=move is used and a hot function with 8*11791ae7SSayhaan Siddiqui## jt is present in the input binary, triggering a scenario where the 9*11791ae7SSayhaan Siddiqui## dynamic relocs rewriting gets confused on where to put .rodata relocs. 10696b8ea0SRafael Auler 11*11791ae7SSayhaan Siddiqui## It is uncommon to end up with dynamic relocations against .rodata, 12*11791ae7SSayhaan Siddiqui## but it can happen. In these cases we cannot corrupt the 13*11791ae7SSayhaan Siddiqui## output binary by writing out dynamic relocs incorrectly. The linker 14*11791ae7SSayhaan Siddiqui## avoids emitting relocs against read-only sections but we override 15*11791ae7SSayhaan Siddiqui## this behavior with the -z notext flag. During runtime, these pages 16*11791ae7SSayhaan Siddiqui## are mapped with write permission and then changed to read-only after 17*11791ae7SSayhaan Siddiqui## the dynamic linker finishes processing the dynamic relocs. 18696b8ea0SRafael Auler 19*11791ae7SSayhaan Siddiqui## In this test, we create a reference to a dynamic object that will 20*11791ae7SSayhaan Siddiqui## imply in R_X86_64_64 being used for .rodata. Now BOLT, when creating 21*11791ae7SSayhaan Siddiqui## a new .rodata to hold jump table entries, needs to remember to emit 22*11791ae7SSayhaan Siddiqui## these dynamic relocs against the original .rodata, and not the new 23*11791ae7SSayhaan Siddiqui## one it just created. 24696b8ea0SRafael Auler 25696b8ea0SRafael Auler# REQUIRES: system-linux 26696b8ea0SRafael Auler 27696b8ea0SRafael Auler# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux \ 28696b8ea0SRafael Auler# RUN: %s -o %t.o 29696b8ea0SRafael Auler# RUN: link_fdata %s %t.o %t.fdata 30696b8ea0SRafael Auler# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux \ 31696b8ea0SRafael Auler# RUN: %p/Inputs/define_bar.s -o %t.2.o 32696b8ea0SRafael Auler# RUN: llvm-strip --strip-unneeded %t.o 33696b8ea0SRafael Auler# RUN: ld.lld %t.2.o -o %t.so -shared 34696b8ea0SRafael Auler# RUN: ld.lld -z notext %t.o -o %t.exe -q %t.so 35696b8ea0SRafael Auler# RUN: llvm-bolt -data %t.fdata %t.exe -relocs -o %t.out -lite=0 \ 36696b8ea0SRafael Auler# RUN: -jump-tables=move 37696b8ea0SRafael Auler# RUN: llvm-readobj -rs %t.out | FileCheck --check-prefix=READOBJ %s 38696b8ea0SRafael Auler 39*11791ae7SSayhaan Siddiqui## Verify that BOLT outputs the dynamic reloc at the correct address, 40*11791ae7SSayhaan Siddiqui## which is the start of the .bolt.org.rodata section. 41696b8ea0SRafael Auler# READOBJ: Relocations [ 42696b8ea0SRafael Auler# READOBJ: Section ([[#]]) .rela.dyn { 43696b8ea0SRafael Auler# READOBJ-NEXT: 0x[[#%X,ADDR:]] R_X86_64_64 bar 0x10 44696b8ea0SRafael Auler# READOBJ: Symbols [ 45696b8ea0SRafael Auler# READOBJ: Name: .bolt.org.rodata 46696b8ea0SRafael Auler# READOBJ-NEXT: Value: 0x[[#ADDR]] 47696b8ea0SRafael Auler 48696b8ea0SRafael Auler # Create a hot function with jump table 49696b8ea0SRafael Auler .text 50696b8ea0SRafael Auler .globl _start 51696b8ea0SRafael Auler .type _start, %function 52696b8ea0SRafael Auler_start: 53696b8ea0SRafael Auler .cfi_startproc 54696b8ea0SRafael Auler# FDATA: 0 [unknown] 0 1 _start 0 0 6 55696b8ea0SRafael Auler movq .LJUMPTABLE(,%rdi,8), %rax 56696b8ea0SRafael Aulerb: jmpq *%rax 57696b8ea0SRafael Auler# FDATA: 1 _start #b# 1 _start #c# 0 3 58696b8ea0SRafael Aulerc: 59696b8ea0SRafael Auler mov $1, %rax 60696b8ea0SRafael Aulerd: 61696b8ea0SRafael Auler xorq %rax, %rax 62696b8ea0SRafael Auler ret 63696b8ea0SRafael Auler .cfi_endproc 64696b8ea0SRafael Auler .size _start, .-_start 65696b8ea0SRafael Auler 66696b8ea0SRafael Auler # This is the section that needs to be tested. 67696b8ea0SRafael Auler .section .rodata 68696b8ea0SRafael Auler .align 4 69696b8ea0SRafael Auler # We will have a R_X86_64_64 here or R_X86_64_COPY if this section 70696b8ea0SRafael Auler # is non-writable. We use -z notext to force the linker to accept dynamic 71696b8ea0SRafael Auler # relocations in read-only sections and make it a R_X86_64_64. 72696b8ea0SRafael Auler .quad bar + 16 # Reference a dynamic object (such as a vtable ref) 73696b8ea0SRafael Auler # Add other contents to this section: a hot jump table that will be 74696b8ea0SRafael Auler # copied by BOLT into a new section. 75696b8ea0SRafael Auler.LJUMPTABLE: 76696b8ea0SRafael Auler .quad c 77696b8ea0SRafael Auler .quad c 78696b8ea0SRafael Auler .quad d 79696b8ea0SRafael Auler .quad d 80