Line data Source code
1 : use super::Command;
2 : use lief_ffi as ffi;
3 : use crate::common::FromFFI;
4 : use crate::declare_iterator;
5 : use std::marker::PhantomData;
6 : use crate::to_slice;
7 :
8 : use crate::macho::section::Section;
9 : use crate::macho::relocation::Relocation;
10 :
11 : /// Class which represents a `LC_SEGMENT/LC_SEGMENT_64` command
12 : pub struct Segment<'a> {
13 : ptr: cxx::UniquePtr<ffi::MachO_SegmentCommand>,
14 : _owner: PhantomData<&'a ffi::MachO_Binary>
15 : }
16 :
17 : impl Segment<'_> {
18 : /// Name of the segment (e.g. `__TEXT`)
19 204144 : pub fn name(&self) -> String {
20 204144 : self.ptr.name().to_string()
21 204144 : }
22 :
23 : /// Absolute virtual base address of the segment
24 204144 : pub fn virtual_address(&self) -> u64 {
25 204144 : self.ptr.virtual_address()
26 204144 : }
27 :
28 : /// Virtual size of the segment
29 204144 : pub fn virtual_size(&self) -> u64 {
30 204144 : self.ptr.virtual_size()
31 204144 : }
32 :
33 : /// Size of this segment in the binary file
34 204144 : pub fn file_size(&self) -> u64 {
35 204144 : self.ptr.file_size()
36 204144 : }
37 :
38 : /// Offset of the data of this segment in the file
39 204144 : pub fn file_offset(&self) -> u64 {
40 204144 : self.ptr.file_offset()
41 204144 : }
42 :
43 : /// The maximum of protections for this segment
44 204144 : pub fn max_protection(&self) -> u32 {
45 204144 : self.ptr.max_protection()
46 204144 : }
47 :
48 : /// The initial protections of this segment
49 204144 : pub fn init_protection(&self) -> u32 {
50 204144 : self.ptr.init_protection()
51 204144 : }
52 :
53 : /// The number of sections associated with this segment
54 204144 : pub fn numberof_sections(&self) -> u32 {
55 204144 : self.ptr.numberof_sections()
56 204144 : }
57 :
58 : /// Flags associated with this segment
59 204144 : pub fn flags(&self) -> u32 {
60 204144 : self.ptr.flags()
61 204144 : }
62 :
63 : /// The raw content of this segment as a slice of bytes
64 424 : pub fn content(&self) -> &[u8] {
65 424 : to_slice!(self.ptr.content());
66 424 : }
67 :
68 : /// Iterator over the [`crate::macho::Section`] owned by this segment
69 424 : pub fn sections(&self) -> Sections {
70 424 : Sections::new(self.ptr.sections())
71 424 : }
72 :
73 : /// Return an iterator over the [`crate::macho::Relocation`] linked to this segment
74 : ///
75 : /// For Mach-O executable or library this iterator should be empty as
76 : /// the relocations are managed by the Dyld's rebase opcodes.
77 : /// On the other hand, for object files (`.o`) this iterator should not be empty.
78 424 : pub fn relocations(&self) -> Relocations {
79 424 : Relocations::new(self.ptr.relocations())
80 424 : }
81 : }
82 :
83 : impl std::fmt::Debug for Segment<'_> {
84 204144 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 204144 : let base = self as &dyn Command;
86 204144 : f.debug_struct("Segment")
87 204144 : .field("base", &base)
88 204144 : .field("name", &self.name())
89 204144 : .field("virtual_address", &self.virtual_address())
90 204144 : .field("virtual_size", &self.virtual_size())
91 204144 : .field("file_size", &self.file_size())
92 204144 : .field("file_offset", &self.file_offset())
93 204144 : .field("max_protection", &self.max_protection())
94 204144 : .field("init_protection", &self.init_protection())
95 204144 : .field("numberof_sections", &self.numberof_sections())
96 204144 : .field("flags", &self.flags())
97 204144 : .finish()
98 204144 : }
99 : }
100 :
101 : impl FromFFI<ffi::MachO_SegmentCommand> for Segment<'_> {
102 204144 : fn from_ffi(cmd: cxx::UniquePtr<ffi::MachO_SegmentCommand>) -> Self {
103 204144 : Self {
104 204144 : ptr: cmd,
105 204144 : _owner: PhantomData
106 204144 : }
107 204144 : }
108 : }
109 :
110 : impl Command for Segment<'_> {
111 816576 : fn get_base(&self) -> &ffi::MachO_Command {
112 816576 : self.ptr.as_ref().unwrap().as_ref()
113 816576 : }
114 : }
115 :
116 424 : declare_iterator!(Segments, Segment<'a>, ffi::MachO_SegmentCommand, ffi::MachO_Binary, ffi::MachO_Binary_it_segments);
117 1848 : declare_iterator!(Sections, Section<'a>, ffi::MachO_Section, ffi::MachO_SegmentCommand, ffi::MachO_SegmentCommand_it_sections);
118 74944 : declare_iterator!(Relocations, Relocation<'a>, ffi::MachO_Relocation, ffi::MachO_SegmentCommand, ffi::MachO_SegmentCommand_it_relocations);
|