about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2013-04-20 21:58:56 +1000
committerHuon Wilson <dbau.pp+github@gmail.com>2013-04-21 01:40:48 +1000
commit93c0888b6c6111c645d5aa2ef78da6fe8ab2c307 (patch)
treef3d3bd7827324a775411e17eec6908481205c355
parent4ff701b7db609cabe59832d47779832a16627b5f (diff)
downloadrust-93c0888b6c6111c645d5aa2ef78da6fe8ab2c307.tar.gz
rust-93c0888b6c6111c645d5aa2ef78da6fe8ab2c307.zip
librustc: implement and use `fixed_stack_segment` attribute for intrinsics.
-rw-r--r--src/libcore/unstable/intrinsics.rs13
-rw-r--r--src/librustc/middle/trans/foreign.rs6
-rw-r--r--src/librustc/middle/trans/monomorphize.rs2
3 files changed, 19 insertions, 2 deletions
diff --git a/src/libcore/unstable/intrinsics.rs b/src/libcore/unstable/intrinsics.rs
index ba96c6e5d30..a18ad173886 100644
--- a/src/libcore/unstable/intrinsics.rs
+++ b/src/libcore/unstable/intrinsics.rs
@@ -70,16 +70,28 @@ pub extern "rust-intrinsic" {
     pub fn powif32(a: f32, x: i32) -> f32;
     pub fn powif64(a: f64, x: i32) -> f64;
 
+    // the following kill the stack canary without
+    // `fixed_stack_segment`. This possibly only affects the f64
+    // variants, but it's hard to be sure since it seems to only
+    // occur with fairly specific arguments.
+    #[fixed_stack_segment]
     pub fn sinf32(x: f32) -> f32;
+    #[fixed_stack_segment]
     pub fn sinf64(x: f64) -> f64;
 
+    #[fixed_stack_segment]
     pub fn cosf32(x: f32) -> f32;
+    #[fixed_stack_segment]
     pub fn cosf64(x: f64) -> f64;
 
+    #[fixed_stack_segment]
     pub fn powf32(a: f32, x: f32) -> f32;
+    #[fixed_stack_segment]
     pub fn powf64(a: f64, x: f64) -> f64;
 
+    #[fixed_stack_segment]
     pub fn expf32(x: f32) -> f32;
+    #[fixed_stack_segment]
     pub fn expf64(x: f64) -> f64;
 
     pub fn exp2f32(x: f32) -> f32;
@@ -128,4 +140,3 @@ pub extern "rust-intrinsic" {
     pub fn bswap32(x: i32) -> i32;
     pub fn bswap64(x: i64) -> i64;
 }
-
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 854ec585d5c..956ee3bf144 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -546,6 +546,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
                        item: @ast::foreign_item,
                        path: ast_map::path,
                        substs: @param_substs,
+                       attributes: &[ast::attribute],
                        ref_id: Option<ast::node_id>) {
     debug!("trans_intrinsic(item.ident=%s)", *ccx.sess.str_of(item.ident));
 
@@ -561,6 +562,11 @@ pub fn trans_intrinsic(ccx: @CrateContext,
                                Some(copy substs),
                                Some(item.span));
 
+    // Set the fixed stack segment flag if necessary.
+    if attr::attrs_contains_name(attributes, "fixed_stack_segment") {
+        set_fixed_stack_segment(fcx.llfn);
+    }
+
     let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
     match *ccx.sess.str_of(item.ident) {
         ~"atomic_cxchg" => {
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index 9d63ac854a9..52ca8ec49bb 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -212,7 +212,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
       }
       ast_map::node_foreign_item(i, _, _, _) => {
           let d = mk_lldecl();
-          foreign::trans_intrinsic(ccx, d, i, pt, psubsts.get(),
+          foreign::trans_intrinsic(ccx, d, i, pt, psubsts.get(), i.attrs,
                                 ref_id);
           d
       }