Re: [PATCH v3 26/26] objtool: Add STT_NOTYPE noinstr validation

From: Peter Zijlstra
Date: Wed Mar 25 2020 - 11:53:56 EST


On Wed, Mar 25, 2020 at 09:42:11AM -0500, Josh Poimboeuf wrote:
> Sure, but couldn't validate_unwind_hints() and
> validate_reachable_instructions() be changed to *only* run on
> .noinstr.text, for the vmlinux case? That might help converge the
> vmlinux and !vmlinux paths.

You're thinking something like so then?

--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2421,24 +2421,34 @@ static int validate_branch(struct objtoo
return 0;
}

-static int validate_unwind_hints(struct objtool_file *file)
+static int validate_unwind_hints(struct objtool_file *file, struct section *sec)
{
struct instruction *insn;
- int ret, warnings = 0;
struct insn_state state;
+ int ret, warnings = 0;

if (!file->hints)
return 0;

clear_insn_state(&state);

- for_each_insn(file, insn) {
+ if (sec) {
+ insn = find_insn(file, sec, 0);
+ if (!insn)
+ return 0;
+ } else {
+ insn = list_first_entry(&file->insn_list, typeof(*insn), list);
+ }
+
+ while (&insn->list != &file->insn_list && (!sec || insn->sec == sec)) {
if (insn->hint && !insn->visited) {
ret = validate_branch(file, insn->func, insn, state);
if (ret && backtrace)
BT_FUNC("<=== (hint)", insn);
warnings += ret;
}
+
+ insn = list_next_entry(insn, list);
}

return warnings;
@@ -2622,12 +2632,16 @@ static int validate_section(struct objto
static int validate_vmlinux_functions(struct objtool_file *file)
{
struct section *sec;
+ int warnings = 0;

sec = find_section_by_name(file->elf, ".noinstr.text");
if (!sec)
return 0;

- return validate_section(file, sec);
+ warnings += validate_section(file, sec);
+ warnings += validate_unwind_hints(file, sec);
+
+ return warnings;
}

static int validate_functions(struct objtool_file *file)
@@ -2712,7 +2726,7 @@ int check(const char *_objname, bool orc
goto out;
warnings += ret;

- ret = validate_unwind_hints(&file);
+ ret = validate_unwind_hints(&file, NULL);
if (ret < 0)
goto out;
warnings += ret;