1use alloc::fmt;
2use alloc::vec::Vec;
3use core::fmt::Debug;
4use core::slice;
5
6use crate::elf;
7use crate::endian::{self, Endianness};
8use crate::pod::Pod;
9use crate::read::{
10 self, Error, ReadRef, Relocation, RelocationEncoding, RelocationFlags, RelocationKind,
11 RelocationTarget, SectionIndex, SymbolIndex,
12};
13
14use super::{ElfFile, FileHeader, SectionHeader, SectionTable};
15
16#[derive(Debug, Default)]
18pub struct RelocationSections {
19 relocations: Vec<usize>,
20}
21
22impl RelocationSections {
23 pub fn parse<'data, Elf: FileHeader, R: ReadRef<'data>>(
27 endian: Elf::Endian,
28 sections: &SectionTable<'data, Elf, R>,
29 symbol_section: SectionIndex,
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 let sh_link = section.link(endian);
38 if sh_link != symbol_section {
39 continue;
40 }
41
42 let sh_info = section.info_link(endian);
43 if sh_info == SectionIndex(0) {
44 continue;
46 }
47 if sh_info.0 >= relocations.len() {
48 return Err(Error("Invalid ELF sh_info for relocation section"));
49 }
50
51 let sh_info_type = sections.section(sh_info)?.sh_type(endian);
54 if sh_info_type == elf::SHT_REL || sh_info_type == elf::SHT_RELA {
55 return Err(Error("Unsupported ELF sh_info for relocation section"));
56 }
57
58 let next = relocations[sh_info.0];
60 relocations[sh_info.0] = index;
61 relocations[index] = next;
62 }
63 }
64 Ok(Self { relocations })
65 }
66
67 pub fn get(&self, index: SectionIndex) -> Option<SectionIndex> {
72 self.relocations
73 .get(index.0)
74 .cloned()
75 .filter(|x| *x != 0)
76 .map(SectionIndex)
77 }
78}
79
80pub(super) enum ElfRelaIterator<'data, Elf: FileHeader> {
81 Rel(slice::Iter<'data, Elf::Rel>),
82 Rela(slice::Iter<'data, Elf::Rela>),
83}
84
85impl<'data, Elf: FileHeader> ElfRelaIterator<'data, Elf> {
86 fn is_rel(&self) -> bool {
87 match self {
88 ElfRelaIterator::Rel(_) => true,
89 ElfRelaIterator::Rela(_) => false,
90 }
91 }
92}
93
94impl<'data, Elf: FileHeader> Iterator for ElfRelaIterator<'data, Elf> {
95 type Item = Elf::Rela;
96
97 fn next(&mut self) -> Option<Self::Item> {
98 match self {
99 ElfRelaIterator::Rel(ref mut i) => i.next().cloned().map(Self::Item::from),
100 ElfRelaIterator::Rela(ref mut i) => i.next().cloned(),
101 }
102 }
103}
104
105pub type ElfDynamicRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
107 ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
108pub type ElfDynamicRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
110 ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
111
112pub struct ElfDynamicRelocationIterator<'data, 'file, Elf, R = &'data [u8]>
114where
115 Elf: FileHeader,
116 R: ReadRef<'data>,
117{
118 pub(super) section_index: SectionIndex,
120 pub(super) file: &'file ElfFile<'data, Elf, R>,
121 pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
122}
123
124impl<'data, 'file, Elf, R> Iterator for ElfDynamicRelocationIterator<'data, 'file, Elf, R>
125where
126 Elf: FileHeader,
127 R: ReadRef<'data>,
128{
129 type Item = (u64, Relocation);
130
131 fn next(&mut self) -> Option<Self::Item> {
132 let endian = self.file.endian;
133 loop {
134 if let Some(ref mut relocations) = self.relocations {
135 if let Some(reloc) = relocations.next() {
136 let relocation =
137 parse_relocation(self.file.header, endian, reloc, relocations.is_rel());
138 return Some((reloc.r_offset(endian).into(), relocation));
139 }
140 self.relocations = None;
141 }
142
143 let section = self.file.sections.section(self.section_index).ok()?;
144 self.section_index.0 += 1;
145
146 if section.link(endian) != self.file.dynamic_symbols.section() {
147 continue;
148 }
149
150 match section.sh_type(endian) {
151 elf::SHT_REL => {
152 if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
153 self.relocations = Some(ElfRelaIterator::Rel(relocations.iter()));
154 }
155 }
156 elf::SHT_RELA => {
157 if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
158 self.relocations = Some(ElfRelaIterator::Rela(relocations.iter()));
159 }
160 }
161 _ => {}
162 }
163 }
164 }
165}
166
167impl<'data, 'file, Elf, R> fmt::Debug for ElfDynamicRelocationIterator<'data, 'file, Elf, R>
168where
169 Elf: FileHeader,
170 R: ReadRef<'data>,
171{
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 f.debug_struct("ElfDynamicRelocationIterator").finish()
174 }
175}
176
177pub type ElfSectionRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
179 ElfSectionRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
180pub type ElfSectionRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
182 ElfSectionRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
183
184pub struct ElfSectionRelocationIterator<'data, 'file, Elf, R = &'data [u8]>
186where
187 Elf: FileHeader,
188 R: ReadRef<'data>,
189{
190 pub(super) section_index: SectionIndex,
192 pub(super) file: &'file ElfFile<'data, Elf, R>,
193 pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
194}
195
196impl<'data, 'file, Elf, R> Iterator for ElfSectionRelocationIterator<'data, 'file, Elf, R>
197where
198 Elf: FileHeader,
199 R: ReadRef<'data>,
200{
201 type Item = (u64, Relocation);
202
203 fn next(&mut self) -> Option<Self::Item> {
204 let endian = self.file.endian;
205 loop {
206 if let Some(ref mut relocations) = self.relocations {
207 if let Some(reloc) = relocations.next() {
208 let relocation =
209 parse_relocation(self.file.header, endian, reloc, relocations.is_rel());
210 return Some((reloc.r_offset(endian).into(), relocation));
211 }
212 self.relocations = None;
213 }
214 self.section_index = self.file.relocations.get(self.section_index)?;
215 let section = self.file.sections.section(self.section_index).unwrap();
217 match section.sh_type(endian) {
218 elf::SHT_REL => {
219 if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
220 self.relocations = Some(ElfRelaIterator::Rel(relocations.iter()));
221 }
222 }
223 elf::SHT_RELA => {
224 if let Ok(relocations) = section.data_as_array(endian, self.file.data) {
225 self.relocations = Some(ElfRelaIterator::Rela(relocations.iter()));
226 }
227 }
228 _ => {}
229 }
230 }
231 }
232}
233
234impl<'data, 'file, Elf, R> fmt::Debug for ElfSectionRelocationIterator<'data, 'file, Elf, R>
235where
236 Elf: FileHeader,
237 R: ReadRef<'data>,
238{
239 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240 f.debug_struct("ElfSectionRelocationIterator").finish()
241 }
242}
243
244fn parse_relocation<Elf: FileHeader>(
245 header: &Elf,
246 endian: Elf::Endian,
247 reloc: Elf::Rela,
248 implicit_addend: bool,
249) -> Relocation {
250 let mut encoding = RelocationEncoding::Generic;
251 let is_mips64el = header.is_mips64el(endian);
252 let r_type = reloc.r_type(endian, is_mips64el);
253 let flags = RelocationFlags::Elf { r_type };
254 let (kind, size) = match header.e_machine(endian) {
255 elf::EM_AARCH64 => {
256 if header.is_type_64() {
257 match r_type {
258 elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64),
259 elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32),
260 elf::R_AARCH64_ABS16 => (RelocationKind::Absolute, 16),
261 elf::R_AARCH64_PREL64 => (RelocationKind::Relative, 64),
262 elf::R_AARCH64_PREL32 => (RelocationKind::Relative, 32),
263 elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16),
264 elf::R_AARCH64_CALL26 => {
265 encoding = RelocationEncoding::AArch64Call;
266 (RelocationKind::PltRelative, 26)
267 }
268 _ => (RelocationKind::Unknown, 0),
269 }
270 } else {
271 match r_type {
272 elf::R_AARCH64_P32_ABS32 => (RelocationKind::Absolute, 32),
273 _ => (RelocationKind::Unknown, 0),
274 }
275 }
276 }
277 elf::EM_ARM => match r_type {
278 elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32),
279 _ => (RelocationKind::Unknown, 0),
280 },
281 elf::EM_AVR => match r_type {
282 elf::R_AVR_32 => (RelocationKind::Absolute, 32),
283 elf::R_AVR_16 => (RelocationKind::Absolute, 16),
284 _ => (RelocationKind::Unknown, 0),
285 },
286 elf::EM_BPF => match r_type {
287 elf::R_BPF_64_64 => (RelocationKind::Absolute, 64),
288 elf::R_BPF_64_32 => (RelocationKind::Absolute, 32),
289 _ => (RelocationKind::Unknown, 0),
290 },
291 elf::EM_CSKY => match r_type {
292 elf::R_CKCORE_ADDR32 => (RelocationKind::Absolute, 32),
293 elf::R_CKCORE_PCREL32 => (RelocationKind::Relative, 32),
294 _ => (RelocationKind::Unknown, 0),
295 },
296 elf::EM_386 => match r_type {
297 elf::R_386_32 => (RelocationKind::Absolute, 32),
298 elf::R_386_PC32 => (RelocationKind::Relative, 32),
299 elf::R_386_GOT32 => (RelocationKind::Got, 32),
300 elf::R_386_PLT32 => (RelocationKind::PltRelative, 32),
301 elf::R_386_GOTOFF => (RelocationKind::GotBaseOffset, 32),
302 elf::R_386_GOTPC => (RelocationKind::GotBaseRelative, 32),
303 elf::R_386_16 => (RelocationKind::Absolute, 16),
304 elf::R_386_PC16 => (RelocationKind::Relative, 16),
305 elf::R_386_8 => (RelocationKind::Absolute, 8),
306 elf::R_386_PC8 => (RelocationKind::Relative, 8),
307 _ => (RelocationKind::Unknown, 0),
308 },
309 elf::EM_X86_64 => match r_type {
310 elf::R_X86_64_64 => (RelocationKind::Absolute, 64),
311 elf::R_X86_64_PC32 => (RelocationKind::Relative, 32),
312 elf::R_X86_64_GOT32 => (RelocationKind::Got, 32),
313 elf::R_X86_64_PLT32 => (RelocationKind::PltRelative, 32),
314 elf::R_X86_64_GOTPCREL => (RelocationKind::GotRelative, 32),
315 elf::R_X86_64_32 => (RelocationKind::Absolute, 32),
316 elf::R_X86_64_32S => {
317 encoding = RelocationEncoding::X86Signed;
318 (RelocationKind::Absolute, 32)
319 }
320 elf::R_X86_64_16 => (RelocationKind::Absolute, 16),
321 elf::R_X86_64_PC16 => (RelocationKind::Relative, 16),
322 elf::R_X86_64_8 => (RelocationKind::Absolute, 8),
323 elf::R_X86_64_PC8 => (RelocationKind::Relative, 8),
324 _ => (RelocationKind::Unknown, 0),
325 },
326 elf::EM_HEXAGON => match r_type {
327 elf::R_HEX_32 => (RelocationKind::Absolute, 32),
328 _ => (RelocationKind::Unknown, 0),
329 },
330 elf::EM_LOONGARCH => match r_type {
331 elf::R_LARCH_32 => (RelocationKind::Absolute, 32),
332 elf::R_LARCH_64 => (RelocationKind::Absolute, 64),
333 elf::R_LARCH_32_PCREL => (RelocationKind::Relative, 32),
334 elf::R_LARCH_64_PCREL => (RelocationKind::Relative, 64),
335 elf::R_LARCH_B16 => {
336 encoding = RelocationEncoding::LoongArchBranch;
337 (RelocationKind::Relative, 16)
338 }
339 elf::R_LARCH_B21 => {
340 encoding = RelocationEncoding::LoongArchBranch;
341 (RelocationKind::Relative, 21)
342 }
343 elf::R_LARCH_B26 => {
344 encoding = RelocationEncoding::LoongArchBranch;
345 (RelocationKind::Relative, 26)
346 }
347 _ => (RelocationKind::Unknown, 0),
348 },
349 elf::EM_MIPS => match r_type {
350 elf::R_MIPS_16 => (RelocationKind::Absolute, 16),
351 elf::R_MIPS_32 => (RelocationKind::Absolute, 32),
352 elf::R_MIPS_64 => (RelocationKind::Absolute, 64),
353 _ => (RelocationKind::Unknown, 0),
354 },
355 elf::EM_MSP430 => match r_type {
356 elf::R_MSP430_32 => (RelocationKind::Absolute, 32),
357 elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16),
358 _ => (RelocationKind::Unknown, 0),
359 },
360 elf::EM_PPC => match r_type {
361 elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32),
362 _ => (RelocationKind::Unknown, 0),
363 },
364 elf::EM_PPC64 => match r_type {
365 elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32),
366 elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64),
367 _ => (RelocationKind::Unknown, 0),
368 },
369 elf::EM_RISCV => match r_type {
370 elf::R_RISCV_32 => (RelocationKind::Absolute, 32),
371 elf::R_RISCV_64 => (RelocationKind::Absolute, 64),
372 _ => (RelocationKind::Unknown, 0),
373 },
374 elf::EM_S390 => match r_type {
375 elf::R_390_8 => (RelocationKind::Absolute, 8),
376 elf::R_390_16 => (RelocationKind::Absolute, 16),
377 elf::R_390_32 => (RelocationKind::Absolute, 32),
378 elf::R_390_64 => (RelocationKind::Absolute, 64),
379 elf::R_390_PC16 => (RelocationKind::Relative, 16),
380 elf::R_390_PC32 => (RelocationKind::Relative, 32),
381 elf::R_390_PC64 => (RelocationKind::Relative, 64),
382 elf::R_390_PC16DBL => {
383 encoding = RelocationEncoding::S390xDbl;
384 (RelocationKind::Relative, 16)
385 }
386 elf::R_390_PC32DBL => {
387 encoding = RelocationEncoding::S390xDbl;
388 (RelocationKind::Relative, 32)
389 }
390 elf::R_390_PLT16DBL => {
391 encoding = RelocationEncoding::S390xDbl;
392 (RelocationKind::PltRelative, 16)
393 }
394 elf::R_390_PLT32DBL => {
395 encoding = RelocationEncoding::S390xDbl;
396 (RelocationKind::PltRelative, 32)
397 }
398 elf::R_390_GOT16 => (RelocationKind::Got, 16),
399 elf::R_390_GOT32 => (RelocationKind::Got, 32),
400 elf::R_390_GOT64 => (RelocationKind::Got, 64),
401 elf::R_390_GOTENT => {
402 encoding = RelocationEncoding::S390xDbl;
403 (RelocationKind::GotRelative, 32)
404 }
405 elf::R_390_GOTOFF16 => (RelocationKind::GotBaseOffset, 16),
406 elf::R_390_GOTOFF32 => (RelocationKind::GotBaseOffset, 32),
407 elf::R_390_GOTOFF64 => (RelocationKind::GotBaseOffset, 64),
408 elf::R_390_GOTPC => (RelocationKind::GotBaseRelative, 64),
409 elf::R_390_GOTPCDBL => {
410 encoding = RelocationEncoding::S390xDbl;
411 (RelocationKind::GotBaseRelative, 32)
412 }
413 _ => (RelocationKind::Unknown, 0),
414 },
415 elf::EM_SBF => match r_type {
416 elf::R_SBF_64_64 => (RelocationKind::Absolute, 64),
417 elf::R_SBF_64_32 => (RelocationKind::Absolute, 32),
418 _ => (RelocationKind::Unknown, 0),
419 },
420 elf::EM_SHARC => match r_type {
421 elf::R_SHARC_ADDR24_V3 => {
422 encoding = RelocationEncoding::SharcTypeA;
423 (RelocationKind::Absolute, 24)
424 }
425 elf::R_SHARC_ADDR32_V3 => {
426 encoding = RelocationEncoding::SharcTypeA;
427 (RelocationKind::Absolute, 32)
428 }
429 elf::R_SHARC_ADDR_VAR_V3 => {
430 encoding = RelocationEncoding::Generic;
431 (RelocationKind::Absolute, 32)
432 }
433 elf::R_SHARC_PCRSHORT_V3 => {
434 encoding = RelocationEncoding::SharcTypeA;
435 (RelocationKind::Relative, 6)
436 }
437 elf::R_SHARC_PCRLONG_V3 => {
438 encoding = RelocationEncoding::SharcTypeA;
439 (RelocationKind::Relative, 24)
440 }
441 elf::R_SHARC_DATA6_V3 => {
442 encoding = RelocationEncoding::SharcTypeA;
443 (RelocationKind::Absolute, 6)
444 }
445 elf::R_SHARC_DATA16_V3 => {
446 encoding = RelocationEncoding::SharcTypeA;
447 (RelocationKind::Absolute, 16)
448 }
449 elf::R_SHARC_DATA6_VISA_V3 => {
450 encoding = RelocationEncoding::SharcTypeB;
451 (RelocationKind::Absolute, 6)
452 }
453 elf::R_SHARC_DATA7_VISA_V3 => {
454 encoding = RelocationEncoding::SharcTypeB;
455 (RelocationKind::Absolute, 7)
456 }
457 elf::R_SHARC_DATA16_VISA_V3 => {
458 encoding = RelocationEncoding::SharcTypeB;
459 (RelocationKind::Absolute, 16)
460 }
461 elf::R_SHARC_PCR6_VISA_V3 => {
462 encoding = RelocationEncoding::SharcTypeB;
463 (RelocationKind::Relative, 16)
464 }
465 elf::R_SHARC_ADDR_VAR16_V3 => {
466 encoding = RelocationEncoding::Generic;
467 (RelocationKind::Absolute, 16)
468 }
469 _ => (RelocationKind::Unknown, 0),
470 },
471 elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => match r_type {
472 elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32),
473 elf::R_SPARC_64 | elf::R_SPARC_UA64 => (RelocationKind::Absolute, 64),
474 _ => (RelocationKind::Unknown, 0),
475 },
476 elf::EM_XTENSA => match r_type {
477 elf::R_XTENSA_32 => (RelocationKind::Absolute, 32),
478 elf::R_XTENSA_32_PCREL => (RelocationKind::Relative, 32),
479 _ => (RelocationKind::Unknown, 0),
480 },
481 _ => (RelocationKind::Unknown, 0),
482 };
483 let target = match reloc.symbol(endian, is_mips64el) {
484 None => RelocationTarget::Absolute,
485 Some(symbol) => RelocationTarget::Symbol(symbol),
486 };
487 Relocation {
488 kind,
489 encoding,
490 size,
491 target,
492 addend: reloc.r_addend(endian).into(),
493 implicit_addend,
494 flags,
495 }
496}
497
498#[allow(missing_docs)]
500pub trait Rel: Debug + Pod + Clone {
501 type Word: Into<u64>;
502 type Sword: Into<i64>;
503 type Endian: endian::Endian;
504
505 fn r_offset(&self, endian: Self::Endian) -> Self::Word;
506 fn r_info(&self, endian: Self::Endian) -> Self::Word;
507 fn r_sym(&self, endian: Self::Endian) -> u32;
508 fn r_type(&self, endian: Self::Endian) -> u32;
509
510 fn symbol(&self, endian: Self::Endian) -> Option<SymbolIndex> {
514 let sym = self.r_sym(endian);
515 if sym == 0 {
516 None
517 } else {
518 Some(SymbolIndex(sym as usize))
519 }
520 }
521}
522
523impl<Endian: endian::Endian> Rel for elf::Rel32<Endian> {
524 type Word = u32;
525 type Sword = i32;
526 type Endian = Endian;
527
528 #[inline]
529 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
530 self.r_offset.get(endian)
531 }
532
533 #[inline]
534 fn r_info(&self, endian: Self::Endian) -> Self::Word {
535 self.r_info.get(endian)
536 }
537
538 #[inline]
539 fn r_sym(&self, endian: Self::Endian) -> u32 {
540 self.r_sym(endian)
541 }
542
543 #[inline]
544 fn r_type(&self, endian: Self::Endian) -> u32 {
545 self.r_type(endian)
546 }
547}
548
549impl<Endian: endian::Endian> Rel for elf::Rel64<Endian> {
550 type Word = u64;
551 type Sword = i64;
552 type Endian = Endian;
553
554 #[inline]
555 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
556 self.r_offset.get(endian)
557 }
558
559 #[inline]
560 fn r_info(&self, endian: Self::Endian) -> Self::Word {
561 self.r_info.get(endian)
562 }
563
564 #[inline]
565 fn r_sym(&self, endian: Self::Endian) -> u32 {
566 self.r_sym(endian)
567 }
568
569 #[inline]
570 fn r_type(&self, endian: Self::Endian) -> u32 {
571 self.r_type(endian)
572 }
573}
574
575#[allow(missing_docs)]
577pub trait Rela: Debug + Pod + Clone {
578 type Word: Into<u64>;
579 type Sword: Into<i64>;
580 type Endian: endian::Endian;
581
582 fn r_offset(&self, endian: Self::Endian) -> Self::Word;
583 fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word;
584 fn r_addend(&self, endian: Self::Endian) -> Self::Sword;
585 fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32;
586 fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32;
587
588 fn symbol(&self, endian: Self::Endian, is_mips64el: bool) -> Option<SymbolIndex> {
592 let sym = self.r_sym(endian, is_mips64el);
593 if sym == 0 {
594 None
595 } else {
596 Some(SymbolIndex(sym as usize))
597 }
598 }
599}
600
601impl<Endian: endian::Endian> Rela for elf::Rela32<Endian> {
602 type Word = u32;
603 type Sword = i32;
604 type Endian = Endian;
605
606 #[inline]
607 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
608 self.r_offset.get(endian)
609 }
610
611 #[inline]
612 fn r_info(&self, endian: Self::Endian, _is_mips64el: bool) -> Self::Word {
613 self.r_info.get(endian)
614 }
615
616 #[inline]
617 fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
618 self.r_addend.get(endian)
619 }
620
621 #[inline]
622 fn r_sym(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 {
623 self.r_sym(endian)
624 }
625
626 #[inline]
627 fn r_type(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 {
628 self.r_type(endian)
629 }
630}
631
632impl<Endian: endian::Endian> Rela for elf::Rela64<Endian> {
633 type Word = u64;
634 type Sword = i64;
635 type Endian = Endian;
636
637 #[inline]
638 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
639 self.r_offset.get(endian)
640 }
641
642 #[inline]
643 fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word {
644 self.get_r_info(endian, is_mips64el)
645 }
646
647 #[inline]
648 fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
649 self.r_addend.get(endian)
650 }
651
652 #[inline]
653 fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
654 self.r_sym(endian, is_mips64el)
655 }
656
657 #[inline]
658 fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
659 self.r_type(endian, is_mips64el)
660 }
661}