Skip to content

Commit 7509c34

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 7509c34

File tree

16 files changed

+117
-1
lines changed

16 files changed

+117
-1
lines changed

compiler/rustc_codegen_llvm/src/back/write.rs

+20
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

+3
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

+7
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

+1
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

+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

+38-1
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

+8
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

+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 {
@@ -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

+2
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

+1
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

+1
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| {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
include ../tools.mk
2+
3+
# only-windows
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'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fn main() {
2+
}
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)