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
This commit is contained in:
parent
45263fc66d
commit
1e0ad0c1d4
13 changed files with 59 additions and 21 deletions
|
@ -103,14 +103,14 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
|
||||||
// for macOS to understand. For more info see #11352
|
// for macOS to understand. For more info see #11352
|
||||||
// This can be overridden using --llvm-opts -dwarf-version,N.
|
// This can be overridden using --llvm-opts -dwarf-version,N.
|
||||||
// Android has the same issue (#22398)
|
// Android has the same issue (#22398)
|
||||||
if let Some(version) = sess.target.dwarf_version {
|
let dwarf_version =
|
||||||
|
sess.opts.debugging_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version);
|
||||||
llvm::LLVMRustAddModuleFlag(
|
llvm::LLVMRustAddModuleFlag(
|
||||||
self.llmod,
|
self.llmod,
|
||||||
llvm::LLVMModFlagBehavior::Warning,
|
llvm::LLVMModFlagBehavior::Warning,
|
||||||
"Dwarf Version\0".as_ptr().cast(),
|
"Dwarf Version\0".as_ptr().cast(),
|
||||||
version,
|
dwarf_version,
|
||||||
)
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Indicate that we want CodeView debug information on MSVC
|
// Indicate that we want CodeView debug information on MSVC
|
||||||
if sess.target.is_like_msvc {
|
if sess.target.is_like_msvc {
|
||||||
|
|
|
@ -733,6 +733,7 @@ fn test_debugging_options_tracking_hash() {
|
||||||
tracked!(dep_info_omit_d_target, true);
|
tracked!(dep_info_omit_d_target, true);
|
||||||
tracked!(drop_tracking, true);
|
tracked!(drop_tracking, true);
|
||||||
tracked!(dual_proc_macros, true);
|
tracked!(dual_proc_macros, true);
|
||||||
|
tracked!(dwarf_version, Some(5));
|
||||||
tracked!(fewer_names, Some(true));
|
tracked!(fewer_names, Some(true));
|
||||||
tracked!(force_unstable_if_unmarked, true);
|
tracked!(force_unstable_if_unmarked, true);
|
||||||
tracked!(fuel, Some(("abc".to_string(), 99)));
|
tracked!(fuel, Some(("abc".to_string(), 99)));
|
||||||
|
|
|
@ -1272,6 +1272,8 @@ options! {
|
||||||
computed `block` spans (one span encompassing a block's terminator and \
|
computed `block` spans (one span encompassing a block's terminator and \
|
||||||
all statements). If `-Z instrument-coverage` is also enabled, create \
|
all statements). If `-Z instrument-coverage` is also enabled, create \
|
||||||
an additional `.html` file showing the computed coverage spans."),
|
an additional `.html` file showing the computed coverage spans."),
|
||||||
|
dwarf_version: Option<u32> = (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_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"emit a section containing stack size metadata (default: no)"),
|
"emit a section containing stack size metadata (default: no)"),
|
||||||
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||||
|
|
|
@ -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.
|
/// Holds data on the current incremental compilation session, if there is one.
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::spec::TargetOptions;
|
||||||
pub fn opts() -> TargetOptions {
|
pub fn opts() -> TargetOptions {
|
||||||
let mut base = super::linux_base::opts();
|
let mut base = super::linux_base::opts();
|
||||||
base.os = "android".into();
|
base.os = "android".into();
|
||||||
base.dwarf_version = Some(2);
|
base.default_dwarf_version = 2;
|
||||||
base.position_independent_executables = true;
|
base.position_independent_executables = true;
|
||||||
base.has_thread_local = false;
|
base.has_thread_local = false;
|
||||||
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
|
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn opts(os: &'static str) -> TargetOptions {
|
||||||
executables: true,
|
executables: true,
|
||||||
families: cvs!["unix"],
|
families: cvs!["unix"],
|
||||||
is_like_osx: true,
|
is_like_osx: true,
|
||||||
dwarf_version: Some(2),
|
default_dwarf_version: 2,
|
||||||
frame_pointer: FramePointer::Always,
|
frame_pointer: FramePointer::Always,
|
||||||
has_rpath: true,
|
has_rpath: true,
|
||||||
dll_suffix: ".dylib".into(),
|
dll_suffix: ".dylib".into(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn opts() -> TargetOptions {
|
||||||
has_rpath: true,
|
has_rpath: true,
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
relro_level: RelroLevel::Full,
|
relro_level: RelroLevel::Full,
|
||||||
dwarf_version: Some(2),
|
default_dwarf_version: 2,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn opts() -> TargetOptions {
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
relro_level: RelroLevel::Full,
|
relro_level: RelroLevel::Full,
|
||||||
abi_return_struct_as_int: true,
|
abi_return_struct_as_int: true,
|
||||||
dwarf_version: Some(2),
|
default_dwarf_version: 2,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1275,9 +1275,9 @@ pub struct TargetOptions {
|
||||||
pub is_like_msvc: bool,
|
pub is_like_msvc: bool,
|
||||||
/// Whether a target toolchain is like WASM.
|
/// Whether a target toolchain is like WASM.
|
||||||
pub is_like_wasm: bool,
|
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.
|
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
|
||||||
pub dwarf_version: Option<u32>,
|
pub default_dwarf_version: u32,
|
||||||
/// Whether the linker support GNU-like arguments such as -O. Defaults to true.
|
/// Whether the linker support GNU-like arguments such as -O. Defaults to true.
|
||||||
pub linker_is_gnu: bool,
|
pub linker_is_gnu: bool,
|
||||||
/// The MinGW toolchain has a known issue that prevents it from correctly
|
/// 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_windows: false,
|
||||||
is_like_msvc: false,
|
is_like_msvc: false,
|
||||||
is_like_wasm: false,
|
is_like_wasm: false,
|
||||||
dwarf_version: None,
|
default_dwarf_version: 4,
|
||||||
linker_is_gnu: true,
|
linker_is_gnu: true,
|
||||||
allows_weak_linkage: true,
|
allows_weak_linkage: true,
|
||||||
has_rpath: false,
|
has_rpath: false,
|
||||||
|
@ -1778,13 +1778,13 @@ impl Target {
|
||||||
base.$key_name = s;
|
base.$key_name = s;
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
($key_name:ident, Option<u32>) => ( {
|
($key_name:ident, u32) => ( {
|
||||||
let name = (stringify!($key_name)).replace("_", "-");
|
let name = (stringify!($key_name)).replace("_", "-");
|
||||||
if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
|
if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
|
||||||
if s < 1 || s > 5 {
|
if s < 1 || s > 5 {
|
||||||
return Err("Not a valid DWARF version number".into());
|
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<u64>) => ( {
|
($key_name:ident, Option<u64>) => ( {
|
||||||
|
@ -2143,7 +2143,7 @@ impl Target {
|
||||||
key!(is_like_windows, bool);
|
key!(is_like_windows, bool);
|
||||||
key!(is_like_msvc, bool);
|
key!(is_like_msvc, bool);
|
||||||
key!(is_like_wasm, bool);
|
key!(is_like_wasm, bool);
|
||||||
key!(dwarf_version, Option<u32>);
|
key!(default_dwarf_version, u32);
|
||||||
key!(linker_is_gnu, bool);
|
key!(linker_is_gnu, bool);
|
||||||
key!(allows_weak_linkage, bool);
|
key!(allows_weak_linkage, bool);
|
||||||
key!(has_rpath, bool);
|
key!(has_rpath, bool);
|
||||||
|
@ -2387,7 +2387,7 @@ impl ToJson for Target {
|
||||||
target_option_val!(is_like_windows);
|
target_option_val!(is_like_windows);
|
||||||
target_option_val!(is_like_msvc);
|
target_option_val!(is_like_msvc);
|
||||||
target_option_val!(is_like_wasm);
|
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!(linker_is_gnu);
|
||||||
target_option_val!(allows_weak_linkage);
|
target_option_val!(allows_weak_linkage);
|
||||||
target_option_val!(has_rpath);
|
target_option_val!(has_rpath);
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub fn opts() -> TargetOptions {
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
relro_level: RelroLevel::Full,
|
relro_level: RelroLevel::Full,
|
||||||
use_ctors_section: true,
|
use_ctors_section: true,
|
||||||
dwarf_version: Some(2),
|
default_dwarf_version: 2,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub fn opts() -> TargetOptions {
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit...
|
frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit...
|
||||||
relro_level: RelroLevel::Full,
|
relro_level: RelroLevel::Full,
|
||||||
dwarf_version: Some(2),
|
default_dwarf_version: 2,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
20
src/test/assembly/dwarf5.rs
Normal file
20
src/test/assembly/dwarf5.rs
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue