Skip to content

Commit a77cc64

Browse files
committed
Auto merge of #89819 - davidtwco:issue-81024-multiple-crates-multiple-dwarves, r=nagisa
cg: split dwarf for crate dependencies Fixes #81024. - In #79570, `-Z split-dwarf-kind={none,single,split}` was replaced by `-C split-debuginfo={off,packed,unpacked}`. `-C split-debuginfo`'s packed and unpacked aren't exact parallels to single and split, respectively. On Unix, `-C split-debuginfo=packed` will put debuginfo in object files and package debuginfo into a DWARF package file (`.dwp`) and `-C split-debuginfo=unpacked` will put debuginfo in dwarf object files and won't package it. In the initial implementation of Split DWARF, split mode wrote sections which did not require relocation into a DWARF object (`.dwo`) file which was ignored by the linker and then packaged those DWARF objects into DWARF packages (`.dwp`). In single mode, sections which did not require relocation were written into object files but ignored by the linker and were not packaged. However, both split and single modes could be packaged or not, the primary difference in behaviour was where the debuginfo sections that did not require link-time relocation were written (in a DWARF object or the object file). In the first commit of this PR, I re-introduce a `-Z split-dwarf-kind` flag, which can be used to pick between split and single modes when `-C split-debuginfo` is used to enable Split DWARF (either packed or unpacked). - Split DWARF packaging requires all of the object files to exist, including those in dependencies. ~~Therefore, the second commit of this PR makes rustc keep all objects or dwarf objects for unpacked mode and if the crate is a dependency in packed mode (determined by heuristic: if no linking is taking place), then objects or dwarf objects are kept. Objects are kept if `-Z split-dwarf-kind` is `SplitDwarfKind::Single`, and dwarf objects if `SplitDwarfKind::Split`.~~ ~~There are other approaches that could be taken to supporting packed Split DWARF with crate dependencies but this seemed like the least complicated and was contained to only rustc. Other potential approaches are described in #81024 (comment), I'm happy to change the approach I've taken here if it isn't what we're looking for.~~ See #89819 (comment) for the current approach. - ~~There's still a dependency on `llvm-dwp` after this change, which [we probably want to move away from](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/llvm-dwp.20is.20not.20recommended) but that seems out-of-scope for this PR. Ideally, Split DWARF (in packed or unpacked modes) will be usable on nightly after this lands. If there aren't any bugs reported then it's possible we could allow Split DWARF to be used on stable after this change, it depends whether or not switching away from `llvm-dwp` later would break any guarantees, or whether we'd want to change how we handle this cross-crate case in future.~~ See #89819 (comment). r? `@nagisa` cc `@alexcrichton`
2 parents f1ce0e6 + 7ecdc89 commit a77cc64

File tree

18 files changed

+443
-162
lines changed

18 files changed

+443
-162
lines changed

Cargo.lock

