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, RelocationKind, RelocationTarget,
11 SectionIndex, SymbolIndex,
12};
13
14use super::{ElfFile, FileHeader, SectionHeader, SectionTable};
15
16/// A mapping from section index to associated relocation sections.
17#[derive(Debug)]
18pub struct RelocationSections {
19 relocations: Vec<usize>,
20}
21
22impl RelocationSections {
23 /// Create a new mapping using the section table.
24 ///
25 /// Skips relocation sections that do not use the given symbol table section.
26 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 // The symbol indices used in relocations must be for the symbol table
36 // we are expecting to use.
37 let sh_link = SectionIndex(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
69pub(super) enum ElfRelaIterator<'data, Elf: FileHeader> {
70 Rel(slice::Iter<'data, Elf::Rel>),
71 Rela(slice::Iter<'data, Elf::Rela>),
72}
73
74impl<'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
83impl<'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: &mut Iter<'_, ::Rel>) => i.next().cloned().map(Self::Item::from),
89 ElfRelaIterator::Rela(ref mut i: &mut Iter<'_, ::Rela>) => i.next().cloned(),
90 }
91 }
92}
93
94/// An iterator for the dynamic relocations in an [`ElfFile32`](super::ElfFile32).
95pub type ElfDynamicRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
96 ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
97/// An iterator for the dynamic relocations in an [`ElfFile64`](super::ElfFile64).
98pub type ElfDynamicRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
99 ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
100
101/// An iterator for the dynamic relocations in an [`ElfFile`].
102pub struct ElfDynamicRelocationIterator<'data, 'file, Elf, R = &'data [u8]>
103where
104 Elf: FileHeader,
105 R: ReadRef<'data>,
106{
107 /// The current relocation section index.
108 pub(super) section_index: SectionIndex,
109 pub(super) file: &'file ElfFile<'data, Elf, R>,
110 pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
111}
112
113impl<'data, 'file, Elf, R> Iterator for ElfDynamicRelocationIterator<'data, 'file, Elf, R>
114where
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.0 += 1;
134
135 let sh_link = SectionIndex(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
157impl<'data, 'file, Elf, R> fmt::Debug for ElfDynamicRelocationIterator<'data, 'file, Elf, R>
158where
159 Elf: FileHeader,
160 R: ReadRef<'data>,
161{
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 f.debug_struct(name:"ElfDynamicRelocationIterator").finish()
164 }
165}
166
167/// An iterator for the relocations for an [`ElfSection32`](super::ElfSection32).
168pub type ElfSectionRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
169 ElfSectionRelocationIterator<'data, 'file, elf::FileHeader32<Endian>, R>;
170/// An iterator for the relocations for an [`ElfSection64`](super::ElfSection64).
171pub type ElfSectionRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
172 ElfSectionRelocationIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
173
174/// An iterator for the relocations for an [`ElfSection`](super::ElfSection).
175pub struct ElfSectionRelocationIterator<'data, 'file, Elf, R = &'data [u8]>
176where
177 Elf: FileHeader,
178 R: ReadRef<'data>,
179{
180 /// The current pointer in the chain of relocation sections.
181 pub(super) section_index: SectionIndex,
182 pub(super) file: &'file ElfFile<'data, Elf, R>,
183 pub(super) relocations: Option<ElfRelaIterator<'data, Elf>>,
184}
185
186impl<'data, 'file, Elf, R> Iterator for ElfSectionRelocationIterator<'data, 'file, Elf, R>
187where
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 = SectionIndex(self.file.relocations.get(self.section_index.0)?);
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
224impl<'data, 'file, Elf, R> fmt::Debug for ElfSectionRelocationIterator<'data, 'file, Elf, R>
225where
226 Elf: FileHeader,
227 R: ReadRef<'data>,
228{
229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230 f.debug_struct(name:"ElfSectionRelocationIterator").finish()
231 }
232}
233
234fn 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 => {
244 if header.is_type_64() {
245 match reloc.r_type(endian, false) {
246 elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64),
247 elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32),
248 elf::R_AARCH64_ABS16 => (RelocationKind::Absolute, 16),
249 elf::R_AARCH64_PREL64 => (RelocationKind::Relative, 64),
250 elf::R_AARCH64_PREL32 => (RelocationKind::Relative, 32),
251 elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16),
252 elf::R_AARCH64_CALL26 => {
253 encoding = RelocationEncoding::AArch64Call;
254 (RelocationKind::PltRelative, 26)
255 }
256 r_type => (RelocationKind::Elf(r_type), 0),
257 }
258 } else {
259 match reloc.r_type(endian, false) {
260 elf::R_AARCH64_P32_ABS32 => (RelocationKind::Absolute, 32),
261 r_type => (RelocationKind::Elf(r_type), 0),
262 }
263 }
264 }
265 elf::EM_ARM => match reloc.r_type(endian, false) {
266 elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32),
267 r_type => (RelocationKind::Elf(r_type), 0),
268 },
269 elf::EM_AVR => match reloc.r_type(endian, false) {
270 elf::R_AVR_32 => (RelocationKind::Absolute, 32),
271 elf::R_AVR_16 => (RelocationKind::Absolute, 16),
272 r_type => (RelocationKind::Elf(r_type), 0),
273 },
274 elf::EM_BPF => match reloc.r_type(endian, false) {
275 elf::R_BPF_64_64 => (RelocationKind::Absolute, 64),
276 elf::R_BPF_64_32 => (RelocationKind::Absolute, 32),
277 r_type => (RelocationKind::Elf(r_type), 0),
278 },
279 elf::EM_CSKY => match reloc.r_type(endian, false) {
280 elf::R_CKCORE_ADDR32 => (RelocationKind::Absolute, 32),
281 elf::R_CKCORE_PCREL32 => (RelocationKind::Relative, 32),
282 r_type => (RelocationKind::Elf(r_type), 0),
283 },
284 elf::EM_386 => match reloc.r_type(endian, false) {
285 elf::R_386_32 => (RelocationKind::Absolute, 32),
286 elf::R_386_PC32 => (RelocationKind::Relative, 32),
287 elf::R_386_GOT32 => (RelocationKind::Got, 32),
288 elf::R_386_PLT32 => (RelocationKind::PltRelative, 32),
289 elf::R_386_GOTOFF => (RelocationKind::GotBaseOffset, 32),
290 elf::R_386_GOTPC => (RelocationKind::GotBaseRelative, 32),
291 elf::R_386_16 => (RelocationKind::Absolute, 16),
292 elf::R_386_PC16 => (RelocationKind::Relative, 16),
293 elf::R_386_8 => (RelocationKind::Absolute, 8),
294 elf::R_386_PC8 => (RelocationKind::Relative, 8),
295 r_type => (RelocationKind::Elf(r_type), 0),
296 },
297 elf::EM_X86_64 => match reloc.r_type(endian, false) {
298 elf::R_X86_64_64 => (RelocationKind::Absolute, 64),
299 elf::R_X86_64_PC32 => (RelocationKind::Relative, 32),
300 elf::R_X86_64_GOT32 => (RelocationKind::Got, 32),
301 elf::R_X86_64_PLT32 => (RelocationKind::PltRelative, 32),
302 elf::R_X86_64_GOTPCREL => (RelocationKind::GotRelative, 32),
303 elf::R_X86_64_32 => (RelocationKind::Absolute, 32),
304 elf::R_X86_64_32S => {
305 encoding = RelocationEncoding::X86Signed;
306 (RelocationKind::Absolute, 32)
307 }
308 elf::R_X86_64_16 => (RelocationKind::Absolute, 16),
309 elf::R_X86_64_PC16 => (RelocationKind::Relative, 16),
310 elf::R_X86_64_8 => (RelocationKind::Absolute, 8),
311 elf::R_X86_64_PC8 => (RelocationKind::Relative, 8),
312 r_type => (RelocationKind::Elf(r_type), 0),
313 },
314 elf::EM_HEXAGON => match reloc.r_type(endian, false) {
315 elf::R_HEX_32 => (RelocationKind::Absolute, 32),
316 r_type => (RelocationKind::Elf(r_type), 0),
317 },
318 elf::EM_LOONGARCH => match reloc.r_type(endian, false) {
319 elf::R_LARCH_32 => (RelocationKind::Absolute, 32),
320 elf::R_LARCH_64 => (RelocationKind::Absolute, 64),
321 elf::R_LARCH_32_PCREL => (RelocationKind::Relative, 32),
322 elf::R_LARCH_64_PCREL => (RelocationKind::Relative, 64),
323 elf::R_LARCH_B16 => {
324 encoding = RelocationEncoding::LoongArchBranch;
325 (RelocationKind::Relative, 16)
326 }
327 elf::R_LARCH_B21 => {
328 encoding = RelocationEncoding::LoongArchBranch;
329 (RelocationKind::Relative, 21)
330 }
331 elf::R_LARCH_B26 => {
332 encoding = RelocationEncoding::LoongArchBranch;
333 (RelocationKind::Relative, 26)
334 }
335 r_type => (RelocationKind::Elf(r_type), 0),
336 },
337 elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) {
338 elf::R_MIPS_16 => (RelocationKind::Absolute, 16),
339 elf::R_MIPS_32 => (RelocationKind::Absolute, 32),
340 elf::R_MIPS_64 => (RelocationKind::Absolute, 64),
341 r_type => (RelocationKind::Elf(r_type), 0),
342 },
343 elf::EM_MSP430 => match reloc.r_type(endian, false) {
344 elf::R_MSP430_32 => (RelocationKind::Absolute, 32),
345 elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16),
346 r_type => (RelocationKind::Elf(r_type), 0),
347 },
348 elf::EM_PPC => match reloc.r_type(endian, false) {
349 elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32),
350 r_type => (RelocationKind::Elf(r_type), 0),
351 },
352 elf::EM_PPC64 => match reloc.r_type(endian, false) {
353 elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32),
354 elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64),
355 r_type => (RelocationKind::Elf(r_type), 0),
356 },
357 elf::EM_RISCV => match reloc.r_type(endian, false) {
358 elf::R_RISCV_32 => (RelocationKind::Absolute, 32),
359 elf::R_RISCV_64 => (RelocationKind::Absolute, 64),
360 r_type => (RelocationKind::Elf(r_type), 0),
361 },
362 elf::EM_S390 => match reloc.r_type(endian, false) {
363 elf::R_390_8 => (RelocationKind::Absolute, 8),
364 elf::R_390_16 => (RelocationKind::Absolute, 16),
365 elf::R_390_32 => (RelocationKind::Absolute, 32),
366 elf::R_390_64 => (RelocationKind::Absolute, 64),
367 elf::R_390_PC16 => (RelocationKind::Relative, 16),
368 elf::R_390_PC32 => (RelocationKind::Relative, 32),
369 elf::R_390_PC64 => (RelocationKind::Relative, 64),
370 elf::R_390_PC16DBL => {
371 encoding = RelocationEncoding::S390xDbl;
372 (RelocationKind::Relative, 16)
373 }
374 elf::R_390_PC32DBL => {
375 encoding = RelocationEncoding::S390xDbl;
376 (RelocationKind::Relative, 32)
377 }
378 elf::R_390_PLT16DBL => {
379 encoding = RelocationEncoding::S390xDbl;
380 (RelocationKind::PltRelative, 16)
381 }
382 elf::R_390_PLT32DBL => {
383 encoding = RelocationEncoding::S390xDbl;
384 (RelocationKind::PltRelative, 32)
385 }
386 elf::R_390_GOT16 => (RelocationKind::Got, 16),
387 elf::R_390_GOT32 => (RelocationKind::Got, 32),
388 elf::R_390_GOT64 => (RelocationKind::Got, 64),
389 elf::R_390_GOTENT => {
390 encoding = RelocationEncoding::S390xDbl;
391 (RelocationKind::GotRelative, 32)
392 }
393 elf::R_390_GOTOFF16 => (RelocationKind::GotBaseOffset, 16),
394 elf::R_390_GOTOFF32 => (RelocationKind::GotBaseOffset, 32),
395 elf::R_390_GOTOFF64 => (RelocationKind::GotBaseOffset, 64),
396 elf::R_390_GOTPC => (RelocationKind::GotBaseRelative, 64),
397 elf::R_390_GOTPCDBL => {
398 encoding = RelocationEncoding::S390xDbl;
399 (RelocationKind::GotBaseRelative, 32)
400 }
401 r_type => (RelocationKind::Elf(r_type), 0),
402 },
403 elf::EM_SBF => match reloc.r_type(endian, false) {
404 elf::R_SBF_64_64 => (RelocationKind::Absolute, 64),
405 elf::R_SBF_64_32 => (RelocationKind::Absolute, 32),
406 r_type => (RelocationKind::Elf(r_type), 0),
407 },
408 elf::EM_SHARC => match reloc.r_type(endian, false) {
409 elf::R_SHARC_ADDR24_V3 => {
410 encoding = RelocationEncoding::SharcTypeA;
411 (RelocationKind::Absolute, 24)
412 }
413 elf::R_SHARC_ADDR32_V3 => {
414 encoding = RelocationEncoding::SharcTypeA;
415 (RelocationKind::Absolute, 32)
416 }
417 elf::R_SHARC_ADDR_VAR_V3 => {
418 encoding = RelocationEncoding::Generic;
419 (RelocationKind::Absolute, 32)
420 }
421 elf::R_SHARC_PCRSHORT_V3 => {
422 encoding = RelocationEncoding::SharcTypeA;
423 (RelocationKind::Relative, 6)
424 }
425 elf::R_SHARC_PCRLONG_V3 => {
426 encoding = RelocationEncoding::SharcTypeA;
427 (RelocationKind::Relative, 24)
428 }
429 elf::R_SHARC_DATA6_V3 => {
430 encoding = RelocationEncoding::SharcTypeA;
431 (RelocationKind::Absolute, 6)
432 }
433 elf::R_SHARC_DATA16_V3 => {
434 encoding = RelocationEncoding::SharcTypeA;
435 (RelocationKind::Absolute, 16)
436 }
437 elf::R_SHARC_DATA6_VISA_V3 => {
438 encoding = RelocationEncoding::SharcTypeB;
439 (RelocationKind::Absolute, 6)
440 }
441 elf::R_SHARC_DATA7_VISA_V3 => {
442 encoding = RelocationEncoding::SharcTypeB;
443 (RelocationKind::Absolute, 7)
444 }
445 elf::R_SHARC_DATA16_VISA_V3 => {
446 encoding = RelocationEncoding::SharcTypeB;
447 (RelocationKind::Absolute, 16)
448 }
449 elf::R_SHARC_PCR6_VISA_V3 => {
450 encoding = RelocationEncoding::SharcTypeB;
451 (RelocationKind::Relative, 16)
452 }
453 elf::R_SHARC_ADDR_VAR16_V3 => {
454 encoding = RelocationEncoding::Generic;
455 (RelocationKind::Absolute, 16)
456 }
457 r_type => (RelocationKind::Elf(r_type), 0),
458 },
459 elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => {
460 match reloc.r_type(endian, false) {
461 elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32),
462 elf::R_SPARC_64 | elf::R_SPARC_UA64 => (RelocationKind::Absolute, 64),
463 r_type => (RelocationKind::Elf(r_type), 0),
464 }
465 }
466 elf::EM_XTENSA => match reloc.r_type(endian, false) {
467 elf::R_XTENSA_32 => (RelocationKind::Absolute, 32),
468 elf::R_XTENSA_32_PCREL => (RelocationKind::Relative, 32),
469 r_type => (RelocationKind::Elf(r_type), 0),
470 },
471 _ => (RelocationKind::Elf(reloc.r_type(endian, false)), 0),
472 };
473 let sym = reloc.r_sym(endian, is_mips64el) as usize;
474 let target = if sym == 0 {
475 RelocationTarget::Absolute
476 } else {
477 RelocationTarget::Symbol(SymbolIndex(sym))
478 };
479 Relocation {
480 kind,
481 encoding,
482 size,
483 target,
484 addend: reloc.r_addend(endian).into(),
485 implicit_addend,
486 }
487}
488
489/// A trait for generic access to [`elf::Rel32`] and [`elf::Rel64`].
490#[allow(missing_docs)]
491pub trait Rel: Debug + Pod + Clone {
492 type Word: Into<u64>;
493 type Sword: Into<i64>;
494 type Endian: endian::Endian;
495
496 fn r_offset(&self, endian: Self::Endian) -> Self::Word;
497 fn r_info(&self, endian: Self::Endian) -> Self::Word;
498 fn r_sym(&self, endian: Self::Endian) -> u32;
499 fn r_type(&self, endian: Self::Endian) -> u32;
500}
501
502impl<Endian: endian::Endian> Rel for elf::Rel32<Endian> {
503 type Word = u32;
504 type Sword = i32;
505 type Endian = Endian;
506
507 #[inline]
508 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
509 self.r_offset.get(endian)
510 }
511
512 #[inline]
513 fn r_info(&self, endian: Self::Endian) -> Self::Word {
514 self.r_info.get(endian)
515 }
516
517 #[inline]
518 fn r_sym(&self, endian: Self::Endian) -> u32 {
519 self.r_sym(endian)
520 }
521
522 #[inline]
523 fn r_type(&self, endian: Self::Endian) -> u32 {
524 self.r_type(endian)
525 }
526}
527
528impl<Endian: endian::Endian> Rel for elf::Rel64<Endian> {
529 type Word = u64;
530 type Sword = i64;
531 type Endian = Endian;
532
533 #[inline]
534 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
535 self.r_offset.get(endian)
536 }
537
538 #[inline]
539 fn r_info(&self, endian: Self::Endian) -> Self::Word {
540 self.r_info.get(endian)
541 }
542
543 #[inline]
544 fn r_sym(&self, endian: Self::Endian) -> u32 {
545 self.r_sym(endian)
546 }
547
548 #[inline]
549 fn r_type(&self, endian: Self::Endian) -> u32 {
550 self.r_type(endian)
551 }
552}
553
554/// A trait for generic access to [`elf::Rela32`] and [`elf::Rela64`].
555#[allow(missing_docs)]
556pub trait Rela: Debug + Pod + Clone {
557 type Word: Into<u64>;
558 type Sword: Into<i64>;
559 type Endian: endian::Endian;
560
561 fn r_offset(&self, endian: Self::Endian) -> Self::Word;
562 fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word;
563 fn r_addend(&self, endian: Self::Endian) -> Self::Sword;
564 fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32;
565 fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32;
566}
567
568impl<Endian: endian::Endian> Rela for elf::Rela32<Endian> {
569 type Word = u32;
570 type Sword = i32;
571 type Endian = Endian;
572
573 #[inline]
574 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
575 self.r_offset.get(endian)
576 }
577
578 #[inline]
579 fn r_info(&self, endian: Self::Endian, _is_mips64el: bool) -> Self::Word {
580 self.r_info.get(endian)
581 }
582
583 #[inline]
584 fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
585 self.r_addend.get(endian)
586 }
587
588 #[inline]
589 fn r_sym(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 {
590 self.r_sym(endian)
591 }
592
593 #[inline]
594 fn r_type(&self, endian: Self::Endian, _is_mips64el: bool) -> u32 {
595 self.r_type(endian)
596 }
597}
598
599impl<Endian: endian::Endian> Rela for elf::Rela64<Endian> {
600 type Word = u64;
601 type Sword = i64;
602 type Endian = Endian;
603
604 #[inline]
605 fn r_offset(&self, endian: Self::Endian) -> Self::Word {
606 self.r_offset.get(endian)
607 }
608
609 #[inline]
610 fn r_info(&self, endian: Self::Endian, is_mips64el: bool) -> Self::Word {
611 self.get_r_info(endian, is_mips64el)
612 }
613
614 #[inline]
615 fn r_addend(&self, endian: Self::Endian) -> Self::Sword {
616 self.r_addend.get(endian)
617 }
618
619 #[inline]
620 fn r_sym(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
621 self.r_sym(endian, is_mips64el)
622 }
623
624 #[inline]
625 fn r_type(&self, endian: Self::Endian, is_mips64el: bool) -> u32 {
626 self.r_type(endian, is_mips64el)
627 }
628}
629