about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorAlan Somers <asomers@gmail.com>2016-04-04 14:18:44 +0000
committerAlan Somers <asomers@gmail.com>2016-04-04 14:18:44 +0000
commitabc3777c06abced90b415b920082a4814d9051d7 (patch)
treee37936a936b551038f3f5b8c3b4e21605ae9f227 /src/libstd/sys
parentbbe8e3502c8c67d9f17d56764031ff3b28206935 (diff)
downloadrust-abc3777c06abced90b415b920082a4814d9051d7.tar.gz
rust-abc3777c06abced90b415b920082a4814d9051d7.zip
Fix stack overflow detection on FreeBSD
src/libstd/sys/unix/thread.rs
	Implement several stack-related functions on FreeBSD

src/libstd/sys/unix/stack_overflow.rs
	Fix a comment
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs2
-rw-r--r--src/libstd/sys/unix/thread.rs45
2 files changed, 45 insertions, 2 deletions
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 1553aba35a2..22d47ba0f62 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -64,7 +64,7 @@ mod imp {
     unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
         #[repr(C)]
         struct siginfo_t {
-            a: [libc::c_int; 3], // si_signo, si_code, si_errno,
+            a: [libc::c_int; 3], // si_signo, si_errno, si_code
             si_addr: *mut libc::c_void,
         }
 
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 6d966a0f694..0f238d5c11c 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -164,6 +164,7 @@ impl Drop for Thread {
 }
 
 #[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
+          not(target_os = "freebsd"),
           not(target_os = "macos"),
           not(target_os = "bitrig"),
           not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
@@ -177,6 +178,7 @@ pub mod guard {
 
 
 #[cfg(any(all(target_os = "linux", not(target_env = "musl")),
+          target_os = "freebsd",
           target_os = "macos",
           target_os = "bitrig",
           all(target_os = "netbsd", not(target_vendor = "rumprun")),
@@ -199,6 +201,22 @@ pub mod guard {
         current().map(|s| s as *mut libc::c_void)
     }
 
+    #[cfg(target_os = "freebsd")]
+    unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
+        let mut ret = None;
+        let mut attr: libc::pthread_attr_t = ::mem::zeroed();
+        assert_eq!(libc::pthread_attr_init(&mut attr), 0);
+        if libc::pthread_attr_get_np(libc::pthread_self(), &mut attr) == 0 {
+            let mut stackaddr = ::ptr::null_mut();
+            let mut stacksize = 0;
+            assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
+                                                   &mut stacksize), 0);
+            ret = Some(stackaddr);
+        }
+        assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+        ret
+    }
+
     #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         let mut ret = None;
@@ -248,7 +266,11 @@ pub mod guard {
             panic!("failed to allocate a guard page");
         }
 
-        let offset = if cfg!(target_os = "linux") {2} else {1};
+        let offset = if cfg!(any(target_os = "linux", target_os = "freebsd")) {
+            2
+        } else {
+            1
+        };
 
         Some(stackaddr as usize + offset * psize)
     }
@@ -282,6 +304,27 @@ pub mod guard {
         })
     }
 
+    #[cfg(target_os = "freebsd")]
+    pub unsafe fn current() -> Option<usize> {
+        let mut ret = None;
+        let mut attr: libc::pthread_attr_t = ::mem::zeroed();
+        assert_eq!(libc::pthread_attr_init(&mut attr), 0);
+        if libc::pthread_attr_get_np(libc::pthread_self(), &mut attr) == 0 {
+            let mut guardsize = 0;
+            assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
+            if guardsize == 0 {
+                panic!("there is no guard page");
+            }
+            let mut stackaddr = ::ptr::null_mut();
+            let mut size = 0;
+            assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
+                                                   &mut size), 0);
+            ret = Some(stackaddr as usize - guardsize as usize);
+        }
+        assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+        ret
+    }
+
     #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
     pub unsafe fn current() -> Option<usize> {
         let mut ret = None;