@@ -27,6 +27,90 @@ static inline u32 str_hash(const char *str)
27
27
return jhash (str , strlen (str ), 0 );
28
28
}
29
29
30
+ static void rb_add (struct rb_root * tree , struct rb_node * node ,
31
+ int (* cmp )(struct rb_node * , const struct rb_node * ))
32
+ {
33
+ struct rb_node * * link = & tree -> rb_node ;
34
+ struct rb_node * parent = NULL ;
35
+
36
+ while (* link ) {
37
+ parent = * link ;
38
+ if (cmp (node , parent ) < 0 )
39
+ link = & parent -> rb_left ;
40
+ else
41
+ link = & parent -> rb_right ;
42
+ }
43
+
44
+ rb_link_node (node , parent , link );
45
+ rb_insert_color (node , tree );
46
+ }
47
+
48
+ static struct rb_node * rb_find_first (struct rb_root * tree , const void * key ,
49
+ int (* cmp )(const void * key , const struct rb_node * ))
50
+ {
51
+ struct rb_node * node = tree -> rb_node ;
52
+ struct rb_node * match = NULL ;
53
+
54
+ while (node ) {
55
+ int c = cmp (key , node );
56
+ if (c <= 0 ) {
57
+ if (!c )
58
+ match = node ;
59
+ node = node -> rb_left ;
60
+ } else if (c > 0 ) {
61
+ node = node -> rb_right ;
62
+ }
63
+ }
64
+
65
+ return match ;
66
+ }
67
+
68
+ static struct rb_node * rb_next_match (struct rb_node * node , const void * key ,
69
+ int (* cmp )(const void * key , const struct rb_node * ))
70
+ {
71
+ node = rb_next (node );
72
+ if (node && cmp (key , node ))
73
+ node = NULL ;
74
+ return node ;
75
+ }
76
+
77
+ #define rb_for_each (tree , node , key , cmp ) \
78
+ for ((node) = rb_find_first((tree), (key), (cmp)); \
79
+ (node); (node) = rb_next_match((node), (key), (cmp)))
80
+
81
+ static int symbol_to_offset (struct rb_node * a , const struct rb_node * b )
82
+ {
83
+ struct symbol * sa = rb_entry (a , struct symbol , node );
84
+ struct symbol * sb = rb_entry (b , struct symbol , node );
85
+
86
+ if (sa -> offset < sb -> offset )
87
+ return -1 ;
88
+ if (sa -> offset > sb -> offset )
89
+ return 1 ;
90
+
91
+ if (sa -> len < sb -> len )
92
+ return -1 ;
93
+ if (sa -> len > sb -> len )
94
+ return 1 ;
95
+
96
+ sa -> alias = sb ;
97
+
98
+ return 0 ;
99
+ }
100
+
101
+ static int symbol_by_offset (const void * key , const struct rb_node * node )
102
+ {
103
+ const struct symbol * s = rb_entry (node , struct symbol , node );
104
+ const unsigned long * o = key ;
105
+
106
+ if (* o < s -> offset )
107
+ return -1 ;
108
+ if (* o > s -> offset + s -> len )
109
+ return 1 ;
110
+
111
+ return 0 ;
112
+ }
113
+
30
114
struct section * find_section_by_name (struct elf * elf , const char * name )
31
115
{
32
116
struct section * sec ;
@@ -63,47 +147,69 @@ static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx)
63
147
64
148
struct symbol * find_symbol_by_offset (struct section * sec , unsigned long offset )
65
149
{
66
- struct symbol * sym ;
150
+ struct rb_node * node ;
67
151
68
- list_for_each_entry (sym , & sec -> symbol_list , list )
69
- if (sym -> type != STT_SECTION && sym -> offset == offset )
70
- return sym ;
152
+ rb_for_each (& sec -> symbol_tree , node , & offset , symbol_by_offset ) {
153
+ struct symbol * s = rb_entry (node , struct symbol , node );
154
+
155
+ if (s -> offset == offset && s -> type != STT_SECTION )
156
+ return s ;
157
+ }
71
158
72
159
return NULL ;
73
160
}
74
161
75
162
struct symbol * find_func_by_offset (struct section * sec , unsigned long offset )
76
163
{
77
- struct symbol * sym ;
164
+ struct rb_node * node ;
78
165
79
- list_for_each_entry (sym , & sec -> symbol_list , list )
80
- if (sym -> type == STT_FUNC && sym -> offset == offset )
81
- return sym ;
166
+ rb_for_each (& sec -> symbol_tree , node , & offset , symbol_by_offset ) {
167
+ struct symbol * s = rb_entry (node , struct symbol , node );
168
+
169
+ if (s -> offset == offset && s -> type == STT_FUNC )
170
+ return s ;
171
+ }
82
172
83
173
return NULL ;
84
174
}
85
175
86
- struct symbol * find_symbol_by_name (struct elf * elf , const char * name )
176
+ struct symbol * find_symbol_containing (struct section * sec , unsigned long offset )
87
177
{
88
- struct section * sec ;
89
- struct symbol * sym ;
178
+ struct rb_node * node ;
90
179
91
- list_for_each_entry (sec , & elf -> sections , list )
92
- list_for_each_entry (sym , & sec -> symbol_list , list )
93
- if (!strcmp (sym -> name , name ))
94
- return sym ;
180
+ rb_for_each (& sec -> symbol_tree , node , & offset , symbol_by_offset ) {
181
+ struct symbol * s = rb_entry (node , struct symbol , node );
182
+
183
+ if (s -> type != STT_SECTION )
184
+ return s ;
185
+ }
95
186
96
187
return NULL ;
97
188
}
98
189
99
- struct symbol * find_symbol_containing (struct section * sec , unsigned long offset )
190
+ struct symbol * find_containing_func (struct section * sec , unsigned long offset )
191
+ {
192
+ struct rb_node * node ;
193
+
194
+ rb_for_each (& sec -> symbol_tree , node , & offset , symbol_by_offset ) {
195
+ struct symbol * s = rb_entry (node , struct symbol , node );
196
+
197
+ if (s -> type == STT_FUNC )
198
+ return s ;
199
+ }
200
+
201
+ return NULL ;
202
+ }
203
+
204
+ struct symbol * find_symbol_by_name (struct elf * elf , const char * name )
100
205
{
206
+ struct section * sec ;
101
207
struct symbol * sym ;
102
208
103
- list_for_each_entry (sym , & sec -> symbol_list , list )
104
- if (sym -> type != STT_SECTION &&
105
- offset >= sym -> offset && offset < sym -> offset + sym -> len )
106
- return sym ;
209
+ list_for_each_entry (sec , & elf -> sections , list )
210
+ list_for_each_entry (sym , & sec -> symbol_list , list )
211
+ if (! strcmp ( sym -> name , name ) )
212
+ return sym ;
107
213
108
214
return NULL ;
109
215
}
@@ -130,18 +236,6 @@ struct rela *find_rela_by_dest(struct section *sec, unsigned long offset)
130
236
return find_rela_by_dest_range (sec , offset , 1 );
131
237
}
132
238
133
- struct symbol * find_containing_func (struct section * sec , unsigned long offset )
134
- {
135
- struct symbol * func ;
136
-
137
- list_for_each_entry (func , & sec -> symbol_list , list )
138
- if (func -> type == STT_FUNC && offset >= func -> offset &&
139
- offset < func -> offset + func -> len )
140
- return func ;
141
-
142
- return NULL ;
143
- }
144
-
145
239
static int read_sections (struct elf * elf )
146
240
{
147
241
Elf_Scn * s = NULL ;
@@ -225,8 +319,9 @@ static int read_sections(struct elf *elf)
225
319
static int read_symbols (struct elf * elf )
226
320
{
227
321
struct section * symtab , * sec ;
228
- struct symbol * sym , * pfunc , * alias ;
229
- struct list_head * entry , * tmp ;
322
+ struct symbol * sym , * pfunc ;
323
+ struct list_head * entry ;
324
+ struct rb_node * pnode ;
230
325
int symbols_nr , i ;
231
326
char * coldstr ;
232
327
@@ -245,7 +340,7 @@ static int read_symbols(struct elf *elf)
245
340
return -1 ;
246
341
}
247
342
memset (sym , 0 , sizeof (* sym ));
248
- alias = sym ;
343
+ sym -> alias = sym ;
249
344
250
345
sym -> idx = i ;
251
346
@@ -283,29 +378,12 @@ static int read_symbols(struct elf *elf)
283
378
sym -> offset = sym -> sym .st_value ;
284
379
sym -> len = sym -> sym .st_size ;
285
380
286
- /* sorted insert into a per-section list */
287
- entry = & sym -> sec -> symbol_list ;
288
- list_for_each_prev (tmp , & sym -> sec -> symbol_list ) {
289
- struct symbol * s ;
290
-
291
- s = list_entry (tmp , struct symbol , list );
292
-
293
- if (sym -> offset > s -> offset ) {
294
- entry = tmp ;
295
- break ;
296
- }
297
-
298
- if (sym -> offset == s -> offset ) {
299
- if (sym -> len && sym -> len == s -> len && alias == sym )
300
- alias = s ;
301
-
302
- if (sym -> len >= s -> len ) {
303
- entry = tmp ;
304
- break ;
305
- }
306
- }
307
- }
308
- sym -> alias = alias ;
381
+ rb_add (& sym -> sec -> symbol_tree , & sym -> node , symbol_to_offset );
382
+ pnode = rb_prev (& sym -> node );
383
+ if (pnode )
384
+ entry = & rb_entry (pnode , struct symbol , node )-> list ;
385
+ else
386
+ entry = & sym -> sec -> symbol_list ;
309
387
list_add (& sym -> list , entry );
310
388
hash_add (elf -> symbol_hash , & sym -> hash , sym -> idx );
311
389
}
0 commit comments