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.
parse<Elf: FileHeader>( endian: Elf::Endian, sections: &SectionTable<Elf>, symbol_section: usize, ) -> read::Result<Self>26     pub fn parse<Elf: FileHeader>(
27         endian: Elf::Endian,
28         sections: &SectionTable<Elf>,
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.
get(&self, index: usize) -> Option<usize>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> {
is_rel(&self) -> bool75     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 
next(&mut self) -> Option<Self::Item>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 
next(&mut self) -> Option<Self::Item>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 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result162     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 
next(&mut self) -> Option<Self::Item>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 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result229     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230         f.debug_struct("ElfSectionRelocationIterator").finish()
231     }
232 }
233 
parse_relocation<Elf: FileHeader>( header: &Elf, endian: Elf::Endian, reloc: Elf::Rela, implicit_addend: bool, ) -> Relocation234 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),
250             elf::R_AARCH64_CALL26 => {
251                 encoding = RelocationEncoding::AArch64Call;
252                 (RelocationKind::PltRelative, 26)
253             }
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 
r_offset(&self, endian: Self::Endian) -> Self::Word402     fn r_offset(&self, endian: Self::Endian) -> Self::Word;
r_info(&self, endian: Self::Endian) -> Self::Word403     fn r_info(&self, endian: Self::Endian) -> Self::Word;
r_sym(&self, endian: Self::Endian) -> u32404     fn r_sym(&self, endian: Self::Endian) -> u32;
r_type(&self, endian: Self::Endian) -> u32405     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]
r_offset(&self, endian: Self::Endian) -> Self::Word414     fn r_offset(&self, endian: Self::Endian) -> Self::Word {
415         self.r_offset.get(endian)
416     }
417 
418     #[inline]
r_info(&self, endian: Self::Endian) -> Self::Word419     fn r_info(&self, endian: Self::Endian) -> Self::Word {
420         self.r_info.get(endian)
421     }
422 
423     #[inline]
r_sym(&self, endian: Self::Endian) -> u32424     fn r_sym(&self, endian: Self::Endian) -> u32 {
425         self.r_sym(endian)
426     }
427 
428     #[inline]
r_type(&self, endian: Self::Endian) -> u32429     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]
r_offset(&self, endian: Self::Endian) -> Self::Word440     fn r_offset(&self, endian: Self::Endian) -> Self::Word {
441         self.r_offset.get(endian)
442     }
443 
444     #[inline]
r_info(&self, endian: Self::Endian) -> Self::Word445     fn r_info(&self, endian: Self::Endian) -> Self::Word {
446         self.r_info.get(endian)
447     }
448 
449     #[inline]
r_sym(&self, endian: Self::Endian) -> u32450     fn r_sym(&self, endian: Self::Endian) -> u32 {
451         self.r_sym(endian)
452     }
453 
454     #[inline]
r_type(&self, endian: Self::Endian) -> u32455     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 
r_offset(&self, endian: Self::Endian) -> Self::Word467     fn r_offset(&self, endian: Self::Endian) -> Self::Word;
r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word468     fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word;
r_addend(&self, endian: Self::Endian) -> Self::Sword469     fn r_addend(&self, endian: Self::Endian) -> Self::Sword;
r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32470     fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32;
r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32471     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]
r_offset(&self, endian: Self::Endian) -> Self::Word480     fn r_offset(&self, endian: Self::Endian) -> Self::Word {
481         self.r_offset.get(endian)
482     }
483 
484     #[inline]
r_info(&self, endian: Self::Endian, _is_mips64el: bool) -> Self::Word485     fn r_info(&self, endian: Self::Endian, _is_mips64el: bool) -> Self::Word {
486         self.r_info.get(endian)
487     }
488 
489     #[inline]
r_addend(&self, endian: Self::Endian) -> Self::Sword490     fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
491         self.r_addend.get(endian)
492     }
493 
494     #[inline]
r_sym(&self, endian: Self::Endian, _is_mips64el: bool) -> u32495     fn r_sym(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 {
496         self.r_sym(endian)
497     }
498 
499     #[inline]
r_type(&self, endian: Self::Endian, _is_mips64el: bool) -> u32500     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]
r_offset(&self, endian: Self::Endian) -> Self::Word511     fn r_offset(&self, endian: Self::Endian) -> Self::Word {
512         self.r_offset.get(endian)
513     }
514 
515     #[inline]
r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word516     fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word {
517         self.get_r_info(endian, is_mips64el)
518     }
519 
520     #[inline]
r_addend(&self, endian: Self::Endian) -> Self::Sword521     fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
522         self.r_addend.get(endian)
523     }
524 
525     #[inline]
r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32526     fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
527         self.r_sym(endian, is_mips64el)
528     }
529 
530     #[inline]
r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32531     fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
532         self.r_type(endian, is_mips64el)
533     }
534 }
535