about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGreg V <greg@unrelenting.technology>2020-07-31 02:55:12 +0300
committerGreg V <greg@unrelenting.technology>2020-08-09 17:52:00 +0300
commitddbc45673b11f706e94fa17730eaa5c113f224d7 (patch)
treedbb045a5f104185487eb9927913306a966a22f9c
parent2f39477ecffb0dd3a08bf76bfb44aafcdb4aae6a (diff)
downloadrust-ddbc45673b11f706e94fa17730eaa5c113f224d7.tar.gz
rust-ddbc45673b11f706e94fa17730eaa5c113f224d7.zip
Add RUST_STD_FREEBSD_12_ABI env variable
Unfortunately, sanitizers do not support versioned symbols[1],
so they break filesystem access via the legacy, pre-ino64 ABI.

To use sanitizers on FreeBSD >= 12, we need to build the libc
crate with LIBC_CI=1 to use the new ABI -- including the libc
used for std. But that removes the st_lspare field std was
expecting for the deprecated metadata extension.

Add a way to skip that field to allow the build to work.

[1]: https://github.com/google/sanitizers/issues/628
-rw-r--r--library/std/build.rs3
-rw-r--r--library/std/src/os/freebsd/fs.rs14
2 files changed, 16 insertions, 1 deletions
diff --git a/library/std/build.rs b/library/std/build.rs
index 83073cc77dd..04bfed12153 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -16,6 +16,9 @@ fn main() {
     } else if target.contains("freebsd") {
         println!("cargo:rustc-link-lib=execinfo");
         println!("cargo:rustc-link-lib=pthread");
+        if env::var("RUST_STD_FREEBSD_12_ABI").is_ok() {
+            println!("cargo:rustc-cfg=freebsd12");
+        }
     } else if target.contains("netbsd") {
         println!("cargo:rustc-link-lib=pthread");
         println!("cargo:rustc-link-lib=rt");
diff --git a/library/std/src/os/freebsd/fs.rs b/library/std/src/os/freebsd/fs.rs
index 6798e0d8f44..fa440548050 100644
--- a/library/std/src/os/freebsd/fs.rs
+++ b/library/std/src/os/freebsd/fs.rs
@@ -74,7 +74,14 @@ pub trait MetadataExt {
 impl MetadataExt for Metadata {
     #[allow(deprecated)]
     fn as_raw_stat(&self) -> &raw::stat {
-        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
+        // The methods below use libc::stat, so they work fine when libc is built with FreeBSD 12 ABI.
+        // This method would just return nonsense.
+        #[cfg(freebsd12)]
+        panic!("as_raw_stat not supported with FreeBSD 12 ABI");
+        #[cfg(not(freebsd12))]
+        unsafe {
+            &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat)
+        }
     }
     fn st_dev(&self) -> u64 {
         self.as_inner().as_inner().st_dev as u64
@@ -136,6 +143,11 @@ impl MetadataExt for Metadata {
     fn st_flags(&self) -> u32 {
         self.as_inner().as_inner().st_flags as u32
     }
+    #[cfg(freebsd12)]
+    fn st_lspare(&self) -> u32 {
+        panic!("st_lspare not supported with FreeBSD 12 ABI");
+    }
+    #[cfg(not(freebsd12))]
     fn st_lspare(&self) -> u32 {
         self.as_inner().as_inner().st_lspare as u32
     }