about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_back/target/apple_base.rs1
-rw-r--r--src/librustc_back/target/bitrig_base.rs1
-rw-r--r--src/librustc_back/target/dragonfly_base.rs1
-rw-r--r--src/librustc_back/target/freebsd_base.rs1
-rw-r--r--src/librustc_back/target/netbsd_base.rs1
-rw-r--r--src/librustc_back/target/openbsd_base.rs1
-rw-r--r--src/librustc_llvm/archive_ro.rs3
-rw-r--r--src/librustc_llvm/lib.rs12
-rw-r--r--src/librustc_trans/back/archive.rs29
-rw-r--r--src/rustllvm/ArchiveWrapper.cpp17
10 files changed, 52 insertions, 15 deletions
diff --git a/src/librustc_back/target/apple_base.rs b/src/librustc_back/target/apple_base.rs
index 795a2c18bc6..f34ba40a8b2 100644
--- a/src/librustc_back/target/apple_base.rs
+++ b/src/librustc_back/target/apple_base.rs
@@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions {
         has_rpath: true,
         dll_prefix: "lib".to_string(),
         dll_suffix: ".dylib".to_string(),
+        archive_format: "bsd".to_string(),
         pre_link_args: Vec::new(),
         .. Default::default()
     }
diff --git a/src/librustc_back/target/bitrig_base.rs b/src/librustc_back/target/bitrig_base.rs
index 6e5a48c0ea1..9f6a1f1e530 100644
--- a/src/librustc_back/target/bitrig_base.rs
+++ b/src/librustc_back/target/bitrig_base.rs
@@ -22,6 +22,7 @@ pub fn opts() -> TargetOptions {
         position_independent_executables: true,
         pre_link_args: vec!(
         ),
+        archive_format: "bsd".to_string(),
 
         .. Default::default()
     }
diff --git a/src/librustc_back/target/dragonfly_base.rs b/src/librustc_back/target/dragonfly_base.rs
index a56621ff97e..51a371db724 100644
--- a/src/librustc_back/target/dragonfly_base.rs
+++ b/src/librustc_back/target/dragonfly_base.rs
@@ -29,6 +29,7 @@ pub fn opts() -> TargetOptions {
             "-Wl,--as-needed".to_string(),
         ),
         position_independent_executables: true,
+        archive_format: "bsd".to_string(),
         .. Default::default()
     }
 }
diff --git a/src/librustc_back/target/freebsd_base.rs b/src/librustc_back/target/freebsd_base.rs
index 3ec6307c72f..2c3d240dbf3 100644
--- a/src/librustc_back/target/freebsd_base.rs
+++ b/src/librustc_back/target/freebsd_base.rs
@@ -18,6 +18,7 @@ pub fn opts() -> TargetOptions {
         executables: true,
         morestack: true,
         has_rpath: true,
+        archive_format: "bsd".to_string(),
 
         .. Default::default()
     }
diff --git a/src/librustc_back/target/netbsd_base.rs b/src/librustc_back/target/netbsd_base.rs
index 0f2ab32be24..9b20bd927cb 100644
--- a/src/librustc_back/target/netbsd_base.rs
+++ b/src/librustc_back/target/netbsd_base.rs
@@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
             "-Wl,--as-needed".to_string(),
         ),
         position_independent_executables: true,
+        archive_format: "bsd".to_string(),
         .. Default::default()
     }
 }
diff --git a/src/librustc_back/target/openbsd_base.rs b/src/librustc_back/target/openbsd_base.rs
index 0f2ab32be24..9b20bd927cb 100644
--- a/src/librustc_back/target/openbsd_base.rs
+++ b/src/librustc_back/target/openbsd_base.rs
@@ -27,6 +27,7 @@ pub fn opts() -> TargetOptions {
             "-Wl,--as-needed".to_string(),
         ),
         position_independent_executables: true,
+        archive_format: "bsd".to_string(),
         .. Default::default()
     }
 }
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
index 2c6022bc614..85c0c721114 100644
--- a/src/librustc_llvm/archive_ro.rs
+++ b/src/librustc_llvm/archive_ro.rs
@@ -118,6 +118,9 @@ impl<'a> Child<'a> {
         unsafe {
             let mut data_len = 0;
             let data_ptr = ::LLVMRustArchiveChildData(self.ptr, &mut data_len);
+            if data_ptr.is_null() {
+                panic!("failed to read data from archive child");
+            }
             slice::from_raw_parts(data_ptr as *const u8, data_len as usize)
         }
     }
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 05f82b86ebb..051cc1c5bb2 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -452,6 +452,15 @@ pub enum DiagnosticKind {
     DK_OptimizationFailure,
 }
 
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub enum ArchiveKind {
+    K_GNU,
+    K_MIPS64,
+    K_BSD,
+    K_COFF,
+}
+
 // Opaque pointer types
 #[allow(missing_copy_implementations)]
 pub enum Module_opaque {}
