|
pub fn compile_unit_metadata( |
|
tcx: TyCtxt<'_>, |
|
codegen_unit_name: &str, |
|
debug_context: &CrateDebugContext<'ll, '_>, |
|
) -> &'ll DIDescriptor { |
|
let mut name_in_debuginfo = match tcx.sess.local_crate_source_file { |
|
Some(ref path) => path.clone(), |
|
None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()), |
|
}; |
|
|
|
// The OSX linker has an idiosyncrasy where it will ignore some debuginfo |
|
// if multiple object files with the same `DW_AT_name` are linked together. |
|
// As a workaround we generate unique names for each object file. Those do |
|
// not correspond to an actual source file but that should be harmless. |
|
if tcx.sess.target.is_like_osx { |
|
name_in_debuginfo.push("@"); |
|
name_in_debuginfo.push(codegen_unit_name); |
|
} |
|
|
|
debug!("compile_unit_metadata: {:?}", name_in_debuginfo); |
|
let rustc_producer = |
|
format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"),); |
|
// FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice. |
|
let producer = format!("clang LLVM ({})", rustc_producer); |
|
|
|
let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); |
|
let flags = "\0"; |
|
|
|
let out_dir = &tcx.output_filenames(LOCAL_CRATE).out_directory; |
|
let split_name = tcx |
|
.output_filenames(LOCAL_CRATE) |
|
.split_dwarf_filename(tcx.sess.opts.debugging_opts.split_dwarf, Some(codegen_unit_name)) |
|
.unwrap_or_default(); |
|
let out_dir = out_dir.to_str().unwrap(); |
|
let split_name = split_name.to_str().unwrap(); |
|
|
|
// FIXME(#60020): |
|
// |
|
// This should actually be |
|
// |
|
// let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo); |
|
// |
|
// That is, we should set LLVM's emission kind to `LineTablesOnly` if |
|
// we are compiling with "limited" debuginfo. However, some of the |
|
// existing tools relied on slightly more debuginfo being generated than |
|
// would be the case with `LineTablesOnly`, and we did not want to break |
|
// these tools in a "drive-by fix", without a good idea or plan about |
|
// what limited debuginfo should exactly look like. So for now we keep |
|
// the emission kind as `FullDebug`. |
|
// |
|
// See https://github.com/rust-lang/rust/issues/60020 for details. |
|
let kind = DebugEmissionKind::FullDebug; |
|
assert!(tcx.sess.opts.debuginfo != DebugInfo::None); |
|
|
|
unsafe { |
|
let file_metadata = llvm::LLVMRustDIBuilderCreateFile( |
|
debug_context.builder, |
|
name_in_debuginfo.as_ptr().cast(), |
|
name_in_debuginfo.len(), |
|
out_dir.as_ptr().cast(), |
|
out_dir.len(), |
|
llvm::ChecksumKind::None, |
|
ptr::null(), |
|
0, |
|
); |
|
|
|
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( |
|
debug_context.builder, |
|
DW_LANG_RUST, |
|
file_metadata, |
|
producer.as_ptr().cast(), |
|
producer.len(), |
|
tcx.sess.opts.optimize != config::OptLevel::No, |
|
flags.as_ptr().cast(), |
|
0, |
|
split_name.as_ptr().cast(), |
|
split_name.len(), |
|
kind, |
|
0, |
|
tcx.sess.opts.debugging_opts.split_dwarf_inlining, |
|
); |
|
|
|
if tcx.sess.opts.debugging_opts.profile { |
|
let cu_desc_metadata = |
|
llvm::LLVMRustMetadataAsValue(debug_context.llcontext, unit_metadata); |
|
let default_gcda_path = &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda"); |
|
let gcda_path = |
|
tcx.sess.opts.debugging_opts.profile_emit.as_ref().unwrap_or(default_gcda_path); |
|
|
|
let gcov_cu_info = [ |
|
path_to_mdstring( |
|
debug_context.llcontext, |
|
&tcx.output_filenames(LOCAL_CRATE).with_extension("gcno"), |
|
), |
|
path_to_mdstring(debug_context.llcontext, &gcda_path), |
|
cu_desc_metadata, |
|
]; |
|
let gcov_metadata = llvm::LLVMMDNodeInContext( |
|
debug_context.llcontext, |
|
gcov_cu_info.as_ptr(), |
|
gcov_cu_info.len() as c_uint, |
|
); |
|
|
|
let llvm_gcov_ident = const_cstr!("llvm.gcov"); |
|
llvm::LLVMAddNamedMetadataOperand( |
|
debug_context.llmod, |
|
llvm_gcov_ident.as_ptr(), |
|
gcov_metadata, |
|
); |
|
} |
|
|
|
// Insert `llvm.ident` metadata on the wasm32 targets since that will |
|
// get hooked up to the "producer" sections `processed-by` information. |
|
if tcx.sess.opts.target_triple.triple().starts_with("wasm32") { |
|
let name_metadata = llvm::LLVMMDStringInContext( |
|
debug_context.llcontext, |
|
rustc_producer.as_ptr().cast(), |
|
rustc_producer.as_bytes().len() as c_uint, |
|
); |
|
llvm::LLVMAddNamedMetadataOperand( |
|
debug_context.llmod, |
|
const_cstr!("llvm.ident").as_ptr(), |
|
llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1), |
|
); |
|
} |
|
|
|
return unit_metadata; |
|
}; |
|
|
|
fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value { |
|
let path_str = path_to_c_string(path); |
|
unsafe { |
|
llvm::LLVMMDStringInContext( |
|
llcx, |
|
path_str.as_ptr(), |
|
path_str.as_bytes().len() as c_uint, |
|
) |
|
} |
|
} |
|
} |
I'm seeing an un-remapped path in a Wasm bin compiled with
--target=wasm32-unknown-unknown--releasedebug = 1--remap-path-prefix=$CARGO_MANIFEST_DIR=onnightly-2021-01-02. Here's a snippet of it and a couple of preceding strings that help contextualise:It looks like it's the out_dir that's not getting remapped:
rust/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Lines 970 to 1109 in dfdfaa1