diff --git a/Cargo.lock b/Cargo.lock index 656e9d40d30..ca69536855e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3318,6 +3318,7 @@ dependencies = [ name = "run_make_support" version = "0.0.0" dependencies = [ + "gimli", "object 0.34.0", "regex", "similar", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index da51b33a9d6..0a861d62c37 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3825,6 +3825,7 @@ fn run_rmake_v2_test(&self) { .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy())) .arg("--extern") .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy())) + .arg("--edition=2021") .arg(&self.testpaths.file.join("rmake.rs")) .env("TARGET", &self.config.target) .env("PYTHON", &self.config.python) diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 61a24c97e77..cf4ae4b16cd 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -8,3 +8,4 @@ object = "0.34.0" similar = "2.5.0" wasmparser = "0.118.2" regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace +gimli = "0.28.1" diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 76e8838d27c..a874c1313b5 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -15,6 +15,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Output}; +pub use gimli; pub use object; pub use regex; pub use wasmparser; diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a2179b895b3..69c6dda4b19 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -235,7 +235,6 @@ run-make/relocation-model/Makefile run-make/relro-levels/Makefile run-make/remap-path-prefix-dwarf/Makefile run-make/remap-path-prefix/Makefile -run-make/repr128-dwarf/Makefile run-make/reproducible-build-2/Makefile run-make/reproducible-build/Makefile run-make/resolve-rename/Makefile diff --git a/tests/run-make/repr128-dwarf/Makefile b/tests/run-make/repr128-dwarf/Makefile deleted file mode 100644 index 3f933042724..00000000000 --- a/tests/run-make/repr128-dwarf/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# ignore-windows -# This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit -# enums. - -include ../tools.mk - -all: - $(RUSTC) -Cdebuginfo=2 lib.rs -o $(TMPDIR)/repr128.rlib - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 7f )" diff --git a/tests/run-make/repr128-dwarf/lib.rs b/tests/run-make/repr128-dwarf/main.rs similarity index 89% rename from tests/run-make/repr128-dwarf/lib.rs rename to tests/run-make/repr128-dwarf/main.rs index 63675441d4b..57923a8386d 100644 --- a/tests/run-make/repr128-dwarf/lib.rs +++ b/tests/run-make/repr128-dwarf/main.rs @@ -1,4 +1,3 @@ -#![crate_type = "lib"] #![feature(repr128)] // Use .to_le() to ensure that the bytes are in the same order on both little- and big-endian @@ -21,3 +20,7 @@ pub enum I128Enum { } pub fn f(_: U128Enum, _: I128Enum) {} + +fn main() { + f(U128Enum::U128A, I128Enum::I128A); +} diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs new file mode 100644 index 00000000000..f6375344f8f --- /dev/null +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -0,0 +1,75 @@ +//@ ignore-windows +// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums. + +extern crate run_make_support; + +use gimli::{AttributeValue, Dwarf, EndianRcSlice, Reader, RunTimeEndian}; +use object::{Object, ObjectSection}; +use run_make_support::{gimli, object, rustc, tmp_dir}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::rc::Rc; + +fn main() { + let output = tmp_dir().join("repr128"); + rustc().input("main.rs").arg("-o").arg(&output).arg("-Cdebuginfo=2").run(); + // Mach-O uses packed debug info + let dsym_location = output + .with_extension("dSYM") + .join("Contents") + .join("Resources") + .join("DWARF") + .join("repr128"); + let output = + std::fs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output }) + .unwrap(); + let obj = object::File::parse(output.as_slice()).unwrap(); + let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big }; + let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> { + let data = obj.section_by_name(section.name()).map(|s| s.uncompressed_data().unwrap()); + Ok(EndianRcSlice::new(Rc::from(data.unwrap_or_default().as_ref()), endian)) + }) + .unwrap(); + let mut iter = dwarf.units(); + let mut still_to_find = HashMap::from([ + ("U128A", 0_u128), + ("U128B", 1_u128), + ("U128C", u64::MAX as u128 + 1), + ("U128D", u128::MAX), + ("I128A", 0_i128 as u128), + ("I128B", (-1_i128) as u128), + ("I128C", i128::MIN as u128), + ("I128D", i128::MAX as u128), + ]); + while let Some(header) = iter.next().unwrap() { + let unit = dwarf.unit(header).unwrap(); + let mut cursor = unit.entries(); + while let Some((_, entry)) = cursor.next_dfs().unwrap() { + if entry.tag() == gimli::constants::DW_TAG_enumerator { + let name = dwarf + .attr_string( + &unit, + entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(), + ) + .unwrap(); + let name = name.to_string().unwrap(); + if let Some(expected) = still_to_find.remove(name.as_ref()) { + match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value() + { + AttributeValue::Block(value) => { + assert_eq!( + value.to_slice().unwrap(), + expected.to_le_bytes().as_slice(), + "{name}" + ); + } + value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"), + } + } + } + } + } + if !still_to_find.is_empty() { + panic!("Didn't find debug entries for {still_to_find:?}"); + } +}