From d22a9a294052ca2fe97862d32c768e581baf797f Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 13 Jul 2016 00:29:47 +0200 Subject: [PATCH 01/33] Upgrade to rust-llvm-2016-07-09 --- src/llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm b/src/llvm index 7ca76af03bb..a5b8261c9a0 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 7ca76af03bb04659562890d6b4f223fffe0d748f +Subproject commit a5b8261c9a0ea200bc4da345ae43823989ad46ed From 7420874a97a268d1c75dbc0e95231e4c8a1d513a Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 13 Jul 2016 00:38:30 +0200 Subject: [PATCH 02/33] [LLVM-3.9] Rename custom methods to Rust-specific ones --- src/librustc_llvm/lib.rs | 6 +++--- src/librustc_trans/builder.rs | 2 +- src/rustllvm/RustWrapper.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index e757201c886..f14df2a7b48 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -226,7 +226,7 @@ pub fn apply_llfn(&self, idx: usize, llfn: ValueRef) { pub fn apply_callsite(&self, idx: usize, callsite: ValueRef) { unsafe { - LLVMAddCallSiteAttribute(callsite, idx as c_uint, self.regular.bits()); + LLVMRustAddCallSiteAttribute(callsite, idx as c_uint, self.regular.bits()); if self.dereferenceable_bytes != 0 { LLVMAddDereferenceableCallSiteAttr(callsite, idx as c_uint, self.dereferenceable_bytes); @@ -1056,7 +1056,7 @@ pub fn LLVMRemoveInstrAttribute(Instr: ValueRef, pub fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint, align: c_uint); - pub fn LLVMAddCallSiteAttribute(Instr: ValueRef, + pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, Val: uint64_t); pub fn LLVMAddDereferenceableCallSiteAttr(Instr: ValueRef, @@ -1561,7 +1561,7 @@ pub fn LLVMBuildAtomicStore(B: BuilderRef, Alignment: c_uint) -> ValueRef; - pub fn LLVMBuildAtomicCmpXchg(B: BuilderRef, + pub fn LLVMRustBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef, CMP: ValueRef, RHS: ValueRef, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index e88257dcd4c..7495f2b753b 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -1083,7 +1083,7 @@ pub fn atomic_cmpxchg(&self, dst: ValueRef, failure_order: AtomicOrdering, weak: llvm::Bool) -> ValueRef { unsafe { - llvm::LLVMBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, + llvm::LLVMRustBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, order, failure_order, weak) } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index fadd95c9a72..bc38245d351 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -99,7 +99,7 @@ extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) { return wrap(Type::getMetadataTy(*unwrap(C))); } -extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) { +extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) { CallSite Call = CallSite(unwrap(Instr)); AttrBuilder B; B.addRawValue(Val); @@ -203,7 +203,7 @@ extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B, return wrap(unwrap(B)->Insert(si)); } -extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, +extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef target, LLVMValueRef old, LLVMValueRef source, From fba1f8f1239e45aa44bacfa0f955a24e3ade6982 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 13 Jul 2016 00:40:38 +0200 Subject: [PATCH 03/33] [LLVM-3.9] Setup the compile unit information immediately Since LLVM reversed the order of the debug info graphs, we need to have a compile unit that exists *before* any functions (`DISubprogram`s) are created. This allows the LLVM debug info builder to automatically link the functions to the compile unit. --- src/librustc_trans/context.rs | 4 +++- src/librustc_trans/debuginfo/metadata.rs | 30 ++++++++++++++---------- src/librustc_trans/debuginfo/mod.rs | 5 ++-- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index a8f8474e940..aa60110fab3 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -558,7 +558,9 @@ fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>, &llmod_id[..]); let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo { - Some(debuginfo::CrateDebugContext::new(llmod)) + let dctx = debuginfo::CrateDebugContext::new(llmod); + debuginfo::metadata::compile_unit_metadata(shared, &dctx, shared.tcx.sess); + Some(dctx) } else { None }; diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 46813d957dc..1119ee07230 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -18,7 +18,9 @@ fn_should_be_ignored, is_node_local_to_unit}; use super::namespace::mangled_name_of_item; use super::type_names::{compute_debuginfo_type_name, push_debuginfo_type_name}; -use super::{declare_local, VariableKind, VariableAccess}; +use super::{declare_local, VariableKind, VariableAccess, CrateDebugContext}; +use context::SharedCrateContext; +use session::Session; use llvm::{self, ValueRef}; use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType}; @@ -48,7 +50,6 @@ use syntax::parse::token; use syntax_pos::{self, Span}; - // From DWARF 5. // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1 const DW_LANG_RUST: c_uint = 0x1c; @@ -981,14 +982,17 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return ptr_metadata; } -pub fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { - let work_dir = &cx.sess().working_dir; - let compile_unit_name = match cx.sess().local_crate_source_file { - None => fallback_path(cx), +pub fn compile_unit_metadata(scc: &SharedCrateContext, + debug_context: &CrateDebugContext, + sess: &Session) + -> DIDescriptor { + let work_dir = &sess.working_dir; + let compile_unit_name = match sess.local_crate_source_file { + None => fallback_path(scc), Some(ref abs_path) => { if abs_path.is_relative() { - cx.sess().warn("debuginfo: Invalid path to crate's local root source file!"); - fallback_path(cx) + sess.warn("debuginfo: Invalid path to crate's local root source file!"); + fallback_path(scc) } else { match abs_path.strip_prefix(work_dir) { Ok(ref p) if p.is_relative() => { @@ -998,7 +1002,7 @@ pub fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { path2cstr(&Path::new(".").join(p)) } } - _ => fallback_path(cx) + _ => fallback_path(scc) } } } @@ -1015,19 +1019,19 @@ pub fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { let split_name = "\0"; return unsafe { llvm::LLVMDIBuilderCreateCompileUnit( - debug_context(cx).builder, + debug_context.builder, DW_LANG_RUST, compile_unit_name, work_dir.as_ptr(), producer.as_ptr(), - cx.sess().opts.optimize != config::OptLevel::No, + sess.opts.optimize != config::OptLevel::No, flags.as_ptr() as *const _, 0, split_name.as_ptr() as *const _) }; - fn fallback_path(cx: &CrateContext) -> CString { - CString::new(cx.link_meta().crate_name.clone()).unwrap() + fn fallback_path(scc: &::context::SharedCrateContext) -> CString { + CString::new(scc.link_meta().crate_name.clone()).unwrap() } } diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 8c5b3ed54c2..ed20d949d55 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -18,7 +18,7 @@ use self::namespace::mangled_name_of_item; use self::type_names::compute_debuginfo_type_name; use self::metadata::{type_metadata, diverging_type_metadata}; -use self::metadata::{file_metadata, scope_metadata, TypeMap, compile_unit_metadata}; +use self::metadata::{file_metadata, scope_metadata, TypeMap}; use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use llvm; @@ -50,7 +50,7 @@ mod utils; mod namespace; mod type_names; -mod metadata; +pub mod metadata; mod create_scope_map; mod source_loc; @@ -168,7 +168,6 @@ pub fn finalize(cx: &CrateContext) { } debug!("finalize"); - let _ = compile_unit_metadata(cx); if gdb::needs_gdb_debug_scripts_section(cx) { // Add a .debug_gdb_scripts section to this compile-unit. This will From 6ed5db8d351038622b180be917ef2e2e3f0727b2 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 13 Jul 2016 00:42:20 +0200 Subject: [PATCH 04/33] [LLVM-3.9] Specify that we are using the legacy interface LLVM pass manager infrastructure is currently getting rewritten to be more flexible, but the rewrite isn't complete yet. --- src/rustllvm/PassWrapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 3564f338a02..95ad686161f 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -267,7 +267,7 @@ LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB, // similar code in clang's BackendUtil.cpp file. extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { - FunctionPassManager *P = unwrap(PM); + llvm::legacy::FunctionPassManager *P = unwrap(PM); P->doInitialization(); for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E; ++I) @@ -294,7 +294,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMModuleRef M, const char *path, TargetMachine::CodeGenFileType FileType) { - PassManager *PM = unwrap(PMR); + llvm::legacy::PassManager *PM = unwrap(PMR); std::string ErrorInfo; std::error_code EC; @@ -320,7 +320,7 @@ extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M, const char* path) { - PassManager *PM = unwrap(PMR); + llvm::legacy::PassManager *PM = unwrap(PMR); std::string ErrorInfo; std::error_code EC; From 5b44e10fb7e9d1226af11df26ee5fa78b8d54cc3 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 13 Jul 2016 00:42:44 +0200 Subject: [PATCH 05/33] [LLVM-3.9] Preserve certain functions when internalizing This makes sure to still use the old way for older LLVM versions. --- src/rustllvm/PassWrapper.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 95ad686161f..64edc79a86a 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -358,9 +358,24 @@ LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMB, bool AddLifetimes) { extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) { - PassManager passes; + llvm::legacy::PassManager passes; + +#if LLVM_VERSION_MINOR <= 8 ArrayRef ref(symbols, len); passes.add(llvm::createInternalizePass(ref)); +#else + auto PreserveFunctions = [=](const GlobalValue &GV) { + for (size_t i=0; i Date: Wed, 13 Jul 2016 15:29:24 +0200 Subject: [PATCH 06/33] [LLVM-3.9] Replace NewArchiveIterator with NewArchiveMember The new NewArchiveMember is simpler and requires less context, according to upstream. This was changed in http://reviews.llvm.org/D21721 --- src/rustllvm/ArchiveWrapper.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 1e7b04c814c..cdd11e8838c 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -150,19 +150,33 @@ LLVMRustWriteArchive(char *Dst, const LLVMRustArchiveMember **NewMembers, bool WriteSymbtab, Archive::Kind Kind) { - std::vector Members; + std::vector Members; for (size_t i = 0; i < NumMembers; i++) { auto Member = NewMembers[i]; assert(Member->name); if (Member->filename) { -#if LLVM_VERSION_MINOR >= 8 - Members.push_back(NewArchiveIterator(Member->filename)); +#if LLVM_VERSION_MINOR >= 9 + Expected MOrErr = NewArchiveMember::getFile(Member->filename, true); + if (!MOrErr) { + LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); + return -1; + } + Members.push_back(std::move(*MOrErr)); #else Members.push_back(NewArchiveIterator(Member->filename, Member->name)); #endif } else { +#if LLVM_VERSION_MINOR >= 9 + Expected MOrErr = NewArchiveMember::getOldMember(Member->child, true); + if (!MOrErr) { + LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); + return -1; + } + Members.push_back(std::move(*MOrErr)); +#else Members.push_back(NewArchiveIterator(Member->child, Member->name)); +#endif } } #if LLVM_VERSION_MINOR >= 8 From dbb4178f4effa2f7686aca70d5fdfa0eff94e692 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 13 Jul 2016 16:06:50 +0200 Subject: [PATCH 07/33] [LLVM-3.9] Update return type for Archive::create Changed in https://github.com/rust-lang/llvm/commit/0b21d88fd31b4bfb6fdb7e2f1ed5f93639d5bd1c --- src/rustllvm/ArchiveWrapper.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index cdd11e8838c..514d25297ee 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -43,11 +43,19 @@ LLVMRustOpenArchive(char *path) { return nullptr; } +#if LLVM_VERSION_MINOR <= 8 ErrorOr> archive_or = +#else + Expected> archive_or = +#endif Archive::create(buf_or.get()->getMemBufferRef()); if (!archive_or) { +#if LLVM_VERSION_MINOR <= 8 LLVMRustSetLastError(archive_or.getError().message().c_str()); +#else + LLVMRustSetLastError(toString(archive_or.takeError()).c_str()); +#endif return nullptr; } From 9e706f90cbc844bb09187e01acd4ae075130bc81 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 13 Jul 2016 00:41:40 +0200 Subject: [PATCH 08/33] [LLVM-3.9] Configure PIE at the module level instead of compilation unit level This was deleted here[1] which appears to be replaced by this[2] which is a new setPIELevel function on the LLVM module itself. [1]: http://reviews.llvm.org/D19753 [2]: http://reviews.llvm.org/D19671 --- src/librustc_llvm/lib.rs | 1 + src/librustc_trans/context.rs | 1 + src/rustllvm/PassWrapper.cpp | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index f14df2a7b48..4fc866752eb 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -2155,6 +2155,7 @@ pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, pub fn LLVMRustSetComdat(M: ModuleRef, V: ValueRef, Name: *const c_char); pub fn LLVMRustUnsetComdat(V: ValueRef); + pub fn LLVMRustSetModulePIELevel(M: ModuleRef); } // LLVM requires symbols from this library, but apparently they're not printed diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index aa60110fab3..2437fa954d1 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -352,6 +352,7 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR let llvm_target = sess.target.target.llvm_target.as_bytes(); let llvm_target = CString::new(llvm_target).unwrap(); llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); + llvm::LLVMRustSetModulePIELevel(llmod); (llcx, llmod) } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 64edc79a86a..edf83bf80d6 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -188,7 +188,10 @@ LLVMRustCreateTargetMachine(const char *triple, } TargetOptions Options; +#if LLVM_VERSION_MINOR <= 8 Options.PositionIndependentExecutable = PositionIndependentExecutable; +#endif + Options.FloatABIType = FloatABI::Default; if (UseSoftFloat) { Options.FloatABIType = FloatABI::Soft; @@ -411,3 +414,10 @@ extern "C" LLVMTargetDataRef LLVMRustGetModuleDataLayout(LLVMModuleRef M) { return wrap(&unwrap(M)->getDataLayout()); } + +extern "C" void +LLVMRustSetModulePIELevel(LLVMModuleRef M) { +#if LLVM_VERSION_MINOR >= 9 + unwrap(M)->setPIELevel(PIELevel::Level::Default); +#endif +} From 12ccff99bf254fe3721ad389953eb53b723872e4 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 14 Jul 2016 19:28:54 +0200 Subject: [PATCH 09/33] Use relative path to type --- src/librustc_trans/debuginfo/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 1119ee07230..09059cc378a 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1030,7 +1030,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, split_name.as_ptr() as *const _) }; - fn fallback_path(scc: &::context::SharedCrateContext) -> CString { + fn fallback_path(scc: &SharedCrateContext) -> CString { CString::new(scc.link_meta().crate_name.clone()).unwrap() } } From deafab19be13e8cd33e55b211ba8835488747a05 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 14 Jul 2016 21:26:09 +0200 Subject: [PATCH 10/33] [LLVM-3.9] Increase PIELevel Previously, we had a PositionIndependentExecutable, now we simply choose the highest level. This should be equivalent. :cake: --- src/rustllvm/PassWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index edf83bf80d6..d4ef4e807f5 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -418,6 +418,6 @@ LLVMRustGetModuleDataLayout(LLVMModuleRef M) { extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) { #if LLVM_VERSION_MINOR >= 9 - unwrap(M)->setPIELevel(PIELevel::Level::Default); + unwrap(M)->setPIELevel(PIELevel::Level::Large); #endif } From 1bc04472609aec664ce434f7a3b7df7e06e80637 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 14 Jul 2016 21:27:14 +0200 Subject: [PATCH 11/33] [LLVM-3.9] Maintain backward compatibility in Archiver --- src/rustllvm/ArchiveWrapper.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 514d25297ee..03b0aaf45b8 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -158,7 +158,12 @@ LLVMRustWriteArchive(char *Dst, const LLVMRustArchiveMember **NewMembers, bool WriteSymbtab, Archive::Kind Kind) { + +#if LLVM_VERSION_MINOR >= 9 std::vector Members; +#else + std::vector Members; +#endif for (size_t i = 0; i < NumMembers; i++) { auto Member = NewMembers[i]; @@ -171,6 +176,8 @@ LLVMRustWriteArchive(char *Dst, return -1; } Members.push_back(std::move(*MOrErr)); +#elif LLVM_VERSION_MINOR == 8 + Members.push_back(NewArchiveIterator(Member->filename)); #else Members.push_back(NewArchiveIterator(Member->filename, Member->name)); #endif From 1798c1aa598a03e0d4d2440d15bdb2ae242b392e Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 14 Jul 2016 23:40:14 +0200 Subject: [PATCH 12/33] Refactor determining of relocation model into methods --- src/librustc_trans/back/write.rs | 26 +++------------------ src/librustc_trans/context.rs | 39 +++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 4b9d5dd9e8d..87815c63f79 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -24,6 +24,7 @@ use errors::{self, Handler, Level, DiagnosticBuilder}; use errors::emitter::Emitter; use syntax_pos::MultiSpan; +use context::{is_pie_binary, get_reloc_model}; use std::collections::HashMap; use std::ffi::{CStr, CString}; @@ -154,32 +155,11 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize { } pub fn create_target_machine(sess: &Session) -> TargetMachineRef { - let reloc_model_arg = match sess.opts.cg.relocation_model { - Some(ref s) => &s[..], - None => &sess.target.target.options.relocation_model[..], - }; - let reloc_model = match reloc_model_arg { - "pic" => llvm::RelocPIC, - "static" => llvm::RelocStatic, - "default" => llvm::RelocDefault, - "dynamic-no-pic" => llvm::RelocDynamicNoPic, - _ => { - sess.err(&format!("{:?} is not a valid relocation mode", - sess.opts - .cg - .relocation_model)); - sess.abort_if_errors(); - bug!(); - } - }; + let reloc_model = get_reloc_model(sess); let opt_level = get_llvm_opt_level(sess.opts.optimize); let use_softfp = sess.opts.cg.soft_float; - let any_library = sess.crate_types.borrow().iter().any(|ty| { - *ty != config::CrateTypeExecutable - }); - let ffunction_sections = sess.target.target.options.function_sections; let fdata_sections = ffunction_sections; @@ -220,7 +200,7 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef { reloc_model, opt_level, use_softfp, - !any_library && reloc_model == llvm::RelocPIC, + is_pie_binary(sess), ffunction_sections, fdata_sections, ) diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 2437fa954d1..d8b3089bc99 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -34,6 +34,7 @@ use rustc::ty::{self, Ty, TyCtxt}; use session::config::NoDebugInfo; use session::Session; +use session::config; use symbol_map::SymbolMap; use util::sha2::Sha256; use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap, FnvHashSet}; @@ -322,6 +323,38 @@ fn next(&mut self) -> Option<(CrateContext<'a, 'tcx>, bool)> { } } +pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode { + let reloc_model_arg = match sess.opts.cg.relocation_model { + Some(ref s) => &s[..], + None => &sess.target.target.options.relocation_model[..], + }; + + match reloc_model_arg { + "pic" => llvm::RelocPIC, + "static" => llvm::RelocStatic, + "default" => llvm::RelocDefault, + "dynamic-no-pic" => llvm::RelocDynamicNoPic, + _ => { + sess.err(&format!("{:?} is not a valid relocation mode", + sess.opts + .cg + .relocation_model)); + sess.abort_if_errors(); + bug!(); + } + } +} + +fn is_any_library(sess: &Session) -> bool { + sess.crate_types.borrow().iter().any(|ty| { + *ty != config::CrateTypeExecutable + }) +} + +pub fn is_pie_binary(sess: &Session) -> bool { + !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocPIC +} + unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) { let llcx = llvm::LLVMContextCreate(); let mod_name = CString::new(mod_name).unwrap(); @@ -352,7 +385,11 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR let llvm_target = sess.target.target.llvm_target.as_bytes(); let llvm_target = CString::new(llvm_target).unwrap(); llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); - llvm::LLVMRustSetModulePIELevel(llmod); + + if is_pie_binary(sess) { + llvm::LLVMRustSetModulePIELevel(llmod); + } + (llcx, llmod) } From 2bcb2b89902762dd1b2e00a7b6ae8c0566470cc1 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Sat, 16 Jul 2016 17:23:00 +0200 Subject: [PATCH 13/33] Upgrade LLVM to include std::thread patch --- src/llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm b/src/llvm index a5b8261c9a0..6e665b76d2b 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit a5b8261c9a0ea200bc4da345ae43823989ad46ed +Subproject commit 6e665b76d2b64256a932a61ac3eeb5ce2971c185 From d0e5aa48201ec100cbd8c519f0a8de0554a84ac7 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Sat, 16 Jul 2016 17:24:02 +0200 Subject: [PATCH 14/33] Upgrade compiler-rt --- src/compiler-rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler-rt b/src/compiler-rt index ac3d1cda612..3c51a621bb3 160000 --- a/src/compiler-rt +++ b/src/compiler-rt @@ -1 +1 @@ -Subproject commit ac3d1cda612edccb6f1da53cbf7716e248405f3b +Subproject commit 3c51a621bb34f31bcb76e8e582945a7e045ce11d From f439aeef070da498f5a75b7cf17080bde0e72738 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Sat, 16 Jul 2016 19:36:51 +0200 Subject: [PATCH 15/33] [LLVM-3.9] Use old way of getting next child This was changed back in https://github.com/rust-lang/llvm/commit/aacf2fbf --- src/rustllvm/ArchiveWrapper.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 03b0aaf45b8..b6d352e4516 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -79,7 +79,12 @@ extern "C" RustArchiveIterator* LLVMRustArchiveIteratorNew(RustArchive *ra) { Archive *ar = ra->getBinary(); RustArchiveIterator *rai = new RustArchiveIterator(); +#if LLVM_VERSION_MINOR >= 9 + Error err; + rai->cur = ar->child_begin(err); +#else rai->cur = ar->child_begin(); +#endif rai->end = ar->child_end(); return rai; } @@ -88,8 +93,8 @@ extern "C" const Archive::Child* LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) { if (rai->cur == rai->end) return NULL; -#if LLVM_VERSION_MINOR >= 8 - const ErrorOr* cur = rai->cur.operator->(); +#if LLVM_VERSION_MINOR == 8 + Archive::Child* cur = rai->cur.operator->(); if (!*cur) { LLVMRustSetLastError(cur->getError().message().c_str()); return NULL; From 09c3f33ec2a5035d35307598a7e66132747ead9d Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Sat, 16 Jul 2016 19:44:43 +0200 Subject: [PATCH 16/33] Flip LLVM verion check clause --- src/rustllvm/ArchiveWrapper.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index b6d352e4516..5e8250b908c 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -79,11 +79,11 @@ extern "C" RustArchiveIterator* LLVMRustArchiveIteratorNew(RustArchive *ra) { Archive *ar = ra->getBinary(); RustArchiveIterator *rai = new RustArchiveIterator(); -#if LLVM_VERSION_MINOR >= 9 +#if LLVM_VERSION_MINOR <= 8 + rai->cur = ar->child_begin(); +#else Error err; rai->cur = ar->child_begin(err); -#else - rai->cur = ar->child_begin(); #endif rai->end = ar->child_end(); return rai; @@ -164,10 +164,10 @@ LLVMRustWriteArchive(char *Dst, bool WriteSymbtab, Archive::Kind Kind) { -#if LLVM_VERSION_MINOR >= 9 - std::vector Members; -#else +#if LLVM_VERSION_MINOR <= 8 std::vector Members; +#else + std::vector Members; #endif for (size_t i = 0; i < NumMembers; i++) { @@ -187,15 +187,15 @@ LLVMRustWriteArchive(char *Dst, Members.push_back(NewArchiveIterator(Member->filename, Member->name)); #endif } else { -#if LLVM_VERSION_MINOR >= 9 +#if LLVM_VERSION_MINOR <= 8 + Members.push_back(NewArchiveIterator(Member->child, Member->name)); +#else Expected MOrErr = NewArchiveMember::getOldMember(Member->child, true); if (!MOrErr) { LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); return -1; } Members.push_back(std::move(*MOrErr)); -#else - Members.push_back(NewArchiveIterator(Member->child, Member->name)); #endif } } From ad262d54dce230d712a2be6db6aa59e1851769ef Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 21 Jul 2016 11:12:31 +0200 Subject: [PATCH 17/33] Update compiler-rt --- src/compiler-rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler-rt b/src/compiler-rt index 3c51a621bb3..8598065bd96 160000 --- a/src/compiler-rt +++ b/src/compiler-rt @@ -1 +1 @@ -Subproject commit 3c51a621bb34f31bcb76e8e582945a7e045ce11d +Subproject commit 8598065bd965d9713bfafb6c1e766d63a7b17b89 From 2c92756dde884bbfa5efef9b4cbd846882a7d46e Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 21 Jul 2016 11:24:05 +0200 Subject: [PATCH 18/33] Upgrade llvm --- src/llvm | 2 +- src/rustllvm/llvm-auto-clean-trigger | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/llvm b/src/llvm index 6e665b76d2b..fb2893b136c 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 6e665b76d2b64256a932a61ac3eeb5ce2971c185 +Subproject commit fb2893b136c6a83a6f34f708fac2530d95e2db65 diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 1953fc5a6b4..09ce8a93174 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2016-06-23 +2016-07-20 From dc7076b52e2464a703de7d87fa6c60b8fc98ada9 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 21 Jul 2016 11:24:35 +0200 Subject: [PATCH 19/33] [LLVM-3.9] Pass correct relocation model flag --- configure | 5 +++++ mk/platform.mk | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/configure b/configure index d2ec457a1c8..af29ef3d39c 100755 --- a/configure +++ b/configure @@ -1020,6 +1020,11 @@ then err "bad LLVM version: $LLVM_VERSION, need >=3.7" ;; esac + + if "$CFG_LLVM_ROOT/bin/llvm-mc" -help | grep "-relocation-model"; then + CFG_LLVM_MC_HAS_RELOCATION_MODEL=1 + putvar CFG_LLVM_MC_HAS_RELOCATION_MODEL + fi fi # Even when the user overrides the choice of CC, still try to detect diff --git a/mk/platform.mk b/mk/platform.mk index c2644621c57..d601cab7221 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -221,12 +221,19 @@ define CFG_MAKE_TOOLCHAIN LLVM_MC_RELOCATION_MODEL="default" endif + # LLVM changed this flag in 3.9 + ifdef CFG_LLVM_MC_HAS_RELOCATION_MODEL + LLVM_MC_RELOC_FLAG := -relocation-model=$$(LLVM_MC_RELOCATION_MODEL) + else + LLVM_MC_RELOC_FLAG := -position-independent + endif + # We're using llvm-mc as our assembler because it supports # .cfi pseudo-ops on mac CFG_ASSEMBLE_$(1)=$$(CPP_$(1)) -E $$(2) | \ $$(LLVM_MC_$$(CFG_BUILD)) \ -assemble \ - -relocation-model=$$(LLVM_MC_RELOCATION_MODEL) \ + $$(LLVM_MC_RELOC_FLAG) \ -filetype=obj \ -triple=$(1) \ -o=$$(1) From 079db4f9715ab5c495115b11adcca5f5bd4ed260 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 21 Jul 2016 11:24:51 +0200 Subject: [PATCH 20/33] Use correct error handling type --- src/rustllvm/ArchiveWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 5e8250b908c..935052a5113 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -94,7 +94,7 @@ LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) { if (rai->cur == rai->end) return NULL; #if LLVM_VERSION_MINOR == 8 - Archive::Child* cur = rai->cur.operator->(); + const ErrorOr* cur = rai->cur.operator->(); if (!*cur) { LLVMRustSetLastError(cur->getError().message().c_str()); return NULL; From 2c16e24643976523e6858fd41a1ded0429a96ef1 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Sun, 24 Jul 2016 22:31:16 +0200 Subject: [PATCH 21/33] Use C type when passing value to LLVM pass Previously the C type LLVMRelocMode (available as RelocMode in Rust) was passed as is to the function. However createTargetMachine expects a Reloc::Model, which is an enum just one value short. Additionally, the function was marked as requiring Reloc::Model in the C code, but RelocMode on the Rust-side. We now use the correct C type LLVMRelocMode and convert it to an Optional as expected by the createTargetMachine call the same the original LLVMCreateTargetMachine function does. See https://github.com/llvm-mirror/llvm/blob/c9b262bfbd5b9fb6f10749dba1465569f39bd625/lib/Target/TargetMachineC.cpp#L104-L121 This was found by @eddyb. --- src/rustllvm/PassWrapper.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index d4ef4e807f5..a1276060271 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -167,12 +167,35 @@ LLVMRustCreateTargetMachine(const char *triple, const char *cpu, const char *feature, CodeModel::Model CM, - Reloc::Model RM, + LLVMRelocMode Reloc, CodeGenOpt::Level OptLevel, bool UseSoftFloat, bool PositionIndependentExecutable, bool FunctionSections, bool DataSections) { + +#if LLVM_VERSION_MINOR <= 8 + Reloc::Model RM; +#else + Optional RM; +#endif + switch (Reloc){ + case LLVMRelocStatic: + RM = Reloc::Static; + break; + case LLVMRelocPIC: + RM = Reloc::PIC_; + break; + case LLVMRelocDynamicNoPic: + RM = Reloc::DynamicNoPIC; + break; + default: +#if LLVM_VERSION_MINOR <= 8 + RM = Reloc::Default; +#endif + break; + } + std::string Error; Triple Trip(Triple::normalize(triple)); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(), From a36595ed14b4ded33d207040e5bcd3da169ecc20 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Sun, 24 Jul 2016 22:34:37 +0200 Subject: [PATCH 22/33] Force check of error The passed error needs to be checked. Otherwise it will force an abort when it is deconstructed, but a success value. --- src/rustllvm/ArchiveWrapper.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 935052a5113..3d48024c879 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -73,6 +73,9 @@ LLVMRustDestroyArchive(RustArchive *ar) { struct RustArchiveIterator { Archive::child_iterator cur; Archive::child_iterator end; +#if LLVM_VERSION_MINOR >= 9 + Error err; +#endif }; extern "C" RustArchiveIterator* @@ -82,8 +85,11 @@ LLVMRustArchiveIteratorNew(RustArchive *ra) { #if LLVM_VERSION_MINOR <= 8 rai->cur = ar->child_begin(); #else - Error err; - rai->cur = ar->child_begin(err); + rai->cur = ar->child_begin(rai->err); + if (rai->err) { + LLVMRustSetLastError(toString(std::move(rai->err)).c_str()); + return NULL; + } #endif rai->end = ar->child_end(); return rai; @@ -91,6 +97,12 @@ LLVMRustArchiveIteratorNew(RustArchive *ra) { extern "C" const Archive::Child* LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) { +#if LLVM_VERSION_MINOR >= 9 + if (rai->err) { + LLVMRustSetLastError(toString(std::move(rai->err)).c_str()); + return NULL; + } +#endif if (rai->cur == rai->end) return NULL; #if LLVM_VERSION_MINOR == 8 From d851428cc352254aed0dd894d1a9970a228ec9ed Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 25 Jul 2016 10:20:05 -0700 Subject: [PATCH 23/33] configure: Fix grep invocation for llvm-mc argument --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index af29ef3d39c..3e2cbcbe364 100755 --- a/configure +++ b/configure @@ -1021,7 +1021,8 @@ then ;; esac - if "$CFG_LLVM_ROOT/bin/llvm-mc" -help | grep "-relocation-model"; then + if "$CFG_LLVM_ROOT/bin/llvm-mc" -help | grep -- "-relocation-model"; then + msg "found older llvm-mc" CFG_LLVM_MC_HAS_RELOCATION_MODEL=1 putvar CFG_LLVM_MC_HAS_RELOCATION_MODEL fi From e8f76661f13620f075626d27f94750ea94d6cf2e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 25 Jul 2016 10:21:31 -0700 Subject: [PATCH 24/33] rustc: Fix data-layout for AArch64 targets Also relax the assertion whenever we have a custom LLVM root as LLVM may disagree about exact specifics. --- .../target/aarch64_linux_android.rs | 2 +- .../target/aarch64_unknown_linux_gnu.rs | 2 +- src/librustc_trans/context.rs | 20 ++++++++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/librustc_back/target/aarch64_linux_android.rs b/src/librustc_back/target/aarch64_linux_android.rs index 81be546e0c8..a5be1a227f1 100644 --- a/src/librustc_back/target/aarch64_linux_android.rs +++ b/src/librustc_back/target/aarch64_linux_android.rs @@ -20,7 +20,7 @@ pub fn target() -> Target { llvm_target: "aarch64-linux-android".to_string(), target_endian: "little".to_string(), target_pointer_width: "64".to_string(), - data_layout: "e-m:e-i64:64-i128:128-n32:64-S128".to_string(), + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), target_os: "android".to_string(), target_env: "".to_string(), diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs index aec1bae60c8..2dc9355e22f 100644 --- a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs +++ b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs @@ -18,7 +18,7 @@ pub fn target() -> Target { target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_env: "gnu".to_string(), - data_layout: "e-m:e-i64:64-i128:128-n32:64-S128".to_string(), + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(), arch: "aarch64".to_string(), target_os: "linux".to_string(), target_vendor: "unknown".to_string(), diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index d8b3089bc99..792169b08a4 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -370,7 +370,25 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR let data_layout = str::from_utf8(CStr::from_ptr(data_layout).to_bytes()) .ok().expect("got a non-UTF8 data-layout from LLVM"); - if sess.target.target.data_layout != data_layout { + // Unfortunately LLVM target specs change over time, and right now we + // don't have proper support to work with any more than one + // `data_layout` than the one that is in the rust-lang/rust repo. If + // this compiler is configured against a custom LLVM, we may have a + // differing data layout, even though we should update our own to use + // that one. + // + // As an interim hack, if CFG_LLVM_ROOT is not an empty string then we + // disable this check entirely as we may be configured with something + // that has a different target layout. + // + // Unsure if this will actually cause breakage when rustc is configured + // as such. + // + // FIXME(#34960) + let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or(""); + let custom_llvm_used = cfg_llvm_root.trim() != ""; + + if !custom_llvm_used && sess.target.target.data_layout != data_layout { bug!("data-layout for builtin `{}` target, `{}`, \ differs from LLVM default, `{}`", sess.target.target.llvm_target, From 5fa55781bd77f7a9fbdb3af8fa4e1b0cd0b1cf06 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 25 Jul 2016 13:32:59 -0700 Subject: [PATCH 25/33] test: Remove the execution-engine test We don't actually officially support this at all, and the execution engine support in LLVM we've had to gut as it's not compiling on MinGW, so just delete this test for now. --- src/test/run-make/execution-engine/Makefile | 21 -- src/test/run-make/execution-engine/test.rs | 282 -------------------- 2 files changed, 303 deletions(-) delete mode 100644 src/test/run-make/execution-engine/Makefile delete mode 100644 src/test/run-make/execution-engine/test.rs diff --git a/src/test/run-make/execution-engine/Makefile b/src/test/run-make/execution-engine/Makefile deleted file mode 100644 index 4c818cd99e2..00000000000 --- a/src/test/run-make/execution-engine/Makefile +++ /dev/null @@ -1,21 +0,0 @@ --include ../tools.mk - -# FIXME: ignore freebsd -# This is a basic test of LLVM ExecutionEngine functionality using compiled -# Rust code built using the `rustc` crate. - -ifeq ($(filter executionengine,$(LLVM_COMPONENTS)),executionengine) - -ifneq ($(shell uname),FreeBSD) -all: - $(RUSTC) test.rs - $(call RUN,test $(RUSTC)) -else -all: - -endif - -else -all: - -endif diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs deleted file mode 100644 index b58295d47f2..00000000000 --- a/src/test/run-make/execution-engine/test.rs +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(rustc_private)] -#![feature(libc)] - -extern crate libc; -extern crate rustc; -extern crate rustc_driver; -extern crate rustc_lint; -extern crate rustc_llvm as llvm; -extern crate rustc_metadata; -extern crate rustc_resolve; -extern crate rustc_errors; -extern crate rustc_errors as errors; -extern crate rustc_trans; -#[macro_use] extern crate syntax; - -use std::ffi::{CStr, CString}; -use std::mem::transmute; -use std::path::PathBuf; -use std::rc::Rc; -use std::thread::Builder; - -use rustc::dep_graph::DepGraph; -use rustc::hir::map as ast_map; -use rustc::middle::cstore::LinkagePreference; -use rustc::ty; -use rustc::session::config::{self, basic_options, build_configuration, Input, Options}; -use rustc::session::build_session; -use rustc_driver::{driver, abort_on_err}; -use rustc_resolve::MakeGlobMap; -use rustc_metadata::cstore::CStore; -use rustc_trans::ModuleSource; -use libc::c_void; - -use rustc_errors::registry::Registry; - -fn main() { - // Currently trips an assertion on i686-msvc, presumably because the support - // in LLVM is a little young. - if cfg!(target_env = "msvc") && cfg!(target_arch = "x86") { - return - } - - let program = r#" - #[no_mangle] - pub static TEST_STATIC: i32 = 42; - "#; - - let program2 = r#" - #[no_mangle] - pub fn test_add(a: i32, b: i32) -> i32 { a + b } - "#; - - let mut path = match std::env::args().nth(2) { - Some(path) => PathBuf::from(&path), - None => panic!("missing rustc path") - }; - - // Remove two segments from rustc path to get sysroot. - path.pop(); - path.pop(); - - let mut ee = ExecutionEngine::new(program, path); - - let test_static = match ee.get_global("TEST_STATIC") { - Some(g) => g as *const i32, - None => panic!("failed to get global") - }; - - assert_eq!(unsafe { *test_static }, 42); - - ee.add_module(program2); - - let test_add: fn(i32, i32) -> i32; - - test_add = match ee.get_function("test_add") { - Some(f) => unsafe { transmute(f) }, - None => panic!("failed to get function") - }; - - assert_eq!(test_add(1, 2), 3); -} - -struct ExecutionEngine { - ee: llvm::ExecutionEngineRef, - modules: Vec, - sysroot: PathBuf, -} - -impl ExecutionEngine { - pub fn new(program: &str, sysroot: PathBuf) -> ExecutionEngine { - let (llmod, deps) = compile_program(program, sysroot.clone()) - .expect("failed to compile program"); - - let ee = unsafe { llvm::LLVMBuildExecutionEngine(llmod) }; - - if ee.is_null() { - panic!("Failed to create ExecutionEngine: {}", llvm_error()); - } - - let ee = ExecutionEngine{ - ee: ee, - modules: vec![llmod], - sysroot: sysroot, - }; - - ee.load_deps(&deps); - ee - } - - pub fn add_module(&mut self, program: &str) { - let (llmod, deps) = compile_program(program, self.sysroot.clone()) - .expect("failed to compile program in add_module"); - - unsafe { llvm::LLVMExecutionEngineAddModule(self.ee, llmod); } - - self.modules.push(llmod); - self.load_deps(&deps); - } - - /// Returns a raw pointer to the named function. - pub fn get_function(&mut self, name: &str) -> Option<*const c_void> { - let s = CString::new(name.as_bytes()).unwrap(); - - for &m in &self.modules { - let fv = unsafe { llvm::LLVMGetNamedFunction(m, s.as_ptr()) }; - - if !fv.is_null() { - let fp = unsafe { llvm::LLVMGetPointerToGlobal(self.ee, fv) }; - - assert!(!fp.is_null()); - return Some(fp); - } - } - None - } - - /// Returns a raw pointer to the named global item. - pub fn get_global(&mut self, name: &str) -> Option<*const c_void> { - let s = CString::new(name.as_bytes()).unwrap(); - - for &m in &self.modules { - let gv = unsafe { llvm::LLVMGetNamedGlobal(m, s.as_ptr()) }; - - if !gv.is_null() { - let gp = unsafe { llvm::LLVMGetPointerToGlobal(self.ee, gv) }; - - assert!(!gp.is_null()); - return Some(gp); - } - } - None - } - - /// Loads all dependencies of compiled code. - /// Expects a series of paths to dynamic library files. - fn load_deps(&self, deps: &[PathBuf]) { - for path in deps { - let s = match path.as_os_str().to_str() { - Some(s) => s, - None => panic!( - "Could not convert crate path to UTF-8 string: {:?}", path) - }; - let cs = CString::new(s).unwrap(); - - let res = unsafe { llvm::LLVMRustLoadDynamicLibrary(cs.as_ptr()) }; - - if res == 0 { - panic!("Failed to load crate {:?}: {}", - path.display(), llvm_error()); - } - } - } -} - -impl Drop for ExecutionEngine { - fn drop(&mut self) { - unsafe { llvm::LLVMDisposeExecutionEngine(self.ee) }; - } -} - -/// Returns last error from LLVM wrapper code. -fn llvm_error() -> String { - String::from_utf8_lossy( - unsafe { CStr::from_ptr(llvm::LLVMRustGetLastError()).to_bytes() }) - .into_owned() -} - -fn build_exec_options(sysroot: PathBuf) -> Options { - let mut opts = basic_options(); - - // librustc derives sysroot from the executable name. - // Since we are not rustc, we must specify it. - opts.maybe_sysroot = Some(sysroot); - - // Prefer faster build time - opts.optimize = config::OptLevel::No; - - // Don't require a `main` function - opts.crate_types = vec![config::CrateTypeDylib]; - - opts -} - -/// Compiles input up to phase 4, translation to LLVM. -/// -/// Returns the LLVM `ModuleRef` and a series of paths to dynamic libraries -/// for crates used in the given input. -fn compile_program(input: &str, sysroot: PathBuf) - -> Option<(llvm::ModuleRef, Vec)> { - let input = Input::Str { - name: driver::anon_src(), - input: input.to_string(), - }; - let thread = Builder::new().name("compile_program".to_string()); - - let handle = thread.spawn(move || { - let opts = build_exec_options(sysroot); - let dep_graph = DepGraph::new(opts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph)); - let sess = build_session(opts, - &dep_graph, - None, - Registry::new(&rustc::DIAGNOSTICS), - cstore.clone()); - rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); - - let cfg = build_configuration(&sess); - - let id = "input".to_string(); - - let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input)); - - let driver::ExpansionResult { defs, analysis, resolutions, mut hir_forest, .. } = { - driver::phase_2_configure_and_expand( - &sess, &cstore, krate, &id, None, MakeGlobMap::No, |_| Ok(()), - ).expect("phase_2 returned `None`") - }; - - let arenas = ty::CtxtArenas::new(); - let ast_map = ast_map::map_crate(&mut hir_forest, defs); - - abort_on_err(driver::phase_3_run_analysis_passes( - &sess, ast_map, analysis, resolutions, &arenas, &id, - |tcx, mir_map, analysis, _| { - - let trans = driver::phase_4_translate_to_llvm(tcx, mir_map.unwrap(), analysis); - - let crates = tcx.sess.cstore.used_crates(LinkagePreference::RequireDynamic); - - // Collect crates used in the session. - // Reverse order finds dependencies first. - let deps = crates.into_iter().rev() - .filter_map(|(_, p)| p).collect(); - - assert_eq!(trans.modules.len(), 1); - let llmod = match trans.modules[0].source { - ModuleSource::Preexisting(_) => unimplemented!(), - ModuleSource::Translated(llvm) => llvm.llmod, - }; - - // Workaround because raw pointers do not impl Send - let modp = llmod as usize; - - (modp, deps) - }), &sess) - }).unwrap(); - - match handle.join() { - Ok((llmod, deps)) => Some((llmod as llvm::ModuleRef, deps)), - Err(_) => None - } -} From 75bcda4cf1c2d16bda20d1efb0c87b227d973180 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 25 Jul 2016 10:23:34 -0700 Subject: [PATCH 26/33] rustc: Update LLVM to the LLVM 3.9 release branch The 3.9 release of LLVM isn't out yet, but this moves us onto that branch to start tracking it. --- src/llvm | 2 +- src/rustllvm/llvm-auto-clean-trigger | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/llvm b/src/llvm index fb2893b136c..6879bb3b6ac 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit fb2893b136c6a83a6f34f708fac2530d95e2db65 +Subproject commit 6879bb3b6ac975987250b10314e7e4069846e8c1 diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 09ce8a93174..e871763a48d 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2016-07-20 +2016-07-25b From 0509be1f6bc48da753d7383275d3c39591f3650c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 25 Jul 2016 15:37:12 -0700 Subject: [PATCH 27/33] Update parsing llvm-config output Now it prints full paths on MSVC, but we're only interested in path names --- src/etc/mklldeps.py | 7 +++++++ src/librustc_llvm/build.rs | 19 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/etc/mklldeps.py b/src/etc/mklldeps.py index 8381e4f7040..24b007576aa 100644 --- a/src/etc/mklldeps.py +++ b/src/etc/mklldeps.py @@ -77,6 +77,13 @@ for lib in out.strip().replace("\n", ' ').split(' '): lib = lib.strip()[2:] elif lib[0] == '-': lib = lib.strip()[1:] + # If this actually points at a literal file then we're on MSVC which now + # prints full paths, so get just the name of the library and strip off the + # trailing ".lib" + elif os.path.exists(lib): + lib = os.path.basename(lib)[:-4] + elif lib[-4:] == '.lib': + lib = lib[:-4] f.write("#[link(name = \"" + lib + "\"") if not llvm_shared and 'LLVM' in lib: f.write(", kind = \"static\"") diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index a2c808cbcb6..085ea240a50 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -13,7 +13,7 @@ use std::process::Command; use std::env; -use std::path::PathBuf; +use std::path::{PathBuf, Path}; use build_helper::output; @@ -135,8 +135,17 @@ fn main() { &lib[2..] } else if lib.starts_with("-") { &lib[1..] + } else if Path::new(lib).exists() { + // On MSVC llvm-config will print the full name to libraries, but + // we're only interested in the name part + let name = Path::new(lib).file_name().unwrap().to_str().unwrap(); + name.trim_right_matches(".lib") + } else if lib.ends_with(".lib") { + // Some MSVC libraries just come up with `.lib` tacked on, so chop + // that off + lib.trim_right_matches(".lib") } else { - continue; + continue }; // Don't need or want this library, but LLVM's CMake build system @@ -145,7 +154,7 @@ fn main() { // library and it otherwise may just pull in extra dependencies on // libedit which we don't want if name == "LLVMLineEditor" { - continue; + continue } let kind = if name.starts_with("LLVM") { @@ -165,7 +174,9 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg("--ldflags"); for lib in output(&mut cmd).split_whitespace() { - if is_crossed { + if lib.starts_with("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", &lib[9..]); + } else if is_crossed { if lib.starts_with("-L") { println!("cargo:rustc-link-search=native={}", lib[2..].replace(&host, &target)); From 2492d24baa57ab0364e7d94ce833e57e503434e5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 25 Jul 2016 18:36:03 -0700 Subject: [PATCH 28/33] llvm: Remove no longer existent LLVMAddTargetData binding --- src/librustc_llvm/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 4fc866752eb..6905abc2902 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -1591,9 +1591,6 @@ pub fn LLVMBuildAtomicFence(B: BuilderRef, /// Creates target data from a target layout string. pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef; - /// Adds the target data to the given pass manager. The pass manager - /// references the target data only weakly. - pub fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef); /// Number of bytes clobbered when doing a Store to *T. pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong; From 330dd39bb2864648cda1dce928bf4b52f1457f09 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Thu, 7 Jul 2016 08:15:10 -0400 Subject: [PATCH 29/33] Remove NO_FILE_METADATA; always use unknown_file_metadata instead of passing 0 --- src/librustc_trans/debuginfo/metadata.rs | 14 +++++++------- src/librustc_trans/debuginfo/namespace.rs | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 09059cc378a..387f24378ce 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -68,7 +68,6 @@ pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0; // ptr::null() doesn't work :( -pub const NO_FILE_METADATA: DIFile = (0 as DIFile); pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope); const FLAGS_NONE: c_uint = 0; @@ -616,7 +615,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, unsafe { llvm::LLVMDIBuilderCreateSubroutineType( DIB(cx), - NO_FILE_METADATA, + unknown_file_metadata(cx), create_DIArray(DIB(cx), &signature_metadata[..])) }, false); @@ -653,6 +652,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id); let trait_llvm_type = type_of::type_of(cx, trait_object_type); + let file_metadata = unknown_file_metadata(cx); composite_type_metadata(cx, trait_llvm_type, @@ -660,7 +660,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, unique_type_id, &[], containing_scope, - NO_FILE_METADATA, + file_metadata, syntax_pos::DUMMY_SP) } @@ -1628,7 +1628,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, DIB(cx), containing_scope, name.as_ptr(), - NO_FILE_METADATA, + file_metadata, UNKNOWN_LINE_NUMBER, bytes_to_bits(discriminant_size), bytes_to_bits(discriminant_align), @@ -1774,7 +1774,7 @@ fn set_members_of_composite_type(cx: &CrateContext, DIB(cx), composite_type_metadata, member_name.as_ptr(), - NO_FILE_METADATA, + unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, bytes_to_bits(member_size), bytes_to_bits(member_align), @@ -1817,7 +1817,7 @@ fn create_struct_stub(cx: &CrateContext, DIB(cx), containing_scope, name.as_ptr(), - NO_FILE_METADATA, + unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, bytes_to_bits(struct_size), bytes_to_bits(struct_align), @@ -1857,7 +1857,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, let loc = span_start(cx, span); (file_metadata(cx, &loc.file.name, &loc.file.abs_path), loc.line as c_uint) } else { - (NO_FILE_METADATA, UNKNOWN_LINE_NUMBER) + (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) }; let is_local_to_unit = is_node_local_to_unit(cx, node_id); diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index 167229ddfd9..736a8c1c7d7 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -10,7 +10,7 @@ // Namespace Handling. -use super::metadata::{file_metadata, NO_FILE_METADATA, UNKNOWN_LINE_NUMBER}; +use super::metadata::{file_metadata, unknown_file_metadata, UNKNOWN_LINE_NUMBER}; use super::utils::{DIB, debug_context, span_start}; use llvm; @@ -74,7 +74,7 @@ pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope { let loc = span_start(ccx, span); (file_metadata(ccx, &loc.file.name, &loc.file.abs_path), loc.line as c_uint) } else { - (NO_FILE_METADATA, UNKNOWN_LINE_NUMBER) + (unknown_file_metadata(ccx), UNKNOWN_LINE_NUMBER) }; let scope = unsafe { From f38762a881255812d8ec9d7b0309b513bed9b8b5 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Wed, 27 Jul 2016 00:18:19 +0200 Subject: [PATCH 30/33] [LLVM-3.9] Use llvm-3.9 branch --- src/llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm b/src/llvm index 6879bb3b6ac..e31fa33700c 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 6879bb3b6ac975987250b10314e7e4069846e8c1 +Subproject commit e31fa33700cdb1a1e6964247f3d222b4b4d33ff7 From 52430727cd45611b2d308d2e57fc6b71e2c902d8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 26 Jul 2016 15:09:39 -0700 Subject: [PATCH 31/33] test: Fix a test on MSVC Apparently MSVC now has namespaces in backtraces! --- src/test/run-pass/backtrace.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index ad38dc8f452..f1ce17c0736 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -46,19 +46,7 @@ fn template(me: &str) -> Command { } fn expected(fn_name: &str) -> String { - // FIXME(#32481) - // - // On windows, we read the function name from debuginfo using some - // system APIs. For whatever reason, these APIs seem to use the - // "name" field, which is only the "relative" name, not the full - // name with namespace info, so we just see `foo` and not - // `backtrace::foo` as we see on linux (which uses the linkage - // name). - if cfg!(windows) && cfg!(target_env = "msvc") { - format!(" - {}", fn_name) - } else { - format!(" - backtrace::{}", fn_name) - } + format!(" - backtrace::{}", fn_name) } fn runtest(me: &str) { From 7c0cd30c4b49905cb9ddf83daa3acfc77906ff91 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Fri, 29 Jul 2016 10:26:56 +0200 Subject: [PATCH 32/33] Update LLVM again --- src/llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm b/src/llvm index e31fa33700c..327e422d9b9 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit e31fa33700cdb1a1e6964247f3d222b4b4d33ff7 +Subproject commit 327e422d9b9df5bc02d947b69d8020817b5a2bfc From 5d1d2475232d06b2a315d87481898819bb547f97 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Mon, 1 Aug 2016 10:14:30 +0200 Subject: [PATCH 33/33] Upgrade LLVM once more to get a bugfix @tmiasko did some digging and discovered that https://reviews.llvm.org/D22858 may be relevant. --- src/llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm b/src/llvm index 327e422d9b9..d1cc48989b1 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 327e422d9b9df5bc02d947b69d8020817b5a2bfc +Subproject commit d1cc48989b13780f21c408fef17dceb104a09c9d