capstone-rust / capstone-rs

high-level Capstone system bindings for Rust
220 stars 78 forks source link

Export cs_group_type as InsnGroupType. #47

Closed waywardmonkeys closed 6 years ago

waywardmonkeys commented 6 years ago

I'd like to chase this with a PR that lets you compare InsnGroupId directly with the various enums ... to avoid some ugly / unsafe code when I use the Capstone bindings.

tmfink commented 6 years ago

Thanks for the PR! But, why do we need to export capstone_sys::cs_group_type? It does not appear in any public API.

In regards to the new PR, I look forward to seeing it.

waywardmonkeys commented 6 years ago

I use cs_group_type for checking if an instruction belongs to some of the common cross-platform groups ... that said, Capstone is pretty weak currently in this regard, but I remain hopeful that it may one day improve.

tmfink commented 6 years ago

I see what you mean--Capstone::group_name() was exposed, but not a "module enum" of possible values. Only the arch-specific types were exported, such as ArmInsnGroup.

I would love to see an enum of group types--I just haven't had the time to put one together. I was thinking of something like:

/// An architecture-independent view of groups
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum InsnGroupType {
    Common(CommonGroupTypes), // currently named InsnGroupType with this PR
    Arm(ArmGroupTypes),
    // ...
    X86(X86GroupTypes),
}

/// Elements from arm_insn_group/ArmInsnGroup
///
/// We would need to script the creation
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum ArmGroupTypes {
    Arm,
    Crc,
    Crypto,
    Databarrier,
    // ...
}

/// Subset of InsnGroupType for Arm only
///
/// Useful when you know you are working in the context of
/// Arm and don't want to worry about other architectures
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum ArmGroup {
    Common(CommonGroupTypes)
    Arm(ArmGroupTypes),
}

// Rest of the arch group types

// conversions between capstone-sys types and Rusty types
impl InsnGroupType {
    /// Different architectures have aliasing group type values, so we need to know the arch
    pub fn from_raw_capstone_group(
        arch: Arch,
        insn_group_id: u32,
    ) -> Option<InsnGroupType> {
        // ...
    }

    /// Convert into the capstone-sys type
    pub fn into_raw_capstone_group(&self) -> u32 { /* ... */ }

    // arch group conversions

    pub into_arm_group(&self) -> Option<ArmGroup> { /* ... */ }

    // ...
}

impl From<ArmGroup> for InsnGroupType {
    /* ... */
}

Instead of returning struct InsnGroupId(InsnGroupIdInt), we would return a proper Rusty enum.