Line data Source code
1 : use super::Command;
2 : use lief_ffi as ffi;
3 : use crate::common::FromFFI;
4 : use std::marker::PhantomData;
5 :
6 : /// Class that represents the `LC_ROUTINE/LC_ROUTINE64` commands.
7 : /// Accodring to the Mach-O `loader.h` documentation:
8 : ///
9 : /// > The routines command contains the address of the dynamic shared library
10 : /// > initialization routine and an index into the module table for the module
11 : /// > that defines the routine. Before any modules are used from the library the
12 : /// > dynamic linker fully binds the module that defines the initialization routine
13 : /// > and then calls it. This gets called before any module initialization
14 : /// > routines (used for C++ static constructors) in the library.
15 : pub struct Routine<'a> {
16 : ptr: cxx::UniquePtr<ffi::MachO_Routine>,
17 : _owner: PhantomData<&'a ffi::MachO_Binary>
18 : }
19 :
20 : impl Routine<'_> {
21 : /// address of initialization routine
22 16 : pub fn init_address(&self) -> u64 {
23 16 : self.ptr.init_address()
24 16 : }
25 :
26 : /// Index into the module table that the init routine is defined in
27 16 : pub fn init_module(&self) -> u64 {
28 16 : self.ptr.init_module()
29 16 : }
30 :
31 16 : pub fn reserved1(&self) -> u64 {
32 16 : self.ptr.reserved1()
33 16 : }
34 :
35 16 : pub fn reserved2(&self) -> u64 {
36 16 : self.ptr.reserved2()
37 16 : }
38 :
39 16 : pub fn reserved3(&self) -> u64 {
40 16 : self.ptr.reserved3()
41 16 : }
42 :
43 16 : pub fn reserved4(&self) -> u64 {
44 16 : self.ptr.reserved4()
45 16 : }
46 :
47 16 : pub fn reserved5(&self) -> u64 {
48 16 : self.ptr.reserved5()
49 16 : }
50 :
51 16 : pub fn reserved6(&self) -> u64 {
52 16 : self.ptr.reserved6()
53 16 : }
54 : }
55 :
56 : impl std::fmt::Debug for Routine<'_> {
57 16 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 16 : let base = self as &dyn Command;
59 16 : f.debug_struct("Routine")
60 16 : .field("base", &base)
61 16 : .field("init_address", &self.init_address())
62 16 : .field("init_module", &self.init_module())
63 16 : .field("reserved1", &self.reserved1())
64 16 : .field("reserved2", &self.reserved2())
65 16 : .field("reserved3", &self.reserved3())
66 16 : .field("reserved4", &self.reserved4())
67 16 : .field("reserved5", &self.reserved5())
68 16 : .field("reserved6", &self.reserved6())
69 16 : .finish()
70 16 : }
71 : }
72 :
73 : impl FromFFI<ffi::MachO_Routine> for Routine<'_> {
74 16 : fn from_ffi(cmd: cxx::UniquePtr<ffi::MachO_Routine>) -> Self {
75 16 : Self {
76 16 : ptr: cmd,
77 16 : _owner: PhantomData
78 16 : }
79 16 : }
80 : }
81 :
82 : impl Command for Routine<'_> {
83 64 : fn get_base(&self) -> &ffi::MachO_Command {
84 64 : self.ptr.as_ref().unwrap().as_ref()
85 64 : }
86 : }
87 :
|