rewrite remap-path-prefix-dwarf to rmake

This commit is contained in:
Oneirical 2024-07-30 16:27:29 -04:00
parent e08b80c0fb
commit fe52572a4a
5 changed files with 235 additions and 115 deletions

View File

@ -48,6 +48,12 @@ pub fn llvm_bcanalyzer() -> LlvmBcanalyzer {
LlvmBcanalyzer::new() LlvmBcanalyzer::new()
} }
/// Construct a new `llvm-dwarfdump` invocation. This assumes that `llvm-dwarfdump` is available
/// at `$LLVM_BIN_DIR/llvm-dwarfdump`.
pub fn llvm_dwarfdump() -> LlvmDwarfdump {
LlvmDwarfdump::new()
}
/// A `llvm-readobj` invocation builder. /// A `llvm-readobj` invocation builder.
#[derive(Debug)] #[derive(Debug)]
#[must_use] #[must_use]
@ -97,6 +103,13 @@ pub struct LlvmBcanalyzer {
cmd: Command, cmd: Command,
} }
/// A `llvm-dwarfdump` invocation builder.
#[derive(Debug)]
#[must_use]
pub struct LlvmDwarfdump {
cmd: Command,
}
crate::macros::impl_common_helpers!(LlvmReadobj); crate::macros::impl_common_helpers!(LlvmReadobj);
crate::macros::impl_common_helpers!(LlvmProfdata); crate::macros::impl_common_helpers!(LlvmProfdata);
crate::macros::impl_common_helpers!(LlvmFilecheck); crate::macros::impl_common_helpers!(LlvmFilecheck);
@ -104,6 +117,7 @@ pub struct LlvmBcanalyzer {
crate::macros::impl_common_helpers!(LlvmAr); crate::macros::impl_common_helpers!(LlvmAr);
crate::macros::impl_common_helpers!(LlvmNm); crate::macros::impl_common_helpers!(LlvmNm);
crate::macros::impl_common_helpers!(LlvmBcanalyzer); crate::macros::impl_common_helpers!(LlvmBcanalyzer);
crate::macros::impl_common_helpers!(LlvmDwarfdump);
/// Generate the path to the bin directory of LLVM. /// Generate the path to the bin directory of LLVM.
#[must_use] #[must_use]
@ -317,3 +331,19 @@ pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self self
} }
} }
impl LlvmDwarfdump {
/// Construct a new `llvm-dwarfdump` invocation. This assumes that `llvm-dwarfdump` is available
/// at `$LLVM_BIN_DIR/llvm-dwarfdump`.
pub fn new() -> Self {
let llvm_dwarfdump = llvm_bin_dir().join("llvm-dwarfdump");
let cmd = Command::new(llvm_dwarfdump);
Self { cmd }
}
/// Provide an input file.
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg(path.as_ref());
self
}
}

View File

