Line data Source code
1 : use super::Command;
2 : use crate::common::FromFFI;
3 : use crate::macho::Symbol;
4 : use lief_ffi as ffi;
5 : use std::marker::PhantomData;
6 :
7 : use crate::declare_iterator;
8 :
9 : /// Structure that represents the `LC_DYSYMTAB` command.
10 : ///
11 : /// This command completes the `LC_SYMTAB` to provide
12 : /// a better granularity over the symbols layout.
13 : pub struct DynamicSymbolCommand<'a> {
14 : ptr: cxx::UniquePtr<ffi::MachO_DynamicSymbolCommand>,
15 : _owner: PhantomData<&'a ffi::MachO_Binary>,
16 : }
17 :
18 : impl DynamicSymbolCommand<'_> {
19 : /// Index of the first symbol in the group of local symbols.
20 336 : pub fn idx_local_symbol(&self) -> u32 {
21 336 : self.ptr.idx_local_symbol()
22 336 : }
23 :
24 : /// Number of symbols in the group of local symbols.
25 336 : pub fn nb_local_symbols(&self) -> u32 {
26 336 : self.ptr.nb_local_symbols()
27 336 : }
28 :
29 : /// Index of the first symbol in the group of defined external symbols.
30 336 : pub fn idx_external_define_symbol(&self) -> u32 {
31 336 : self.ptr.idx_external_define_symbol()
32 336 : }
33 :
34 : /// Number of symbols in the group of defined external symbols.
35 336 : pub fn nb_external_define_symbols(&self) -> u32 {
36 336 : self.ptr.nb_external_define_symbols()
37 336 : }
38 :
39 : /// Index of the first symbol in the group of undefined external symbols.
40 336 : pub fn idx_undefined_symbol(&self) -> u32 {
41 336 : self.ptr.idx_undefined_symbol()
42 336 : }
43 :
44 : /// Number of symbols in the group of undefined external symbols.
45 336 : pub fn nb_undefined_symbols(&self) -> u32 {
46 336 : self.ptr.nb_undefined_symbols()
47 336 : }
48 :
49 : /// Byte offset from the start of the file to the table of contents data
50 : ///
51 : /// Table of content is used by legacy Mach-O loader and this field should be
52 : /// set to 0
53 336 : pub fn toc_offset(&self) -> u32 {
54 336 : self.ptr.toc_offset()
55 336 : }
56 :
57 : /// Number of entries in the table of contents.
58 : ///
59 : /// Should be set to 0 on recent Mach-O
60 336 : pub fn nb_toc(&self) -> u32 {
61 336 : self.ptr.nb_toc()
62 336 : }
63 :
64 : /// Byte offset from the start of the file to the module table data.
65 : ///
66 : /// This field seems unused by recent Mach-O loader and should be set to 0
67 336 : pub fn module_table_offset(&self) -> u32 {
68 336 : self.ptr.module_table_offset()
69 336 : }
70 :
71 : /// Number of entries in the module table.
72 : ///
73 : /// This field seems unused by recent Mach-O loader and should be set to 0
74 336 : pub fn nb_module_table(&self) -> u32 {
75 336 : self.ptr.nb_module_table()
76 336 : }
77 :
78 : /// Byte offset from the start of the file to the external reference table data.
79 : ///
80 : /// This field seems unused by recent Mach-O loader and should be set to 0
81 336 : pub fn external_reference_symbol_offset(&self) -> u32 {
82 336 : self.ptr.external_reference_symbol_offset()
83 336 : }
84 :
85 : /// Number of entries in the external reference table
86 : ///
87 : /// This field seems unused by recent Mach-O loader and should be set to 0
88 336 : pub fn nb_external_reference_symbols(&self) -> u32 {
89 336 : self.ptr.nb_external_reference_symbols()
90 336 : }
91 :
92 : /// Byte offset from the start of the file to the indirect symbol table data.
93 : ///
94 : /// Indirect symbol table is used by the loader to speed-up symbol resolution during
95 : /// the *lazy binding* process
96 : ///
97 : /// References:
98 : /// * dyld-519.2.1/src/ImageLoaderMachOCompressed.cpp
99 : /// * dyld-519.2.1/src/ImageLoaderMachOClassic.cpp
100 336 : pub fn indirect_symbol_offset(&self) -> u32 {
101 336 : self.ptr.indirect_symbol_offset()
102 336 : }
103 :
104 : /// Number of entries in the indirect symbol table.
105 336 : pub fn nb_indirect_symbols(&self) -> u32 {
106 336 : self.ptr.nb_indirect_symbols()
107 336 : }
108 :
109 : /// Byte offset from the start of the file to the external relocation table data.
110 : ///
111 : /// This field seems unused by recent Mach-O loader and should be set to 0
112 336 : pub fn external_relocation_offset(&self) -> u32 {
113 336 : self.ptr.external_relocation_offset()
114 336 : }
115 :
116 : /// Number of entries in the external relocation table.
117 : ///
118 : /// This field seems unused by recent Mach-O loader and should be set to 0
119 336 : pub fn nb_external_relocations(&self) -> u32 {
120 336 : self.ptr.nb_external_relocations()
121 336 : }
122 :
123 : /// Byte offset from the start of the file to the local relocation table data.
124 : ///
125 : /// This field seems unused by recent Mach-O loader and should be set to 0
126 336 : pub fn local_relocation_offset(&self) -> u32 {
127 336 : self.ptr.local_relocation_offset()
128 336 : }
129 :
130 : /// Number of entries in the local relocation table.
131 : ///
132 : /// This field seems unused by recent Mach-O loader and should be set to 0
133 336 : pub fn nb_local_relocations(&self) -> u32 {
134 336 : self.ptr.nb_local_relocations()
135 336 : }
136 :
137 : /// Iterator over the indirect symbols indexed by this command
138 168 : pub fn indirect_symbols(&self) -> IndirectSymbols {
139 168 : IndirectSymbols::new(self.ptr.indirect_symbols())
140 168 : }
141 : }
142 :
143 : impl std::fmt::Debug for DynamicSymbolCommand<'_> {
144 336 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 336 : let base = self as &dyn Command;
146 336 : f.debug_struct("DynamicSymbolCommand")
147 336 : .field("base", &base)
148 336 : .field("idx_local_symbol", &self.idx_local_symbol())
149 336 : .field("nb_local_symbols", &self.nb_local_symbols())
150 336 : .field(
151 336 : "idx_external_define_symbol",
152 336 : &self.idx_external_define_symbol(),
153 336 : )
154 336 : .field(
155 336 : "nb_external_define_symbols",
156 336 : &self.nb_external_define_symbols(),
157 336 : )
158 336 : .field("idx_undefined_symbol", &self.idx_undefined_symbol())
159 336 : .field("nb_undefined_symbols", &self.nb_undefined_symbols())
160 336 : .field("toc_offset", &self.toc_offset())
161 336 : .field("nb_toc", &self.nb_toc())
162 336 : .field("module_table_offset", &self.module_table_offset())
163 336 : .field("nb_module_table", &self.nb_module_table())
164 336 : .field(
165 336 : "external_reference_symbol_offset",
166 336 : &self.external_reference_symbol_offset(),
167 336 : )
168 336 : .field(
169 336 : "nb_external_reference_symbols",
170 336 : &self.nb_external_reference_symbols(),
171 336 : )
172 336 : .field("indirect_symbol_offset", &self.indirect_symbol_offset())
173 336 : .field("nb_indirect_symbols", &self.nb_indirect_symbols())
174 336 : .field(
175 336 : "external_relocation_offset",
176 336 : &self.external_relocation_offset(),
177 336 : )
178 336 : .field("nb_external_relocations", &self.nb_external_relocations())
179 336 : .field("local_relocation_offset", &self.local_relocation_offset())
180 336 : .field("nb_local_relocations", &self.nb_local_relocations())
181 336 : .finish()
182 336 : }
183 : }
184 :
185 : impl FromFFI<ffi::MachO_DynamicSymbolCommand> for DynamicSymbolCommand<'_> {
186 336 : fn from_ffi(cmd: cxx::UniquePtr<ffi::MachO_DynamicSymbolCommand>) -> Self {
187 336 : Self {
188 336 : ptr: cmd,
189 336 : _owner: PhantomData,
190 336 : }
191 336 : }
192 : }
193 :
194 : impl Command for DynamicSymbolCommand<'_> {
195 1344 : fn get_base(&self) -> &ffi::MachO_Command {
196 1344 : self.ptr.as_ref().unwrap().as_ref()
197 1344 : }
198 : }
199 :
200 50496 : declare_iterator!(
201 50496 : IndirectSymbols,
202 50496 : Symbol<'a>,
203 50496 : ffi::MachO_Symbol,
204 50496 : ffi::MachO_DynamicSymbolCommand,
205 50496 : ffi::MachO_DynamicSymbolCommand_it_indirect_symbols
206 50496 : );
|