Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 4cdc633

Browse files
committed
Add missing Debuginfo to PDB debug file on windows.
Set Arg0 and CommandLineArgs in MCTargetoptions so LLVM outputs correct CL and CMD in LF_DEBUGINFO instead of empty/invalid values.
1 parent f91c53d commit 4cdc633

File tree

16 files changed

+117
-1
lines changed

16 files changed

+117
-1
lines changed

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,24 @@ pub fn target_machine_factory(
216216

217217
let force_emulated_tls = sess.target.force_emulated_tls;
218218

219+
// copy the exe path, followed by path all into one buffer
220+
// null terminating them so we can use them as null terminated strings
221+
let args_cstr_buff = {
222+
let mut args_cstr_buff: Vec<u8> = Vec::new();
223+
let exe_path = std::env::current_exe().unwrap_or_default();
224+
let exe_path_str = exe_path.into_os_string().into_string().unwrap_or_default();
225+
226+
args_cstr_buff.extend_from_slice(exe_path_str.as_bytes());
227+
args_cstr_buff.push(0);
228+
229+
for arg in sess.expanded_args.iter() {
230+
args_cstr_buff.extend_from_slice(arg.as_bytes());
231+
args_cstr_buff.push(0);
232+
}
233+
234+
args_cstr_buff
235+
};
236+
219237
Arc::new(move |config: TargetMachineFactoryConfig| {
220238
let split_dwarf_file =
221239
path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0;
@@ -242,6 +260,8 @@ pub fn target_machine_factory(
242260
use_init_array,
243261
split_dwarf_file.as_ptr(),
244262
force_emulated_tls,
263+
args_cstr_buff.as_ptr() as *const c_char,
264+
args_cstr_buff.len(),
245265
)
246266
};
247267

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,10 @@ extern "C" {
21322132
UseInitArray: bool,
21332133
SplitDwarfFile: *const c_char,
21342134
ForceEmulatedTls: bool,
2135+
ArgsCstrBuff: *const c_char,
2136+
ArgsCstrBuffLen: usize,
21352137
) -> Option<&'static mut TargetMachine>;
2138+
21362139
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
21372140
pub fn LLVMRustAddLibraryInfo<'a>(
21382141
PM: &PassManager<'a>,

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@ pub struct CodegenContext<B: WriteBackendMethods> {
343343
pub split_debuginfo: rustc_target::spec::SplitDebuginfo,
344344
pub split_dwarf_kind: rustc_session::config::SplitDwarfKind,
345345

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

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ fn run_compiler(
313313
override_queries: None,
314314
make_codegen_backend,
315315
registry: diagnostics_registry(),
316+
expanded_args: args,
316317
};
317318

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

compiler/rustc_interface/src/interface.rs

Lines changed: 7 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
406406
bool RelaxELFRelocations,
407407
bool UseInitArray,
408408
const char *SplitDwarfFile,
409-
bool ForceEmulatedTls) {
409+
bool ForceEmulatedTls,
410+
const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
410411

411412
auto OptLevel = fromRust(RustOptLevel);
412413
auto RM = fromRust(RustReloc);
@@ -462,12 +463,48 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
462463

463464
Options.EmitStackSizeSection = EmitStackSizeSection;
464465

466+
467+
if (ArgsCstrBuff != nullptr)
468+
{
469+
int buffer_offset = 0;
470+
assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
471+
472+
const size_t arg0_len = std::strlen(ArgsCstrBuff);
473+
char* arg0 = new char[arg0_len + 1];
474+
memcpy(arg0, ArgsCstrBuff, arg0_len);
475+
arg0[arg0_len] = '\0';
476+
buffer_offset += arg0_len + 1;
477+
478+
const int num_cmd_arg_strings =
479+
std::count(&ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0');
480+
481+
std::string* cmd_arg_strings = new std::string[num_cmd_arg_strings];
482+
for (int i = 0; i < num_cmd_arg_strings; ++i)
483+
{
484+
assert(buffer_offset < ArgsCstrBuffLen);
485+
const int len = std::strlen(ArgsCstrBuff + buffer_offset);
486+
cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len);
487+
buffer_offset += len + 1;
488+
}
489+
490+
assert(buffer_offset == ArgsCstrBuffLen);
491+
492+
Options.MCOptions.Argv0 = arg0;
493+
Options.MCOptions.CommandLineArgs =
494+
llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings);
495+
}
496+
465497
TargetMachine *TM = TheTarget->createTargetMachine(
466498
Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
467499
return wrap(TM);
468500
}
469501

470502
extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
503+
504+
MCTargetOptions& MCOptions = unwrap(TM)->Options.MCOptions;
505+
delete[] MCOptions.Argv0;
506+
delete[] MCOptions.CommandLineArgs.data();
507+
471508
delete unwrap(TM);
472509
}
473510

compiler/rustc_session/src/session.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ pub struct Session {
204204

205205
/// The version of the rustc process, possibly including a commit hash and description.
206206
pub cfg_version: &'static str,
207+
208+
/// All commandline args used to invoke the compiler, with @file args fully expanded.
209+
/// This will only be used within debug info, e.g. in the pdb file on windows
210+
/// This is mainly useful for other tools that reads that debuginfo to figure out
211+
/// how to call the compiler with the same arguments.
212+
pub expanded_args: Vec<String>,
207213
}
208214

209215
pub struct PerfStats {
@@ -1325,6 +1331,7 @@ pub fn build_session(
13251331
target_override: Option<Target>,
13261332
cfg_version: &'static str,
13271333
ice_file: Option<PathBuf>,
1334+
expanded_args: Vec<String>,
13281335
) -> Session {
13291336
// FIXME: This is not general enough to make the warning lint completely override
13301337
// normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -1467,6 +1474,7 @@ pub fn build_session(
14671474
target_features: Default::default(),
14681475
unstable_target_features: Default::default(),
14691476
cfg_version,
1477+
expanded_args,
14701478
};
14711479

14721480
validate_commandline_args_with_session_available(&sess);

src/librustdoc/config.rs

Lines changed: 7 additions & 0 deletions
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 {
@@ -744,6 +750,7 @@ impl Options {
744750
json_unused_externs,
745751
scrape_examples_options,
746752
unstable_features,
753+
expanded_args: args,
747754
};
748755
let render_options = RenderOptions {
749756
output,

src/librustdoc/core.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ pub(crate) fn create_config(
194194
describe_lints,
195195
lint_cap,
196196
scrape_examples_options,
197+
expanded_args,
197198
..
198199
}: RustdocOptions,
199200
RenderOptions { document_private, .. }: &RenderOptions,
@@ -291,6 +292,7 @@ pub(crate) fn create_config(
291292
make_codegen_backend: None,
292293
registry: rustc_driver::diagnostics_registry(),
293294
ice_file: None,
295+
expanded_args,
294296
}
295297
}
296298

src/librustdoc/doctest.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
109109
make_codegen_backend: None,
110110
registry: rustc_driver::diagnostics_registry(),
111111
ice_file: None,
112+
expanded_args: options.expanded_args.clone(),
112113
};
113114

114115
let test_args = options.test_args.clone();

tests/run-make-fulldeps/issue-19371/foo.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
6161
override_queries: None,
6262
make_codegen_backend: None,
6363
registry: rustc_driver::diagnostics_registry(),
64+
expanded_args: Default::default(),
6465
};
6566

6667
interface::run_compiler(config, |compiler| {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
include ../tools.mk
2+
3+
# only-windows-msvc
4+
5+
# tests if the pdb contains the following information in the LF_BUILDINFO:
6+
# 1. the commandline args to compile it (cmd)
7+
# 2. full path to the compiler (cl)
8+
9+
# we just do a stringsearch on the pdb, as these need to show up at least once, as the LF_BUILDINFO is created for each cgu
10+
# actual parsing would be better, but this is a simple and good enough solution for now
11+
12+
all:
13+
$(RUSTC_ORIGINAL) main.rs -g --crate-name my_crate_name --crate-type bin -C metadata=dc9ef878b0a48666 --out-dir $(TMPDIR)
14+
cat '$(TMPDIR)/my_crate_name.pdb' | grep -F '$(RUSTC_ORIGINAL)'
15+
# using a file containing the string so I don't have problems with escaping quotes and spaces
16+
cat '$(TMPDIR)/my_crate_name.pdb' | grep -f 'stringlist.txt'
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fn main() {
2+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"main.rs" "-g" "--crate-name" "my_crate_name" "--crate-type" "bin" "-C" "metadata=dc9ef878b0a48666" "--out-dir"

0 commit comments

Comments
 (0)