@@ -66,9 +66,8 @@ struct objtool_file {
66
66
const char * objname ;
67
67
static bool nofp ;
68
68
69
- static struct instruction * find_instruction (struct objtool_file * file ,
70
- struct section * sec ,
71
- unsigned long offset )
69
+ static struct instruction * find_insn (struct objtool_file * file ,
70
+ struct section * sec , unsigned long offset )
72
71
{
73
72
struct instruction * insn ;
74
73
@@ -79,6 +78,31 @@ static struct instruction *find_instruction(struct objtool_file *file,
79
78
return NULL ;
80
79
}
81
80
81
+ static struct instruction * next_insn_same_sec (struct objtool_file * file ,
82
+ struct instruction * insn )
83
+ {
84
+ struct instruction * next = list_next_entry (insn , list );
85
+
86
+ if (& next -> list == & file -> insns || next -> sec != insn -> sec )
87
+ return NULL ;
88
+
89
+ return next ;
90
+ }
91
+
92
+ #define for_each_insn (file , insn ) \
93
+ list_for_each_entry(insn, &file->insns, list)
94
+
95
+ #define func_for_each_insn (file , func , insn ) \
96
+ for (insn = find_insn(file, func->sec, func->offset); \
97
+ insn && &insn->list != &file->insns && \
98
+ insn->sec == func->sec && \
99
+ insn->offset < func->offset + func->len; \
100
+ insn = list_next_entry(insn, list))
101
+
102
+ #define sec_for_each_insn_from (file , insn ) \
103
+ for (; insn; insn = next_insn_same_sec(file, insn))
104
+
105
+
82
106
/*
83
107
* Check if the function has been manually whitelisted with the
84
108
* STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
@@ -99,16 +123,9 @@ static bool ignore_func(struct objtool_file *file, struct symbol *func)
99
123
return true;
100
124
101
125
/* check if it has a context switching instruction */
102
- insn = find_instruction (file , func -> sec , func -> offset );
103
- if (!insn )
104
- return false;
105
- list_for_each_entry_from (insn , & file -> insns , list ) {
106
- if (insn -> sec != func -> sec ||
107
- insn -> offset >= func -> offset + func -> len )
108
- break ;
126
+ func_for_each_insn (file , func , insn )
109
127
if (insn -> type == INSN_CONTEXT_SWITCH )
110
128
return true;
111
- }
112
129
113
130
return false;
114
131
}
@@ -131,7 +148,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
131
148
int recursion )
132
149
{
133
150
int i ;
134
- struct instruction * insn , * func_insn ;
151
+ struct instruction * insn ;
135
152
bool empty = true;
136
153
137
154
/*
@@ -160,16 +177,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
160
177
if (!func -> sec )
161
178
return 0 ;
162
179
163
- func_insn = find_instruction (file , func -> sec , func -> offset );
164
- if (!func_insn )
165
- return 0 ;
166
-
167
- insn = func_insn ;
168
- list_for_each_entry_from (insn , & file -> insns , list ) {
169
- if (insn -> sec != func -> sec ||
170
- insn -> offset >= func -> offset + func -> len )
171
- break ;
172
-
180
+ func_for_each_insn (file , func , insn ) {
173
181
empty = false;
174
182
175
183
if (insn -> type == INSN_RETURN )
@@ -184,8 +192,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
184
192
* case, the function's dead-end status depends on whether the target
185
193
* of the sibling call returns.
186
194
*/
187
- insn = func_insn ;
188
- list_for_each_entry_from (insn , & file -> insns , list ) {
195
+ func_for_each_insn (file , func , insn ) {
189
196
if (insn -> sec != func -> sec ||
190
197
insn -> offset >= func -> offset + func -> len )
191
198
break ;
@@ -294,17 +301,8 @@ static void get_ignores(struct objtool_file *file)
294
301
if (!ignore_func (file , func ))
295
302
continue ;
296
303
297
- insn = find_instruction (file , sec , func -> offset );
298
- if (!insn )
299
- continue ;
300
-
301
- list_for_each_entry_from (insn , & file -> insns , list ) {
302
- if (insn -> sec != func -> sec ||
303
- insn -> offset >= func -> offset + func -> len )
304
- break ;
305
-
304
+ func_for_each_insn (file , func , insn )
306
305
insn -> visited = true;
307
- }
308
306
}
309
307
}
310
308
}
@@ -319,7 +317,7 @@ static int get_jump_destinations(struct objtool_file *file)
319
317
struct section * dest_sec ;
320
318
unsigned long dest_off ;
321
319
322
- list_for_each_entry ( insn , & file -> insns , list ) {
320
+ for_each_insn ( file , insn ) {
323
321
if (insn -> type != INSN_JUMP_CONDITIONAL &&
324
322
insn -> type != INSN_JUMP_UNCONDITIONAL )
325
323
continue ;
@@ -345,7 +343,7 @@ static int get_jump_destinations(struct objtool_file *file)
345
343
continue ;
346
344
}
347
345
348
- insn -> jump_dest = find_instruction (file , dest_sec , dest_off );
346
+ insn -> jump_dest = find_insn (file , dest_sec , dest_off );
349
347
if (!insn -> jump_dest ) {
350
348
351
349
/*
@@ -375,7 +373,7 @@ static int get_call_destinations(struct objtool_file *file)
375
373
unsigned long dest_off ;
376
374
struct rela * rela ;
377
375
378
- list_for_each_entry ( insn , & file -> insns , list ) {
376
+ for_each_insn ( file , insn ) {
379
377
if (insn -> type != INSN_CALL )
380
378
continue ;
381
379
@@ -438,9 +436,8 @@ static int handle_group_alt(struct objtool_file *file,
438
436
439
437
last_orig_insn = NULL ;
440
438
insn = orig_insn ;
441
- list_for_each_entry_from (insn , & file -> insns , list ) {
442
- if (insn -> sec != special_alt -> orig_sec ||
443
- insn -> offset >= special_alt -> orig_off + special_alt -> orig_len )
439
+ sec_for_each_insn_from (file , insn ) {
440
+ if (insn -> offset >= special_alt -> orig_off + special_alt -> orig_len )
444
441
break ;
445
442
446
443
if (special_alt -> skip_orig )
@@ -450,8 +447,7 @@ static int handle_group_alt(struct objtool_file *file,
450
447
last_orig_insn = insn ;
451
448
}
452
449
453
- if (list_is_last (& last_orig_insn -> list , & file -> insns ) ||
454
- list_next_entry (last_orig_insn , list )-> sec != special_alt -> orig_sec ) {
450
+ if (!next_insn_same_sec (file , last_orig_insn )) {
455
451
WARN ("%s: don't know how to handle alternatives at end of section" ,
456
452
special_alt -> orig_sec -> name );
457
453
return -1 ;
@@ -476,9 +472,8 @@ static int handle_group_alt(struct objtool_file *file,
476
472
477
473
last_new_insn = NULL ;
478
474
insn = * new_insn ;
479
- list_for_each_entry_from (insn , & file -> insns , list ) {
480
- if (insn -> sec != special_alt -> new_sec ||
481
- insn -> offset >= special_alt -> new_off + special_alt -> new_len )
475
+ sec_for_each_insn_from (file , insn ) {
476
+ if (insn -> offset >= special_alt -> new_off + special_alt -> new_len )
482
477
break ;
483
478
484
479
last_new_insn = insn ;
@@ -561,8 +556,8 @@ static int get_special_section_alts(struct objtool_file *file)
561
556
goto out ;
562
557
}
563
558
564
- orig_insn = find_instruction (file , special_alt -> orig_sec ,
565
- special_alt -> orig_off );
559
+ orig_insn = find_insn (file , special_alt -> orig_sec ,
560
+ special_alt -> orig_off );
566
561
if (!orig_insn ) {
567
562
WARN_FUNC ("special: can't find orig instruction" ,
568
563
special_alt -> orig_sec , special_alt -> orig_off );
@@ -572,8 +567,8 @@ static int get_special_section_alts(struct objtool_file *file)
572
567
573
568
new_insn = NULL ;
574
569
if (!special_alt -> group || special_alt -> new_len ) {
575
- new_insn = find_instruction (file , special_alt -> new_sec ,
576
- special_alt -> new_off );
570
+ new_insn = find_insn (file , special_alt -> new_sec ,
571
+ special_alt -> new_off );
577
572
if (!new_insn ) {
578
573
WARN_FUNC ("special: can't find new instruction" ,
579
574
special_alt -> new_sec ,
@@ -619,7 +614,7 @@ static int get_switch_alts(struct objtool_file *file)
619
614
struct symbol * func ;
620
615
struct alternative * alt ;
621
616
622
- list_for_each_entry ( insn , & file -> insns , list ) {
617
+ for_each_insn ( file , insn ) {
623
618
if (insn -> type != INSN_JUMP_DYNAMIC )
624
619
continue ;
625
620
@@ -655,8 +650,7 @@ static int get_switch_alts(struct objtool_file *file)
655
650
rela -> addend >= func -> offset + func -> len )
656
651
break ;
657
652
658
- alt_insn = find_instruction (file , insn -> sec ,
659
- rela -> addend );
653
+ alt_insn = find_insn (file , insn -> sec , rela -> addend );
660
654
if (!alt_insn ) {
661
655
WARN ("%s: can't find instruction at %s+0x%x" ,
662
656
rodata -> rela -> name , insn -> sec -> name ,
@@ -881,9 +875,8 @@ static int validate_branch(struct objtool_file *file,
881
875
break ;
882
876
}
883
877
884
- insn = list_next_entry (insn , list );
885
-
886
- if (& insn -> list == & file -> insns || insn -> sec != sec ) {
878
+ insn = next_insn_same_sec (file , insn );
879
+ if (!insn ) {
887
880
WARN ("%s: unexpected end of section" , sec -> name );
888
881
warnings ++ ;
889
882
return warnings ;
@@ -934,8 +927,8 @@ static bool is_ubsan_insn(struct instruction *insn)
934
927
"__ubsan_handle_builtin_unreachable" ));
935
928
}
936
929
937
- static bool ignore_unreachable_insn (struct instruction * insn ,
938
- unsigned long func_end )
930
+ static bool ignore_unreachable_insn (struct symbol * func ,
931
+ struct instruction * insn )
939
932
{
940
933
int i ;
941
934
@@ -961,7 +954,7 @@ static bool ignore_unreachable_insn(struct instruction *insn,
961
954
continue ;
962
955
}
963
956
964
- if (insn -> offset + insn -> len >= func_end )
957
+ if (insn -> offset + insn -> len >= func -> offset + func -> len )
965
958
break ;
966
959
insn = list_next_entry (insn , list );
967
960
}
@@ -974,15 +967,14 @@ static int validate_functions(struct objtool_file *file)
974
967
struct section * sec ;
975
968
struct symbol * func ;
976
969
struct instruction * insn ;
977
- unsigned long func_end ;
978
970
int ret , warnings = 0 ;
979
971
980
972
list_for_each_entry (sec , & file -> elf -> sections , list ) {
981
973
list_for_each_entry (func , & sec -> symbols , list ) {
982
974
if (func -> type != STT_FUNC )
983
975
continue ;
984
976
985
- insn = find_instruction (file , sec , func -> offset );
977
+ insn = find_insn (file , sec , func -> offset );
986
978
if (!insn ) {
987
979
WARN ("%s(): can't find starting instruction" ,
988
980
func -> name );
@@ -1000,21 +992,11 @@ static int validate_functions(struct objtool_file *file)
1000
992
if (func -> type != STT_FUNC )
1001
993
continue ;
1002
994
1003
- insn = find_instruction (file , sec , func -> offset );
1004
- if (!insn )
1005
- continue ;
1006
-
1007
- func_end = func -> offset + func -> len ;
1008
-
1009
- list_for_each_entry_from (insn , & file -> insns , list ) {
1010
- if (insn -> sec != func -> sec ||
1011
- insn -> offset >= func_end )
1012
- break ;
1013
-
995
+ func_for_each_insn (file , func , insn ) {
1014
996
if (insn -> visited )
1015
997
continue ;
1016
998
1017
- if (!ignore_unreachable_insn (insn , func_end )) {
999
+ if (!ignore_unreachable_insn (func , insn )) {
1018
1000
WARN_FUNC ("function has unreachable instruction" , insn -> sec , insn -> offset );
1019
1001
warnings ++ ;
1020
1002
}
@@ -1032,7 +1014,7 @@ static int validate_uncallable_instructions(struct objtool_file *file)
1032
1014
struct instruction * insn ;
1033
1015
int warnings = 0 ;
1034
1016
1035
- list_for_each_entry ( insn , & file -> insns , list ) {
1017
+ for_each_insn ( file , insn ) {
1036
1018
if (!insn -> visited && insn -> type == INSN_RETURN ) {
1037
1019
WARN_FUNC ("return instruction outside of a callable function" ,
1038
1020
insn -> sec , insn -> offset );
0 commit comments