Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

objtool: Detect missing __noreturn annotations

Most "unreachable instruction" warnings these days seem to actually be
the result of a missing __noreturn annotation. Add an explicit check
for that.

Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lore.kernel.org/r/6e2b93d8c65eaed6c4166a358269dc0ef01f890c.1681853186.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

+19 -1
+6
tools/objtool/Documentation/objtool.txt
··· 303 303 If it's not actually in a callable function (e.g. kernel entry code), 304 304 change ENDPROC to END. 305 305 306 + 3. file.o: warning: objtool: foo+0x48c: bar() is missing a __noreturn annotation 307 + 308 + The call from foo() to bar() doesn't return, but bar() is missing the 309 + __noreturn annotation. NOTE: In addition to adding the __noreturn 310 + annotation, the function name also needs to be added to 311 + 'global_noreturns' in tools/objtool/check.c. 306 312 307 313 4. file.o: warning: objtool: func(): can't find starting instruction 308 314 or
+13 -1
tools/objtool/check.c
··· 4507 4507 4508 4508 static int validate_reachable_instructions(struct objtool_file *file) 4509 4509 { 4510 - struct instruction *insn; 4510 + struct instruction *insn, *prev_insn; 4511 + struct symbol *call_dest; 4511 4512 int warnings = 0; 4512 4513 4513 4514 if (file->ignore_unreachables) ··· 4517 4516 for_each_insn(file, insn) { 4518 4517 if (insn->visited || ignore_unreachable_insn(file, insn)) 4519 4518 continue; 4519 + 4520 + prev_insn = prev_insn_same_sec(file, insn); 4521 + if (prev_insn && prev_insn->dead_end) { 4522 + call_dest = insn_call_dest(prev_insn); 4523 + if (call_dest) { 4524 + WARN_INSN(insn, "%s() is missing a __noreturn annotation", 4525 + call_dest->name); 4526 + warnings++; 4527 + continue; 4528 + } 4529 + } 4520 4530 4521 4531 WARN_INSN(insn, "unreachable instruction"); 4522 4532 warnings++;