@ -49,8 +49,9 @@ pub mod rfs {
pub use clang::{clang, Clang}; pub use clang::{clang, Clang};
pub use htmldocck::htmldocck; pub use htmldocck::htmldocck;
pub use llvm::{ pub use llvm::{
llvm_ar, llvm_bcanalyzer, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata, llvm_readobj, llvm_ar, llvm_bcanalyzer, llvm_dwarfdump, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata,
LlvmAr, LlvmBcanalyzer, LlvmFilecheck, LlvmNm, LlvmObjdump, LlvmProfdata, LlvmReadobj, llvm_readobj, LlvmAr, LlvmBcanalyzer, LlvmDwarfdump, LlvmFilecheck, LlvmNm, LlvmObjdump,
LlvmProfdata, LlvmReadobj,
}; };
pub use python::python_command; pub use python::python_command;
pub use rustc::{aux_build, bare_rustc, rustc, Rustc}; pub use rustc::{aux_build, bare_rustc, rustc, Rustc};

View File

@ -16,7 +16,6 @@ run-make/macos-deployment-target/Makefile
run-make/min-global-align/Makefile run-make/min-global-align/Makefile
run-make/native-link-modifier-bundle/Makefile run-make/native-link-modifier-bundle/Makefile
run-make/no-alloc-shim/Makefile run-make/no-alloc-shim/Makefile
run-make/remap-path-prefix-dwarf/Makefile
run-make/reproducible-build/Makefile run-make/reproducible-build/Makefile
run-make/rlib-format-packed-bundled-libs/Makefile run-make/rlib-format-packed-bundled-libs/Makefile
run-make/split-debuginfo/Makefile run-make/split-debuginfo/Makefile

View File

@ -1,112 +0,0 @@
# This test makes sure that --remap-path-prefix has the expected effects on paths in debuginfo.
# It tests several cases, each of them has a detailed description attached to it.
# ignore-windows
include ../tools.mk
SRC_DIR := $(abspath .)
SRC_DIR_PARENT := $(abspath ..)
ifeq ($(UNAME),Darwin)
DEBUGINFOOPTS := -Csplit-debuginfo=off
else
DEBUGINFOOPTS :=
endif
all: \
abs_input_outside_working_dir \
rel_input_remap_working_dir \
rel_input_remap_working_dir_scope \
rel_input_remap_working_dir_parent \
rel_input_remap_working_dir_child \
rel_input_remap_working_dir_diagnostics \
abs_input_inside_working_dir \
abs_input_inside_working_dir_scope \
abs_input_outside_working_dir
# The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path *is* within
# the working directory of the compiler. We are remapping the path that contains `src`.
abs_input_inside_working_dir:
# We explicitly switch to a directory that *is* a prefix of the directory our
# source code is contained in.
cd $(SRC_DIR) && $(RUSTC) $(SRC_DIR)/src/quux.rs -o "$(TMPDIR)/abs_input_inside_working_dir.rlib" -Cdebuginfo=2 --remap-path-prefix $(SRC_DIR)=REMAPPED
# We expect the path to the main source file to be remapped.
"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir.rlib | $(CGREP) "REMAPPED/src/quux.rs"
# No weird duplication of remapped components (see #78479)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir.rlib | $(CGREP) -v "REMAPPED/REMAPPED"
# The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path *is* within
# the working directory of the compiler. We are remapping the path that contains `src`.
abs_input_inside_working_dir_scope:
# We explicitly switch to a directory that *is* a prefix of the directory our
# source code is contained in.
cd $(SRC_DIR) && $(RUSTC) $(SRC_DIR)/src/quux.rs -o "$(TMPDIR)/abs_input_inside_working_dir_scope.rlib" -Cdebuginfo=2 --remap-path-prefix $(SRC_DIR)=REMAPPED -Zremap-path-scope=object $(DEBUGINFOOPTS)
# We expect the path to the main source file to be remapped.
"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir_scope.rlib | $(CGREP) "REMAPPED/src/quux.rs"
# No weird duplication of remapped components (see #78479)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir_scope.rlib | $(CGREP) -v "REMAPPED/REMAPPED"
# The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path is *not* within
# the working directory of the compiler. We are remapping both the path that contains `src` and
# the working directory to the same thing. This setup corresponds to a workaround that is needed
# when trying to remap everything to something that looks like a local path.
# Relative paths are interpreted as relative to the compiler's working directory (e.g. in
# debuginfo). If we also remap the working directory, the compiler strip it from other paths so
# that the final outcome is the desired one again.
abs_input_outside_working_dir:
# We explicitly switch to a directory that is *not* a prefix of the directory our
# source code is contained in.
cd $(TMPDIR) && $(RUSTC) $(SRC_DIR)/src/quux.rs -o "$(TMPDIR)/abs_input_outside_working_dir.rlib" -Cdebuginfo=2 --remap-path-prefix $(SRC_DIR)=REMAPPED --remap-path-prefix $(TMPDIR)=REMAPPED
"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_outside_working_dir.rlib | $(CGREP) "REMAPPED/src/quux.rs"
# No weird duplication of remapped components (see #78479)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_outside_working_dir.rlib | $(CGREP) -v "REMAPPED/REMAPPED"
# The compiler is called with a *RELATIVE PATH* as input. We are remapping the working directory of
# the compiler, which naturally is an implicit prefix of our relative input path. Debuginfo will
# expand the relative path to an absolute path and we expect the working directory to be remapped
# in that expansion.
rel_input_remap_working_dir:
cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)=REMAPPED"
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir.rlib" | $(CGREP) "REMAPPED/src/quux.rs"
# No weird duplication of remapped components (see #78479)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
# The compiler is called with a *RELATIVE PATH* as input. We are remapping the working directory of
# the compiler, which naturally is an implicit prefix of our relative input path. Debuginfo will
# expand the relative path to an absolute path and we expect the working directory to be remapped
# in that expansion.
rel_input_remap_working_dir_scope:
cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)=REMAPPED" -Zremap-path-scope=object $(DEBUGINFOOPTS)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) "REMAPPED/src/quux.rs"
# No weird duplication of remapped components (see #78479)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
rel_input_remap_working_dir_diagnostics:
cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)=REMAPPED" -Zremap-path-scope=diagnostics $(DEBUGINFOOPTS)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) -v "REMAPPED/src/quux.rs"
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
# The compiler is called with a *RELATIVE PATH* as input. We are remapping a *SUB-DIRECTORY* of the
# compiler's working directory. This test makes sure that that directory is remapped even though it
# won't actually show up in this form in the compiler's SourceMap and instead is only constructed
# on demand during debuginfo generation.
rel_input_remap_working_dir_child:
cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)/src=REMAPPED"
# We expect `src/quux.rs` to have been remapped to `REMAPPED/quux.rs`.
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" | $(CGREP) "REMAPPED/quux.rs"
# We don't want to find the path that we just remapped anywhere in the DWARF
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" | $(CGREP) -v "$(SRC_DIR)/src"
# No weird duplication of remapped components (see #78479)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
# The compiler is called with a *RELATIVE PATH* as input. We are remapping a *PARENT DIRECTORY* of
# the compiler's working directory.
rel_input_remap_working_dir_parent:
cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR_PARENT)=REMAPPED"
# We expect `src/quux.rs` to have been remapped to `REMAPPED/remap-path-prefix-dwarf/src/quux.rs`.
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" | $(CGREP) "REMAPPED/remap-path-prefix-dwarf/src/quux.rs"
# We don't want to find the path that we just remapped anywhere in the DWARF
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" | $(CGREP) -v "$(SRC_DIR_PARENT)"
# No weird duplication of remapped components (see #78479)
"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"

