diff options
| author | Matthew Maurer <matthew.r.maurer@gmail.com> | 2023-12-12 13:32:43 -0800 |
|---|---|---|
| committer | Florian Schmiderer <florian.schmiderer@posteo.net> | 2024-06-25 18:21:42 +0200 |
| commit | ac7595fdb1ee2aafecdd99cd8a3e56192639ada6 (patch) | |
| tree | 4be37518dc4e5f5366b2920c90573749a75d3b0e /compiler/rustc_session | |
| parent | d929a42a664c026167800801b26d734db925314f (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.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 29 |
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 |
