Skip to content

Commit b093958

Browse files
committed
Updated code for changes to RFC, added additional error handling
1 parent 5642202 commit b093958

File tree

10 files changed

+85
-48
lines changed

10 files changed

+85
-48
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+46-14
Original file line numberDiff line numberDiff line change
@@ -457,24 +457,56 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
457457
}
458458
sym::patchable_function_entry => {
459459
codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| {
460-
let mut prefix = 0;
461-
let mut entry = 0;
460+
let mut prefix = None;
461+
let mut entry = None;
462462
for item in l {
463-
if let Some((sym, lit)) = item.name_value_literal() {
464-
let val = match lit.kind {
465-
// FIXME emit error if too many nops requested
466-
rustc_ast::LitKind::Int(i, _) => i as u8,
467-
_ => continue,
463+
let Some(metaitem) = item.meta_item() else {
464+
continue;
465+
};
466+
467+
let [single_segment] = &metaitem.path.segments[..] else {
468+
continue;
469+
};
470+
471+
let attrib_to_write = match single_segment.ident.name {
472+
sym::prefix_nops => &mut prefix,
473+
sym::entry_nops => &mut entry,
474+
_ => {
475+
tcx.dcx().span_err(metaitem.span, "Unexpected parameter.");
476+
continue;
477+
}
478+
};
479+
480+
if let Some(metaitem) =
481+
item.meta_item().map(|e| e.name_value_literal()).flatten()
482+
{
483+
let rustc_ast::LitKind::Int(val, _) = metaitem.kind else {
484+
tcx.dcx().span_err(
485+
metaitem.span,
486+
"Expected integer value between 0 and 255",
487+
);
488+
continue;
468489
};
469-
match sym {
470-
sym::prefix => prefix = val,
471-
sym::entry => entry = val,
472-
// FIXME possibly emit error here?
473-
_ => continue,
474-
}
490+
491+
let Ok(val) = val.get().try_into() else {
492+
tcx.dcx().span_err(
493+
metaitem.span,
494+
"Integer value outside range between 0 and 255.",
495+
);
496+
continue;
497+
};
498+
499+
*attrib_to_write = Some(val);
475500
}
476501
}
477-
Some(PatchableFunctionEntry::from_prefix_and_entry(prefix, entry))
502+
if let (None, None) = (prefix, entry) {
503+
tcx.dcx().span_err(attr.span, "Must specify at least one parameter.");
504+
}
505+
506+
Some(PatchableFunctionEntry::from_prefix_and_entry(
507+
prefix.unwrap_or(0),
508+
entry.unwrap_or(0),
509+
))
478510
})
479511
}
480512
_ => {}

compiler/rustc_feature/src/builtin_attrs.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
533533
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
534534
),
535535

536-
// FIXME RFC
537-
// `#[patchable_function_entry(prefix(n), entry(n))]`
536+
// RFC 3543
537+
// `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
538538
gated!(
539-
patchable_function_entry, Normal, template!(List: "prefix(n), entry(n)"), ErrorPreceding,
540-
experimental!(patchable_function_entry)
539+
patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding,
540+
EncodeCrossCrate::Yes, experimental!(patchable_function_entry)
541541
),
542542

543543
// ==========================================================================

