[lld] [LLD][ELF][AArch64] Mark .plt and .iplt with PURECODE flag (PR #134798)

Csanád Hajdú via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 09:54:16 PDT 2025


https://github.com/Il-Capitano updated https://github.com/llvm/llvm-project/pull/134798

>From f8e78ec37398fe5c7755176d0cbfa64428124fe7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Mon, 24 Mar 2025 16:46:01 +0100
Subject: [PATCH 1/2] [LLD][ELF][AArch64] Mark .plt and .iplt with PURECODE
 flag

Mark the synthetic sections `.plt` and `.iplt` with the
`SHF_AARCH64_PURECODE` section flag, allowing them to be placed in an
executable-only segment.
---
 lld/ELF/SyntheticSections.cpp        | 10 ++++++++++
 lld/test/ELF/aarch64-gnu-ifunc-plt.s | 20 ++++++++++++++++++--
 lld/test/ELF/aarch64-plt.s           |  2 ++
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 3bb9815336a7c..88e2a369000e1 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2610,6 +2610,11 @@ PltSection::PltSection(Ctx &ctx)
   // modify the instructions in the PLT entries.
   if (ctx.arg.emachine == EM_SPARCV9)
     this->flags |= SHF_WRITE;
+
+  // On AArch64, PLT entries only do loads from the .got.plt section, so the
+  // .plt section can be marked with the SHF_AARCH64_PURECODE section flag.
+  if (ctx.arg.emachine == EM_AARCH64)
+    this->flags |= SHF_AARCH64_PURECODE;
 }
 
 void PltSection::writeTo(uint8_t *buf) {
@@ -2658,6 +2663,11 @@ IpltSection::IpltSection(Ctx &ctx)
     name = ".glink";
     addralign = 4;
   }
