Skip to content

Commit a372ab9

Browse files
committed
Add missing Debuginfo to PDB debug file on windows.
Fixed CL and CMD in LF_DEBUGINFO to contain the correct information instead of empty/invalid values.
1 parent a6236fa commit a372ab9

File tree

18 files changed

+185
-7
lines changed

18 files changed

+185
-7
lines changed

compiler/rustc_codegen_llvm/src/back/lto.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::back::write::{self, save_temp_bitcode, CodegenDiagnosticsStage, DiagnosticHandlers};
1+
use crate::back::write::{
2+
self, add_cpp_args_to_target_machine, create_target_machine_args, save_temp_bitcode,
3+
CodegenDiagnosticsStage, DiagnosticHandlers,
4+
};
25
use crate::errors::{
36
DynamicLinkingWithLTO, LlvmError, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib,
47
};
@@ -696,6 +699,8 @@ pub unsafe fn optimize_thin_module(
696699
let module_name = &thin_module.shared.module_names[thin_module.idx];
697700
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
698701
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&diag_handler, e))?;
702+
let tm_cpp_args = create_target_machine_args(&cgcx.expanded_args);
703+
add_cpp_args_to_target_machine(tm, &*tm_cpp_args);
699704

700705
// Right now the implementation we've got only works over serialized
701706
// modules, so we create a fresh new LLVM context and parse the module
@@ -705,7 +710,7 @@ pub unsafe fn optimize_thin_module(
705710
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
706711
let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &diag_handler)? as *const _;
707712
let mut module = ModuleCodegen {
708-
module_llvm: ModuleLlvm { llmod_raw, llcx, tm },
713+
module_llvm: ModuleLlvm { llmod_raw, llcx, tm, tm_cpp_args },
709714
name: thin_module.name().to_string(),
710715
kind: ModuleKind::Regular,
711716
};

compiler/rustc_codegen_llvm/src/back/write.rs

+39
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,33 @@ pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm:
104104
.unwrap_or_else(|err| llvm_err(sess.diagnostic(), err).raise())
105105
}
106106

107+
pub fn create_target_machine_args(expanded_args: &[String]) -> *mut llvm::TargetMachineCppArgs {
108+
let expanded_args_cstr: Vec<CString> =
109+
expanded_args.iter().map(|s| CString::new(s.as_str()).ok()).flatten().collect();
110+
111+
let expanded_args_cstr_ptrs: Vec<*const c_char> =
112+
expanded_args_cstr.iter().map(|cstr| cstr.as_ptr()).collect();
113+
114+
fn path_to_cstr(os: std::path::PathBuf) -> Option<CString> {
115+
let s = os.to_str()?;
116+
CString::new(s).ok()
117+
}
118+
let exe_path: CString =
119+
std::env::current_exe().ok().map(path_to_cstr).flatten().unwrap_or_default();
120+
121+
let exe_path_ptr = exe_path.as_ptr();
122+
let expanded_args_cstr_ptrs_slice = &expanded_args_cstr_ptrs[..];
123+
124+
// SAFETY: Ptrs are valid, and this function does make its own copies so we are allowed to invalidate the pointers after the functions exits
125+
unsafe {
126+
llvm::LLVMRustCreateTargetMachineArgs(
127+
exe_path_ptr,
128+
expanded_args_cstr_ptrs_slice.len() as c_int,
129+
expanded_args_cstr_ptrs_slice.as_ptr(),
130+
)
131+
}
132+
}
133+
107134
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
108135
let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
109136
tcx.output_filenames(()).split_dwarf_path(
@@ -123,6 +150,18 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut ll
123150
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), err).raise())
124151
}
125152

