Skip to content

[ELF] Add support for PT_OPENBSD_NOBTCFI #120005

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 1 commit into from
Dec 20, 2024
Merged

[ELF] Add support for PT_OPENBSD_NOBTCFI #120005

merged 1 commit into from
Dec 20, 2024

Conversation

brad0
Copy link
Contributor

@brad0 brad0 commented Dec 15, 2024

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Dec 15, 2024

@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Brad Smith (brad0)

Changes

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

5 Files Affected:

  • (modified) lld/ELF/Config.h (+1)
  • (modified) lld/ELF/Driver.cpp (+1)
  • (modified) lld/ELF/Writer.cpp (+5)
  • (modified) lld/docs/ld.lld.1 (+5)
  • (modified) lld/test/ELF/openbsd-phdr.s (+7)
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 5b6b332cd597df..b2859486d58e93 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -363,6 +363,7 @@ struct Config {
   bool zInterpose;
   bool zKeepTextSectionPrefix;
   bool zLrodataAfterBss;
+  bool zNoBtCfi;
   bool zNodefaultlib;
   bool zNodelete;
   bool zNodlopen;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 9240f29d98d614..f573a8d3e19f3b 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1487,6 +1487,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
       args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
   ctx.arg.zLrodataAfterBss =
       getZFlag(args, "lrodata-after-bss", "nolrodata-after-bss", false);
+  ctx.arg.zNoBtCfi = hasZOption(args, "nobtcfi");
   ctx.arg.zNodefaultlib = hasZOption(args, "nodefaultlib");
   ctx.arg.zNodelete = hasZOption(args, "nodelete");
   ctx.arg.zNodlopen = hasZOption(args, "nodlopen");
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index d5581ca3e1c921..0ae871f231bec9 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2412,6 +2412,11 @@ Writer<ELFT>::createPhdrs(Partition &part) {
   if (ctx.arg.zWxneeded)
     addHdr(PT_OPENBSD_WXNEEDED, PF_X);
 
+  // PT_OPENBSD_NOBTCFI is an OpenBSD-specific header to mark that the
+  // executable is expected to violate branch-target CFI checks.
+  if (ctx.arg.zNoBtCfi)
+    addHdr(PT_OPENBSD_NOBTCFI, PF_X);
+
   if (OutputSection *cmd = findSection(ctx, ".note.gnu.property", partNo))
     addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd);
 
diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index 2fa6f64b2d2032..b28c6082f68b09 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -952,6 +952,11 @@ Let __start_/__stop_ references retain the associated C identifier name sections
 Do not allow relocations against read-only segments.
 This is the default.
 .Pp
+.It Cm nobtcfi
+Create a
+.Dv PT_OPENBSD_NOBTCFI
+segment.
+.Pp
 .It Cm wxneeded
 Create a
 .Dv PT_OPENBSD_WXNEEDED
diff --git a/lld/test/ELF/openbsd-phdr.s b/lld/test/ELF/openbsd-phdr.s
index 275f944511701e..097a499318a5bc 100644
--- a/lld/test/ELF/openbsd-phdr.s
+++ b/lld/test/ELF/openbsd-phdr.s
@@ -4,6 +4,10 @@
 # RUN: ld.lld randomdata.o -o randomdata
 # RUN: llvm-readelf -S -l randomdata | FileCheck %s --check-prefix=RANDOMDATA
 
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-openbsd /dev/null -o nobtcfi.o
+# RUN: ld.lld -z nobtcfi nobtcfi.o -o nobtcfi
+# RUN: llvm-readelf -l nobtcfi | FileCheck %s --check-prefix=NOBTCFI
+
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-openbsd /dev/null -o wxneeded.o
 # RUN: ld.lld -z wxneeded wxneeded.o -o wxneeded
 # RUN: llvm-readelf -l wxneeded | FileCheck %s --check-prefix=WXNEEDED
@@ -14,6 +18,9 @@
 # RANDOMDATA: Name                Type     Address            Off             Size   ES Flg Lk Inf Al
 # RANDOMDATA: .openbsd.randomdata PROGBITS [[ADDR:[0-9a-f]+]] [[O:[0-9a-f]+]] 000008 00   A  0   0  1
 
+# NOBTCFI:    Type              Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+# NOBTCFI:    OPENBSD_NOBTCFI   0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 E   0
+
 # WXNEEDED:   Type              Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
 # WXNEEDED:   OPENBSD_WXNEEDED  0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 E   0
 

@brad0 brad0 requested a review from MaskRay December 15, 2024 15:10
Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

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

I think this is fine... but it is not a good idea to keep introducing new PT_OPENBSD program headers...

@brad0 brad0 requested a review from MaskRay December 19, 2024 04:55
@brad0 brad0 merged commit 52574b5 into llvm:main Dec 20, 2024
9 checks passed
@brad0 brad0 deleted the lld_openbsd branch December 20, 2024 00:41
@@ -1897,6 +1897,9 @@ static void setConfigs(Ctx &ctx, opt::InputArgList &args) {
ErrAlways(ctx) << "cannot open --why-extract= file " << ctx.arg.whyExtract
<< ": " << e.message();
}

if (ctx.arg.osabi == ELFOSABI_OPENBSD)
Copy link
Member

@MaskRay MaskRay Dec 20, 2024

Choose a reason for hiding this comment

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

ld.lld -z nobtcfi empty.o has a false positive warning. Perhaps we need to move this variable back to readConfigs.

In driver.test, I use --implicit-check-not=warning: to catch such issues.

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.

3 participants