xref: /openbmc/linux/tools/objtool/builtin-check.c (revision e983940270f10fe8551baf0098be76ea478294a3)
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 
717 	text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
718 	if (text_rela && text_rela->sym == file->rodata->sym) {
719 		/* case 1 */
720 		rodata_rela = find_rela_by_dest(file->rodata,
721 						text_rela->addend);
722 		if (rodata_rela)
723 			return rodata_rela;
724 
725 		/* case 2 */
726 		rodata_rela = find_rela_by_dest(file->rodata,
727 						text_rela->addend + 4);
728 		if (!rodata_rela)
729 			return NULL;
730 		file->ignore_unreachables = true;
731 		return rodata_rela;
732 	}
733 
734 	/* case 3 */
735 	func_for_each_insn_continue_reverse(file, func, insn) {
736 		if (insn->type == INSN_JUMP_UNCONDITIONAL ||
737 		    insn->type == INSN_JUMP_DYNAMIC)
738 			break;
739 
740 		text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
741 						    insn->len);
742 		if (text_rela && text_rela->sym == file->rodata->sym)
743 			return find_rela_by_dest(file->rodata,
744 						 text_rela->addend);
745 	}
746 
747 	return NULL;
748 }
749 
750 static int add_func_switch_tables(struct objtool_file *file,
751 				  struct symbol *func)
752 {
753 	struct instruction *insn, *prev_jump = NULL;
754 	struct rela *rela, *prev_rela = NULL;
755 	int ret;
756 
757 	func_for_each_insn(file, func, insn) {
758 		if (insn->type != INSN_JUMP_DYNAMIC)
759 			continue;
760 
761 		rela = find_switch_table(file, func, insn);
762 		if (!rela)
763 			continue;
764 
765 		/*
766 		 * We found a switch table, but we don't know yet how big it
767 		 * is.  Don't add it until we reach the end of the function or
768 		 * the beginning of another switch table in the same function.
769 		 */
770 		if (prev_jump) {
771 			ret = add_switch_table(file, func, prev_jump, prev_rela,
772 					       rela);
773 			if (ret)
774 				return ret;
775 		}
776 
777 		prev_jump = insn;
778 		prev_rela = rela;
779 	}
780 
781 	if (prev_jump) {
782 		ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
783 		if (ret)
784 			return ret;
785 	}
786 
787 	return 0;
788 }
789 
790 /*
791  * For some switch statements, gcc generates a jump table in the .rodata
792  * section which contains a list of addresses within the function to jump to.
793  * This finds these jump tables and adds them to the insn->alts lists.
794  */
795 static int add_switch_table_alts(struct objtool_file *file)
796 {
797 	struct section *sec;
798 	struct symbol *func;
799 	int ret;
800 
801 	if (!file->rodata || !file->rodata->rela)
802 		return 0;
803 
804 	list_for_each_entry(sec, &file->elf->sections, list) {
805 		list_for_each_entry(func, &sec->symbol_list, list) {
806 			if (func->type != STT_FUNC)
807 				continue;
808 
809 			ret = add_func_switch_tables(file, func);
810 			if (ret)
811 				return ret;
812 		}
813 	}
814 
815 	return 0;
816 }
817 
818 static int decode_sections(struct objtool_file *file)
819 {
820 	int ret;
821 
822 	ret = decode_instructions(file);
823 	if (ret)
824 		return ret;
825 
826 	add_ignores(file);
827 
828 	ret = add_jump_destinations(file);
829 	if (ret)
830 		return ret;
831 
832 	ret = add_call_destinations(file);
833 	if (ret)
834 		return ret;
835 
836 	ret = add_special_section_alts(file);
837 	if (ret)
838 		return ret;
839 
840 	ret = add_switch_table_alts(file);
841 	if (ret)
842 		return ret;
843 
844 	return 0;
845 }
846 
847 static bool is_fentry_call(struct instruction *insn)
848 {
849 	if (insn->type == INSN_CALL &&
850 	    insn->call_dest->type == STT_NOTYPE &&
851 	    !strcmp(insn->call_dest->name, "__fentry__"))
852 		return true;
853 
854 	return false;
855 }
856 
857 static bool has_modified_stack_frame(struct instruction *insn)
858 {
859 	return (insn->state & STATE_FP_SAVED) ||
860 	       (insn->state & STATE_FP_SETUP);
861 }
862 
863 static bool has_valid_stack_frame(struct instruction *insn)
864 {
865 	return (insn->state & STATE_FP_SAVED) &&
866 	       (insn->state & STATE_FP_SETUP);
867 }
868 
869 static unsigned int frame_state(unsigned long state)
870 {
871 	return (state & (STATE_FP_SAVED | STATE_FP_SETUP));
872 }
873 
874 /*
875  * Follow the branch starting at the given instruction, and recursively follow
876  * any other branches (jumps).  Meanwhile, track the frame pointer state at
877  * each instruction and validate all the rules described in
878  * tools/objtool/Documentation/stack-validation.txt.
879  */
880 static int validate_branch(struct objtool_file *file,
881 			   struct instruction *first, unsigned char first_state)
882 {
883 	struct alternative *alt;
884 	struct instruction *insn;
885 	struct section *sec;
886 	struct symbol *func = NULL;
887 	unsigned char state;
888 	int ret;
889 
890 	insn = first;
891 	sec = insn->sec;
892 	state = first_state;
893 
894 	if (insn->alt_group && list_empty(&insn->alts)) {
895 		WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
896 			  sec, insn->offset);
897 		return 1;
898 	}
899 
900 	while (1) {
901 		if (file->c_file && insn->func) {
902 			if (func && func != insn->func) {
903 				WARN("%s() falls through to next function %s()",
904 				     func->name, insn->func->name);
905 				return 1;
906 			}
907 
908 			func = insn->func;
909 		}
910 
911 		if (insn->visited) {
912 			if (frame_state(insn->state) != frame_state(state)) {
913 				WARN_FUNC("frame pointer state mismatch",
914 					  sec, insn->offset);
915 				return 1;
916 			}
917 
918 			return 0;
919 		}
920 
921 		insn->visited = true;
922 		insn->state = state;
923 
924 		list_for_each_entry(alt, &insn->alts, list) {
925 			ret = validate_branch(file, alt->insn, state);
926 			if (ret)
927 				return 1;
928 		}
929 
930 		switch (insn->type) {
931 
932 		case INSN_FP_SAVE:
933 			if (!nofp) {
934 				if (state & STATE_FP_SAVED) {
935 					WARN_FUNC("duplicate frame pointer save",
936 						  sec, insn->offset);
937 					return 1;
938 				}
939 				state |= STATE_FP_SAVED;
940 			}
941 			break;
942 
943 		case INSN_FP_SETUP:
944 			if (!nofp) {
945 				if (state & STATE_FP_SETUP) {
946 					WARN_FUNC("duplicate frame pointer setup",
947 						  sec, insn->offset);
948 					return 1;
949 				}
950 				state |= STATE_FP_SETUP;
951 			}
952 			break;
953 
954 		case INSN_FP_RESTORE:
955 			if (!nofp) {
956 				if (has_valid_stack_frame(insn))
957 					state &= ~STATE_FP_SETUP;
958 
959 				state &= ~STATE_FP_SAVED;
960 			}
961 			break;
962 
963 		case INSN_RETURN:
964 			if (!nofp && has_modified_stack_frame(insn)) {
965 				WARN_FUNC("return without frame pointer restore",
966 					  sec, insn->offset);
967 				return 1;
968 			}
969 			return 0;
970 
971 		case INSN_CALL:
972 			if (is_fentry_call(insn)) {
973 				state |= STATE_FENTRY;
974 				break;
975 			}
976 
977 			ret = dead_end_function(file, insn->call_dest);
978 			if (ret == 1)
979 				return 0;
980 			if (ret == -1)
981 				return 1;
982 
983 			/* fallthrough */
984 		case INSN_CALL_DYNAMIC:
985 			if (!nofp && !has_valid_stack_frame(insn)) {
986 				WARN_FUNC("call without frame pointer save/setup",
987 					  sec, insn->offset);
988 				return 1;
989 			}
990 			break;
991 
992 		case INSN_JUMP_CONDITIONAL:
993 		case INSN_JUMP_UNCONDITIONAL:
994 			if (insn->jump_dest) {
995 				ret = validate_branch(file, insn->jump_dest,
996 						      state);
997 				if (ret)
998 					return 1;
999 			} else if (has_modified_stack_frame(insn)) {
1000 				WARN_FUNC("sibling call from callable instruction with changed frame pointer",
1001 					  sec, insn->offset);
1002 				return 1;
1003 			} /* else it's a sibling call */
1004 
1005 			if (insn->type == INSN_JUMP_UNCONDITIONAL)
1006 				return 0;
1007 
1008 			break;
1009 
1010 		case INSN_JUMP_DYNAMIC:
1011 			if (list_empty(&insn->alts) &&
1012 			    has_modified_stack_frame(insn)) {
1013 				WARN_FUNC("sibling call from callable instruction with changed frame pointer",
1014 					  sec, insn->offset);
1015 				return 1;
1016 			}
1017 
1018 			return 0;
1019 
1020 		case INSN_BUG:
1021 			return 0;
1022 
1023 		default:
1024 			break;
1025 		}
1026 
1027 		insn = next_insn_same_sec(file, insn);
1028 		if (!insn) {
1029 			WARN("%s: unexpected end of section", sec->name);
1030 			return 1;
1031 		}
1032 	}
1033 
1034 	return 0;
1035 }
1036 
1037 static bool is_gcov_insn(struct instruction *insn)
1038 {
1039 	struct rela *rela;
1040 	struct section *sec;
1041 	struct symbol *sym;
1042 	unsigned long offset;
1043 
1044 	rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
1045 	if (!rela)
1046 		return false;
1047 
1048 	if (rela->sym->type != STT_SECTION)
1049 		return false;
1050 
1051 	sec = rela->sym->sec;
1052 	offset = rela->addend + insn->offset + insn->len - rela->offset;
1053 
1054 	list_for_each_entry(sym, &sec->symbol_list, list) {
1055 		if (sym->type != STT_OBJECT)
1056 			continue;
1057 
1058 		if (offset >= sym->offset && offset < sym->offset + sym->len)
1059 			return (!memcmp(sym->name, "__gcov0.", 8));
1060 	}
1061 
1062 	return false;
1063 }
1064 
1065 static bool is_kasan_insn(struct instruction *insn)
1066 {
1067 	return (insn->type == INSN_CALL &&
1068 		!strcmp(insn->call_dest->name, "__asan_handle_no_return"));
1069 }
1070 
1071 static bool is_ubsan_insn(struct instruction *insn)
1072 {
1073 	return (insn->type == INSN_CALL &&
1074 		!strcmp(insn->call_dest->name,
1075 			"__ubsan_handle_builtin_unreachable"));
1076 }
1077 
1078 static bool ignore_unreachable_insn(struct symbol *func,
1079 				    struct instruction *insn)
1080 {
1081 	int i;
1082 
1083 	if (insn->type == INSN_NOP)
1084 		return true;
1085 
1086 	if (is_gcov_insn(insn))
1087 		return true;
1088 
1089 	/*
1090 	 * Check if this (or a subsequent) instruction is related to
1091 	 * CONFIG_UBSAN or CONFIG_KASAN.
1092 	 *
1093 	 * End the search at 5 instructions to avoid going into the weeds.
1094 	 */
1095 	for (i = 0; i < 5; i++) {
1096 
1097 		if (is_kasan_insn(insn) || is_ubsan_insn(insn))
1098 			return true;
1099 
1100 		if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) {
1101 			insn = insn->jump_dest;
1102 			continue;
1103 		}
1104 
1105 		if (insn->offset + insn->len >= func->offset + func->len)
1106 			break;
1107 		insn = list_next_entry(insn, list);
1108 	}
1109 
1110 	return false;
1111 }
1112 
1113 static int validate_functions(struct objtool_file *file)
1114 {
1115 	struct section *sec;
1116 	struct symbol *func;
1117 	struct instruction *insn;
1118 	int ret, warnings = 0;
1119 
1120 	list_for_each_entry(sec, &file->elf->sections, list) {
1121 		list_for_each_entry(func, &sec->symbol_list, list) {
1122 			if (func->type != STT_FUNC)
1123 				continue;
1124 
1125 			insn = find_insn(file, sec, func->offset);
1126 			if (!insn)
1127 				continue;
1128 
1129 			ret = validate_branch(file, insn, 0);
1130 			warnings += ret;
1131 		}
1132 	}
1133 
1134 	list_for_each_entry(sec, &file->elf->sections, list) {
1135 		list_for_each_entry(func, &sec->symbol_list, list) {
1136 			if (func->type != STT_FUNC)
1137 				continue;
1138 
1139 			func_for_each_insn(file, func, insn) {
1140 				if (insn->visited)
1141 					continue;
1142 
1143 				insn->visited = true;
1144 
1145 				if (file->ignore_unreachables || warnings ||
1146 				    ignore_unreachable_insn(func, insn))
1147 					continue;
1148 
1149 				WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
1150 				warnings++;
1151 			}
1152 		}
1153 	}
1154 
1155 	return warnings;
1156 }
1157 
1158 static int validate_uncallable_instructions(struct objtool_file *file)
1159 {
1160 	struct instruction *insn;
1161 	int warnings = 0;
1162 
1163 	for_each_insn(file, insn) {
1164 		if (!insn->visited && insn->type == INSN_RETURN) {
1165 			WARN_FUNC("return instruction outside of a callable function",
1166 				  insn->sec, insn->offset);
1167 			warnings++;
1168 		}
1169 	}
1170 
1171 	return warnings;
1172 }
1173 
1174 static void cleanup(struct objtool_file *file)
1175 {
1176 	struct instruction *insn, *tmpinsn;
1177 	struct alternative *alt, *tmpalt;
1178 
1179 	list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) {
1180 		list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) {
1181 			list_del(&alt->list);
1182 			free(alt);
1183 		}
1184 		list_del(&insn->list);
1185 		hash_del(&insn->hash);
1186 		free(insn);
1187 	}
1188 	elf_close(file->elf);
1189 }
1190 
1191 const char * const check_usage[] = {
1192 	"objtool check [<options>] file.o",
1193 	NULL,
1194 };
1195 
1196 int cmd_check(int argc, const char **argv)
1197 {
1198 	struct objtool_file file;
1199 	int ret, warnings = 0;
1200 
1201 	const struct option options[] = {
1202 		OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"),
1203 		OPT_END(),
1204 	};
1205 
1206 	argc = parse_options(argc, argv, options, check_usage, 0);
1207 
1208 	if (argc != 1)
1209 		usage_with_options(check_usage, options);
1210 
1211 	objname = argv[0];
1212 
1213 	file.elf = elf_open(objname);
1214 	if (!file.elf) {
1215 		fprintf(stderr, "error reading elf file %s\n", objname);
1216 		return 1;
1217 	}
1218 
1219 	INIT_LIST_HEAD(&file.insn_list);
1220 	hash_init(file.insn_hash);
1221 	file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard");
1222 	file.rodata = find_section_by_name(file.elf, ".rodata");
1223 	file.ignore_unreachables = false;
1224 	file.c_file = find_section_by_name(file.elf, ".comment");
1225 
1226 	ret = decode_sections(&file);
1227 	if (ret < 0)
1228 		goto out;
1229 	warnings += ret;
1230 
1231 	ret = validate_functions(&file);
1232 	if (ret < 0)
1233 		goto out;
1234 	warnings += ret;
1235 
1236 	ret = validate_uncallable_instructions(&file);
1237 	if (ret < 0)
1238 		goto out;
1239 	warnings += ret;
1240 
1241 out:
1242 	cleanup(&file);
1243 
1244 	/* ignore warnings for now until we get all the code cleaned up */
1245 	if (ret || warnings)
1246 		return 0;
1247 	return 0;
1248 }
1249