153+
pub fn add_cpp_args_to_target_machine<'tm, 'args>(
154+
tm: &'tm mut llvm::TargetMachine,
155+
args: &'args llvm::TargetMachineCppArgs,
156+
) where
157+
'args: 'tm,
158+
{
159+
// SAFETY: args lives at least as long tm
160+
unsafe {
161+
llvm::LLVMRustAddCppArgsRefToTargetMachine(tm, args);
162+
}
163+
}
164+
126165
pub fn to_llvm_opt_settings(
127166
cfg: config::OptLevel,
128167
) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) {

compiler/rustc_codegen_llvm/src/lib.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ extern crate rustc_macros;
2121
#[macro_use]
2222
extern crate tracing;
2323

24-
use back::write::{create_informational_target_machine, create_target_machine};
24+
use back::write::{
25+
add_cpp_args_to_target_machine, create_informational_target_machine, create_target_machine,
26+
create_target_machine_args,
27+
};
2528

2629
use errors::ParseTargetMachineConfig;
2730
pub use llvm_util::target_features;
@@ -412,6 +415,7 @@ impl CodegenBackend for LlvmCodegenBackend {
412415
pub struct ModuleLlvm {
413416
llcx: &'static mut llvm::Context,
414417
llmod_raw: *const llvm::Module,
418+
tm_cpp_args: *mut llvm::TargetMachineCppArgs,
415419
tm: &'static mut llvm::TargetMachine,
416420
}
417421

@@ -423,15 +427,21 @@ impl ModuleLlvm {
423427
unsafe {
424428
let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
425429
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
426-
ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, mod_name) }
430+
let tm_cpp_args = create_target_machine_args(&tcx.sess.expanded_args);
431+
let tm = create_target_machine(tcx, mod_name);
432+
add_cpp_args_to_target_machine(tm, &*tm_cpp_args);
433+
ModuleLlvm { llmod_raw, llcx, tm, tm_cpp_args }
427434
}
428435
}
429436

430437
fn new_metadata(tcx: TyCtxt<'_>, mod_name: &str) -> Self {
431438
unsafe {
432439
let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
433440
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
434-
ModuleLlvm { llmod_raw, llcx, tm: create_informational_target_machine(tcx.sess) }
441+
let tm_cpp_args = create_target_machine_args(&tcx.sess.expanded_args);
442+
let tm = create_informational_target_machine(tcx.sess);
443+
add_cpp_args_to_target_machine(tm, &*tm_cpp_args);
444+
ModuleLlvm { llmod_raw, llcx, tm, tm_cpp_args }
435445
}
436446
}
437447

@@ -451,8 +461,10 @@ impl ModuleLlvm {
451461
return Err(handler.emit_almost_fatal(ParseTargetMachineConfig(e)));
452462
}
453463
};
464+
let tm_cpp_args = create_target_machine_args(&cgcx.expanded_args);
465+
add_cpp_args_to_target_machine(tm, &*tm_cpp_args);
454466

455-
Ok(ModuleLlvm { llmod_raw, llcx, tm })
467+
Ok(ModuleLlvm { llmod_raw, llcx, tm, tm_cpp_args })
456468
}
457469
}
458470

