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 20 : pub fn init_address(&self) -> u64 {
23 20 : self.ptr.init_address()
24 20 : }
25 :
26 : /// Index into the module table that the init routine is defined in
27 20 : pub fn init_module(&self) -> u64 {
28 20 : self.ptr.init_module()
29 20 : }
30 :
31 20 : pub fn reserved1(&self) -> u64 {
32 20 : self.ptr.reserved1()
33 20 : }
34 :
35 20 : pub fn reserved2(&self) -> u64 {
36 20 : self.ptr.reserved2()
37 20 : }
38 :
39 20 : pub fn reserved3(&self) -> u64 {
40 20 : self.ptr.reserved3()
41 20 : }
42 :
43 20 : pub fn reserved4(&self) -> u64 {
44 20 : self.ptr.reserved4()
45 20 : }
46 :
47 20 : pub fn reserved5(&self) -> u64 {
48 20 : self.ptr.reserved5()
49 20 : }
50 :
51 20 : pub fn reserved6(&self) -> u64 {
52 20 : self.ptr.reserved6()
53 20 : }
54 : }
55 :
56 : impl std::fmt::Debug for Routine<'_> {
57 20 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 20 : let base = self as &dyn Command;
59 20 : f.debug_struct("Routine")
60 20 : .field("base", &base)
61 20 : .field("init_address", &self.init_address())
62 20 : .field("init_module", &self.init_module())
63 20 : .field("reserved1", &self.reserved1())
64 20 : .field("reserved2", &self.reserved2())
65 20 : .field("reserved3", &self.reserved3())
66 20 : .field("reserved4", &self.reserved4())
67 20 : .field("reserved5", &self.reserved5())
68 20 : .field("reserved6", &self.reserved6())
69 20 : .finish()
70 20 : }
71 : }
72 :
73 : impl FromFFI<ffi::MachO_Routine> for Routine<'_> {
74 20 : fn from_ffi(cmd: cxx::UniquePtr<ffi::MachO_Routine>) -> Self {
75 20 : Self {
76 20 : ptr: cmd,
77 20 : _owner: PhantomData
78 20 : }
79 20 : }
80 : }
81 :
82 : impl Command for Routine<'_> {
83 80 : fn get_base(&self) -> &ffi::MachO_Command {
84 80 : self.ptr.as_ref().unwrap().as_ref()
85 80 : }
86 : }
87 :
|