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 152448 : #[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 152448 : fn from(value: u64) -> Self {
27 152448 : match value {
28 152448 : 0x00000000 => Kind::REGULAR,
29 0 : 0x00000001 => Kind::THREAD_LOCAL,
30 0 : 0x00000002 => Kind::ABSOLUTE,
31 0 : _ => Kind::UNKNOWN(value),
32 : }
33 152448 : }
34 : }
35 :
36 0 : bitflags! {
37 152448 : #[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 : }
43 0 : }
44 :
45 :
46 : impl From<u64> for Flags {
47 152448 : fn from(value: u64) -> Self {
48 152448 : Flags::from_bits_truncate(value)
49 152448 : }
50 : }
51 : impl From<Flags> for u64 {
52 0 : fn from(value: Flags) -> Self {
53 0 : value.bits()
54 0 : }
55 : }
56 : impl std::fmt::Display for Flags {
57 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
58 0 : bitflags::parser::to_writer(self, f)
59 0 : }
60 : }
61 :
62 : impl fmt::Debug for ExportInfo<'_> {
63 152448 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 152448 : f.debug_struct("ExportInfo")
65 152448 : .field("node_offset", &self.node_offset())
66 152448 : .field("flags", &self.flags())
67 152448 : .field("address", &self.address())
68 152448 : .field("other", &self.other())
69 152448 : .field("kind", &self.kind())
70 152448 : .finish()
71 152448 : }
72 : }
73 :
74 : impl ExportInfo<'_> {
75 : /// Original offset in the export Trie
76 152448 : pub fn node_offset(&self) -> u64 {
77 152448 : self.ptr.node_offset()
78 152448 : }
79 :
80 152448 : pub fn flags(&self) -> Flags {
81 152448 : Flags::from(self.ptr.flags())
82 152448 : }
83 :
84 : /// The address of the export
85 152448 : pub fn address(&self) -> u64 {
86 152448 : self.ptr.address()
87 152448 : }
88 :
89 152448 : pub fn other(&self) -> u64 {
90 152448 : self.ptr.other()
91 152448 : }
92 :
93 : /// The export's kind (regular, thread local, absolute, ...)
94 152448 : pub fn kind(&self) -> Kind {
95 152448 : Kind::from(self.ptr.kind())
96 152448 : }
97 :
98 : /// Symbol associated with this export
99 7360 : pub fn symbol(&self) -> Option<Symbol> {
100 7360 : into_optional(self.ptr.symbol())
101 7360 : }
102 :
103 : /// If the export is a re-export ([`Flags::REEXPORT`]) this function returns
104 : /// the symbol being re-exported
105 7360 : pub fn alias(&self) -> Option<Symbol> {
106 7360 : into_optional(self.ptr.alias())
107 7360 : }
108 :
109 : /// If the export is a re-export ([`Flags::REEXPORT`]) this function returns
110 : /// the library from which the symbol is re-exported
111 7360 : pub fn alias_library(&self) -> Option<Dylib> {
112 7360 : into_optional(self.ptr.alias_library())
113 7360 : }
114 : }
115 :
116 : impl<'a> FromFFI<ffi::MachO_ExportInfo> for ExportInfo<'a> {
117 152448 : fn from_ffi(ptr: cxx::UniquePtr<ffi::MachO_ExportInfo>) -> Self {
118 152448 : Self {
119 152448 : ptr,
120 152448 : _owner: PhantomData,
121 152448 : }
122 152448 : }
123 : }
|