Line data Source code
1 : //! Module for the PE exception support
2 :
3 : use super::exception_aarch64;
4 : use super::exception_x64;
5 : use lief_ffi as ffi;
6 :
7 : use crate::common::FromFFI;
8 :
9 : /// Enum that wraps the different kinds of runtime functions associated with exceptions
10 1002417 : #[derive(Debug)]
11 : pub enum RuntimeExceptionFunction<'a> {
12 : /// A x86_64 exception entry
13 : X86_64(exception_x64::RuntimeFunction<'a>),
14 :
15 : /// An ARM64 exception entry
16 : AArch64(exception_aarch64::RuntimeFunction<'a>),
17 : }
18 :
19 : impl<'a> FromFFI<ffi::PE_ExceptionInfo> for RuntimeExceptionFunction<'a> {
20 1002417 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_ExceptionInfo>) -> Self {
21 1002417 : unsafe {
22 1002417 : let obj_ref = ffi_entry.as_ref().unwrap();
23 1002417 : if ffi::PE_RuntimeFunctionX64::classof(obj_ref) {
24 695500 : let raw = {
25 695500 : type From = cxx::UniquePtr<ffi::PE_ExceptionInfo>;
26 695500 : type To = cxx::UniquePtr<ffi::PE_RuntimeFunctionX64>;
27 695500 : std::mem::transmute::<From, To>(ffi_entry)
28 695500 : };
29 695500 : RuntimeExceptionFunction::X86_64(exception_x64::RuntimeFunction::from_ffi(raw))
30 306917 : } else if ffi::PE_RuntimeFunctionAArch64::classof(obj_ref) {
31 306917 : let raw = {
32 306917 : type From = cxx::UniquePtr<ffi::PE_ExceptionInfo>;
33 306917 : type To = cxx::UniquePtr<ffi::PE_RuntimeFunctionAArch64>;
34 306917 : std::mem::transmute::<From, To>(ffi_entry)
35 306917 : };
36 306917 : RuntimeExceptionFunction::AArch64(exception_aarch64::RuntimeFunction::from_ffi(raw))
37 : } else {
38 0 : panic!("unsupported architecture");
39 : }
40 : }
41 1002417 : }
42 : }
43 :
44 : /// Trait shared by all runtime functions
45 : pub trait ExceptionInfo {
46 : #[doc(hidden)]
47 : fn as_generic(&self) -> &ffi::PE_ExceptionInfo;
48 :
49 : /// Function start address
50 695500 : fn rva_start(&self) -> u32 {
51 695500 : self.as_generic().rva_start()
52 695500 : }
53 :
54 : /// Offset in the binary where the raw exception information associated with
55 : /// this entry is defined
56 0 : fn offset(&self) -> u64 {
57 0 : self.as_generic().offset()
58 0 : }
59 : }
60 :
61 : impl std::fmt::Display for &dyn ExceptionInfo {
62 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
63 0 : write!(f, "{}", self.as_generic().to_string())
64 0 : }
65 : }
|