+
+  // On AArch64, PLT entries only do loads from the .got.plt section, so the
+  // .iplt section can be marked with the SHF_AARCH64_PURECODE section flag.
+  if (ctx.arg.emachine == EM_AARCH64)
+    this->flags |= SHF_AARCH64_PURECODE;
 }
 
 void IpltSection::writeTo(uint8_t *buf) {
diff --git a/lld/test/ELF/aarch64-gnu-ifunc-plt.s b/lld/test/ELF/aarch64-gnu-ifunc-plt.s
index bde6f1420540f..dfecb5c9e6ea1 100644
--- a/lld/test/ELF/aarch64-gnu-ifunc-plt.s
+++ b/lld/test/ELF/aarch64-gnu-ifunc-plt.s
@@ -5,7 +5,7 @@
 // RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %tout | FileCheck %s --check-prefix=DISASM
 // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
-// RUN: llvm-readobj --dynamic-table -r %tout | FileCheck %s
+// RUN: llvm-readobj --dynamic-table -r -S %tout | FileCheck %s
 
 // RUN: llvm-mc -filetype=obj -triple=aarch64_be %S/Inputs/shared2.s -o %t1.be.o
 // RUN: ld.lld %t1.be.o --shared --soname=t.so -o %t.be.so
@@ -13,7 +13,23 @@
 // RUN: ld.lld --hash-style=sysv %t.be.so %t.be.o -o %t.be
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t.be | FileCheck %s --check-prefix=DISASM
 // RUN: llvm-objdump -s %t.be | FileCheck %s --check-prefix=GOTPLT_BE
-// RUN: llvm-readobj --dynamic-table -r %t.be | FileCheck %s
+// RUN: llvm-readobj --dynamic-table -r -S %t.be | FileCheck %s
+
+// Check that the .iplt section has the SHF_AARCH64_PURECODE section flag set
+// CHECK:      Sections [
+// CHECK:        Name: .iplt
+// CHECK-NEXT:   Type: SHT_PROGBITS
+// CHECK-NEXT:   Flags [
+// CHECK-NEXT:     SHF_AARCH64_PURECODE
+// CHECK-NEXT:     SHF_ALLOC
+// CHECK-NEXT:     SHF_EXECINSTR
+// CHECK-NEXT:   ]
+// CHECK-NEXT:   Address: 0x210330
+// CHECK-NEXT:   Offset:
+// CHECK-NEXT:   Size: 32
+// CHECK-NEXT:   Link:
+// CHECK-NEXT:   Info:
+// CHECK-NEXT:   AddressAlignment: 16
 
 // Check that the PLTRELSZ tag does not include the IRELATIVE relocations
 // CHECK: DynamicSection [
diff --git a/lld/test/ELF/aarch64-plt.s b/lld/test/ELF/aarch64-plt.s
index 7d83a40dfc278..88e719484921b 100644
--- a/lld/test/ELF/aarch64-plt.s
+++ b/lld/test/ELF/aarch64-plt.s
@@ -14,6 +14,7 @@
 // CHECKDSO:     Name: .plt
 // CHECKDSO-NEXT:     Type: SHT_PROGBITS
 // CHECKDSO-NEXT:     Flags [
+// CHECKDSO-NEXT:       SHF_AARCH64_PURECODE
 // CHECKDSO-NEXT:       SHF_ALLOC
 // CHECKDSO-NEXT:       SHF_EXECINSTR
 // CHECKDSO-NEXT:     ]
@@ -109,6 +110,7 @@
 // CHECKEXE:     Name: .plt
 // CHECKEXE-NEXT:     Type: SHT_PROGBITS
 // CHECKEXE-NEXT:     Flags [
+// CHECKEXE-NEXT:       SHF_AARCH64_PURECODE
 // CHECKEXE-NEXT:       SHF_ALLOC
 // CHECKEXE-NEXT:       SHF_EXECINSTR
 // CHECKEXE-NEXT:     ]

>From 4fe2ab7b409ef998c3a500dba3b9e1f0b91a58ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Tue, 8 Apr 2025 18:47:11 +0200
Subject: [PATCH 2/2] Move EM_AARCH64 check to be alphabetically ordered

---
 lld/ELF/SyntheticSections.cpp | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 88e2a369000e1..196ecc4fee8c8 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2594,6 +2594,11 @@ PltSection::PltSection(Ctx &ctx)
     : SyntheticSection(ctx, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR,
                        16),
       headerSize(ctx.target->pltHeaderSize) {
+  // On AArch64, PLT entries only do loads from the .got.plt section, so the
+  // .plt section can be marked with the SHF_AARCH64_PURECODE section flag.
+  if (ctx.arg.emachine == EM_AARCH64)
+    this->flags |= SHF_AARCH64_PURECODE;
+
   // On PowerPC, this section contains lazy symbol resolvers.
   if (ctx.arg.emachine == EM_PPC64) {
     name = ".glink";
@@ -2610,11 +2615,6 @@ PltSection::PltSection(Ctx &ctx)
   // modify the instructions in the PLT entries.
   if (ctx.arg.emachine == EM_SPARCV9)
     this->flags |= SHF_WRITE;
-
-  // On AArch64, PLT entries only do loads from the .got.plt section, so the
-  // .plt section can be marked with the SHF_AARCH64_PURECODE section flag.
-  if (ctx.arg.emachine == EM_AARCH64)
-    this->flags |= SHF_AARCH64_PURECODE;
 }
 
 void PltSection::writeTo(uint8_t *buf) {
@@ -2659,15 +2659,15 @@ void PltSection::addSymbols() {
 IpltSection::IpltSection(Ctx &ctx)
     : SyntheticSection(ctx, ".iplt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR,
                        16) {
-  if (ctx.arg.emachine == EM_PPC || ctx.arg.emachine == EM_PPC64) {
-    name = ".glink";
-    addralign = 4;
-  }
-
   // On AArch64, PLT entries only do loads from the .got.plt section, so the
   // .iplt section can be marked with the SHF_AARCH64_PURECODE section flag.
   if (ctx.arg.emachine == EM_AARCH64)
     this->flags |= SHF_AARCH64_PURECODE;
+
+  if (ctx.arg.emachine == EM_PPC || ctx.arg.emachine == EM_PPC64) {
+    name = ".glink";
+    addralign = 4;
+  }
 }
 
 void IpltSection::writeTo(uint8_t *buf) {



More information about the llvm-commits mailing list