Skip to content

Preserve the .debug_gdb_scripts section #143679

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions compiler/rustc_codegen_gcc/src/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
_variable_alloca.set_location(_dbg_loc);
}

fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
// TODO(antoyo): insert reference to gdb debug scripts section global.
}

/// FIXME(tempdragon): Currently, this function is not yet implemented. It seems that the
/// debug name and the mangled name should both be included in the LValues.
/// Besides, a function to get the rvalue type(m_is_lvalue) should also be included.
Expand Down Expand Up @@ -254,7 +250,8 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
// TODO(antoyo): implement.
}

fn debuginfo_finalize(&self) {
fn debuginfo_finalize(&mut self) {
// TODO: emit section `.debug_gdb_scripts`.
self.context.set_debug_info(true)
}

Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,16 @@ pub(crate) fn compile_codegen_unit(
}

// Finalize code coverage by injecting the coverage map. Note, the coverage map will
// also be added to the `llvm.compiler.used` variable, created next.
// also be added to the `llvm.compiler.used` variable, created below.
if cx.sess().instrument_coverage() {
cx.coverageinfo_finalize();
}

// Finalize debuginfo. This adds to `llvm.used`, created below.
if cx.sess().opts.debuginfo != DebugInfo::None {
cx.debuginfo_finalize();
}

// Create the llvm.used and llvm.compiler.used variables.
if !cx.used_statics.is_empty() {
cx.create_used_variable_impl(c"llvm.used", &cx.used_statics);
Expand All @@ -130,11 +135,6 @@ pub(crate) fn compile_codegen_unit(
llvm::LLVMDeleteGlobal(old_g);
}
}

// Finalize debuginfo
if cx.sess().opts.debuginfo != DebugInfo::None {
cx.debuginfo_finalize();
}
}

ModuleCodegen::new_regular(cgu_name.to_string(), llvm_module)
Expand Down
28 changes: 11 additions & 17 deletions compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// .debug_gdb_scripts binary section.

use std::ffi::CString;

use rustc_ast::attr;
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
use rustc_codegen_ssa::traits::*;
Expand All @@ -9,31 +11,21 @@ use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType;
use rustc_session::config::{CrateType, DebugInfo};
use rustc_span::sym;

use crate::builder::Builder;
use crate::common::CodegenCx;
use crate::llvm;
use crate::value::Value;

/// 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(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
if needs_gdb_debug_scripts_section(bx) {
let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
// Load just the first byte as that's all that's necessary to force
// LLVM to keep around the reference to the global.
let volatile_load_instruction = bx.volatile_load(bx.type_i8(), gdb_debug_scripts_section);
unsafe {
llvm::LLVMSetAlignment(volatile_load_instruction, 1);
}
}
}

/// Allocates the global variable responsible for the .debug_gdb_scripts binary
/// section.
pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
cx: &CodegenCx<'ll, '_>,
cx: &mut CodegenCx<'ll, '_>,
) -> &'ll Value {
let c_section_var_name = c"__rustc_debug_gdb_scripts_section__";
let c_section_var_name = CString::new(format!(
"__rustc_debug_gdb_scripts_section_{}_{:08x}",
cx.tcx.crate_name(LOCAL_CRATE),
cx.tcx.stable_crate_id(LOCAL_CRATE),
))
.unwrap();
let section_var_name = c_section_var_name.to_str().unwrap();

let section_var = unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr()) };
Expand Down Expand Up @@ -80,6 +72,8 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
// 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);
// Make sure that the linker doesn't optimize the global away.
cx.add_used_global(section_var);
section_var
}
})
Expand Down
34 changes: 16 additions & 18 deletions compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use tracing::debug;

use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node};
use self::namespace::mangled_name_of_instance;
use self::utils::{DIB, create_DIArray, is_node_local_to_unit};
use self::utils::{DIB, create_DIArray, debug_context, is_node_local_to_unit};
use crate::builder::Builder;
use crate::common::{AsCCharPtr, CodegenCx};
use crate::llvm;
Expand Down Expand Up @@ -131,20 +131,22 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
}

