about summary refs log tree commit diff
path: root/src/librustc_trans
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-06-21 12:08:18 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-07-06 08:58:19 -0700
commit5dbd97de3d825c6898df62baca33ff1f57cb77eb (patch)
tree58b555b75d77d30358f257b93e0e6ceda8cf30ee /src/librustc_trans
parent8cab2c73d47a4b0ec7dc1bf40eb59492139fb707 (diff)
downloadrust-5dbd97de3d825c6898df62baca33ff1f57cb77eb.tar.gz
rust-5dbd97de3d825c6898df62baca33ff1f57cb77eb.zip
rustc: Implement stack probes for x86
This commit implements stack probes on x86/x86_64 using the freshly landed
support upstream in LLVM. The purpose of stack probes here are to guarantee a
segfault on stack overflow rather than having a chance of running over the guard
page already present on all threads by accident.

At this time there's no support for any other architecture because LLVM itself
does not have support for other architectures.
Diffstat (limited to 'src/librustc_trans')
-rw-r--r--src/librustc_trans/attributes.rs26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs
index fa93c005dcd..cbad43066e4 100644
--- a/src/librustc_trans/attributes.rs
+++ b/src/librustc_trans/attributes.rs
@@ -11,13 +11,14 @@
 
 use std::ffi::{CStr, CString};
 
+use rustc::session::config::Sanitizer;
+
 use llvm::{self, Attribute, ValueRef};
 use llvm::AttributePlace::Function;
 pub use syntax::attr::{self, InlineAttr};
 use syntax::ast;
 use context::CrateContext;
 
-
 /// Mark LLVM function to use provided inline heuristic.
 #[inline]
 pub fn inline(val: ValueRef, inline: InlineAttr) {
@@ -69,6 +70,28 @@ pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) {
     }
 }
 
+pub fn set_probestack(ccx: &CrateContext, llfn: ValueRef) {
+    // Only use stack probes if the target specification indicates that we
+    // should be using stack probes
+    if !ccx.sess().target.target.options.stack_probes {
+        return
+    }
+
+    // Currently stack probes seem somewhat incompatible with the address
+    // sanitizer. With asan we're already protected from stack overflow anyway
+    // so we don't really need stack probes regardless.
+    match ccx.sess().opts.debugging_opts.sanitizer {
+        Some(Sanitizer::Address) => return,
+        _ => {}
+    }
+
+    // Flag our internal `__rust_probestack` function as the stack probe symbol.
+    // This is defined in the `compiler-builtins` crate for each architecture.
+    llvm::AddFunctionAttrStringValue(
+        llfn, llvm::AttributePlace::Function,
+        cstr("probe-stack\0"), cstr("__rust_probestack\0"));
+}
+
 /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
 /// attributes.
 pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
@@ -76,6 +99,7 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
     inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));
 
     set_frame_pointer_elimination(ccx, llfn);
+    set_probestack(ccx, llfn);
     let mut target_features = vec![];
     for attr in attrs {
         if attr.check_name("target_feature") {