[lld] 92fbb60 - [lld][AArch64] Add BTI landing pad to PLT entries when the symbol is exported.

Daniel Kiss via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 29 13:17:22 PDT 2023


Author: Daniel Kiss
Date: 2023-06-29T22:17:17+02:00
New Revision: 92fbb602f3b635110417e40e2f774b31798b0b1d

URL: https://github.com/llvm/llvm-project/commit/92fbb602f3b635110417e40e2f774b31798b0b1d
DIFF: https://github.com/llvm/llvm-project/commit/92fbb602f3b635110417e40e2f774b31798b0b1d.diff

LOG: [lld][AArch64] Add BTI landing pad to PLT entries when the symbol is exported.

With relative vtables the caller jumps directly to the plt entries in the shared object,
therefore landing pad is need for these entries.

Reproducer:
main.cpp
```
#include "v.hpp"
int main() {
    A* a = new B();
    a->do_something2();
    return 0;
}
```
v.hpp
```
struct A {
    virtual void do_something() = 0;
    virtual void do_something2();
};
struct B : public A {
    void do_something() override;
    void do_something2() override;
};
```
v.cpp
```
#include "v.hpp"
void A::do_something2() { }
void B::do_something() { }
void B::do_something2() { }
```
```
CC="clang++ --target=aarch64-unknown-linux-gnu -fuse-ld=lld -mbranch-protection=bti"
F=-fexperimental-relative-c++-abi-vtables
${=CC} $F -shared v.cpp -o v.so -z force-bti
${=CC} $F main.cpp -L./ v.so -Wl,-rpath=. -z force-bti
qemu-aarch64-static -L /usr/aarch64-linux-gnu -cpu max ./a.out
```
For v.so, the regular vtable entry is relocated by an R_AARCH64_ABS64 relocation referencing _ZN1B13do_something2Ev.
```
_ZTV1B:
.xword  _ZN1B13do_something2Ev
```
Using relative vtable entry for a DSO has a downside of creating many PLT entries and making their addresses escape.
The relative vtable entry references a PLT entry _ZN1B13do_something2Ev at plt.
```
.L_ZTV1A.local:
        .word   (_ZN1A13do_something2Ev at PLT-.L_ZTV1A.local)-8
```

fixes: #63580

Reviewed By: peter.smith, MaskRay

Differential Revision: https://reviews.llvm.org/D153264

Added: 
    

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/test/ELF/aarch64-feature-bti.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 0301508fea2398..c83a159e3f0530 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -136,7 +136,9 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_CONDBR19:
   case R_AARCH64_JUMP26:
   case R_AARCH64_TSTBR14:
+    return R_PLT_PC;
   case R_AARCH64_PLT32:
+    const_cast<Symbol &>(s).thunkAccessed = true;
     return R_PLT_PC;
   case R_AARCH64_PREL16:
   case R_AARCH64_PREL32:
@@ -910,8 +912,9 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
 
   // NEEDS_COPY indicates a non-ifunc canonical PLT entry whose address may
   // escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its
-  // address may escape if referenced by a direct relocation. The condition is
-  // conservative.
+  // address may escape if referenced by a direct relocation. If relative
+  // vtables are used then if the vtable is in a shared object the offsets will
+  // be to the PLT entry. The condition is conservative.
   bool hasBti = btiHeader &&
                 (sym.hasFlag(NEEDS_COPY) || sym.isInIplt || sym.thunkAccessed);
   if (hasBti) {

diff  --git a/lld/test/ELF/aarch64-feature-bti.s b/lld/test/ELF/aarch64-feature-bti.s
index f364660351f28f..67291ad8670d97 100644
--- a/lld/test/ELF/aarch64-feature-bti.s
+++ b/lld/test/ELF/aarch64-feature-bti.s
@@ -1,6 +1,7 @@
 # REQUIRES: aarch64
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu --defsym CANONICAL_PLT=1 %s -o %tcanon.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu --defsym RELVTABLE_PLT=1 %s -o %trelvtable.o
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-bti1.s -o %t1.o
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3.s -o %t2.o
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-bti.s -o %t3.o
@@ -154,6 +155,42 @@
 # PIE-NEXT:           nop
 # PIE-NEXT:           nop
 
+## We expect the same for R_AARCH64_PLT32, as the address of an plt entry escapes
+# RUN: ld.lld --shared %trelvtable.o -o %trelv.exe
+# RUN: llvm-readelf -n %trelv.exe | FileCheck --check-prefix=BTIPROP %s
+# RUN: llvm-readelf --dynamic-table -n %trelv.exe | FileCheck --check-prefix=BTIPROP %s
+# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+bti --no-show-raw-insn %trelv.exe | FileCheck --check-prefix=RELV %s
+
+# RELV:       Disassembly of section .text:
+# RELV-LABEL: <func1>:
+# RELV-NEXT:    10380: bl     0x103b0 <func2 at plt>
+# RELV-NEXT:           bl      0x103c8 <funcRelVtable at plt>
+# RELV-NEXT:           ret
+# RELV:        Disassembly of section .plt:
+# RELV-LABEL:  <.plt>:
+# RELV-NEXT:    10390: bti    c
+# RELV-NEXT:           stp    x16, x30, [sp, #-16]!
+# RELV-NEXT:           adrp   x16, 0x30000
+# RELV-NEXT:           ldr    x17, [x16, #1200]
+# RELV-NEXT:           add    x16, x16, #1200
+# RELV-NEXT:           br     x17
+# RELV-NEXT:           nop
+# RELV-NEXT:           nop
+# RELV-LABEL: <func2 at plt>:
+# RELV-NEXT:    103b0: adrp   x16, 0x30000
+# RELV-NEXT:           ldr    x17, [x16, #1208]
+# RELV-NEXT:           add    x16, x16, #1208
+# RELV-NEXT:           br     x17
+# RELV-NEXT:           nop
+# RELV-NEXT:           nop
+# RELV-LABEL: <funcRelVtable at plt>:
+# RELV-NEXT:   103c8:  bti     c
+# RELV-NEXT:           adrp    x16, 0x30000 <_DYNAMIC+0xfc20>
+# RELV-NEXT:           ldr     x17, [x16, #1216]
+# RELV-NEXT:           add     x16, x16, #1216
+# RELV-NEXT:           br      x17
+# RELV-NEXT:           nop
+
 ## Build and executable with not all relocatable inputs having the BTI
 ## .note.property, expect no bti c and no .note.gnu.property entry
 
@@ -241,5 +278,13 @@ func1:
   add  x0, x0, :lo12:func2
 .else
   bl func2
+.endif
+.ifdef RELVTABLE_PLT
+  bl funcRelVtable
 .endif
   ret
+
+.ifdef RELVTABLE_PLT
+// R_AARCH64_PLT32
+.word funcRelVtable at PLT - .
+.endif


        


More information about the llvm-commits mailing list