From 1e0ad0c1d4fdca7a37221e05fd5e39739d9084f5 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 20 Jun 2022 16:26:51 -0700 Subject: [PATCH] Implement support for DWARF version 5. DWARF version 5 brings a number of improvements over version 4. Quoting from the announcement [1]: > Version 5 incorporates improvements in many areas: better data compression, > separation of debugging data from executable files, improved description of > macros and source files, faster searching for symbols, improved debugging > optimized code, as well as numerous improvements in functionality and > performance. On platforms where DWARF version 5 is supported (Linux, primarily), this commit adds support for it behind a new `-Z dwarf-version=5` flag. [1]: https://dwarfstd.org/Public_Review.php --- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 16 +++++++-------- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/options.rs | 2 ++ compiler/rustc_session/src/session.rs | 6 ++++++ .../rustc_target/src/spec/android_base.rs | 2 +- compiler/rustc_target/src/spec/apple_base.rs | 2 +- .../rustc_target/src/spec/dragonfly_base.rs | 2 +- .../rustc_target/src/spec/freebsd_base.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 14 ++++++------- compiler/rustc_target/src/spec/netbsd_base.rs | 2 +- .../rustc_target/src/spec/openbsd_base.rs | 2 +- .../src/compiler-flags/dwarf-version.md | 9 +++++++++ src/test/assembly/dwarf5.rs | 20 +++++++++++++++++++ 13 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/dwarf-version.md create mode 100644 src/test/assembly/dwarf5.rs diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 64ecbc82c5600..730048d061b55 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -103,14 +103,14 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { // for macOS to understand. For more info see #11352 // This can be overridden using --llvm-opts -dwarf-version,N. // Android has the same issue (#22398) - if let Some(version) = sess.target.dwarf_version { - llvm::LLVMRustAddModuleFlag( - self.llmod, - llvm::LLVMModFlagBehavior::Warning, - "Dwarf Version\0".as_ptr().cast(), - version, - ) - } + let dwarf_version = + sess.opts.debugging_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version); + llvm::LLVMRustAddModuleFlag( + self.llmod, + llvm::LLVMModFlagBehavior::Warning, + "Dwarf Version\0".as_ptr().cast(), + dwarf_version, + ); // Indicate that we want CodeView debug information on MSVC if sess.target.is_like_msvc { diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 1bb79a0264dd1..55827ff583aff 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -733,6 +733,7 @@ fn test_debugging_options_tracking_hash() { tracked!(dep_info_omit_d_target, true); tracked!(drop_tracking, true); tracked!(dual_proc_macros, true); + tracked!(dwarf_version, Some(5)); tracked!(fewer_names, Some(true)); tracked!(force_unstable_if_unmarked, true); tracked!(fuel, Some(("abc".to_string(), 99))); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b617eb02eb6e3..8f1057b793fa3 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1272,6 +1272,8 @@ options! { computed `block` spans (one span encompassing a block's terminator and \ all statements). If `-Z instrument-coverage` is also enabled, create \ an additional `.html` file showing the computed coverage spans."), + dwarf_version: Option = (None, parse_opt_number, [TRACKED], + "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emit a section containing stack size metadata (default: no)"), fewer_names: Option = (None, parse_opt_bool, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 1eee0c3163d40..1cccef2f64fec 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1498,6 +1498,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) { )) } } + + if let Some(dwarf_version) = sess.opts.debugging_opts.dwarf_version { + if dwarf_version > 5 { + sess.err(&format!("requested DWARF version {} is greater than 5", dwarf_version)); + } + } } /// Holds data on the current incremental compilation session, if there is one. diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs index c2b9d696776f5..dc06597db6fd4 100644 --- a/compiler/rustc_target/src/spec/android_base.rs +++ b/compiler/rustc_target/src/spec/android_base.rs @@ -3,7 +3,7 @@ use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); base.os = "android".into(); - base.dwarf_version = Some(2); + base.default_dwarf_version = 2; base.position_independent_executables = true; base.has_thread_local = false; // This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867 diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index e8460a509e2ba..713dc9a1f0ea7 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -28,7 +28,7 @@ pub fn opts(os: &'static str) -> TargetOptions { executables: true, families: cvs!["unix"], is_like_osx: true, - dwarf_version: Some(2), + default_dwarf_version: 2, frame_pointer: FramePointer::Always, has_rpath: true, dll_suffix: ".dylib".into(), diff --git a/compiler/rustc_target/src/spec/dragonfly_base.rs b/compiler/rustc_target/src/spec/dragonfly_base.rs index b59322d07f57a..c1e469746cb4c 100644 --- a/compiler/rustc_target/src/spec/dragonfly_base.rs +++ b/compiler/rustc_target/src/spec/dragonfly_base.rs @@ -9,7 +9,7 @@ pub fn opts() -> TargetOptions { has_rpath: true, position_independent_executables: true, relro_level: RelroLevel::Full, - dwarf_version: Some(2), + default_dwarf_version: 2, ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs index a7e0f9f704127..36312d26e3700 100644 --- a/compiler/rustc_target/src/spec/freebsd_base.rs +++ b/compiler/rustc_target/src/spec/freebsd_base.rs @@ -10,7 +10,7 @@ pub fn opts() -> TargetOptions { position_independent_executables: true, relro_level: RelroLevel::Full, abi_return_struct_as_int: true, - dwarf_version: Some(2), + default_dwarf_version: 2, ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index a08603da04095..48ccb10f21426 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1275,9 +1275,9 @@ pub struct TargetOptions { pub is_like_msvc: bool, /// Whether a target toolchain is like WASM. pub is_like_wasm: bool, - /// Version of DWARF to use if not using the default. + /// Default supported version of DWARF on this platform. /// Useful because some platforms (osx, bsd) only want up to DWARF2. - pub dwarf_version: Option, + pub default_dwarf_version: u32, /// Whether the linker support GNU-like arguments such as -O. Defaults to true. pub linker_is_gnu: bool, /// The MinGW toolchain has a known issue that prevents it from correctly @@ -1539,7 +1539,7 @@ impl Default for TargetOptions { is_like_windows: false, is_like_msvc: false, is_like_wasm: false, - dwarf_version: None, + default_dwarf_version: 4, linker_is_gnu: true, allows_weak_linkage: true, has_rpath: false, @@ -1778,13 +1778,13 @@ impl Target { base.$key_name = s; } } ); - ($key_name:ident, Option) => ( { + ($key_name:ident, u32) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) { if s < 1 || s > 5 { return Err("Not a valid DWARF version number".into()); } - base.$key_name = Some(s as u32); + base.$key_name = s as u32; } } ); ($key_name:ident, Option) => ( { @@ -2143,7 +2143,7 @@ impl Target { key!(is_like_windows, bool); key!(is_like_msvc, bool); key!(is_like_wasm, bool); - key!(dwarf_version, Option); + key!(default_dwarf_version, u32); key!(linker_is_gnu, bool); key!(allows_weak_linkage, bool); key!(has_rpath, bool); @@ -2387,7 +2387,7 @@ impl ToJson for Target { target_option_val!(is_like_windows); target_option_val!(is_like_msvc); target_option_val!(is_like_wasm); - target_option_val!(dwarf_version); + target_option_val!(default_dwarf_version); target_option_val!(linker_is_gnu); target_option_val!(allows_weak_linkage); target_option_val!(has_rpath); diff --git a/compiler/rustc_target/src/spec/netbsd_base.rs b/compiler/rustc_target/src/spec/netbsd_base.rs index 69016d77cf97b..40ef04ba04382 100644 --- a/compiler/rustc_target/src/spec/netbsd_base.rs +++ b/compiler/rustc_target/src/spec/netbsd_base.rs @@ -11,7 +11,7 @@ pub fn opts() -> TargetOptions { position_independent_executables: true, relro_level: RelroLevel::Full, use_ctors_section: true, - dwarf_version: Some(2), + default_dwarf_version: 2, ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs index bbd322bb6ce2b..51cecdd47eab2 100644 --- a/compiler/rustc_target/src/spec/openbsd_base.rs +++ b/compiler/rustc_target/src/spec/openbsd_base.rs @@ -11,7 +11,7 @@ pub fn opts() -> TargetOptions { position_independent_executables: true, frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit... relro_level: RelroLevel::Full, - dwarf_version: Some(2), + default_dwarf_version: 2, ..Default::default() } } diff --git a/src/doc/unstable-book/src/compiler-flags/dwarf-version.md b/src/doc/unstable-book/src/compiler-flags/dwarf-version.md new file mode 100644 index 0000000000000..c5e86f17df741 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/dwarf-version.md @@ -0,0 +1,9 @@ +## `dwarf-version` + +This option controls the version of DWARF that the compiler emits, on platforms +that use DWARF to encode debug information. It takes one of the following +values: + +* `2`: DWARF version 2 (the default on certain platforms, like macOS). +* `4`: DWARF version 4 (the default on certain platforms, like Linux). +* `5`: DWARF version 5. diff --git a/src/test/assembly/dwarf5.rs b/src/test/assembly/dwarf5.rs new file mode 100644 index 0000000000000..f41e6bd55be7d --- /dev/null +++ b/src/test/assembly/dwarf5.rs @@ -0,0 +1,20 @@ +// Makes sure that `-Z dwarf-version=5` causes `rustc` to emit DWARF version 5. +// assembly-output: emit-asm +// compile-flags: -g --target x86_64-unknown-linux-gnu -Z dwarf-version=5 +// needs-llvm-components: x86 + +#![feature(no_core, lang_items)] +#![crate_type = "rlib"] +#![no_core] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +pub fn wibble() {} + +// CHECK: .section .debug_info +// CHECK-NOT: .short 2 +// CHECK-NOT: .short 4 +// CHECK: .short 5