From 8acc93124c6de80fea5c7efc648c5dd56775d74a Mon Sep 17 00:00:00 2001 From: Florian Schmiderer Date: Mon, 3 Jul 2023 13:11:27 +0200 Subject: [PATCH] draft: added CL and CMD to pdb --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 5 +++ compiler/rustc_codegen_llvm/src/llvm_util.rs | 32 ++++++++++++++++++- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 23 ++++++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 3ad546b61e9..d1d43f346fc 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2362,6 +2362,11 @@ pub fn LLVMRustPrintModule( Demangle: extern "C" fn(*const c_char, size_t, *mut c_char, size_t) -> size_t, ) -> LLVMRustResult; pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char); + pub fn LLVMRustSaveInvocationArguments( + CompilerPath: *const c_char, + OtherArgc: c_int, + OtherArgv: *const *const c_char, + ); pub fn LLVMRustPrintPasses(); pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char); pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t); diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 03be0654b50..4a3a3aecf41 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -16,7 +16,7 @@ use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy}; -use std::ffi::{CStr, CString}; +use std::ffi::{c_char, CStr, CString}; use std::path::Path; use std::ptr; @@ -34,6 +34,7 @@ pub(crate) fn init(sess: &Session) { } INIT.call_once(|| { configure_llvm(sess); + save_invocation_args_for_debuginfo(); }); } } @@ -124,6 +125,35 @@ fn llvm_arg_to_arg_name(full_arg: &str) -> &str { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()); } +fn save_invocation_args_for_debuginfo() { + fn os_to_cstr(os: &std::ffi::OsStr) -> Option { + let s = os.to_str()?; + CString::new(s).ok() + } + + let full_args: Vec = std::env::args_os().map(|s| os_to_cstr(&s)).flatten().collect(); + let full_arg_ptrs: Vec<*const c_char> = full_args.iter().map(|cstr| cstr.as_ptr()).collect(); + + let exe_path: Option = + std::env::current_exe().ok().map(|s| os_to_cstr(s.as_os_str())).flatten(); + let exe_path_ptr = if let Some(p) = &exe_path { + p.as_ptr() + } else { + full_args.get(0).map_or(ptr::null(), |c| c.as_ptr()) + }; + + let other_args_ptrs = &full_arg_ptrs[1..]; + + // SAFETY: Ptrs are valid, and this function does make its own copies so we are allowed to invalidate the pointers after the functions exits + unsafe { + llvm::LLVMRustSaveInvocationArguments( + exe_path_ptr, + other_args_ptrs.len() as c_int, + other_args_ptrs.as_ptr(), + ); + } +} + pub fn time_trace_profiler_finish(file_name: &Path) { unsafe { let file_name = path_to_c_string(file_name); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c43a0272477..b6c0ef11d17 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -55,6 +55,9 @@ typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef) DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) +static std::string SavedCompilerPath; +static std::vector SavedOtherArgs; + extern "C" void LLVMTimeTraceProfilerInitialize() { timeTraceProfilerInitialize( /* TimeTraceGranularity */ 0, @@ -377,7 +380,8 @@ extern "C" const char* LLVMRustGetHostCPUName(size_t *len) { extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( const char *TripleStr, const char *CPU, const char *Feature, - const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc, + const char *ABIStr, + LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc, LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat, bool FunctionSections, bool DataSections, @@ -416,6 +420,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.MCOptions.AsmVerbose = AsmComments; Options.MCOptions.PreserveAsmComments = AsmComments; Options.MCOptions.ABIName = ABIStr; + + Options.MCOptions.Argv0 = SavedCompilerPath.c_str(); + Options.MCOptions.CommandLineArgs = llvm::ArrayRef(SavedOtherArgs); + if (SplitDwarfFile) { Options.MCOptions.SplitDwarfFile = SplitDwarfFile; } @@ -477,6 +485,19 @@ extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) { cl::ParseCommandLineOptions(Argc, Argv); } + +extern "C" void LLVMRustSaveInvocationArguments(const char * CompilerPath, + int OtherArgc, + const char *const *OtherArgv) { + SavedCompilerPath = std::string(CompilerPath); + SavedOtherArgs.clear(); + SavedOtherArgs.reserve(OtherArgc); + for (int i = 0; i < OtherArgc; ++i) + { + SavedOtherArgs.push_back(std::string(OtherArgv[i])); + } +} + enum class LLVMRustFileType { AssemblyFile, ObjectFile, -- 2.32.0.windows.2