@@ -42,32 +42,72 @@ use libc::c_void;
42
42
43
43
use ffi:: uc_handle;
44
44
45
- pub use crate :: arm:: * ;
46
- pub use crate :: arm64:: * ;
47
- pub use crate :: m68k:: * ;
48
- pub use crate :: mips:: * ;
49
- pub use crate :: ppc:: * ;
50
- pub use crate :: riscv:: * ;
51
- pub use crate :: s390x:: * ;
52
- pub use crate :: sparc:: * ;
53
- pub use crate :: tricore:: * ;
54
- pub use crate :: unicorn_const:: * ;
55
- pub use crate :: x86:: * ;
56
-
57
45
#[ macro_use]
58
46
pub mod unicorn_const;
47
+ pub use unicorn_const:: * ;
59
48
pub mod ffi; // lets consumers call ffi if desired
60
49
50
+ // include arm support if conditionally compiled in
51
+ #[ cfg( feature = "arch_arm" ) ]
61
52
mod arm;
53
+ #[ cfg( feature = "arch_arm" ) ]
54
+ pub use crate :: arm:: * ;
55
+
56
+ // include arm64 support if conditionally compiled in
57
+ // NOTE: unicorn-c only separates on top-level arch name,
58
+ // not on the bit-length, so we include both
59
+ #[ cfg( feature = "arch_arm" ) ]
62
60
mod arm64;
61
+ #[ cfg( feature = "arch_arm" ) ]
62
+ pub use crate :: arm64:: * ;
63
+
64
+ // include m68k support if conditionally compiled in
65
+ #[ cfg( feature = "arch_m68k" ) ]
63
66
mod m68k;
67
+ #[ cfg( feature = "arch_m68k" ) ]
68
+ pub use crate :: m68k:: * ;
69
+
70
+ // include mips support if conditionally compiled in
71
+ #[ cfg( feature = "arch_mips" ) ]
64
72
mod mips;
73
+ #[ cfg( feature = "arch_mips" ) ]
74
+ pub use crate :: mips:: * ;
75
+
76
+ // include ppc support if conditionally compiled in
77
+ #[ cfg( feature = "arch_ppc" ) ]
65
78
mod ppc;
79
+ #[ cfg( feature = "arch_ppc" ) ]
80
+ pub use crate :: ppc:: * ;
81
+
82
+ // include riscv support if conditionally compiled in
83
+ #[ cfg( feature = "arch_riscv" ) ]
66
84
mod riscv;
85
+ #[ cfg( feature = "arch_riscv" ) ]
86
+ pub use crate :: riscv:: * ;
87
+
88
+ // include s390x support if conditionally compiled in
89
+ #[ cfg( feature = "arch_s390x" ) ]
67
90
mod s390x;
91
+ #[ cfg( feature = "arch_s390x" ) ]
92
+ pub use crate :: s390x:: * ;
93
+
94
+ // include sparc support if conditionally compiled in
95
+ #[ cfg( feature = "arch_sparc" ) ]
68
96
mod sparc;
97
+ #[ cfg( feature = "arch_sparc" ) ]
98
+ pub use crate :: sparc:: * ;
99
+
100
+ // include tricore support if conditionally compiled in
101
+ #[ cfg( feature = "arch_tricore" ) ]
69
102
mod tricore;
103
+ #[ cfg( feature = "arch_tricore" ) ]
104
+ pub use crate :: tricore:: * ;
105
+
106
+ // include x86 support if conditionally compiled in
107
+ #[ cfg( feature = "arch_x86" ) ]
70
108
mod x86;
109
+ #[ cfg( feature = "arch_x86" ) ]
110
+ pub use crate :: x86:: * ;
71
111
72
112
#[ derive( Debug ) ]
73
113
pub struct Context {
@@ -508,7 +548,9 @@ impl<'a, D> Unicorn<'a, D> {
508
548
let curr_arch = self . get_arch ( ) ;
509
549
510
550
let value_size = match curr_arch {
551
+ #[ cfg( feature = "arch_x86" ) ]
511
552
Arch :: X86 => Self :: value_size_x86 ( curr_reg_id) ?,
553
+ #[ cfg( feature = "arch_arm" ) ]
512
554
Arch :: ARM64 => Self :: value_size_arm64 ( curr_reg_id) ?,
513
555
_ => Err ( uc_error:: ARCH ) ?,
514
556
} ;
@@ -517,6 +559,7 @@ impl<'a, D> Unicorn<'a, D> {
517
559
. and_then ( || Ok ( value. into_boxed_slice ( ) ) )
518
560
}
519
561
562
+ #[ cfg( feature = "arch_arm" ) ]
520
563
fn value_size_arm64 ( curr_reg_id : i32 ) -> Result < usize , uc_error > {
521
564
match curr_reg_id {
522
565
r if ( RegisterARM64 :: Q0 as i32 ..=RegisterARM64 :: Q31 as i32 ) . contains ( & r)
@@ -528,6 +571,7 @@ impl<'a, D> Unicorn<'a, D> {
528
571
}
529
572
}
530
573
574
+ #[ cfg( feature = "arch_x86" ) ]
531
575
fn value_size_x86 ( curr_reg_id : i32 ) -> Result < usize , uc_error > {
532
576
match curr_reg_id {
533
577
r if ( RegisterX86 :: XMM0 as i32 ..=RegisterX86 :: XMM31 as i32 ) . contains ( & r) => Ok ( 16 ) ,
@@ -716,6 +760,7 @@ impl<'a, D> Unicorn<'a, D> {
716
760
}
717
761
718
762
/// Add hook for x86 IN instruction.
763
+ #[ cfg( feature = "arch_x86" ) ]
719
764
pub fn add_insn_in_hook < F : ' a > ( & mut self , callback : F ) -> Result < UcHookId , uc_error >
720
765
where
721
766
F : FnMut ( & mut Unicorn < D > , u32 , usize ) -> u32 ,
@@ -746,6 +791,7 @@ impl<'a, D> Unicorn<'a, D> {
746
791
}
747
792
748
793
/// Add hook for x86 OUT instruction.
794
+ #[ cfg( feature = "arch_x86" ) ]
749
795
pub fn add_insn_out_hook < F : ' a > ( & mut self , callback : F ) -> Result < UcHookId , uc_error >
750
796
where
751
797
F : FnMut ( & mut Unicorn < D > , u32 , usize , u32 ) ,
@@ -776,6 +822,7 @@ impl<'a, D> Unicorn<'a, D> {
776
822
}
777
823
778
824
/// Add hook for x86 SYSCALL or SYSENTER.
825
+ #[ cfg( feature = "arch_x86" ) ]
779
826
pub fn add_insn_sys_hook < F > (
780
827
& mut self ,
781
828
insn_type : InsnSysX86 ,
@@ -932,44 +979,52 @@ impl<'a, D> Unicorn<'a, D> {
932
979
unsafe { ffi:: uc_query ( self . get_handle ( ) , query, & mut result) } . and ( Ok ( result) )
933
980
}
934
981
982
+ /// Get the `i32` register value for the program counter for the specified architecture.
983
+ ///
984
+ /// If an architecture is not compiled in, this function will return `uc_error::ARCH`.
985
+ #[ inline]
986
+ fn arch_to_pc_register ( arch : Arch ) -> Result < i32 , uc_error > {
987
+ match arch {
988
+ #[ cfg( feature = "arch_x86" ) ]
989
+ Arch :: X86 => Ok ( RegisterX86 :: RIP as i32 ) ,
990
+ #[ cfg( feature = "arch_arm" ) ]
991
+ Arch :: ARM => Ok ( RegisterARM :: PC as i32 ) ,
992
+ #[ cfg( feature = "arch_arm" ) ]
993
+ Arch :: ARM64 => Ok ( RegisterARM64 :: PC as i32 ) ,
994
+ #[ cfg( feature = "arch_mips" ) ]
995
+ Arch :: MIPS => Ok ( RegisterMIPS :: PC as i32 ) ,
996
+ #[ cfg( feature = "arch_sparc" ) ]
997
+ Arch :: SPARC => Ok ( RegisterSPARC :: PC as i32 ) ,
998
+ #[ cfg( feature = "arch_m68k" ) ]
999
+ Arch :: M68K => Ok ( RegisterM68K :: PC as i32 ) ,
1000
+ #[ cfg( feature = "arch_ppc" ) ]
1001
+ Arch :: PPC => Ok ( RegisterPPC :: PC as i32 ) ,
1002
+ #[ cfg( feature = "arch_riscv" ) ]
1003
+ Arch :: RISCV => Ok ( RegisterRISCV :: PC as i32 ) ,
1004
+ #[ cfg( feature = "arch_s390x" ) ]
1005
+ Arch :: S390X => Ok ( RegisterS390X :: PC as i32 ) ,
1006
+ #[ cfg( feature = "arch_tricore" ) ]
1007
+ Arch :: TRICORE => Ok ( RegisterTRICORE :: PC as i32 ) ,
1008
+ // returns `uc_error::ARCH` for `Arch::MAX`, and any
1009
+ // other architecture that are not compiled in
1010
+ _ => Err ( uc_error:: ARCH ) ,
1011
+ }
1012
+ }
1013
+
935
1014
/// Gets the current program counter for this `unicorn` instance.
936
1015
#[ inline]
937
1016
pub fn pc_read ( & self ) -> Result < u64 , uc_error > {
938
1017
let arch = self . get_arch ( ) ;
939
- let reg = match arch {
940
- Arch :: X86 => RegisterX86 :: RIP as i32 ,
941
- Arch :: ARM => RegisterARM :: PC as i32 ,
942
- Arch :: ARM64 => RegisterARM64 :: PC as i32 ,
943
- Arch :: MIPS => RegisterMIPS :: PC as i32 ,
944
- Arch :: SPARC => RegisterSPARC :: PC as i32 ,
945
- Arch :: M68K => RegisterM68K :: PC as i32 ,
946
- Arch :: PPC => RegisterPPC :: PC as i32 ,
947
- Arch :: RISCV => RegisterRISCV :: PC as i32 ,
948
- Arch :: S390X => RegisterS390X :: PC as i32 ,
949
- Arch :: TRICORE => RegisterTRICORE :: PC as i32 ,
950
- Arch :: MAX => panic ! ( "Illegal Arch specified" ) ,
951
- } ;
952
- self . reg_read ( reg)
1018
+
1019
+ self . reg_read ( Self :: arch_to_pc_register ( arch) ?)
953
1020
}
954
1021
955
1022
/// Sets the program counter for this `unicorn` instance.
956
1023
#[ inline]
957
1024
pub fn set_pc ( & mut self , value : u64 ) -> Result < ( ) , uc_error > {
958
1025
let arch = self . get_arch ( ) ;
959
- let reg = match arch {
960
- Arch :: X86 => RegisterX86 :: RIP as i32 ,
961
- Arch :: ARM => RegisterARM :: PC as i32 ,
962
- Arch :: ARM64 => RegisterARM64 :: PC as i32 ,
963
- Arch :: MIPS => RegisterMIPS :: PC as i32 ,
964
- Arch :: SPARC => RegisterSPARC :: PC as i32 ,
965
- Arch :: M68K => RegisterM68K :: PC as i32 ,
966
- Arch :: PPC => RegisterPPC :: PC as i32 ,
967
- Arch :: RISCV => RegisterRISCV :: PC as i32 ,
968
- Arch :: S390X => RegisterS390X :: PC as i32 ,
969
- Arch :: TRICORE => RegisterTRICORE :: PC as i32 ,
970
- Arch :: MAX => panic ! ( "Illegal Arch specified" ) ,
971
- } ;
972
- self . reg_write ( reg, value)
1026
+
1027
+ self . reg_write ( Self :: arch_to_pc_register ( arch) ?, value)
973
1028
}
974
1029
975
1030
pub fn ctl_get_mode ( & self ) -> Result < Mode , uc_error > {
0 commit comments