Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::{to_slice, to_result, Error};
4 : use crate::common::FromFFI;
5 :
6 : use std::fmt;
7 : use std::marker::PhantomData;
8 :
9 : /// This class represents a stub entry in sections like `__stubs,__auth_stubs`.
10 : ///
11 : /// It wraps assembly instructions which are used to access the *got* where the
12 : /// address of the symbol is resolved.
13 : ///
14 : /// Example:
15 : ///
16 : /// ```text
17 : /// 0000000236a3c1bc: ___memcpy_chk
18 : /// adrp x17, #0x241513aa8
19 : /// add x17, x17, #0x241513aa8
20 : /// ldr x16, [x17]
21 : /// braa x16, x17
22 : /// ```
23 : pub struct Stub<'a> {
24 : ptr: cxx::UniquePtr<ffi::MachO_Stub>,
25 : _owner: PhantomData<&'a ffi::MachO_Binary>
26 : }
27 :
28 : impl Stub<'_> {
29 : /// The virtual address where the stub is located
30 15200 : pub fn address(&self) -> u64 {
31 15200 : self.ptr.address()
32 15200 : }
33 :
34 : /// The (raw) instructions of this entry as a slice of bytes
35 15200 : pub fn raw(&self) -> &[u8] {
36 15200 : to_slice!(self.ptr.raw());
37 15200 : }
38 :
39 : ///
40 : /// For instance, given this stub:
41 : ///
42 : /// ```text
43 : /// 0x3eec: adrp x16, #4096
44 : /// 0x3ef0: ldr x16, [x16, #24]
45 : /// 0x3ef4: br x16
46 : /// ```
47 : ///
48 : /// The function returns: `0x4018`.
49 : ///
50 : /// <div class="warning">This function is only available with LIEF's extended version</div>
51 0 : pub fn target(&self) -> Result<u64, Error> {
52 0 : to_result!(ffi::MachO_Stub::target, self);
53 0 : }
54 : }
55 :
56 : impl fmt::Debug for Stub<'_> {
57 15200 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 15200 : f.debug_struct("Stub")
59 15200 : .field("address", &self.address())
60 15200 : .finish()
61 15200 : }
62 : }
63 :
64 :
65 : impl FromFFI<ffi::MachO_Stub> for Stub<'_> {
66 15200 : fn from_ffi(stub: cxx::UniquePtr<ffi::MachO_Stub>) -> Self {
67 15200 : Self {
68 15200 : ptr: stub,
69 15200 : _owner: PhantomData
70 15200 : }
71 15200 : }
72 : }
|