Skip to content

Commit 1498771

Browse files
committed
Updated code for changes to RFC, added additional error handling.
1 parent 6b2a26b commit 1498771

File tree

11 files changed

+86
-46
lines changed

11 files changed

+86
-46
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -469,24 +469,56 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
469469
}
470470
sym::patchable_function_entry => {
471471
codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| {
472-
let mut prefix = 0;
473-
let mut entry = 0;
472+
let mut prefix = None;
473+
let mut entry = None;
474474
for item in l {
475-
if let Some((sym, lit)) = item.name_value_literal() {
476-
let val = match lit.kind {
477-
// FIXME emit error if too many nops requested
478-
rustc_ast::LitKind::Int(i, _) => i as u8,
479-
_ => continue,
475+
let Some(metaitem) = item.meta_item() else {
476+
continue;
477+
};
478+
479+
let [single_segment] = &metaitem.path.segments[..] else {
480+
continue;
481+
};
482+
483+
let attrib_to_write = match single_segment.ident.name {
484+
sym::prefix_nops => &mut prefix,
485+
sym::entry_nops => &mut entry,
486+
_ => {
487+
tcx.dcx().span_err(metaitem.span, "Unexpected parameter.");
488+
continue;
489+
}
490+
};
491+
492+
if let Some(metaitem) =
493+
item.meta_item().map(|e| e.name_value_literal()).flatten()
494+
{
495+
let rustc_ast::LitKind::Int(val, _) = metaitem.kind else {
496+
tcx.dcx().span_err(
497+
metaitem.span,
498+
"Expected integer value between 0 and 255",
499+
);
500+
continue;
480501
};
481-
match sym {
482-
sym::prefix => prefix = val,
483-
sym::entry => entry = val,
484-
// FIXME possibly emit error here?
485-
_ => continue,
486-
}
502+
503+
let Ok(val) = val.get().try_into() else {
504+
tcx.dcx().span_err(
505+
metaitem.span,
506+
"Integer value outside range between 0 and 255.",
507+
);
508+
continue;
509+
};
510+
511+
*attrib_to_write = Some(val);
487512
}
488513
}
489-
Some(PatchableFunctionEntry::from_prefix_and_entry(prefix, entry))
514+
if let (None, None) = (prefix, entry) {
515+
tcx.dcx().span_err(attr.span, "Must specify at least one parameter.");
516+
}
517+
518+
Some(PatchableFunctionEntry::from_prefix_and_entry(
519+
prefix.unwrap_or(0),
520+
entry.unwrap_or(0),
521+
))
490522
})
491523
}
492524
_ => {}

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -527,11 +527,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
527527
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
528528
),
529529

530-
// FIXME RFC
531-
// `#[patchable_function_entry(prefix(n), entry(n))]`
530+
// RFC 3543
531+
// `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
532532
gated!(
533-
patchable_function_entry, Normal, template!(List: "prefix(n), entry(n)"), ErrorPreceding,
534-
experimental!(patchable_function_entry)
533+
patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding,
534+
EncodeCrossCrate::Yes, experimental!(patchable_function_entry)
535535
),
536536

537537
// ==========================================================================

