diff options
Diffstat (limited to 'compiler/rustc_target/src/spec/mod.rs')
| -rw-r--r-- | compiler/rustc_target/src/spec/mod.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0771f998535..0d49c7f6ee8 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -712,6 +712,59 @@ impl ToJson for FramePointer { } } +/// Controls use of stack canaries. +#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)] +pub enum StackProtector { + /// Disable stack canary generation. + None, + + /// On LLVM, mark all generated LLVM functions with the `ssp` attribute (see + /// llvm/docs/LangRef.rst). This triggers stack canary generation in + /// functions which contain an array of a byte-sized type with more than + /// eight elements. + Basic, + + /// On LLVM, mark all generated LLVM functions with the `sspstrong` + /// attribute (see llvm/docs/LangRef.rst). This triggers stack canary + /// generation in functions which either contain an array, or which take + /// the address of a local variable. + Strong, + + /// Generate stack canaries in all functions. + All, +} + +impl StackProtector { + fn as_str(&self) -> &'static str { + match self { + StackProtector::None => "none", + StackProtector::Basic => "basic", + StackProtector::Strong => "strong", + StackProtector::All => "all", + } + } +} + +impl FromStr for StackProtector { + type Err = (); + + fn from_str(s: &str) -> Result<StackProtector, ()> { + Ok(match s { + "none" => StackProtector::None, + "basic" => StackProtector::Basic, + "strong" => StackProtector::Strong, + "all" => StackProtector::All, + _ => return Err(()), + }) + } +} + +impl fmt::Display for StackProtector { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + macro_rules! supported_targets { ( $(($( $triple:literal, )+ $module:ident ),)+ ) => { $(mod $module;)+ @@ -1360,6 +1413,10 @@ pub struct TargetOptions { /// Whether or not the DWARF `.debug_aranges` section should be generated. pub generate_arange_section: bool, + + /// Whether the target supports stack canary checks. `true` by default, + /// since this is most common among tier 1 and tier 2 targets. + pub supports_stack_protector: bool, } impl Default for TargetOptions { @@ -1466,6 +1523,7 @@ impl Default for TargetOptions { default_adjusted_cabi: None, c_enum_min_bits: 32, generate_arange_section: true, + supports_stack_protector: true, } } } @@ -2052,6 +2110,7 @@ impl Target { key!(default_adjusted_cabi, Option<Abi>)?; key!(c_enum_min_bits, u64); key!(generate_arange_section, bool); + key!(supports_stack_protector, bool); if base.is_builtin { // This can cause unfortunate ICEs later down the line. @@ -2292,6 +2351,7 @@ impl ToJson for Target { target_option_val!(supported_sanitizers); target_option_val!(c_enum_min_bits); target_option_val!(generate_arange_section); + target_option_val!(supports_stack_protector); if let Some(abi) = self.default_adjusted_cabi { d.insert("default-adjusted-cabi".to_string(), Abi::name(abi).to_json()); |
