-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[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
Conversation
@llvm/pr-subscribers-lld-elf @llvm/pr-subscribers-lld Author: Brad Smith (brad0) ChangesFull diff: https://github.com/llvm/llvm-project/pull/120005.diff 5 Files Affected:
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
|
There was a problem hiding this 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...
@@ -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) |
There was a problem hiding this comment.
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.
No description provided.