/// Creates any deferred debug metadata nodes
pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
if let Some(dbg_cx) = &cx.dbg_cx {
debug!("finalize");

if gdb::needs_gdb_debug_scripts_section(cx) {
// Add a .debug_gdb_scripts section to this compile-unit. This will
// cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
// which activates the Rust pretty printers for binary this section is
// contained in.
gdb::get_or_insert_gdb_debug_scripts_section_global(cx);
}
pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) {
if cx.dbg_cx.is_none() {
return;
}

debug!("finalize");

dbg_cx.finalize(cx.sess());
if gdb::needs_gdb_debug_scripts_section(cx) {
// Add a .debug_gdb_scripts section to this compile-unit. This will
// cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
// which activates the Rust pretty printers for binary this section is
// contained in.
gdb::get_or_insert_gdb_debug_scripts_section_global(cx);
}

debug_context(cx).finalize(cx.sess());
}

impl<'ll> Builder<'_, 'll, '_> {
Expand Down Expand Up @@ -215,10 +217,6 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
}
}

fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
gdb::insert_reference_to_gdb_debug_scripts_section_global(self)
}

fn set_var_name(&mut self, value: &'ll Value, name: &str) {
// Avoid wasting time if LLVM value names aren't even enabled.
if self.sess().fewer_names() {
Expand Down Expand Up @@ -614,7 +612,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
metadata::extend_scope_to_file(self, scope_metadata, file)
}

fn debuginfo_finalize(&self) {
fn debuginfo_finalize(&mut self) {
finalize(self)
}

Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,6 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let llbb = Bx::append_block(cx, llfn, "top");
let mut bx = Bx::build(cx, llbb);

bx.insert_reference_to_gdb_debug_scripts_section_global();

let isize_ty = cx.type_isize();
let ptr_ty = cx.type_ptr();
let (arg_argc, arg_argv) = get_argc_argv(&mut bx);
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
scope_metadata: Self::DIScope,
file: &SourceFile,
) -> Self::DIScope;
fn debuginfo_finalize(&self);
fn debuginfo_finalize(&mut self);

// FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
Expand Down Expand Up @@ -81,6 +81,5 @@ pub trait DebugInfoBuilderMethods: BackendTypes {
);
fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation);
fn clear_dbg_loc(&mut self);
fn insert_reference_to_gdb_debug_scripts_section_global(&mut self);
fn set_var_name(&mut self, value: Self::Value, name: &str);
}
1 change: 1 addition & 0 deletions src/tools/compiletest/src/directive-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"ignore-gnu",
"ignore-haiku",
"ignore-horizon",
"ignore-i586-unknown-linux-gnu",
"ignore-i686-pc-windows-gnu",
"ignore-i686-pc-windows-msvc",
"ignore-illumos",
Expand Down
26 changes: 3 additions & 23 deletions tests/codegen/gdb_debug_script_load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,14 @@
//@ ignore-wasm
//@ ignore-emscripten

//@ compile-flags: -g -C no-prepopulate-passes -Cpanic=abort
//@ compile-flags: -g -Cpanic=abort

#![feature(lang_items)]
#![no_std]
#![no_main]

#[panic_handler]
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
loop {}
}

#[no_mangle]
extern "C" fn rust_eh_personality() {
loop {}
}

// Needs rustc to generate `main` as that's where the magic load is inserted.
// IOW, we cannot write this test with `#![no_main]`.
// CHECK-LABEL: @main
// CHECK: load volatile i8, {{.+}} @__rustc_debug_gdb_scripts_section__

#[lang = "start"]
fn lang_start<T: 'static>(
_main: fn() -> T,
_argc: isize,
_argv: *const *const u8,
_sigpipe: u8,
) -> isize {
return 0;
}

fn main() {}
// CHECK: @llvm.used = {{.+}} @__rustc_debug_gdb_scripts_section
1 change: 1 addition & 0 deletions tests/debuginfo/embedded-visualizer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//@ compile-flags:-g
//@ ignore-lldb
//@ ignore-windows-gnu: #128981
//@ ignore-i586-unknown-linux-gnu: linker too old in CI

// === CDB TESTS ==================================================================================

Expand Down
Loading