compiler/rustc_feature/src/unstable.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,7 @@ declare_features! (
564564
/// Allows using `#[optimize(X)]`.
565565
(unstable, optimize_attribute, "1.34.0", Some(54882)),
566566
/// Allows specifying nop padding on functions for dynamic patching.
567-
// FIXME this needs an RFC #
568-
(unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(9999)),
567+
(unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(123115)),
569568
/// Allows postfix match `expr.match { ... }`
570569
(unstable, postfix_match, "1.79.0", Some(121618)),
571570
/// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args.

compiler/rustc_interface/src/tests.rs

Lines changed: 6 additions & 3 deletions
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;
@@ -813,7 +813,10 @@ fn test_unstable_options_tracking_hash() {
813813
tracked!(packed_bundled_libs, true);
814814
tracked!(panic_abort_tests, true);
815815
tracked!(panic_in_drop, PanicStrategy::Abort);
816-
tracked!(patchable_function_entry, PatchableFunctionEntry::from_nop_count_and_offset(3, 4));
816+
tracked!(
817+
patchable_function_entry,
818+
PatchableFunctionEntry::from_total_and_prefix_nops(10, 5).expect("total >= prefix")
819+
);
817820
tracked!(plt, Some(true));
818821
tracked!(polonius, Polonius::Legacy);
819822
tracked!(precise_enum_drop_elaboration, false);

compiler/rustc_session/src/config.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2933,8 +2933,9 @@ pub(crate) mod dep_tracking {
29332933
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn,
29342934
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
29352935
LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
2936-
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
2937-
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
2936+
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks,
2937+
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
2938+
WasiExecModel,
29382939
};
29392940
use crate::lint;
29402941
use crate::utils::NativeLib;
@@ -3231,11 +3232,14 @@ pub struct PatchableFunctionEntry {
32313232
}
32323233

32333234
impl PatchableFunctionEntry {
3234-
pub fn from_nop_count_and_offset(nop_count: u8, offset: u8) -> Option<PatchableFunctionEntry> {
3235-
if nop_count < offset {
3235+
pub fn from_total_and_prefix_nops(
3236+
total_nops: u8,
3237+
prefix_nops: u8,
3238+
) -> Option<PatchableFunctionEntry> {
3239+
if total_nops < prefix_nops {
32363240
None
32373241
} else {
3238-
Some(Self { prefix: offset, entry: nop_count - offset })
3242+
Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
32393243
}
32403244
}
32413245
pub fn prefix(&self) -> u8 {

compiler/rustc_session/src/options.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ mod desc {
380380
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
381381
pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
382382
pub const parse_patchable_function_entry: &str =
383-
"nop_count,entry_offset or nop_count (defaulting entry_offset=0)";
383+
"total_nops and optionally prefix_nops (defaulting prefix_nops=0)";
384384
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
385385
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
386386
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
@@ -712,7 +712,6 @@ mod parse {
712712
true
713713
}
714714

715-
716715
pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool {
717716
match v {
718717
// OnBrokenPipe::Default can't be explicitly specified
@@ -728,20 +727,22 @@ mod parse {
728727
slot: &mut PatchableFunctionEntry,
729728
v: Option<&str>,
730729
) -> bool {
731-
let mut nop_count = 0;
732-
let mut offset = 0;
730+
let mut total_nops = 0;
731+
let mut prefix_nops = 0;
733732

734-
if !parse_number(&mut nop_count, v) {
733+
if !parse_number(&mut total_nops, v) {
735734
let parts = v.and_then(|v| v.split_once(',')).unzip();
736-
if !parse_number(&mut nop_count, parts.0) {
735+
if !parse_number(&mut total_nops, parts.0) {
737736
return false;
738737
}
739-
if !parse_number(&mut offset, parts.1) {
738+
if !parse_number(&mut prefix_nops, parts.1) {
740739
return false;
741740
}
742741
}
743742

744-
if let Some(pfe) = PatchableFunctionEntry::from_nop_count_and_offset(nop_count, offset) {
743+
if let Some(pfe) =
744+
PatchableFunctionEntry::from_total_and_prefix_nops(total_nops, prefix_nops)
745+
{
745746
*slot = pfe;
746747
return true;
747748
}

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ symbols! {
758758
enable,
759759
encode,
760760
end,
761-
entry,
761+
entry_nops,
762762
enumerate_method,
763763
env,
764764
env_CFG_RELEASE: env!("CFG_RELEASE"),
@@ -1408,7 +1408,7 @@ symbols! {
14081408
prefetch_read_instruction,
14091409
prefetch_write_data,
14101410
prefetch_write_instruction,
1411-
prefix,
1411+
prefix_nops,
14121412
preg,
14131413
prelude,
14141414
prelude_import,

src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ N defaults to 0.
99

1010
As an illustrative example, `-Z patchable-function-entry=3,2` would produce:
1111

12-
```
12+
```text
1313
nop
1414
nop
1515
function_label:

tests/codegen/patchable-function-entry.rs

Lines changed: 3 additions & 3 deletions
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
Lines changed: 1 addition & 1 deletion
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

Lines changed: 4 additions & 3 deletions
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)