Messages in this thread Patch in this message | | | From | Kamalesh Babulal <> | Subject | [PATCH] objtool: Refactor insn search in add_dead_ends() | Date | Mon, 23 Oct 2017 10:31:08 +0530 |
| |
Move the search for instruction dead_end into helper function __add_dead_ends(), instead of duplicating the search for unreachable and reachable sections in add_dead_ends().
Cc: Ingo Molnar <mingo@kernel.org> Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> --- tools/objtool/check.c | 108 +++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 58 deletions(-)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index c0e26ad1fa7e..c82966b3ad96 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -303,36 +303,23 @@ static int decode_instructions(struct objtool_file *file) return ret; } -/* - * Mark "ud2" instructions and manually annotated dead ends. - */ -static int add_dead_ends(struct objtool_file *file) +static int __add_dead_ends(struct objtool_file *file, struct section *sec, + bool unreachable_sec) { - struct section *sec; - struct rela *rela; + char warn_str[12] = "unreachable"; struct instruction *insn; + struct rela *rela; bool found; - /* - * By default, "ud2" is a dead end unless otherwise annotated, because - * GCC 7 inserts it for certain divide-by-zero cases. - */ - for_each_insn(file, insn) - if (insn->type == INSN_BUG) - insn->dead_end = true; - - /* - * Check for manually annotated dead ends. - */ - sec = find_section_by_name(file->elf, ".rela.discard.unreachable"); - if (!sec) - goto reachable; + if (!unreachable_sec) + strcpy(warn_str, "reachable"); list_for_each_entry(rela, &sec->rela_list, list) { if (rela->sym->type != STT_SECTION) { - WARN("unexpected relocation symbol type in %s", sec->name); + WARN("Unexpected relocation symbol type in %s", sec->name); return -1; } + insn = find_insn(file, rela->sym->sec, rela->addend); if (insn) insn = list_prev_entry(insn, list); @@ -346,19 +333,54 @@ static int add_dead_ends(struct objtool_file *file) } if (!found) { - WARN("can't find unreachable insn at %s+0x%x", - rela->sym->sec->name, rela->addend); + WARN("can't find %s insn at %s+0x%x", + warn_str, rela->sym->sec->name, + rela->addend); return -1; } } else { - WARN("can't find unreachable insn at %s+0x%x", - rela->sym->sec->name, rela->addend); + WARN("can't find %s insn at %s+0x%x", + warn_str, rela->sym->sec->name, rela->addend); return -1; } - insn->dead_end = true; + /* + * reachable section's insn->dead_end are false. + */ + insn->dead_end = unreachable_sec; } + return 0; +} + +/* + * Mark "ud2" instructions and manually annotated dead ends. + */ +static int add_dead_ends(struct objtool_file *file) +{ + struct section *sec; + struct instruction *insn; + int ret; + + /* + * By default, "ud2" is a dead end unless otherwise annotated, because + * GCC 7 inserts it for certain divide-by-zero cases. + */ + for_each_insn(file, insn) + if (insn->type == INSN_BUG) + insn->dead_end = true; + + /* + * Check for manually annotated dead ends. + */ + sec = find_section_by_name(file->elf, ".rela.discard.unreachable"); + if (!sec) + goto reachable; + + ret = __add_dead_ends(file, sec, true); + if (ret == -1) + return ret; + reachable: /* * These manually annotated reachable checks are needed for GCC 4.4, @@ -370,38 +392,8 @@ static int add_dead_ends(struct objtool_file *file) if (!sec) return 0; - list_for_each_entry(rela, &sec->rela_list, list) { - if (rela->sym->type != STT_SECTION) { - WARN("unexpected relocation symbol type in %s", sec->name); - return -1; - } - insn = find_insn(file, rela->sym->sec, rela->addend); - if (insn) - insn = list_prev_entry(insn, list); - else if (rela->addend == rela->sym->sec->len) { - found = false; - list_for_each_entry_reverse(insn, &file->insn_list, list) { - if (insn->sec == rela->sym->sec) { - found = true; - break; - } - } - - if (!found) { - WARN("can't find reachable insn at %s+0x%x", - rela->sym->sec->name, rela->addend); - return -1; - } - } else { - WARN("can't find reachable insn at %s+0x%x", - rela->sym->sec->name, rela->addend); - return -1; - } - - insn->dead_end = false; - } - - return 0; + ret = __add_dead_ends(file, sec, false); + return ret; } /* -- 2.7.4
| |