]> git.proxmox.com Git - rustc.git/blame - src/librustc_codegen_llvm/debuginfo/gdb.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc_codegen_llvm / debuginfo / gdb.rs
CommitLineData
d9579d0f
AL
1// .debug_gdb_scripts binary section.
2
9fa01778 3use crate::llvm;
d9579d0f 4
9fa01778
XL
5use crate::common::CodegenCx;
6use crate::builder::Builder;
7use crate::value::Value;
b7449926 8use rustc::session::config::DebugInfo;
a1dfa0c6 9use rustc_codegen_ssa::traits::*;
60c5eb7d 10use rustc::bug;
d9579d0f 11
b039eaaf 12use syntax::attr;
48663c56 13use syntax::symbol::sym;
d9579d0f
AL
14
15
16/// Inserts a side-effect free instruction sequence that makes sure that the
17/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
9fa01778 18pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
a1dfa0c6
XL
19 if needs_gdb_debug_scripts_section(bx) {
20 let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
32a655c1
SL
21 // Load just the first byte as that's all that's necessary to force
22 // LLVM to keep around the reference to the global.
a1dfa0c6 23 let indices = [bx.const_i32(0), bx.const_i32(0)];
2c00a5a8
XL
24 let element = bx.inbounds_gep(gdb_debug_scripts_section, &indices);
25 let volative_load_instruction = bx.volatile_load(element);
d9579d0f 26 unsafe {
b039eaaf 27 llvm::LLVMSetAlignment(volative_load_instruction, 1);
d9579d0f
AL
28 }
29 }
30}
31
32/// Allocates the global variable responsible for the .debug_gdb_scripts binary
33/// section.
b7449926
XL
34pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>)
35 -> &'ll Value {
b039eaaf
SL
36 let c_section_var_name = "__rustc_debug_gdb_scripts_section__\0";
37 let section_var_name = &c_section_var_name[..c_section_var_name.len()-1];
d9579d0f
AL
38
39 let section_var = unsafe {
2c00a5a8 40 llvm::LLVMGetNamedGlobal(cx.llmod,
e74abb32 41 c_section_var_name.as_ptr().cast())
d9579d0f
AL
42 };
43
b7449926 44 section_var.unwrap_or_else(|| {
d9579d0f
AL
45 let section_name = b".debug_gdb_scripts\0";
46 let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
47
48 unsafe {
a1dfa0c6 49 let llvm_type = cx.type_array(cx.type_i8(),
d9579d0f
AL
50 section_contents.len() as u64);
51
a1dfa0c6 52 let section_var = cx.define_global(section_var_name,
d9579d0f 53 llvm_type).unwrap_or_else(||{
54a0048b 54 bug!("symbol `{}` is already defined", section_var_name)
d9579d0f 55 });
e74abb32 56 llvm::LLVMSetSection(section_var, section_name.as_ptr().cast());
a1dfa0c6 57 llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents));
d9579d0f
AL
58 llvm::LLVMSetGlobalConstant(section_var, llvm::True);
59 llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
9e0c209e 60 llvm::LLVMRustSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
d9579d0f
AL
61 // This should make sure that the whole section is not larger than
62 // the string it contains. Otherwise we get a warning from GDB.
63 llvm::LLVMSetAlignment(section_var, 1);
64 section_var
65 }
b7449926 66 })
d9579d0f
AL
67}
68
9fa01778 69pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
d9579d0f 70 let omit_gdb_pretty_printer_section =
48663c56 71 attr::contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
d9579d0f
AL
72
73 !omit_gdb_pretty_printer_section &&
b7449926 74 cx.sess().opts.debuginfo != DebugInfo::None &&
83c7162d 75 cx.sess().target.target.options.emit_debug_gdb_scripts
d9579d0f 76}