View File

@ -0,0 +1,202 @@
// This test makes sure that --remap-path-prefix has the expected effects on paths in debuginfo.
// We explicitly switch to a directory that *is* a prefix of the directory our
// source code is contained in.
// It tests several cases, each of them has a detailed description attached to it.
// See https://github.com/rust-lang/rust/pull/96867
//@ ignore-windows
// Reason: the remap path prefix is not printed in the dwarf dump.
use run_make_support::{cwd, is_darwin, llvm_dwarfdump, rust_lib_name, rustc};
fn main() {
// The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path *is* within
// the working directory of the compiler. We are remapping the path that contains `src`.
check_dwarf(DwarfTest {
lib_name: "abs_input_inside_working_dir",
input_path: PathType::Absolute,
scope: None,
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
dwarf_test: DwarfDump::ContainsSrcPath,
});
check_dwarf(DwarfTest {
lib_name: "abs_input_inside_working_dir_scope",
input_path: PathType::Absolute,
scope: Some(ScopeType::Object),
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
dwarf_test: DwarfDump::ContainsSrcPath,
});
// The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path is *not*
// within the working directory of the compiler. We are remapping both the path that contains
// `src` and the working directory to the same thing. This setup corresponds to a workaround
// that is needed when trying to remap everything to something that looks like a local
// path. Relative paths are interpreted as relative to the compiler's working directory (e.g.
// in debuginfo). If we also remap the working directory, the compiler strip it from other
// paths so that the final outcome is the desired one again.
check_dwarf(DwarfTest {
lib_name: "abs_input_outside_working_dir",
input_path: PathType::Absolute,
scope: None,
remap_path_prefix: PrefixType::Dual((
format!("{}=REMAPPED", cwd().display()),
"rmake_out=REMAPPED".to_owned(),
)),
dwarf_test: DwarfDump::ContainsSrcPath,
});
// The compiler is called with a *RELATIVE PATH* as input. We are remapping the working
// directory of the compiler, which naturally is an implicit prefix of our relative input path.
// Debuginfo will expand the relative path to an absolute path and we expect the working
// directory to be remapped in that expansion.
check_dwarf(DwarfTest {
lib_name: "rel_input_remap_working_dir",
input_path: PathType::Relative,
scope: None,
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
dwarf_test: DwarfDump::ContainsSrcPath,
});
check_dwarf(DwarfTest {
lib_name: "rel_input_remap_working_dir_scope",
input_path: PathType::Relative,
scope: Some(ScopeType::Object),
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
dwarf_test: DwarfDump::ContainsSrcPath,
});
check_dwarf(DwarfTest {
lib_name: "rel_input_remap_working_dir_scope",
input_path: PathType::Relative,
scope: Some(ScopeType::Diagnostics),
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
dwarf_test: DwarfDump::AvoidSrcPath,
});
// The compiler is called with a *RELATIVE PATH* as input. We are remapping a *SUB-DIRECTORY*
// of the compiler's working directory. This test makes sure that that directory is remapped
// even though it won't actually show up in this form in the compiler's SourceMap and instead
// is only constructed on demand during debuginfo generation.
check_dwarf(DwarfTest {
lib_name: "rel_input_remap_working_dir_child",
input_path: PathType::Relative,
scope: None,
remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().join("src").display())),
dwarf_test: DwarfDump::ChildTest,
});
// The compiler is called with a *RELATIVE PATH* as input. We are remapping a
// *PARENT DIRECTORY* of the compiler's working directory.
check_dwarf(DwarfTest {
lib_name: "rel_input_remap_working_dir_parent",
input_path: PathType::Relative,
scope: None,
remap_path_prefix: PrefixType::Regular(format!(
"{}=REMAPPED",
cwd().parent().unwrap().display()
)),
dwarf_test: DwarfDump::ParentTest,
});
}
#[track_caller]
fn check_dwarf(test: DwarfTest) {
let mut rustc = rustc();
match test.input_path {
PathType::Absolute => rustc.input(cwd().join("src/quux.rs")),
PathType::Relative => rustc.input("src/quux.rs"),
};
rustc.output(rust_lib_name(test.lib_name));
rustc.arg("-Cdebuginfo=2");
if let Some(scope) = test.scope {
match scope {
ScopeType::Object => rustc.arg("-Zremap-path-scope=object"),
ScopeType::Diagnostics => rustc.arg("-Zremap-path-scope=diagnostics"),
};
if is_darwin() {
rustc.arg("-Csplit-debuginfo=off");
}
}
match test.remap_path_prefix {
PrefixType::Regular(prefix) => {
// We explicitly switch to a directory that *is* a prefix of the directory our
// source code is contained in.
rustc.arg("--remap-path-prefix");
rustc.arg(prefix);
}
PrefixType::Dual((prefix1, prefix2)) => {
// We explicitly switch to a directory that is *not* a prefix of the directory our
// source code is contained in.
rustc.arg("--remap-path-prefix");
rustc.arg(prefix1);
rustc.arg("--remap-path-prefix");
rustc.arg(prefix2);
}
}
rustc.run();
match test.dwarf_test {
DwarfDump::ContainsSrcPath => {
llvm_dwarfdump()
.input(rust_lib_name(test.lib_name))
.run()
// We expect the path to the main source file to be remapped.
.assert_stdout_contains("REMAPPED/src/quux.rs")
// No weird duplication of remapped components (see #78479)
.assert_stdout_not_contains("REMAPPED/REMAPPED");
}
DwarfDump::AvoidSrcPath => {
llvm_dwarfdump()
.input(rust_lib_name(test.lib_name))
.run()
.assert_stdout_not_contains("REMAPPED/src/quux.rs")
.assert_stdout_not_contains("REMAPPED/REMAPPED");
}
DwarfDump::ChildTest => {
llvm_dwarfdump()
.input(rust_lib_name(test.lib_name))
.run()
// We expect `src/quux.rs` to have been remapped to `REMAPPED/quux.rs`.
.assert_stdout_contains("REMAPPED/quux.rs")
// We don't want to find the path that we just remapped anywhere in the DWARF
.assert_stdout_not_contains(cwd().join("src").to_str().unwrap())
// No weird duplication of remapped components (see #78479)
.assert_stdout_not_contains("REMAPPED/REMAPPED");
}
DwarfDump::ParentTest => {
llvm_dwarfdump()
.input(rust_lib_name(test.lib_name))
.run()
// We expect `src/quux.rs` to have been remapped to
// `REMAPPED/remap-path-prefix-dwarf/src/quux.rs`.
.assert_stdout_contains("REMAPPED/rmake_out/src/quux.rs")
// We don't want to find the path that we just remapped anywhere in the DWARF
.assert_stdout_not_contains(cwd().parent().unwrap().to_str().unwrap())
// No weird duplication of remapped components (see #78479)
.assert_stdout_not_contains("REMAPPED/REMAPPED");
}
};
}
struct DwarfTest {
lib_name: &'static str,
input_path: PathType,
scope: Option<ScopeType>,
remap_path_prefix: PrefixType,
dwarf_test: DwarfDump,
}
enum PathType {
Absolute,
Relative,
}
enum ScopeType {
Object,
Diagnostics,
}
enum DwarfDump {
ContainsSrcPath,
AvoidSrcPath,
ChildTest,
ParentTest,
}
enum PrefixType {
Regular(String),
Dual((String, String)),
}