1
1
// .debug_gdb_scripts binary section.
2
2
3
- use std:: collections:: BTreeSet ;
4
- use std:: ffi:: CString ;
5
-
3
+ use rustc_codegen_ssa:: base:: collect_debugger_visualizers_transitive;
6
4
use rustc_codegen_ssa:: traits:: * ;
7
5
use rustc_hir:: def_id:: LOCAL_CRATE ;
8
6
use rustc_middle:: bug;
9
7
use rustc_middle:: middle:: debugger_visualizer:: DebuggerVisualizerType ;
10
- use rustc_session:: config:: DebugInfo ;
8
+ use rustc_session:: config:: { CrateType , DebugInfo } ;
11
9
12
10
use crate :: builder:: Builder ;
13
11
use crate :: common:: CodegenCx ;
@@ -33,12 +31,7 @@ pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Buil
33
31
pub ( crate ) fn get_or_insert_gdb_debug_scripts_section_global < ' ll > (
34
32
cx : & CodegenCx < ' ll , ' _ > ,
35
33
) -> & ' 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__" ;
42
35
let section_var_name = c_section_var_name. to_str ( ) . unwrap ( ) ;
43
36
44
37
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>(
51
44
52
45
// Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
53
46
// 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
+ ) ;
62
51
let crate_name = cx. tcx . crate_name ( LOCAL_CRATE ) ;
63
52
for ( index, visualizer) in visualizers. iter ( ) . enumerate ( ) {
64
53
// 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>(
95
84
}
96
85
97
86
pub ( 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
99
118
}
0 commit comments