|
| 1 | +//@ ignore-windows |
| 2 | +// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums. |
| 3 | + |
| 4 | +extern crate run_make_support; |
| 5 | + |
| 6 | +use gimli::{AttributeValue, Dwarf, EndianRcSlice, Reader, RunTimeEndian}; |
| 7 | +use object::{Object, ObjectSection}; |
| 8 | +use run_make_support::{gimli, object, rustc, tmp_dir}; |
| 9 | +use std::borrow::Cow; |
| 10 | +use std::collections::HashMap; |
| 11 | +use std::rc::Rc; |
| 12 | + |
| 13 | +fn main() { |
| 14 | + let output = tmp_dir().join("repr128"); |
| 15 | + dbg!(&output); |
| 16 | + rustc().input("main.rs").arg("-o").arg(&output).arg("-Cdebuginfo=2").run(); |
| 17 | + let output = std::fs::read(output).unwrap(); |
| 18 | + let obj = object::File::parse(output.as_slice()).unwrap(); |
| 19 | + let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big }; |
| 20 | + let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> { |
| 21 | + let data = obj.section_by_name(section.name()).map(|s| s.uncompressed_data().unwrap()); |
| 22 | + Ok(EndianRcSlice::new(Rc::from(data.unwrap_or_default().as_ref()), endian)) |
| 23 | + }) |
| 24 | + .unwrap(); |
| 25 | + let mut iter = dwarf.units(); |
| 26 | + let mut still_to_find = HashMap::from([ |
| 27 | + ("U128A", 0_u128), |
| 28 | + ("U128B", 1_u128), |
| 29 | + ("U128C", u64::MAX as u128 + 1), |
| 30 | + ("U128D", u128::MAX), |
| 31 | + ("I128A", 0_i128 as u128), |
| 32 | + ("I128B", (-1_i128) as u128), |
| 33 | + ("I128C", i128::MIN as u128), |
| 34 | + ("I128D", i128::MAX as u128), |
| 35 | + ]); |
| 36 | + while let Some(header) = iter.next().unwrap() { |
| 37 | + let unit = dwarf.unit(header).unwrap(); |
| 38 | + let mut cursor = unit.entries(); |
| 39 | + while let Some((_, entry)) = cursor.next_dfs().unwrap() { |
| 40 | + if entry.tag() == gimli::constants::DW_TAG_enumerator { |
| 41 | + let name = dwarf |
| 42 | + .attr_string( |
| 43 | + &unit, |
| 44 | + entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(), |
| 45 | + ) |
| 46 | + .unwrap(); |
| 47 | + let name = name.to_string().unwrap(); |
| 48 | + if let Some(expected) = still_to_find.remove(name.as_ref()) { |
| 49 | + match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value() |
| 50 | + { |
| 51 | + AttributeValue::Block(value) => { |
| 52 | + assert_eq!( |
| 53 | + value.to_slice().unwrap(), |
| 54 | + expected.to_le_bytes().as_slice(), |
| 55 | + "{name}" |
| 56 | + ); |
| 57 | + } |
| 58 | + value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"), |
| 59 | + } |
| 60 | + } |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | + if !still_to_find.is_empty() { |
| 65 | + panic!("Didn't find debug entries for {still_to_find:?}"); |
| 66 | + } |
| 67 | +} |
0 commit comments