[llvm] [Bolt] fix a wrong relocation update issue with weak references (PR #69136)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 01:08:58 PST 2023
https://github.com/linsinan1995 updated https://github.com/llvm/llvm-project/pull/69136
>From 4affa0779586d26e118b135bf42397e99bc8e0bd Mon Sep 17 00:00:00 2001
From: Sinan Lin <sinan.lin at linux.alibaba.com>
Date: Mon, 16 Oct 2023 09:51:48 +0800
Subject: [PATCH] [BOLT] do not search for PLT entries if the relocation is
against a weak reference symbol.
Take a common weak reference pattern for example
```
__attribute__((weak)) void undef_weak_fun();
if (&undef_weak_fun)
undef_weak_fun();
```
In this case, an undefined weak symbol `undef_weak_fun` has an address
of zero, and Bolt incorrectly changes the relocation for the
corresponding symbol to symbol at PLT, leading to incorrect runtime
behavior.
---
bolt/lib/Rewrite/RewriteInstance.cpp | 11 +-
.../AArch64/Inputs/weak-reference-symbol.yaml | 420 ++++++++++++++++++
.../AArch64/update-weak-reference-symbol.test | 40 ++
3 files changed, 470 insertions(+), 1 deletion(-)
create mode 100644 bolt/test/AArch64/Inputs/weak-reference-symbol.yaml
create mode 100644 bolt/test/AArch64/update-weak-reference-symbol.test
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 81c9cbff726bb9a..ea94d0d0a655160 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2067,6 +2067,14 @@ bool RewriteInstance::analyzeRelocation(
if (!Relocation::isSupported(RType))
return false;
+ auto IsWeakReference = [](const SymbolRef &Symbol) {
+ Expected<uint32_t> SymFlagsOrErr = Symbol.getFlags();
+ if (!SymFlagsOrErr)
+ return false;
+ return (*SymFlagsOrErr & SymbolRef::SF_Undefined) &&
+ (*SymFlagsOrErr & SymbolRef::SF_Weak);
+ };
+
const bool IsAArch64 = BC->isAArch64();
const size_t RelSize = Relocation::getSizeForType(RType);
@@ -2098,7 +2106,8 @@ bool RewriteInstance::analyzeRelocation(
// Section symbols are marked as ST_Debug.
IsSectionRelocation = (cantFail(Symbol.getType()) == SymbolRef::ST_Debug);
// Check for PLT entry registered with symbol name
- if (!SymbolAddress && (IsAArch64 || BC->isRISCV())) {
+ if (!SymbolAddress && !IsWeakReference(Symbol) &&
+ (IsAArch64 || BC->isRISCV())) {
const BinaryData *BD = BC->getPLTBinaryDataByName(SymbolName);
SymbolAddress = BD ? BD->getAddress() : 0;
}
diff --git a/bolt/test/AArch64/Inputs/weak-reference-symbol.yaml b/bolt/test/AArch64/Inputs/weak-reference-symbol.yaml
new file mode 100644
index 000000000000000..d66bdb89601a8e8
--- /dev/null
+++ b/bolt/test/AArch64/Inputs/weak-reference-symbol.yaml
@@ -0,0 +1,420 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_AARCH64
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .gnu.hash
+ LastSec: .eh_frame
+ Align: 0x10000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .bss
+ VAddr: 0x1FEA0
+ Align: 0x10000
+ Offset: 0xFEA0
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x1FEA0
+ Align: 0x8
+ Offset: 0xFEA0
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x360
+ Align: 0x4
+ Offset: 0x360
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x10
+ Offset: 0x0
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .dynamic
+ LastSec: .got
+ VAddr: 0x1FEA0
+ Offset: 0xFEA0
+Sections:
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x190
+ Link: .dynsym
+ AddressAlign: 0x8
+ Header:
+ SymNdx: 0x4
+ Shift2: 0x6
+ BloomFilter: [ 0x900400000000 ]
+ HashBuckets: [ 0x4, 0x0 ]
+ HashValues: [ 0xB88BBE2, 0xFE506B23 ]
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x1B8
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x248
+ AddressAlign: 0x1
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x260
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x350
+ Symbol: func_1
+ Type: R_AARCH64_ABS64
+ - Offset: 0x358
+ Symbol: func_2
+ Type: R_AARCH64_ABS64
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x290
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x20000
+ Symbol: func_2
+ Type: R_AARCH64_JUMP_SLOT
+ - Offset: 0x20008
+ Symbol: func_1
+ Type: R_AARCH64_JUMP_SLOT
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x2C0
+ AddressAlign: 0x10
+ Content: F07BBFA9F00000F011FE47F910E23F9120021FD61F2003D51F2003D51F2003D510010090110240F91002009120021FD610010090110640F91022009120021FD6
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x300
+ AddressAlign: 0x4
+ Content: FD7BBFA9FD0300910000009000400D91000040F91F0000F140000054F5FFFF970000009000600D91000040F91F0000F160000054EBFFFF971F2003D51F2003D5FD7BC1A8C0035FD61F2003D5C0035FD6
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x350
+ AddressAlign: 0x8
+ Content: '00000000000000000000000000000000'
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x360
+ AddressAlign: 0x4
+ Content: 011B033B1C00000002000000A0FFFFFF34000000E8FFFFFF58000000
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x380
+ AddressAlign: 0x8
+ Content: 1000000000000000017A520004781E011B0C1F00200000001800000064FFFFFF4800000000410E109D029E0150DEDD0E0000000000000000100000003C00000088FFFFFF0800000000000000
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x1FEA0
+ Link: .dynstr
+ AddressAlign: 0x8
+ Offset: 0xFEA0
+ Entries:
+ - Tag: DT_GNU_HASH
+ Value: 0x190
+ - Tag: DT_STRTAB
+ Value: 0x248
+ - Tag: DT_SYMTAB
+ Value: 0x1B8
+ - Tag: DT_STRSZ
+ Value: 0x13
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_PLTGOT
+ Value: 0x1FFE8
+ - Tag: DT_PLTRELSZ
+ Value: 0x30
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x290
+ - Tag: DT_RELA
+ Value: 0x260
+ - Tag: DT_RELASZ
+ Value: 0x30
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_TEXTREL
+ Value: 0x0
+ - Tag: DT_FLAGS
+ Value: 0x4
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x1FFE0
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: A0FE010000000000
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x1FFE8
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: 000000000000000000000000000000000000000000000000C002000000000000C002000000000000
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x20010
+ AddressAlign: 0x1
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x20010
+ AddressAlign: 0x1
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 4743433A2028474E55292031302E322E312032303230303832352028416C69626162612031302E322E312D332E3520322E33322900
+ - Name: .rela.text
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .text
+ Relocations:
+ - Offset: 0x308
+ Symbol: .rodata
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ - Offset: 0x30C
+ Symbol: .rodata
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ - Offset: 0x31C
+ Symbol: func_1
+ Type: R_AARCH64_CALL26
+ - Offset: 0x320
+ Symbol: .rodata
+ Type: R_AARCH64_ADR_PREL_PG_HI21
+ Addend: 8
+ - Offset: 0x324
+ Symbol: .rodata
+ Type: R_AARCH64_ADD_ABS_LO12_NC
+ Addend: 8
+ - Offset: 0x334
+ Symbol: func_2
+ Type: R_AARCH64_CALL26
+ - Name: .rela.rodata
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .rodata
+ Relocations:
+ - Offset: 0x350
+ Symbol: func_1
+ Type: R_AARCH64_ABS64
+ - Offset: 0x358
+ Symbol: func_2
+ Type: R_AARCH64_ABS64
+ - Name: .rela.eh_frame
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .eh_frame
+ Relocations:
+ - Offset: 0x39C
+ Symbol: .text
+ Type: R_AARCH64_PREL32
+ - Offset: 0x3C0
+ Symbol: .text
+ Type: R_AARCH64_PREL32
+ Addend: 72
+ - Type: SectionHeaderTable
+ Sections:
+ - Name: .gnu.hash
+ - Name: .dynsym
+ - Name: .dynstr
+ - Name: .rela.dyn
+ - Name: .rela.plt
+ - Name: .plt
+ - Name: .text
+ - Name: .rela.text
+ - Name: .rodata
+ - Name: .rela.rodata
+ - Name: .eh_frame_hdr
+ - Name: .eh_frame
+ - Name: .rela.eh_frame
+ - Name: .dynamic
+ - Name: .got
+ - Name: .got.plt
+ - Name: .data
+ - Name: .bss
+ - Name: .comment
+ - Name: .symtab
+ - Name: .strtab
+ - Name: .shstrtab
+Symbols:
+ - Name: .gnu.hash
+ Type: STT_SECTION
+ Section: .gnu.hash
+ Value: 0x190
+ - Name: .dynsym
+ Type: STT_SECTION
+ Section: .dynsym
+ Value: 0x1B8
+ - Name: .dynstr
+ Type: STT_SECTION
+ Section: .dynstr
+ Value: 0x248
+ - Name: .rela.dyn
+ Type: STT_SECTION
+ Section: .rela.dyn
+ Value: 0x260
+ - Name: .rela.plt
+ Type: STT_SECTION
+ Section: .rela.plt
+ Value: 0x290
+ - Name: .plt
+ Type: STT_SECTION
+ Section: .plt
+ Value: 0x2C0
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ Value: 0x300
+ - Name: .rodata
+ Type: STT_SECTION
+ Section: .rodata
+ Value: 0x350
+ - Name: .eh_frame_hdr
+ Type: STT_SECTION
+ Section: .eh_frame_hdr
+ Value: 0x360
+ - Name: .eh_frame
+ Type: STT_SECTION
+ Section: .eh_frame
+ Value: 0x380
+ - Name: .dynamic
+ Type: STT_SECTION
+ Section: .dynamic
+ Value: 0x1FEA0
+ - Name: .got
+ Type: STT_SECTION
+ Section: .got
+ Value: 0x1FFE0
+ - Name: .got.plt
+ Type: STT_SECTION
+ Section: .got.plt
+ Value: 0x1FFE8
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ Value: 0x20010
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ Value: 0x20010
+ - Name: .comment
+ Type: STT_SECTION
+ Section: .comment
+ - Name: test.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: '$x'
+ Section: .text
+ Value: 0x300
+ - Name: '$d'
+ Section: .rodata
+ Value: 0x350
+ - Name: '$d (1)'
+ Section: .eh_frame
+ Value: 0x394
+ - Name: test1.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: '$x (1)'
+ Section: .text
+ Value: 0x348
+ - Name: '$d (2)'
+ Section: .eh_frame
+ Value: 0x3B8
+ - Type: STT_FILE
+ Index: SHN_ABS
+ - Name: _DYNAMIC
+ Type: STT_OBJECT
+ Index: SHN_ABS
+ Value: 0x1FEA0
+ - Name: __GNU_EH_FRAME_HDR
+ Section: .eh_frame_hdr
+ Value: 0x360
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Type: STT_OBJECT
+ Index: SHN_ABS
+ Value: 0x1FFE0
+ - Name: '$x (2)'
+ Section: .plt
+ Value: 0x2C0
+ - Name: wow
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x300
+ Size: 0x48
+ - Name: func_2
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x348
+ Size: 0x8
+ - Name: func_1
+ Binding: STB_WEAK
+DynamicSymbols:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ Value: 0x300
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ Value: 0x20010
+ - Name: func_1
+ Binding: STB_WEAK
+ - Name: wow
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x300
+ Size: 0x48
+ - Name: func_2
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x348
+ Size: 0x8
+...
diff --git a/bolt/test/AArch64/update-weak-reference-symbol.test b/bolt/test/AArch64/update-weak-reference-symbol.test
new file mode 100644
index 000000000000000..d0b02cf3ee977f4
--- /dev/null
+++ b/bolt/test/AArch64/update-weak-reference-symbol.test
@@ -0,0 +1,40 @@
+// This test checks whether BOLT can correctly handle relocations against weak symbols.
+
+// RUN: yaml2obj %S/Inputs/weak-reference-symbol.yaml -o %t.so
+// RUN: llvm-bolt %t.so -o %t.so.bolt
+
+// RUN: llvm-nm -n %t.so.bolt > %t.out.txt
+// RUN: llvm-objdump -dj .rodata %t.so.bolt >> %t.out.txt
+// RUN: FileCheck %s --input-file=%t.out.txt
+
+# CHECK: w func_1
+# CHECK: {{0+}}[[#%x,ADDR:]] T func_2
+
+# CHECK: {{.*}} <.rodata>:
+# CHECK-NEXT: {{.*}} .word 0x00000000
+# CHECK-NEXT: {{.*}} .word 0x00000000
+# CHECK-NEXT: {{.*}} .word 0x{{[0]+}}[[#ADDR]]
+# CHECK-NEXT: {{.*}} .word 0x00000000
+
+// YAML is based in the following code:
+
+// File 1: test1.c
+__attribute__((weak)) void func_1();
+__attribute__((weak)) void func_2();
+
+void wow() {
+ if (&func_1)
+ func_1();
+ if (&func_2)
+ func_2();
+
+ return;
+}
+
+// File 2: test2.c
+void func_2() {}
+
+// with commands
+gcc -c test1.c -o test1.o
+gcc -c test1.c -o test2.o
+clang -no-pie -shared -nostartfiles -nostdlib -Wl,-q test1.o test2.o -o test
More information about the llvm-commits
mailing list