Skip to content

Commit 07de96b

Browse files
Preserve the .debug_gdb_scripts section
Make sure that compiler and linker don't optimize the section's contents away by adding the global holding the data to "llvm.used". This eliminates the need for a volatile load in the main shim; since the LLVM codegen backend is the only implementer of the corresponding trait function, remove it entirely.
1 parent 558d253 commit 07de96b

File tree

7 files changed

+37
-72
lines changed

7 files changed

+37
-72
lines changed

compiler/rustc_codegen_gcc/src/debuginfo.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
3636
_variable_alloca.set_location(_dbg_loc);
3737
}
3838

39-
fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
40-
// TODO(antoyo): insert reference to gdb debug scripts section global.
41-
}
42-
4339
/// FIXME(tempdragon): Currently, this function is not yet implemented. It seems that the
4440
/// debug name and the mangled name should both be included in the LValues.
4541
/// Besides, a function to get the rvalue type(m_is_lvalue) should also be included.
@@ -254,7 +250,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
254250
// TODO(antoyo): implement.
255251
}
256252

257-
fn debuginfo_finalize(&self) {
253+
fn debuginfo_finalize(&mut self) {
258254
self.context.set_debug_info(true)
259255
}
260256

compiler/rustc_codegen_llvm/src/base.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,16 @@ pub(crate) fn compile_codegen_unit(
109109
}
110110

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

117+
// Finalize debuginfo. This adds to `llvm.used`, created below.
118+
if cx.sess().opts.debuginfo != DebugInfo::None {
119+
cx.debuginfo_finalize();
120+
}
121+
117122
// Create the llvm.used and llvm.compiler.used variables.
118123
if !cx.used_statics.is_empty() {
119124
cx.create_used_variable_impl(c"llvm.used", &cx.used_statics);
@@ -130,11 +135,6 @@ pub(crate) fn compile_codegen_unit(
130135
llvm::LLVMDeleteGlobal(old_g);
131136
}
132137
}
133-
134-
// Finalize debuginfo
135-
if cx.sess().opts.debuginfo != DebugInfo::None {
136-
cx.debuginfo_finalize();
137-
}
138138
}
139139

140140
ModuleCodegen::new_regular(cgu_name.to_string(), llvm_module)

compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// .debug_gdb_scripts binary section.
22

3+
use std::ffi::CString;
4+
35
use rustc_ast::attr;
46
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
57
use rustc_codegen_ssa::traits::*;
@@ -9,31 +11,21 @@ use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType;
911
use rustc_session::config::{CrateType, DebugInfo};
1012
use rustc_span::sym;
1113

12-
use crate::builder::Builder;
1314
use crate::common::CodegenCx;
1415
use crate::llvm;
1516
use crate::value::Value;
1617

17-
/// Inserts a side-effect free instruction sequence that makes sure that the
18-
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
19-
pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
20-
if needs_gdb_debug_scripts_section(bx) {
21-
let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
22-
// Load just the first byte as that's all that's necessary to force
23-
// LLVM to keep around the reference to the global.
24-
let volatile_load_instruction = bx.volatile_load(bx.type_i8(), gdb_debug_scripts_section);
25-
unsafe {
26-
llvm::LLVMSetAlignment(volatile_load_instruction, 1);
27-
}
28-
}
29-
}
30-
3118
/// Allocates the global variable responsible for the .debug_gdb_scripts binary
3219
/// section.
3320
pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
34-
cx: &CodegenCx<'ll, '_>,
21+
cx: &mut CodegenCx<'ll, '_>,
3522
) -> &'ll Value {
36-
let c_section_var_name = c"__rustc_debug_gdb_scripts_section__";
23+
let c_section_var_name = CString::new(format!(
24+
"__rustc_debug_gdb_scripts_section_{}_{:08x}",
25+
cx.tcx.crate_name(LOCAL_CRATE),
26+
cx.tcx.stable_crate_id(LOCAL_CRATE),
27+
))
28+
.unwrap();
3729
let section_var_name = c_section_var_name.to_str().unwrap();
3830

3931
let section_var = unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr()) };
@@ -80,6 +72,8 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
8072
// This should make sure that the whole section is not larger than
8173
// the string it contains. Otherwise we get a warning from GDB.
8274
llvm::LLVMSetAlignment(section_var, 1);
75+
// Make sure that the linker doesn't optimize the global away.
76+
cx.add_used_global(section_var);
8377
section_var
8478
}
8579
})

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use tracing::debug;
3030

