Skip to content

[LLD][ELF][AArch64] Mark .plt and .iplt with PURECODE flag #134798

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 17, 2025

Conversation

Il-Capitano
Copy link
Contributor

Mark the synthetic sections .plt and .iplt with the SHF_AARCH64_PURECODE section flag, allowing them to be placed in an executable-only segment.

Mark the synthetic sections `.plt` and `.iplt` with the
`SHF_AARCH64_PURECODE` section flag, allowing them to be placed in an
executable-only segment.
@llvmbot
Copy link
Member

llvmbot commented Apr 8, 2025

@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Csanád Hajdú (Il-Capitano)

Changes

Mark the synthetic sections .plt and .iplt with the SHF_AARCH64_PURECODE section flag, allowing them to be placed in an executable-only segment.


Full diff: https://github.com/llvm/llvm-project/pull/134798.diff

3 Files Affected:

  • (modified) lld/ELF/SyntheticSections.cpp (+10)
  • (modified) lld/test/ELF/aarch64-gnu-ifunc-plt.s (+18-2)
  • (modified) lld/test/ELF/aarch64-plt.s (+2)
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:     ]

@Il-Capitano
Copy link
Contributor Author

Thanks for the approval, I'll merge this once CI is all green.

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM on my side. I don't have any suggestions to add to MaskRay's.

@Il-Capitano Il-Capitano merged commit 10f75b8 into llvm:main Apr 17, 2025
11 checks passed
@Il-Capitano Il-Capitano deleted the execute-only-plt branch April 22, 2025 10:59
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Mark the synthetic sections `.plt` and `.iplt` with the
`SHF_AARCH64_PURECODE` section flag, allowing them to be placed in an
executable-only segment.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Mark the synthetic sections `.plt` and `.iplt` with the
`SHF_AARCH64_PURECODE` section flag, allowing them to be placed in an
executable-only segment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants