about summary refs log tree commit diff
path: root/compiler/rustc_session
diff options
context:
space:
mode:
authorMatthew Maurer <matthew.r.maurer@gmail.com>2023-12-12 13:32:43 -0800
committerFlorian Schmiderer <florian.schmiderer@posteo.net>2024-06-25 18:21:42 +0200
commitac7595fdb1ee2aafecdd99cd8a3e56192639ada6 (patch)
tree4be37518dc4e5f5366b2920c90573749a75d3b0e /compiler/rustc_session
parentd929a42a664c026167800801b26d734db925314f (diff)
Support for -Z patchable-function-entry
`-Z patchable-function-entry` works like `-fpatchable-function-entry`
on clang/gcc. The arguments are total nop count and function offset.

See MCP rust-lang/compiler-team#704
Diffstat (limited to 'compiler/rustc_session')
-rw-r--r--compiler/rustc_session/src/config.rs29
-rw-r--r--compiler/rustc_session/src/options.rs29
2 files changed, 57 insertions, 1 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 839cc51efce..2534152267e 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2963,7 +2963,7 @@ pub(crate) mod dep_tracking {
         CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn,
         InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
         LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
-        Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
+        PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
         SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
     };
     use crate::lint;
@@ -3071,6 +3071,7 @@ pub(crate) mod dep_tracking {
         OomStrategy,
         LanguageIdentifier,
         NextSolverConfig,
+        PatchableFunctionEntry,
         Polonius,
         InliningThreshold,
         FunctionReturn,
@@ -3248,6 +3249,32 @@ impl DumpMonoStatsFormat {
     }
 }
 
+/// `-Z patchable-function-entry` representation - how many nops to put before and after function
+/// entry.
+#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
+pub struct PatchableFunctionEntry {
+    /// Nops before the entry
+    prefix: u8,
+    /// Nops after the entry
+    entry: u8,
+}
+
+impl PatchableFunctionEntry {
+    pub fn from_nop_count_and_offset(nop_count: u8, offset: u8) -> Option<PatchableFunctionEntry> {
+        if nop_count < offset {
+            None
+        } else {
+            Some(Self { prefix: offset, entry: nop_count - offset })
+        }
+    }
+    pub fn prefix(&self) -> u8 {
+        self.prefix
+    }
+    pub fn entry(&self) -> u8 {
+        self.entry
+    }
+}
+
 /// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
 /// or future prototype.
 #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 9a10adeb6d1..f4f8a16662d 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -379,6 +379,8 @@ mod desc {
     pub const parse_passes: &str = "a space-separated list of passes, or `all`";
     pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
     pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
+    pub const parse_patchable_function_entry: &str =
+        "nop_count,entry_offset or nop_count (defaulting entry_offset=0)";
     pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
     pub const parse_oom_strategy: &str = "either `panic` or `abort`";
     pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
@@ -723,6 +725,7 @@ mod parse {
         true
     }
 
+
     pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool {
         match v {
             // OnBrokenPipe::Default can't be explicitly specified
@@ -734,6 +737,30 @@ mod parse {
         true
     }
 
+    pub(crate) fn parse_patchable_function_entry(
+        slot: &mut PatchableFunctionEntry,
+        v: Option<&str>,
+    ) -> bool {
+        let mut nop_count = 0;
+        let mut offset = 0;
+
+        if !parse_number(&mut nop_count, v) {
+            let parts = v.and_then(|v| v.split_once(',')).unzip();
+            if !parse_number(&mut nop_count, parts.0) {
+                return false;
+            }
+            if !parse_number(&mut offset, parts.1) {
+                return false;
+            }
+        }
+
+        if let Some(pfe) = PatchableFunctionEntry::from_nop_count_and_offset(nop_count, offset) {
+            *slot = pfe;
+            return true;
+        }
+        false
+    }
+
     pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool {
         match v {
             Some("panic") => *slot = OomStrategy::Panic,
@@ -1859,6 +1886,8 @@ options! {
         "panic strategy for panics in drops"),
     parse_only: bool = (false, parse_bool, [UNTRACKED],
         "parse only; do not compile, assemble, or link (default: no)"),
+    patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED],
+        "nop padding at function entry"),
     plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "whether to use the PLT when calling into shared libraries;
         only has effect for PIC code on systems with ELF binaries