idakit_sys/
segment_flags.rs1use std::ffi::c_int;
5
6use bitflags::bitflags;
7
8bitflags! {
9 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14 #[doc(alias("SEGPERM_EXEC", "SEGPERM_WRITE", "SEGPERM_READ"))]
15 pub struct SegmentPermissions: c_int {
16 #[doc(alias("SEGPERM_EXEC"))]
18 const EXEC = 1;
19 #[doc(alias("SEGPERM_WRITE"))]
21 const WRITE = 2;
22 #[doc(alias("SEGPERM_READ"))]
24 const READ = 4;
25 }
26}
27
28bitflags! {
29 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
34 #[doc(alias("SFL_COMORG", "SFL_OBOK", "SFL_HIDDEN", "SFL_DEBUG", "SFL_LOADER", "SFL_HIDETYPE", "SFL_HEADER"))]
35 pub struct SegmentFlags: c_int {
36 #[doc(alias("SFL_COMORG"))]
38 const COMORG = 0x01;
39 #[doc(alias("SFL_OBOK"))]
41 const OBOK = 0x02;
42 #[doc(alias("SFL_HIDDEN"))]
44 const HIDDEN = 0x04;
45 #[doc(alias("SFL_DEBUG"))]
47 const DEBUG = 0x08;
48 #[doc(alias("SFL_LOADER"))]
50 const LOADER = 0x10;
51 #[doc(alias("SFL_HIDETYPE"))]
53 const HIDETYPE = 0x20;
54 #[doc(alias("SFL_HEADER"))]
56 const HEADER = 0x40;
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use assert2::assert;
63 use proptest::prelude::*;
64 use rstest::rstest;
65
66 use super::*;
67
68 #[rstest]
69 #[case::exec(SegmentPermissions::EXEC, 1)]
70 #[case::write(SegmentPermissions::WRITE, 2)]
71 #[case::read(SegmentPermissions::READ, 4)]
72 fn flags_pin_the_raw_sdk_values(#[case] flag: SegmentPermissions, #[case] raw: c_int) {
73 assert!(flag.bits() == raw);
74 }
75
76 #[rstest]
77 #[case::comorg(SegmentFlags::COMORG, 0x01)]
78 #[case::obok(SegmentFlags::OBOK, 0x02)]
79 #[case::hidden(SegmentFlags::HIDDEN, 0x04)]
80 #[case::debug(SegmentFlags::DEBUG, 0x08)]
81 #[case::loader(SegmentFlags::LOADER, 0x10)]
82 #[case::hidetype(SegmentFlags::HIDETYPE, 0x20)]
83 #[case::header(SegmentFlags::HEADER, 0x40)]
84 fn seg_flags_pin_the_raw_sdk_values(#[case] flag: SegmentFlags, #[case] raw: c_int) {
85 assert!(flag.bits() == raw);
86 }
87
88 proptest! {
89 #[test]
90 fn seg_perm_from_bits_retain_round_trips_every_bit_pattern(raw: c_int) {
91 prop_assert_eq!(SegmentPermissions::from_bits_retain(raw).bits(), raw);
92 }
93
94 #[test]
95 fn seg_perm_union_and_intersection_are_raw_bitwise_ops(a: c_int, b: c_int) {
96 let (fa, fb) = (SegmentPermissions::from_bits_retain(a), SegmentPermissions::from_bits_retain(b));
97 prop_assert_eq!((fa | fb).bits(), a | b);
98 prop_assert_eq!((fa & fb).bits(), a & b);
99 }
100
101 #[test]
102 fn seg_perm_complement_truncates_to_the_known_flag_mask(a: c_int) {
103 let fa = SegmentPermissions::from_bits_retain(a);
104 prop_assert_eq!((!fa).bits(), !a & SegmentPermissions::all().bits());
105 }
106
107 #[test]
108 fn seg_flags_from_bits_retain_round_trips_every_bit_pattern(raw: c_int) {
109 prop_assert_eq!(SegmentFlags::from_bits_retain(raw).bits(), raw);
110 }
111
112 #[test]
113 fn seg_flags_union_and_intersection_are_raw_bitwise_ops(a: c_int, b: c_int) {
114 let (fa, fb) = (SegmentFlags::from_bits_retain(a), SegmentFlags::from_bits_retain(b));
115 prop_assert_eq!((fa | fb).bits(), a | b);
116 prop_assert_eq!((fa & fb).bits(), a & b);
117 }
118
119 #[test]
120 fn seg_flags_complement_truncates_to_the_known_flag_mask(a: c_int) {
121 let fa = SegmentFlags::from_bits_retain(a);
122 prop_assert_eq!((!fa).bits(), !a & SegmentFlags::all().bits());
123 }
124 }
125}