diff options
| author | Irina Popa <irinagpopa@gmail.com> | 2018-05-08 16:10:16 +0300 |
|---|---|---|
| committer | Irina Popa <irinagpopa@gmail.com> | 2018-05-17 15:08:30 +0300 |
| commit | b63d7e2b1c4019e40051036bcb1fd5f254a8f6e2 (patch) | |
| tree | 314792e2f467d17181d29d4988550058197ac029 /src/librustc_codegen_llvm/debuginfo/gdb.rs | |
| parent | e3150564f889a3bad01795d9fcb31d4f14d58a99 (diff) | |
| download | rust-b63d7e2b1c4019e40051036bcb1fd5f254a8f6e2.tar.gz rust-b63d7e2b1c4019e40051036bcb1fd5f254a8f6e2.zip | |
Rename trans to codegen everywhere.
Diffstat (limited to 'src/librustc_codegen_llvm/debuginfo/gdb.rs')
| -rw-r--r-- | src/librustc_codegen_llvm/debuginfo/gdb.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs new file mode 100644 index 00000000000..0b4858c7ab0 --- /dev/null +++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs @@ -0,0 +1,88 @@ +// Copyright 2015 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. + +// .debug_gdb_scripts binary section. + +use llvm; + +use common::{C_bytes, CodegenCx, C_i32}; +use builder::Builder; +use declare; +use type_::Type; +use rustc::session::config::NoDebugInfo; + +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(bx: &Builder) { + if needs_gdb_debug_scripts_section(bx.cx) { + let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx.cx); + // 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(bx.cx, 0), C_i32(bx.cx, 0)]; + let element = bx.inbounds_gep(gdb_debug_scripts_section, &indices); + let volative_load_instruction = bx.volatile_load(element); + unsafe { + llvm::LLVMSetAlignment(volative_load_instruction, 1); + } + } +} + +/// Allocates the global variable responsible for the .debug_gdb_scripts binary +/// section. +pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx) + -> llvm::ValueRef { + let c_section_var_name = "__rustc_debug_gdb_scripts_section__\0"; + let section_var_name = &c_section_var_name[..c_section_var_name.len()-1]; + + let section_var = unsafe { + llvm::LLVMGetNamedGlobal(cx.llmod, + c_section_var_name.as_ptr() as *const _) + }; + + if section_var == ptr::null_mut() { + let section_name = b".debug_gdb_scripts\0"; + let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; + + unsafe { + let llvm_type = Type::array(&Type::i8(cx), + section_contents.len() as u64); + + let section_var = declare::define_global(cx, section_var_name, + llvm_type).unwrap_or_else(||{ + bug!("symbol `{}` is already defined", section_var_name) + }); + llvm::LLVMSetSection(section_var, section_name.as_ptr() as *const _); + llvm::LLVMSetInitializer(section_var, C_bytes(cx, section_contents)); + llvm::LLVMSetGlobalConstant(section_var, llvm::True); + llvm::LLVMSetUnnamedAddr(section_var, llvm::True); + llvm::LLVMRustSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage); + // This should make sure that the whole section is not larger than + // the string it contains. Otherwise we get a warning from GDB. + llvm::LLVMSetAlignment(section_var, 1); + section_var + } + } else { + section_var + } +} + +pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx) -> bool { + let omit_gdb_pretty_printer_section = + attr::contains_name(&cx.tcx.hir.krate_attrs(), + "omit_gdb_pretty_printer_section"); + + !omit_gdb_pretty_printer_section && + cx.sess().opts.debuginfo != NoDebugInfo && + cx.sess().target.target.options.emit_debug_gdb_scripts +} |
