11// .debug_gdb_scripts binary section.
22
3- use std:: collections:: BTreeSet ;
4- use std:: ffi:: CString ;
5-
3+ use rustc_codegen_ssa:: base:: collect_debugger_visualizers_transitive;
64use rustc_codegen_ssa:: traits:: * ;
75use rustc_hir:: def_id:: LOCAL_CRATE ;
86use rustc_middle:: bug;
97use rustc_middle:: middle:: debugger_visualizer:: DebuggerVisualizerType ;
10- use rustc_session:: config:: DebugInfo ;
8+ use rustc_session:: config:: { CrateType , DebugInfo } ;
119
1210use crate :: builder:: Builder ;
1311use crate :: common:: CodegenCx ;
@@ -33,12 +31,7 @@ pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Buil
3331pub ( crate ) fn get_or_insert_gdb_debug_scripts_section_global < ' ll > (
3432 cx : & CodegenCx < ' ll , ' _ > ,
3533) -> & ' ll Value {
36- let c_section_var_name = CString :: new ( format ! (
37- "__rustc_debug_gdb_scripts_section_{}_{:08x}" ,
38- cx. tcx. crate_name( LOCAL_CRATE ) ,
39- cx. tcx. stable_crate_id( LOCAL_CRATE ) ,
40- ) )
41- . unwrap ( ) ;
34+ let c_section_var_name = c"__rustc_debug_gdb_scripts_section__" ;
4235 let section_var_name = c_section_var_name. to_str ( ) . unwrap ( ) ;
4336
4437 let section_var = unsafe { llvm:: LLVMGetNamedGlobal ( cx. llmod , c_section_var_name. as_ptr ( ) ) } ;
@@ -51,14 +44,10 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
5144
5245 // Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
5346 // attribute.
54- let visualizers = cx
55- . tcx
56- . debugger_visualizers ( LOCAL_CRATE )
57- . iter ( )
58- . filter ( |visualizer| {
59- visualizer. visualizer_type == DebuggerVisualizerType :: GdbPrettyPrinter
60- } )
61- . collect :: < BTreeSet < _ > > ( ) ;
47+ let visualizers = collect_debugger_visualizers_transitive (
48+ cx. tcx ,
49+ DebuggerVisualizerType :: GdbPrettyPrinter ,
50+ ) ;
6251 let crate_name = cx. tcx . crate_name ( LOCAL_CRATE ) ;
6352 for ( index, visualizer) in visualizers. iter ( ) . enumerate ( ) {
6453 // The initial byte `4` instructs GDB that the following pretty printer
@@ -95,5 +84,35 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
9584}
9685
9786pub ( crate ) fn needs_gdb_debug_scripts_section ( cx : & CodegenCx < ' _ , ' _ > ) -> bool {
98- cx. sess ( ) . opts . debuginfo != DebugInfo :: None && cx. sess ( ) . target . emit_debug_gdb_scripts
87+ // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
88+ // ODR violations at link time, this section will not be emitted for rlibs since
89+ // each rlib could produce a different set of visualizers that would be embedded
90+ // in the `.debug_gdb_scripts` section. For that reason, we make sure that the
91+ // section is only emitted for leaf crates.
92+ let embed_visualizers = cx. tcx . crate_types ( ) . iter ( ) . any ( |& crate_type| match crate_type {
93+ CrateType :: Executable
94+ | CrateType :: Dylib
95+ | CrateType :: Cdylib
96+ | CrateType :: Staticlib
97+ | CrateType :: Sdylib => {
98+ // These are crate types for which we will embed pretty printers since they
99+ // are treated as leaf crates.
100+ true
101+ }
102+ CrateType :: ProcMacro => {
103+ // We could embed pretty printers for proc macro crates too but it does not
104+ // seem like a good default, since this is a rare use case and we don't
105+ // want to slow down the common case.
106+ false
107+ }
108+ CrateType :: Rlib => {
109+ // As per the above description, embedding pretty printers for rlibs could
110+ // lead to ODR violations so we skip this crate type as well.
111+ false
112+ }
113+ } ) ;
114+
115+ cx. sess ( ) . opts . debuginfo != DebugInfo :: None
116+ && cx. sess ( ) . target . emit_debug_gdb_scripts
117+ && embed_visualizers
99118}
0 commit comments