@@ -5,13 +5,27 @@ use elf::{
5
5
} ;
6
6
use std:: io:: { Error as IoError , ErrorKind as IoErrorKind } ;
7
7
8
+ // Sorting criteria.
9
+ #[ derive( Clone , Debug , Default ) ]
10
+ enum SortBy {
11
+ /// Elf encounter order.
12
+ #[ default]
13
+ None = 0 ,
14
+ /// Name.
15
+ Name = 1 ,
16
+ /// Value.
17
+ Value = 2 ,
18
+ }
19
+
8
20
/// ELF symbols wrapper.
9
21
#[ derive( Clone , Debug , Default ) ]
10
22
pub struct Symbols {
11
23
/// Symbols.
12
24
symbols : Vec < Symbol > ,
13
25
/// Symbol names.
14
26
names : Vec < String > ,
27
+ /// Sort by.
28
+ sort : SortBy ,
15
29
}
16
30
17
31
impl < ' a > TryFrom < Option < ( ParsingTable < ' a , AnyEndian , Symbol > , StringTable < ' a > ) > > for Symbols {
@@ -36,37 +50,58 @@ impl<'a> TryFrom<Option<(ParsingTable<'a, AnyEndian, Symbol>, StringTable<'a>)>>
36
50
. unwrap_or_else ( |_| String :: from ( "unknown" ) )
37
51
} )
38
52
. collect ( ) ,
53
+ sort : SortBy :: default ( ) ,
39
54
} )
40
55
}
41
56
}
42
57
43
58
impl < ' a > Property < ' a > for Symbols {
44
59
fn items ( & self ) -> Vec < Vec < String > > {
45
- self . symbols
60
+ let mut indices: Vec < usize > = ( 0 ..self . symbols . len ( ) ) . collect ( ) ;
61
+ match self . sort {
62
+ SortBy :: Name => {
63
+ indices. sort_by ( |& a, & b| self . names [ a] . cmp ( & self . names [ b] ) ) ;
64
+ }
65
+ SortBy :: Value => {
66
+ indices. sort_by ( |& a, & b| self . symbols [ a] . st_value . cmp ( & self . symbols [ b] . st_value ) ) ;
67
+ }
68
+ SortBy :: None => { }
69
+ }
70
+
71
+ indices
46
72
. iter ( )
47
- . enumerate ( )
48
- . map ( |( i, symbol) | {
49
- let name = self . names [ i] . to_string ( ) ;
73
+ . map ( |& i| {
50
74
vec ! [
51
- name ,
52
- elf:: to_str:: st_symtype_to_string( symbol . st_symtype( ) )
75
+ self . names [ i ] . to_string ( ) ,
76
+ elf:: to_str:: st_symtype_to_string( self . symbols [ i ] . st_symtype( ) )
53
77
. trim_start_matches( "STT_" )
54
78
. to_string( ) ,
55
- format!( "{:#x}" , symbol . st_value) ,
56
- symbol . st_size. to_string( ) ,
57
- elf:: to_str:: st_bind_to_string( symbol . st_bind( ) )
79
+ format!( "{:#x}" , self . symbols [ i ] . st_value) ,
80
+ self . symbols [ i ] . st_size. to_string( ) ,
81
+ elf:: to_str:: st_bind_to_string( self . symbols [ i ] . st_bind( ) )
58
82
. trim_start_matches( "STB_" )
59
83
. to_string( ) ,
60
- elf:: to_str:: st_vis_to_string( symbol . st_vis( ) )
84
+ elf:: to_str:: st_vis_to_string( self . symbols [ i ] . st_vis( ) )
61
85
. trim_start_matches( "STV_" )
62
86
. to_string( ) ,
63
- symbol . st_shndx. to_string( ) ,
87
+ self . symbols [ i ] . st_shndx. to_string( ) ,
64
88
]
65
89
} )
66
90
. collect ( )
67
91
}
68
92
}
69
93
94
+ impl Symbols {
95
+ /// Cycle sorting criteria.
96
+ pub fn cycle_sort ( & mut self ) {
97
+ match self . sort {
98
+ SortBy :: None => self . sort = SortBy :: Name ,
99
+ SortBy :: Name => self . sort = SortBy :: Value ,
100
+ SortBy :: Value => self . sort = SortBy :: None ,
101
+ }
102
+ }
103
+ }
104
+
70
105
/// ELF dynamic symbols wrapper.
71
106
#[ derive( Clone , Debug , Default ) ]
72
107
pub struct DynamicSymbols {
@@ -76,6 +111,8 @@ pub struct DynamicSymbols {
76
111
names : Vec < String > ,
77
112
/// Requirements.
78
113
requirements : Vec < String > ,
114
+ /// Sort by.
115
+ sort : SortBy ,
79
116
}
80
117
81
118
impl < ' a >
@@ -131,33 +168,55 @@ impl<'a>
131
168
. to_string ( )
132
169
} )
133
170
. collect ( ) ,
171
+ sort : SortBy :: default ( ) ,
134
172
} )
135
173
}
136
174
}
137
175
138
176
impl < ' a > Property < ' a > for DynamicSymbols {
139
177
fn items ( & self ) -> Vec < Vec < String > > {
140
- self . symbols
178
+ let mut indices: Vec < usize > = ( 0 ..self . symbols . len ( ) ) . collect ( ) ;
179
+ match self . sort {
180
+ SortBy :: Name => {
181
+ indices. sort_by ( |& a, & b| self . names [ a] . cmp ( & self . names [ b] ) ) ;
182
+ }
183
+ SortBy :: Value => {
184
+ indices. sort_by ( |& a, & b| self . symbols [ a] . st_value . cmp ( & self . symbols [ b] . st_value ) ) ;
185
+ }
186
+ SortBy :: None => { }
187
+ }
188
+
189
+ indices
141
190
. iter ( )
142
- . enumerate ( )
143
- . map ( |( i, symbol) | {
191
+ . map ( |& i| {
144
192
vec ! [
145
193
self . names[ i] . to_string( ) ,
146
194
self . requirements[ i] . to_string( ) ,
147
- elf:: to_str:: st_symtype_to_string( symbol . st_symtype( ) )
195
+ elf:: to_str:: st_symtype_to_string( self . symbols [ i ] . st_symtype( ) )
148
196
. trim_start_matches( "STT_" )
149
197
. to_string( ) ,
150
- format!( "{:#x}" , symbol . st_value) ,
151
- symbol . st_size. to_string( ) ,
152
- elf:: to_str:: st_bind_to_string( symbol . st_bind( ) )
198
+ format!( "{:#x}" , self . symbols [ i ] . st_value) ,
199
+ self . symbols [ i ] . st_size. to_string( ) ,
200
+ elf:: to_str:: st_bind_to_string( self . symbols [ i ] . st_bind( ) )
153
201
. trim_start_matches( "STB_" )
154
202
. to_string( ) ,
155
- elf:: to_str:: st_vis_to_string( symbol . st_vis( ) )
203
+ elf:: to_str:: st_vis_to_string( self . symbols [ i ] . st_vis( ) )
156
204
. trim_start_matches( "STV_" )
157
205
. to_string( ) ,
158
- symbol . st_shndx. to_string( ) ,
206
+ self . symbols [ i ] . st_shndx. to_string( ) ,
159
207
]
160
208
} )
161
209
. collect ( )
162
210
}
163
211
}
212
+
213
+ impl DynamicSymbols {
214
+ /// Cycle sorting criteria.
215
+ pub fn cycle_sort ( & mut self ) {
216
+ match self . sort {
217
+ SortBy :: None => self . sort = SortBy :: Name ,
218
+ SortBy :: Name => self . sort = SortBy :: Value ,
219
+ SortBy :: Value => self . sort = SortBy :: None ,
220
+ }
221
+ }
222
+ }
0 commit comments