rust/src/librustc_trans/trans/debuginfo/gdb.rs
Jared Roesch 9faae6a5ca Remove Typer and ClosureTyper
This commit finalizes the work of the past commits by fully moving the fulfillment context into
the InferCtxt, cleaning up related context interfaces, removing the Typer and ClosureTyper
traits and cleaning up related intefaces
2015-06-30 02:41:40 -07:00

94 lines
3.6 KiB
Rust

// 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 llvm::ValueRef;
use trans::common::{C_bytes, CrateContext};
use trans::declare;
use trans::type_::Type;
use session::config::NoDebugInfo;
use std::ffi::CString;
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) {
if needs_gdb_debug_scripts_section(ccx) {
let empty = CString::new("").unwrap();
let gdb_debug_scripts_section_global =
get_or_insert_gdb_debug_scripts_section_global(ccx);
unsafe {
let volative_load_instruction =
llvm::LLVMBuildLoad(ccx.raw_builder(),
gdb_debug_scripts_section_global,
empty.as_ptr());
llvm::LLVMSetVolatile(volative_load_instruction, llvm::True);
}
}
}
/// Allocates the global variable responsible for the .debug_gdb_scripts binary
/// section.
pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
-> llvm::ValueRef {
let section_var_name = "__rustc_debug_gdb_scripts_section__";
let section_var = unsafe {
llvm::LLVMGetNamedGlobal(ccx.llmod(),
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(ccx),
section_contents.len() as u64);
let section_var = declare::define_global(ccx, section_var_name,
llvm_type).unwrap_or_else(||{
ccx.sess().bug(&format!("symbol `{}` is already defined", section_var_name))
});
llvm::LLVMSetSection(section_var, section_name.as_ptr() as *const _);
llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents));
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
llvm::SetLinkage(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(ccx: &CrateContext) -> bool {
let omit_gdb_pretty_printer_section =
attr::contains_name(&ccx.tcx()
.map
.krate()
.attrs,
"omit_gdb_pretty_printer_section");
!omit_gdb_pretty_printer_section &&
!ccx.sess().target.target.options.is_like_osx &&
!ccx.sess().target.target.options.is_like_windows &&
ccx.sess().opts.debuginfo != NoDebugInfo
}