Lines Matching refs:insn
26 struct instruction *insn; member
35 struct instruction *insn; in find_insn() local
37 hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, offset)) { in find_insn()
38 if (insn->sec == sec && insn->offset == offset) in find_insn()
39 return insn; in find_insn()
46 struct instruction *insn) in next_insn_same_sec() argument
48 struct instruction *next = list_next_entry(insn, list); in next_insn_same_sec()
50 if (!next || &next->list == &file->insn_list || next->sec != insn->sec) in next_insn_same_sec()
57 struct instruction *insn) in next_insn_same_func() argument
59 struct instruction *next = list_next_entry(insn, list); in next_insn_same_func()
60 struct symbol *func = insn->func; in next_insn_same_func()
77 struct instruction *insn) in prev_insn_same_sym() argument
79 struct instruction *prev = list_prev_entry(insn, list); in prev_insn_same_sym()
81 if (&prev->list != &file->insn_list && prev->func == insn->func) in prev_insn_same_sym()
87 #define func_for_each_insn(file, func, insn) \ argument
88 for (insn = find_insn(file, func->sec, func->offset); \
89 insn; \
90 insn = next_insn_same_func(file, insn))
92 #define sym_for_each_insn(file, sym, insn) \ argument
93 for (insn = find_insn(file, sym->sec, sym->offset); \
94 insn && &insn->list != &file->insn_list && \
95 insn->sec == sym->sec && \
96 insn->offset < sym->offset + sym->len; \
97 insn = list_next_entry(insn, list))
99 #define sym_for_each_insn_continue_reverse(file, sym, insn) \ argument
100 for (insn = list_prev_entry(insn, list); \
101 &insn->list != &file->insn_list && \
102 insn->sec == sym->sec && insn->offset >= sym->offset; \
103 insn = list_prev_entry(insn, list))
105 #define sec_for_each_insn_from(file, insn) \ argument
106 for (; insn; insn = next_insn_same_sec(file, insn))
108 #define sec_for_each_insn_continue(file, insn) \ argument
109 for (insn = next_insn_same_sec(file, insn); insn; \
110 insn = next_insn_same_sec(file, insn))
112 static bool is_sibling_call(struct instruction *insn) in is_sibling_call() argument
115 if (insn->type == INSN_JUMP_DYNAMIC) in is_sibling_call()
116 return list_empty(&insn->alts); in is_sibling_call()
118 if (!is_static_jump(insn)) in is_sibling_call()
122 return !!insn->call_dest; in is_sibling_call()
138 struct instruction *insn; in __dead_end_function() local
175 insn = find_insn(file, func->sec, func->offset); in __dead_end_function()
176 if (!insn->func) in __dead_end_function()
179 func_for_each_insn(file, func, insn) { in __dead_end_function()
182 if (insn->type == INSN_RETURN) in __dead_end_function()
194 func_for_each_insn(file, func, insn) { in __dead_end_function()
195 if (is_sibling_call(insn)) { in __dead_end_function()
196 struct instruction *dest = insn->jump_dest; in __dead_end_function()
260 struct instruction *insn; in decode_instructions() local
278 for (offset = 0; offset < sec->len; offset += insn->len) { in decode_instructions()
279 insn = malloc(sizeof(*insn)); in decode_instructions()
280 if (!insn) { in decode_instructions()
284 memset(insn, 0, sizeof(*insn)); in decode_instructions()
285 INIT_LIST_HEAD(&insn->alts); in decode_instructions()
286 INIT_LIST_HEAD(&insn->stack_ops); in decode_instructions()
287 init_cfi_state(&insn->cfi); in decode_instructions()
289 insn->sec = sec; in decode_instructions()
290 insn->offset = offset; in decode_instructions()
294 &insn->len, &insn->type, in decode_instructions()
295 &insn->immediate, in decode_instructions()
296 &insn->stack_ops); in decode_instructions()
300 hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset)); in decode_instructions()
301 list_add_tail(&insn->list, &file->insn_list); in decode_instructions()
315 sym_for_each_insn(file, func, insn) in decode_instructions()
316 insn->func = func; in decode_instructions()
326 free(insn); in decode_instructions()
333 struct instruction *insn = NULL; in find_last_insn() local
337 for (offset = sec->len - 1; offset >= end && !insn; offset--) in find_last_insn()
338 insn = find_insn(file, sec, offset); in find_last_insn()
340 return insn; in find_last_insn()
350 struct instruction *insn; in add_dead_ends() local
356 for_each_insn(file, insn) in add_dead_ends()
357 if (insn->type == INSN_BUG) in add_dead_ends()
358 insn->dead_end = true; in add_dead_ends()
372 insn = find_insn(file, reloc->sym->sec, reloc->addend); in add_dead_ends()
373 if (insn) in add_dead_ends()
374 insn = list_prev_entry(insn, list); in add_dead_ends()
376 insn = find_last_insn(file, reloc->sym->sec); in add_dead_ends()
377 if (!insn) { in add_dead_ends()
388 insn->dead_end = true; in add_dead_ends()
407 insn = find_insn(file, reloc->sym->sec, reloc->addend); in add_dead_ends()
408 if (insn) in add_dead_ends()
409 insn = list_prev_entry(insn, list); in add_dead_ends()
411 insn = find_last_insn(file, reloc->sym->sec); in add_dead_ends()
412 if (!insn) { in add_dead_ends()
423 insn->dead_end = false; in add_dead_ends()
434 struct instruction *insn; in create_static_call_sections() local
450 list_for_each_entry(insn, &file->static_call_list, static_call_node) in create_static_call_sections()
463 list_for_each_entry(insn, &file->static_call_list, static_call_node) { in create_static_call_sections()
475 reloc->sym = insn->sec->sym; in create_static_call_sections()
476 reloc->addend = insn->offset; in create_static_call_sections()
483 key_name = strdup(insn->call_dest->name); in create_static_call_sections()
511 reloc->addend = is_sibling_call(insn) ? STATIC_CALL_SITE_TAIL : 0; in create_static_call_sections()
531 struct instruction *insn; in add_ignores() local
557 func_for_each_insn(file, func, insn) in add_ignores()
558 insn->ignore = true; in add_ignores()
732 struct instruction *insn; in add_ignore_alternatives() local
744 insn = find_insn(file, reloc->sym->sec, reloc->addend); in add_ignore_alternatives()
745 if (!insn) { in add_ignore_alternatives()
750 insn->ignore_alts = true; in add_ignore_alternatives()
761 struct instruction *insn; in add_jump_destinations() local
766 for_each_insn(file, insn) { in add_jump_destinations()
767 if (!is_static_jump(insn)) in add_jump_destinations()
770 if (insn->offset == FAKE_JUMP_OFFSET) in add_jump_destinations()
773 reloc = find_reloc_by_dest_range(file->elf, insn->sec, in add_jump_destinations()
774 insn->offset, insn->len); in add_jump_destinations()
776 dest_sec = insn->sec; in add_jump_destinations()
777 dest_off = arch_jump_destination(insn); in add_jump_destinations()
790 if (insn->type == INSN_JUMP_UNCONDITIONAL) in add_jump_destinations()
791 insn->type = INSN_JUMP_DYNAMIC; in add_jump_destinations()
793 insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL; in add_jump_destinations()
795 insn->retpoline_safe = true; in add_jump_destinations()
799 insn->call_dest = reloc->sym; in add_jump_destinations()
800 if (insn->call_dest->static_call_tramp) { in add_jump_destinations()
801 list_add_tail(&insn->static_call_node, in add_jump_destinations()
807 insn->jump_dest = find_insn(file, dest_sec, dest_off); in add_jump_destinations()
808 if (!insn->jump_dest) { in add_jump_destinations()
815 if (!strcmp(insn->sec->name, ".altinstr_replacement")) in add_jump_destinations()
819 insn->sec, insn->offset, dest_sec->name, in add_jump_destinations()
827 if (insn->func && insn->jump_dest->func && in add_jump_destinations()
828 insn->func != insn->jump_dest->func) { in add_jump_destinations()
845 if (!strstr(insn->func->name, ".cold.") && in add_jump_destinations()
846 strstr(insn->jump_dest->func->name, ".cold.")) { in add_jump_destinations()
847 insn->func->cfunc = insn->jump_dest->func; in add_jump_destinations()
848 insn->jump_dest->func->pfunc = insn->func; in add_jump_destinations()
850 } else if (insn->jump_dest->func->pfunc != insn->func->pfunc && in add_jump_destinations()
851 insn->jump_dest->offset == insn->jump_dest->func->offset) { in add_jump_destinations()
854 insn->call_dest = insn->jump_dest->func; in add_jump_destinations()
855 if (insn->call_dest->static_call_tramp) { in add_jump_destinations()
856 list_add_tail(&insn->static_call_node, in add_jump_destinations()
866 static void remove_insn_ops(struct instruction *insn) in remove_insn_ops() argument
870 list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) { in remove_insn_ops()
892 struct instruction *insn; in add_call_destinations() local
896 for_each_insn(file, insn) { in add_call_destinations()
897 if (insn->type != INSN_CALL) in add_call_destinations()
900 reloc = find_reloc_by_dest_range(file->elf, insn->sec, in add_call_destinations()
901 insn->offset, insn->len); in add_call_destinations()
903 dest_off = arch_jump_destination(insn); in add_call_destinations()
904 insn->call_dest = find_call_destination(insn->sec, dest_off); in add_call_destinations()
906 if (insn->ignore) in add_call_destinations()
909 if (!insn->call_dest) { in add_call_destinations()
910 WARN_FUNC("unannotated intra-function call", insn->sec, insn->offset); in add_call_destinations()
914 if (insn->func && insn->call_dest->type != STT_FUNC) { in add_call_destinations()
916 insn->sec, insn->offset); in add_call_destinations()
922 insn->call_dest = find_call_destination(reloc->sym->sec, in add_call_destinations()
924 if (!insn->call_dest) { in add_call_destinations()
926 insn->sec, insn->offset, in add_call_destinations()
932 insn->call_dest = reloc->sym; in add_call_destinations()
939 if (insn->sec->noinstr && in add_call_destinations()
940 !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) { in add_call_destinations()
946 elf_write_insn(file->elf, insn->sec, in add_call_destinations()
947 insn->offset, insn->len, in add_call_destinations()
948 arch_nop_insn(insn->len)); in add_call_destinations()
949 insn->type = INSN_NOP; in add_call_destinations()
959 remove_insn_ops(insn); in add_call_destinations()
988 struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump = NULL; in handle_group_alt() local
993 insn = orig_insn; in handle_group_alt()
994 sec_for_each_insn_from(file, insn) { in handle_group_alt()
995 if (insn->offset >= special_alt->orig_off + special_alt->orig_len) in handle_group_alt()
998 insn->alt_group = alt_group; in handle_group_alt()
999 last_orig_insn = insn; in handle_group_alt()
1033 insn = *new_insn; in handle_group_alt()
1034 sec_for_each_insn_from(file, insn) { in handle_group_alt()
1037 if (insn->offset >= special_alt->new_off + special_alt->new_len) in handle_group_alt()
1040 last_new_insn = insn; in handle_group_alt()
1042 insn->ignore = orig_insn->ignore_alts; in handle_group_alt()
1043 insn->func = orig_insn->func; in handle_group_alt()
1044 insn->alt_group = alt_group; in handle_group_alt()
1054 alt_reloc = find_reloc_by_dest_range(file->elf, insn->sec, in handle_group_alt()
1055 insn->offset, insn->len); in handle_group_alt()
1057 !arch_support_alt_relocation(special_alt, insn, alt_reloc)) { in handle_group_alt()
1060 insn->sec, insn->offset); in handle_group_alt()
1064 if (!is_static_jump(insn)) in handle_group_alt()
1067 if (!insn->immediate) in handle_group_alt()
1070 dest_off = arch_jump_destination(insn); in handle_group_alt()
1077 insn->jump_dest = fake_jump; in handle_group_alt()
1080 if (!insn->jump_dest) { in handle_group_alt()
1082 insn->sec, insn->offset); in handle_group_alt()
1189 alt->insn = new_insn; in add_special_section_alts()
1202 static int add_jump_table(struct objtool_file *file, struct instruction *insn, in add_jump_table() argument
1208 struct symbol *pfunc = insn->func->pfunc; in add_jump_table()
1244 alt->insn = dest_insn; in add_jump_table()
1245 list_add_tail(&alt->list, &insn->alts); in add_jump_table()
1251 insn->sec, insn->offset); in add_jump_table()
1264 struct instruction *insn) in find_jump_table() argument
1267 struct instruction *dest_insn, *orig_insn = insn; in find_jump_table()
1275 insn && insn->func && insn->func->pfunc == func; in find_jump_table()
1276 insn = insn->first_jump_src ?: prev_insn_same_sym(file, insn)) { in find_jump_table()
1278 if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC) in find_jump_table()
1282 if (insn->type == INSN_JUMP_UNCONDITIONAL && in find_jump_table()
1283 insn->jump_dest && in find_jump_table()
1284 (insn->jump_dest->offset <= insn->offset || in find_jump_table()
1285 insn->jump_dest->offset > orig_insn->offset)) in find_jump_table()
1288 table_reloc = arch_find_switch_table(file, insn); in find_jump_table()
1308 struct instruction *insn, *last = NULL; in mark_func_jump_tables() local
1311 func_for_each_insn(file, func, insn) { in mark_func_jump_tables()
1313 last = insn; in mark_func_jump_tables()
1320 if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest && in mark_func_jump_tables()
1321 insn->offset > last->offset && in mark_func_jump_tables()
1322 insn->jump_dest->offset > insn->offset && in mark_func_jump_tables()
1323 !insn->jump_dest->first_jump_src) { in mark_func_jump_tables()
1325 insn->jump_dest->first_jump_src = insn; in mark_func_jump_tables()
1326 last = insn->jump_dest; in mark_func_jump_tables()
1329 if (insn->type != INSN_JUMP_DYNAMIC) in mark_func_jump_tables()
1332 reloc = find_jump_table(file, func, insn); in mark_func_jump_tables()
1335 insn->jump_table = reloc; in mark_func_jump_tables()
1343 struct instruction *insn; in add_func_jump_tables() local
1346 func_for_each_insn(file, func, insn) { in add_func_jump_tables()
1347 if (!insn->jump_table) in add_func_jump_tables()
1350 ret = add_jump_table(file, insn, insn->jump_table); in add_func_jump_tables()
1392 struct instruction *insn; in read_unwind_hints() local
1422 insn = find_insn(file, reloc->sym->sec, reloc->addend); in read_unwind_hints()
1423 if (!insn) { in read_unwind_hints()
1428 cfa = &insn->cfi.cfa; in read_unwind_hints()
1431 insn->ret_offset = hint->sp_offset; in read_unwind_hints()
1435 insn->hint = true; in read_unwind_hints()
1437 if (arch_decode_hint_reg(insn, hint->sp_reg)) { in read_unwind_hints()
1439 insn->sec, insn->offset, hint->sp_reg); in read_unwind_hints()
1444 insn->cfi.type = hint->type; in read_unwind_hints()
1445 insn->cfi.end = hint->end; in read_unwind_hints()
1454 struct instruction *insn; in read_retpoline_hints() local
1467 insn = find_insn(file, reloc->sym->sec, reloc->addend); in read_retpoline_hints()
1468 if (!insn) { in read_retpoline_hints()
1473 if (insn->type != INSN_JUMP_DYNAMIC && in read_retpoline_hints()
1474 insn->type != INSN_CALL_DYNAMIC) { in read_retpoline_hints()
1476 insn->sec, insn->offset); in read_retpoline_hints()
1480 insn->retpoline_safe = true; in read_retpoline_hints()
1489 struct instruction *insn; in read_instr_hints() local
1502 insn = find_insn(file, reloc->sym->sec, reloc->addend); in read_instr_hints()
1503 if (!insn) { in read_instr_hints()
1508 insn->instr--; in read_instr_hints()
1521 insn = find_insn(file, reloc->sym->sec, reloc->addend); in read_instr_hints()
1522 if (!insn) { in read_instr_hints()
1527 insn->instr++; in read_instr_hints()
1535 struct instruction *insn; in read_intra_function_calls() local
1552 insn = find_insn(file, reloc->sym->sec, reloc->addend); in read_intra_function_calls()
1553 if (!insn) { in read_intra_function_calls()
1558 if (insn->type != INSN_CALL) { in read_intra_function_calls()
1560 insn->sec, insn->offset); in read_intra_function_calls()
1569 insn->type = INSN_JUMP_UNCONDITIONAL; in read_intra_function_calls()
1571 dest_off = insn->offset + insn->len + insn->immediate; in read_intra_function_calls()
1572 insn->jump_dest = find_insn(file, insn->sec, dest_off); in read_intra_function_calls()
1573 if (!insn->jump_dest) { in read_intra_function_calls()
1575 insn->sec, insn->offset, in read_intra_function_calls()
1576 insn->sec->name, dest_off); in read_intra_function_calls()
1687 static bool is_fentry_call(struct instruction *insn) in is_fentry_call() argument
1689 if (insn->type == INSN_CALL && insn->call_dest && in is_fentry_call()
1690 insn->call_dest->type == STT_NOTYPE && in is_fentry_call()
1691 !strcmp(insn->call_dest->name, "__fentry__")) in is_fentry_call()
1697 static bool has_modified_stack_frame(struct instruction *insn, struct insn_state *state) in has_modified_stack_frame() argument
1699 u8 ret_offset = insn->ret_offset; in has_modified_stack_frame()
1743 static int update_cfi_state_regs(struct instruction *insn, in update_cfi_state_regs() argument
1836 static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi, in update_cfi_state() argument
1844 if (insn->func) { in update_cfi_state()
1845 WARN_FUNC("undefined stack state", insn->sec, insn->offset); in update_cfi_state()
1853 return update_cfi_state_regs(insn, cfi, op); in update_cfi_state()
1984 insn->sec, insn->offset); in update_cfi_state()
1995 insn->sec, insn->offset); in update_cfi_state()
2070 insn->sec, insn->offset); in update_cfi_state()
2113 if (!no_fp && insn->func && op->src.reg == CFI_BP && in update_cfi_state()
2149 insn->sec, insn->offset); in update_cfi_state()
2168 insn->sec, insn->offset); in update_cfi_state()
2181 insn->sec, insn->offset); in update_cfi_state()
2188 static int handle_insn_ops(struct instruction *insn, struct insn_state *state) in handle_insn_ops() argument
2192 list_for_each_entry(op, &insn->stack_ops, list) { in handle_insn_ops()
2196 res = update_cfi_state(insn, &state->cfi, op); in handle_insn_ops()
2200 if (insn->alt_group && memcmp(&state->cfi, &old_cfi, sizeof(struct cfi_state))) { in handle_insn_ops()
2201 WARN_FUNC("alternative modifies stack", insn->sec, insn->offset); in handle_insn_ops()
2210 insn->sec, insn->offset); in handle_insn_ops()
2230 static bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2) in insn_cfi_match() argument
2232 struct cfi_state *cfi1 = &insn->cfi; in insn_cfi_match()
2238 insn->sec, insn->offset, in insn_cfi_match()
2249 insn->sec, insn->offset, in insn_cfi_match()
2258 insn->sec, insn->offset, cfi1->type, cfi2->type); in insn_cfi_match()
2265 insn->sec, insn->offset, in insn_cfi_match()
2283 static inline const char *call_dest_name(struct instruction *insn) in call_dest_name() argument
2285 if (insn->call_dest) in call_dest_name()
2286 return insn->call_dest->name; in call_dest_name()
2317 static int validate_call(struct instruction *insn, struct insn_state *state) in validate_call() argument
2320 !noinstr_call_dest(insn->call_dest)) { in validate_call()
2322 insn->sec, insn->offset, call_dest_name(insn)); in validate_call()
2326 if (state->uaccess && !func_uaccess_safe(insn->call_dest)) { in validate_call()
2328 insn->sec, insn->offset, call_dest_name(insn)); in validate_call()
2334 insn->sec, insn->offset, call_dest_name(insn)); in validate_call()
2341 static int validate_sibling_call(struct instruction *insn, struct insn_state *state) in validate_sibling_call() argument
2343 if (has_modified_stack_frame(insn, state)) { in validate_sibling_call()
2345 insn->sec, insn->offset); in validate_sibling_call()
2349 return validate_call(insn, state); in validate_sibling_call()
2352 static int validate_return(struct symbol *func, struct instruction *insn, struct insn_state *state) in validate_return() argument
2356 insn->sec, insn->offset); in validate_return()
2362 insn->sec, insn->offset); in validate_return()
2368 insn->sec, insn->offset); in validate_return()
2374 insn->sec, insn->offset); in validate_return()
2378 if (func && has_modified_stack_frame(insn, state)) { in validate_return()
2380 insn->sec, insn->offset); in validate_return()
2386 insn->sec, insn->offset); in validate_return()
2405 static void fill_alternative_cfi(struct objtool_file *file, struct instruction *insn) in fill_alternative_cfi() argument
2407 struct instruction *first_insn = insn; in fill_alternative_cfi()
2408 int alt_group = insn->alt_group; in fill_alternative_cfi()
2410 sec_for_each_insn_continue(file, insn) { in fill_alternative_cfi()
2411 if (insn->alt_group != alt_group) in fill_alternative_cfi()
2413 insn->cfi = first_insn->cfi; in fill_alternative_cfi()
2424 struct instruction *insn, struct insn_state state) in validate_branch() argument
2432 sec = insn->sec; in validate_branch()
2435 next_insn = next_insn_same_sec(file, insn); in validate_branch()
2437 if (file->c_file && func && insn->func && func != insn->func->pfunc) { in validate_branch()
2439 func->name, insn->func->name); in validate_branch()
2443 if (func && insn->ignore) { in validate_branch()
2445 sec, insn->offset); in validate_branch()
2450 if (insn->visited) { in validate_branch()
2451 if (!insn->hint && !insn_cfi_match(insn, &state.cfi)) in validate_branch()
2454 if (insn->visited & visited) in validate_branch()
2459 state.instr += insn->instr; in validate_branch()
2461 if (insn->hint) in validate_branch()
2462 state.cfi = insn->cfi; in validate_branch()
2464 insn->cfi = state.cfi; in validate_branch()
2466 insn->visited |= visited; in validate_branch()
2468 if (!insn->ignore_alts && !list_empty(&insn->alts)) { in validate_branch()
2471 list_for_each_entry(alt, &insn->alts, list) { in validate_branch()
2475 ret = validate_branch(file, func, alt->insn, state); in validate_branch()
2478 BT_FUNC("(alt)", insn); in validate_branch()
2483 if (insn->alt_group) in validate_branch()
2484 fill_alternative_cfi(file, insn); in validate_branch()
2490 if (handle_insn_ops(insn, &state)) in validate_branch()
2493 switch (insn->type) { in validate_branch()
2496 return validate_return(func, insn, &state); in validate_branch()
2500 ret = validate_call(insn, &state); in validate_branch()
2504 if (!no_fp && func && !is_fentry_call(insn) && in validate_branch()
2507 sec, insn->offset); in validate_branch()
2511 if (dead_end_function(file, insn->call_dest)) in validate_branch()
2514 if (insn->type == INSN_CALL && insn->call_dest->static_call_tramp) { in validate_branch()
2515 list_add_tail(&insn->static_call_node, in validate_branch()
2523 if (func && is_sibling_call(insn)) { in validate_branch()
2524 ret = validate_sibling_call(insn, &state); in validate_branch()
2528 } else if (insn->jump_dest) { in validate_branch()
2530 insn->jump_dest, state); in validate_branch()
2533 BT_FUNC("(branch)", insn); in validate_branch()
2538 if (insn->type == INSN_JUMP_UNCONDITIONAL) in validate_branch()
2545 if (func && is_sibling_call(insn)) { in validate_branch()
2546 ret = validate_sibling_call(insn, &state); in validate_branch()
2551 if (insn->type == INSN_JUMP_DYNAMIC) in validate_branch()
2559 sec, insn->offset); in validate_branch()
2566 WARN_FUNC("recursive UACCESS enable", sec, insn->offset); in validate_branch()
2575 WARN_FUNC("redundant UACCESS disable", sec, insn->offset); in validate_branch()
2580 WARN_FUNC("UACCESS-safe disables UACCESS", sec, insn->offset); in validate_branch()
2589 WARN_FUNC("recursive STD", sec, insn->offset); in validate_branch()
2596 WARN_FUNC("redundant CLD", sec, insn->offset); in validate_branch()
2605 if (insn->dead_end) in validate_branch()
2615 insn = next_insn; in validate_branch()
2623 struct instruction *insn; in validate_unwind_hints() local
2633 insn = find_insn(file, sec, 0); in validate_unwind_hints()
2634 if (!insn) in validate_unwind_hints()
2637 insn = list_first_entry(&file->insn_list, typeof(*insn), list); in validate_unwind_hints()
2640 while (&insn->list != &file->insn_list && (!sec || insn->sec == sec)) { in validate_unwind_hints()
2641 if (insn->hint && !insn->visited) { in validate_unwind_hints()
2642 ret = validate_branch(file, insn->func, insn, state); in validate_unwind_hints()
2644 BT_FUNC("<=== (hint)", insn); in validate_unwind_hints()
2648 insn = list_next_entry(insn, list); in validate_unwind_hints()
2656 struct instruction *insn; in validate_retpoline() local
2659 for_each_insn(file, insn) { in validate_retpoline()
2660 if (insn->type != INSN_JUMP_DYNAMIC && in validate_retpoline()
2661 insn->type != INSN_CALL_DYNAMIC) in validate_retpoline()
2664 if (insn->retpoline_safe) in validate_retpoline()
2673 if (!strcmp(insn->sec->name, ".init.text") && !module) in validate_retpoline()
2677 insn->sec, insn->offset, in validate_retpoline()
2678 insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call"); in validate_retpoline()
2686 static bool is_kasan_insn(struct instruction *insn) in is_kasan_insn() argument
2688 return (insn->type == INSN_CALL && in is_kasan_insn()
2689 !strcmp(insn->call_dest->name, "__asan_handle_no_return")); in is_kasan_insn()
2692 static bool is_ubsan_insn(struct instruction *insn) in is_ubsan_insn() argument
2694 return (insn->type == INSN_CALL && in is_ubsan_insn()
2695 !strcmp(insn->call_dest->name, in is_ubsan_insn()
2699 static bool ignore_unreachable_insn(struct objtool_file *file, struct instruction *insn) in ignore_unreachable_insn() argument
2704 if (insn->ignore || insn->type == INSN_NOP) in ignore_unreachable_insn()
2714 if (!strcmp(insn->sec->name, ".fixup") || in ignore_unreachable_insn()
2715 !strcmp(insn->sec->name, ".altinstr_replacement") || in ignore_unreachable_insn()
2716 !strcmp(insn->sec->name, ".altinstr_aux")) in ignore_unreachable_insn()
2719 if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->offset == FAKE_JUMP_OFFSET) in ignore_unreachable_insn()
2722 if (!insn->func) in ignore_unreachable_insn()
2733 prev_insn = list_prev_entry(insn, list); in ignore_unreachable_insn()
2735 (insn->type == INSN_BUG || in ignore_unreachable_insn()
2736 (insn->type == INSN_JUMP_UNCONDITIONAL && in ignore_unreachable_insn()
2737 insn->jump_dest && insn->jump_dest->type == INSN_BUG))) in ignore_unreachable_insn()
2748 if (is_kasan_insn(insn) || is_ubsan_insn(insn)) in ignore_unreachable_insn()
2751 if (insn->type == INSN_JUMP_UNCONDITIONAL) { in ignore_unreachable_insn()
2752 if (insn->jump_dest && in ignore_unreachable_insn()
2753 insn->jump_dest->func == insn->func) { in ignore_unreachable_insn()
2754 insn = insn->jump_dest; in ignore_unreachable_insn()
2761 if (insn->offset + insn->len >= insn->func->offset + insn->func->len) in ignore_unreachable_insn()
2764 insn = list_next_entry(insn, list); in ignore_unreachable_insn()
2773 struct instruction *insn; in validate_symbol() local
2784 insn = find_insn(file, sec, sym->offset); in validate_symbol()
2785 if (!insn || insn->ignore || insn->visited) in validate_symbol()
2790 ret = validate_branch(file, insn->func, insn, *state); in validate_symbol()
2792 BT_FUNC("<=== (sym)", insn); in validate_symbol()
2855 struct instruction *insn; in validate_reachable_instructions() local
2860 for_each_insn(file, insn) { in validate_reachable_instructions()
2861 if (insn->visited || ignore_unreachable_insn(file, insn)) in validate_reachable_instructions()
2864 WARN_FUNC("unreachable instruction", insn->sec, insn->offset); in validate_reachable_instructions()