Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use bitflags::bitflags;
4 : use std::{fmt, marker::PhantomData};
5 :
6 : use crate::common::{into_optional, FromFFI};
7 :
8 : use super::{commands::Dylib, Symbol};
9 :
10 : /// This structure represents an export (info) in a Mach-O binary
11 : pub struct ExportInfo<'a> {
12 : ptr: cxx::UniquePtr<ffi::MachO_ExportInfo>,
13 : _owner: PhantomData<&'a ()>,
14 : }
15 :
16 : #[allow(non_camel_case_types)]
17 228708 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
18 : pub enum Kind {
19 : REGULAR,
20 : THREAD_LOCAL,
21 : ABSOLUTE,
22 : UNKNOWN(u64),
23 : }
24 :
25 : impl From<u64> for Kind {
26 228708 : fn from(value: u64) -> Self {
27 228708 : match value {
28 228708 : 0x00000000 => Kind::REGULAR,
29 0 : 0x00000001 => Kind::THREAD_LOCAL,
30 0 : 0x00000002 => Kind::ABSOLUTE,
31 0 : _ => Kind::UNKNOWN(value),
32 : }
33 228708 : }
34 : }
35 :
36 0 : bitflags! {
37 228708 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
38 0 : pub struct Flags: u64 {
39 0 : const WEAK_DEFINITION = 0x4;
40 0 : const REEXPORT = 0x8;
41 0 : const STUB_AND_RESOLVER = 0x10;
42 0 : const STATIC_RESOLVER = 0x20;
43 0 : }
44 0 : }
45 :
46 :
47 : impl From<u64> for Flags {
48 228708 : fn from(value: u64) -> Self {
49 228708 : Flags::from_bits_truncate(value)
50 228708 : }
51 : }
52 : impl From<Flags> for u64 {
53 0 : fn from(value: Flags) -> Self {
54 0 : value.bits()
55 0 : }
56 : }
57 : impl std::fmt::Display for Flags {
58 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
59 0 : bitflags::parser::to_writer(self, f)
60 0 : }
61 : }
62 :
63 : impl fmt::Debug for ExportInfo<'_> {
64 228708 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 228708 : f.debug_struct("ExportInfo")
66 228708 : .field("node_offset", &self.node_offset())
67 228708 : .field("flags", &self.flags())
68 228708 : .field("address", &self.address())
69 228708 : .field("other", &self.other())
70 228708 : .field("kind", &self.kind())
71 228708 : .finish()
72 228708 : }
73 : }
74 :
75 : impl ExportInfo<'_> {
76 : /// Original offset in the export Trie
77 228708 : pub fn node_offset(&self) -> u64 {
78 228708 : self.ptr.node_offset()
79 228708 : }
80 :
81 228708 : pub fn flags(&self) -> Flags {
82 228708 : Flags::from(self.ptr.flags())
83 228708 : }
84 :
85 : /// The address of the export
86 228708 : pub fn address(&self) -> u64 {
87 228708 : self.ptr.address()
88 228708 : }
89 :
90 228708 : pub fn other(&self) -> u64 {
91 228708 : self.ptr.other()
92 228708 : }
93 :
94 : /// The export's kind (regular, thread local, absolute, ...)
95 228708 : pub fn kind(&self) -> Kind {
96 228708 : Kind::from(self.ptr.kind())
97 228708 : }
98 :
99 : /// Symbol associated with this export
100 11052 : pub fn symbol(&self) -> Option<Symbol> {
101 11052 : into_optional(self.ptr.symbol())
102 11052 : }
103 :
104 : /// If the export is a re-export ([`Flags::REEXPORT`]) this function returns
105 : /// the symbol being re-exported
106 11052 : pub fn alias(&self) -> Option<Symbol> {
107 11052 : into_optional(self.ptr.alias())
108 11052 : }
109 :
110 : /// If the export is a re-export ([`Flags::REEXPORT`]) this function returns
111 : /// the library from which the symbol is re-exported
112 11052 : pub fn alias_library(&self) -> Option<Dylib> {
113 11052 : into_optional(self.ptr.alias_library())
114 11052 : }
115 : }
116 :
117 : impl<'a> FromFFI<ffi::MachO_ExportInfo> for ExportInfo<'a> {
118 228708 : fn from_ffi(ptr: cxx::UniquePtr<ffi::MachO_ExportInfo>) -> Self {
119 228708 : Self {
120 228708 : ptr,
121 228708 : _owner: PhantomData,
122 228708 : }
123 228708 : }
124 : }
|