Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/bolt
diff options
context:
space:
mode:
authorRafael Auler <rafaelauler@fb.com>2022-10-07 21:26:51 +0300
committerRafael Auler <rafaelauler@fb.com>2022-10-07 21:27:23 +0300
commit696b8ea05fb18309bf3a68ae1d7e9d1659561ed8 (patch)
treee27643543136aa4015701fe99c3fcbbb92a49c51 /bolt
parent07c0a41b53f532902ed977589363d2ba51748e75 (diff)
[BOLT] Testcase to repro dyn reloc bug
Add a new testcase that shows a bug in BOLT when writing out dynamic relocations. This is currently marked as XFAIL as we work on solving it. This bug happens when the current strategy fails to recognize that the original dynamic relocation in the input should reference the original .bolt.org.rodata section instead of the new one .rodata created by BOLT after moving jump tables. This bug started happening after 729d29e167a5. Reviewed By: Amir Differential Revision: https://reviews.llvm.org/D125941
Diffstat (limited to 'bolt')
-rw-r--r--bolt/test/X86/Inputs/define_bar.s7
-rw-r--r--bolt/test/X86/dynrelocs.s81
2 files changed, 88 insertions, 0 deletions
diff --git a/bolt/test/X86/Inputs/define_bar.s b/bolt/test/X86/Inputs/define_bar.s
new file mode 100644
index 000000000000..8c5fb43f2500
--- /dev/null
+++ b/bolt/test/X86/Inputs/define_bar.s
@@ -0,0 +1,7 @@
+# Mocks a vtable object weak def in the C++ stdlib.
+ .data.rel.ro
+ .weak bar
+ .type bar, %object
+bar:
+ .space 20
+ .size bar, 20
diff --git a/bolt/test/X86/dynrelocs.s b/bolt/test/X86/dynrelocs.s
new file mode 100644
index 000000000000..f8ea8639c65d
--- /dev/null
+++ b/bolt/test/X86/dynrelocs.s
@@ -0,0 +1,81 @@
+# This reproduces a bug when rewriting dynamic relocations in X86 as
+# BOLT incorrectly attributes R_X86_64_64 dynamic relocations
+# to the wrong section when the -jump-tables=move flag is used. We
+# expect the relocations to belong to the .bolt.org.rodata section but
+# it is attributed to a new .rodata section that only contains jump
+# table entries, created by BOLT. BOLT will only create this new .rodata
+# section if both -jump-tables=move is used and a hot function with
+# jt is present in the input binary, triggering a scenario where the
+# dynamic relocs rewriting gets confused on where to put .rodata relocs.
+
+# It is uncommon to end up with dynamic relocations against .rodata,
+# but it can happen. In these cases we cannot corrupt the
+# output binary by writing out dynamic relocs incorrectly. The linker
+# avoids emitting relocs against read-only sections but we override
+# this behvior with the -z notext flag. During runtime, these pages
+# are mapped with write permission and then changed to read-only after
+# the dynamic linker finishes processing the dynamic relocs.
+
+# In this test, we create a reference to a dynamic object that will
+# imply in R_X86_64_64 being used for .rodata. Now BOLT, when creating
+# a new .rodata to hold jump table entries, needs to remember to emit
+# these dynamic relocs against the original .rodata, and not the new
+# one it just created.
+
+# REQUIRES: system-linux
+# Currently XFAIL as we do not support it.
+# XFAIL: *
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux \
+# RUN: %s -o %t.o
+# RUN: link_fdata %s %t.o %t.fdata
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux \
+# RUN: %p/Inputs/define_bar.s -o %t.2.o
+# RUN: llvm-strip --strip-unneeded %t.o
+# RUN: ld.lld %t.2.o -o %t.so -shared
+# RUN: ld.lld -z notext %t.o -o %t.exe -q %t.so
+# RUN: llvm-bolt -data %t.fdata %t.exe -relocs -o %t.out -lite=0 \
+# RUN: -jump-tables=move
+# RUN: llvm-readobj -rs %t.out | FileCheck --check-prefix=READOBJ %s
+
+# Verify that BOLT outputs the dynamic reloc at the correct address,
+# which is the start of the .bolt.org.rodata section.
+# READOBJ: Relocations [
+# READOBJ: Section ([[#]]) .rela.dyn {
+# READOBJ-NEXT: 0x[[#%X,ADDR:]] R_X86_64_64 bar 0x10
+# READOBJ: Symbols [
+# READOBJ: Name: .bolt.org.rodata
+# READOBJ-NEXT: Value: 0x[[#ADDR]]
+
+ # Create a hot function with jump table
+ .text
+ .globl _start
+ .type _start, %function
+_start:
+ .cfi_startproc
+# FDATA: 0 [unknown] 0 1 _start 0 0 6
+ movq .LJUMPTABLE(,%rdi,8), %rax
+b: jmpq *%rax
+# FDATA: 1 _start #b# 1 _start #c# 0 3
+c:
+ mov $1, %rax
+d:
+ xorq %rax, %rax
+ ret
+ .cfi_endproc
+ .size _start, .-_start
+
+ # This is the section that needs to be tested.
+ .section .rodata
+ .align 4
+ # We will have a R_X86_64_64 here or R_X86_64_COPY if this section
+ # is non-writable. We use -z notext to force the linker to accept dynamic
+ # relocations in read-only sections and make it a R_X86_64_64.
+ .quad bar + 16 # Reference a dynamic object (such as a vtable ref)
+ # Add other contents to this section: a hot jump table that will be
+ # copied by BOLT into a new section.
+.LJUMPTABLE:
+ .quad c
+ .quad c
+ .quad d
+ .quad d