@@ -2119,7 +2128,8 @@ extern {
     pub fn LLVMRustWriteArchive(Dst: *const c_char,
                                 NumMembers: size_t,
                                 Members: *const RustArchiveMemberRef,
-                                WriteSymbtab: bool) -> c_int;
+                                WriteSymbtab: bool,
+                                Kind: ArchiveKind) -> c_int;
     pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
                                     Name: *const c_char,
                                     Child: ArchiveChildRef) -> RustArchiveMemberRef;
diff --git a/src/librustc_trans/back/archive.rs b/src/librustc_trans/back/archive.rs
index cc3d1d842fa..02f4bc83b75 100644
--- a/src/librustc_trans/back/archive.rs
+++ b/src/librustc_trans/back/archive.rs
@@ -22,7 +22,7 @@ use std::str;
 
 use libc;
 use llvm::archive_ro::{ArchiveRO, Child};
-use llvm;
+use llvm::{self, ArchiveKind};
 use rustc::metadata::loader::METADATA_FILENAME;
 use rustc::session::Session;
 use rustc_back::tempdir::TempDir;
@@ -208,28 +208,34 @@ impl<'a> ArchiveBuilder<'a> {
     /// Combine the provided files, rlibs, and native libraries into a single
     /// `Archive`.
     pub fn build(&mut self) {
-        let res = if self.using_llvm() {
-            self.build_with_llvm()
-        } else {
-            self.build_with_ar_cmd()
+        let res = match self.llvm_archive_kind() {
+            Some(kind) => self.build_with_llvm(kind),
+            None => self.build_with_ar_cmd(),
         };
         if let Err(e) = res {
             self.config.sess.fatal(&format!("failed to build archive: {}", e));
         }
     }
 
-    pub fn using_llvm(&self) -> bool {
+    pub fn llvm_archive_kind(&self) -> Option<ArchiveKind> {
         if unsafe { llvm::LLVMVersionMinor() < 7 } {
-            return false
+            return None
         }
 
         // Currently LLVM only supports writing archives in the 'gnu' format.
         match &self.config.sess.target.target.options.archive_format[..] {
-            "gnu" => true,
-            _ => false,
+            "gnu" => Some(ArchiveKind::K_GNU),
+            "mips64" => Some(ArchiveKind::K_MIPS64),
+            "bsd" => Some(ArchiveKind::K_BSD),
+            "coff" => Some(ArchiveKind::K_COFF),
+            _ => None,
         }
     }
 
+    pub fn using_llvm(&self) -> bool {
+        self.llvm_archive_kind().is_some()
+    }
+
     fn build_with_ar_cmd(&mut self) -> io::Result<()> {
         let removals = mem::replace(&mut self.removals, Vec::new());
         let additions = mem::replace(&mut self.additions, Vec::new());
@@ -425,7 +431,7 @@ impl<'a> ArchiveBuilder<'a> {
         }
     }
 
-    fn build_with_llvm(&mut self) -> io::Result<()> {
+    fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
         let mut archives = Vec::new();
         let mut strings = Vec::new();
         let mut members = Vec::new();
@@ -482,7 +488,8 @@ impl<'a> ArchiveBuilder<'a> {
             let r = llvm::LLVMRustWriteArchive(dst.as_ptr(),
                                                members.len() as libc::size_t,
                                                members.as_ptr(),
-                                               self.should_update_symbols);
+                                               self.should_update_symbols,
+                                               kind);
             let ret = if r != 0 {
                 let err = llvm::LLVMRustGetLastError();
                 let msg = if err.is_null() {
diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp
index 2e94c196935..86225874df7 100644
--- a/src/rustllvm/ArchiveWrapper.cpp
+++ b/src/rustllvm/ArchiveWrapper.cpp
@@ -120,7 +120,17 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
 
 extern "C" const char*
 LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
-    StringRef buf = child->getBuffer();
+    StringRef buf;
+#if LLVM_VERSION_MINOR >= 7
+    ErrorOr<StringRef> buf_or_err = child->getBuffer();
+    if (buf_or_err.getError()) {
+      LLVMRustSetLastError(buf_or_err.getError().message().c_str());
+      return NULL;
+    }
+    buf = buf_or_err.get();
+#else
+    buf = child->getBuffer();
+#endif
     *size = buf.size();
     return buf.data();
 }
@@ -144,7 +154,8 @@ extern "C" int
 LLVMRustWriteArchive(char *Dst,
                      size_t NumMembers,
                      const LLVMRustArchiveMember **NewMembers,
-                     bool WriteSymbtab) {
+                     bool WriteSymbtab,
+                     Archive::Kind Kind) {
 #if LLVM_VERSION_MINOR >= 7
   std::vector<NewArchiveIterator> Members;
 
@@ -157,7 +168,7 @@ LLVMRustWriteArchive(char *Dst,
       Members.push_back(NewArchiveIterator(Member->child, Member->name));
     }
   }
-  auto pair = writeArchive(Dst, Members, WriteSymbtab);
+  auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, false);
   if (!pair.second)
     return 0;
   LLVMRustSetLastError(pair.second.message().c_str());