3131
use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node};
3232
use self::namespace::mangled_name_of_instance;
33-
use self::utils::{DIB, create_DIArray, is_node_local_to_unit};
33+
use self::utils::{DIB, create_DIArray, debug_context, is_node_local_to_unit};
3434
use crate::builder::Builder;
3535
use crate::common::{AsCCharPtr, CodegenCx};
3636
use crate::llvm;
@@ -131,20 +131,22 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
131131
}
132132

133133
/// Creates any deferred debug metadata nodes
134-
pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
135-
if let Some(dbg_cx) = &cx.dbg_cx {
136-
debug!("finalize");
137-
138-
if gdb::needs_gdb_debug_scripts_section(cx) {
139-
// Add a .debug_gdb_scripts section to this compile-unit. This will
140-
// cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
141-
// which activates the Rust pretty printers for binary this section is
142-
// contained in.
143-
gdb::get_or_insert_gdb_debug_scripts_section_global(cx);
144-
}
134+
pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) {
135+
if cx.dbg_cx.is_none() {
136+
return;
137+
}
138+
139+
debug!("finalize");
145140

146-
dbg_cx.finalize(cx.sess());
141+
if gdb::needs_gdb_debug_scripts_section(cx) {
142+
// Add a .debug_gdb_scripts section to this compile-unit. This will
143+
// cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
144+
// which activates the Rust pretty printers for binary this section is
145+
// contained in.
146+
gdb::get_or_insert_gdb_debug_scripts_section_global(cx);
147147
}
148+
149+
debug_context(cx).finalize(cx.sess());
148150
}
149151

150152
impl<'ll> Builder<'_, 'll, '_> {
@@ -215,10 +217,6 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
215217
}
216218
}
217219

218-
fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
219-
gdb::insert_reference_to_gdb_debug_scripts_section_global(self)
220-
}
221-
222220
fn set_var_name(&mut self, value: &'ll Value, name: &str) {
223221
// Avoid wasting time if LLVM value names aren't even enabled.
224222
if self.sess().fewer_names() {
@@ -614,7 +612,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
614612
metadata::extend_scope_to_file(self, scope_metadata, file)
615613
}
616614

617-
fn debuginfo_finalize(&self) {
615+
fn debuginfo_finalize(&mut self) {
618616
finalize(self)
619617
}
620618

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,6 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
528528
let llbb = Bx::append_block(cx, llfn, "top");
529529
let mut bx = Bx::build(cx, llbb);
530530

531-
bx.insert_reference_to_gdb_debug_scripts_section_global();
532-
533531
let isize_ty = cx.type_isize();
534532
let ptr_ty = cx.type_ptr();
535533
let (arg_argc, arg_argv) = get_argc_argv(&mut bx);

compiler/rustc_codegen_ssa/src/traits/debuginfo.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
5050
scope_metadata: Self::DIScope,
5151
file: &SourceFile,
5252
) -> Self::DIScope;
53-
fn debuginfo_finalize(&self);
53+
fn debuginfo_finalize(&mut self);
5454

5555
// FIXME(eddyb) find a common convention for all of the debuginfo-related
5656
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
@@ -81,6 +81,5 @@ pub trait DebugInfoBuilderMethods: BackendTypes {
8181
);
8282
fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation);
8383
fn clear_dbg_loc(&mut self);
84-
fn insert_reference_to_gdb_debug_scripts_section_global(&mut self);
8584
fn set_var_name(&mut self, value: Self::Value, name: &str);
8685
}

tests/codegen/gdb_debug_script_load.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,12 @@
66

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

9-
#![feature(lang_items)]
109
#![no_std]
10+
#![no_main]
1111

1212
#[panic_handler]
1313
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
1414
loop {}
1515
}
1616

17-
#[no_mangle]
18-
extern "C" fn rust_eh_personality() {
19-
loop {}
20-
}
21-
22-
// Needs rustc to generate `main` as that's where the magic load is inserted.
23-
// IOW, we cannot write this test with `#![no_main]`.
24-
// CHECK-LABEL: @main
25-
// CHECK: load volatile i8, {{.+}} @__rustc_debug_gdb_scripts_section__
26-
27-
#[lang = "start"]
28-
fn lang_start<T: 'static>(
29-
_main: fn() -> T,
30-
_argc: isize,
31-
_argv: *const *const u8,
32-
_sigpipe: u8,
33-
) -> isize {
34-
return 0;
35-
}
36-
37-
fn main() {}
17+
// CHECK: @llvm.used = {{.+}} @__rustc_debug_gdb_scripts_section

0 commit comments

Comments
 (0)