@@ -465,6 +477,7 @@ impl Drop for ModuleLlvm {
465477
fn drop(&mut self) {
466478
unsafe {
467479
llvm::LLVMRustDisposeTargetMachine(&mut *(self.tm as *mut _));
480+
llvm::LLVMRustDisposeTargetMachineArgs(self.tm_cpp_args);
468481
llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
469482
}
470483
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+30
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,19 @@ pub struct PassManager<'a>(InvariantOpaque<'a>);
655655
extern "C" {
656656
pub type Pass;
657657
}
658+
659+
extern "C" {
660+
pub type TargetMachineCppArgs;
661+
}
662+
663+
// SAFETY: TargetMachineCppArgs is equivalent to the following, which is Send + Sync
664+
// struct LLVMTargetMachineCppArgs {
665+
// CompilerPath : String,
666+
// OtherArgs : Vec<String>,
667+
// };
668+
unsafe impl Send for TargetMachineCppArgs {}
669+
unsafe impl Sync for TargetMachineCppArgs {}
670+
658671
extern "C" {
659672
pub type TargetMachine;
660673
}
@@ -2298,6 +2311,15 @@ extern "C" {
22982311
);
22992312

23002313
pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
2314+
2315+
pub fn LLVMRustCreateTargetMachineArgs(
2316+
CompilerPath: *const c_char,
2317+
OtherArgc: c_int,
2318+
OtherArgv: *const *const c_char,
2319+
) -> *mut TargetMachineCppArgs;
2320+
2321+
pub fn LLVMRustDisposeTargetMachineArgs(Args: *mut TargetMachineCppArgs);
2322+
23012323
pub fn LLVMRustCreateTargetMachine(
23022324
Triple: *const c_char,
23032325
CPU: *const c_char,
@@ -2319,7 +2341,15 @@ extern "C" {
23192341
SplitDwarfFile: *const c_char,
23202342
ForceEmulatedTls: bool,
23212343
) -> Option<&'static mut TargetMachine>;
2344+
23222345
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
2346+
2347+
pub fn LLVMRustAddCppArgsRefToTargetMachine<'tm, 'args>(
2348+
tm: &'tm mut TargetMachine,
2349+
args: &'args TargetMachineCppArgs,
2350+
) where
2351+
'args: 'tm;
2352+
23232353
pub fn LLVMRustAddLibraryInfo<'a>(
23242354
PM: &PassManager<'a>,
23252355
M: &'a Module,

compiler/rustc_codegen_ssa/src/back/write.rs

+7
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,12 @@ pub struct CodegenContext<B: WriteBackendMethods> {
342342
pub split_debuginfo: rustc_target::spec::SplitDebuginfo,
343343
pub split_dwarf_kind: rustc_session::config::SplitDwarfKind,
344344

345+
/// All commandline args used to invoke the compiler, with @file args fully expanded.
346+
/// This will only be used within debug info, e.g. in the pdb file on windows
347+
/// This is mainly useful for other tools that reads that debuginfo to figure out
348+
/// how to call the compiler with the same arguments.
349+
pub expanded_args: Vec<String>,
350+
345351
/// Handler to use for diagnostics produced during codegen.
346352
pub diag_emitter: SharedEmitter,
347353
/// LLVM optimizations for which we want to print remarks.
@@ -1093,6 +1099,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
10931099
incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()),
10941100
cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(),
10951101
coordinator_send,
1102+
expanded_args: tcx.sess.expanded_args.clone(),
10961103
diag_emitter: shared_emitter.clone(),
10971104
output_filenames: tcx.output_filenames(()).clone(),
10981105
regular_module_config: regular_config,

compiler/rustc_driver_impl/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ fn run_compiler(
312312
override_queries: None,
313313
make_codegen_backend,
314314
registry: diagnostics_registry(),
315+
expanded_args: args,
315316
};
316317

317318
match make_input(&early_error_handler, &matches.free) {

compiler/rustc_interface/src/interface.rs

+7
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,12 @@ pub struct Config {
279279

280280
/// Registry of diagnostics codes.
281281
pub registry: Registry,
282+
283+
/// All commandline args used to invoke the compiler, with @file args fully expanded.
284+
/// This will only be used within debug info, e.g. in the pdb file on windows
285+
/// This is mainly useful for other tools that reads that debuginfo to figure out
286+
/// how to call the compiler with the same arguments.
287+
pub expanded_args: Vec<String>,
282288
}
283289

284290
// JUSTIFICATION: before session exists, only config
@@ -317,6 +323,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
317323
config.make_codegen_backend,
318324
registry.clone(),
319325
config.ice_file,
326+
config.expanded_args,
320327
);
321328

322329
if let Some(parse_sess_created) = config.parse_sess_created {

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se
6868
None,
6969
"",
7070
None,
71+
Default::default(),
7172
);
7273
(sess, cfg)
7374
}

compiler/rustc_interface/src/util.rs

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub fn create_session(
7171
>,
7272
descriptions: Registry,
7373
ice_file: Option<PathBuf>,
74+
expanded_args: Vec<String>,
7475
) -> (Session, Box<dyn CodegenBackend>) {
7576
let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
7677
make_codegen_backend(&sopts)
@@ -113,6 +114,7 @@ pub fn create_session(
113114
target_override,
114115
rustc_version_str().unwrap_or("unknown"),
115116
ice_file,
117+
expanded_args,
116118
);
117119

118120
codegen_backend.init(&sess);

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050

5151
using namespace llvm;
5252

53+
struct LLVMTargetMachineCppArgs {
54+
std::string CompilerPath;
55+
std::vector<std::string> OtherArgs;
56+
};
57+
5358
typedef struct LLVMOpaquePass *LLVMPassRef;
5459
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
5560

@@ -387,9 +392,28 @@ extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
387392
return Name.data();
388393
}
389394

395+
extern "C" LLVMTargetMachineCppArgs* LLVMRustCreateTargetMachineArgs(const char * CompilerPath,
396+
int OtherArgc,
397+
const char *const *OtherArgv) {
398+
LLVMTargetMachineCppArgs* args = new LLVMTargetMachineCppArgs;
399+
args->CompilerPath = std::string(CompilerPath);
400+
args->OtherArgs.reserve(OtherArgc);
401+
for (int i = 0; i < OtherArgc; ++i)
402+
{
403+
args->OtherArgs.push_back(std::string(OtherArgv[i]));
404+
}
405+
406+
return args;
407+
}
408+
409+
extern "C" void LLVMRustDisposeTargetMachineArgs(LLVMTargetMachineCppArgs* Args) {
410+
delete Args;
411+
}
412+
390413
extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
391414
const char *TripleStr, const char *CPU, const char *Feature,
392-
const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
415+
const char *ABIStr,
416+
LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
393417
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
394418
bool FunctionSections,
395419
bool DataSections,
@@ -428,6 +452,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
428452
Options.MCOptions.AsmVerbose = AsmComments;
429453
Options.MCOptions.PreserveAsmComments = AsmComments;
430454
Options.MCOptions.ABIName = ABIStr;
455+
431456
if (SplitDwarfFile) {
432457
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
433458
}
@@ -466,6 +491,13 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
466491
delete unwrap(TM);
467492
}
468493

