Skip to content

Commit

Permalink
objtool: optimize add_dead_ends for split sections
Browse files Browse the repository at this point in the history
Instead of iterating through all instructions to find the last
instruction each time .rela.discard.(un)reachable points beyond the
section, use find_insn to locate the last instruction by looking at
the last bytes of the section instead.

Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200421220843.188260-3-samitolvanen@google.com
  • Loading branch information
Sami Tolvanen authored and Peter Zijlstra committed May 15, 2020
1 parent 28fe1d7 commit 6b5dd71
Showing 1 changed file with 17 additions and 19 deletions.
36 changes: 17 additions & 19 deletions tools/objtool/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,19 @@ static int decode_instructions(struct objtool_file *file)
return ret;
}

static struct instruction *find_last_insn(struct objtool_file *file,
struct section *sec)
{
struct instruction *insn = NULL;
unsigned int offset;
unsigned int end = (sec->len > 10) ? sec->len - 10 : 0;

for (offset = sec->len - 1; offset >= end && !insn; offset--)
insn = find_insn(file, sec, offset);

return insn;
}

/*
* Mark "ud2" instructions and manually annotated dead ends.
*/
Expand All @@ -330,7 +343,6 @@ static int add_dead_ends(struct objtool_file *file)
struct section *sec;
struct rela *rela;
struct instruction *insn;
bool found;

/*
* By default, "ud2" is a dead end unless otherwise annotated, because
Expand All @@ -356,15 +368,8 @@ static int add_dead_ends(struct objtool_file *file)
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) {
insn = find_last_insn(file, rela->sym->sec);
if (!insn) {
WARN("can't find unreachable insn at %s+0x%x",
rela->sym->sec->name, rela->addend);
return -1;
Expand Down Expand Up @@ -398,15 +403,8 @@ static int add_dead_ends(struct objtool_file *file)
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) {
insn = find_last_insn(file, rela->sym->sec);
if (!insn) {
WARN("can't find reachable insn at %s+0x%x",
rela->sym->sec->name, rela->addend);
return -1;
Expand Down

0 comments on commit 6b5dd71

Please sign in to comment.