Skip to content

Commit

Permalink
add a tilib tool
Browse files Browse the repository at this point in the history
  • Loading branch information
rbran committed Dec 10, 2024
1 parent ad181b4 commit 81d551e
Show file tree
Hide file tree
Showing 7 changed files with 428 additions and 73 deletions.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ serde = { version = "1.0", features = ["derive"] }
[[bin]]
name = "idb-tools"
path = "src/tools/tools.rs"


[[bin]]
name = "tilib"
path = "src/tools/tilib.rs"
14 changes: 7 additions & 7 deletions src/til.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,14 @@ impl Type {
// IDBParam in the `Root Node`
let header = section::TILSectionHeader {
format: 12,
flags: section::TILSectionFlag(0),
flags: section::TILSectionFlags(0),
title: Vec::new(),
description: Vec::new(),
id: 0,
compiler_id: 0,
cm: 0,
size_enum: 0,
size_i: 4.try_into().unwrap(),
size_b: 1.try_into().unwrap(),
size_enum: None,
size_int: 4.try_into().unwrap(),
size_bool: 1.try_into().unwrap(),
def_align: 0,
size_long_double: None,
size_short: 2.try_into().unwrap(),
Expand Down Expand Up @@ -371,7 +371,7 @@ impl Basic {
BT_INT32 => bytes(4),
BT_INT64 => bytes(8),
BT_INT128 => bytes(16),
BT_INT => til.size_i,
BT_INT => til.size_int,
_ => unreachable!(),
};
Ok(Self::Int { bytes, is_signed })
Expand All @@ -380,7 +380,7 @@ impl Basic {
// InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x4805c4
BT_BOOL => {
let bytes = match btmt {
BTMT_DEFBOOL => til.size_b,
BTMT_DEFBOOL => til.size_bool,
BTMT_BOOL1 => bytes(1),
BTMT_BOOL4 => bytes(4),
// TODO get the inf_is_64bit field
Expand Down
10 changes: 5 additions & 5 deletions src/til/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ impl EnumRaw {
let bte = bincode::deserialize_from(&mut *input)?;
let mut cur: u64 = 0;
let emsize = bte & flag::tf_enum::BTE_SIZE_MASK;
let bytesize: u32 = match emsize {
0 if header.size_enum != 0 => header.size_enum.into(),
0 => return Err(anyhow!("BTE emsize is 0 without header")),
1..=4 => 1u32 << (emsize - 1),
5..=7 => return Err(anyhow!("BTE emsize with reserved values")),
let bytesize: u32 = match (emsize, header.size_enum) {
(0, Some(enum_size)) => enum_size.get().into(),
(0, None) => return Err(anyhow!("BTE emsize is 0 without header")),
(1..=4, _) => 1u32 << (emsize - 1),
(5..=7, _) => return Err(anyhow!("BTE emsize with reserved values")),
_ => unreachable!(),
};

Expand Down
18 changes: 9 additions & 9 deletions src/til/flag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,20 +413,20 @@ pub mod tf_shortcuts {
}

/// pack buckets using zip
pub const TIL_ZIP: u32 = 0x0001;
pub const TIL_ZIP: u16 = 0x0001;
/// til has macro table
pub const TIL_MAC: u32 = 0x0002;
pub const TIL_MAC: u16 = 0x0002;
/// extended sizeof info (short, long, longlong)
pub const TIL_ESI: u32 = 0x0004;
pub const TIL_ESI: u16 = 0x0004;
/// universal til for any compiler
pub const TIL_UNI: u32 = 0x0008;
pub const TIL_UNI: u16 = 0x0008;
/// type ordinal numbers are present
pub const TIL_ORD: u32 = 0x0010;
pub const TIL_ORD: u16 = 0x0010;
/// type aliases are present (this bit is used only on the disk)
pub const TIL_ALI: u32 = 0x0020;
pub const TIL_ALI: u16 = 0x0020;
/// til has been modified, should be saved
pub const TIL_MOD: u32 = 0x0040;
pub const TIL_MOD: u16 = 0x0040;
/// til has extra streams
pub const TIL_STM: u32 = 0x0080;
pub const TIL_STM: u16 = 0x0080;
/// sizeof(long double)
pub const TIL_SLD: u32 = 0x0100;
pub const TIL_SLD: u16 = 0x0100;
108 changes: 62 additions & 46 deletions src/til/section.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::id0::Id0TilOrd;
use crate::id0::{Compiler, Id0TilOrd};
use crate::ida_reader::{IdaGenericBufUnpack, IdaGenericUnpack};
use crate::til::{flag, TILMacro, TILTypeInfo};
use crate::IDBSectionCompression;
Expand All @@ -16,18 +16,21 @@ pub struct TILSection {
// TODO is title and description inverted?
/// short file name (without path and extension)
pub title: Vec<u8>,
pub flags: TILSectionFlags,
/// human readable til description
pub description: Vec<u8>,
pub id: u8,
/// the compiler used to generated types
pub compiler_id: Compiler,
/// information about the target compiler
pub cm: u8,
pub def_align: u8,
pub symbols: Vec<TILTypeInfo>,
// TODO create a struct for ordinal aliases
pub type_ordinal_alias: Option<Vec<(u32, u32)>>,
pub types: Vec<TILTypeInfo>,
pub size_i: NonZeroU8,
pub size_b: NonZeroU8,
pub size_int: NonZeroU8,
pub size_bool: NonZeroU8,
pub size_enum: Option<NonZeroU8>,
pub size_short: NonZeroU8,
pub size_long: NonZeroU8,
pub size_long_long: NonZeroU8,
Expand All @@ -39,14 +42,14 @@ pub struct TILSection {
#[derive(Debug, Clone)]
pub struct TILSectionHeader {
pub format: u32,
pub flags: TILSectionFlag,
pub flags: TILSectionFlags,
pub title: Vec<u8>,
pub description: Vec<u8>,
pub id: u8,
pub compiler_id: u8,
pub cm: u8,
pub size_enum: u8,
pub size_i: NonZeroU8,
pub size_b: NonZeroU8,
pub size_enum: Option<NonZeroU8>,
pub size_int: NonZeroU8,
pub size_bool: NonZeroU8,
pub def_align: u8,
pub size_short: NonZeroU8,
pub size_long: NonZeroU8,
Expand All @@ -58,15 +61,15 @@ pub struct TILSectionHeader {
pub struct TILSectionHeader1 {
pub signature: [u8; 6],
pub format: u32,
pub flags: TILSectionFlag,
pub flags: TILSectionFlags,
}

#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
pub struct TILSectionHeader2 {
pub id: u8,
pub compiler_id: u8,
pub cm: u8,
pub size_i: u8,
pub size_b: u8,
pub size_int: u8,
pub size_bool: u8,
pub size_enum: u8,
pub def_align: u8,
}
Expand Down Expand Up @@ -119,14 +122,16 @@ impl TILSection {
Ok(TILSection {
format: header.format,
title: header.title,
flags: header.flags,
description: header.description,
id: header.id,
compiler_id: Compiler::from_value(header.compiler_id),
cm: header.cm,
def_align: header.def_align,
size_long_double: header.size_long_double,
is_universal: header.flags.is_universal(),
size_b: header.size_b,
size_i: header.size_i,
size_bool: header.size_bool,
size_int: header.size_int,
size_enum: header.size_enum,
size_short: header.size_short,
size_long: header.size_long,
size_long_long: header.size_long_long,
Expand Down Expand Up @@ -198,11 +203,11 @@ impl TILSection {
format @ 0x13.. => return Err(anyhow!("Invalid TIL format {format}")),
// read the flag after the format
format @ 0x10..=0x12 => {
let flags = TILSectionFlag(input.read_u32()?);
let flags = TILSectionFlags::new(input.read_u32()?)?;
(format, flags)
}
// format and flag are the same
value @ ..=0xf => (value, TILSectionFlag(value)),
value @ ..=0xf => (value, TILSectionFlags::new(value)?),
};
let header1 = TILSectionHeader1 {
signature,
Expand Down Expand Up @@ -233,22 +238,21 @@ impl TILSection {
// InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x42ef86

// InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x431ffe
let (size_short, size_long, size_long_long) =
if header1.flags.have_size_short_long_longlong() {
let ss = input.read_u8()?;
let ls = input.read_u8()?;
let lls = input.read_u8()?;
let ss = NonZeroU8::new(ss).ok_or_else(|| anyhow!("Invalid short size"))?;
let ls = NonZeroU8::new(ls).ok_or_else(|| anyhow!("Invalid long size"))?;
let lls = NonZeroU8::new(lls).ok_or_else(|| anyhow!("Invalid long long size"))?;
(ss, ls, lls)
} else {
(
2.try_into().unwrap(),
4.try_into().unwrap(),
8.try_into().unwrap(),
)
};
let (size_short, size_long, size_long_long) = if header1.flags.have_extended_sizeof_info() {
let ss = input.read_u8()?;
let ls = input.read_u8()?;
let lls = input.read_u8()?;
let ss = NonZeroU8::new(ss).ok_or_else(|| anyhow!("Invalid short size"))?;
let ls = NonZeroU8::new(ls).ok_or_else(|| anyhow!("Invalid long size"))?;
let lls = NonZeroU8::new(lls).ok_or_else(|| anyhow!("Invalid long long size"))?;
(ss, ls, lls)
} else {
(
2.try_into().unwrap(),
4.try_into().unwrap(),
8.try_into().unwrap(),
)
};

// InnerRef fb47f2c2-3c08-4d40-b7ab-3c7736dce31d 0x432014
let size_long_double = header1
Expand All @@ -264,10 +268,10 @@ impl TILSection {
flags: header1.flags,
title,
description,
id: header2.id,
size_enum: header2.size_enum,
size_i: header2.size_i.try_into()?,
size_b: header2.size_b.try_into()?,
compiler_id: header2.compiler_id,
size_enum: header2.size_enum.try_into().ok(),
size_int: header2.size_int.try_into()?,
size_bool: header2.size_bool.try_into()?,
cm: header2.cm,
def_align: header2.def_align,
size_short,
Expand Down Expand Up @@ -302,18 +306,18 @@ impl TILSection {
flags: header.flags,
};
let header2 = TILSectionHeader2 {
id: header.id,
compiler_id: header.compiler_id,
cm: header.cm,
size_i: header.size_i.get(),
size_b: header.size_b.get(),
size_enum: header.size_enum,
size_int: header.size_int.get(),
size_bool: header.size_bool.get(),
size_enum: header.size_enum.map(NonZeroU8::get).unwrap_or(0),
def_align: header.def_align,
};
bincode::serialize_into(&mut *output, &header1)?;
crate::write_string_len_u8(&mut *output, &header.title)?;
crate::write_string_len_u8(&mut *output, &header.description)?;
bincode::serialize_into(&mut *output, &header2)?;
if header.flags.have_size_short_long_longlong() {
if header.flags.have_extended_sizeof_info() {
bincode::serialize_into(
&mut *output,
&(
Expand Down Expand Up @@ -376,8 +380,20 @@ impl TILSection {

// TODO remove deserialize and implement a verification if the value is correct
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct TILSectionFlag(pub(crate) u32);
impl TILSectionFlag {
pub struct TILSectionFlags(pub(crate) u16);
impl TILSectionFlags {
fn new(value: u32) -> Result<Self> {
ensure!(
value < (flag::TIL_SLD as u32) << 1,
"Unknown flag values for TILSectionFlags"
);
Ok(Self(value as u16))
}

pub fn as_raw(&self) -> u16 {
self.0
}

pub fn is_zip(&self) -> bool {
self.0 & flag::TIL_ZIP != 0
}
Expand All @@ -392,7 +408,7 @@ impl TILSectionFlag {
self.0 & flag::TIL_MAC != 0
}
/// extended sizeof info (short, long, longlong)
pub fn have_size_short_long_longlong(&self) -> bool {
pub fn have_extended_sizeof_info(&self) -> bool {
self.0 & flag::TIL_ESI != 0
}
/// universal til for any compiler
Expand Down
15 changes: 9 additions & 6 deletions src/tools/dump_til.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ pub fn dump_til(args: &Args) -> Result<()> {
let TILSection {
format,
title,
flags: _,
description,
id,
compiler_id,
cm,
def_align,
type_ordinal_alias,
size_i,
size_b,
size_int,
size_enum,
size_bool,
size_short,
size_long,
size_long_long,
Expand All @@ -49,11 +51,12 @@ pub fn dump_til(args: &Args) -> Result<()> {
println!("format: {format}");
println!("title: {}", String::from_utf8_lossy(&title));
println!("description: {}", String::from_utf8_lossy(&description));
println!("id: {id}");
println!("id: {compiler_id:?}");
println!("cm: {cm}");
println!("def_align: {def_align}");
println!("size_i: {size_i}");
println!("size_b: {size_b}");
println!("size_int: {size_int}");
println!("size_bool: {size_bool}");
println!("size_enum: {size_enum:?}");
println!("is_universal: {is_universal}");
if let Some(type_ordinal_numbers) = type_ordinal_alias {
println!("type_ordinal_numbers: {type_ordinal_numbers:?}");
Expand Down
Loading

0 comments on commit 81d551e

Please sign in to comment.