494+
extern "C" void LLVMRustAddCppArgsRefToTargetMachine(LLVMTargetMachineRef TM,
495+
LLVMTargetMachineCppArgs* TargetMachineCppArgs) {
496+
unwrap(TM)->Options.MCOptions.Argv0 = TargetMachineCppArgs->CompilerPath.c_str();
497+
unwrap(TM)->Options.MCOptions.CommandLineArgs =
498+
llvm::ArrayRef<std::string>(TargetMachineCppArgs->OtherArgs);
499+
}
500+
469501
// Unfortunately, the LLVM C API doesn't provide a way to create the
470502
// TargetLibraryInfo pass, so we use this method to do so.
471503
extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
@@ -489,6 +521,8 @@ extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
489521
cl::ParseCommandLineOptions(Argc, Argv);
490522
}
491523

524+
525+
492526
enum class LLVMRustFileType {
493527
AssemblyFile,
494528
ObjectFile,

compiler/rustc_session/src/session.rs

+8
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ pub struct Session {
214214

215215
/// The version of the rustc process, possibly including a commit hash and description.
216216
pub cfg_version: &'static str,
217+
218+
/// All commandline args used to invoke the compiler, with @file args fully expanded.
219+
/// This will only be used within debug info, e.g. in the pdb file on windows
220+
/// This is mainly useful for other tools that reads that debuginfo to figure out
221+
/// how to call the compiler with the same arguments.
222+
pub expanded_args: Vec<String>,
217223
}
218224

219225
pub struct PerfStats {
@@ -1397,6 +1403,7 @@ pub fn build_session(
13971403
target_override: Option<Target>,
13981404
cfg_version: &'static str,
13991405
ice_file: Option<PathBuf>,
1406+
expanded_args: Vec<String>,
14001407
) -> Session {
14011408
// FIXME: This is not general enough to make the warning lint completely override
14021409
// normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -1542,6 +1549,7 @@ pub fn build_session(
15421549
target_features: Default::default(),
15431550
unstable_target_features: Default::default(),
15441551
cfg_version,
1552+
expanded_args,
15451553
};
15461554

15471555
validate_commandline_args_with_session_available(&sess);

src/librustdoc/config.rs

+7
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ pub(crate) struct Options {
157157
/// Note: this field is duplicated in `RenderOptions` because it's useful
158158
/// to have it in both places.
159159
pub(crate) unstable_features: rustc_feature::UnstableFeatures,
160+
161+
/// All commandline args used to invoke the compiler, with @file args fully expanded.
162+
/// This will only be used within debug info, e.g. in the pdb file on windows
163+
/// This is mainly useful for other tools that reads that debuginfo to figure out
164+
/// how to call the compiler with the same arguments.
165+
pub(crate) expanded_args: Vec<String>,
160166
}
161167

162168
impl fmt::Debug for Options {
@@ -743,6 +749,7 @@ impl Options {
743749
json_unused_externs,
744750
scrape_examples_options,
745751
unstable_features,
752+
expanded_args: args,
746753
};
747754
let render_options = RenderOptions {
748755
output,

0 commit comments

Comments
 (0)