33mod emit;
44mod line_info;
55mod object;
6+ mod types;
67mod unwind;
78
89use cranelift_codegen:: ir:: Endianness ;
910use cranelift_codegen:: isa:: TargetIsa ;
11+ use cranelift_module:: DataId ;
1012use gimli:: write:: {
1113 Address , AttributeValue , DwarfUnit , Expression , FileId , LineProgram , LineString , Range ,
1214 RangeList , UnitEntryId ,
1315} ;
1416use gimli:: { AArch64 , Encoding , Format , LineEncoding , Register , RiscV , RunTimeEndian , X86_64 } ;
1517use indexmap:: IndexSet ;
1618use rustc_codegen_ssa:: debuginfo:: type_names;
19+ use rustc_hir:: def:: DefKind ;
1720use rustc_hir:: def_id:: DefIdMap ;
1821use rustc_session:: Session ;
22+ use rustc_span:: { SourceFileHash , StableSourceFileId } ;
1923
2024pub ( crate ) use self :: emit:: { DebugReloc , DebugRelocName } ;
25+ pub ( crate ) use self :: types:: TypeDebugContext ;
2126pub ( crate ) use self :: unwind:: UnwindContext ;
27+ use crate :: debuginfo:: emit:: { address_for_data, address_for_func} ;
2228use crate :: prelude:: * ;
2329
2430pub ( crate ) fn producer ( sess : & Session ) -> String {
@@ -30,8 +36,10 @@ pub(crate) struct DebugContext {
3036
3137 dwarf : DwarfUnit ,
3238 unit_range_list : RangeList ,
39+ created_files : FxHashMap < ( StableSourceFileId , SourceFileHash ) , FileId > ,
3340 stack_pointer_register : Register ,
3441 namespace_map : DefIdMap < UnitEntryId > ,
42+ array_size_type : UnitEntryId ,
3543
3644 should_remap_filepaths : bool ,
3745}
@@ -126,12 +134,27 @@ impl DebugContext {
126134 root. set ( gimli:: DW_AT_low_pc , AttributeValue :: Address ( Address :: Constant ( 0 ) ) ) ;
127135 }
128136
137+ let array_size_type = dwarf. unit . add ( dwarf. unit . root ( ) , gimli:: DW_TAG_base_type ) ;
138+ let array_size_type_entry = dwarf. unit . get_mut ( array_size_type) ;
139+ array_size_type_entry. set (
140+ gimli:: DW_AT_name ,
141+ AttributeValue :: StringRef ( dwarf. strings . add ( "__ARRAY_SIZE_TYPE__" ) ) ,
142+ ) ;
143+ array_size_type_entry
144+ . set ( gimli:: DW_AT_encoding , AttributeValue :: Encoding ( gimli:: DW_ATE_unsigned ) ) ;
145+ array_size_type_entry. set (
146+ gimli:: DW_AT_byte_size ,
147+ AttributeValue :: Udata ( isa. frontend_config ( ) . pointer_bytes ( ) . into ( ) ) ,
148+ ) ;
149+
129150 DebugContext {
130151 endian,
131152 dwarf,
132153 unit_range_list : RangeList ( Vec :: new ( ) ) ,
154+ created_files : FxHashMap :: default ( ) ,
133155 stack_pointer_register,
134156 namespace_map : DefIdMap :: default ( ) ,
157+ array_size_type,
135158 should_remap_filepaths,
136159 }
137160 }
@@ -169,11 +192,8 @@ impl DebugContext {
169192 linkage_name : & str ,
170193 function_span : Span ,
171194 ) -> FunctionDebugContext {
172- let ( file , line, column) = DebugContext :: get_span_loc ( tcx, function_span, function_span) ;
195+ let ( file_id , line, column) = self . get_span_loc ( tcx, function_span, function_span) ;
173196
174- let file_id = self . add_source_file ( & file) ;
175-
176- // FIXME: add to appropriate scope instead of root
177197 let scope = self . item_namespace ( tcx, tcx. parent ( instance. def_id ( ) ) ) ;
178198
179199 let mut name = String :: new ( ) ;
@@ -230,6 +250,62 @@ impl DebugContext {
230250 source_loc_set : IndexSet :: new ( ) ,
231251 }
232252 }
253+
254+ // Adapted from https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs#L1288-L1346
255+ pub ( crate ) fn define_static < ' tcx > (
256+ & mut self ,
257+ tcx : TyCtxt < ' tcx > ,
258+ type_dbg : & mut TypeDebugContext < ' tcx > ,
259+ def_id : DefId ,
260+ data_id : DataId ,
261+ ) {
262+ let DefKind :: Static { nested, .. } = tcx. def_kind ( def_id) else { bug ! ( ) } ;
263+ if nested {
264+ return ;
265+ }
266+
267+ let scope = self . item_namespace ( tcx, tcx. parent ( def_id) ) ;
268+
269+ let span = tcx. def_span ( def_id) ;
270+ let ( file_id, line, _column) = self . get_span_loc ( tcx, span, span) ;
271+
272+ let static_type = Instance :: mono ( tcx, def_id) . ty ( tcx, ty:: ParamEnv :: reveal_all ( ) ) ;
273+ let static_layout = tcx. layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( static_type) ) . unwrap ( ) ;
274+ // FIXME use the actual type layout
275+ let type_id = self . debug_type ( tcx, type_dbg, static_type) ;
276+
277+ let name = tcx. item_name ( def_id) ;
278+ let linkage_name = tcx. symbol_name ( Instance :: mono ( tcx, def_id) ) . name ;
279+
280+ let entry_id = self . dwarf . unit . add ( scope, gimli:: DW_TAG_variable ) ;
281+ let entry = self . dwarf . unit . get_mut ( entry_id) ;
282+ let linkage_name_id = if name. as_str ( ) != linkage_name {
283+ Some ( self . dwarf . strings . add ( linkage_name) )
284+ } else {
285+ None
286+ } ;
287+ let name_id = self . dwarf . strings . add ( name. as_str ( ) ) ;
288+
289+ entry. set ( gimli:: DW_AT_name , AttributeValue :: StringRef ( name_id) ) ;
290+ entry. set ( gimli:: DW_AT_type , AttributeValue :: UnitRef ( type_id) ) ;
291+
292+ if tcx. is_reachable_non_generic ( def_id) {
293+ entry. set ( gimli:: DW_AT_external , AttributeValue :: FlagPresent ) ;
294+ }
295+
296+ entry. set ( gimli:: DW_AT_decl_file , AttributeValue :: FileIndex ( Some ( file_id) ) ) ;
297+ entry. set ( gimli:: DW_AT_decl_line , AttributeValue :: Udata ( line) ) ;
298+
299+ entry. set ( gimli:: DW_AT_alignment , AttributeValue :: Udata ( static_layout. align . pref . bytes ( ) ) ) ;
300+
301+ let mut expr = Expression :: new ( ) ;
302+ expr. op_addr ( address_for_data ( data_id) ) ;
303+ entry. set ( gimli:: DW_AT_location , AttributeValue :: Exprloc ( expr) ) ;
304+
305+ if let Some ( linkage_name_id) = linkage_name_id {
306+ entry. set ( gimli:: DW_AT_linkage_name , AttributeValue :: StringRef ( linkage_name_id) ) ;
307+ }
308+ }
233309}
234310
235311impl FunctionDebugContext {
@@ -239,21 +315,16 @@ impl FunctionDebugContext {
239315 func_id : FuncId ,
240316 context : & Context ,
241317 ) {
242- let symbol = func_id . as_u32 ( ) as usize ;
318+ let end = self . create_debug_lines ( debug_context , func_id , context ) ;
243319
244- let end = self . create_debug_lines ( debug_context, symbol, context) ;
245-
246- debug_context. unit_range_list . 0 . push ( Range :: StartLength {
247- begin : Address :: Symbol { symbol, addend : 0 } ,
248- length : u64:: from ( end) ,
249- } ) ;
320+ debug_context
321+ . unit_range_list
322+ . 0
323+ . push ( Range :: StartLength { begin : address_for_func ( func_id) , length : u64:: from ( end) } ) ;
250324
251325 let func_entry = debug_context. dwarf . unit . get_mut ( self . entry_id ) ;
252326 // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
253- func_entry. set (
254- gimli:: DW_AT_low_pc ,
255- AttributeValue :: Address ( Address :: Symbol { symbol, addend : 0 } ) ,
256- ) ;
327+ func_entry. set ( gimli:: DW_AT_low_pc , AttributeValue :: Address ( address_for_func ( func_id) ) ) ;
257328 // Using Udata for DW_AT_high_pc requires at least DWARF4
258329 func_entry. set ( gimli:: DW_AT_high_pc , AttributeValue :: Udata ( u64:: from ( end) ) ) ;
259330 }
0 commit comments