diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 50d21c7ed4c99..f7fa5fade9934 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -6,6 +6,5 @@ run-make/incr-add-rust-src-component/Makefile run-make/issue-84395-lto-embed-bitcode/Makefile run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile -run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile run-make/translation/Makefile diff --git a/tests/run-make/split-debuginfo/Makefile b/tests/run-make/split-debuginfo/Makefile deleted file mode 100644 index 5f463ffe8cde6..0000000000000 --- a/tests/run-make/split-debuginfo/Makefile +++ /dev/null @@ -1,371 +0,0 @@ -# ignore-cross-compile -# ignore-riscv64 On this platform only `-Csplit-debuginfo=off` is supported, see #120518 - -include ../tools.mk - -all: off packed unpacked - -ifeq ($(UNAME),Darwin) -# If disabled, don't run `dsymutil`. -off: - rm -rf $(TMPDIR)/*.dSYM - $(RUSTC) foo.rs -g -C split-debuginfo=off - [ ! -d $(TMPDIR)/foo.dSYM ] - -# Packed by default, but only if debuginfo is requested -packed: - rm -rf $(TMPDIR)/*.dSYM - $(RUSTC) foo.rs - [ ! -d $(TMPDIR)/foo.dSYM ] - rm -rf $(TMPDIR)/*.dSYM - $(RUSTC) foo.rs -g - [ -d $(TMPDIR)/foo.dSYM ] - rm -rf $(TMPDIR)/*.dSYM - $(RUSTC) foo.rs -g -C split-debuginfo=packed - [ -d $(TMPDIR)/foo.dSYM ] - rm -rf $(TMPDIR)/*.dSYM - -# Object files are preserved with unpacked and `dsymutil` isn't run -unpacked: - $(RUSTC) foo.rs -g -C split-debuginfo=unpacked - ls $(TMPDIR)/*.o - [ ! -d $(TMPDIR)/foo.dSYM ] -else -ifdef IS_WINDOWS -# Windows only supports packed debuginfo - nothing to test. -off: -packed: -unpacked: -else -# Some non-Windows, non-Darwin platforms are not stable, and some are. -ifeq ($(UNAME),Linux) - UNSTABLEOPTS := -else - UNSTABLEOPTS := -Zunstable-options -endif - -# - Debuginfo in `.o` files -# - `.o` deleted -# - `.dwo` never created -# - `.dwp` never created -off: - $(RUSTC) foo.rs -g -C $(UNSTABLEOPTS) split-debuginfo=off - [ ! -f $(TMPDIR)/*.dwp ] - [ ! -f $(TMPDIR)/*.dwo ] - $(RUSTC) foo.rs -g - [ ! -f $(TMPDIR)/*.dwp ] - [ ! -f $(TMPDIR)/*.dwo ] - -packed: packed-split packed-single packed-lto packed-remapped packed-crosscrate - -# - Debuginfo in `.dwo` files -# - `.o` deleted -# - `.dwo` deleted -# - `.dwp` present -packed-split: - $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=split - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/foo.dwp - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` deleted -# - `.dwo` never created -# - `.dwp` present -packed-single: - $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=single - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/foo.dwp - rm $(TMPDIR)/$(call BIN,foo) - -packed-lto: packed-lto-split packed-lto-single - -# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated -# - `.o` never created -# - `.dwo` never created -# - `.dwp` never created -packed-lto-split: - $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split \ - --crate-type=rlib -Clinker-plugin-lto - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/libbaz.rlib - -# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated -# - `.o` never created -# - `.dwo` never created -# - `.dwp` never created -packed-lto-single: - $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single \ - --crate-type=rlib -Clinker-plugin-lto - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/libbaz.rlib - -packed-remapped: packed-remapped-split packed-remapped-single packed-remapped-scope packed-remapped-wrong-scope - -# - Debuginfo in `.dwo` files -# - `.o` and binary refer to remapped `.dwo` paths which do not exist -# - `.o` deleted -# - `.dwo` deleted -# - `.dwp` present -packed-remapped-split: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ - -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/foo.dwp - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` and binary refer to remapped `.o` paths which do not exist -# - `.o` deleted -# - `.dwo` never created -# - `.dwp` present -packed-remapped-single: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ - -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/foo.dwp - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` and binary refer to remapped `.o` paths which do not exist -# - `.o` deleted -# - `.dwo` never created -# - `.dwp` present -packed-remapped-scope: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ - -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \ - -Z remap-path-scope=debuginfo foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/foo.dwp - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` and binary refer to remapped `.o` paths which do not exist -# - `.o` deleted -# - `.dwo` never created -# - `.dwp` present -packed-remapped-wrong-scope: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ - -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \ - -Z remap-path-scope=macro foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (grep $(TMPDIR)) || exit 1 - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/foo.dwp - rm $(TMPDIR)/$(call BIN,foo) - -packed-crosscrate: packed-crosscrate-split packed-crosscrate-single - -# - Debuginfo in `.dwo` files -# - (bar) `.rlib` file created, contains `.dwo` -# - (bar) `.o` deleted -# - (bar) `.dwo` deleted -# - (bar) `.dwp` never created -# - (main) `.o` deleted -# - (main) `.dwo` deleted -# - (main) `.dwp` present -packed-crosscrate-split: - $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \ - -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs - ls $(TMPDIR)/*.rlib - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ - -C split-debuginfo=packed -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/main.dwp - rm $(TMPDIR)/$(call BIN,main) - -# - Debuginfo in `.o` files -# - (bar) `.rlib` file created, contains `.o` -# - (bar) `.o` deleted -# - (bar) `.dwo` never created -# - (bar) `.dwp` never created -# - (main) `.o` deleted -# - (main) `.dwo` never created -# - (main) `.dwp` present -packed-crosscrate-single: - $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \ - -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs - ls $(TMPDIR)/*.rlib - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ - -C split-debuginfo=packed -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm $(TMPDIR)/main.dwp - rm $(TMPDIR)/$(call BIN,main) - -unpacked: unpacked-split unpacked-single unpacked-lto unpacked-remapped unpacked-crosscrate - -# - Debuginfo in `.dwo` files -# - `.o` deleted -# - `.dwo` present -# - `.dwp` never created -unpacked-split: - $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split - ls $(TMPDIR)/*.o && exit 1 || exit 0 - rm $(TMPDIR)/*.dwo - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` present -# - `.dwo` never created -# - `.dwp` never created -unpacked-single: - $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single - ls $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,foo) - -unpacked-lto: unpacked-lto-split unpacked-lto-single - -# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated -# - `.o` present (bitcode) -# - `.dwo` never created -# - `.dwp` never created -unpacked-lto-split: - $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=split \ - --crate-type=rlib -Clinker-plugin-lto - rm $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/libbaz.rlib - -# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated -# - `.o` present (bitcode) -# - `.dwo` never created -# - `.dwp` never created -unpacked-lto-single: - $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single \ - --crate-type=rlib -Clinker-plugin-lto - rm $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/libbaz.rlib - -unpacked-remapped: unpacked-remapped-split unpacked-remapped-single unpacked-remapped-scope unpacked-remapped-wrong-scope - -# - Debuginfo in `.dwo` files -# - `.o` and binary refer to remapped `.dwo` paths which do not exist -# - `.o` deleted -# - `.dwo` present -# - `.dwp` never created -unpacked-remapped-split: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ - -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 - ls $(TMPDIR)/*.o && exit 1 || exit 0 - rm $(TMPDIR)/*.dwo - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` and binary refer to remapped `.o` paths which do not exist -# - `.o` present -# - `.dwo` never created -# - `.dwp` never created -unpacked-remapped-single: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ - -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 - rm $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` and binary refer to remapped `.o` paths which do not exist -# - `.o` present -# - `.dwo` never created -# - `.dwp` never created -unpacked-remapped-scope: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ - -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \ - -Z remap-path-scope=debuginfo foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 - rm $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,foo) - -# - Debuginfo in `.o` files -# - `.o` and binary refer to remapped `.o` paths which do not exist -# - `.o` present -# - `.dwo` never created -# - `.dwp` never created -unpacked-remapped-wrong-scope: - $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ - -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a \ - -Z remap-path-scope=macro foo.rs -g - objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (grep $(TMPDIR)) || exit 1 - rm $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,foo) - -unpacked-crosscrate: unpacked-crosscrate-split unpacked-crosscrate-single - -# - Debuginfo in `.dwo` files -# - (bar) `.rlib` file created, contains `.dwo` -# - (bar) `.o` deleted -# - (bar) `.dwo` present -# - (bar) `.dwp` never created -# - (main) `.o` deleted -# - (main) `.dwo` present -# - (main) `.dwp` never created -unpacked-crosscrate-split: - $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \ - -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs - ls $(TMPDIR)/*.rlib - ls $(TMPDIR)/*.o && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ - -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs - ls $(TMPDIR)/*.o && exit 1 || exit 0 - rm $(TMPDIR)/*.dwo - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,main) - -# - Debuginfo in `.o` files -# - (bar) `.rlib` file created, contains `.o` -# - (bar) `.o` present -# - (bar) `.dwo` never created -# - (bar) `.dwp` never created -# - (main) `.o` present -# - (main) `.dwo` never created -# - (main) `.dwp` never created -unpacked-crosscrate-single: - $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \ - -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs - ls $(TMPDIR)/*.rlib - ls $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ - -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs - ls $(TMPDIR)/*.o - ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - rm $(TMPDIR)/$(call BIN,main) -endif -endif diff --git a/tests/run-make/split-debuginfo/baz.rs b/tests/run-make/split-debuginfo/lto.rs similarity index 100% rename from tests/run-make/split-debuginfo/baz.rs rename to tests/run-make/split-debuginfo/lto.rs diff --git a/tests/run-make/split-debuginfo/rmake.rs b/tests/run-make/split-debuginfo/rmake.rs new file mode 100644 index 0000000000000..c6bca9b560310 --- /dev/null +++ b/tests/run-make/split-debuginfo/rmake.rs @@ -0,0 +1,588 @@ +// This test checks that the `-C split-debuginfo` feature behaves in certain expected +// ways. It comes in 3 different flavours: +// * `off` - This indicates that split-debuginfo from the final artifact is +// not desired. This is not supported on Windows and is the default on +// Unix platforms except macOS. On macOS this means that `dsymutil` is +// not executed. + +// * `packed` - This means that debuginfo is desired in one location +// separate from the main executable. This is the default on Windows +// (`*.pdb`) and macOS (`*.dSYM`). On other Unix platforms this subsumes +// `-Zsplit-dwarf=single` and produces a `*.dwp` file. + +// * `unpacked` - This means that debuginfo will be roughly equivalent to +// object files, meaning that it's throughout the build directory +// rather than in one location (often the fastest for local development). +// This is not the default on any platform and is not supported on Windows. +// For each test, compilation should be successful, output artifacts should be +// exactly what is expected, no more, no less, and in some cases, the dwarf dump +// of debuginfo should reveal a certain symbol and the current working directory, +// depending on if the scope passed was wrong or not. +// See https://github.com/rust-lang/rust/pull/81493 + +//@ ignore-windows +// Reason: Windows only supports packed debuginfo - nothing to test. +//@ ignore-riscv64 +// Reason: on this platform only `-Csplit-debuginfo=off` is supported, see #120518 + +//FIXME(Oneirical): try it with ignore-cross-compile + +use run_make_support::{ + bin_name, cwd, has_extension, is_darwin, llvm_dwarfdump, rfs, rust_lib_name, rustc, + shallow_find_files, target, Rustc, +}; + +fn main() { + if is_darwin() { + // If disabled, don't run `dsymutil`. + for dsym in shallow_find_files(cwd(), |path| has_extension(path, "dSYM")) { + rfs::remove_file(dsym); + } + rustc().input("foo.rs").arg("-Cdebuginfo=2").arg("-Csplit-debuginfo=off").run(); + check_extension_not_exists("dSYM"); + + // Packed by default, but only if debuginfo is requested + for dsym in shallow_find_files(cwd(), |path| has_extension(path, "dSYM")) { + rfs::remove_file(dsym); + } + rustc().input("foo.rs").run(); + check_extension_not_exists("dSYM"); + rustc().input("foo.rs").arg("-Cdebuginfo=2").run(); + check_extension_exists("dSYM"); + for dsym in shallow_find_files(cwd(), |path| has_extension(path, "dSYM")) { + rfs::remove_file(dsym); + } + rustc().input("foo.rs").arg("-Cdebuginfo=2").arg("-Csplit-debuginfo=packed").run(); + check_extension_exists("dSYM"); + + // Object files are preserved with unpacked and `dsymutil` isn't run + for dsym in shallow_find_files(cwd(), |path| has_extension(path, "dSYM")) { + rfs::remove_file(dsym); + } + rustc().input("foo.rs").arg("-Cdebuginfo=2").arg("-Csplit-debuginfo=unpacked").run(); + check_extension_exists("o"); + check_extension_not_exists("dSYM"); + } else { + // PACKED + + // - Debuginfo in `.o` files + // - `.o` deleted + // - `.dwo` never created + // - `.dwp` never created + unstable_rustc().input("foo.rs").arg("-Cdebuginfo=2").arg("-Csplit-debuginfo=off").run(); + check_extension_not_exists("dwp"); + check_extension_not_exists("dwo"); + rustc().input("foo.rs").arg("-Cdebuginfo=2").run(); + check_extension_not_exists("dwp"); + check_extension_not_exists("dwo"); + + let split_dwarf_types = [SplitDwarf::Split, SplitDwarf::Single]; + + for dwarf_type in split_dwarf_types { + // SPLIT + // - Debuginfo in `.dwo` files + // - `.o` deleted + // - `.dwo` deleted + // - `.dwp` present + + // SINGLE + // - Debuginfo in `.o` files + // - `.o` deleted + // - `.dwo` never created + // - `.dwp` present + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Packed, + split_dwarf: dwarf_type, + has_o: false, + has_dwo: false, + dwp: Some("foo"), + output: Some(bin_name("foo")), + remap_scope: None, + }); + } + + for dwarf_type in split_dwarf_types { + // SPLIT + // - rmeta file added to rlib, no object files are generated and thus no debuginfo is + // generated + // - `.o` never created + // - `.dwo` never created + // - `.dwp` never created + + // SINGLE + // - rmeta file added to rlib, no object files are generated and thus no debuginfo is + // generated + // - `.o` never created + // - `.dwo` never created + // - `.dwp` never created + run_test(DebugInfoTest { + input: "lto.rs", + extra_flag: Some(ExtraFlag::LinkerPluginLto), + crate_type: Some(CrateType::Rlib), + debug_info: DebugInfo::Packed, + split_dwarf: dwarf_type, + has_o: false, + has_dwo: false, + dwp: None, + output: Some(rust_lib_name("lto")), + remap_scope: None, + }); + } + + for dwarf_type in split_dwarf_types { + // SPLIT + // - Debuginfo in `.dwo` files + // - `.o` and binary refer to remapped `.dwo` paths which do not exist + // - `.o` deleted + // - `.dwo` deleted + // - `.dwp` present + + // SINGLE + // - Debuginfo in `.o` files + // - `.o` and binary refer to remapped `.o` paths which do not exist + // - `.o` deleted + // - `.dwo` never created + // - `.dwp` present + + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Packed, + split_dwarf: dwarf_type, + has_o: false, + has_dwo: false, + dwp: Some("foo"), + output: Some(bin_name("foo")), + remap_scope: Some(None), + }); + } + + // - Debuginfo in `.o` files + // - `.o` and binary refer to remapped `.o` paths which do not exist + // - `.o` deleted + // - `.dwo` never created + // - `.dwp` present + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Packed, + split_dwarf: SplitDwarf::Single, + has_o: false, + has_dwo: false, + dwp: Some("foo"), + output: Some(bin_name("foo")), + remap_scope: Some(Some(Scope::Debug)), + }); + + // - Debuginfo in `.o` files + // - `.o` and binary refer to remapped `.o` paths which do not exist + // - `.o` deleted + // - `.dwo` never created + // - `.dwp` present + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Packed, + split_dwarf: SplitDwarf::Single, + has_o: false, + has_dwo: false, + dwp: Some("foo"), + output: Some(bin_name("foo")), + remap_scope: Some(Some(Scope::Macro)), + }); + + for dwarf_type in split_dwarf_types { + // SPLIT + // - Debuginfo in `.dwo` files + // - (bar) `.rlib` file created, contains `.dwo` + // - (bar) `.o` deleted + // - (bar) `.dwo` deleted + // - (bar) `.dwp` never created + // - (main) `.o` deleted + // - (main) `.dwo` deleted + // - (main) `.dwp` present + + // SINGLE + // - Debuginfo in `.o` files + // - (bar) `.rlib` file created, contains `.o` + // - (bar) `.o` deleted + // - (bar) `.dwo` never created + // - (bar) `.dwp` never created + // - (main) `.o` deleted + // - (main) `.dwo` never created + // - (main) `.dwp` present + + run_test(DebugInfoTest { + input: "bar.rs", + extra_flag: None, + crate_type: Some(CrateType::Lib), + debug_info: DebugInfo::Packed, + split_dwarf: dwarf_type, + has_o: false, + has_dwo: false, + dwp: None, + output: None, + remap_scope: None, + }); + run_test(DebugInfoTest { + input: "main.rs", + extra_flag: Some(ExtraFlag::ExternBar), + crate_type: None, + debug_info: DebugInfo::Packed, + split_dwarf: dwarf_type, + has_o: false, + has_dwo: false, + dwp: Some("main"), + output: Some(bin_name("main")), + remap_scope: None, + }); + } + + // UNPACKED + + // - Debuginfo in `.dwo` files + // - `.o` deleted + // - `.dwo` present + // - `.dwp` never created + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Split, + has_o: false, + has_dwo: true, + dwp: None, + output: Some(bin_name("foo")), + remap_scope: None, + }); + + // - Debuginfo in `.o` files + // - `.o` present + // - `.dwo` never created + // - `.dwp` never created + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Single, + has_o: true, + has_dwo: false, + dwp: None, + output: Some(bin_name("foo")), + remap_scope: None, + }); + + for dwarf_type in split_dwarf_types { + // SPLIT + // - rmeta file added to rlib, no object files are generated and thus no debuginfo + // is generated + // - `.o` present (bitcode) + // - `.dwo` never created + // - `.dwp` never created + + // SINGLE + // - rmeta file added to rlib, no object files are generated and thus no debuginfo + // is generated + // - `.o` present (bitcode) + // - `.dwo` never created + // - `.dwp` never created + + run_test(DebugInfoTest { + input: "lto.rs", + extra_flag: Some(ExtraFlag::LinkerPluginLto), + crate_type: Some(CrateType::Rlib), + debug_info: DebugInfo::Unpacked, + split_dwarf: dwarf_type, + has_o: true, + has_dwo: false, + dwp: None, + output: Some(rust_lib_name("lto")), + remap_scope: None, + }); + } + + // - Debuginfo in `.dwo` files + // - `.o` and binary refer to remapped `.dwo` paths which do not exist + // - `.o` deleted + // - `.dwo` present + // - `.dwp` never created + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Split, + has_o: false, + has_dwo: true, + dwp: None, + output: Some(bin_name("foo")), + remap_scope: Some(None), + }); + + // - Debuginfo in `.o` files + // - `.o` and binary refer to remapped `.o` paths which do not exist + // - `.o` present + // - `.dwo` never created + // - `.dwp` never created + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Single, + has_o: true, + has_dwo: false, + dwp: None, + output: Some(bin_name("foo")), + remap_scope: Some(None), + }); + + // - Debuginfo in `.o` files + // - `.o` and binary refer to remapped `.o` paths which do not exist + // - `.o` present + // - `.dwo` never created + // - `.dwp` never created + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Single, + has_o: true, + has_dwo: false, + dwp: None, + output: Some(bin_name("foo")), + remap_scope: Some(Some(Scope::Debug)), + }); + + // - Debuginfo in `.o` files + // - `.o` and binary refer to remapped `.o` paths which do not exist + // - `.o` present + // - `.dwo` never created + // - `.dwp` never created + run_test(DebugInfoTest { + input: "foo.rs", + extra_flag: None, + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Single, + has_o: true, + has_dwo: false, + dwp: None, + output: Some(bin_name("foo")), + remap_scope: Some(Some(Scope::Macro)), + }); + + // - Debuginfo in `.dwo` files + // - (bar) `.rlib` file created, contains `.dwo` + // - (bar) `.o` deleted + // - (bar) `.dwo` present + // - (bar) `.dwp` never created + // - (main) `.o` deleted + // - (main) `.dwo` present + // - (main) `.dwp` never created + run_test(DebugInfoTest { + input: "bar.rs", + extra_flag: None, + crate_type: Some(CrateType::Lib), + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Split, + has_o: false, + has_dwo: true, + dwp: None, + output: None, + remap_scope: None, + }); + run_test(DebugInfoTest { + input: "main.rs", + extra_flag: Some(ExtraFlag::ExternBar), + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Split, + has_o: false, + has_dwo: true, + dwp: None, + output: Some(bin_name("main")), + remap_scope: None, + }); + + // - Debuginfo in `.o` files + // - (bar) `.rlib` file created, contains `.o` + // - (bar) `.o` present + // - (bar) `.dwo` never created + // - (bar) `.dwp` never created + // - (main) `.o` present + // - (main) `.dwo` never created + // - (main) `.dwp` never created + run_test(DebugInfoTest { + input: "bar.rs", + extra_flag: None, + crate_type: Some(CrateType::Lib), + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Single, + has_o: true, + has_dwo: false, + dwp: None, + output: None, + remap_scope: None, + }); + run_test(DebugInfoTest { + input: "main.rs", + extra_flag: Some(ExtraFlag::ExternBar), + crate_type: None, + debug_info: DebugInfo::Unpacked, + split_dwarf: SplitDwarf::Single, + has_o: true, + has_dwo: false, + dwp: None, + output: Some(bin_name("main")), + remap_scope: None, + }); + } +} + +#[track_caller] +fn run_test(params: DebugInfoTest) { + let mut compiler = unstable_rustc(); + compiler.input(params.input).arg("-Cdebuginfo=2"); + match params.debug_info { + DebugInfo::Packed => compiler.arg("-Csplit-debuginfo=packed"), + DebugInfo::Unpacked => compiler.arg("-Csplit-debuginfo=unpacked"), + }; + match params.split_dwarf { + SplitDwarf::Split => compiler.arg("-Zsplit-dwarf-kind=split"), + SplitDwarf::Single => compiler.arg("-Zsplit-dwarf-kind=single"), + }; + if let Some(crate_type) = params.crate_type { + match crate_type { + CrateType::Rlib => compiler.crate_type("rlib"), + CrateType::Lib => compiler.crate_type("lib"), + }; + }; + + if let Some(extra_flag) = params.extra_flag { + match extra_flag { + ExtraFlag::LinkerPluginLto => compiler.arg("-Clinker-plugin-lto"), + ExtraFlag::ExternBar => compiler.extern_("bar", rust_lib_name("bar")), + }; + }; + + if let Some(remap) = params.remap_scope { + compiler.remap_path_prefix(cwd(), "/a"); + if let Some(scope) = remap { + match scope { + Scope::Debug => compiler.arg("-Zremap-path-scope=debuginfo"), + Scope::Macro => compiler.arg("-Zremap-path-scope=macro"), + }; + }; + } + compiler.run(); + if let Some(remap) = params.remap_scope { + let mut objdump = llvm_dwarfdump(); + let out = objdump.arg("--debug-info").input("foo").run(); + out.assert_stdout_contains("DW_AT_GNU_dwo_name"); + if let Some(scope) = remap { + match scope { + Scope::Debug => out.assert_stdout_not_contains(cwd().display().to_string()), + Scope::Macro => out.assert_stdout_contains(cwd().display().to_string()), + }; + } else { + out.assert_stdout_not_contains(cwd().display().to_string()); + }; + } + if params.has_o { + for object in shallow_find_files(cwd(), |path| has_extension(path, "o")) { + rfs::remove_file(object); + } + } else { + check_extension_not_exists("o"); + } + if params.has_dwo { + for dwo in shallow_find_files(cwd(), |path| has_extension(path, "dwo")) { + rfs::remove_file(dwo); + } + } else { + check_extension_not_exists("dwo"); + } + if let Some(name) = params.dwp { + rfs::remove_file(&format!("{name}.dwp")); + } else { + check_extension_not_exists("dwp"); + } + if let Some(output) = params.output { + rfs::remove_file(output); + } +} + +struct DebugInfoTest { + input: &'static str, + extra_flag: Option, + crate_type: Option, + debug_info: DebugInfo, + split_dwarf: SplitDwarf, + has_o: bool, + has_dwo: bool, + dwp: Option<&'static str>, + output: Option, + remap_scope: Option>, +} + +enum CrateType { + Lib, + Rlib, +} + +enum ExtraFlag { + LinkerPluginLto, + ExternBar, +} + +#[derive(Clone, Copy)] +enum Scope { + Debug, + Macro, +} + +enum DebugInfo { + Packed, + Unpacked, +} + +#[derive(Clone, Copy)] +enum SplitDwarf { + Split, + Single, +} + +// Some non-Windows, non-Darwin platforms are not stable, and some are. +fn unstable_rustc() -> Rustc { + let mut compiler = rustc(); + if !target().contains("linux") { + compiler.arg("-Zunstable-options"); + } + compiler +} + +#[track_caller] +fn check_extension_exists(ext: &str) { + if shallow_find_files(cwd(), |path| has_extension(path, ext)).is_empty() { + eprintln!("{:#?}", rfs::shallow_find_dir_entries(cwd())); + panic!("a file with the requested extension {ext} was not found"); + } +} + +#[track_caller] +fn check_extension_not_exists(ext: &str) { + if !shallow_find_files(cwd(), |path| has_extension(path, ext)).is_empty() { + eprintln!("{:#?}", rfs::shallow_find_dir_entries(cwd())); + panic!("a file with the requested extension {ext} was unexpectedly found"); + } +}