1use std::ffi::{c_char, c_int, c_void};
5
6use bitflags::bitflags;
7
8use crate::Address;
9
10unsafe extern "C" {
12 #[link_name = "idakit_get_bytes"]
15 pub fn get_bytes_into(address: Address, buf: *mut c_void, size: usize) -> i64;
16}
17
18bitflags! {
19 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
21 #[doc(alias("BIN_SEARCH_CASE", "BIN_SEARCH_BITMASK"))]
22 pub struct BinSearchFlags: c_int {
23 #[doc(alias("BIN_SEARCH_CASE"))]
25 const CASE = 0x01;
26 #[doc(alias("BIN_SEARCH_BITMASK"))]
28 const BITMASK = 0x20;
29 }
30}
31
32pub const MS_CLS: u64 = 0x0000_0600;
40pub const FF_CODE: u64 = 0x0000_0600;
42pub const FF_DATA: u64 = 0x0000_0400;
44
45unsafe extern "C" {
47 pub fn set_cmt(address: Address, comm: *const c_char, rptble: bool) -> bool;
49}
50
51#[cfg(test)]
52mod tests {
53 use assert2::assert;
54 use proptest::prelude::*;
55 use rstest::rstest;
56
57 use super::*;
58
59 #[rstest]
60 #[case::case(BinSearchFlags::CASE, 0x01)]
61 #[case::bitmask(BinSearchFlags::BITMASK, 0x20)]
62 fn flags_pin_the_raw_sdk_values(#[case] flag: BinSearchFlags, #[case] raw: c_int) {
63 assert!(flag.bits() == raw);
64 }
65
66 #[rstest]
67 #[case::ms_cls(MS_CLS, 0x0000_0600)]
68 #[case::ff_code(FF_CODE, 0x0000_0600)]
69 #[case::ff_data(FF_DATA, 0x0000_0400)]
70 fn classification_consts_pin_the_raw_sdk_values(#[case] value: u64, #[case] raw: u64) {
71 assert!(value == raw);
72 }
73
74 #[test]
75 fn ff_code_and_ff_data_are_distinct_under_the_class_mask() {
76 assert!(FF_CODE & MS_CLS == FF_CODE);
77 assert!(FF_DATA & MS_CLS == FF_DATA);
78 assert!(FF_CODE != FF_DATA);
79 }
80
81 proptest! {
82 #[test]
83 fn from_bits_retain_round_trips_every_bit_pattern(raw: c_int) {
84 prop_assert_eq!(BinSearchFlags::from_bits_retain(raw).bits(), raw);
85 }
86
87 #[test]
88 fn union_and_intersection_are_raw_bitwise_ops(a: c_int, b: c_int) {
89 let (fa, fb) = (BinSearchFlags::from_bits_retain(a), BinSearchFlags::from_bits_retain(b));
90 prop_assert_eq!((fa | fb).bits(), a | b);
91 prop_assert_eq!((fa & fb).bits(), a & b);
92 }
93
94 #[test]
96 fn complement_truncates_to_the_known_flag_mask(a: c_int) {
97 let fa = BinSearchFlags::from_bits_retain(a);
98 prop_assert_eq!((!fa).bits(), !a & BinSearchFlags::all().bits());
99 }
100 }
101}