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 255180 : pub fn name(&self) -> String {
20 255180 : self.ptr.name().to_string()
21 255180 : }
22 :
23 : /// Absolute virtual base address of the segment
24 255180 : pub fn virtual_address(&self) -> u64 {
25 255180 : self.ptr.virtual_address()
26 255180 : }
27 :
28 : /// Virtual size of the segment
29 255180 : pub fn virtual_size(&self) -> u64 {
30 255180 : self.ptr.virtual_size()
31 255180 : }
32 :
33 : /// Size of this segment in the binary file
34 255180 : pub fn file_size(&self) -> u64 {
35 255180 : self.ptr.file_size()
36 255180 : }
37 :
38 : /// Offset of the data of this segment in the file
39 255180 : pub fn file_offset(&self) -> u64 {
40 255180 : self.ptr.file_offset()
41 255180 : }
42 :
43 : /// The maximum of protections for this segment
44 255180 : pub fn max_protection(&self) -> u32 {
45 255180 : self.ptr.max_protection()
46 255180 : }
47 :
48 : /// The initial protections of this segment
49 255180 : pub fn init_protection(&self) -> u32 {
50 255180 : self.ptr.init_protection()
51 255180 : }
52 :
53 : /// The number of sections associated with this segment
54 255180 : pub fn numberof_sections(&self) -> u32 {
55 255180 : self.ptr.numberof_sections()
56 255180 : }
57 :
58 : /// Flags associated with this segment
59 255180 : pub fn flags(&self) -> u32 {
60 255180 : self.ptr.flags()
61 255180 : }
62 :
63 : /// The raw content of this segment as a slice of bytes
64 530 : pub fn content(&self) -> &[u8] {
65 530 : to_slice!(self.ptr.content());
66 530 : }
67 :
68 : /// Iterator over the [`crate::macho::Section`] owned by this segment
69 530 : pub fn sections(&self) -> Sections {
70 530 : Sections::new(self.ptr.sections())
71 530 : }
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 530 : pub fn relocations(&self) -> Relocations {
79 530 : Relocations::new(self.ptr.relocations())
80 530 : }
81 : }
82 :
83 : impl std::fmt::Debug for Segment<'_> {
84 255180 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 255180 : let base = self as &dyn Command;
86 255180 : f.debug_struct("Segment")
87 255180 : .field("base", &base)
88 255180 : .field("name", &self.name())
89 255180 : .field("virtual_address", &self.virtual_address())
90 255180 : .field("virtual_size", &self.virtual_size())
91 255180 : .field("file_size", &self.file_size())
92 255180 : .field("file_offset", &self.file_offset())
93 255180 : .field("max_protection", &self.max_protection())
94 255180 : .field("init_protection", &self.init_protection())
95 255180 : .field("numberof_sections", &self.numberof_sections())
96 255180 : .field("flags", &self.flags())
97 255180 : .finish()
98 255180 : }
99 : }
100 :
101 : impl FromFFI<ffi::MachO_SegmentCommand> for Segment<'_> {
102 255180 : fn from_ffi(cmd: cxx::UniquePtr<ffi::MachO_SegmentCommand>) -> Self {
103 255180 : Self {
104 255180 : ptr: cmd,
105 255180 : _owner: PhantomData
106 255180 : }
107 255180 : }
108 : }
109 :
110 : impl Command for Segment<'_> {
111 1020720 : fn get_base(&self) -> &ffi::MachO_Command {
112 1020720 : self.ptr.as_ref().unwrap().as_ref()
113 1020720 : }
114 : }
115 :
116 530 : declare_iterator!(Segments, Segment<'a>, ffi::MachO_SegmentCommand, ffi::MachO_Binary, ffi::MachO_Binary_it_segments);
117 2310 : declare_iterator!(Sections, Section<'a>, ffi::MachO_Section, ffi::MachO_SegmentCommand, ffi::MachO_SegmentCommand_it_sections);
118 93680 : declare_iterator!(Relocations, Relocation<'a>, ffi::MachO_Relocation, ffi::MachO_SegmentCommand, ffi::MachO_SegmentCommand_it_relocations);
|