Skip to content

Commit c84301d

Browse files
jpoimboeingomolnar
authored andcommitted
objtool: Ignore entire functions rather than instructions
STACK_FRAME_NON_STANDARD applies to functions. Use a function-specific ignore attribute in preparation for getting rid of insn->ignore. Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lore.kernel.org/r/4af13376567f83331a9372ae2bb25e11a3d0f055.1742852846.git.jpoimboe@kernel.org
1 parent eeff7ac commit c84301d

2 files changed

Lines changed: 19 additions & 17 deletions

File tree

tools/objtool/check.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,6 @@ static int create_direct_call_sections(struct objtool_file *file)
981981
*/
982982
static void add_ignores(struct objtool_file *file)
983983
{
984-
struct instruction *insn;
985984
struct section *rsec;
986985
struct symbol *func;
987986
struct reloc *reloc;
@@ -1008,8 +1007,7 @@ static void add_ignores(struct objtool_file *file)
10081007
continue;
10091008
}
10101009

1011-
func_for_each_insn(file, func, insn)
1012-
insn->ignore = true;
1010+
func->ignore = true;
10131011
}
10141012
}
10151013

@@ -1612,6 +1610,7 @@ static int add_call_destinations(struct objtool_file *file)
16121610
struct reloc *reloc;
16131611

16141612
for_each_insn(file, insn) {
1613+
struct symbol *func = insn_func(insn);
16151614
if (insn->type != INSN_CALL)
16161615
continue;
16171616

@@ -1622,15 +1621,15 @@ static int add_call_destinations(struct objtool_file *file)
16221621

16231622
add_call_dest(file, insn, dest, false);
16241623

1625-
if (insn->ignore)
1624+
if (func && func->ignore)
16261625
continue;
16271626

16281627
if (!insn_call_dest(insn)) {
16291628
WARN_INSN(insn, "unannotated intra-function call");
16301629
return -1;
16311630
}
16321631

1633-
if (insn_func(insn) && insn_call_dest(insn)->type != STT_FUNC) {
1632+
if (func && insn_call_dest(insn)->type != STT_FUNC) {
16341633
WARN_INSN(insn, "unsupported call to non-function");
16351634
return -1;
16361635
}
@@ -3470,6 +3469,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
34703469
u8 visited;
34713470
int ret;
34723471

3472+
if (func && func->ignore)
3473+
return 0;
3474+
34733475
sec = insn->sec;
34743476

34753477
while (1) {
@@ -3715,7 +3717,7 @@ static int validate_unwind_hint(struct objtool_file *file,
37153717
struct instruction *insn,
37163718
struct insn_state *state)
37173719
{
3718-
if (insn->hint && !insn->visited && !insn->ignore) {
3720+
if (insn->hint && !insn->visited) {
37193721
int ret = validate_branch(file, insn_func(insn), insn, *state);
37203722
if (ret)
37213723
BT_INSN(insn, "<=== (hint)");
@@ -3929,10 +3931,11 @@ static bool is_ubsan_insn(struct instruction *insn)
39293931

39303932
static bool ignore_unreachable_insn(struct objtool_file *file, struct instruction *insn)
39313933
{
3932-
int i;
3934+
struct symbol *func = insn_func(insn);
39333935
struct instruction *prev_insn;
3936+
int i;
39343937

3935-
if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP)
3938+
if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP || (func && func->ignore))
39363939
return true;
39373940

39383941
/*
@@ -3951,7 +3954,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
39513954
* In this case we'll find a piece of code (whole function) that is not
39523955
* covered by a !section symbol. Ignore them.
39533956
*/
3954-
if (opts.link && !insn_func(insn)) {
3957+
if (opts.link && !func) {
39553958
int size = find_symbol_hole_containing(insn->sec, insn->offset);
39563959
unsigned long end = insn->offset + size;
39573960

@@ -3977,19 +3980,17 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
39773980
*/
39783981
if (insn->jump_dest && insn_func(insn->jump_dest) &&
39793982
strstr(insn_func(insn->jump_dest)->name, ".cold")) {
3980-
struct instruction *dest = insn->jump_dest;
3981-
func_for_each_insn(file, insn_func(dest), dest)
3982-
dest->ignore = true;
3983+
insn_func(insn->jump_dest)->ignore = true;
39833984
}
39843985
}
39853986

39863987
return false;
39873988
}
39883989

3989-
if (!insn_func(insn))
3990+
if (!func)
39903991
return false;
39913992

3992-
if (insn_func(insn)->static_call_tramp)
3993+
if (func->static_call_tramp)
39933994
return true;
39943995

39953996
/*
@@ -4020,15 +4021,15 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
40204021

40214022
if (insn->type == INSN_JUMP_UNCONDITIONAL) {
40224023
if (insn->jump_dest &&
4023-
insn_func(insn->jump_dest) == insn_func(insn)) {
4024+
insn_func(insn->jump_dest) == func) {
40244025
insn = insn->jump_dest;
40254026
continue;
40264027
}
40274028

40284029
break;
40294030
}
40304031

4031-
if (insn->offset + insn->len >= insn_func(insn)->offset + insn_func(insn)->len)
4032+
if (insn->offset + insn->len >= func->offset + func->len)
40324033
break;
40334034

40344035
insn = next_insn_same_sec(file, insn);
@@ -4120,7 +4121,7 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
41204121
return 0;
41214122

41224123
insn = find_insn(file, sec, sym->offset);
4123-
if (!insn || insn->ignore || insn->visited)
4124+
if (!insn || insn->visited)
41244125
return 0;
41254126

41264127
state->uaccess = sym->uaccess_safe;

tools/objtool/include/objtool/elf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct symbol {
6868
u8 embedded_insn : 1;
6969
u8 local_label : 1;
7070
u8 frame_pointer : 1;
71+
u8 ignore : 1;
7172
u8 warnings : 2;
7273
struct list_head pv_target;
7374
struct reloc *relocs;

0 commit comments

Comments
 (0)