Line data Source code
1 : //! COFF relocation module
2 :
3 : use std::marker::PhantomData;
4 : use crate::common::{into_optional, FromFFI};
5 : use crate::generic;
6 : use super::{Section, Symbol};
7 :
8 : use lief_ffi as ffi;
9 :
10 : /// This class represents a COFF relocation
11 : pub struct Relocation<'a> {
12 : ptr: cxx::UniquePtr<ffi::COFF_Relocation>,
13 : _owner: PhantomData<&'a ffi::COFF_Binary>,
14 : }
15 :
16 : impl FromFFI<ffi::COFF_Relocation> for Relocation<'_> {
17 11184 : fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Relocation>) -> Self {
18 11184 : Relocation {
19 11184 : ptr,
20 11184 : _owner: PhantomData,
21 11184 : }
22 11184 : }
23 : }
24 :
25 : impl generic::Relocation for Relocation<'_> {
26 22368 : fn as_generic(&self) -> &ffi::AbstractRelocation {
27 22368 : self.ptr.as_ref().unwrap().as_ref()
28 22368 : }
29 : }
30 :
31 : impl Relocation<'_> {
32 : /// Symbol index associated with this relocation
33 11184 : pub fn symbol_idx(&self) -> u32 {
34 11184 : self.ptr.symbol_idx()
35 11184 : }
36 :
37 : /// Symbol associated with the relocation (if any)
38 11184 : pub fn symbol(&self) -> Option<Symbol> {
39 11184 : into_optional(self.ptr.symbol())
40 11184 : }
41 :
42 : /// Type of the relocation
43 11184 : pub fn get_type(&self) -> Type {
44 11184 : Type::from(self.ptr.get_type())
45 11184 : }
46 :
47 : /// Section in which the relocation takes place
48 11184 : pub fn section(&self) -> Option<Section> {
49 11184 : into_optional(self.ptr.section())
50 11184 : }
51 : }
52 :
53 : impl std::fmt::Debug for Relocation<'_> {
54 11184 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 11184 : let base = self as &dyn generic::Relocation;
56 11184 : f.debug_struct("Relocation")
57 11184 : .field("base", &base)
58 11184 : .field("symbol_idx", &self.symbol_idx())
59 11184 : .field("type", &self.get_type())
60 11184 : .finish()
61 11184 : }
62 : }
63 :
64 : impl std::fmt::Display for Relocation<'_> {
65 11184 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
66 11184 : write!(f, "{}", self.ptr.to_string())
67 11184 : }
68 : }
69 :
70 : #[allow(non_camel_case_types)]
71 11184 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
72 : pub enum Type {
73 : I386_ABSOLUTE,
74 : I386_DIR16,
75 : I386_REL16,
76 : I386_DIR32,
77 : I386_DIR32NB,
78 : I386_SEG12,
79 : I386_SECTION,
80 : I386_SECREL,
81 : I386_TOKEN,
82 : I386_SECREL7,
83 : I386_REL32,
84 : AMD64_ABSOLUTE,
85 : AMD64_ADDR64,
86 : AMD64_ADDR32,
87 : AMD64_ADDR32NB,
88 : AMD64_REL32,
89 : AMD64_REL32_1,
90 : AMD64_REL32_2,
91 : AMD64_REL32_3,
92 : AMD64_REL32_4,
93 : AMD64_REL32_5,
94 : AMD64_SECTION,
95 : AMD64_SECREL,
96 : AMD64_SECREL7,
97 : AMD64_TOKEN,
98 : AMD64_SREL32,
99 : AMD64_PAIR,
100 : AMD64_SSPAN32,
101 : ARM_ABSOLUTE,
102 : ARM_ADDR32,
103 : ARM_ADDR32NB,
104 : ARM_BRANCH24,
105 : ARM_BRANCH11,
106 : ARM_TOKEN,
107 : ARM_BLX24,
108 : ARM_BLX11,
109 : ARM_REL32,
110 : ARM_SECTION,
111 : ARM_SECREL,
112 : ARM_MOV32A,
113 : ARM_MOV32T,
114 : ARM_BRANCH20T,
115 : ARM_BRANCH24T,
116 : ARM_BLX23T,
117 : ARM_PAIR,
118 : ARM64_ABSOLUTE,
119 : ARM64_ADDR32,
120 : ARM64_ADDR32NB,
121 : ARM64_BRANCH26,
122 : ARM64_PAGEBASE_REL21,
123 : ARM64_REL21,
124 : ARM64_PAGEOFFSET_12A,
125 : ARM64_PAGEOFFSET_12L,
126 : ARM64_SECREL,
127 : ARM64_SECREL_LOW12A,
128 : ARM64_SECREL_HIGH12A,
129 : ARM64_SECREL_LOW12L,
130 : ARM64_TOKEN,
131 : ARM64_SECTION,
132 : ARM64_ADDR64,
133 : ARM64_BRANCH19,
134 : ARM64_BRANCH14,
135 : ARM64_REL32,
136 : MIPS_ABSOLUTE,
137 : MIPS_REFHALF,
138 : MIPS_REFWORD,
139 : MIPS_JMPADDR,
140 : MIPS_REFHI,
141 : MIPS_REFLO,
142 : MIPS_GPREL,
143 : MIPS_LITERAL,
144 : MIPS_SECTION,
145 : MIPS_SECREL,
146 : MIPS_SECRELLO,
147 : MIPS_SECRELHI,
148 : MIPS_JMPADDR16,
149 : MIPS_REFWORDNB,
150 : MIPS_PAIR,
151 : UNKNOWN(u32),
152 : }
153 :
154 : impl From<u32> for Type {
155 11184 : fn from(value: u32) -> Self {
156 11184 : match value {
157 0 : 0x00020000 => Type::I386_ABSOLUTE,
158 0 : 0x00020001 => Type::I386_DIR16,
159 0 : 0x00020002 => Type::I386_REL16,
160 0 : 0x00020006 => Type::I386_DIR32,
161 0 : 0x00020007 => Type::I386_DIR32NB,
162 0 : 0x00020009 => Type::I386_SEG12,
163 0 : 0x0002000a => Type::I386_SECTION,
164 0 : 0x0002000b => Type::I386_SECREL,
165 0 : 0x0002000c => Type::I386_TOKEN,
166 0 : 0x0002000d => Type::I386_SECREL7,
167 0 : 0x00020014 => Type::I386_REL32,
168 0 : 0x00040000 => Type::AMD64_ABSOLUTE,
169 312 : 0x00040001 => Type::AMD64_ADDR64,
170 0 : 0x00040002 => Type::AMD64_ADDR32,
171 3420 : 0x00040003 => Type::AMD64_ADDR32NB,
172 2268 : 0x00040004 => Type::AMD64_REL32,
173 0 : 0x00040005 => Type::AMD64_REL32_1,
174 0 : 0x00040006 => Type::AMD64_REL32_2,
175 0 : 0x00040007 => Type::AMD64_REL32_3,
176 0 : 0x00040008 => Type::AMD64_REL32_4,
177 0 : 0x00040009 => Type::AMD64_REL32_5,
178 1848 : 0x0004000a => Type::AMD64_SECTION,
179 1980 : 0x0004000b => Type::AMD64_SECREL,
180 0 : 0x0004000c => Type::AMD64_SECREL7,
181 60 : 0x0004000d => Type::AMD64_TOKEN,
182 0 : 0x0004000e => Type::AMD64_SREL32,
183 0 : 0x0004000f => Type::AMD64_PAIR,
184 0 : 0x00040010 => Type::AMD64_SSPAN32,
185 0 : 0x00080000 => Type::ARM_ABSOLUTE,
186 0 : 0x00080001 => Type::ARM_ADDR32,
187 0 : 0x00080002 => Type::ARM_ADDR32NB,
188 0 : 0x00080003 => Type::ARM_BRANCH24,
189 0 : 0x00080004 => Type::ARM_BRANCH11,
190 0 : 0x00080005 => Type::ARM_TOKEN,
191 0 : 0x00080008 => Type::ARM_BLX24,
192 0 : 0x00080009 => Type::ARM_BLX11,
193 0 : 0x0008000a => Type::ARM_REL32,
194 0 : 0x0008000e => Type::ARM_SECTION,
195 0 : 0x0008000f => Type::ARM_SECREL,
196 0 : 0x00080010 => Type::ARM_MOV32A,
197 0 : 0x00080011 => Type::ARM_MOV32T,
198 0 : 0x00080012 => Type::ARM_BRANCH20T,
199 0 : 0x00080014 => Type::ARM_BRANCH24T,
200 0 : 0x00080015 => Type::ARM_BLX23T,
201 0 : 0x00080016 => Type::ARM_PAIR,
202 0 : 0x00100000 => Type::ARM64_ABSOLUTE,
203 0 : 0x00100001 => Type::ARM64_ADDR32,
204 192 : 0x00100002 => Type::ARM64_ADDR32NB,
205 120 : 0x00100003 => Type::ARM64_BRANCH26,
206 144 : 0x00100004 => Type::ARM64_PAGEBASE_REL21,
207 0 : 0x00100005 => Type::ARM64_REL21,
208 72 : 0x00100006 => Type::ARM64_PAGEOFFSET_12A,
209 72 : 0x00100007 => Type::ARM64_PAGEOFFSET_12L,
210 288 : 0x00100008 => Type::ARM64_SECREL,
211 0 : 0x00100009 => Type::ARM64_SECREL_LOW12A,
212 0 : 0x0010000a => Type::ARM64_SECREL_HIGH12A,
213 0 : 0x0010000b => Type::ARM64_SECREL_LOW12L,
214 0 : 0x0010000c => Type::ARM64_TOKEN,
215 288 : 0x0010000d => Type::ARM64_SECTION,
216 120 : 0x0010000e => Type::ARM64_ADDR64,
217 0 : 0x0010000f => Type::ARM64_BRANCH19,
218 0 : 0x00100010 => Type::ARM64_BRANCH14,
219 0 : 0x00100011 => Type::ARM64_REL32,
220 0 : 0x00200000 => Type::MIPS_ABSOLUTE,
221 0 : 0x00200001 => Type::MIPS_REFHALF,
222 0 : 0x00200002 => Type::MIPS_REFWORD,
223 0 : 0x00200003 => Type::MIPS_JMPADDR,
224 0 : 0x00200004 => Type::MIPS_REFHI,
225 0 : 0x00200005 => Type::MIPS_REFLO,
226 0 : 0x00200006 => Type::MIPS_GPREL,
227 0 : 0x00200007 => Type::MIPS_LITERAL,
228 0 : 0x0020000a => Type::MIPS_SECTION,
229 0 : 0x0020000b => Type::MIPS_SECREL,
230 0 : 0x0020000c => Type::MIPS_SECRELLO,
231 0 : 0x0020000d => Type::MIPS_SECRELHI,
232 0 : 0x00200010 => Type::MIPS_JMPADDR16,
233 0 : 0x00200022 => Type::MIPS_REFWORDNB,
234 0 : 0x00200025 => Type::MIPS_PAIR,
235 0 : _ => Type::UNKNOWN(value),
236 :
237 : }
238 11184 : }
239 : }
240 :
241 : impl From<Type> for u32 {
242 0 : fn from(value: Type) -> u32 {
243 0 : match value {
244 0 : Type::I386_ABSOLUTE => 0x00020000,
245 0 : Type::I386_DIR16 => 0x00020001,
246 0 : Type::I386_REL16 => 0x00020002,
247 0 : Type::I386_DIR32 => 0x00020006,
248 0 : Type::I386_DIR32NB => 0x00020007,
249 0 : Type::I386_SEG12 => 0x00020009,
250 0 : Type::I386_SECTION => 0x0002000a,
251 0 : Type::I386_SECREL => 0x0002000b,
252 0 : Type::I386_TOKEN => 0x0002000c,
253 0 : Type::I386_SECREL7 => 0x0002000d,
254 0 : Type::I386_REL32 => 0x00020014,
255 0 : Type::AMD64_ABSOLUTE => 0x00040000,
256 0 : Type::AMD64_ADDR64 => 0x00040001,
257 0 : Type::AMD64_ADDR32 => 0x00040002,
258 0 : Type::AMD64_ADDR32NB => 0x00040003,
259 0 : Type::AMD64_REL32 => 0x00040004,
260 0 : Type::AMD64_REL32_1 => 0x00040005,
261 0 : Type::AMD64_REL32_2 => 0x00040006,
262 0 : Type::AMD64_REL32_3 => 0x00040007,
263 0 : Type::AMD64_REL32_4 => 0x00040008,
264 0 : Type::AMD64_REL32_5 => 0x00040009,
265 0 : Type::AMD64_SECTION => 0x0004000a,
266 0 : Type::AMD64_SECREL => 0x0004000b,
267 0 : Type::AMD64_SECREL7 => 0x0004000c,
268 0 : Type::AMD64_TOKEN => 0x0004000d,
269 0 : Type::AMD64_SREL32 => 0x0004000e,
270 0 : Type::AMD64_PAIR => 0x0004000f,
271 0 : Type::AMD64_SSPAN32 => 0x00040010,
272 0 : Type::ARM_ABSOLUTE => 0x00080000,
273 0 : Type::ARM_ADDR32 => 0x00080001,
274 0 : Type::ARM_ADDR32NB => 0x00080002,
275 0 : Type::ARM_BRANCH24 => 0x00080003,
276 0 : Type::ARM_BRANCH11 => 0x00080004,
277 0 : Type::ARM_TOKEN => 0x00080005,
278 0 : Type::ARM_BLX24 => 0x00080008,
279 0 : Type::ARM_BLX11 => 0x00080009,
280 0 : Type::ARM_REL32 => 0x0008000a,
281 0 : Type::ARM_SECTION => 0x0008000e,
282 0 : Type::ARM_SECREL => 0x0008000f,
283 0 : Type::ARM_MOV32A => 0x00080010,
284 0 : Type::ARM_MOV32T => 0x00080011,
285 0 : Type::ARM_BRANCH20T => 0x00080012,
286 0 : Type::ARM_BRANCH24T => 0x00080014,
287 0 : Type::ARM_BLX23T => 0x00080015,
288 0 : Type::ARM_PAIR => 0x00080016,
289 0 : Type::ARM64_ABSOLUTE => 0x00100000,
290 0 : Type::ARM64_ADDR32 => 0x00100001,
291 0 : Type::ARM64_ADDR32NB => 0x00100002,
292 0 : Type::ARM64_BRANCH26 => 0x00100003,
293 0 : Type::ARM64_PAGEBASE_REL21 => 0x00100004,
294 0 : Type::ARM64_REL21 => 0x00100005,
295 0 : Type::ARM64_PAGEOFFSET_12A => 0x00100006,
296 0 : Type::ARM64_PAGEOFFSET_12L => 0x00100007,
297 0 : Type::ARM64_SECREL => 0x00100008,
298 0 : Type::ARM64_SECREL_LOW12A => 0x00100009,
299 0 : Type::ARM64_SECREL_HIGH12A => 0x0010000a,
300 0 : Type::ARM64_SECREL_LOW12L => 0x0010000b,
301 0 : Type::ARM64_TOKEN => 0x0010000c,
302 0 : Type::ARM64_SECTION => 0x0010000d,
303 0 : Type::ARM64_ADDR64 => 0x0010000e,
304 0 : Type::ARM64_BRANCH19 => 0x0010000f,
305 0 : Type::ARM64_BRANCH14 => 0x00100010,
306 0 : Type::ARM64_REL32 => 0x00100011,
307 0 : Type::MIPS_ABSOLUTE => 0x00200000,
308 0 : Type::MIPS_REFHALF => 0x00200001,
309 0 : Type::MIPS_REFWORD => 0x00200002,
310 0 : Type::MIPS_JMPADDR => 0x00200003,
311 0 : Type::MIPS_REFHI => 0x00200004,
312 0 : Type::MIPS_REFLO => 0x00200005,
313 0 : Type::MIPS_GPREL => 0x00200006,
314 0 : Type::MIPS_LITERAL => 0x00200007,
315 0 : Type::MIPS_SECTION => 0x0020000a,
316 0 : Type::MIPS_SECREL => 0x0020000b,
317 0 : Type::MIPS_SECRELLO => 0x0020000c,
318 0 : Type::MIPS_SECRELHI => 0x0020000d,
319 0 : Type::MIPS_JMPADDR16 => 0x00200010,
320 0 : Type::MIPS_REFWORDNB => 0x00200022,
321 0 : Type::MIPS_PAIR => 0x00200025,
322 0 : Type::UNKNOWN(value) => value,
323 :
324 : }
325 0 : }
326 : }
327 :
|