objtool: Improve rare switch jump table pattern detection
[cascardo/linux.git] / tools / objtool / builtin-check.c
1 /*
2  * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * objtool check:
20  *
21  * This command analyzes every .o file and ensures the validity of its stack
22  * trace metadata.  It enforces a set of rules on asm code and C inline
23  * assembly code so that stack traces can be reliable.
24  *
25  * For more information, see tools/objtool/Documentation/stack-validation.txt.
26  */
27
28 #include <string.h>
29 #include <stdlib.h>
30 #include <subcmd/parse-options.h>
31
32 #include "builtin.h"
33 #include "elf.h"
34 #include "special.h"
35 #include "arch.h"
36 #include "warn.h"
37
38 #include <linux/hashtable.h>
39
40 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
41
42 #define STATE_FP_SAVED          0x1
43 #define STATE_FP_SETUP          0x2
44 #define STATE_FENTRY            0x4
45
46 struct instruction {
47         struct list_head list;
48         struct hlist_node hash;
49         struct section *sec;
50         unsigned long offset;
51         unsigned int len, state;
52         unsigned char type;
53         unsigned long immediate;
54         bool alt_group, visited;
55         struct symbol *call_dest;
56         struct instruction *jump_dest;
57         struct list_head alts;
58         struct symbol *func;
59 };
60
61 struct alternative {
62         struct list_head list;
63         struct instruction *insn;
64 };
65
66 struct objtool_file {
67         struct elf *elf;
68         struct list_head insn_list;
69         DECLARE_HASHTABLE(insn_hash, 16);
70         struct section *rodata, *whitelist;
71         bool ignore_unreachables, c_file;
72 };
73
74 const char *objname;
75 static bool nofp;
76
77 static struct instruction *find_insn(struct objtool_file *file,
78                                      struct section *sec, unsigned long offset)
79 {
80         struct instruction *insn;
81
82         hash_for_each_possible(file->insn_hash, insn, hash, offset)
83                 if (insn->sec == sec && insn->offset == offset)
84                         return insn;
85
86         return NULL;
87 }
88
89 static struct instruction *next_insn_same_sec(struct objtool_file *file,
90                                               struct instruction *insn)
91 {
92         struct instruction *next = list_next_entry(insn, list);
93
94         if (&next->list == &file->insn_list || next->sec != insn->sec)
95                 return NULL;
96
97         return next;
98 }
99
100 #define for_each_insn(file, insn)                                       \
101         list_for_each_entry(insn, &file->insn_list, list)
102
103 #define func_for_each_insn(file, func, insn)                            \
104         for (insn = find_insn(file, func->sec, func->offset);           \
105              insn && &insn->list != &file->insn_list &&                 \
106                 insn->sec == func->sec &&                               \
107                 insn->offset < func->offset + func->len;                \
108              insn = list_next_entry(insn, list))
109
110 #define func_for_each_insn_continue_reverse(file, func, insn)           \
111         for (insn = list_prev_entry(insn, list);                        \
112              &insn->list != &file->insn_list &&                         \
113                 insn->sec == func->sec && insn->offset >= func->offset; \
114              insn = list_prev_entry(insn, list))
115
116 #define sec_for_each_insn_from(file, insn)                              \
117         for (; insn; insn = next_insn_same_sec(file, insn))
118
119
120 /*
121  * Check if the function has been manually whitelisted with the
122  * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted
123  * due to its use of a context switching instruction.
124  */
125 static bool ignore_func(struct objtool_file *file, struct symbol *func)
126 {
127         struct rela *rela;
128         struct instruction *insn;
129
130         /* check for STACK_FRAME_NON_STANDARD */
131         if (file->whitelist && file->whitelist->rela)
132                 list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) {
133                         if (rela->sym->type == STT_SECTION &&
134                             rela->sym->sec == func->sec &&
135                             rela->addend == func->offset)
136                                 return true;
137                         if (rela->sym->type == STT_FUNC && rela->sym == func)
138                                 return true;
139                 }
140
141         /* check if it has a context switching instruction */
142         func_for_each_insn(file, func, insn)
143                 if (insn->type == INSN_CONTEXT_SWITCH)
144                         return true;
145
146         return false;
147 }
148
149 /*
150  * This checks to see if the given function is a "noreturn" function.
151  *
152  * For global functions which are outside the scope of this object file, we
153  * have to keep a manual list of them.
154  *
155  * For local functions, we have to detect them manually by simply looking for
156  * the lack of a return instruction.
157  *
158  * Returns:
159  *  -1: error
160  *   0: no dead end
161  *   1: dead end
162  */
163 static int __dead_end_function(struct objtool_file *file, struct symbol *func,
164                                int recursion)
165 {
166         int i;
167         struct instruction *insn;
168         bool empty = true;
169
170         /*
171          * Unfortunately these have to be hard coded because the noreturn
172          * attribute isn't provided in ELF data.
173          */
174         static const char * const global_noreturns[] = {
175                 "__stack_chk_fail",
176                 "panic",
177                 "do_exit",
178                 "do_task_dead",
179                 "__module_put_and_exit",
180                 "complete_and_exit",
181                 "kvm_spurious_fault",
182                 "__reiserfs_panic",
183                 "lbug_with_loc"
184         };
185
186         if (func->bind == STB_WEAK)
187                 return 0;
188
189         if (func->bind == STB_GLOBAL)
190                 for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
191                         if (!strcmp(func->name, global_noreturns[i]))
192                                 return 1;
193
194         if (!func->sec)
195                 return 0;
196
197         func_for_each_insn(file, func, insn) {
198                 empty = false;
199
200                 if (insn->type == INSN_RETURN)
201                         return 0;
202         }
203
204         if (empty)
205                 return 0;
206
207         /*
208          * A function can have a sibling call instead of a return.  In that
209          * case, the function's dead-end status depends on whether the target
210          * of the sibling call returns.
211          */
212         func_for_each_insn(file, func, insn) {
213                 if (insn->sec != func->sec ||
214                     insn->offset >= func->offset + func->len)
215                         break;
216
217                 if (insn->type == INSN_JUMP_UNCONDITIONAL) {
218                         struct instruction *dest = insn->jump_dest;
219                         struct symbol *dest_func;
220
221                         if (!dest)
222                                 /* sibling call to another file */
223                                 return 0;
224
225                         if (dest->sec != func->sec ||
226                             dest->offset < func->offset ||
227                             dest->offset >= func->offset + func->len) {
228                                 /* local sibling call */
229                                 dest_func = find_symbol_by_offset(dest->sec,
230                                                                   dest->offset);
231                                 if (!dest_func)
232                                         continue;
233
234                                 if (recursion == 5) {
235                                         WARN_FUNC("infinite recursion (objtool bug!)",
236                                                   dest->sec, dest->offset);
237                                         return -1;
238                                 }
239
240                                 return __dead_end_function(file, dest_func,
241                                                            recursion + 1);
242                         }
243                 }
244
245                 if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
246                         /* sibling call */
247                         return 0;
248         }
249
250         return 1;
251 }
252
253 static int dead_end_function(struct objtool_file *file, struct symbol *func)
254 {
255         return __dead_end_function(file, func, 0);
256 }
257
258 /*
259  * Call the arch-specific instruction decoder for all the instructions and add
260  * them to the global instruction list.
261  */
262 static int decode_instructions(struct objtool_file *file)
263 {
264         struct section *sec;
265         struct symbol *func;
266         unsigned long offset;
267         struct instruction *insn;
268         int ret;
269
270         list_for_each_entry(sec, &file->elf->sections, list) {
271
272                 if (!(sec->sh.sh_flags & SHF_EXECINSTR))
273                         continue;
274
275                 for (offset = 0; offset < sec->len; offset += insn->len) {
276                         insn = malloc(sizeof(*insn));
277                         memset(insn, 0, sizeof(*insn));
278
279                         INIT_LIST_HEAD(&insn->alts);
280                         insn->sec = sec;
281                         insn->offset = offset;
282
283                         ret = arch_decode_instruction(file->elf, sec, offset,
284                                                       sec->len - offset,
285                                                       &insn->len, &insn->type,
286                                                       &insn->immediate);
287                         if (ret)
288                                 return ret;
289
290                         if (!insn->type || insn->type > INSN_LAST) {
291                                 WARN_FUNC("invalid instruction type %d",
292                                           insn->sec, insn->offset, insn->type);
293                                 return -1;
294                         }
295
296                         hash_add(file->insn_hash, &insn->hash, insn->offset);
297                         list_add_tail(&insn->list, &file->insn_list);
298                 }
299
300                 list_for_each_entry(func, &sec->symbol_list, list) {
301                         if (func->type != STT_FUNC)
302                                 continue;
303
304                         if (!find_insn(file, sec, func->offset)) {
305                                 WARN("%s(): can't find starting instruction",
306                                      func->name);
307                                 return -1;
308                         }
309
310                         func_for_each_insn(file, func, insn)
311                                 if (!insn->func)
312                                         insn->func = func;
313                 }
314         }
315
316         return 0;
317 }
318
319 /*
320  * Warnings shouldn't be reported for ignored functions.
321  */
322 static void add_ignores(struct objtool_file *file)
323 {
324         struct instruction *insn;
325         struct section *sec;
326         struct symbol *func;
327
328         list_for_each_entry(sec, &file->elf->sections, list) {
329                 list_for_each_entry(func, &sec->symbol_list, list) {
330                         if (func->type != STT_FUNC)
331                                 continue;
332
333                         if (!ignore_func(file, func))
334                                 continue;
335
336                         func_for_each_insn(file, func, insn)
337                                 insn->visited = true;
338                 }
339         }
340 }
341
342 /*
343  * Find the destination instructions for all jumps.
344  */
345 static int add_jump_destinations(struct objtool_file *file)
346 {
347         struct instruction *insn;
348         struct rela *rela;
349         struct section *dest_sec;
350         unsigned long dest_off;
351
352         for_each_insn(file, insn) {
353                 if (insn->type != INSN_JUMP_CONDITIONAL &&
354                     insn->type != INSN_JUMP_UNCONDITIONAL)
355                         continue;
356
357                 /* skip ignores */
358                 if (insn->visited)
359                         continue;
360
361                 rela = find_rela_by_dest_range(insn->sec, insn->offset,
362                                                insn->len);
363                 if (!rela) {
364                         dest_sec = insn->sec;
365                         dest_off = insn->offset + insn->len + insn->immediate;
366                 } else if (rela->sym->type == STT_SECTION) {
367                         dest_sec = rela->sym->sec;
368                         dest_off = rela->addend + 4;
369                 } else if (rela->sym->sec->idx) {
370                         dest_sec = rela->sym->sec;
371                         dest_off = rela->sym->sym.st_value + rela->addend + 4;
372                 } else {
373                         /* sibling call */
374                         insn->jump_dest = 0;
375                         continue;
376                 }
377
378                 insn->jump_dest = find_insn(file, dest_sec, dest_off);
379                 if (!insn->jump_dest) {
380
381                         /*
382                          * This is a special case where an alt instruction
383                          * jumps past the end of the section.  These are
384                          * handled later in handle_group_alt().
385                          */
386                         if (!strcmp(insn->sec->name, ".altinstr_replacement"))
387                                 continue;
388
389                         WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
390                                   insn->sec, insn->offset, dest_sec->name,
391                                   dest_off);
392                         return -1;
393                 }
394         }
395
396         return 0;
397 }
398
399 /*
400  * Find the destination instructions for all calls.
401  */
402 static int add_call_destinations(struct objtool_file *file)
403 {
404         struct instruction *insn;
405         unsigned long dest_off;
406         struct rela *rela;
407
408         for_each_insn(file, insn) {
409                 if (insn->type != INSN_CALL)
410                         continue;
411
412                 rela = find_rela_by_dest_range(insn->sec, insn->offset,
413                                                insn->len);
414                 if (!rela) {
415                         dest_off = insn->offset + insn->len + insn->immediate;
416                         insn->call_dest = find_symbol_by_offset(insn->sec,
417                                                                 dest_off);
418                         if (!insn->call_dest) {
419                                 WARN_FUNC("can't find call dest symbol at offset 0x%lx",
420                                           insn->sec, insn->offset, dest_off);
421                                 return -1;
422                         }
423                 } else if (rela->sym->type == STT_SECTION) {
424                         insn->call_dest = find_symbol_by_offset(rela->sym->sec,
425                                                                 rela->addend+4);
426                         if (!insn->call_dest ||
427                             insn->call_dest->type != STT_FUNC) {
428                                 WARN_FUNC("can't find call dest symbol at %s+0x%x",
429                                           insn->sec, insn->offset,
430                                           rela->sym->sec->name,
431                                           rela->addend + 4);
432                                 return -1;
433                         }
434                 } else
435                         insn->call_dest = rela->sym;
436         }
437
438         return 0;
439 }
440
441 /*
442  * The .alternatives section requires some extra special care, over and above
443  * what other special sections require:
444  *
445  * 1. Because alternatives are patched in-place, we need to insert a fake jump
446  *    instruction at the end so that validate_branch() skips all the original
447  *    replaced instructions when validating the new instruction path.
448  *
449  * 2. An added wrinkle is that the new instruction length might be zero.  In
450  *    that case the old instructions are replaced with noops.  We simulate that
451  *    by creating a fake jump as the only new instruction.
452  *
453  * 3. In some cases, the alternative section includes an instruction which
454  *    conditionally jumps to the _end_ of the entry.  We have to modify these
455  *    jumps' destinations to point back to .text rather than the end of the
456  *    entry in .altinstr_replacement.
457  *
458  * 4. It has been requested that we don't validate the !POPCNT feature path
459  *    which is a "very very small percentage of machines".
460  */
461 static int handle_group_alt(struct objtool_file *file,
462                             struct special_alt *special_alt,
463                             struct instruction *orig_insn,
464                             struct instruction **new_insn)
465 {
466         struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump;
467         unsigned long dest_off;
468
469         last_orig_insn = NULL;
470         insn = orig_insn;
471         sec_for_each_insn_from(file, insn) {
472                 if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
473                         break;
474
475                 if (special_alt->skip_orig)
476                         insn->type = INSN_NOP;
477
478                 insn->alt_group = true;
479                 last_orig_insn = insn;
480         }
481
482         if (!next_insn_same_sec(file, last_orig_insn)) {
483                 WARN("%s: don't know how to handle alternatives at end of section",
484                      special_alt->orig_sec->name);
485                 return -1;
486         }
487
488         fake_jump = malloc(sizeof(*fake_jump));
489         if (!fake_jump) {
490                 WARN("malloc failed");
491                 return -1;
492         }
493         memset(fake_jump, 0, sizeof(*fake_jump));
494         INIT_LIST_HEAD(&fake_jump->alts);
495         fake_jump->sec = special_alt->new_sec;
496         fake_jump->offset = -1;
497         fake_jump->type = INSN_JUMP_UNCONDITIONAL;
498         fake_jump->jump_dest = list_next_entry(last_orig_insn, list);
499
500         if (!special_alt->new_len) {
501                 *new_insn = fake_jump;
502                 return 0;
503         }
504
505         last_new_insn = NULL;
506         insn = *new_insn;
507         sec_for_each_insn_from(file, insn) {
508                 if (insn->offset >= special_alt->new_off + special_alt->new_len)
509                         break;
510
511                 last_new_insn = insn;
512
513                 if (insn->type != INSN_JUMP_CONDITIONAL &&
514                     insn->type != INSN_JUMP_UNCONDITIONAL)
515                         continue;
516
517                 if (!insn->immediate)
518                         continue;
519
520                 dest_off = insn->offset + insn->len + insn->immediate;
521                 if (dest_off == special_alt->new_off + special_alt->new_len)
522                         insn->jump_dest = fake_jump;
523
524                 if (!insn->jump_dest) {
525                         WARN_FUNC("can't find alternative jump destination",
526                                   insn->sec, insn->offset);
527                         return -1;
528                 }
529         }
530
531         if (!last_new_insn) {
532                 WARN_FUNC("can't find last new alternative instruction",
533                           special_alt->new_sec, special_alt->new_off);
534                 return -1;
535         }
536
537         list_add(&fake_jump->list, &last_new_insn->list);
538
539         return 0;
540 }
541
542 /*
543  * A jump table entry can either convert a nop to a jump or a jump to a nop.
544  * If the original instruction is a jump, make the alt entry an effective nop
545  * by just skipping the original instruction.
546  */
547 static int handle_jump_alt(struct objtool_file *file,
548                            struct special_alt *special_alt,
549                            struct instruction *orig_insn,
550                            struct instruction **new_insn)
551 {
552         if (orig_insn->type == INSN_NOP)
553                 return 0;
554
555         if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) {
556                 WARN_FUNC("unsupported instruction at jump label",
557                           orig_insn->sec, orig_insn->offset);
558                 return -1;
559         }
560
561         *new_insn = list_next_entry(orig_insn, list);
562         return 0;
563 }
564
565 /*
566  * Read all the special sections which have alternate instructions which can be
567  * patched in or redirected to at runtime.  Each instruction having alternate
568  * instruction(s) has them added to its insn->alts list, which will be
569  * traversed in validate_branch().
570  */
571 static int add_special_section_alts(struct objtool_file *file)
572 {
573         struct list_head special_alts;
574         struct instruction *orig_insn, *new_insn;
575         struct special_alt *special_alt, *tmp;
576         struct alternative *alt;
577         int ret;
578
579         ret = special_get_alts(file->elf, &special_alts);
580         if (ret)
581                 return ret;
582
583         list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
584                 alt = malloc(sizeof(*alt));
585                 if (!alt) {
586                         WARN("malloc failed");
587                         ret = -1;
588                         goto out;
589                 }
590
591                 orig_insn = find_insn(file, special_alt->orig_sec,
592                                       special_alt->orig_off);
593                 if (!orig_insn) {
594                         WARN_FUNC("special: can't find orig instruction",
595                                   special_alt->orig_sec, special_alt->orig_off);
596                         ret = -1;
597                         goto out;
598                 }
599
600                 new_insn = NULL;
601                 if (!special_alt->group || special_alt->new_len) {
602                         new_insn = find_insn(file, special_alt->new_sec,
603                                              special_alt->new_off);
604                         if (!new_insn) {
605                                 WARN_FUNC("special: can't find new instruction",
606                                           special_alt->new_sec,
607                                           special_alt->new_off);
608                                 ret = -1;
609                                 goto out;
610                         }
611                 }
612
613                 if (special_alt->group) {
614                         ret = handle_group_alt(file, special_alt, orig_insn,
615                                                &new_insn);
616                         if (ret)
617                                 goto out;
618                 } else if (special_alt->jump_or_nop) {
619                         ret = handle_jump_alt(file, special_alt, orig_insn,
620                                               &new_insn);
621                         if (ret)
622                                 goto out;
623                 }
624
625                 alt->insn = new_insn;
626                 list_add_tail(&alt->list, &orig_insn->alts);
627
628                 list_del(&special_alt->list);
629                 free(special_alt);
630         }
631
632 out:
633         return ret;
634 }
635
636 static int add_switch_table(struct objtool_file *file, struct symbol *func,
637                             struct instruction *insn, struct rela *table,
638                             struct rela *next_table)
639 {
640         struct rela *rela = table;
641         struct instruction *alt_insn;
642         struct alternative *alt;
643
644         list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
645                 if (rela == next_table)
646                         break;
647
648                 if (rela->sym->sec != insn->sec ||
649                     rela->addend <= func->offset ||
650                     rela->addend >= func->offset + func->len)
651                         break;
652
653                 alt_insn = find_insn(file, insn->sec, rela->addend);
654                 if (!alt_insn) {
655                         WARN("%s: can't find instruction at %s+0x%x",
656                              file->rodata->rela->name, insn->sec->name,
657                              rela->addend);
658                         return -1;
659                 }
660
661                 alt = malloc(sizeof(*alt));
662                 if (!alt) {
663                         WARN("malloc failed");
664                         return -1;
665                 }
666
667                 alt->insn = alt_insn;
668                 list_add_tail(&alt->list, &insn->alts);
669         }
670
671         return 0;
672 }
673
674 /*
675  * find_switch_table() - Given a dynamic jump, find the switch jump table in
676  * .rodata associated with it.
677  *
678  * There are 3 basic patterns:
679  *
680  * 1. jmpq *[rodata addr](,%reg,8)
681  *
682  *    This is the most common case by far.  It jumps to an address in a simple
683  *    jump table which is stored in .rodata.
684  *
685  * 2. jmpq *[rodata addr](%rip)
686  *
687  *    This is caused by a rare GCC quirk, currently only seen in three driver
688  *    functions in the kernel, only with certain obscure non-distro configs.
689  *
690  *    As part of an optimization, GCC makes a copy of an existing switch jump
691  *    table, modifies it, and then hard-codes the jump (albeit with an indirect
692  *    jump) to use a single entry in the table.  The rest of the jump table and
693  *    some of its jump targets remain as dead code.
694  *
695  *    In such a case we can just crudely ignore all unreachable instruction
696  *    warnings for the entire object file.  Ideally we would just ignore them
697  *    for the function, but that would require redesigning the code quite a
698  *    bit.  And honestly that's just not worth doing: unreachable instruction
699  *    warnings are of questionable value anyway, and this is such a rare issue.
700  *
701  * 3. mov [rodata addr],%reg1
702  *    ... some instructions ...
703  *    jmpq *(%reg1,%reg2,8)
704  *
705  *    This is a fairly uncommon pattern which is new for GCC 6.  As of this
706  *    writing, there are 11 occurrences of it in the allmodconfig kernel.
707  *
708  *    TODO: Once we have DWARF CFI and smarter instruction decoding logic,
709  *    ensure the same register is used in the mov and jump instructions.
710  */
711 static struct rela *find_switch_table(struct objtool_file *file,
712                                       struct symbol *func,
713                                       struct instruction *insn)
714 {
715         struct rela *text_rela, *rodata_rela;
716         struct instruction *orig_insn = insn;
717
718         text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
719         if (text_rela && text_rela->sym == file->rodata->sym) {
720                 /* case 1 */
721                 rodata_rela = find_rela_by_dest(file->rodata,
722                                                 text_rela->addend);
723                 if (rodata_rela)
724                         return rodata_rela;
725
726                 /* case 2 */
727                 rodata_rela = find_rela_by_dest(file->rodata,
728                                                 text_rela->addend + 4);
729                 if (!rodata_rela)
730                         return NULL;
731                 file->ignore_unreachables = true;
732                 return rodata_rela;
733         }
734
735         /* case 3 */
736         func_for_each_insn_continue_reverse(file, func, insn) {
737                 if (insn->type == INSN_JUMP_DYNAMIC)
738                         break;
739
740                 /* allow small jumps within the range */
741                 if (insn->type == INSN_JUMP_UNCONDITIONAL &&
742                     insn->jump_dest &&
743                     (insn->jump_dest->offset <= insn->offset ||
744                      insn->jump_dest->offset >= orig_insn->offset))
745                     break;
746
747                 text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
748                                                     insn->len);
749                 if (text_rela && text_rela->sym == file->rodata->sym)
750                         return find_rela_by_dest(file->rodata,
751                                                  text_rela->addend);
752         }
753
754         return NULL;
755 }
756
757 static int add_func_switch_tables(struct objtool_file *file,
758                                   struct symbol *func)
759 {
760         struct instruction *insn, *prev_jump = NULL;
761         struct rela *rela, *prev_rela = NULL;
762         int ret;
763
764         func_for_each_insn(file, func, insn) {
765                 if (insn->type != INSN_JUMP_DYNAMIC)
766                         continue;
767
768                 rela = find_switch_table(file, func, insn);
769                 if (!rela)
770                         continue;
771
772                 /*
773                  * We found a switch table, but we don't know yet how big it
774                  * is.  Don't add it until we reach the end of the function or
775                  * the beginning of another switch table in the same function.
776                  */
777                 if (prev_jump) {
778                         ret = add_switch_table(file, func, prev_jump, prev_rela,
779                                                rela);
780                         if (ret)
781                                 return ret;
782                 }
783
784                 prev_jump = insn;
785                 prev_rela = rela;
786         }
787
788         if (prev_jump) {
789                 ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
790                 if (ret)
791                         return ret;
792         }
793
794         return 0;
795 }
796
797 /*
798  * For some switch statements, gcc generates a jump table in the .rodata
799  * section which contains a list of addresses within the function to jump to.
800  * This finds these jump tables and adds them to the insn->alts lists.
801  */
802 static int add_switch_table_alts(struct objtool_file *file)
803 {
804         struct section *sec;
805         struct symbol *func;
806         int ret;
807
808         if (!file->rodata || !file->rodata->rela)
809                 return 0;
810
811         list_for_each_entry(sec, &file->elf->sections, list) {
812                 list_for_each_entry(func, &sec->symbol_list, list) {
813                         if (func->type != STT_FUNC)
814                                 continue;
815
816                         ret = add_func_switch_tables(file, func);
817                         if (ret)
818                                 return ret;
819                 }
820         }
821
822         return 0;
823 }
824
825 static int decode_sections(struct objtool_file *file)
826 {
827         int ret;
828
829         ret = decode_instructions(file);
830         if (ret)
831                 return ret;
832
833         add_ignores(file);
834
835         ret = add_jump_destinations(file);
836         if (ret)
837                 return ret;
838
839         ret = add_call_destinations(file);
840         if (ret)
841                 return ret;
842
843         ret = add_special_section_alts(file);
844         if (ret)
845                 return ret;
846
847         ret = add_switch_table_alts(file);
848         if (ret)
849                 return ret;
850
851         return 0;
852 }
853
854 static bool is_fentry_call(struct instruction *insn)
855 {
856         if (insn->type == INSN_CALL &&
857             insn->call_dest->type == STT_NOTYPE &&
858             !strcmp(insn->call_dest->name, "__fentry__"))
859                 return true;
860
861         return false;
862 }
863
864 static bool has_modified_stack_frame(struct instruction *insn)
865 {
866         return (insn->state & STATE_FP_SAVED) ||
867                (insn->state & STATE_FP_SETUP);
868 }
869
870 static bool has_valid_stack_frame(struct instruction *insn)
871 {
872         return (insn->state & STATE_FP_SAVED) &&
873                (insn->state & STATE_FP_SETUP);
874 }
875
876 static unsigned int frame_state(unsigned long state)
877 {
878         return (state & (STATE_FP_SAVED | STATE_FP_SETUP));
879 }
880
881 /*
882  * Follow the branch starting at the given instruction, and recursively follow
883  * any other branches (jumps).  Meanwhile, track the frame pointer state at
884  * each instruction and validate all the rules described in
885  * tools/objtool/Documentation/stack-validation.txt.
886  */
887 static int validate_branch(struct objtool_file *file,
888                            struct instruction *first, unsigned char first_state)
889 {
890         struct alternative *alt;
891         struct instruction *insn;
892         struct section *sec;
893         struct symbol *func = NULL;
894         unsigned char state;
895         int ret;
896
897         insn = first;
898         sec = insn->sec;
899         state = first_state;
900
901         if (insn->alt_group && list_empty(&insn->alts)) {
902                 WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
903                           sec, insn->offset);
904                 return 1;
905         }
906
907         while (1) {
908                 if (file->c_file && insn->func) {
909                         if (func && func != insn->func) {
910                                 WARN("%s() falls through to next function %s()",
911                                      func->name, insn->func->name);
912                                 return 1;
913                         }
914
915                         func = insn->func;
916                 }
917
918                 if (insn->visited) {
919                         if (frame_state(insn->state) != frame_state(state)) {
920                                 WARN_FUNC("frame pointer state mismatch",
921                                           sec, insn->offset);
922                                 return 1;
923                         }
924
925                         return 0;
926                 }
927
928                 insn->visited = true;
929                 insn->state = state;
930
931                 list_for_each_entry(alt, &insn->alts, list) {
932                         ret = validate_branch(file, alt->insn, state);
933                         if (ret)
934                                 return 1;
935                 }
936
937                 switch (insn->type) {
938
939                 case INSN_FP_SAVE:
940                         if (!nofp) {
941                                 if (state & STATE_FP_SAVED) {
942                                         WARN_FUNC("duplicate frame pointer save",
943                                                   sec, insn->offset);
944                                         return 1;
945                                 }
946                                 state |= STATE_FP_SAVED;
947                         }
948                         break;
949
950                 case INSN_FP_SETUP:
951                         if (!nofp) {
952                                 if (state & STATE_FP_SETUP) {
953                                         WARN_FUNC("duplicate frame pointer setup",
954                                                   sec, insn->offset);
955                                         return 1;
956                                 }
957                                 state |= STATE_FP_SETUP;
958                         }
959                         break;
960
961                 case INSN_FP_RESTORE:
962                         if (!nofp) {
963                                 if (has_valid_stack_frame(insn))
964                                         state &= ~STATE_FP_SETUP;
965
966                                 state &= ~STATE_FP_SAVED;
967                         }
968                         break;
969
970                 case INSN_RETURN:
971                         if (!nofp && has_modified_stack_frame(insn)) {
972                                 WARN_FUNC("return without frame pointer restore",
973                                           sec, insn->offset);
974                                 return 1;
975                         }
976                         return 0;
977
978                 case INSN_CALL:
979                         if (is_fentry_call(insn)) {
980                                 state |= STATE_FENTRY;
981                                 break;
982                         }
983
984                         ret = dead_end_function(file, insn->call_dest);
985                         if (ret == 1)
986                                 return 0;
987                         if (ret == -1)
988                                 return 1;
989
990                         /* fallthrough */
991                 case INSN_CALL_DYNAMIC:
992                         if (!nofp && !has_valid_stack_frame(insn)) {
993                                 WARN_FUNC("call without frame pointer save/setup",
994                                           sec, insn->offset);
995                                 return 1;
996                         }
997                         break;
998
999                 case INSN_JUMP_CONDITIONAL:
1000                 case INSN_JUMP_UNCONDITIONAL:
1001                         if (insn->jump_dest) {
1002                                 ret = validate_branch(file, insn->jump_dest,
1003                                                       state);
1004                                 if (ret)
1005                                         return 1;
1006                         } else if (has_modified_stack_frame(insn)) {
1007                                 WARN_FUNC("sibling call from callable instruction with changed frame pointer",
1008                                           sec, insn->offset);
1009                                 return 1;
1010                         } /* else it's a sibling call */
1011
1012                         if (insn->type == INSN_JUMP_UNCONDITIONAL)
1013                                 return 0;
1014
1015                         break;
1016
1017                 case INSN_JUMP_DYNAMIC:
1018                         if (list_empty(&insn->alts) &&
1019                             has_modified_stack_frame(insn)) {
1020                                 WARN_FUNC("sibling call from callable instruction with changed frame pointer",
1021                                           sec, insn->offset);
1022                                 return 1;
1023                         }
1024
1025                         return 0;
1026
1027                 case INSN_BUG:
1028                         return 0;
1029
1030                 default:
1031                         break;
1032                 }
1033
1034                 insn = next_insn_same_sec(file, insn);
1035                 if (!insn) {
1036                         WARN("%s: unexpected end of section", sec->name);
1037                         return 1;
1038                 }
1039         }
1040
1041         return 0;
1042 }
1043
1044 static bool is_gcov_insn(struct instruction *insn)
1045 {
1046         struct rela *rela;
1047         struct section *sec;
1048         struct symbol *sym;
1049         unsigned long offset;
1050
1051         rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
1052         if (!rela)
1053                 return false;
1054
1055         if (rela->sym->type != STT_SECTION)
1056                 return false;
1057
1058         sec = rela->sym->sec;
1059         offset = rela->addend + insn->offset + insn->len - rela->offset;
1060
1061         list_for_each_entry(sym, &sec->symbol_list, list) {
1062                 if (sym->type != STT_OBJECT)
1063                         continue;
1064
1065                 if (offset >= sym->offset && offset < sym->offset + sym->len)
1066                         return (!memcmp(sym->name, "__gcov0.", 8));
1067         }
1068
1069         return false;
1070 }
1071
1072 static bool is_kasan_insn(struct instruction *insn)
1073 {
1074         return (insn->type == INSN_CALL &&
1075                 !strcmp(insn->call_dest->name, "__asan_handle_no_return"));
1076 }
1077
1078 static bool is_ubsan_insn(struct instruction *insn)
1079 {
1080         return (insn->type == INSN_CALL &&
1081                 !strcmp(insn->call_dest->name,
1082                         "__ubsan_handle_builtin_unreachable"));
1083 }
1084
1085 static bool ignore_unreachable_insn(struct symbol *func,
1086                                     struct instruction *insn)
1087 {
1088         int i;
1089
1090         if (insn->type == INSN_NOP)
1091                 return true;
1092
1093         if (is_gcov_insn(insn))
1094                 return true;
1095
1096         /*
1097          * Check if this (or a subsequent) instruction is related to
1098          * CONFIG_UBSAN or CONFIG_KASAN.
1099          *
1100          * End the search at 5 instructions to avoid going into the weeds.
1101          */
1102         for (i = 0; i < 5; i++) {
1103
1104                 if (is_kasan_insn(insn) || is_ubsan_insn(insn))
1105                         return true;
1106
1107                 if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) {
1108                         insn = insn->jump_dest;
1109                         continue;
1110                 }
1111
1112                 if (insn->offset + insn->len >= func->offset + func->len)
1113                         break;
1114                 insn = list_next_entry(insn, list);
1115         }
1116
1117         return false;
1118 }
1119
1120 static int validate_functions(struct objtool_file *file)
1121 {
1122         struct section *sec;
1123         struct symbol *func;
1124         struct instruction *insn;
1125         int ret, warnings = 0;
1126
1127         list_for_each_entry(sec, &file->elf->sections, list) {
1128                 list_for_each_entry(func, &sec->symbol_list, list) {
1129                         if (func->type != STT_FUNC)
1130                                 continue;
1131
1132                         insn = find_insn(file, sec, func->offset);
1133                         if (!insn)
1134                                 continue;
1135
1136                         ret = validate_branch(file, insn, 0);
1137                         warnings += ret;
1138                 }
1139         }
1140
1141         list_for_each_entry(sec, &file->elf->sections, list) {
1142                 list_for_each_entry(func, &sec->symbol_list, list) {
1143                         if (func->type != STT_FUNC)
1144                                 continue;
1145
1146                         func_for_each_insn(file, func, insn) {
1147                                 if (insn->visited)
1148                                         continue;
1149
1150                                 insn->visited = true;
1151
1152                                 if (file->ignore_unreachables || warnings ||
1153                                     ignore_unreachable_insn(func, insn))
1154                                         continue;
1155
1156                                 WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
1157                                 warnings++;
1158                         }
1159                 }
1160         }
1161
1162         return warnings;
1163 }
1164
1165 static int validate_uncallable_instructions(struct objtool_file *file)
1166 {
1167         struct instruction *insn;
1168         int warnings = 0;
1169
1170         for_each_insn(file, insn) {
1171                 if (!insn->visited && insn->type == INSN_RETURN) {
1172                         WARN_FUNC("return instruction outside of a callable function",
1173                                   insn->sec, insn->offset);
1174                         warnings++;
1175                 }
1176         }
1177
1178         return warnings;
1179 }
1180
1181 static void cleanup(struct objtool_file *file)
1182 {
1183         struct instruction *insn, *tmpinsn;
1184         struct alternative *alt, *tmpalt;
1185
1186         list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
1187                 list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
1188                         list_del(&alt->list);
1189                         free(alt);
1190                 }
1191                 list_del(&insn->list);
1192                 hash_del(&insn->hash);
1193                 free(insn);
1194         }
1195         elf_close(file->elf);
1196 }
1197
1198 const char * const check_usage[] = {
1199         "objtool check [<options>] file.o",
1200         NULL,
1201 };
1202
1203 int cmd_check(int argc, const char **argv)
1204 {
1205         struct objtool_file file;
1206         int ret, warnings = 0;
1207
1208         const struct option options[] = {
1209                 OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"),
1210                 OPT_END(),
1211         };
1212
1213         argc = parse_options(argc, argv, options, check_usage, 0);
1214
1215         if (argc != 1)
1216                 usage_with_options(check_usage, options);
1217
1218         objname = argv[0];
1219
1220         file.elf = elf_open(objname);
1221         if (!file.elf) {
1222                 fprintf(stderr, "error reading elf file %s\n", objname);
1223                 return 1;
1224         }
1225
1226         INIT_LIST_HEAD(&file.insn_list);
1227         hash_init(file.insn_hash);
1228         file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard");
1229         file.rodata = find_section_by_name(file.elf, ".rodata");
1230         file.ignore_unreachables = false;
1231         file.c_file = find_section_by_name(file.elf, ".comment");
1232
1233         ret = decode_sections(&file);
1234         if (ret < 0)
1235                 goto out;
1236         warnings += ret;
1237
1238         ret = validate_functions(&file);
1239         if (ret < 0)
1240                 goto out;
1241         warnings += ret;
1242
1243         ret = validate_uncallable_instructions(&file);
1244         if (ret < 0)
1245                 goto out;
1246         warnings += ret;
1247
1248 out:
1249         cleanup(&file);
1250
1251         /* ignore warnings for now until we get all the code cleaned up */
1252         if (ret || warnings)
1253                 return 0;
1254         return 0;
1255 }