Skip to content

Commit 69363cf

Browse files
authored
Merge pull request #1472 from rust-lang/debuginfo_improvements2
Add debuginfo for statics
2 parents 68b5931 + 4b80941 commit 69363cf

File tree

10 files changed

+346
-116
lines changed

10 files changed

+346
-116
lines changed

src/base.rs

-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ pub(crate) fn codegen_fn<'tcx>(
9595
caller_location: None, // set by `codegen_fn_prelude`
9696

9797
clif_comments,
98-
last_source_file: None,
9998
next_ssa_var: 0,
10099
};
101100

src/common.rs

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
use cranelift_codegen::isa::TargetFrontendConfig;
2-
use gimli::write::FileId;
3-
use rustc_data_structures::sync::Lrc;
42
use rustc_index::IndexVec;
53
use rustc_middle::ty::layout::{
64
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
75
};
86
use rustc_span::source_map::Spanned;
9-
use rustc_span::SourceFile;
107
use rustc_target::abi::call::FnAbi;
118
use rustc_target::abi::{Integer, Primitive};
129
use rustc_target::spec::{HasTargetSpec, Target};
@@ -305,11 +302,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
305302

306303
pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
307304

308-
/// Last accessed source file and it's debuginfo file id.
309-
///
310-
/// For optimization purposes only
311-
pub(crate) last_source_file: Option<(Lrc<SourceFile>, FileId)>,
312-
313305
/// This should only be accessed by `CPlace::new_var`.
314306
pub(crate) next_ssa_var: u32,
315307
}
@@ -419,25 +411,8 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
419411

420412
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
421413
if let Some(debug_context) = &mut self.cx.debug_context {
422-
let (file, line, column) =
423-
DebugContext::get_span_loc(self.tcx, self.mir.span, source_info.span);
424-
425-
// add_source_file is very slow.
426-
// Optimize for the common case of the current file not being changed.
427-
let mut cached_file_id = None;
428-
if let Some((ref last_source_file, last_file_id)) = self.last_source_file {
429-
// If the allocations are not equal, the files may still be equal, but that
430-
// doesn't matter, as this is just an optimization.
431-
if rustc_data_structures::sync::Lrc::ptr_eq(last_source_file, &file) {
432-
cached_file_id = Some(last_file_id);
433-
}
434-
}
435-
436-
let file_id = if let Some(file_id) = cached_file_id {
437-
file_id
438-
} else {
439-
debug_context.add_source_file(&file)
440-
};
414+
let (file_id, line, column) =
415+
debug_context.get_span_loc(self.tcx, self.mir.span, source_info.span);
441416

442417
let source_loc =
443418
self.func_debug_cx.as_mut().unwrap().add_dbg_loc(file_id, line, column);

src/constant.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@ impl ConstantCx {
3131
}
3232
}
3333

34-
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) {
34+
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) -> DataId {
3535
let mut constants_cx = ConstantCx::new();
3636
constants_cx.todo.push(TodoItem::Static(def_id));
3737
constants_cx.finalize(tcx, module);
38+
39+
data_id_for_static(
40+
tcx, module, def_id, false,
41+
// For a declaration the stated mutability doesn't matter.
42+
false,
43+
)
3844
}
3945

4046
pub(crate) fn codegen_tls_ref<'tcx>(

src/debuginfo/emit.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Write the debuginfo into an object file.
22
3+
use cranelift_module::{DataId, FuncId};
34
use cranelift_object::ObjectProduct;
45
use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
56
use gimli::{RunTimeEndian, SectionId};
@@ -8,6 +9,18 @@ use rustc_data_structures::fx::FxHashMap;
89
use super::object::WriteDebugInfo;
910
use super::DebugContext;
1011

