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 information (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 : /// Return the COFF string associated with the section's name (or a None)
111 : ///
112 : /// This coff string is usually present for long section names whose length
113 : /// does not fit in the 8 bytes allocated by the COFF format.
114 0 : pub fn coff_string(&self) -> Option<coff::String> {
115 0 : into_optional(self.ptr.coff_string())
116 0 : }
117 : }
118 :
119 : impl generic::Section for Section<'_> {
120 60864 : fn as_generic(&self) -> &ffi::AbstractSection {
121 60864 : self.ptr.as_ref().unwrap().as_ref()
122 60864 : }
123 : }
124 :
125 : impl std::fmt::Debug for Section<'_> {
126 12420 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 12420 : let base = self as &dyn generic::Section;
128 12420 : f.debug_struct("Section")
129 12420 : .field("base", &base)
130 12420 : .field("sizeof_raw_data", &self.sizeof_raw_data())
131 12420 : .field("virtual_size", &self.virtual_size())
132 12420 : .field("pointerto_raw_data", &self.pointerto_raw_data())
133 12420 : .field("pointerto_relocation", &self.pointerto_relocation())
134 12420 : .field("pointerto_line_numbers", &self.pointerto_line_numbers())
135 12420 : .field("numberof_relocations", &self.numberof_relocations())
136 12420 : .field("numberof_line_numbers", &self.numberof_line_numbers())
137 12420 : .field("characteristics", &self.characteristics())
138 12420 : .finish()
139 12420 : }
140 : }
141 :
142 : impl std::fmt::Display for Section<'_> {
143 12420 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
144 12420 : write!(f, "{}", self.ptr.to_string())
145 12420 : }
146 : }
147 :
148 : /// This structure wraps comdat information which is composed of the symbol
149 : /// associated with the comdat section and its selection flag
150 : pub struct ComdatInfo<'a> {
151 : ptr: cxx::UniquePtr<ffi::COFF_Section_ComdataInfo>,
152 : _owner: PhantomData<&'a ffi::COFF_Binary>,
153 : }
154 :
155 : impl ComdatInfo<'_> {
156 2580 : pub fn symbol(&self) -> Option<Symbol> {
157 2580 : into_optional(self.ptr.symbol())
158 2580 : }
159 :
160 2580 : pub fn kind(&self) -> coff::symbol::ComdatSelection {
161 2580 : coff::symbol::ComdatSelection::from(self.ptr.kind())
162 2580 : }
163 : }
164 :
165 : impl FromFFI<ffi::COFF_Section_ComdataInfo> for ComdatInfo<'_> {
166 2580 : fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Section_ComdataInfo>) -> Self {
167 2580 : Self {
168 2580 : ptr,
169 2580 : _owner: PhantomData,
170 2580 : }
171 2580 : }
172 : }
173 :
174 : impl std::fmt::Debug for ComdatInfo<'_> {
175 2580 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176 2580 : f.debug_struct("ComdatInfo")
177 2580 : .field("symbol", &self.symbol())
178 2580 : .field("kind", &self.kind())
179 2580 : .finish()
180 2580 : }
181 : }
182 :
183 :
184 0 : declare_iterator!(
185 0 : Relocations,
186 0 : Relocation<'a>,
187 0 : ffi::COFF_Relocation,
188 0 : ffi::COFF_Section,
189 0 : ffi::COFF_Section_it_relocations
190 0 : );
191 :
192 :
193 8400 : declare_iterator!(
194 8400 : Symbols,
195 8400 : Symbol<'a>,
196 8400 : ffi::COFF_Symbol,
197 8400 : ffi::COFF_Section,
198 8400 : ffi::COFF_Section_it_symbols
199 8400 : );
|