Support some more MetroWerkz DWARF extensions (#22)

* Support FT_MW_int128

* Support OP_MW_FPREG

* Support AT_MW_mangled on local variables

* cargo fmt

---------

Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
Benjamin Moir 2024-01-03 03:33:07 +10:00 committed by GitHub
parent fdf421a5d8
commit dd23fef4f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 2 deletions

View File

@ -86,6 +86,7 @@ pub enum FundType {
LongLong = 0x8008, LongLong = 0x8008,
SignedLongLong = 0x8108, SignedLongLong = 0x8108,
UnsignedLongLong = 0x8208, UnsignedLongLong = 0x8208,
Int128 = 0xa510,
Vec2x32Float = 0xac00, Vec2x32Float = 0xac00,
} }
@ -108,6 +109,7 @@ impl FundType {
| FundType::SignedLongLong | FundType::SignedLongLong
| FundType::UnsignedLongLong | FundType::UnsignedLongLong
| FundType::Vec2x32Float => 8, | FundType::Vec2x32Float => 8,
FundType::Int128 => 16,
FundType::Void => 0, FundType::Void => 0,
FundType::ExtPrecFloat FundType::ExtPrecFloat
| FundType::Complex | FundType::Complex
@ -145,6 +147,7 @@ impl FundType {
FundType::LongLong => "long long", FundType::LongLong => "long long",
FundType::SignedLongLong => "signed long long", FundType::SignedLongLong => "signed long long",
FundType::UnsignedLongLong => "unsigned long long", FundType::UnsignedLongLong => "unsigned long long",
FundType::Int128 => "__int128",
FundType::Vec2x32Float => "__vec2x32float__", FundType::Vec2x32Float => "__vec2x32float__",
}) })
} }
@ -670,6 +673,7 @@ pub struct SubroutineParameter {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SubroutineVariable { pub struct SubroutineVariable {
pub name: Option<String>, pub name: Option<String>,
pub mangled_name: Option<String>,
pub kind: Type, pub kind: Type,
pub location: Option<String>, pub location: Option<String>,
} }
@ -1478,7 +1482,9 @@ pub const fn register_name(reg: u32) -> &'static str {
pub fn process_variable_location(block: &[u8], e: Endian) -> Result<String> { pub fn process_variable_location(block: &[u8], e: Endian) -> Result<String> {
if block.len() == 5 if block.len() == 5
&& (block[0] == LocationOp::Register as u8 || block[0] == LocationOp::BaseRegister as u8) && (block[0] == LocationOp::Register as u8
|| block[0] == LocationOp::BaseRegister as u8
|| block[0] == LocationOp::MwFpReg as u8)
{ {
Ok(register_name(u32::from_bytes(*array_ref!(block, 1, 4), e)).to_string()) Ok(register_name(u32::from_bytes(*array_ref!(block, 1, 4), e)).to_string())
} else if block.len() == 5 && block[0] == LocationOp::Address as u8 { } else if block.len() == 5 && block[0] == LocationOp::Address as u8 {
@ -2143,6 +2149,7 @@ fn process_subroutine_parameter_tag(info: &DwarfInfo, tag: &Tag) -> Result<Subro
fn process_local_variable_tag(info: &DwarfInfo, tag: &Tag) -> Result<SubroutineVariable> { fn process_local_variable_tag(info: &DwarfInfo, tag: &Tag) -> Result<SubroutineVariable> {
ensure!(tag.kind == TagKind::LocalVariable, "{:?} is not a LocalVariable tag", tag.kind); ensure!(tag.kind == TagKind::LocalVariable, "{:?} is not a LocalVariable tag", tag.kind);
let mut mangled_name = None;
let mut name = None; let mut name = None;
let mut kind = None; let mut kind = None;
let mut location = None; let mut location = None;
@ -2150,6 +2157,7 @@ fn process_local_variable_tag(info: &DwarfInfo, tag: &Tag) -> Result<SubroutineV
match (attr.kind, &attr.value) { match (attr.kind, &attr.value) {
(AttributeKind::Sibling, _) => {} (AttributeKind::Sibling, _) => {}
(AttributeKind::Name, AttributeValue::String(s)) => name = Some(s.clone()), (AttributeKind::Name, AttributeValue::String(s)) => name = Some(s.clone()),
(AttributeKind::MwMangled, AttributeValue::String(s)) => mangled_name = Some(s.clone()),
( (
AttributeKind::FundType AttributeKind::FundType
| AttributeKind::ModFundType | AttributeKind::ModFundType
@ -2188,7 +2196,7 @@ fn process_local_variable_tag(info: &DwarfInfo, tag: &Tag) -> Result<SubroutineV
} }
let kind = kind.ok_or_else(|| anyhow!("LocalVariable without type: {:?}", tag))?; let kind = kind.ok_or_else(|| anyhow!("LocalVariable without type: {:?}", tag))?;
Ok(SubroutineVariable { name, kind, location }) Ok(SubroutineVariable { name, mangled_name, kind, location })
} }
fn process_ptr_to_member_tag(info: &DwarfInfo, tag: &Tag) -> Result<PtrToMemberType> { fn process_ptr_to_member_tag(info: &DwarfInfo, tag: &Tag) -> Result<PtrToMemberType> {