use session::config;
use syntax::ast;
use trans::CrateTranslation;
-use trans::link_guard;
/// Linker abstraction used by back::link to build up the command to invoke a
/// linker.
writeln!(f, " {}", symbol)?;
}
- // Add link-guard symbols
- {
- // local crate
- let symbol = link_guard::link_guard_name(&trans.link.crate_name[..],
- &trans.link.crate_hash);
- try!(writeln!(f, " {}", symbol));
- }
- // statically linked dependencies
- for (i, format) in formats[&CrateTypeDylib].iter().enumerate() {
- if *format == Linkage::Static {
- let cnum = (i + 1) as ast::CrateNum;
- let crate_name = cstore.original_crate_name(cnum);
- let svh = cstore.crate_hash(cnum);
-
- let symbol = link_guard::link_guard_name(&crate_name[..], &svh);
- try!(writeln!(f, " {}", symbol));
- }
- }
-
Ok(())
})();
if let Err(e) = res {
use trans::glue;
use trans::inline;
use trans::intrinsic;
-use trans::link_guard;
use trans::machine;
use trans::machine::{llalign_of_min, llsize_of, llsize_of_real};
use trans::meth;
unsafe {
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
- link_guard::insert_reference_to_link_guard(ccx, llbb);
debuginfo::gdb::insert_reference_to_gdb_debug_scripts_section_global(ccx);
let (start_fn, args) = if use_start_lang_item {
symbol_names_test::report_symbol_names(&ccx);
}
- emit_link_guard_if_necessary(&shared_ccx);
-
for ccx in shared_ccx.iter() {
if ccx.sess().opts.debuginfo != NoDebugInfo {
debuginfo::finalize(&ccx);
if sess.entry_fn.borrow().is_some() {
reachable_symbols.push("main".to_string());
}
- reachable_symbols.push(link_guard::link_guard_name(&link_meta.crate_name,
- &link_meta.crate_hash));
// For the purposes of LTO, we add to the reachable set all of the upstream
// reachable extern fns. These functions are all part of the public ABI of
}
}
-fn emit_link_guard_if_necessary(shared_ccx: &SharedCrateContext) {
- let link_meta = shared_ccx.link_meta();
- let link_guard_name = link_guard::link_guard_name(&link_meta.crate_name,
- &link_meta.crate_hash);
- let link_guard_name = CString::new(link_guard_name).unwrap();
-
- // Check if the link-guard has already been emitted in a codegen unit
- let link_guard_already_emitted = shared_ccx.iter().any(|ccx| {
- let link_guard = unsafe { llvm::LLVMGetNamedValue(ccx.llmod(),
- link_guard_name.as_ptr()) };
- !link_guard.is_null()
- });
-
- if !link_guard_already_emitted {
- link_guard::get_or_insert_link_guard(&shared_ccx.get_ccx(0));
- }
-}
-
/// We visit all the items in the krate and translate them. We do
/// this in two walks. The first walk just finds module items. It then
/// walks the full contents of those module items and translates all
+++ /dev/null
-// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use back::svh::Svh;
-use libc::c_uint;
-use llvm;
-use std::ffi::CString;
-use std::ptr;
-use trans::attributes;
-use trans::builder;
-use trans::CrateContext;
-use trans::declare;
-use trans::type_::Type;
-
-const GUARD_PREFIX: &'static str = "__rustc_link_guard_";
-
-pub fn link_guard_name(crate_name: &str, crate_svh: &Svh) -> String {
-
- let mut guard_name = String::new();
-
- guard_name.push_str(GUARD_PREFIX);
- guard_name.push_str(crate_name);
- guard_name.push_str("_");
- guard_name.push_str(crate_svh.as_str());
-
- guard_name
-}
-
-pub fn get_or_insert_link_guard<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>)
- -> llvm::ValueRef {
-
- let guard_name = link_guard_name(&ccx.tcx().crate_name[..],
- &ccx.link_meta().crate_hash);
-
- let guard_function = unsafe {
- let guard_name_c_string = CString::new(&guard_name[..]).unwrap();
- llvm::LLVMGetNamedValue(ccx.llmod(), guard_name_c_string.as_ptr())
- };
-
- if guard_function != ptr::null_mut() {
- return guard_function;
- }
-
- let llfty = Type::func(&[], &Type::void(ccx));
- if declare::get_defined_value(ccx, &guard_name[..]).is_some() {
- ccx.sess().bug(
- &format!("Link guard already defined"));
- }
- let guard_function = declare::declare_cfn(ccx, &guard_name[..], llfty);
-
- attributes::emit_uwtable(guard_function, true);
- attributes::unwind(guard_function, false);
-
- let bld = ccx.raw_builder();
- unsafe {
- let llbb = llvm::LLVMAppendBasicBlockInContext(ccx.llcx(),
- guard_function,
- "link_guard_top\0".as_ptr() as *const _);
- llvm::LLVMPositionBuilderAtEnd(bld, llbb);
-
- for crate_num in ccx.sess().cstore.crates() {
- if !ccx.sess().cstore.is_explicitly_linked(crate_num) {
- continue;
- }
-
- let crate_name = ccx.sess().cstore.original_crate_name(crate_num);
- let svh = ccx.sess().cstore.crate_hash(crate_num);
-
- let dependency_guard_name = link_guard_name(&crate_name[..], &svh);
-
- if declare::get_defined_value(ccx, &dependency_guard_name[..]).is_some() {
- ccx.sess().bug(
- &format!("Link guard already defined for dependency `{}`",
- crate_name));
- }
- let decl = declare::declare_cfn(ccx, &dependency_guard_name[..], llfty);
- attributes::unwind(decl, false);
-
- llvm::LLVMPositionBuilderAtEnd(bld, llbb);
-
- let args: &[llvm::ValueRef] = &[];
- llvm::LLVMRustBuildCall(bld,
- decl,
- args.as_ptr(),
- args.len() as c_uint,
- 0 as *mut _,
- builder::noname());
- }
-
- llvm::LLVMBuildRetVoid(bld);
- }
-
- guard_function
-}
-
-pub fn insert_reference_to_link_guard<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
- llbb: llvm::BasicBlockRef) {
- let guard_function = get_or_insert_link_guard(ccx);
-
- unsafe {
- llvm::LLVMPositionBuilderAtEnd(ccx.raw_builder(), llbb);
- let args: &[llvm::ValueRef] = &[];
- llvm::LLVMRustBuildCall(ccx.raw_builder(),
- guard_function,
- args.as_ptr(),
- args.len() as c_uint,
- 0 as *mut _,
- builder::noname());
- }
-}