[PATCH] D125941: [BOLT] Testcase to repro dyn reloc bug

Rafael Auler via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 14:49:24 PDT 2022


rafauler updated this revision to Diff 431066.
rafauler added a comment.

Remove linker script to simplify test. Update comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125941/new/

https://reviews.llvm.org/D125941

Files:
  bolt/test/X86/Inputs/define_bar.s
  bolt/test/X86/dynrelocs.s


Index: bolt/test/X86/dynrelocs.s
===================================================================
--- /dev/null
+++ 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
Index: bolt/test/X86/Inputs/define_bar.s
===================================================================
--- /dev/null
+++ 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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D125941.431066.patch
Type: text/x-patch
Size: 3755 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220520/4556a444/attachment-0001.bin>


More information about the llvm-commits mailing list