Skip to content

Commit 7d81cc3

Browse files
Implement debuginfo path remapping.
This commit adds the -Zdebug-prefix-map-from/-Zdebug-prefix-map-to commandline option pair. This feature allows to replace prefixes of any file paths that are emitted into debuginfo.
1 parent 84be2df commit 7d81cc3

File tree

26 files changed

+558
-251
lines changed

26 files changed

+558
-251
lines changed

src/grammar/verify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ fn main() {
296296
syntax::errors::registry::Registry::new(&[]),
297297
Rc::new(DummyCrateStore));
298298
let filemap = session.parse_sess.codemap()
299-
.new_filemap("<n/a>".to_string(), None, code);
299+
.new_filemap("<n/a>".to_string(), code);
300300
let mut lexer = lexer::StringReader::new(session.diagnostic(), filemap);
301301
let cm = session.codemap();
302302

src/librustc/middle/cstore.rs

+15
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,15 @@ pub trait CrateStore {
237237
fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId>;
238238
fn is_no_builtins(&self, cnum: CrateNum) -> bool;
239239

240+
/// Gives the directory the compiler has been executed in when compiling
241+
/// crate `cnum`. This is used by debuginfo generation.
242+
fn compiler_working_dir(&self, cnum: CrateNum) -> String;
243+
244+
/// Gives the prefix map as specified via `-Zdebug-prefix-map-*`. We keep
245+
/// using the original prefix-mapping for a crate, not the mapping specified
246+
/// for the current one.
247+
fn debug_prefix_map(&self, cnum: CrateNum) -> Vec<(String, String)>;
248+
240249
// resolve
241250
fn retrace_path(&self,
242251
cnum: CrateNum,
@@ -380,6 +389,12 @@ impl CrateStore for DummyCrateStore {
380389
{ bug!("native_libraries") }
381390
fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId> { bug!("exported_symbols") }
382391
fn is_no_builtins(&self, cnum: CrateNum) -> bool { bug!("is_no_builtins") }
392+
fn compiler_working_dir(&self, cnum: CrateNum) -> String {
393+
bug!("compiler_working_dir")
394+
}
395+
fn debug_prefix_map(&self, cnum: CrateNum) -> Vec<(String, String)> {
396+
bug!("debug_prefix_map")
397+
}
383398

384399
// resolve
385400
fn retrace_path(&self,

src/librustc/session/config.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
10121012
"Set the optimization fuel quota for a crate."),
10131013
print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
10141014
"Make Rustc print the total optimization fuel used by a crate."),
1015+
debug_prefix_map_from: Vec<String> = (vec![], parse_string_push, [TRACKED],
1016+
"push a debuginfo path remapping source"),
1017+
debug_prefix_map_to: Vec<String> = (vec![], parse_string_push, [TRACKED],
1018+
"push a debuginfo path remapping target"),
10151019
}
10161020

10171021
pub fn default_lib_output() -> CrateType {
@@ -1430,6 +1434,23 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
14301434
output_types.insert(OutputType::Exe, None);
14311435
}
14321436

1437+
let debug_prefix_map_sources = debugging_opts.debug_prefix_map_from.len();
1438+
let debug_prefix_map_targets = debugging_opts.debug_prefix_map_from.len();
1439+
1440+
if debug_prefix_map_targets < debug_prefix_map_sources {
1441+
for source in &debugging_opts.debug_prefix_map_from[debug_prefix_map_targets..] {
1442+
early_error(error_format,
1443+
&format!("option `-Zdebug_prefix_map_from='{}'` does not have \
1444+
a corresponding `-Zdebug_prefix_map_to`", source))
1445+
}
1446+
} else if debug_prefix_map_targets > debug_prefix_map_sources {
1447+
for target in &debugging_opts.debug_prefix_map_to[debug_prefix_map_sources..] {
1448+
early_error(error_format,
1449+
&format!("option `-Zdebug_prefix_map_to='{}'` does not have \
1450+
a corresponding `-Zdebug_prefix_map_from`", target))
1451+
}
1452+
}
1453+
14331454
let mut cg = build_codegen_options(matches, error_format);
14341455

14351456
// Issue #30063: if user requests llvm-related output to one

src/librustc/session/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -631,15 +631,6 @@ pub fn build_session_(sopts: config::Options,
631631
None => Some(filesearch::get_or_default_sysroot())
632632
};
633633

634-
// Make the path absolute, if necessary
635-
let local_crate_source_file = local_crate_source_file.map(|path|
636-
if path.is_absolute() {
637-
path.clone()
638-
} else {
639-
env::current_dir().unwrap().join(&path)
640-
}
641-
);
642-
643634
let optimization_fuel_crate = sopts.debugging_opts.fuel.as_ref().map(|i| i.0.clone());
644635
let optimization_fuel_limit = Cell::new(sopts.debugging_opts.fuel.as_ref()
645636
.map(|i| i.1).unwrap_or(0));

src/librustc_metadata/cstore_impl.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,14 @@ impl CrateStore for cstore::CStore {
340340
self.get_crate_data(cnum).is_no_builtins()
341341
}
342342

343+
fn compiler_working_dir(&self, cnum: CrateNum) -> String {
344+
self.get_crate_data(cnum).compiler_working_dir()
345+
}
346+
347+
fn debug_prefix_map(&self, cnum: CrateNum) -> Vec<(String, String)> {
348+
self.get_crate_data(cnum).debug_prefix_map()
349+
}
350+
343351
fn retrace_path(&self,
344352
cnum: CrateNum,
345353
path: &[DisambiguatedDefPathData])
@@ -399,7 +407,7 @@ impl CrateStore for cstore::CStore {
399407
let (name, def) = data.get_macro(id.index);
400408
let source_name = format!("<{} macros>", name);
401409

402-
let filemap = sess.parse_sess.codemap().new_filemap(source_name, None, def.body);
410+
let filemap = sess.parse_sess.codemap().new_filemap(source_name, def.body);
403411
let local_span = Span { lo: filemap.start_pos, hi: filemap.end_pos, ctxt: NO_EXPANSION };
404412
let body = filemap_to_stream(&sess.parse_sess, filemap);
405413

src/librustc_metadata/decoder.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,14 @@ impl<'a, 'tcx> CrateMetadata {
646646
self.root.lang_items.decode(self).collect()
647647
}
648648

649+
pub fn compiler_working_dir(&self) -> String {
650+
self.root.compiler_working_dir.clone()
651+
}
652+
653+
pub fn debug_prefix_map(&self) -> Vec<(String, String)> {
654+
self.root.debug_prefix_map.decode(self).collect()
655+
}
656+
649657
/// Iterates over each child of the given item.
650658
pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
651659
where F: FnMut(def::Export)
@@ -1120,7 +1128,6 @@ impl<'a, 'tcx> CrateMetadata {
11201128
// We can't reuse an existing FileMap, so allocate a new one
11211129
// containing the information we need.
11221130
let syntax_pos::FileMap { name,
1123-
abs_path,
11241131
start_pos,
11251132
end_pos,
11261133
lines,
@@ -1144,7 +1151,6 @@ impl<'a, 'tcx> CrateMetadata {
11441151
}
11451152

11461153
let local_version = local_codemap.new_imported_filemap(name,
1147-
abs_path,
11481154
source_length,
11491155
lines,
11501156
multibyte_chars);

src/librustc_metadata/encoder.rs

+26
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,25 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13421342
self.lazy_seq(exported_symbols.iter().map(|&id| tcx.hir.local_def_id(id).index))
13431343
}
13441344

1345+
fn encode_debug_prefix_map(&mut self) -> LazySeq<(String, String)> {
1346+
let tcx = self.tcx;
1347+
1348+
let debug_prefix_map = tcx.sess
1349+
.opts
1350+
.debugging_opts
1351+
.debug_prefix_map_from
1352+
.iter()
1353+
.cloned()
1354+
.zip(tcx.sess
1355+
.opts
1356+
.debugging_opts
1357+
.debug_prefix_map_from
1358+
.iter()
1359+
.cloned())
1360+
.collect::<Vec<(String, String)>>();
1361+
self.lazy_seq(debug_prefix_map.into_iter())
1362+
}
1363+
13451364
fn encode_dylib_dependency_formats(&mut self) -> LazySeq<Option<LinkagePreference>> {
13461365
match self.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) {
13471366
Some(arr) => {
@@ -1397,6 +1416,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13971416
let exported_symbols = self.encode_exported_symbols();
13981417
let exported_symbols_bytes = self.position() - i;
13991418

1419+
i = self.position();
1420+
let debug_prefix_map = self.encode_debug_prefix_map();
1421+
let debug_prefix_map_bytes = self.position() - i;
1422+
14001423
// Encode and index the items.
14011424
i = self.position();
14021425
let items = self.encode_info_for_items();
@@ -1435,6 +1458,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14351458
def_path_table: def_path_table,
14361459
impls: impls,
14371460
exported_symbols: exported_symbols,
1461+
compiler_working_dir: tcx.sess.working_dir.to_string_lossy().into_owned(),
1462+
debug_prefix_map: debug_prefix_map,
14381463
index: index,
14391464
});
14401465

@@ -1455,6 +1480,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14551480
println!(" codemap bytes: {}", codemap_bytes);
14561481
println!(" impl bytes: {}", impl_bytes);
14571482
println!(" exp. symbols bytes: {}", exported_symbols_bytes);
1483+
println!("debug prefix map bytes: {}", debug_prefix_map_bytes);
14581484
println!(" def-path table bytes: {}", def_path_table_bytes);
14591485
println!(" item bytes: {}", item_bytes);
14601486
println!(" index bytes: {}", index_bytes);

src/librustc_metadata/schema.rs

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ pub struct CrateRoot {
205205
pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
206206
pub impls: LazySeq<TraitImpls>,
207207
pub exported_symbols: LazySeq<DefIndex>,
208+
pub compiler_working_dir: String,
209+
pub debug_prefix_map: LazySeq<(String, String)>,
208210
pub index: LazySeq<index::Index>,
209211
}
210212

src/librustc_trans/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
452452
&llmod_id[..]);
453453

454454
let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
455-
let dctx = debuginfo::CrateDebugContext::new(llmod);
455+
let dctx = debuginfo::CrateDebugContext::new(shared.sess(), llmod);
456456
debuginfo::metadata::compile_unit_metadata(shared, &dctx, shared.tcx.sess);
457457
Some(dctx)
458458
} else {

src/librustc_trans/debuginfo/create_scope_map.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::FunctionDebugContext;
11+
use super::{FunctionDebugContext, FunctionDebugContextData};
1212
use super::metadata::file_metadata;
1313
use super::utils::{DIB, span_start};
1414

1515
use llvm;
16-
use llvm::debuginfo::{DIScope, DISubprogram};
16+
use llvm::debuginfo::DIScope;
1717
use common::CrateContext;
1818
use rustc::mir::{Mir, VisibilityScope};
1919

@@ -53,8 +53,8 @@ pub fn create_mir_scopes(ccx: &CrateContext, mir: &Mir, debug_context: &Function
5353
};
5454
let mut scopes = IndexVec::from_elem(null_scope, &mir.visibility_scopes);
5555

56-
let fn_metadata = match *debug_context {
57-
FunctionDebugContext::RegularContext(ref data) => data.fn_metadata,
56+
let debug_context = match *debug_context {
57+
FunctionDebugContext::RegularContext(ref data) => data,
5858
FunctionDebugContext::DebugInfoDisabled |
5959
FunctionDebugContext::FunctionWithoutDebugInfo => {
6060
return scopes;
@@ -71,7 +71,12 @@ pub fn create_mir_scopes(ccx: &CrateContext, mir: &Mir, debug_context: &Function
7171
// Instantiate all scopes.
7272
for idx in 0..mir.visibility_scopes.len() {
7373
let scope = VisibilityScope::new(idx);
74-
make_mir_scope(ccx, &mir, &has_variables, fn_metadata, scope, &mut scopes);
74+
make_mir_scope(ccx,
75+
&mir,
76+
&has_variables,
77+
debug_context,
78+
scope,
79+
&mut scopes);
7580
}
7681

7782
scopes
@@ -80,7 +85,7 @@ pub fn create_mir_scopes(ccx: &CrateContext, mir: &Mir, debug_context: &Function
8085
fn make_mir_scope(ccx: &CrateContext,
8186
mir: &Mir,
8287
has_variables: &BitVector,
83-
fn_metadata: DISubprogram,
88+
debug_context: &FunctionDebugContextData,
8489
scope: VisibilityScope,
8590
scopes: &mut IndexVec<VisibilityScope, MirDebugScope>) {
8691
if scopes[scope].is_valid() {
@@ -89,13 +94,13 @@ fn make_mir_scope(ccx: &CrateContext,
8994

9095
let scope_data = &mir.visibility_scopes[scope];
9196
let parent_scope = if let Some(parent) = scope_data.parent_scope {
92-
make_mir_scope(ccx, mir, has_variables, fn_metadata, parent, scopes);
97+
make_mir_scope(ccx, mir, has_variables, debug_context, parent, scopes);
9398
scopes[parent]
9499
} else {
95100
// The root is the function itself.
96101
let loc = span_start(ccx, mir.span);
97102
scopes[scope] = MirDebugScope {
98-
scope_metadata: fn_metadata,
103+
scope_metadata: debug_context.fn_metadata,
99104
file_start_pos: loc.file.start_pos,
100105
file_end_pos: loc.file.end_pos,
101106
};
@@ -109,14 +114,14 @@ fn make_mir_scope(ccx: &CrateContext,
109114
// However, we don't skip creating a nested scope if
110115
// our parent is the root, because we might want to
111116
// put arguments in the root and not have shadowing.
112-
if parent_scope.scope_metadata != fn_metadata {
117+
if parent_scope.scope_metadata != debug_context.fn_metadata {
113118
scopes[scope] = parent_scope;
114119
return;
115120
}
116121
}
117122

118123
let loc = span_start(ccx, scope_data.span);
119-
let file_metadata = file_metadata(ccx, &loc.file.name, &loc.file.abs_path);
124+
let file_metadata = file_metadata(ccx, &loc.file.name, debug_context.defining_crate);
120125
let scope_metadata = unsafe {
121126
llvm::LLVMRustDIBuilderCreateLexicalBlock(
122127
DIB(ccx),

0 commit comments

Comments
 (0)