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.
This commit is contained in:
parent
342aad1d1b
commit
a390803782
src
librustc_codegen_llvm/back
librustc_codegen_ssa/back
librustc_target/spec
@ -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<LlvmCodegenBackend>,
|
||||
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),
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
},
|
||||
})
|
||||
|
@ -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<u64>,
|
||||
@ -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<u64>);
|
||||
key!(min_atomic_width, Option<u64>);
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user