diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 56ff5ebb069ea..84b9c5e72decf 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -701,7 +701,7 @@ pub fn maybe_create_entry_wrapper(ccx: &CrateContext) { let bld = Builder::new_block(ccx, llfn, "top"); - debuginfo::gdb::insert_reference_to_gdb_debug_scripts_section_global(ccx, &bld); + debuginfo::gdb::insert_reference_to_gdb_debug_scripts_section_global(ccx); let (start_fn, args) = if use_start_lang_item { let start_def_id = ccx.tcx().require_lang_item(StartFnLangItem); @@ -785,17 +785,19 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, tcx.sess.cstore.metadata_section_name(&tcx.sess.target.target); let name = CString::new(section_name).unwrap(); llvm::LLVMSetSection(llglobal, name.as_ptr()); - - // Also generate a .section directive to force no - // flags, at least for ELF outputs, so that the - // metadata doesn't get loaded into memory. - let directive = format!(".section {}", section_name); - let directive = CString::new(directive).unwrap(); - llvm::LLVMSetModuleInlineAsm(metadata_llmod, directive.as_ptr()) + make_section_non_loadable(metadata_llmod, section_name); } return (metadata_llcx, metadata_llmod, metadata); } +/// Generate a .section directive to force no flags (e.g. for ELF outputs) +/// so that the contents of that section don't get loaded into memory. +pub unsafe fn make_section_non_loadable(llmod: ModuleRef, section: &str) { + let directive = format!(".section {}", section); + let directive = CString::new(directive).unwrap(); + llvm::LLVMSetModuleInlineAsm(llmod, directive.as_ptr()) +} + /// Find any symbols that are defined in one compilation unit, but not declared /// in any other compilation unit. Give these symbols internal linkage. fn internalize_symbols<'a, 'tcx>(sess: &Session, diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 6afb340107d66..916479cf201b2 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -273,7 +273,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, if attr::contains_name(attrs, "used") { // This static will be stored in the llvm.used variable which is an array of i8* - let cast = llvm::LLVMConstPointerCast(g, Type::i8p(ccx).to_ref()); + let cast = ptrcast(g, Type::i8p(ccx)); ccx.used_statics().borrow_mut().push(cast); } diff --git a/src/librustc_trans/debuginfo/gdb.rs b/src/librustc_trans/debuginfo/gdb.rs index 4567ec8b452df..cb2d575eec958 100644 --- a/src/librustc_trans/debuginfo/gdb.rs +++ b/src/librustc_trans/debuginfo/gdb.rs @@ -12,8 +12,9 @@ use llvm; -use common::{C_bytes, CrateContext, C_i32}; -use builder::Builder; +use common::{C_bytes, CrateContext}; +use base; +use consts; use declare; use type_::Type; use session::config::NoDebugInfo; @@ -22,19 +23,13 @@ use std::ptr; use syntax::attr; -/// Inserts a side-effect free instruction sequence that makes sure that the -/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. -pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext, builder: &Builder) { +/// Inserts the .debug_gdb_scripts global into the set of symbols +/// to be placed in `llvm.used`, so it isn't removed by the linker. +pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext) { if needs_gdb_debug_scripts_section(ccx) { let gdb_debug_scripts_section_global = get_or_insert_gdb_debug_scripts_section_global(ccx); - // Load just the first byte as that's all that's necessary to force - // LLVM to keep around the reference to the global. - let indices = [C_i32(ccx, 0), C_i32(ccx, 0)]; - let element = builder.inbounds_gep(gdb_debug_scripts_section_global, &indices); - let volative_load_instruction = builder.volatile_load(element); - unsafe { - llvm::LLVMSetAlignment(volative_load_instruction, 1); - } + let cast = consts::ptrcast(gdb_debug_scripts_section_global, Type::i8p(ccx)); + ccx.used_statics().borrow_mut().push(cast); } } @@ -51,7 +46,9 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext) }; if section_var == ptr::null_mut() { - let section_name = b".debug_gdb_scripts\0"; + let c_section_name = ".debug_gdb_scripts\0"; + let section_name = &c_section_name[..c_section_name.len()-1]; + let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; unsafe { @@ -62,7 +59,8 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext) llvm_type).unwrap_or_else(||{ bug!("symbol `{}` is already defined", section_var_name) }); - llvm::LLVMSetSection(section_var, section_name.as_ptr() as *const _); + llvm::LLVMSetSection(section_var, c_section_name.as_ptr() as *const _); + base::make_section_non_loadable(ccx.llmod(), section_name); llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents)); llvm::LLVMSetGlobalConstant(section_var, llvm::True); llvm::LLVMSetUnnamedAddr(section_var, llvm::True);