about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-07-16 21:46:21 +0000
committerbors <bors@rust-lang.org>2014-07-16 21:46:21 +0000
commitd3adccda4e0a90e4163c261d6b9ab4de7cfd0ccb (patch)
treede751d96f9a6b911890f0bc13ac3fc4ed3cbb0a5 /src
parent06c7ee9c56f7c768be94c89f699527b44be664ab (diff)
parent036b9e8e3e79b6454f8b6dc92b6a2490b3910dc5 (diff)
auto merge of #15696 : Zoxc/rust/redzone, r=alexcrichton
Disabling the redzone is required in x86-64's kernel mode to avoid interrupts trashing the stack.

I'm not sure if decl_fn is the right place to tag all functions with noredzone. It might have interactions with external functions when linking with bitcode built without -C no-redzone although I see no reason to do that.

I'm not sure how to write a test inspecting the bitcode output for noredzone attributes on all functions either.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/driver/config.rs2
-rw-r--r--src/librustc/middle/trans/base.rs8
2 files changed, 10 insertions, 0 deletions
diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs
index 345877d9ab6..3a59c2bbcc3 100644
--- a/src/librustc/driver/config.rs
+++ b/src/librustc/driver/config.rs
@@ -332,6 +332,8 @@ cgoptions!(
         "prefer dynamic linking to static linking"),
     no_integrated_as: bool = (false, parse_bool,
         "use an external assembler rather than LLVM's integrated one"),
+    no_redzone: bool = (false, parse_bool,
+        "disable the use of the redzone"),
     relocation_model: String = ("pic".to_string(), parse_string,
          "choose the relocation model to use (llc -relocation-model for details)"),
     metadata: Vec<String> = (Vec::new(), parse_list,
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 6bcc9b9b745..3ca188cf281 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -193,6 +193,14 @@ fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
         _ => {}
     }
 
+    if ccx.tcx.sess.opts.cg.no_redzone {
+        unsafe {
+            llvm::LLVMAddFunctionAttribute(llfn,
+                                           llvm::FunctionIndex as c_uint,
+                                           llvm::NoRedZoneAttribute as uint64_t)
+        }
+    }
+
     llvm::SetFunctionCallConv(llfn, cc);
     // Function addresses in Rust are never significant, allowing functions to be merged.
     llvm::SetUnnamedAddr(llfn, true);