2024-04-23 00:41:28 -05:00
|
|
|
//@ ignore-windows
|
|
|
|
// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums.
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
2024-06-06 14:34:34 -05:00
|
|
|
use std::path::PathBuf;
|
2024-04-23 00:41:28 -05:00
|
|
|
use std::rc::Rc;
|
|
|
|
|
2024-06-06 14:34:34 -05:00
|
|
|
use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian};
|
2024-04-23 00:41:28 -05:00
|
|
|
use object::{Object, ObjectSection};
|
2024-07-17 08:31:38 -05:00
|
|
|
use run_make_support::{gimli, object, rfs, rustc};
|
2024-07-28 17:13:50 -05:00
|
|
|
|
2024-04-23 00:41:28 -05:00
|
|
|
fn main() {
|
2024-06-06 14:34:34 -05:00
|
|
|
let output = PathBuf::from("repr128");
|
2024-05-05 09:26:35 -05:00
|
|
|
rustc().input("main.rs").output(&output).arg("-Cdebuginfo=2").run();
|
2024-04-23 00:41:28 -05:00
|
|
|
// Mach-O uses packed debug info
|
|
|
|
let dsym_location = output
|
|
|
|
.with_extension("dSYM")
|
|
|
|
.join("Contents")
|
|
|
|
.join("Resources")
|
|
|
|
.join("DWARF")
|
|
|
|
.join("repr128");
|
|
|
|
let output =
|
2024-07-17 07:42:06 -05:00
|
|
|
rfs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output });
|
2024-04-23 00:41:28 -05:00
|
|
|
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:?}");
|
|
|
|
}
|
|
|
|
}
|