diff --git a/src/til/array.rs b/src/til/array.rs index 52e38f7..1383c24 100644 --- a/src/til/array.rs +++ b/src/til/array.rs @@ -1,11 +1,14 @@ -use std::num::NonZeroU16; +use std::num::{NonZeroU16, NonZeroU8}; + +use anyhow::ensure; use crate::ida_reader::IdaGenericBufUnpack; use crate::til::section::TILSectionHeader; -use crate::til::{Type, TypeRaw}; +use crate::til::{Type, TypeAttribute, TypeRaw}; #[derive(Clone, Debug)] pub struct Array { + pub align: Option, pub base: u8, pub nelem: Option, pub elem_type: Box, @@ -17,6 +20,7 @@ impl Array { fields: &mut impl Iterator>>, ) -> anyhow::Result { Ok(Self { + align: value.align, base: value.base, nelem: value.nelem, elem_type: Type::new(til, *value.elem_type, fields).map(Box::new)?, @@ -26,6 +30,7 @@ impl Array { #[derive(Clone, Debug)] pub(crate) struct ArrayRaw { + pub align: Option, pub base: u8, pub nelem: Option, pub elem_type: Box, @@ -37,6 +42,7 @@ impl ArrayRaw { header: &TILSectionHeader, metadata: u8, ) -> anyhow::Result { + use crate::til::flag::tattr::*; use crate::til::flag::tf_array::*; let (base, nelem) = match metadata { BTMT_NONBASED => { @@ -50,10 +56,25 @@ impl ArrayRaw { } }; // InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x48078e - let _tah = input.read_tah()?; + let align = match input.read_tah()? { + None => None, + Some(TypeAttribute { tattr, extended }) => { + let align = (tattr & MAX_DECL_ALIGN) as u8; + ensure!( + tattr & !MAX_DECL_ALIGN == 0, + "unknown TypeAttribute {tattr:x}" + ); + ensure!( + extended.is_none(), + "unknown TypeAttribute ext {extended:x?}" + ); + NonZeroU8::new(align) + } + }; let elem_type = TypeRaw::read(&mut *input, header)?; Ok(ArrayRaw { base, + align, nelem: NonZeroU16::new(nelem), elem_type: Box::new(elem_type), }) diff --git a/src/til/enum.rs b/src/til/enum.rs index 809b09a..6f562ce 100644 --- a/src/til/enum.rs +++ b/src/til/enum.rs @@ -69,13 +69,13 @@ impl EnumRaw { return Ok(TypeVariantRaw::EnumRef(ref_type)); }; - let taenum_bits = input.read_tah()?; - let (is_64, is_signed, is_unsigned) = match taenum_bits { + let (is_64, is_signed, is_unsigned) = match input.read_tah()? { None => (false, false, false), Some(TypeAttribute { tattr, extended: None, }) => { + // TODO enum have an align field (MAX_DECL_ALIGN) in tattr? let is_64 = tattr & TAENUM_64BIT != 0; let is_signed = tattr & TAENUM_SIGNED != 0; let is_unsigned = tattr & TAENUM_UNSIGNED != 0; diff --git a/src/til/pointer.rs b/src/til/pointer.rs index db45cee..aecc3bf 100644 --- a/src/til/pointer.rs +++ b/src/til/pointer.rs @@ -89,6 +89,7 @@ impl PointerRaw { header: &TILSectionHeader, metadata: u8, ) -> Result { + use crate::til::flag::tattr::*; use crate::til::flag::tattr_ptr::*; use crate::til::flag::tf_ptr::*; // InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x478d67 @@ -103,12 +104,11 @@ impl PointerRaw { }; // InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x4804fa // InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x459b7e - let tah = input.read_tah()?; - let (_ta_lower, is_shifted, ptr_type_raw) = match tah { + let (_ta_lower, is_shifted, ptr_type_raw) = match input.read_tah()? { None => (0, false, 0), Some(TypeAttribute { tattr, extended }) => { // all bits of tattr are consumed - let ta_lower = (tattr & 0xf) as u8; + let ta_lower = (tattr & MAX_DECL_ALIGN) as u8; let is_shifted = tattr & TAPTR_SHIFTED != 0; let ptr_type = tattr & TAPTR_RESTRICT; if let Some(_extended) = extended {