mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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.
This commit is contained in:
parent
f91c53d738
commit
4cdc633301
@ -216,6 +216,24 @@ pub fn target_machine_factory(
|
||||
|
||||
let force_emulated_tls = sess.target.force_emulated_tls;
|
||||
|
||||
// copy the exe path, followed by path all into one buffer
|
||||
// null terminating them so we can use them as null terminated strings
|
||||
let args_cstr_buff = {
|
||||
let mut args_cstr_buff: Vec<u8> = Vec::new();
|
||||
let exe_path = std::env::current_exe().unwrap_or_default();
|
||||
let exe_path_str = exe_path.into_os_string().into_string().unwrap_or_default();
|
||||
|
||||
args_cstr_buff.extend_from_slice(exe_path_str.as_bytes());
|
||||
args_cstr_buff.push(0);
|
||||
|
||||
for arg in sess.expanded_args.iter() {
|
||||
args_cstr_buff.extend_from_slice(arg.as_bytes());
|
||||
args_cstr_buff.push(0);
|
||||
}
|
||||
|
||||
args_cstr_buff
|
||||
};
|
||||
|
||||
Arc::new(move |config: TargetMachineFactoryConfig| {
|
||||
let split_dwarf_file =
|
||||
path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0;
|
||||
@ -242,6 +260,8 @@ pub fn target_machine_factory(
|
||||
use_init_array,
|
||||
split_dwarf_file.as_ptr(),
|
||||
force_emulated_tls,
|
||||
args_cstr_buff.as_ptr() as *const c_char,
|
||||
args_cstr_buff.len(),
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -2132,7 +2132,10 @@ extern "C" {
|
||||
UseInitArray: bool,
|
||||
SplitDwarfFile: *const c_char,
|
||||
ForceEmulatedTls: bool,
|
||||
ArgsCstrBuff: *const c_char,
|
||||
ArgsCstrBuffLen: usize,
|
||||
) -> Option<&'static mut TargetMachine>;
|
||||
|
||||
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
|
||||
pub fn LLVMRustAddLibraryInfo<'a>(
|
||||
PM: &PassManager<'a>,
|
||||
|
@ -343,6 +343,12 @@ pub struct CodegenContext<B: WriteBackendMethods> {
|
||||
pub split_debuginfo: rustc_target::spec::SplitDebuginfo,
|
||||
pub split_dwarf_kind: rustc_session::config::SplitDwarfKind,
|
||||
|
||||
/// All commandline args used to invoke the compiler, with @file args fully expanded.
|
||||
/// This will only be used within debug info, e.g. in the pdb file on windows
|
||||
/// This is mainly useful for other tools that reads that debuginfo to figure out
|
||||
/// how to call the compiler with the same arguments.
|
||||
pub expanded_args: Vec<String>,
|
||||
|
||||
/// Handler to use for diagnostics produced during codegen.
|
||||
pub diag_emitter: SharedEmitter,
|
||||
/// LLVM optimizations for which we want to print remarks.
|
||||
@ -1108,6 +1114,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
||||
incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()),
|
||||
cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(),
|
||||
coordinator_send,
|
||||
expanded_args: tcx.sess.expanded_args.clone(),
|
||||
diag_emitter: shared_emitter.clone(),
|
||||
output_filenames: tcx.output_filenames(()).clone(),
|
||||
regular_module_config: regular_config,
|
||||
|
@ -313,6 +313,7 @@ fn run_compiler(
|
||||
override_queries: None,
|
||||
make_codegen_backend,
|
||||
registry: diagnostics_registry(),
|
||||
expanded_args: args,
|
||||
};
|
||||
|
||||
match make_input(&early_error_handler, &matches.free) {
|
||||
|
@ -279,6 +279,12 @@ pub struct Config {
|
||||
|
||||
/// Registry of diagnostics codes.
|
||||
pub registry: Registry,
|
||||
|
||||
/// All commandline args used to invoke the compiler, with @file args fully expanded.
|
||||
/// This will only be used within debug info, e.g. in the pdb file on windows
|
||||
/// This is mainly useful for other tools that reads that debuginfo to figure out
|
||||
/// how to call the compiler with the same arguments.
|
||||
pub expanded_args: Vec<String>,
|
||||
}
|
||||
|
||||
// JUSTIFICATION: before session exists, only config
|
||||
@ -317,6 +323,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
||||
config.make_codegen_backend,
|
||||
registry.clone(),
|
||||
config.ice_file,
|
||||
config.expanded_args,
|
||||
);
|
||||
|
||||
if let Some(parse_sess_created) = config.parse_sess_created {
|
||||
|
@ -68,6 +68,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se
|
||||
None,
|
||||
"",
|
||||
None,
|
||||
Default::default(),
|
||||
);
|
||||
(sess, cfg)
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ pub fn create_session(
|
||||
>,
|
||||
descriptions: Registry,
|
||||
ice_file: Option<PathBuf>,
|
||||
expanded_args: Vec<String>,
|
||||
) -> (Session, Box<dyn CodegenBackend>) {
|
||||
let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
|
||||
make_codegen_backend(&sopts)
|
||||
@ -113,6 +114,7 @@ pub fn create_session(
|
||||
target_override,
|
||||
rustc_version_str().unwrap_or("unknown"),
|
||||
ice_file,
|
||||
expanded_args,
|
||||
);
|
||||
|
||||
codegen_backend.init(&sess);
|
||||
|
@ -406,7 +406,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
bool RelaxELFRelocations,
|
||||
bool UseInitArray,
|
||||
const char *SplitDwarfFile,
|
||||
bool ForceEmulatedTls) {
|
||||
bool ForceEmulatedTls,
|
||||
const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
|
||||
|
||||
auto OptLevel = fromRust(RustOptLevel);
|
||||
auto RM = fromRust(RustReloc);
|
||||
@ -462,12 +463,48 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||
|
||||
Options.EmitStackSizeSection = EmitStackSizeSection;
|
||||
|
||||
|
||||
if (ArgsCstrBuff != nullptr)
|
||||
{
|
||||
int buffer_offset = 0;
|
||||
assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
|
||||
|
||||
const size_t arg0_len = std::strlen(ArgsCstrBuff);
|
||||
char* arg0 = new char[arg0_len + 1];
|
||||
memcpy(arg0, ArgsCstrBuff, arg0_len);
|
||||
arg0[arg0_len] = '\0';
|
||||
buffer_offset += arg0_len + 1;
|
||||
|
||||
const int num_cmd_arg_strings =
|
||||
std::count(&ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0');
|
||||
|
||||
std::string* cmd_arg_strings = new std::string[num_cmd_arg_strings];
|
||||
for (int i = 0; i < num_cmd_arg_strings; ++i)
|
||||
{
|
||||
assert(buffer_offset < ArgsCstrBuffLen);
|
||||
const int len = std::strlen(ArgsCstrBuff + buffer_offset);
|
||||
cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len);
|
||||
buffer_offset += len + 1;
|
||||
}
|
||||
|
||||
assert(buffer_offset == ArgsCstrBuffLen);
|
||||
|
||||
Options.MCOptions.Argv0 = arg0;
|
||||
Options.MCOptions.CommandLineArgs =
|
||||
llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings);
|
||||
}
|
||||
|
||||
TargetMachine *TM = TheTarget->createTargetMachine(
|
||||
Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
|
||||
return wrap(TM);
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
|
||||
|
||||
MCTargetOptions& MCOptions = unwrap(TM)->Options.MCOptions;
|
||||
delete[] MCOptions.Argv0;
|
||||
delete[] MCOptions.CommandLineArgs.data();
|
||||
|
||||
delete unwrap(TM);
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,12 @@ pub struct Session {
|
||||
|
||||
/// The version of the rustc process, possibly including a commit hash and description.
|
||||
pub cfg_version: &'static str,
|
||||
|
||||
/// All commandline args used to invoke the compiler, with @file args fully expanded.
|
||||
/// This will only be used within debug info, e.g. in the pdb file on windows
|
||||
/// This is mainly useful for other tools that reads that debuginfo to figure out
|
||||
/// how to call the compiler with the same arguments.
|
||||
pub expanded_args: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct PerfStats {
|
||||
@ -1325,6 +1331,7 @@ pub fn build_session(
|
||||
target_override: Option<Target>,
|
||||
cfg_version: &'static str,
|
||||
ice_file: Option<PathBuf>,
|
||||
expanded_args: Vec<String>,
|
||||
) -> Session {
|
||||
// FIXME: This is not general enough to make the warning lint completely override
|
||||
// normal diagnostic warnings, since the warning lint can also be denied and changed
|
||||
@ -1467,6 +1474,7 @@ pub fn build_session(
|
||||
target_features: Default::default(),
|
||||
unstable_target_features: Default::default(),
|
||||
cfg_version,
|
||||
expanded_args,
|
||||
};
|
||||
|
||||
validate_commandline_args_with_session_available(&sess);
|
||||
|
@ -157,6 +157,12 @@ pub(crate) struct Options {
|
||||
/// Note: this field is duplicated in `RenderOptions` because it's useful
|
||||
/// to have it in both places.
|
||||
pub(crate) unstable_features: rustc_feature::UnstableFeatures,
|
||||
|
||||
/// All commandline args used to invoke the compiler, with @file args fully expanded.
|
||||
/// This will only be used within debug info, e.g. in the pdb file on windows
|
||||
/// This is mainly useful for other tools that reads that debuginfo to figure out
|
||||
/// how to call the compiler with the same arguments.
|
||||
pub(crate) expanded_args: Vec<String>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Options {
|
||||
@ -744,6 +750,7 @@ impl Options {
|
||||
json_unused_externs,
|
||||
scrape_examples_options,
|
||||
unstable_features,
|
||||
expanded_args: args,
|
||||
};
|
||||
let render_options = RenderOptions {
|
||||
output,
|
||||
|
@ -194,6 +194,7 @@ pub(crate) fn create_config(
|
||||
describe_lints,
|
||||
lint_cap,
|
||||
scrape_examples_options,
|
||||
expanded_args,
|
||||
..
|
||||
}: RustdocOptions,
|
||||
RenderOptions { document_private, .. }: &RenderOptions,
|
||||
@ -291,6 +292,7 @@ pub(crate) fn create_config(
|
||||
make_codegen_backend: None,
|
||||
registry: rustc_driver::diagnostics_registry(),
|
||||
ice_file: None,
|
||||
expanded_args,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
|
||||
make_codegen_backend: None,
|
||||
registry: rustc_driver::diagnostics_registry(),
|
||||
ice_file: None,
|
||||
expanded_args: options.expanded_args.clone(),
|
||||
};
|
||||
|
||||
let test_args = options.test_args.clone();
|
||||
|
@ -61,6 +61,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
|
||||
override_queries: None,
|
||||
make_codegen_backend: None,
|
||||
registry: rustc_driver::diagnostics_registry(),
|
||||
expanded_args: Default::default(),
|
||||
};
|
||||
|
||||
interface::run_compiler(config, |compiler| {
|
||||
|
16
tests/run-make/pdb-buildinfo-cl-cmd/Makefile
Normal file
16
tests/run-make/pdb-buildinfo-cl-cmd/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
include ../tools.mk
|
||||
|
||||
# only-windows-msvc
|
||||
|
||||
# tests if the pdb contains the following information in the LF_BUILDINFO:
|
||||
# 1. the commandline args to compile it (cmd)
|
||||
# 2. full path to the compiler (cl)
|
||||
|
||||
# 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
|
||||
# actual parsing would be better, but this is a simple and good enough solution for now
|
||||
|
||||
all:
|
||||
$(RUSTC_ORIGINAL) main.rs -g --crate-name my_crate_name --crate-type bin -C metadata=dc9ef878b0a48666 --out-dir $(TMPDIR)
|
||||
cat '$(TMPDIR)/my_crate_name.pdb' | grep -F '$(RUSTC_ORIGINAL)'
|
||||
# using a file containing the string so I don't have problems with escaping quotes and spaces
|
||||
cat '$(TMPDIR)/my_crate_name.pdb' | grep -f 'stringlist.txt'
|
2
tests/run-make/pdb-buildinfo-cl-cmd/main.rs
Normal file
2
tests/run-make/pdb-buildinfo-cl-cmd/main.rs
Normal file
@ -0,0 +1,2 @@
|
||||
fn main() {
|
||||
}
|
1
tests/run-make/pdb-buildinfo-cl-cmd/stringlist.txt
Normal file
1
tests/run-make/pdb-buildinfo-cl-cmd/stringlist.txt
Normal file
@ -0,0 +1 @@
|
||||
"main.rs" "-g" "--crate-name" "my_crate_name" "--crate-type" "bin" "-C" "metadata=dc9ef878b0a48666" "--out-dir"
|
Loading…
Reference in New Issue
Block a user