compiler/rustc_feature/src/unstable.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,7 @@ declare_features! (
562562
/// Allows using `#[optimize(X)]`.
563563
(unstable, optimize_attribute, "1.34.0", Some(54882)),
564564
/// Allows specifying nop padding on functions for dynamic patching.
565-
// FIXME this needs an RFC #
566-
(unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(9999)),
565+
(unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(123115)),
567566
/// Allows postfix match `expr.match { ... }`
568567
(unstable, postfix_match, "1.79.0", Some(121618)),
569568
/// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args.

compiler/rustc_interface/src/tests.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use rustc_session::config::{
88
ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold,
99
Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail,
1010
LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey,
11-
PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
12-
SymbolManglingVersion, WasiExecModel,
11+
PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
12+
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
1313
};
1414
use rustc_session::lint::Level;
1515
use rustc_session::search_paths::SearchPath;
@@ -815,7 +815,10 @@ fn test_unstable_options_tracking_hash() {
815815
tracked!(packed_bundled_libs, true);
816816
tracked!(panic_abort_tests, true);
817817
tracked!(panic_in_drop, PanicStrategy::Abort);
818-
tracked!(patchable_function_entry, PatchableFunctionEntry::from_nop_count_and_offset(3, 4));
818+
tracked!(
819+
patchable_function_entry,
820+
PatchableFunctionEntry::from_total_and_prefix_nops(10, 5).expect("total >= prefix")
821+
);
819822
tracked!(plt, Some(true));
820823
tracked!(polonius, Polonius::Legacy);
821824
tracked!(precise_enum_drop_elaboration, false);

compiler/rustc_session/src/config.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -2898,8 +2898,9 @@ pub(crate) mod dep_tracking {
28982898
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn,
28992899
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
29002900
LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
2901-
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
2902-
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
2901+
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks,
2902+
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
2903+
WasiExecModel,
29032904
};
29042905
use crate::lint;
29052906
use crate::utils::NativeLib;
@@ -3196,11 +3197,14 @@ pub struct PatchableFunctionEntry {
31963197
}
31973198

31983199
impl PatchableFunctionEntry {
3199-
pub fn from_nop_count_and_offset(nop_count: u8, offset: u8) -> Option<PatchableFunctionEntry> {
3200-
if nop_count < offset {
3200+
pub fn from_total_and_prefix_nops(
3201+
total_nops: u8,
3202+
prefix_nops: u8,
3203+
) -> Option<PatchableFunctionEntry> {
3204+
if total_nops < prefix_nops {
32013205
None
32023206
} else {
3203-
Some(Self { prefix: offset, entry: nop_count - offset })
3207+
Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
32043208
}
32053209
}
32063210
pub fn prefix(&self) -> u8 {

compiler/rustc_session/src/options.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -378,12 +378,9 @@ mod desc {
378378
pub const parse_time_passes_format: &str = "`text` (default) or `json`";
379379
pub const parse_passes: &str = "a space-separated list of passes, or `all`";
380380
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
381-
<<<<<<< HEAD
382381
pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
383-
=======
384382
pub const parse_patchable_function_entry: &str =
385-
"nop_count,entry_offset or nop_count (defaulting entry_offset=0)";
386-
>>>>>>> 7814dd86eb5 (Support for -Z patchable-function-entry)
383+
"total_nops and optionally prefix_nops (defaulting prefix_nops=0)";
387384
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
388385
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
389386
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
@@ -714,7 +711,6 @@ mod parse {
714711
true
715712
}
716713

717-
718714
pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool {
719715
match v {
720716
// OnBrokenPipe::Default can't be explicitly specified
@@ -730,20 +726,22 @@ mod parse {
730726
slot: &mut PatchableFunctionEntry,
731727
v: Option<&str>,
732728
) -> bool {
733-
let mut nop_count = 0;
734-
let mut offset = 0;
729+
let mut total_nops = 0;
730+
let mut prefix_nops = 0;
735731

736-
if !parse_number(&mut nop_count, v) {
732+
if !parse_number(&mut total_nops, v) {
737733
let parts = v.and_then(|v| v.split_once(',')).unzip();
738-
if !parse_number(&mut nop_count, parts.0) {
734+
if !parse_number(&mut total_nops, parts.0) {
739735
return false;
740736
}
741-
if !parse_number(&mut offset, parts.1) {
737+
if !parse_number(&mut prefix_nops, parts.1) {
742738
return false;
743739
}
744740
}
745741

746-
if let Some(pfe) = PatchableFunctionEntry::from_nop_count_and_offset(nop_count, offset) {
742+
if let Some(pfe) =
743+
PatchableFunctionEntry::from_total_and_prefix_nops(total_nops, prefix_nops)
744+
{
747745
*slot = pfe;
748746
return true;
749747
}

compiler/rustc_span/src/symbol.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ symbols! {
754754
enable,
755755
encode,
756756
end,
757-
entry,
757+
entry_nops,
758758
enumerate_method,
759759
env,
760760
env_CFG_RELEASE: env!("CFG_RELEASE"),
@@ -1399,7 +1399,7 @@ symbols! {
13991399
prefetch_read_instruction,
14001400
prefetch_write_data,
14011401
prefetch_write_instruction,
1402-
prefix,
1402+
prefix_nops,
14031403
preg,
14041404
prelude,
14051405
prelude_import,

tests/codegen/patchable-function-entry.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![feature(patchable_function_entry)]
2-
// compile-flags: -Z patchable-function-entry=15,10
2+
//@ compile-flags: -Z patchable-function-entry=15,10
33

44
#![crate_type = "lib"]
55

@@ -9,12 +9,12 @@ pub fn foo() {}
99

1010
// The attribute should override the compile flags
1111
#[no_mangle]
12-
#[patchable_function_entry(prefix(1), entry(2))]
12+
#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)]
1313
pub fn bar() {}
1414

1515
// If we override an attribute to 0 or unset, the attribute should go away
1616
#[no_mangle]
17-
#[patchable_function_entry(entry(0))]
17+
#[patchable_function_entry(entry_nops = 0)]
1818
pub fn baz() {}
1919

2020
// CHECK: @foo() unnamed_addr #0
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
#[patchable_function_entry(entry(1), prefix(1))]
1+
#[patchable_function_entry(prefix_nops = 1, entry_nops = 1)]
22
//~^ ERROR: the `#[patchable_function_entry]` attribute is an experimental feature
33
fn main() {}

tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
error[E0658]: the `#[patchable_function_entry]` attribute is an experimental feature
22
--> $DIR/feature-gate-patchable-function-entry.rs:1:1
33
|
4-
LL | #[patchable_function_entry(entry(1), prefix(1))]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | #[patchable_function_entry(prefix_nops = 1, entry_nops = 1)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: see issue #9999 <https://github.com/rust-lang/rust/issues/9999> for more information
7+
= note: see issue #123115 <https://github.com/rust-lang/rust/issues/123115> for more information
88
= help: add `#![feature(patchable_function_entry)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
910

1011
error: aborting due to 1 previous error
1112

0 commit comments

Comments
 (0)