]>
Commit | Line | Data |
---|---|---|
17df50a5 XL |
1 | use alloc::fmt; |
2 | use alloc::vec::Vec; | |
3 | use core::fmt::Debug; | |
4 | use core::slice; | |
5 | ||
6 | use crate::elf; | |
7 | use crate::endian::{self, Endianness}; | |
8 | use crate::pod::Pod; | |
9 | use crate::read::{ | |
10 | self, Error, ReadRef, Relocation, RelocationEncoding, RelocationKind, RelocationTarget, | |
11 | SymbolIndex, | |
12 | }; | |
13 | ||
14 | use super::{ElfFile, FileHeader, SectionHeader, SectionTable}; | |
15 | ||
16 | /// A mapping from section index to associated relocation sections. | |
17 | #[derive(Debug)] | |
18 | pub struct RelocationSections { | |
19 | relocations: Vec<usize>, | |
20 | } | |
21 | ||
22 | impl RelocationSections { | |
23 | /// Create a new mapping using the section table. | |
24 | /// | |
25 | /// Skips relocation sections that do not use the given symbol table section. | |
136023e0 | 26 | pub fn parse<'data, Elf: FileHeader, R: ReadRef<'data>>( |
17df50a5 | 27 | endian: Elf::Endian, |
136023e0 | 28 | sections: &SectionTable<'data, Elf, R>, |
17df50a5 XL |
29 | symbol_section: usize, |
30 | ) -> read::Result<Self> { | |
31 | let mut relocations = vec![0; sections.len()]; | |
32 | for (index, section) in sections.iter().enumerate().rev() { | |
33 | let sh_type = section.sh_type(endian); | |
34 | if sh_type == elf::SHT_REL || sh_type == elf::SHT_RELA { | |
35 | // The symbol indices used in relocations must be for the symbol table | |
36 | // we are expecting to use. | |
37 | let sh_link = section.sh_link(endian) as usize; | |
38 | if sh_link != symbol_section { | |
39 | continue; | |
40 | } | |
41 | ||
42 | let sh_info = section.sh_info(endian) as usize; | |
43 | if sh_info == 0 { | |
44 | // Skip dynamic relocations. | |
45 | continue; | |
46 | } | |
47 | if sh_info >= relocations.len() { | |
48 | return Err(Error("Invalid ELF sh_info for relocation section")); | |
49 | } | |
50 | ||
51 | // Handle multiple relocation sections by chaining them. | |
52 | let next = relocations[sh_info]; | |
53 | relocations[sh_info] = index; | |
54 | relocations[index] = next; | |
55 | } | |
56 | } | |
57 | Ok(Self { relocations }) | |
58 | } | |
59 | ||
60 | /// Given a section index, return the section index of the associated relocation section. | |
61 | /// | |
62 | /// This may also be called with a relocation section index, and it will return the | |
63 | /// next associated relocation section. | |
64 | pub fn get(&self, index: usize) -> Option<usize> { | |
65 | self.relocations.get(index).cloned().filter(|x| *x != 0) | |
66 | } | |
67 | } | |
68 | ||
69 | pub(super) enum ElfRelaIterator<'data, Elf: FileHeader> { | |
70 | Rel(slice::Iter<'data, Elf::Rel>), | |
71 | Rela(slice::Iter<'data, Elf::Rela>), | |
72 | } | |
73 | ||
74 | impl<'data, Elf: FileHeader> ElfRelaIterator<'data, Elf> { | |
75 | fn is_rel(&self) -> bool { | |
76 | match self { | |
77 | ElfRelaIterator::Rel(_) => true, | |
78 | ElfRelaIterator::Rela(_) => false, | |
79 | } | |
80 | } | |
81 | } | |
82 | ||
83 | impl<'data, Elf: FileHeader> Iterator for ElfRelaIterator<'data, Elf> { | |
84 | type Item = Elf::Rela; | |
85 | ||
86 | fn next(&mut self) -> Option<Self::Item> { | |
87 | match self { | |
88 | ElfRelaIterator::Rel(ref mut i) => i.next().cloned().map(Self::Item::from), | |
89 | ElfRelaIterator::Rela(ref mut i) => i.next().cloned(), | |
90 | } | |
91 | } | |
92 | } | |
93 | ||
94 | /// An iterator over the dynamic relocations for an `ElfFile32`. | |
95 | pub type ElfDynamicRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = | |
96 | ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>; | |
97 | /// An iterator over the dynamic relocations for an `ElfFile64`. | |
98 | pub type ElfDynamicRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = | |
99 | ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>; | |
100 | ||
101 | /// An iterator over the dynamic relocations for an `ElfFile`. | |
102 | pub struct ElfDynamicRelocationIterator<'data, 'file, Elf, R = &'data [u8]> | |
103 | where | |
104 | Elf: FileHeader, | |
105 | R: ReadRef<'data>, | |
106 | { | |
107 | /// The current relocation section index. | |
108 | pub(super) section_index: usize, | |
109 | pub(super) file: &'file ElfFile<'data, Elf, R>, | |
110 | pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>, | |
111 | } | |
112 | ||
113 | impl<'data, 'file, Elf, R> Iterator for ElfDynamicRelocationIterator<'data, 'file, Elf, R> | |
114 | where | |
115 | Elf: FileHeader, | |
116 | R: ReadRef<'data>, | |
117 | { | |
118 | type Item = (u64, Relocation); | |
119 | ||
120 | fn next(&mut self) -> Option<Self::Item> { | |
121 | let endian = self.file.endian; | |
122 | loop { | |
123 | if let Some(ref mut relocations) = self.relocations { | |
124 | if let Some(reloc) = relocations.next() { | |
125 | let relocation = | |
126 | parse_relocation(self.file.header, endian, reloc, relocations.is_rel()); | |
127 | return Some((reloc.r_offset(endian).into(), relocation)); | |
128 | } | |
129 | self.relocations = None; | |
130 | } | |
131 | ||
132 | let section = self.file.sections.section(self.section_index).ok()?; | |
133 | self.section_index += 1; | |
134 | ||
135 | let sh_link = section.sh_link(endian) as usize; | |
136 | if sh_link != self.file.dynamic_symbols.section() { | |
137 | continue; | |
138 | } | |
139 | ||
140 | match section.sh_type(endian) { | |
141 | elf::SHT_REL => { | |
142 | if let Ok(relocations) = section.data_as_array(endian, self.file.data) { | |
143 | self.relocations = Some(ElfRelaIterator::Rel(relocations.iter())); | |
144 | } | |
145 | } | |
146 | elf::SHT_RELA => { | |
147 | if let Ok(relocations) = section.data_as_array(endian, self.file.data) { | |
148 | self.relocations = Some(ElfRelaIterator::Rela(relocations.iter())); | |
149 | } | |
150 | } | |
151 | _ => {} | |
152 | } | |
153 | } | |
154 | } | |
155 | } | |
156 | ||
157 | impl<'data, 'file, Elf, R> fmt::Debug for ElfDynamicRelocationIterator<'data, 'file, Elf, R> | |
158 | where | |
159 | Elf: FileHeader, | |
160 | R: ReadRef<'data>, | |
161 | { | |
162 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
163 | f.debug_struct("ElfDynamicRelocationIterator").finish() | |
164 | } | |
165 | } | |
166 | ||
167 | /// An iterator over the relocations for an `ElfSection32`. | |
168 | pub type ElfSectionRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = | |
169 | ElfSectionRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>; | |
170 | /// An iterator over the relocations for an `ElfSection64`. | |
171 | pub type ElfSectionRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = | |
172 | ElfSectionRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>; | |
173 | ||
174 | /// An iterator over the relocations for an `ElfSection`. | |
175 | pub struct ElfSectionRelocationIterator<'data, 'file, Elf, R = &'data [u8]> | |
176 | where | |
177 | Elf: FileHeader, | |
178 | R: ReadRef<'data>, | |
179 | { | |
180 | /// The current pointer in the chain of relocation sections. | |
181 | pub(super) section_index: usize, | |
182 | pub(super) file: &'file ElfFile<'data, Elf, R>, | |
183 | pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>, | |
184 | } | |
185 | ||
186 | impl<'data, 'file, Elf, R> Iterator for ElfSectionRelocationIterator<'data, 'file, Elf, R> | |
187 | where | |
188 | Elf: FileHeader, | |
189 | R: ReadRef<'data>, | |
190 | { | |
191 | type Item = (u64, Relocation); | |
192 | ||
193 | fn next(&mut self) -> Option<Self::Item> { | |
194 | let endian = self.file.endian; | |
195 | loop { | |
196 | if let Some(ref mut relocations) = self.relocations { | |
197 | if let Some(reloc) = relocations.next() { | |
198 | let relocation = | |
199 | parse_relocation(self.file.header, endian, reloc, relocations.is_rel()); | |
200 | return Some((reloc.r_offset(endian).into(), relocation)); | |
201 | } | |
202 | self.relocations = None; | |
203 | } | |
204 | self.section_index = self.file.relocations.get(self.section_index)?; | |
205 | // The construction of RelocationSections ensures section_index is valid. | |
206 | let section = self.file.sections.section(self.section_index).unwrap(); | |
207 | match section.sh_type(endian) { | |
208 | elf::SHT_REL => { | |
209 | if let Ok(relocations) = section.data_as_array(endian, self.file.data) { | |
210 | self.relocations = Some(ElfRelaIterator::Rel(relocations.iter())); | |
211 | } | |
212 | } | |
213 | elf::SHT_RELA => { | |
214 | if let Ok(relocations) = section.data_as_array(endian, self.file.data) { | |
215 | self.relocations = Some(ElfRelaIterator::Rela(relocations.iter())); | |
216 | } | |
217 | } | |
218 | _ => {} | |
219 | } | |
220 | } | |
221 | } | |
222 | } | |
223 | ||
224 | impl<'data, 'file, Elf, R> fmt::Debug for ElfSectionRelocationIterator<'data, 'file, Elf, R> | |
225 | where | |
226 | Elf: FileHeader, | |
227 | R: ReadRef<'data>, | |
228 | { | |
229 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
230 | f.debug_struct("ElfSectionRelocationIterator").finish() | |
231 | } | |
232 | } | |
233 | ||
234 | fn parse_relocation<Elf: FileHeader>( | |
235 | header: &Elf, | |
236 | endian: Elf::Endian, | |
237 | reloc: Elf::Rela, | |
238 | implicit_addend: bool, | |
239 | ) -> Relocation { | |
240 | let mut encoding = RelocationEncoding::Generic; | |
241 | let is_mips64el = header.is_mips64el(endian); | |
242 | let (kind, size) = match header.e_machine(endian) { | |
243 | elf::EM_AARCH64 => match reloc.r_type(endian, false) { | |
244 | elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64), | |
245 | elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32), | |
246 | elf::R_AARCH64_ABS16 => (RelocationKind::Absolute, 16), | |
247 | elf::R_AARCH64_PREL64 => (RelocationKind::Relative, 64), | |
248 | elf::R_AARCH64_PREL32 => (RelocationKind::Relative, 32), | |
249 | elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16), | |
136023e0 XL |
250 | elf::R_AARCH64_CALL26 => { |
251 | encoding = RelocationEncoding::AArch64Call; | |
252 | (RelocationKind::PltRelative, 26) | |
253 | } | |
17df50a5 XL |
254 | r_type => (RelocationKind::Elf(r_type), 0), |
255 | }, | |
256 | elf::EM_ARM => match reloc.r_type(endian, false) { | |
257 | elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32), | |
258 | r_type => (RelocationKind::Elf(r_type), 0), | |
259 | }, | |
260 | elf::EM_AVR => match reloc.r_type(endian, false) { | |
261 | elf::R_AVR_32 => (RelocationKind::Absolute, 32), | |
262 | elf::R_AVR_16 => (RelocationKind::Absolute, 16), | |
263 | r_type => (RelocationKind::Elf(r_type), 0), | |
264 | }, | |
265 | elf::EM_BPF => match reloc.r_type(endian, false) { | |
266 | elf::R_BPF_64_64 => (RelocationKind::Absolute, 64), | |
267 | elf::R_BPF_64_32 => (RelocationKind::Absolute, 32), | |
268 | r_type => (RelocationKind::Elf(r_type), 0), | |
269 | }, | |
270 | elf::EM_386 => match reloc.r_type(endian, false) { | |
271 | elf::R_386_32 => (RelocationKind::Absolute, 32), | |
272 | elf::R_386_PC32 => (RelocationKind::Relative, 32), | |
273 | elf::R_386_GOT32 => (RelocationKind::Got, 32), | |
274 | elf::R_386_PLT32 => (RelocationKind::PltRelative, 32), | |
275 | elf::R_386_GOTOFF => (RelocationKind::GotBaseOffset, 32), | |
276 | elf::R_386_GOTPC => (RelocationKind::GotBaseRelative, 32), | |
277 | elf::R_386_16 => (RelocationKind::Absolute, 16), | |
278 | elf::R_386_PC16 => (RelocationKind::Relative, 16), | |
279 | elf::R_386_8 => (RelocationKind::Absolute, 8), | |
280 | elf::R_386_PC8 => (RelocationKind::Relative, 8), | |
281 | r_type => (RelocationKind::Elf(r_type), 0), | |
282 | }, | |
283 | elf::EM_X86_64 => match reloc.r_type(endian, false) { | |
284 | elf::R_X86_64_64 => (RelocationKind::Absolute, 64), | |
285 | elf::R_X86_64_PC32 => (RelocationKind::Relative, 32), | |
286 | elf::R_X86_64_GOT32 => (RelocationKind::Got, 32), | |
287 | elf::R_X86_64_PLT32 => (RelocationKind::PltRelative, 32), | |
288 | elf::R_X86_64_GOTPCREL => (RelocationKind::GotRelative, 32), | |
289 | elf::R_X86_64_32 => (RelocationKind::Absolute, 32), | |
290 | elf::R_X86_64_32S => { | |
291 | encoding = RelocationEncoding::X86Signed; | |
292 | (RelocationKind::Absolute, 32) | |
293 | } | |
294 | elf::R_X86_64_16 => (RelocationKind::Absolute, 16), | |
295 | elf::R_X86_64_PC16 => (RelocationKind::Relative, 16), | |
296 | elf::R_X86_64_8 => (RelocationKind::Absolute, 8), | |
297 | elf::R_X86_64_PC8 => (RelocationKind::Relative, 8), | |
298 | r_type => (RelocationKind::Elf(r_type), 0), | |
299 | }, | |
300 | elf::EM_HEXAGON => match reloc.r_type(endian, false) { | |
301 | elf::R_HEX_32 => (RelocationKind::Absolute, 32), | |
302 | r_type => (RelocationKind::Elf(r_type), 0), | |
303 | }, | |
304 | elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) { | |
305 | elf::R_MIPS_16 => (RelocationKind::Absolute, 16), | |
306 | elf::R_MIPS_32 => (RelocationKind::Absolute, 32), | |
307 | elf::R_MIPS_64 => (RelocationKind::Absolute, 64), | |
308 | r_type => (RelocationKind::Elf(r_type), 0), | |
309 | }, | |
310 | elf::EM_MSP430 => match reloc.r_type(endian, false) { | |
311 | elf::R_MSP430_32 => (RelocationKind::Absolute, 32), | |
312 | elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16), | |
313 | r_type => (RelocationKind::Elf(r_type), 0), | |
314 | }, | |
315 | elf::EM_PPC => match reloc.r_type(endian, false) { | |
316 | elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32), | |
317 | r_type => (RelocationKind::Elf(r_type), 0), | |
318 | }, | |
319 | elf::EM_PPC64 => match reloc.r_type(endian, false) { | |
320 | elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32), | |
321 | elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64), | |
322 | r_type => (RelocationKind::Elf(r_type), 0), | |
323 | }, | |
324 | elf::EM_RISCV => match reloc.r_type(endian, false) { | |
325 | elf::R_RISCV_32 => (RelocationKind::Absolute, 32), | |
326 | elf::R_RISCV_64 => (RelocationKind::Absolute, 64), | |
327 | r_type => (RelocationKind::Elf(r_type), 0), | |
328 | }, | |
329 | elf::EM_S390 => match reloc.r_type(endian, false) { | |
330 | elf::R_390_8 => (RelocationKind::Absolute, 8), | |
331 | elf::R_390_16 => (RelocationKind::Absolute, 16), | |
332 | elf::R_390_32 => (RelocationKind::Absolute, 32), | |
333 | elf::R_390_64 => (RelocationKind::Absolute, 64), | |
334 | elf::R_390_PC16 => (RelocationKind::Relative, 16), | |
335 | elf::R_390_PC32 => (RelocationKind::Relative, 32), | |
336 | elf::R_390_PC64 => (RelocationKind::Relative, 64), | |
337 | elf::R_390_PC16DBL => { | |
338 | encoding = RelocationEncoding::S390xDbl; | |
339 | (RelocationKind::Relative, 16) | |
340 | } | |
341 | elf::R_390_PC32DBL => { | |
342 | encoding = RelocationEncoding::S390xDbl; | |
343 | (RelocationKind::Relative, 32) | |
344 | } | |
345 | elf::R_390_PLT16DBL => { | |
346 | encoding = RelocationEncoding::S390xDbl; | |
347 | (RelocationKind::PltRelative, 16) | |
348 | } | |
349 | elf::R_390_PLT32DBL => { | |
350 | encoding = RelocationEncoding::S390xDbl; | |
351 | (RelocationKind::PltRelative, 32) | |
352 | } | |
353 | elf::R_390_GOT16 => (RelocationKind::Got, 16), | |
354 | elf::R_390_GOT32 => (RelocationKind::Got, 32), | |
355 | elf::R_390_GOT64 => (RelocationKind::Got, 64), | |
356 | elf::R_390_GOTENT => { | |
357 | encoding = RelocationEncoding::S390xDbl; | |
358 | (RelocationKind::GotRelative, 32) | |
359 | } | |
360 | elf::R_390_GOTOFF16 => (RelocationKind::GotBaseOffset, 16), | |
361 | elf::R_390_GOTOFF32 => (RelocationKind::GotBaseOffset, 32), | |
362 | elf::R_390_GOTOFF64 => (RelocationKind::GotBaseOffset, 64), | |
363 | elf::R_390_GOTPC => (RelocationKind::GotBaseRelative, 64), | |
364 | elf::R_390_GOTPCDBL => { | |
365 | encoding = RelocationEncoding::S390xDbl; | |
366 | (RelocationKind::GotBaseRelative, 32) | |
367 | } | |
368 | r_type => (RelocationKind::Elf(r_type), 0), | |
369 | }, | |
370 | elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => { | |
371 | match reloc.r_type(endian, false) { | |
372 | elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32), | |
373 | elf::R_SPARC_64 | elf::R_SPARC_UA64 => (RelocationKind::Absolute, 64), | |
374 | r_type => (RelocationKind::Elf(r_type), 0), | |
375 | } | |
376 | } | |
377 | _ => (RelocationKind::Elf(reloc.r_type(endian, false)), 0), | |
378 | }; | |
379 | let sym = reloc.r_sym(endian, is_mips64el) as usize; | |
380 | let target = if sym == 0 { | |
381 | RelocationTarget::Absolute | |
382 | } else { | |
383 | RelocationTarget::Symbol(SymbolIndex(sym)) | |
384 | }; | |
385 | Relocation { | |
386 | kind, | |
387 | encoding, | |
388 | size, | |
389 | target, | |
390 | addend: reloc.r_addend(endian).into(), | |
391 | implicit_addend, | |
392 | } | |
393 | } | |
394 | ||
395 | /// A trait for generic access to `Rel32` and `Rel64`. | |
396 | #[allow(missing_docs)] | |
397 | pub trait Rel: Debug + Pod + Clone { | |
398 | type Word: Into<u64>; | |
399 | type Sword: Into<i64>; | |
400 | type Endian: endian::Endian; | |
401 | ||
402 | fn r_offset(&self, endian: Self::Endian) -> Self::Word; | |
403 | fn r_info(&self, endian: Self::Endian) -> Self::Word; | |
404 | fn r_sym(&self, endian: Self::Endian) -> u32; | |
405 | fn r_type(&self, endian: Self::Endian) -> u32; | |
406 | } | |
407 | ||
408 | impl<Endian: endian::Endian> Rel for elf::Rel32<Endian> { | |
409 | type Word = u32; | |
410 | type Sword = i32; | |
411 | type Endian = Endian; | |
412 | ||
413 | #[inline] | |
414 | fn r_offset(&self, endian: Self::Endian) -> Self::Word { | |
415 | self.r_offset.get(endian) | |
416 | } | |
417 | ||
418 | #[inline] | |
419 | fn r_info(&self, endian: Self::Endian) -> Self::Word { | |
420 | self.r_info.get(endian) | |
421 | } | |
422 | ||
423 | #[inline] | |
424 | fn r_sym(&self, endian: Self::Endian) -> u32 { | |
425 | self.r_sym(endian) | |
426 | } | |
427 | ||
428 | #[inline] | |
429 | fn r_type(&self, endian: Self::Endian) -> u32 { | |
430 | self.r_type(endian) | |
431 | } | |
432 | } | |
433 | ||
434 | impl<Endian: endian::Endian> Rel for elf::Rel64<Endian> { | |
435 | type Word = u64; | |
436 | type Sword = i64; | |
437 | type Endian = Endian; | |
438 | ||
439 | #[inline] | |
440 | fn r_offset(&self, endian: Self::Endian) -> Self::Word { | |
441 | self.r_offset.get(endian) | |
442 | } | |
443 | ||
444 | #[inline] | |
445 | fn r_info(&self, endian: Self::Endian) -> Self::Word { | |
446 | self.r_info.get(endian) | |
447 | } | |
448 | ||
449 | #[inline] | |
450 | fn r_sym(&self, endian: Self::Endian) -> u32 { | |
451 | self.r_sym(endian) | |
452 | } | |
453 | ||
454 | #[inline] | |
455 | fn r_type(&self, endian: Self::Endian) -> u32 { | |
456 | self.r_type(endian) | |
457 | } | |
458 | } | |
459 | ||
460 | /// A trait for generic access to `Rela32` and `Rela64`. | |
461 | #[allow(missing_docs)] | |
462 | pub trait Rela: Debug + Pod + Clone { | |
463 | type Word: Into<u64>; | |
464 | type Sword: Into<i64>; | |
465 | type Endian: endian::Endian; | |
466 | ||
467 | fn r_offset(&self, endian: Self::Endian) -> Self::Word; | |
468 | fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word; | |
469 | fn r_addend(&self, endian: Self::Endian) -> Self::Sword; | |
470 | fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32; | |
471 | fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32; | |
472 | } | |
473 | ||
474 | impl<Endian: endian::Endian> Rela for elf::Rela32<Endian> { | |
475 | type Word = u32; | |
476 | type Sword = i32; | |
477 | type Endian = Endian; | |
478 | ||
479 | #[inline] | |
480 | fn r_offset(&self, endian: Self::Endian) -> Self::Word { | |
481 | self.r_offset.get(endian) | |
482 | } | |
483 | ||
484 | #[inline] | |
485 | fn r_info(&self, endian: Self::Endian, _is_mips64el: bool) -> Self::Word { | |
486 | self.r_info.get(endian) | |
487 | } | |
488 | ||
489 | #[inline] | |
490 | fn r_addend(&self, endian: Self::Endian) -> Self::Sword { | |
491 | self.r_addend.get(endian) | |
492 | } | |
493 | ||
494 | #[inline] | |
495 | fn r_sym(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 { | |
496 | self.r_sym(endian) | |
497 | } | |
498 | ||
499 | #[inline] | |
500 | fn r_type(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 { | |
501 | self.r_type(endian) | |
502 | } | |
503 | } | |
504 | ||
505 | impl<Endian: endian::Endian> Rela for elf::Rela64<Endian> { | |
506 | type Word = u64; | |
507 | type Sword = i64; | |
508 | type Endian = Endian; | |
509 | ||
510 | #[inline] | |
511 | fn r_offset(&self, endian: Self::Endian) -> Self::Word { | |
512 | self.r_offset.get(endian) | |
513 | } | |
514 | ||
515 | #[inline] | |
516 | fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word { | |
517 | self.get_r_info(endian, is_mips64el) | |
518 | } | |
519 | ||
520 | #[inline] | |
521 | fn r_addend(&self, endian: Self::Endian) -> Self::Sword { | |
522 | self.r_addend.get(endian) | |
523 | } | |
524 | ||
525 | #[inline] | |
526 | fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32 { | |
527 | self.r_sym(endian, is_mips64el) | |
528 | } | |
529 | ||
530 | #[inline] | |
531 | fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32 { | |
532 | self.r_type(endian, is_mips64el) | |
533 | } | |
534 | } |