From ac7595fdb1ee2aafecdd99cd8a3e56192639ada6 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 12 Dec 2023 13:32:43 -0800 Subject: 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 --- compiler/rustc_session/src/config.rs | 29 ++++++++++++++++++++++++++++- compiler/rustc_session/src/options.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_session') 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 { + 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 = (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 -- cgit 1.4.1-3-g733a5