11// .debug_gdb_scripts binary section.
22
3+ use std:: ffi:: CString ;
4+
35use rustc_attr_data_structures:: { AttributeKind , find_attr} ;
46use rustc_codegen_ssa:: base:: collect_debugger_visualizers_transitive;
57use rustc_codegen_ssa:: traits:: * ;
@@ -8,31 +10,21 @@ use rustc_middle::bug;
810use rustc_middle:: middle:: debugger_visualizer:: DebuggerVisualizerType ;
911use rustc_session:: config:: { CrateType , DebugInfo } ;
1012
11- use crate :: builder:: Builder ;
1213use crate :: common:: CodegenCx ;
1314use crate :: llvm;
1415use crate :: value:: Value ;
1516
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.
18- pub ( crate ) fn insert_reference_to_gdb_debug_scripts_section_global ( bx : & mut Builder < ' _ , ' _ , ' _ > ) {
19- if needs_gdb_debug_scripts_section ( bx) {
20- let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global ( bx) ;
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.
23- let volatile_load_instruction = bx. volatile_load ( bx. type_i8 ( ) , gdb_debug_scripts_section) ;
24- unsafe {
25- llvm:: LLVMSetAlignment ( volatile_load_instruction, 1 ) ;
26- }
27- }
28- }
29-
3017/// Allocates the global variable responsible for the .debug_gdb_scripts binary
3118/// section.
3219pub ( crate ) fn get_or_insert_gdb_debug_scripts_section_global < ' ll > (
33- cx : & CodegenCx < ' ll , ' _ > ,
20+ cx : & mut CodegenCx < ' ll , ' _ > ,
3421) -> & ' ll Value {
35- let c_section_var_name = c"__rustc_debug_gdb_scripts_section__" ;
22+ let c_section_var_name = CString :: new ( format ! (
23+ "__rustc_debug_gdb_scripts_section_{}_{:08x}" ,
24+ cx. tcx. crate_name( LOCAL_CRATE ) ,
25+ cx. tcx. stable_crate_id( LOCAL_CRATE ) ,
26+ ) )
27+ . unwrap ( ) ;
3628 let section_var_name = c_section_var_name. to_str ( ) . unwrap ( ) ;
3729
3830 let section_var = unsafe { llvm:: LLVMGetNamedGlobal ( cx. llmod , c_section_var_name. as_ptr ( ) ) } ;
@@ -79,6 +71,8 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
7971 // This should make sure that the whole section is not larger than
8072 // the string it contains. Otherwise we get a warning from GDB.
8173 llvm:: LLVMSetAlignment ( section_var, 1 ) ;
74+ // Make sure that the linker doesn't optimize the global away.
75+ cx. add_used_global ( section_var) ;
8276 section_var
8377 }
8478 } )
@@ -88,17 +82,10 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
8882 let omit_gdb_pretty_printer_section =
8983 find_attr ! ( cx. tcx. hir_krate_attrs( ) , AttributeKind :: OmitGdbPrettyPrinterSection ) ;
9084
91- // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
92- // ODR violations at link time, this section will not be emitted for rlibs since
93- // each rlib could produce a different set of visualizers that would be embedded
94- // in the `.debug_gdb_scripts` section. For that reason, we make sure that the
95- // section is only emitted for leaf crates.
85+ // We collect pretty printers transitively for all crates, so we make sure
86+ // that the section is only emitted for leaf crates.
9687 let embed_visualizers = cx. tcx . crate_types ( ) . iter ( ) . any ( |& crate_type| match crate_type {
97- CrateType :: Executable
98- | CrateType :: Dylib
99- | CrateType :: Cdylib
100- | CrateType :: Staticlib
101- | CrateType :: Sdylib => {
88+ CrateType :: Executable | CrateType :: Cdylib | CrateType :: Staticlib | CrateType :: Sdylib => {
10289 // These are crate types for which we will embed pretty printers since they
10390 // are treated as leaf crates.
10491 true
@@ -109,9 +96,11 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
10996 // want to slow down the common case.
11097 false
11198 }
112- CrateType :: Rlib => {
113- // As per the above description, embedding pretty printers for rlibs could
114- // lead to ODR violations so we skip this crate type as well.
99+ CrateType :: Rlib | CrateType :: Dylib => {
100+ // Don't embed pretty printers for these crate types; the compiler
101+ // can see the `#[debug_visualizer]` attributes when using the
102+ // library, and emitting `.debug_gdb_scripts` regardless would
103+ // break `#![omit_gdb_pretty_printer_section]`.
115104 false
116105 }
117106 } ) ;
0 commit comments