+60-17
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
99
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
1010
dependencies = [
1111
"compiler_builtins",
12-
"gimli",
12+
"gimli 0.25.0",
1313
"rustc-std-workspace-alloc",
1414
"rustc-std-workspace-core",
1515
]
@@ -87,9 +87,9 @@ dependencies = [
8787

8888
[[package]]
8989
name = "anyhow"
90-
version = "1.0.34"
90+
version = "1.0.51"
9191
source = "registry+https://github.com/rust-lang/crates.io-index"
92-
checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
92+
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
9393

9494
[[package]]
9595
name = "array_tool"
@@ -1158,6 +1158,12 @@ version = "0.1.2"
11581158
source = "registry+https://github.com/rust-lang/crates.io-index"
11591159
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
11601160

1161+
[[package]]
1162+
name = "fallible-iterator"
1163+
version = "0.2.0"
1164+
source = "registry+https://github.com/rust-lang/crates.io-index"
1165+
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
1166+
11611167
[[package]]
11621168
name = "filetime"
11631169
version = "0.2.14"
@@ -1446,6 +1452,17 @@ dependencies = [
14461452
"rustc-std-workspace-core",
14471453
]
14481454

1455+
[[package]]
1456+
name = "gimli"
1457+
version = "0.26.1"
1458+
source = "registry+https://github.com/rust-lang/crates.io-index"
1459+
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
1460+
dependencies = [
1461+
"fallible-iterator",
1462+
"indexmap",
1463+
"stable_deref_trait",
1464+
]
1465+
14491466
[[package]]
14501467
name = "git2"
14511468
version = "0.13.23"
@@ -2339,6 +2356,18 @@ dependencies = [
23392356
"rustc-std-workspace-core",
23402357
]
23412358

2359+
[[package]]
2360+
name = "object"
2361+
version = "0.27.1"
2362+
source = "registry+https://github.com/rust-lang/crates.io-index"
2363+
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
2364+
dependencies = [
2365+
"crc32fast",
2366+
"flate2",
2367+
"indexmap",
2368+
"memchr",
2369+
]
2370+
23422371
[[package]]
23432372
name = "odht"
23442373
version = "0.3.1"
@@ -3725,10 +3754,11 @@ dependencies = [
37253754
"itertools 0.9.0",
37263755
"jobserver",
37273756
"libc",
3728-
"object",
3757+
"object 0.26.2",
37293758
"pathdiff",
37303759
"regex",
37313760
"rustc_apfloat",
3761+
"rustc_arena",
37323762
"rustc_ast",
37333763
"rustc_attr",
37343764
"rustc_data_structures",
@@ -3749,6 +3779,7 @@ dependencies = [
37493779
"smallvec",
37503780
"snap",
37513781
"tempfile",
3782+
"thorin-dwp",
37523783
"tracing",
37533784
]
37543785

@@ -4993,7 +5024,7 @@ dependencies = [
49935024
"hermit-abi",
49945025
"libc",
49955026
"miniz_oxide",
4996-
"object",
5027+
"object 0.26.2",
49975028
"panic_abort",
49985029
"panic_unwind",
49995030
"profiler_builtins",
@@ -5057,9 +5088,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
50575088

50585089
[[package]]
50595090
name = "structopt"
5060-
version = "0.3.16"
5091+
version = "0.3.25"
50615092
source = "registry+https://github.com/rust-lang/crates.io-index"
5062-
checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
5093+
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
50635094
dependencies = [
50645095
"clap",
50655096
"lazy_static",
@@ -5068,9 +5099,9 @@ dependencies = [
50685099

50695100
[[package]]
50705101
name = "structopt-derive"
5071-
version = "0.4.9"
5102+
version = "0.4.18"
50725103
source = "registry+https://github.com/rust-lang/crates.io-index"
5073-
checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
5104+
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
50745105
dependencies = [
50755106
"heck",
50765107
"proc-macro-error",
@@ -5249,24 +5280,36 @@ dependencies = [
52495280

52505281
[[package]]
52515282
name = "thiserror"
5252-
version = "1.0.20"
5283+
version = "1.0.30"
52535284
source = "registry+https://github.com/rust-lang/crates.io-index"
5254-
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
5285+
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
52555286
dependencies = [
52565287
"thiserror-impl",
52575288
]
52585289

52595290
[[package]]
52605291
name = "thiserror-impl"
5261-
version = "1.0.20"
5292+
version = "1.0.30"
52625293
source = "registry+https://github.com/rust-lang/crates.io-index"
5263-
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
5294+
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
52645295
dependencies = [
52655296
"proc-macro2",
52665297
"quote",
52675298
"syn",
52685299
]
52695300

5301+
[[package]]
5302+
name = "thorin-dwp"
5303+
version = "0.1.1"
5304+
source = "registry+https://github.com/rust-lang/crates.io-index"
5305+
checksum = "039d1fc0bfdb73910c2702893515580e38c192f47a987bc98ddd38a36f2d953a"
5306+
dependencies = [
5307+
"gimli 0.26.1",
5308+
"indexmap",
5309+
"object 0.27.1",
5310+
"tracing",
5311+
]
5312+
52705313
[[package]]
52715314
name = "thread_local"
52725315
version = "1.0.1"
@@ -5394,9 +5437,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
53945437

53955438
[[package]]
53965439
name = "tracing"
5397-
version = "0.1.28"
5440+
version = "0.1.29"
53985441
source = "registry+https://github.com/rust-lang/crates.io-index"
5399-
checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8"
5442+
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
54005443
dependencies = [
54015444
"cfg-if 1.0.0",
54025445
"pin-project-lite",
@@ -5406,9 +5449,9 @@ dependencies = [
54065449

54075450
[[package]]
54085451
name = "tracing-attributes"
5409-
version = "0.1.17"
5452+
version = "0.1.18"
54105453
source = "registry+https://github.com/rust-lang/crates.io-index"
5411-
checksum = "c4f915eb6abf914599c200260efced9203504c4c37380af10cdf3b7d36970650"
5454+
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
54125455
dependencies = [
54135456
"proc-macro2",
54145457
"quote",

compiler/rustc_codegen_llvm/src/back/write.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_errors::{FatalError, Handler, Level};
2323
use rustc_fs_util::{link_or_copy, path_to_c_string};
2424
use rustc_middle::bug;
2525
use rustc_middle::ty::TyCtxt;
26-
use rustc_session::config::{self, Lto, OutputType, Passes, SwitchWithOptPath};
26+
use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
2727
use rustc_session::Session;
2828
use rustc_span::symbol::sym;
2929
use rustc_span::InnerSpan;
@@ -106,7 +106,11 @@ pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm:
106106

107107
pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
108108
let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
109-
tcx.output_filenames(()).split_dwarf_path(tcx.sess.split_debuginfo(), Some(mod_name))
109+
tcx.output_filenames(()).split_dwarf_path(
110+
tcx.sess.split_debuginfo(),
111+
tcx.sess.opts.debugging_opts.split_dwarf_kind,
112+
Some(mod_name),
113+
)
110114
} else {
111115
None
112116
};
@@ -892,17 +896,18 @@ pub(crate) unsafe fn codegen(
892896
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name);
893897

894898
let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name);
895-
let dwo_out = match cgcx.split_debuginfo {
896-
// Don't change how DWARF is emitted in single mode (or when disabled).
897-
SplitDebuginfo::Off | SplitDebuginfo::Packed => None,
898-
// Emit (a subset of the) DWARF into a separate file in split mode.
899-
SplitDebuginfo::Unpacked => {
900-
if cgcx.target_can_use_split_dwarf {
901-
Some(dwo_out.as_path())
902-
} else {
903-
None
904-
}
905-
}
899+
let dwo_out = match (cgcx.split_debuginfo, cgcx.split_dwarf_kind) {
900+
// Don't change how DWARF is emitted when disabled.
901+
(SplitDebuginfo::Off, _) => None,
902+
// Don't provide a DWARF object path if split debuginfo is enabled but this is
903+
// a platform that doesn't support Split DWARF.
904+
_ if !cgcx.target_can_use_split_dwarf => None,
905+
// Don't provide a DWARF object path in single mode, sections will be written
906+
// into the object as normal but ignored by linker.
907+
(_, SplitDwarfKind::Single) => None,
908+
// Emit (a subset of the) DWARF into a separate dwarf object file in split
909+
// mode.
910+
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
906911
};
907912

908913
with_codegen(tm, llmod, config.no_builtins, |cpm| {
@@ -939,7 +944,9 @@ pub(crate) unsafe fn codegen(
939944

940945
Ok(module.into_compiled_module(
941946
config.emit_obj != EmitObj::None,
942-
cgcx.target_can_use_split_dwarf && cgcx.split_debuginfo == SplitDebuginfo::Unpacked,
947+
cgcx.target_can_use_split_dwarf
948+
&& cgcx.split_debuginfo != SplitDebuginfo::Off
949+
&& cgcx.split_dwarf_kind == SplitDwarfKind::Split,
943950
config.emit_bc,
944951
&cgcx.output_filenames,
945952
))

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,11 @@ pub fn compile_unit_metadata<'ll, 'tcx>(
10721072
let output_filenames = tcx.output_filenames(());
10731073
let split_name = if tcx.sess.target_can_use_split_dwarf() {
10741074
output_filenames
1075-
.split_dwarf_path(tcx.sess.split_debuginfo(), Some(codegen_unit_name))
1075+
.split_dwarf_path(
1076+
tcx.sess.split_debuginfo(),
1077+
tcx.sess.opts.debugging_opts.split_dwarf_kind,
1078+
Some(codegen_unit_name),
1079+
)
10761080
// We get a path relative to the working directory from split_dwarf_path
10771081
.map(|f| tcx.sess.source_map().path_mapping().map_prefix(f).0)
10781082
} else {

compiler/rustc_codegen_ssa/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ tracing = "0.1"
1414
libc = "0.2.50"
1515
jobserver = "0.1.22"
1616
tempfile = "3.2"
17+
thorin-dwp = "0.1.1"
1718
pathdiff = "0.2.0"
1819
snap = "1"
1920
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
2021
regex = "1.4"
2122

2223
rustc_serialize = { path = "../rustc_serialize" }
24+
rustc_arena = { path = "../rustc_arena" }
2325
rustc_ast = { path = "../rustc_ast" }
2426
rustc_span = { path = "../rustc_span" }
2527
rustc_middle = { path = "../rustc_middle" }

0 commit comments

Comments
 (0)