From a0c2276ee7bd71a619f0f66c7a875cb8c54409ac Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 8 Feb 2021 11:48:54 +0100 Subject: [PATCH] Add a version marker This prevents deserializing a function with a different Cranelift version --- cranelift/codegen/src/ir/function.rs | 47 +++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/cranelift/codegen/src/ir/function.rs b/cranelift/codegen/src/ir/function.rs index f5dc7f916f..1b579e18a1 100644 --- a/cranelift/codegen/src/ir/function.rs +++ b/cranelift/codegen/src/ir/function.rs @@ -18,19 +18,63 @@ use crate::isa::{CallConv, EncInfo, Encoding, Legalize, TargetIsa}; use crate::regalloc::{EntryRegDiversions, RegDiversions}; use crate::value_label::ValueLabelsRanges; use crate::write::write_function; +#[cfg(feature = "enable-serde")] +use alloc::string::String; use alloc::vec::Vec; use core::fmt; +#[cfg(feature = "enable-serde")] +use serde::de::{Deserializer, Error}; +#[cfg(feature = "enable-serde")] +use serde::ser::Serializer; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -/// A function. +/// A version marker used to ensure that serialized clif ir is never deserialized with a +/// different version of Cranelift. +#[derive(Copy, Clone, Debug)] +pub struct VersionMarker; + +#[cfg(feature = "enable-serde")] +impl Serialize for VersionMarker { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + crate::VERSION.serialize(serializer) + } +} + +#[cfg(feature = "enable-serde")] +impl<'de> Deserialize<'de> for VersionMarker { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let version = String::deserialize(deserializer)?; + if version != crate::VERSION { + return Err(D::Error::custom(&format!( + "Expected a clif ir function for version {}, found one for version {}", + crate::VERSION, + version, + ))); + } + Ok(VersionMarker) + } +} + /// /// Functions can be cloned, but it is not a very fast operation. /// The clone will have all the same entity numbers as the original. #[derive(Clone)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct Function { + /// A version marker used to ensure that serialized clif ir is never deserialized with a + /// different version of Cranelift. + // Note: This must be the first field to ensure that Serde will deserialize it before + // attempting to deserialize other fields that are potentially changed between versions. + pub version_marker: VersionMarker, + /// Name of this function. Mostly used by `.clif` files. pub name: ExternalName, @@ -113,6 +157,7 @@ impl Function { /// Create a function with the given name and signature. pub fn with_name_signature(name: ExternalName, sig: Signature) -> Self { Self { + version_marker: VersionMarker, name, signature: sig, old_signature: None,