Line data Source code
1 : //! COFF section module
2 :
3 : use std::marker::PhantomData;
4 : use crate::common::into_optional;
5 : use crate::common::FromFFI;
6 : use crate::coff;
7 : use crate::generic;
8 : use crate::pe;
9 : use super::Relocation;
10 : use super::Symbol;
11 : use crate::declare_iterator;
12 :
13 : use lief_ffi as ffi;
14 :
15 : pub struct Section<'a> {
16 : ptr: cxx::UniquePtr<ffi::COFF_Section>,
17 : _owner: PhantomData<&'a ffi::COFF_Binary>,
18 : }
19 :
20 : impl FromFFI<ffi::COFF_Section> for Section<'_> {
21 23604 : fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Section>) -> Self {
22 23604 : Self {
23 23604 : ptr,
24 23604 : _owner: PhantomData,
25 23604 : }
26 23604 : }
27 : }
28 :
29 : impl Section<'_> {
30 : /// Return the size of the data in the section.
31 12420 : pub fn sizeof_raw_data(&self) -> u32 {
32 12420 : self.ptr.sizeof_raw_data()
33 12420 : }
34 :
35 : /// Return the size of the data when mapped in memory (should be 0)
36 12420 : pub fn virtual_size(&self) -> u32 {
37 12420 : self.ptr.virtual_size()
38 12420 : }
39 :
40 : /// Offset to the section's content
41 12420 : pub fn pointerto_raw_data(&self) -> u32 {
42 12420 : self.ptr.pointerto_raw_data()
43 12420 : }
44 :
45 : /// Offset to the relocation table
46 12420 : pub fn pointerto_relocation(&self) -> u32 {
47 12420 : self.ptr.pointerto_relocation()
48 12420 : }
49 :
50 : /// The file pointer to the beginning of line-number entries for the section.
51 : ///
52 : /// This is set to zero if there are no COFF line numbers.
53 : /// This value should be zero for an image because COFF debugging information
54 : /// is deprecated and modern debug information relies on the PDB files.
55 12420 : pub fn pointerto_line_numbers(&self) -> u32 {
56 12420 : self.ptr.pointerto_line_numbers()
57 12420 : }
58 :
59 : /// Number of relocations.
60 : ///
61 : /// <div class="warning">
62 : /// If the number of relocations is greater than 0xFFFF (maximum value for 16-bits integer),
63 : /// then the number of relocations is stored in the virtual address attribute.
64 : /// </div>
65 12420 : pub fn numberof_relocations(&self) -> u16 {
66 12420 : self.ptr.numberof_relocations()
67 12420 : }
68 :
69 : /// Number of line number entries (if any).
70 12420 : pub fn numberof_line_numbers(&self) -> u16 {
71 12420 : self.ptr.numberof_line_numbers()
72 12420 : }
73 :
74 : /// Characteristics of the section: it provides information about
75 : /// the permissions of the section when mapped. It can also provide
76 : /// information about the *purpose* of the section (contain code, BSS-like, ...)
77 12420 : pub fn characteristics(&self) -> pe::section::Characteristics {
78 12420 : pe::section::Characteristics::from(self.ptr.characteristics())
79 12420 : }
80 :
81 : /// True if the section can be discarded as needed.
82 : ///
83 : /// This is typically the case for debug-related sections
84 0 : pub fn is_discardable(&self) -> bool {
85 0 : self.ptr.is_discardable()
86 0 : }
87 :
88 : /// Whether there is a large number of relocations whose number need to be stored in the
89 : /// virtual address attribute
90 0 : pub fn has_extended_relocations(&self) -> bool {
91 0 : self.ptr.has_extended_relocations()
92 0 : }
93 :
94 : /// Iterator over the relocations associated with this section
95 4020 : pub fn relocations(&self) -> Relocations {
96 4020 : Relocations::new(self.ptr.relocations())
97 4020 : }
98 :
99 : /// Iterator over the symbols associated with this section
100 4020 : pub fn symbols(&self) -> Symbols {
101 4020 : Symbols::new(self.ptr.symbols())
102 4020 : }
103 :
104 : /// Return comdat infomration (only if the section has the
105 : /// [`crate::pe::section::Characteristics::LNK_COMDAT`] characteristic)
106 4020 : pub fn comdat_info(&self) -> Option<ComdatInfo> {
107 4020 : into_optional(self.ptr.comdat_info())
108 4020 : }
109 : }
110 :
111 : impl generic::Section for Section<'_> {
112 60864 : fn as_generic(&self) -> &ffi::AbstractSection {
113 60864 : self.ptr.as_ref().unwrap().as_ref()
114 60864 : }
115 : }
116 :
117 : impl std::fmt::Debug for Section<'_> {
118 12420 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 12420 : let base = self as &dyn generic::Section;
120 12420 : f.debug_struct("Section")
121 12420 : .field("base", &base)
122 12420 : .field("sizeof_raw_data", &self.sizeof_raw_data())
123 12420 : .field("virtual_size", &self.virtual_size())
124 12420 : .field("pointerto_raw_data", &self.pointerto_raw_data())
125 12420 : .field("pointerto_relocation", &self.pointerto_relocation())
126 12420 : .field("pointerto_line_numbers", &self.pointerto_line_numbers())
127 12420 : .field("numberof_relocations", &self.numberof_relocations())
128 12420 : .field("numberof_line_numbers", &self.numberof_line_numbers())
129 12420 : .field("characteristics", &self.characteristics())
130 12420 : .finish()
131 12420 : }
132 : }
133 :
134 : impl std::fmt::Display for Section<'_> {
135 12420 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
136 12420 : write!(f, "{}", self.ptr.to_string())
137 12420 : }
138 : }
139 :
140 : /// This structure wraps comdat information which is composed of the symbol
141 : /// associated with the comdat section and its selection flag
142 : pub struct ComdatInfo<'a> {
143 : ptr: cxx::UniquePtr<ffi::COFF_Section_ComdataInfo>,
144 : _owner: PhantomData<&'a ffi::COFF_Binary>,
145 : }
146 :
147 : impl ComdatInfo<'_> {
148 2580 : pub fn symbol(&self) -> Option<Symbol> {
149 2580 : into_optional(self.ptr.symbol())
150 2580 : }
151 :
152 2580 : pub fn kind(&self) -> coff::symbol::ComdatSelection {
153 2580 : coff::symbol::ComdatSelection::from(self.ptr.kind())
154 2580 : }
155 : }
156 :
157 : impl FromFFI<ffi::COFF_Section_ComdataInfo> for ComdatInfo<'_> {
158 2580 : fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Section_ComdataInfo>) -> Self {
159 2580 : Self {
160 2580 : ptr,
161 2580 : _owner: PhantomData,
162 2580 : }
163 2580 : }
164 : }
165 :
166 : impl std::fmt::Debug for ComdatInfo<'_> {
167 2580 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 2580 : f.debug_struct("ComdatInfo")
169 2580 : .field("symbol", &self.symbol())
170 2580 : .field("kind", &self.kind())
171 2580 : .finish()
172 2580 : }
173 : }
174 :
175 :
176 0 : declare_iterator!(
177 0 : Relocations,
178 0 : Relocation<'a>,
179 0 : ffi::COFF_Relocation,
180 0 : ffi::COFF_Section,
181 0 : ffi::COFF_Section_it_relocations
182 0 : );
183 :
184 :
185 8400 : declare_iterator!(
186 8400 : Symbols,
187 8400 : Symbol<'a>,
188 8400 : ffi::COFF_Symbol,
189 8400 : ffi::COFF_Section,
190 8400 : ffi::COFF_Section_it_symbols
191 8400 : );
|