1use crate::endian::EndianParse;
3use crate::file::Class;
4use crate::parse::{ParseAt, ParseError, ParsingTable};
5
6pub type DynamicTable<'data, E> = ParsingTable<'data, E, Dyn>;
7
8#[derive(Debug)]
12#[repr(C)]
13pub struct Elf32_Dyn {
14 pub d_tag: i32,
15 pub d_un: u32,
17}
18
19#[derive(Debug)]
23#[repr(C)]
24pub struct Elf64_Dyn {
25 pub d_tag: i64,
26 pub d_un: u64,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct Dyn {
32 pub d_tag: i64,
33 pub(super) d_un: u64,
34}
35
36impl Dyn {
37 pub fn d_val(self) -> u64 {
38 self.d_un
39 }
40
41 pub fn d_ptr(self) -> u64 {
42 self.d_un
43 }
44}
45
46impl ParseAt for Dyn {
47 fn parse_at<E: EndianParse>(
48 endian: E,
49 class: Class,
50 offset: &mut usize,
51 data: &[u8],
52 ) -> Result<Self, ParseError> {
53 match class {
54 Class::ELF32 => Ok(Dyn {
55 d_tag: endian.parse_i32_at(offset, data)? as i64,
56 d_un: endian.parse_u32_at(offset, data)? as u64,
57 }),
58 Class::ELF64 => Ok(Dyn {
59 d_tag: endian.parse_i64_at(offset, data)?,
60 d_un: endian.parse_u64_at(offset, data)?,
61 }),
62 }
63 }
64
65 #[inline]
66 fn size_for(class: Class) -> usize {
67 match class {
68 Class::ELF32 => 8,
69 Class::ELF64 => 16,
70 }
71 }
72}
73
74#[cfg(test)]
75mod parse_tests {
76 use super::*;
77 use crate::endian::{BigEndian, LittleEndian};
78 use crate::parse::{test_parse_for, test_parse_fuzz_too_short};
79
80 #[test]
81 fn parse_dyn32_lsb() {
82 test_parse_for(
83 LittleEndian,
84 Class::ELF32,
85 Dyn {
86 d_tag: 0x03020100,
87 d_un: 0x07060504,
88 },
89 );
90 }
91
92 #[test]
93 fn parse_dyn32_msb() {
94 test_parse_for(
95 BigEndian,
96 Class::ELF32,
97 Dyn {
98 d_tag: 0x00010203,
99 d_un: 0x04050607,
100 },
101 );
102 }
103
104 #[test]
105 fn parse_dyn64_lsb() {
106 test_parse_for(
107 LittleEndian,
108 Class::ELF64,
109 Dyn {
110 d_tag: 0x0706050403020100,
111 d_un: 0x0F0E0D0C0B0A0908,
112 },
113 );
114 }
115
116 #[test]
117 fn parse_dyn64_msb() {
118 test_parse_for(
119 BigEndian,
120 Class::ELF64,
121 Dyn {
122 d_tag: 0x0001020304050607,
123 d_un: 0x08090A0B0C0D0E0F,
124 },
125 );
126 }
127
128 #[test]
129 fn parse_dyn32_lsb_fuzz_too_short() {
130 test_parse_fuzz_too_short::<_, Dyn>(LittleEndian, Class::ELF32);
131 }
132
133 #[test]
134 fn parse_dyn32_msb_fuzz_too_short() {
135 test_parse_fuzz_too_short::<_, Dyn>(BigEndian, Class::ELF32);
136 }
137
138 #[test]
139 fn parse_dyn64_lsb_fuzz_too_short() {
140 test_parse_fuzz_too_short::<_, Dyn>(LittleEndian, Class::ELF64);
141 }
142
143 #[test]
144 fn parse_dyn64_msb_fuzz_too_short() {
145 test_parse_fuzz_too_short::<_, Dyn>(BigEndian, Class::ELF64);
146 }
147}