diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_back/target/apple_base.rs | 1 | ||||
| -rw-r--r-- | src/librustc_back/target/bitrig_base.rs | 1 | ||||
| -rw-r--r-- | src/librustc_back/target/dragonfly_base.rs | 1 | ||||
| -rw-r--r-- | src/librustc_back/target/freebsd_base.rs | 1 | ||||
| -rw-r--r-- | src/librustc_back/target/netbsd_base.rs | 1 | ||||
| -rw-r--r-- | src/librustc_back/target/openbsd_base.rs | 1 | ||||
| -rw-r--r-- | src/librustc_llvm/archive_ro.rs | 3 | ||||
| -rw-r--r-- | src/librustc_llvm/lib.rs | 12 | ||||
| -rw-r--r-- | src/librustc_trans/back/archive.rs | 29 | ||||
| -rw-r--r-- | src/rustllvm/ArchiveWrapper.cpp | 17 |
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()); |
