Skip to content

Commit a390803

Browse files
committed
Provide configurable LLVM cmdline section via target spec
The App Store performs certain sanity checks on bitcode, including that an acceptable set of command line arguments was used when compiling a given module. For Rust code to be distributed on the app store with bitcode rustc must pretend to have the same command line arguments.
1 parent 342aad1 commit a390803

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

src/librustc_codegen_llvm/back/write.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -651,10 +651,10 @@ pub(crate) unsafe fn codegen(
651651
"LLVM_module_codegen_embed_bitcode",
652652
&module.name[..],
653653
);
654-
embed_bitcode(cgcx, llcx, llmod, Some(data));
654+
embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, Some(data));
655655
}
656656
} else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) {
657-
embed_bitcode(cgcx, llcx, llmod, None);
657+
embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, None);
658658
}
659659

660660
if config.emit_ir {
@@ -777,8 +777,8 @@ pub(crate) unsafe fn codegen(
777777
/// * __LLVM,__cmdline
778778
///
779779
/// It appears *both* of these sections are necessary to get the linker to
780-
/// recognize what's going on. For us though we just always throw in an empty
781-
/// cmdline section.
780+
/// recognize what's going on. A suitable cmdline value is taken from the
781+
/// target spec.
782782
///
783783
/// Furthermore debug/O1 builds don't actually embed bitcode but rather just
784784
/// embed an empty section.
@@ -789,6 +789,7 @@ unsafe fn embed_bitcode(
789789
cgcx: &CodegenContext<LlvmCodegenBackend>,
790790
llcx: &llvm::Context,
791791
llmod: &llvm::Module,
792+
cmdline: &str,
792793
bitcode: Option<&[u8]>,
793794
) {
794795
let llconst = common::bytes_in_context(llcx, bitcode.unwrap_or(&[]));
@@ -800,14 +801,15 @@ unsafe fn embed_bitcode(
800801
llvm::LLVMSetInitializer(llglobal, llconst);
801802

802803
let is_apple = cgcx.opts.target_triple.triple().contains("-ios")
803-
|| cgcx.opts.target_triple.triple().contains("-darwin");
804+
|| cgcx.opts.target_triple.triple().contains("-darwin")
805+
|| cgcx.opts.target_triple.triple().contains("-tvos");
804806

805807
let section = if is_apple { "__LLVM,__bitcode\0" } else { ".llvmbc\0" };
806808
llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
807809
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
808810
llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
809811

810-
let llconst = common::bytes_in_context(llcx, &[]);
812+
let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
811813
let llglobal = llvm::LLVMAddGlobal(
812814
llmod,
813815
common::val_ty(llconst),

src/librustc_codegen_ssa/back/write.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ pub struct ModuleConfig {
101101
pub emit_ir: bool,
102102
pub emit_asm: bool,
103103
pub emit_obj: EmitObj,
104+
pub bc_cmdline: String,
104105

105106
// Miscellaneous flags. These are mostly copied from command-line
106107
// options.
@@ -213,6 +214,7 @@ impl ModuleConfig {
213214
false
214215
),
215216
emit_obj,
217+
bc_cmdline: sess.target.target.options.bitcode_llvm_cmdline.clone(),
216218

217219
verify_llvm_ir: sess.verify_llvm_ir(),
218220
no_prepopulate_passes: sess.opts.cg.no_prepopulate_passes,

src/librustc_target/spec/aarch64_apple_ios.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ pub fn target() -> TargetResult {
2020
max_atomic_width: Some(128),
2121
abi_blacklist: super::arm_base::abi_blacklist(),
2222
forces_embed_bitcode: true,
23+
// Taken from a clang build on Xcode 11.4.1.
24+
// These arguments are not actually invoked - they just have
25+
// to look right to pass App Store validation.
26+
bitcode_llvm_cmdline: "-triple\0\
27+
arm64-apple-ios11.0.0\0\
28+
-emit-obj\0\
29+
-disable-llvm-passes\0\
30+
-target-abi\0\
31+
darwinpcs\0\
32+
-Os\0"
33+
.to_string(),
2334
..base
2435
},
2536
})

src/librustc_target/spec/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,8 @@ pub struct TargetOptions {
785785
pub obj_is_bitcode: bool,
786786
/// Whether the target requires that emitted object code includes bitcode.
787787
pub forces_embed_bitcode: bool,
788+
/// Content of the LLVM cmdline section associated with embedded bitcode.
789+
pub bitcode_llvm_cmdline: String,
788790

789791
/// Don't use this field; instead use the `.min_atomic_width()` method.
790792
pub min_atomic_width: Option<u64>,
@@ -942,6 +944,7 @@ impl Default for TargetOptions {
942944
has_elf_tls: false,
943945
obj_is_bitcode: false,
944946
forces_embed_bitcode: false,
947+
bitcode_llvm_cmdline: String::new(),
945948
min_atomic_width: None,
946949
max_atomic_width: None,
947950
atomic_cas: true,
@@ -1282,6 +1285,7 @@ impl Target {
12821285
key!(has_elf_tls, bool);
12831286
key!(obj_is_bitcode, bool);
12841287
key!(forces_embed_bitcode, bool);
1288+
key!(bitcode_llvm_cmdline);
12851289
key!(max_atomic_width, Option<u64>);
12861290
key!(min_atomic_width, Option<u64>);
12871291
key!(atomic_cas, bool);
@@ -1510,6 +1514,7 @@ impl ToJson for Target {
15101514
target_option_val!(has_elf_tls);
15111515
target_option_val!(obj_is_bitcode);
15121516
target_option_val!(forces_embed_bitcode);
1517+
target_option_val!(bitcode_llvm_cmdline);
15131518
target_option_val!(min_atomic_width);
15141519
target_option_val!(max_atomic_width);
15151520
target_option_val!(atomic_cas);

0 commit comments

Comments
 (0)