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:
Tom Karpiniec 2020-05-07 15:34:31 +10:00
parent 342aad1d1b
commit a390803782
4 changed files with 26 additions and 6 deletions
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);