1
+ use header:: Tag ;
1
2
2
3
#[ derive( Debug ) ]
3
- #[ repr( packed) ] // repr(C) would add unwanted padding before first_section
4
4
pub struct ElfSectionsTag {
5
- typ : u32 ,
6
- size : u32 ,
5
+ inner : * const ElfSectionsTagInner ,
6
+ }
7
+
8
+ pub fn elf_sections_tag ( tag : & Tag ) -> ElfSectionsTag {
9
+ assert_eq ! ( 9 , tag. typ) ;
10
+ let es = ElfSectionsTag {
11
+ inner : unsafe { ( tag as * const _ ) . offset ( 1 ) } as * const _ ,
12
+ } ;
13
+ assert ! ( ( es. get( ) . entry_size * es. get( ) . shndx) <= tag. size) ;
14
+ es
15
+ }
16
+
17
+ #[ derive( Debug ) ]
18
+ #[ repr( C , packed) ] // only repr(C) would add unwanted padding at the end
19
+ struct ElfSectionsTagInner {
7
20
number_of_sections : u32 ,
8
21
entry_size : u32 ,
9
22
shndx : u32 , // string table
10
- first_section : ElfSection ,
11
23
}
12
24
13
25
impl ElfSectionsTag {
14
- pub fn sections ( & ' static self ) -> ElfSectionIter {
26
+ pub fn sections ( & self ) -> ElfSectionIter {
27
+ let string_section_offset = ( self . get ( ) . shndx * self . get ( ) . entry_size ) as isize ;
28
+ let string_section_ptr = unsafe {
29
+ self . first_section ( ) . offset ( string_section_offset) as * const _
30
+ } ;
15
31
ElfSectionIter {
16
- current_section : & self . first_section ,
17
- remaining_sections : self . number_of_sections - 1 ,
18
- entry_size : self . entry_size ,
32
+ current_section : self . first_section ( ) ,
33
+ remaining_sections : self . get ( ) . number_of_sections - 1 ,
34
+ entry_size : self . get ( ) . entry_size ,
35
+ string_section : string_section_ptr,
19
36
}
20
37
}
21
38
22
- pub fn string_table ( & self ) -> & ' static StringTable {
23
- unsafe {
24
- let string_table_ptr =
25
- ( & self . first_section as * const ElfSection ) . offset ( self . shndx as isize ) ;
26
- & * ( ( * string_table_ptr) . addr as * const StringTable )
27
- }
39
+ fn first_section ( & self ) -> * const u8 {
40
+ ( unsafe { self . inner . offset ( 1 ) } ) as * const _
28
41
}
29
- }
30
-
31
- pub struct StringTable ( u8 ) ;
32
-
33
- impl StringTable {
34
- pub fn section_name ( & self , section : & ElfSection ) -> & ' static str {
35
- use core:: { str, slice} ;
36
-
37
- let name_ptr = unsafe {
38
- ( & self . 0 as * const u8 ) . offset ( section. name_index as isize )
39
- } ;
40
- let strlen = {
41
- let mut len = 0 ;
42
- while unsafe { * name_ptr. offset ( len) } != 0 {
43
- len += 1 ;
44
- }
45
- len as usize
46
- } ;
47
42
48
- str:: from_utf8 ( unsafe {
49
- slice:: from_raw_parts ( name_ptr, strlen)
50
- } ) . unwrap ( )
43
+ fn get ( & self ) -> & ElfSectionsTagInner {
44
+ unsafe { & * self . inner }
51
45
}
52
46
}
53
47
54
48
#[ derive( Clone ) ]
55
49
pub struct ElfSectionIter {
56
- current_section : & ' static ElfSection ,
50
+ current_section : * const u8 ,
57
51
remaining_sections : u32 ,
58
52
entry_size : u32 ,
53
+ string_section : * const u8 ,
59
54
}
60
55
61
56
impl Iterator for ElfSectionIter {
62
- type Item = & ' static ElfSection ;
63
- fn next ( & mut self ) -> Option < & ' static ElfSection > {
57
+ type Item = ElfSection ;
58
+
59
+ fn next ( & mut self ) -> Option < ElfSection > {
64
60
if self . remaining_sections == 0 {
65
- None
66
- } else {
67
- let section = self . current_section ;
68
- let next_section_addr = ( self . current_section as * const _ as u64 ) + self . entry_size as u64 ;
69
- self . current_section = unsafe { & * ( next_section_addr as * const ElfSection ) } ;
61
+ return None ;
62
+ }
63
+
64
+ loop {
65
+ let section = ElfSection {
66
+ inner : self . current_section ,
67
+ string_section : self . string_section ,
68
+ entry_size : self . entry_size ,
69
+ } ;
70
+
71
+ self . current_section = unsafe { self . current_section . offset ( self . entry_size as isize ) } ;
70
72
self . remaining_sections -= 1 ;
71
- if section. typ == ElfSectionType :: Unused as u32 {
72
- self . next ( )
73
- } else {
74
- Some ( section)
73
+
74
+ if section. section_type ( ) != ElfSectionType :: Unused {
75
+ return Some ( section) ;
75
76
}
76
77
}
77
78
}
78
79
}
79
80
80
- #[ cfg( feature = "elf32" ) ]
81
+ pub struct ElfSection {
82
+ inner : * const u8 ,
83
+ string_section : * const u8 ,
84
+ entry_size : u32 ,
85
+ }
86
+
81
87
#[ derive( Debug ) ]
82
88
#[ repr( C ) ]
83
- pub struct ElfSection {
89
+ struct ElfSectionInner32 {
84
90
name_index : u32 ,
85
91
typ : u32 ,
86
92
flags : u32 ,
@@ -93,10 +99,9 @@ pub struct ElfSection {
93
99
entry_size : u32 ,
94
100
}
95
101
96
- #[ cfg( not( feature = "elf32" ) ) ]
97
102
#[ derive( Debug ) ]
98
103
#[ repr( C ) ]
99
- pub struct ElfSection {
104
+ struct ElfSectionInner64 {
100
105
name_index : u32 ,
101
106
typ : u32 ,
102
107
flags : u64 ,
@@ -111,7 +116,7 @@ pub struct ElfSection {
111
116
112
117
impl ElfSection {
113
118
pub fn section_type ( & self ) -> ElfSectionType {
114
- match self . typ {
119
+ match self . get ( ) . typ ( ) {
115
120
0 => ElfSectionType :: Unused ,
116
121
1 => ElfSectionType :: ProgramSection ,
117
122
2 => ElfSectionType :: LinkerSymbolTable ,
@@ -131,28 +136,117 @@ impl ElfSection {
131
136
}
132
137
133
138
pub fn section_type_raw ( & self ) -> u32 {
134
- self . typ
139
+ self . get ( ) . typ ( )
140
+ }
141
+
142
+ pub fn name ( & self ) -> & str {
143
+ use core:: { str, slice} ;
144
+
145
+ let name_ptr = unsafe {
146
+ self . string_table ( ) . offset ( self . get ( ) . name_index ( ) as isize )
147
+ } ;
148
+ let strlen = {
149
+ let mut len = 0 ;
150
+ while unsafe { * name_ptr. offset ( len) } != 0 {
151
+ len += 1 ;
152
+ }
153
+ len as usize
154
+ } ;
155
+
156
+ str:: from_utf8 ( unsafe { slice:: from_raw_parts ( name_ptr, strlen) } ) . unwrap ( )
135
157
}
136
158
137
159
pub fn start_address ( & self ) -> usize {
138
- self . addr as usize
160
+ self . get ( ) . addr ( )
139
161
}
140
162
141
163
pub fn end_address ( & self ) -> usize {
142
- ( self . addr + self . size ) as usize
164
+ self . get ( ) . addr ( ) + self . get ( ) . size ( )
143
165
}
144
166
145
167
pub fn size ( & self ) -> usize {
146
- self . size as usize
168
+ self . get ( ) . size ( )
147
169
}
148
170
149
171
pub fn flags ( & self ) -> ElfSectionFlags {
150
- ElfSectionFlags :: from_bits_truncate ( self . flags )
172
+ ElfSectionFlags :: from_bits_truncate ( self . get ( ) . flags ( ) )
151
173
}
152
174
153
175
pub fn is_allocated ( & self ) -> bool {
154
176
self . flags ( ) . contains ( ELF_SECTION_ALLOCATED )
155
177
}
178
+
179
+ fn get ( & self ) -> & ElfSectionInner {
180
+ match self . entry_size {
181
+ 40 => unsafe { & * ( self . inner as * const ElfSectionInner32 ) } ,
182
+ 64 => unsafe { & * ( self . inner as * const ElfSectionInner64 ) } ,
183
+ _ => panic ! ( ) ,
184
+ }
185
+ }
186
+
187
+ unsafe fn string_table ( & self ) -> * const u8 {
188
+ match self . entry_size {
189
+ 40 => ( * ( self . string_section as * const ElfSectionInner32 ) ) . addr as * const _ ,
190
+ 64 => ( * ( self . string_section as * const ElfSectionInner64 ) ) . addr as * const _ ,
191
+ _ => panic ! ( ) ,
192
+ }
193
+ }
194
+ }
195
+
196
+ trait ElfSectionInner {
197
+ fn name_index ( & self ) -> u32 ;
198
+
199
+ fn typ ( & self ) -> u32 ;
200
+
201
+ fn flags ( & self ) -> u32 ;
202
+
203
+ fn addr ( & self ) -> usize ;
204
+
205
+ fn size ( & self ) -> usize ;
206
+ }
207
+
208
+ impl ElfSectionInner for ElfSectionInner32 {
209
+ fn name_index ( & self ) -> u32 {
210
+ self . name_index
211
+ }
212
+
213
+ fn typ ( & self ) -> u32 {
214
+ self . typ
215
+ }
216
+
217
+ fn flags ( & self ) -> u32 {
218
+ self . flags
219
+ }
220
+
221
+ fn addr ( & self ) -> usize {
222
+ self . addr as usize
223
+ }
224
+
225
+ fn size ( & self ) -> usize {
226
+ self . size as usize
227
+ }
228
+ }
229
+
230
+ impl ElfSectionInner for ElfSectionInner64 {
231
+ fn name_index ( & self ) -> u32 {
232
+ self . name_index
233
+ }
234
+
235
+ fn typ ( & self ) -> u32 {
236
+ self . typ
237
+ }
238
+
239
+ fn flags ( & self ) -> u32 {
240
+ self . flags as u32
241
+ }
242
+
243
+ fn addr ( & self ) -> usize {
244
+ self . addr as usize
245
+ }
246
+
247
+ fn size ( & self ) -> usize {
248
+ self . size as usize
249
+ }
156
250
}
157
251
158
252
#[ derive( PartialEq , Eq , Debug , Copy , Clone ) ]
@@ -174,14 +268,8 @@ pub enum ElfSectionType {
174
268
ProcessorSpecific = 0x7000_0000 ,
175
269
}
176
270
177
- #[ cfg( feature = "elf32" ) ]
178
- type ElfSectionFlagsType = u32 ;
179
-
180
- #[ cfg( not( feature = "elf32" ) ) ]
181
- type ElfSectionFlagsType = u64 ;
182
-
183
271
bitflags ! {
184
- flags ElfSectionFlags : ElfSectionFlagsType {
272
+ flags ElfSectionFlags : u32 {
185
273
const ELF_SECTION_WRITABLE = 0x1 ,
186
274
const ELF_SECTION_ALLOCATED = 0x2 ,
187
275
const ELF_SECTION_EXECUTABLE = 0x4 ,
0 commit comments