use callee;
use common::{C_bool, C_bytes_in_context, C_i32, C_uint};
use collector::{self, TransItemCollectionMode};
-use common::{C_struct_in_context, C_u64, C_undef};
+use common::{C_struct_in_context, C_u64, C_undef, C_array};
use common::CrateContext;
use common::{type_is_zero_size, val_ty};
use common;
n_bytes: ValueRef,
align: u32) {
let ccx = b.ccx;
- let ptr_width = &ccx.sess().target.target.target_pointer_width[..];
+ let ptr_width = &ccx.sess().target.target.target_pointer_width;
let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
let memcpy = ccx.get_intrinsic(&key);
let src_ptr = b.pointercast(src, Type::i8p(ccx));
size: ValueRef,
align: ValueRef,
volatile: bool) -> ValueRef {
- let ptr_width = &b.ccx.sess().target.target.target_pointer_width[..];
+ let ptr_width = &b.ccx.sess().target.target.target_pointer_width;
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
let llintrinsicfn = b.ccx.get_intrinsic(&intrinsic_key);
let volatile = C_bool(b.ccx, volatile);
ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1);
- if !ccx.sess().no_landing_pads() {
+ // The `uwtable` attribute according to LLVM is:
+ //
+ // This attribute indicates that the ABI being targeted requires that an
+ // unwind table entry be produced for this function even if we can show
+ // that no exceptions passes by it. This is normally the case for the
+ // ELF x86-64 abi, but it can be disabled for some compilation units.
+ //
+ // Typically when we're compiling with `-C panic=abort` (which implies this
+ // `no_landing_pads` check) we don't need `uwtable` because we can't
+ // generate any exceptions! On Windows, however, exceptions include other
+ // events such as illegal instructions, segfaults, etc. This means that on
+ // Windows we end up still needing the `uwtable` attribute even if the `-C
+ // panic=abort` flag is passed.
+ //
+ // You can also find more info on why Windows is whitelisted here in:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1302078
+ if !ccx.sess().no_landing_pads() ||
+ ccx.sess().target.target.options.is_like_windows {
attributes::emit_uwtable(lldecl, true);
}
let cstore = &cx.tcx().sess.cstore;
let metadata = cstore.encode_metadata(cx.tcx(),
- cx.export_map(),
cx.link_meta(),
exported_symbols);
if kind == MetadataKind::Uncompressed {
let mut compressed = cstore.metadata_encoding_version().to_vec();
compressed.extend_from_slice(&flate::deflate_bytes(&metadata));
- let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]);
+ let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed);
let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
let name = cx.metadata_symbol_name();
let buf = CString::new(name).unwrap();
symbol_map: &SymbolMap<'tcx>,
exported_symbols: &ExportedSymbols) {
let export_threshold =
- symbol_export::crates_export_threshold(&sess.crate_types.borrow()[..]);
+ symbol_export::crates_export_threshold(&sess.crate_types.borrow());
let exported_symbols = exported_symbols
.exported_symbols(LOCAL_CRATE)
(generics.parent_types == 0 && generics.types.is_empty()) &&
// Functions marked with #[inline] are only ever translated
// with "internal" linkage and are never exported.
- !attr::requests_inline(&attributes[..])
+ !attr::requests_inline(&attributes)
}
_ => false
// particular items that will be processed.
let krate = tcx.hir.krate();
- let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis;
+ let ty::CrateAnalysis { reachable, name, .. } = analysis;
let exported_symbols = find_exported_symbols(tcx, reachable);
let check_overflow = tcx.sess.overflow_checks();
let link_meta = link::build_link_meta(incremental_hashes_map, &name);
let shared_ccx = SharedCrateContext::new(tcx,
- export_map,
link_meta.clone(),
exported_symbols,
check_overflow);
}
}
+ // Create the llvm.used variable
+ // This variable has type [N x i8*] and is stored in the llvm.metadata section
+ if !ccx.used_statics().borrow().is_empty() {
+ let name = CString::new("llvm.used").unwrap();
+ let section = CString::new("llvm.metadata").unwrap();
+ let array = C_array(Type::i8(&ccx).ptr_to(), &*ccx.used_statics().borrow());
+
+ unsafe {
+ let g = llvm::LLVMAddGlobal(ccx.llmod(),
+ val_ty(array).to_ref(),
+ name.as_ptr());
+ llvm::LLVMSetInitializer(g, array);
+ llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
+ llvm::LLVMSetSection(g, section.as_ptr());
+ }
+ }
+
// Finalize debuginfo
if ccx.sess().opts.debuginfo != NoDebugInfo {
debuginfo::finalize(&ccx);
cgus.dedup();
for &(ref cgu_name, linkage) in cgus.iter() {
output.push_str(" ");
- output.push_str(&cgu_name[..]);
+ output.push_str(&cgu_name);
let linkage_abbrev = match linkage {
llvm::Linkage::ExternalLinkage => "External",