Line data Source code
1 : //! Module for the PE exception support
2 :
3 : use lief_ffi as ffi;
4 : use super::exception_x64;
5 : use super::exception_aarch64;
6 :
7 : use crate::common::FromFFI;
8 :
9 : /// Enum that wraps the different kinds of runtime functions associated with exceptions
10 771090 : #[derive(Debug)]
11 : pub enum RuntimeExceptionFunction<'a> {
12 : /// An 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 771090 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_ExceptionInfo>) -> Self {
21 771090 : unsafe {
22 771090 : let obj_ref = ffi_entry.as_ref().unwrap();
23 771090 : if ffi::PE_RuntimeFunctionX64::classof(obj_ref) {
24 535000 : let raw = {
25 535000 : type From = cxx::UniquePtr<ffi::PE_ExceptionInfo>;
26 535000 : type To = cxx::UniquePtr<ffi::PE_RuntimeFunctionX64>;
27 535000 : std::mem::transmute::<From, To>(ffi_entry)
28 535000 : };
29 535000 : RuntimeExceptionFunction::X86_64(exception_x64::RuntimeFunction::from_ffi(raw))
30 236090 : } else if ffi::PE_RuntimeFunctionAArch64::classof(obj_ref) {
31 236090 : let raw = {
32 236090 : type From = cxx::UniquePtr<ffi::PE_ExceptionInfo>;
33 236090 : type To = cxx::UniquePtr<ffi::PE_RuntimeFunctionAArch64>;
34 236090 : std::mem::transmute::<From, To>(ffi_entry)
35 236090 : };
36 236090 : RuntimeExceptionFunction::AArch64(exception_aarch64::RuntimeFunction::from_ffi(raw))
37 : } else {
38 0 : panic!("unsupported architecture");
39 : }
40 : }
41 771090 : }
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 535000 : fn rva_start(&self) -> u32 {
51 535000 : self.as_generic().rva_start()
52 535000 : }
53 : }
54 :
55 : impl std::fmt::Display for &dyn ExceptionInfo {
56 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
57 0 : write!(f, "{}", self.as_generic().to_string())
58 0 : }
59 : }
|