[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