12+
pub(super) fn address_for_func(func_id: FuncId) -> Address {
13+
let symbol = func_id.as_u32();
14+
assert!(symbol & 1 << 31 == 0);
15+
Address::Symbol { symbol: symbol as usize, addend: 0 }
16+
}
17+
18+
pub(super) fn address_for_data(data_id: DataId) -> Address {
19+
let symbol = data_id.as_u32();
20+
assert!(symbol & 1 << 31 == 0);
21+
Address::Symbol { symbol: (symbol | 1 << 31) as usize, addend: 0 }
22+
}
23+
1124
impl DebugContext {
1225
pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
1326
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
@@ -171,6 +184,7 @@ impl Writer for WriterRelocate {
171184
gimli::DW_EH_PE_pcrel => {
172185
let size = match eh_pe.format() {
173186
gimli::DW_EH_PE_sdata4 => 4,
187+
gimli::DW_EH_PE_sdata8 => 8,
174188
_ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
175189
};
176190
self.relocs.push(DebugReloc {

src/debuginfo/line_info.rs

+57-60
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ use std::path::{Component, Path};
55

66
use cranelift_codegen::binemit::CodeOffset;
77
use cranelift_codegen::MachSrcLoc;
8-
use gimli::write::{
9-
Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
10-
};
11-
use rustc_data_structures::sync::Lrc;
8+
use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable};
129
use rustc_span::{
1310
FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
1411
};
1512

13+
use crate::debuginfo::emit::address_for_func;
1614
use crate::debuginfo::FunctionDebugContext;
1715
use crate::prelude::*;
1816

@@ -60,72 +58,78 @@ fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
6058

6159
impl DebugContext {
6260
pub(crate) fn get_span_loc(
61+
&mut self,
6362
tcx: TyCtxt<'_>,
6463
function_span: Span,
6564
span: Span,
66-
) -> (Lrc<SourceFile>, u64, u64) {
65+
) -> (FileId, u64, u64) {
6766
// Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
6867
// In order to have a good line stepping behavior in debugger, we overwrite debug
6968
// locations of macro expansions with that of the outermost expansion site (when the macro is
7069
// annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
7170
let span = tcx.collapsed_debuginfo(span, function_span);
7271
match tcx.sess.source_map().lookup_line(span.lo()) {
7372
Ok(SourceFileAndLine { sf: file, line }) => {
73+
let file_id = self.add_source_file(&file);
7474
let line_pos = file.lines()[line];
7575
let col = file.relative_position(span.lo()) - line_pos;
7676

77-
(file, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1)
77+
(file_id, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1)
7878
}
79-
Err(file) => (file, 0, 0),
79+
Err(file) => (self.add_source_file(&file), 0, 0),
8080
}
8181
}
8282

8383
pub(crate) fn add_source_file(&mut self, source_file: &SourceFile) -> FileId {
84-
let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program;
85-
let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings;
86-
87-
match &source_file.name {
88-
FileName::Real(path) => {
89-
let (dir_path, file_name) =
90-
split_path_dir_and_file(if self.should_remap_filepaths {
91-
path.remapped_path_if_available()
92-
} else {
93-
path.local_path_if_available()
94-
});
95-
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
96-
let file_name = osstr_as_utf8_bytes(file_name);
97-
98-
let dir_id = if !dir_name.is_empty() {
99-
let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings);
100-
line_program.add_directory(dir_name)
101-
} else {
102-
line_program.default_directory()
103-
};
104-
let file_name = LineString::new(file_name, line_program.encoding(), line_strings);
105-
106-
let info = make_file_info(source_file.src_hash);
107-
108-
line_program.file_has_md5 &= info.is_some();
109-
line_program.add_file(file_name, dir_id, info)
110-
}
111-
// FIXME give more appropriate file names
112-
filename => {
113-
let dir_id = line_program.default_directory();
114-
let dummy_file_name = LineString::new(
115-
filename
116-
.display(if self.should_remap_filepaths {
117-
FileNameDisplayPreference::Remapped
84+
let cache_key = (source_file.stable_id, source_file.src_hash);
85+
*self.created_files.entry(cache_key).or_insert_with(|| {
86+
let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program;
87+
let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings;
88+
89+
match &source_file.name {
90+
FileName::Real(path) => {
91+
let (dir_path, file_name) =
92+
split_path_dir_and_file(if self.should_remap_filepaths {
93+
path.remapped_path_if_available()
11894
} else {
119-
FileNameDisplayPreference::Local
120-
})
121-
.to_string()
122-
.into_bytes(),
123-
line_program.encoding(),
124-
line_strings,
125-
);
126-
line_program.add_file(dummy_file_name, dir_id, None)
95+
path.local_path_if_available()
96+
});
97+
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
98+
let file_name = osstr_as_utf8_bytes(file_name);
99+
100+
let dir_id = if !dir_name.is_empty() {
101+
let dir_name =
102+
LineString::new(dir_name, line_program.encoding(), line_strings);
103+
line_program.add_directory(dir_name)
104+
} else {
105+
line_program.default_directory()
106+
};
107+
let file_name =
108+
LineString::new(file_name, line_program.encoding(), line_strings);
109+
110+
let info = make_file_info(source_file.src_hash);
111+
112+
line_program.file_has_md5 &= info.is_some();
113+
line_program.add_file(file_name, dir_id, info)
114+
}
115+
filename => {
116+
let dir_id = line_program.default_directory();
117+
let dummy_file_name = LineString::new(
118+
filename
119+
.display(if self.should_remap_filepaths {
120+
FileNameDisplayPreference::Remapped
121+
} else {
122+
FileNameDisplayPreference::Local
123+
})
124+
.to_string()
125+
.into_bytes(),
126+
line_program.encoding(),
127+
line_strings,
128+
);
129+
line_program.add_file(dummy_file_name, dir_id, None)
130+
}
127131
}
128-
}
132+
})
129133
}
130134
}
131135

@@ -138,7 +142,7 @@ impl FunctionDebugContext {
138142
pub(super) fn create_debug_lines(
139143
&mut self,
140144
debug_context: &mut DebugContext,
141-
symbol: usize,
145+
func_id: FuncId,
142146
context: &Context,
143147
) -> CodeOffset {
144148
let create_row_for_span =
@@ -151,11 +155,7 @@ impl FunctionDebugContext {
151155
debug_context.dwarf.unit.line_program.generate_row();
152156
};
153157

154-
debug_context
155-
.dwarf
156-
.unit
157-
.line_program
158-
.begin_sequence(Some(Address::Symbol { symbol, addend: 0 }));
158+
debug_context.dwarf.unit.line_program.begin_sequence(Some(address_for_func(func_id)));
159159

160160
let mut func_end = 0;
161161

@@ -178,10 +178,7 @@ impl FunctionDebugContext {
178178
assert_ne!(func_end, 0);
179179

180180
let entry = debug_context.dwarf.unit.get_mut(self.entry_id);
181-
entry.set(
182-
gimli::DW_AT_low_pc,
183-
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
184-
);
181+
entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
185182
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
186183

187184
func_end

0 commit comments

Comments
 (0)