@@ -62,12 +62,12 @@ static struct instruction *next_insn_same_func(struct objtool_file *file,
62
62
struct instruction * insn )
63
63
{
64
64
struct instruction * next = list_next_entry (insn , list );
65
- struct symbol * func = insn -> func ;
65
+ struct symbol * func = insn_func ( insn ) ;
66
66
67
67
if (!func )
68
68
return NULL ;
69
69
70
- if (& next -> list != & file -> insn_list && next -> func == func )
70
+ if (& next -> list != & file -> insn_list && insn_func ( next ) == func )
71
71
return next ;
72
72
73
73
/* Check if we're already in the subfunction: */
@@ -83,7 +83,7 @@ static struct instruction *prev_insn_same_sym(struct objtool_file *file,
83
83
{
84
84
struct instruction * prev = list_prev_entry (insn , list );
85
85
86
- if (& prev -> list != & file -> insn_list && prev -> func == insn -> func )
86
+ if (& prev -> list != & file -> insn_list && insn_func ( prev ) == insn_func ( insn ) )
87
87
return prev ;
88
88
89
89
return NULL ;
@@ -133,7 +133,7 @@ static bool is_sibling_call(struct instruction *insn)
133
133
* sibling call detection consistency between vmlinux.o and individual
134
134
* objects.
135
135
*/
136
- if (!insn -> func )
136
+ if (!insn_func ( insn ) )
137
137
return false;
138
138
139
139
/* An indirect jump is either a sibling call or a jump to a table. */
@@ -207,7 +207,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
207
207
return false;
208
208
209
209
insn = find_insn (file , func -> sec , func -> offset );
210
- if (!insn -> func )
210
+ if (!insn_func ( insn ) )
211
211
return false;
212
212
213
213
func_for_each_insn (file , func , insn ) {
@@ -243,7 +243,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
243
243
return false;
244
244
}
245
245
246
- return __dead_end_function (file , dest -> func , recursion + 1 );
246
+ return __dead_end_function (file , insn_func ( dest ) , recursion + 1 );
247
247
}
248
248
}
249
249
@@ -427,7 +427,10 @@ static int decode_instructions(struct objtool_file *file)
427
427
}
428
428
429
429
list_for_each_entry (func , & sec -> symbol_list , list ) {
430
- if (func -> type != STT_FUNC || func -> alias != func )
430
+ if (func -> type != STT_NOTYPE && func -> type != STT_FUNC )
431
+ continue ;
432
+
433
+ if (func -> return_thunk || func -> alias != func )
431
434
continue ;
432
435
433
436
if (!find_insn (file , sec , func -> offset )) {
@@ -437,9 +440,11 @@ static int decode_instructions(struct objtool_file *file)
437
440
}
438
441
439
442
sym_for_each_insn (file , func , insn ) {
440
- insn -> func = func ;
441
- if (insn -> type == INSN_ENDBR && list_empty (& insn -> call_node )) {
442
- if (insn -> offset == insn -> func -> offset ) {
443
+ insn -> sym = func ;
444
+ if (func -> type == STT_FUNC &&
445
+ insn -> type == INSN_ENDBR &&
446
+ list_empty (& insn -> call_node )) {
447
+ if (insn -> offset == func -> offset ) {
443
448
list_add_tail (& insn -> call_node , & file -> endbr_list );
444
449
file -> nr_endbr ++ ;
445
450
} else {
@@ -1397,19 +1402,19 @@ static void add_return_call(struct objtool_file *file, struct instruction *insn,
1397
1402
1398
1403
static bool same_function (struct instruction * insn1 , struct instruction * insn2 )
1399
1404
{
1400
- return insn1 -> func -> pfunc == insn2 -> func -> pfunc ;
1405
+ return insn_func ( insn1 ) -> pfunc == insn_func ( insn2 ) -> pfunc ;
1401
1406
}
1402
1407
1403
1408
static bool is_first_func_insn (struct objtool_file * file , struct instruction * insn )
1404
1409
{
1405
- if (insn -> offset == insn -> func -> offset )
1410
+ if (insn -> offset == insn_func ( insn ) -> offset )
1406
1411
return true;
1407
1412
1408
1413
if (opts .ibt ) {
1409
1414
struct instruction * prev = prev_insn_same_sym (file , insn );
1410
1415
1411
1416
if (prev && prev -> type == INSN_ENDBR &&
1412
- insn -> offset == insn -> func -> offset + prev -> len )
1417
+ insn -> offset == insn_func ( insn ) -> offset + prev -> len )
1413
1418
return true;
1414
1419
}
1415
1420
@@ -1450,7 +1455,7 @@ static int add_jump_destinations(struct objtool_file *file)
1450
1455
} else if (reloc -> sym -> return_thunk ) {
1451
1456
add_return_call (file , insn , true);
1452
1457
continue ;
1453
- } else if (insn -> func ) {
1458
+ } else if (insn_func ( insn ) ) {
1454
1459
/*
1455
1460
* External sibling call or internal sibling call with
1456
1461
* STT_FUNC reloc.
@@ -1492,8 +1497,8 @@ static int add_jump_destinations(struct objtool_file *file)
1492
1497
/*
1493
1498
* Cross-function jump.
1494
1499
*/
1495
- if (insn -> func && jump_dest -> func &&
1496
- insn -> func != jump_dest -> func ) {
1500
+ if (insn_func ( insn ) && insn_func ( jump_dest ) &&
1501
+ insn_func ( insn ) != insn_func ( jump_dest ) ) {
1497
1502
1498
1503
/*
1499
1504
* For GCC 8+, create parent/child links for any cold
@@ -1510,18 +1515,18 @@ static int add_jump_destinations(struct objtool_file *file)
1510
1515
* case where the parent function's only reference to a
1511
1516
* subfunction is through a jump table.
1512
1517
*/
1513
- if (!strstr (insn -> func -> name , ".cold" ) &&
1514
- strstr (jump_dest -> func -> name , ".cold" )) {
1515
- insn -> func -> cfunc = jump_dest -> func ;
1516
- jump_dest -> func -> pfunc = insn -> func ;
1518
+ if (!strstr (insn_func ( insn ) -> name , ".cold" ) &&
1519
+ strstr (insn_func ( jump_dest ) -> name , ".cold" )) {
1520
+ insn_func ( insn ) -> cfunc = insn_func ( jump_dest ) ;
1521
+ insn_func ( jump_dest ) -> pfunc = insn_func ( insn ) ;
1517
1522
1518
1523
} else if (!same_function (insn , jump_dest ) &&
1519
1524
is_first_func_insn (file , jump_dest )) {
1520
1525
/*
1521
1526
* Internal sibling call without reloc or with
1522
1527
* STT_SECTION reloc.
1523
1528
*/
1524
- add_call_dest (file , insn , jump_dest -> func , true);
1529
+ add_call_dest (file , insn , insn_func ( jump_dest ) , true);
1525
1530
continue ;
1526
1531
}
1527
1532
}
@@ -1572,7 +1577,7 @@ static int add_call_destinations(struct objtool_file *file)
1572
1577
return -1 ;
1573
1578
}
1574
1579
1575
- if (insn -> func && insn -> call_dest -> type != STT_FUNC ) {
1580
+ if (insn_func ( insn ) && insn -> call_dest -> type != STT_FUNC ) {
1576
1581
WARN_FUNC ("unsupported call to non-function" ,
1577
1582
insn -> sec , insn -> offset );
1578
1583
return -1 ;
@@ -1668,7 +1673,7 @@ static int handle_group_alt(struct objtool_file *file,
1668
1673
nop -> offset = special_alt -> new_off + special_alt -> new_len ;
1669
1674
nop -> len = special_alt -> orig_len - special_alt -> new_len ;
1670
1675
nop -> type = INSN_NOP ;
1671
- nop -> func = orig_insn -> func ;
1676
+ nop -> sym = orig_insn -> sym ;
1672
1677
nop -> alt_group = new_alt_group ;
1673
1678
nop -> ignore = orig_insn -> ignore_alts ;
1674
1679
}
@@ -1688,7 +1693,7 @@ static int handle_group_alt(struct objtool_file *file,
1688
1693
last_new_insn = insn ;
1689
1694
1690
1695
insn -> ignore = orig_insn -> ignore_alts ;
1691
- insn -> func = orig_insn -> func ;
1696
+ insn -> sym = orig_insn -> sym ;
1692
1697
insn -> alt_group = new_alt_group ;
1693
1698
1694
1699
/*
@@ -1882,7 +1887,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
1882
1887
struct reloc * reloc = table ;
1883
1888
struct instruction * dest_insn ;
1884
1889
struct alternative * alt ;
1885
- struct symbol * pfunc = insn -> func -> pfunc ;
1890
+ struct symbol * pfunc = insn_func ( insn ) -> pfunc ;
1886
1891
unsigned int prev_offset = 0 ;
1887
1892
1888
1893
/*
@@ -1909,7 +1914,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
1909
1914
break ;
1910
1915
1911
1916
/* Make sure the destination is in the same function: */
1912
- if (!dest_insn -> func || dest_insn -> func -> pfunc != pfunc )
1917
+ if (!insn_func ( dest_insn ) || insn_func ( dest_insn ) -> pfunc != pfunc )
1913
1918
break ;
1914
1919
1915
1920
alt = malloc (sizeof (* alt ));
@@ -1949,7 +1954,7 @@ static struct reloc *find_jump_table(struct objtool_file *file,
1949
1954
* it.
1950
1955
*/
1951
1956
for (;
1952
- insn && insn -> func && insn -> func -> pfunc == func ;
1957
+ insn && insn_func ( insn ) && insn_func ( insn ) -> pfunc == func ;
1953
1958
insn = insn -> first_jump_src ?: prev_insn_same_sym (file , insn )) {
1954
1959
1955
1960
if (insn != orig_insn && insn -> type == INSN_JUMP_DYNAMIC )
@@ -1966,7 +1971,7 @@ static struct reloc *find_jump_table(struct objtool_file *file,
1966
1971
if (!table_reloc )
1967
1972
continue ;
1968
1973
dest_insn = find_insn (file , table_reloc -> sym -> sec , table_reloc -> addend );
1969
- if (!dest_insn || !dest_insn -> func || dest_insn -> func -> pfunc != func )
1974
+ if (!dest_insn || !insn_func ( dest_insn ) || insn_func ( dest_insn ) -> pfunc != func )
1970
1975
continue ;
1971
1976
1972
1977
return table_reloc ;
@@ -2415,6 +2420,13 @@ static int decode_sections(struct objtool_file *file)
2415
2420
if (ret )
2416
2421
return ret ;
2417
2422
2423
+ /*
2424
+ * Must be before add_{jump_call}_destination.
2425
+ */
2426
+ ret = classify_symbols (file );
2427
+ if (ret )
2428
+ return ret ;
2429
+
2418
2430
ret = decode_instructions (file );
2419
2431
if (ret )
2420
2432
return ret ;
@@ -2433,13 +2445,6 @@ static int decode_sections(struct objtool_file *file)
2433
2445
if (ret )
2434
2446
return ret ;
2435
2447
2436
- /*
2437
- * Must be before add_{jump_call}_destination.
2438
- */
2439
- ret = classify_symbols (file );
2440
- if (ret )
2441
- return ret ;
2442
-
2443
2448
/*
2444
2449
* Must be before add_jump_destinations(), which depends on 'func'
2445
2450
* being set for alternatives, to enable proper sibling call detection.
@@ -2648,7 +2653,7 @@ static int update_cfi_state(struct instruction *insn,
2648
2653
2649
2654
/* stack operations don't make sense with an undefined CFA */
2650
2655
if (cfa -> base == CFI_UNDEFINED ) {
2651
- if (insn -> func ) {
2656
+ if (insn_func ( insn ) ) {
2652
2657
WARN_FUNC ("undefined stack state" , insn -> sec , insn -> offset );
2653
2658
return -1 ;
2654
2659
}
@@ -2994,7 +2999,7 @@ static int update_cfi_state(struct instruction *insn,
2994
2999
}
2995
3000
2996
3001
/* detect when asm code uses rbp as a scratch register */
2997
- if (opts .stackval && insn -> func && op -> src .reg == CFI_BP &&
3002
+ if (opts .stackval && insn_func ( insn ) && op -> src .reg == CFI_BP &&
2998
3003
cfa -> base != CFI_BP )
2999
3004
cfi -> bp_scratch = true;
3000
3005
break ;
@@ -3390,13 +3395,13 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
3390
3395
while (1 ) {
3391
3396
next_insn = next_insn_to_validate (file , insn );
3392
3397
3393
- if (func && insn -> func && func != insn -> func -> pfunc ) {
3398
+ if (func && insn_func ( insn ) && func != insn_func ( insn ) -> pfunc ) {
3394
3399
/* Ignore KCFI type preambles, which always fall through */
3395
3400
if (!strncmp (func -> name , "__cfi_" , 6 ))
3396
3401
return 0 ;
3397
3402
3398
3403
WARN ("%s() falls through to next function %s()" ,
3399
- func -> name , insn -> func -> name );
3404
+ func -> name , insn_func ( insn ) -> name );
3400
3405
return 1 ;
3401
3406
}
3402
3407
@@ -3638,7 +3643,7 @@ static int validate_unwind_hints(struct objtool_file *file, struct section *sec)
3638
3643
3639
3644
while (& insn -> list != & file -> insn_list && (!sec || insn -> sec == sec )) {
3640
3645
if (insn -> hint && !insn -> visited && !insn -> ignore ) {
3641
- ret = validate_branch (file , insn -> func , insn , state );
3646
+ ret = validate_branch (file , insn_func ( insn ) , insn , state );
3642
3647
if (ret && opts .backtrace )
3643
3648
BT_FUNC ("<=== (hint)" , insn );
3644
3649
warnings += ret ;
@@ -3861,7 +3866,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
3861
3866
* In this case we'll find a piece of code (whole function) that is not
3862
3867
* covered by a !section symbol. Ignore them.
3863
3868
*/
3864
- if (opts .link && !insn -> func ) {
3869
+ if (opts .link && !insn_func ( insn ) ) {
3865
3870
int size = find_symbol_hole_containing (insn -> sec , insn -> offset );
3866
3871
unsigned long end = insn -> offset + size ;
3867
3872
@@ -3885,21 +3890,21 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
3885
3890
/*
3886
3891
* If this hole jumps to a .cold function, mark it ignore too.
3887
3892
*/
3888
- if (insn -> jump_dest && insn -> jump_dest -> func &&
3889
- strstr (insn -> jump_dest -> func -> name , ".cold" )) {
3893
+ if (insn -> jump_dest && insn_func ( insn -> jump_dest ) &&
3894
+ strstr (insn_func ( insn -> jump_dest ) -> name , ".cold" )) {
3890
3895
struct instruction * dest = insn -> jump_dest ;
3891
- func_for_each_insn (file , dest -> func , dest )
3896
+ func_for_each_insn (file , insn_func ( dest ) , dest )
3892
3897
dest -> ignore = true;
3893
3898
}
3894
3899
}
3895
3900
3896
3901
return false;
3897
3902
}
3898
3903
3899
- if (!insn -> func )
3904
+ if (!insn_func ( insn ) )
3900
3905
return false;
3901
3906
3902
- if (insn -> func -> static_call_tramp )
3907
+ if (insn_func ( insn ) -> static_call_tramp )
3903
3908
return true;
3904
3909
3905
3910
/*
@@ -3930,15 +3935,15 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
3930
3935
3931
3936
if (insn -> type == INSN_JUMP_UNCONDITIONAL ) {
3932
3937
if (insn -> jump_dest &&
3933
- insn -> jump_dest -> func == insn -> func ) {
3938
+ insn_func ( insn -> jump_dest ) == insn_func ( insn ) ) {
3934
3939
insn = insn -> jump_dest ;
3935
3940
continue ;
3936
3941
}
3937
3942
3938
3943
break ;
3939
3944
}
3940
3945
3941
- if (insn -> offset + insn -> len >= insn -> func -> offset + insn -> func -> len )
3946
+ if (insn -> offset + insn -> len >= insn_func ( insn ) -> offset + insn_func ( insn ) -> len )
3942
3947
break ;
3943
3948
3944
3949
insn = list_next_entry (insn , list );
@@ -3967,7 +3972,7 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
3967
3972
3968
3973
state -> uaccess = sym -> uaccess_safe ;
3969
3974
3970
- ret = validate_branch (file , insn -> func , insn , * state );
3975
+ ret = validate_branch (file , insn_func ( insn ) , insn , * state );
3971
3976
if (ret && opts .backtrace )
3972
3977
BT_FUNC ("<=== (sym)" , insn );
3973
3978
return ret ;
@@ -4104,7 +4109,7 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn
4104
4109
continue ;
4105
4110
}
4106
4111
4107
- if (dest -> func && dest -> func == insn -> func ) {
4112
+ if (insn_func ( dest ) && insn_func ( dest ) == insn_func ( insn ) ) {
4108
4113
/*
4109
4114
* Anything from->to self is either _THIS_IP_ or
4110
4115
* IRET-to-self.
0 commit comments