diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 394e2f332cb2..d8faa82a8944 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -651,10 +651,10 @@ pub(crate) unsafe fn codegen( "LLVM_module_codegen_embed_bitcode", &module.name[..], ); - embed_bitcode(cgcx, llcx, llmod, Some(data)); + embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, Some(data)); } } else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) { - embed_bitcode(cgcx, llcx, llmod, None); + embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, None); } if config.emit_ir { @@ -777,8 +777,8 @@ pub(crate) unsafe fn codegen( /// * __LLVM,__cmdline /// /// It appears *both* of these sections are necessary to get the linker to -/// recognize what's going on. For us though we just always throw in an empty -/// cmdline section. +/// recognize what's going on. A suitable cmdline value is taken from the +/// target spec. /// /// Furthermore debug/O1 builds don't actually embed bitcode but rather just /// embed an empty section. @@ -789,6 +789,7 @@ unsafe fn embed_bitcode( cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::Module, + cmdline: &str, bitcode: Option<&[u8]>, ) { let llconst = common::bytes_in_context(llcx, bitcode.unwrap_or(&[])); @@ -800,14 +801,15 @@ unsafe fn embed_bitcode( llvm::LLVMSetInitializer(llglobal, llconst); let is_apple = cgcx.opts.target_triple.triple().contains("-ios") - || cgcx.opts.target_triple.triple().contains("-darwin"); + || cgcx.opts.target_triple.triple().contains("-darwin") + || cgcx.opts.target_triple.triple().contains("-tvos"); let section = if is_apple { "__LLVM,__bitcode\0" } else { ".llvmbc\0" }; llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); llvm::LLVMSetGlobalConstant(llglobal, llvm::True); - let llconst = common::bytes_in_context(llcx, &[]); + let llconst = common::bytes_in_context(llcx, cmdline.as_bytes()); let llglobal = llvm::LLVMAddGlobal( llmod, common::val_ty(llconst), diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 72c4539e8290..cae99f630c35 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -101,6 +101,7 @@ pub struct ModuleConfig { pub emit_ir: bool, pub emit_asm: bool, pub emit_obj: EmitObj, + pub bc_cmdline: String, // Miscellaneous flags. These are mostly copied from command-line // options. @@ -213,6 +214,7 @@ impl ModuleConfig { false ), emit_obj, + bc_cmdline: sess.target.target.options.bitcode_llvm_cmdline.clone(), verify_llvm_ir: sess.verify_llvm_ir(), no_prepopulate_passes: sess.opts.cg.no_prepopulate_passes, diff --git a/src/librustc_target/spec/aarch64_apple_ios.rs b/src/librustc_target/spec/aarch64_apple_ios.rs index 3ecedd769fae..eac2c3e6aa40 100644 --- a/src/librustc_target/spec/aarch64_apple_ios.rs +++ b/src/librustc_target/spec/aarch64_apple_ios.rs @@ -20,6 +20,17 @@ pub fn target() -> TargetResult { max_atomic_width: Some(128), abi_blacklist: super::arm_base::abi_blacklist(), forces_embed_bitcode: true, + // Taken from a clang build on Xcode 11.4.1. + // These arguments are not actually invoked - they just have + // to look right to pass App Store validation. + bitcode_llvm_cmdline: "-triple\0\ + arm64-apple-ios11.0.0\0\ + -emit-obj\0\ + -disable-llvm-passes\0\ + -target-abi\0\ + darwinpcs\0\ + -Os\0" + .to_string(), ..base }, }) diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 8b319a0e3811..51dce9e144ca 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -785,6 +785,8 @@ pub struct TargetOptions { pub obj_is_bitcode: bool, /// Whether the target requires that emitted object code includes bitcode. pub forces_embed_bitcode: bool, + /// Content of the LLVM cmdline section associated with embedded bitcode. + pub bitcode_llvm_cmdline: String, /// Don't use this field; instead use the `.min_atomic_width()` method. pub min_atomic_width: Option, @@ -942,6 +944,7 @@ impl Default for TargetOptions { has_elf_tls: false, obj_is_bitcode: false, forces_embed_bitcode: false, + bitcode_llvm_cmdline: String::new(), min_atomic_width: None, max_atomic_width: None, atomic_cas: true, @@ -1282,6 +1285,7 @@ impl Target { key!(has_elf_tls, bool); key!(obj_is_bitcode, bool); key!(forces_embed_bitcode, bool); + key!(bitcode_llvm_cmdline); key!(max_atomic_width, Option); key!(min_atomic_width, Option); key!(atomic_cas, bool); @@ -1510,6 +1514,7 @@ impl ToJson for Target { target_option_val!(has_elf_tls); target_option_val!(obj_is_bitcode); target_option_val!(forces_embed_bitcode); + target_option_val!(bitcode_llvm_cmdline); target_option_val!(min_atomic_width); target_option_val!(max_atomic_width); target_option_val!(atomic_cas);