Lines Matching refs:file
37 struct instruction *find_insn(struct objtool_file *file, in find_insn() argument
42 hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, offset)) { in find_insn()
50 struct instruction *next_insn_same_sec(struct objtool_file *file, in next_insn_same_sec() argument
54 return find_insn(file, insn->sec, insn->offset + insn->len); in next_insn_same_sec()
63 static struct instruction *next_insn_same_func(struct objtool_file *file, in next_insn_same_func() argument
66 struct instruction *next = next_insn_same_sec(file, insn); in next_insn_same_func()
80 return find_insn(file, func->cfunc->sec, func->cfunc->offset); in next_insn_same_func()
83 static struct instruction *prev_insn_same_sec(struct objtool_file *file, in prev_insn_same_sec() argument
88 return find_insn(file, insn->sec, insn->offset - insn->prev_len); in prev_insn_same_sec()
95 static struct instruction *prev_insn_same_sym(struct objtool_file *file, in prev_insn_same_sym() argument
98 struct instruction *prev = prev_insn_same_sec(file, insn); in prev_insn_same_sym()
106 #define for_each_insn(file, insn) \ argument
109 for_each_sec(file, __sec) \
110 sec_for_each_insn(file, __sec, insn)
112 #define func_for_each_insn(file, func, insn) \ argument
113 for (insn = find_insn(file, func->sec, func->offset); \
115 insn = next_insn_same_func(file, insn))
117 #define sym_for_each_insn(file, sym, insn) \ argument
118 for (insn = find_insn(file, sym->sec, sym->offset); \
120 insn = next_insn_same_sec(file, insn))
122 #define sym_for_each_insn_continue_reverse(file, sym, insn) \ argument
123 for (insn = prev_insn_same_sec(file, insn); \
125 insn = prev_insn_same_sec(file, insn))
127 #define sec_for_each_insn_from(file, insn) \ argument
128 for (; insn; insn = next_insn_same_sec(file, insn))
130 #define sec_for_each_insn_continue(file, insn) \ argument
131 for (insn = next_insn_same_sec(file, insn); insn; \
132 insn = next_insn_same_sec(file, insn))
188 static bool __dead_end_function(struct objtool_file *file, struct symbol *func, in __dead_end_function() argument
215 insn = find_insn(file, func->sec, func->offset); in __dead_end_function()
219 func_for_each_insn(file, func, insn) { in __dead_end_function()
234 func_for_each_insn(file, func, insn) { in __dead_end_function()
252 return __dead_end_function(file, insn_func(dest), recursion+1); in __dead_end_function()
259 static bool dead_end_function(struct objtool_file *file, struct symbol *func) in dead_end_function() argument
261 return __dead_end_function(file, func, 0); in dead_end_function()
277 static void init_insn_state(struct objtool_file *file, struct insn_state *state, in init_insn_state() argument
368 static int decode_instructions(struct objtool_file *file) in decode_instructions() argument
376 for_each_sec(file, sec) { in decode_instructions()
423 ret = arch_decode_instruction(file, sec, offset, in decode_instructions()
439 hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset)); in decode_instructions()
461 if (!find_insn(file, sec, func->offset)) { in decode_instructions()
467 sym_for_each_insn(file, func, insn) { in decode_instructions()
473 list_add_tail(&insn->call_node, &file->endbr_list); in decode_instructions()
474 file->nr_endbr++; in decode_instructions()
476 file->nr_endbr_int++; in decode_instructions()
492 static int add_pv_ops(struct objtool_file *file, const char *symname) in add_pv_ops() argument
499 sym = find_symbol_by_name(file->elf, symname); in add_pv_ops()
506 reloc = find_reloc_by_dest_range(file->elf, sym->sec, off, end - off); in add_pv_ops()
517 objtool_pv_add(file, idx, func); in add_pv_ops()
530 static int init_pv_ops(struct objtool_file *file) in init_pv_ops() argument
546 file->pv_ops = NULL; in init_pv_ops()
548 sym = find_symbol_by_name(file->elf, "pv_ops"); in init_pv_ops()
553 file->pv_ops = calloc(sizeof(struct pv_state), nr); in init_pv_ops()
554 if (!file->pv_ops) in init_pv_ops()
558 INIT_LIST_HEAD(&file->pv_ops[idx].targets); in init_pv_ops()
561 add_pv_ops(file, pv_ops); in init_pv_ops()
566 static struct instruction *find_last_insn(struct objtool_file *file, in find_last_insn() argument
574 insn = find_insn(file, sec, offset); in find_last_insn()
582 static int add_dead_ends(struct objtool_file *file) in add_dead_ends() argument
592 rsec = find_section_by_name(file->elf, ".rela.discard.unreachable"); in add_dead_ends()
605 insn = find_insn(file, reloc->sym->sec, addend); in add_dead_ends()
607 insn = prev_insn_same_sec(file, insn); in add_dead_ends()
609 insn = find_last_insn(file, reloc->sym->sec); in add_dead_ends()
631 rsec = find_section_by_name(file->elf, ".rela.discard.reachable"); in add_dead_ends()
644 insn = find_insn(file, reloc->sym->sec, addend); in add_dead_ends()
646 insn = prev_insn_same_sec(file, insn); in add_dead_ends()
648 insn = find_last_insn(file, reloc->sym->sec); in add_dead_ends()
666 static int create_static_call_sections(struct objtool_file *file) in create_static_call_sections() argument
675 sec = find_section_by_name(file->elf, ".static_call_sites"); in create_static_call_sections()
677 INIT_LIST_HEAD(&file->static_call_list); in create_static_call_sections()
682 if (list_empty(&file->static_call_list)) in create_static_call_sections()
686 list_for_each_entry(insn, &file->static_call_list, call_node) in create_static_call_sections()
689 sec = elf_create_section_pair(file->elf, ".static_call_sites", in create_static_call_sections()
698 list_for_each_entry(insn, &file->static_call_list, call_node) { in create_static_call_sections()
701 if (!elf_init_reloc_text_sym(file->elf, sec, in create_static_call_sections()
721 key_sym = find_symbol_by_name(file->elf, tmp); in create_static_call_sections()
743 if (!elf_init_reloc_data_sym(file->elf, sec, in create_static_call_sections()
755 static int create_retpoline_sites_sections(struct objtool_file *file) in create_retpoline_sites_sections() argument
761 sec = find_section_by_name(file->elf, ".retpoline_sites"); in create_retpoline_sites_sections()
768 list_for_each_entry(insn, &file->retpoline_call_list, call_node) in create_retpoline_sites_sections()
774 sec = elf_create_section_pair(file->elf, ".retpoline_sites", in create_retpoline_sites_sections()
780 list_for_each_entry(insn, &file->retpoline_call_list, call_node) { in create_retpoline_sites_sections()
782 if (!elf_init_reloc_text_sym(file->elf, sec, in create_retpoline_sites_sections()
793 static int create_return_sites_sections(struct objtool_file *file) in create_return_sites_sections() argument
799 sec = find_section_by_name(file->elf, ".return_sites"); in create_return_sites_sections()
806 list_for_each_entry(insn, &file->return_thunk_list, call_node) in create_return_sites_sections()
812 sec = elf_create_section_pair(file->elf, ".return_sites", in create_return_sites_sections()
818 list_for_each_entry(insn, &file->return_thunk_list, call_node) { in create_return_sites_sections()
820 if (!elf_init_reloc_text_sym(file->elf, sec, in create_return_sites_sections()
831 static int create_ibt_endbr_seal_sections(struct objtool_file *file) in create_ibt_endbr_seal_sections() argument
837 sec = find_section_by_name(file->elf, ".ibt_endbr_seal"); in create_ibt_endbr_seal_sections()
844 list_for_each_entry(insn, &file->endbr_list, call_node) in create_ibt_endbr_seal_sections()
848 printf("ibt: ENDBR at function start: %d\n", file->nr_endbr); in create_ibt_endbr_seal_sections()
849 printf("ibt: ENDBR inside functions: %d\n", file->nr_endbr_int); in create_ibt_endbr_seal_sections()
856 sec = elf_create_section_pair(file->elf, ".ibt_endbr_seal", in create_ibt_endbr_seal_sections()
862 list_for_each_entry(insn, &file->endbr_list, call_node) { in create_ibt_endbr_seal_sections()
874 if (!elf_init_reloc_text_sym(file->elf, sec, in create_ibt_endbr_seal_sections()
885 static int create_cfi_sections(struct objtool_file *file) in create_cfi_sections() argument
891 sec = find_section_by_name(file->elf, ".cfi_sites"); in create_cfi_sections()
893 INIT_LIST_HEAD(&file->call_list); in create_cfi_sections()
899 for_each_sym(file, sym) { in create_cfi_sections()
909 sec = elf_create_section_pair(file->elf, ".cfi_sites", in create_cfi_sections()
915 for_each_sym(file, sym) { in create_cfi_sections()
922 if (!elf_init_reloc_text_sym(file->elf, sec, in create_cfi_sections()
933 static int create_mcount_loc_sections(struct objtool_file *file) in create_mcount_loc_sections() argument
935 size_t addr_size = elf_addr_size(file->elf); in create_mcount_loc_sections()
940 sec = find_section_by_name(file->elf, "__mcount_loc"); in create_mcount_loc_sections()
942 INIT_LIST_HEAD(&file->mcount_loc_list); in create_mcount_loc_sections()
947 if (list_empty(&file->mcount_loc_list)) in create_mcount_loc_sections()
951 list_for_each_entry(insn, &file->mcount_loc_list, call_node) in create_mcount_loc_sections()
954 sec = elf_create_section_pair(file->elf, "__mcount_loc", addr_size, in create_mcount_loc_sections()
962 list_for_each_entry(insn, &file->mcount_loc_list, call_node) { in create_mcount_loc_sections()
966 reloc = elf_init_reloc_text_sym(file->elf, sec, idx * addr_size, idx, in create_mcount_loc_sections()
971 set_reloc_type(file->elf, reloc, addr_size == 8 ? R_ABS64 : R_ABS32); in create_mcount_loc_sections()
979 static int create_direct_call_sections(struct objtool_file *file) in create_direct_call_sections() argument
985 sec = find_section_by_name(file->elf, ".call_sites"); in create_direct_call_sections()
987 INIT_LIST_HEAD(&file->call_list); in create_direct_call_sections()
992 if (list_empty(&file->call_list)) in create_direct_call_sections()
996 list_for_each_entry(insn, &file->call_list, call_node) in create_direct_call_sections()
999 sec = elf_create_section_pair(file->elf, ".call_sites", in create_direct_call_sections()
1005 list_for_each_entry(insn, &file->call_list, call_node) { in create_direct_call_sections()
1007 if (!elf_init_reloc_text_sym(file->elf, sec, in create_direct_call_sections()
1021 static void add_ignores(struct objtool_file *file) in add_ignores() argument
1028 rsec = find_section_by_name(file->elf, ".rela.discard.func_stack_frame_non_standard"); in add_ignores()
1050 func_for_each_insn(file, func, insn) in add_ignores()
1240 static void add_uaccess_safe(struct objtool_file *file) in add_uaccess_safe() argument
1249 func = find_symbol_by_name(file->elf, *name); in add_uaccess_safe()
1263 static int add_ignore_alternatives(struct objtool_file *file) in add_ignore_alternatives() argument
1269 rsec = find_section_by_name(file->elf, ".rela.discard.ignore_alts"); in add_ignore_alternatives()
1279 insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in add_ignore_alternatives()
1318 static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn) in insn_reloc() argument
1325 if (!file) in insn_reloc()
1328 reloc = find_reloc_by_dest_range(file->elf, insn->sec, in insn_reloc()
1349 static void annotate_call_site(struct objtool_file *file, in annotate_call_site() argument
1352 struct reloc *reloc = insn_reloc(file, insn); in annotate_call_site()
1368 list_add_tail(&insn->call_node, &file->static_call_list); in annotate_call_site()
1373 list_add_tail(&insn->call_node, &file->retpoline_call_list); in annotate_call_site()
1384 set_reloc_type(file->elf, reloc, R_NONE); in annotate_call_site()
1386 elf_write_insn(file->elf, insn->sec, in annotate_call_site()
1411 set_reloc_type(file->elf, reloc, R_NONE); in annotate_call_site()
1413 elf_write_insn(file->elf, insn->sec, in annotate_call_site()
1420 list_add_tail(&insn->call_node, &file->mcount_loc_list); in annotate_call_site()
1425 list_add_tail(&insn->call_node, &file->call_list); in annotate_call_site()
1427 if (!sibling && dead_end_function(file, sym)) in annotate_call_site()
1431 static void add_call_dest(struct objtool_file *file, struct instruction *insn, in add_call_dest() argument
1447 annotate_call_site(file, insn, sibling); in add_call_dest()
1450 static void add_retpoline_call(struct objtool_file *file, struct instruction *insn) in add_retpoline_call() argument
1481 annotate_call_site(file, insn, false); in add_retpoline_call()
1484 static void add_return_call(struct objtool_file *file, struct instruction *insn, bool add) in add_return_call() argument
1494 list_add_tail(&insn->call_node, &file->return_thunk_list); in add_return_call()
1497 static bool is_first_func_insn(struct objtool_file *file, in is_first_func_insn() argument
1505 struct instruction *prev = prev_insn_same_sym(file, insn); in is_first_func_insn()
1519 static bool jump_is_sibling_call(struct objtool_file *file, in jump_is_sibling_call() argument
1530 if (!is_first_func_insn(file, to, ts)) in jump_is_sibling_call()
1544 static int add_jump_destinations(struct objtool_file *file) in add_jump_destinations() argument
1551 for_each_insn(file, insn) { in add_jump_destinations()
1562 reloc = insn_reloc(file, insn); in add_jump_destinations()
1570 add_retpoline_call(file, insn); in add_jump_destinations()
1573 add_return_call(file, insn, true); in add_jump_destinations()
1580 add_call_dest(file, insn, reloc->sym, true); in add_jump_destinations()
1591 jump_dest = find_insn(file, dest_sec, dest_off); in add_jump_destinations()
1604 add_return_call(file, insn, false); in add_jump_destinations()
1641 if (jump_is_sibling_call(file, insn, jump_dest)) { in add_jump_destinations()
1646 add_call_dest(file, insn, insn_func(jump_dest), true); in add_jump_destinations()
1670 static int add_call_destinations(struct objtool_file *file) in add_call_destinations() argument
1677 for_each_insn(file, insn) { in add_call_destinations()
1681 reloc = insn_reloc(file, insn); in add_call_destinations()
1686 add_call_dest(file, insn, dest, false); in add_call_destinations()
1710 add_call_dest(file, insn, dest, false); in add_call_destinations()
1713 add_retpoline_call(file, insn); in add_call_destinations()
1716 add_call_dest(file, insn, reloc->sym, false); in add_call_destinations()
1726 static int handle_group_alt(struct objtool_file *file, in handle_group_alt() argument
1752 sec_for_each_insn_from(file, insn) { in handle_group_alt()
1811 sec_for_each_insn_from(file, insn) { in handle_group_alt()
1831 alt_reloc = insn_reloc(file, insn); in handle_group_alt()
1847 insn->jump_dest = next_insn_same_sec(file, orig_alt_group->last_insn); in handle_group_alt()
1875 static int handle_jump_alt(struct objtool_file *file, in handle_jump_alt() argument
1888 struct reloc *reloc = insn_reloc(file, orig_insn); in handle_jump_alt()
1891 set_reloc_type(file->elf, reloc, R_NONE); in handle_jump_alt()
1892 elf_write_insn(file->elf, orig_insn->sec, in handle_jump_alt()
1900 file->jl_nop_short++; in handle_jump_alt()
1902 file->jl_nop_long++; in handle_jump_alt()
1908 file->jl_short++; in handle_jump_alt()
1910 file->jl_long++; in handle_jump_alt()
1912 *new_insn = next_insn_same_sec(file, orig_insn); in handle_jump_alt()
1922 static int add_special_section_alts(struct objtool_file *file) in add_special_section_alts() argument
1930 ret = special_get_alts(file->elf, &special_alts); in add_special_section_alts()
1936 orig_insn = find_insn(file, special_alt->orig_sec, in add_special_section_alts()
1947 new_insn = find_insn(file, special_alt->new_sec, in add_special_section_alts()
1964 ret = handle_group_alt(file, special_alt, orig_insn, in add_special_section_alts()
1969 ret = handle_jump_alt(file, special_alt, orig_insn, in add_special_section_alts()
1994 printf("short:\t%ld\t%ld\n", file->jl_nop_short, file->jl_short); in add_special_section_alts()
1995 printf("long:\t%ld\t%ld\n", file->jl_nop_long, file->jl_long); in add_special_section_alts()
2002 static int add_jump_table(struct objtool_file *file, struct instruction *insn, in add_jump_table() argument
2031 dest_insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in add_jump_table()
2063 static struct reloc *find_jump_table(struct objtool_file *file, in find_jump_table() argument
2077 insn = insn->first_jump_src ?: prev_insn_same_sym(file, insn)) { in find_jump_table()
2089 table_reloc = arch_find_switch_table(file, insn); in find_jump_table()
2092 dest_insn = find_insn(file, table_reloc->sym->sec, reloc_addend(table_reloc)); in find_jump_table()
2106 static void mark_func_jump_tables(struct objtool_file *file, in mark_func_jump_tables() argument
2112 func_for_each_insn(file, func, insn) { in mark_func_jump_tables()
2133 reloc = find_jump_table(file, func, insn); in mark_func_jump_tables()
2139 static int add_func_jump_tables(struct objtool_file *file, in add_func_jump_tables() argument
2145 func_for_each_insn(file, func, insn) { in add_func_jump_tables()
2156 ret = add_jump_table(file, insn_t1, insn_jump_table(insn_t2)); in add_func_jump_tables()
2164 ret = add_jump_table(file, insn_t1, NULL); in add_func_jump_tables()
2174 static int add_jump_table_alts(struct objtool_file *file) in add_jump_table_alts() argument
2179 if (!file->rodata) in add_jump_table_alts()
2182 for_each_sym(file, func) { in add_jump_table_alts()
2186 mark_func_jump_tables(file, func); in add_jump_table_alts()
2187 ret = add_func_jump_tables(file, func); in add_jump_table_alts()
2204 static int read_unwind_hints(struct objtool_file *file) in read_unwind_hints() argument
2213 sec = find_section_by_name(file->elf, ".discard.unwind_hints"); in read_unwind_hints()
2227 file->hints = true; in read_unwind_hints()
2232 reloc = find_reloc_by_dest(file->elf, sec, i * sizeof(*hint)); in read_unwind_hints()
2238 insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in read_unwind_hints()
2285 cfi.cfa.offset = bswap_if_needed(file->elf, hint->sp_offset); in read_unwind_hints()
2295 static int read_noendbr_hints(struct objtool_file *file) in read_noendbr_hints() argument
2301 rsec = find_section_by_name(file->elf, ".rela.discard.noendbr"); in read_noendbr_hints()
2306 insn = find_insn(file, reloc->sym->sec, in read_noendbr_hints()
2319 static int read_retpoline_hints(struct objtool_file *file) in read_retpoline_hints() argument
2325 rsec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe"); in read_retpoline_hints()
2335 insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in read_retpoline_hints()
2355 static int read_instr_hints(struct objtool_file *file) in read_instr_hints() argument
2361 rsec = find_section_by_name(file->elf, ".rela.discard.instr_end"); in read_instr_hints()
2371 insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in read_instr_hints()
2380 rsec = find_section_by_name(file->elf, ".rela.discard.instr_begin"); in read_instr_hints()
2390 insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in read_instr_hints()
2402 static int read_validate_unret_hints(struct objtool_file *file) in read_validate_unret_hints() argument
2408 rsec = find_section_by_name(file->elf, ".rela.discard.validate_unret"); in read_validate_unret_hints()
2418 insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in read_validate_unret_hints()
2430 static int read_intra_function_calls(struct objtool_file *file) in read_intra_function_calls() argument
2436 rsec = find_section_by_name(file->elf, ".rela.discard.intra_function_calls"); in read_intra_function_calls()
2449 insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc)); in read_intra_function_calls()
2468 insn->jump_dest = find_insn(file, insn->sec, dest_off); in read_intra_function_calls()
2504 static int classify_symbols(struct objtool_file *file) in classify_symbols() argument
2508 for_each_sym(file, func) { in classify_symbols()
2535 static void mark_rodata(struct objtool_file *file) in mark_rodata() argument
2550 for_each_sec(file, sec) { in mark_rodata()
2558 file->rodata = found; in mark_rodata()
2561 static int decode_sections(struct objtool_file *file) in decode_sections() argument
2565 mark_rodata(file); in decode_sections()
2567 ret = init_pv_ops(file); in decode_sections()
2574 ret = classify_symbols(file); in decode_sections()
2578 ret = decode_instructions(file); in decode_sections()
2582 add_ignores(file); in decode_sections()
2583 add_uaccess_safe(file); in decode_sections()
2585 ret = add_ignore_alternatives(file); in decode_sections()
2592 ret = read_noendbr_hints(file); in decode_sections()
2601 ret = add_special_section_alts(file); in decode_sections()
2606 ret = add_jump_destinations(file); in decode_sections()
2614 ret = read_intra_function_calls(file); in decode_sections()
2618 ret = add_call_destinations(file); in decode_sections()
2626 ret = add_dead_ends(file); in decode_sections()
2630 ret = add_jump_table_alts(file); in decode_sections()
2634 ret = read_unwind_hints(file); in decode_sections()
2638 ret = read_retpoline_hints(file); in decode_sections()
2642 ret = read_instr_hints(file); in decode_sections()
2646 ret = read_validate_unret_hints(file); in decode_sections()
3225 static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn) in propagate_alt_cfi() argument
3369 static bool pv_call_dest(struct objtool_file *file, struct instruction *insn) in pv_call_dest() argument
3375 reloc = insn_reloc(file, insn); in pv_call_dest()
3381 if (file->pv_ops[idx].clean) in pv_call_dest()
3384 file->pv_ops[idx].clean = true; in pv_call_dest()
3386 list_for_each_entry(target, &file->pv_ops[idx].targets, pv_target) { in pv_call_dest()
3389 file->pv_ops[idx].clean = false; in pv_call_dest()
3393 return file->pv_ops[idx].clean; in pv_call_dest()
3396 static inline bool noinstr_call_dest(struct objtool_file *file, in noinstr_call_dest() argument
3405 if (file->pv_ops) in noinstr_call_dest()
3406 return pv_call_dest(file, insn); in noinstr_call_dest()
3434 static int validate_call(struct objtool_file *file, in validate_call() argument
3439 !noinstr_call_dest(file, insn, insn_call_dest(insn))) { in validate_call()
3457 static int validate_sibling_call(struct objtool_file *file, in validate_sibling_call() argument
3466 return validate_call(file, insn, state); in validate_sibling_call()
3504 static struct instruction *next_insn_to_validate(struct objtool_file *file, in next_insn_to_validate() argument
3531 return next_insn_same_sec(file, insn); in next_insn_to_validate()
3534 return next_insn_same_sec(file, alt_group->orig_group->last_insn); in next_insn_to_validate()
3543 static int validate_branch(struct objtool_file *file, struct symbol *func, in validate_branch() argument
3555 next_insn = next_insn_to_validate(file, insn); in validate_branch()
3594 sym_for_each_insn_continue_reverse(file, func, i) { in validate_branch()
3629 if (propagate_alt_cfi(file, insn)) in validate_branch()
3639 ret = validate_branch(file, func, alt->insn, state); in validate_branch()
3660 ret = validate_call(file, insn, &state); in validate_branch()
3678 ret = validate_sibling_call(file, insn, &state); in validate_branch()
3683 ret = validate_branch(file, func, in validate_branch()
3699 ret = validate_sibling_call(file, insn, &state); in validate_branch()
3778 static int validate_unwind_hint(struct objtool_file *file, in validate_unwind_hint() argument
3783 int ret = validate_branch(file, insn_func(insn), insn, *state); in validate_unwind_hint()
3792 static int validate_unwind_hints(struct objtool_file *file, struct section *sec) in validate_unwind_hints() argument
3798 if (!file->hints) in validate_unwind_hints()
3801 init_insn_state(file, &state, sec); in validate_unwind_hints()
3804 sec_for_each_insn(file, sec, insn) in validate_unwind_hints()
3805 warnings += validate_unwind_hint(file, insn, &state); in validate_unwind_hints()
3807 for_each_insn(file, insn) in validate_unwind_hints()
3808 warnings += validate_unwind_hint(file, insn, &state); in validate_unwind_hints()
3820 static int validate_unret(struct objtool_file *file, struct instruction *insn) in validate_unret() argument
3826 next = next_insn_to_validate(file, insn); in validate_unret()
3841 ret = validate_unret(file, alt->insn); in validate_unret()
3867 ret = validate_unret(file, insn->jump_dest); in validate_unret()
3882 dest = find_insn(file, insn_call_dest(insn)->sec, in validate_unret()
3890 ret = validate_unret(file, dest); in validate_unret()
3928 static int validate_unrets(struct objtool_file *file) in validate_unrets() argument
3933 for_each_insn(file, insn) { in validate_unrets()
3937 ret = validate_unret(file, insn); in validate_unrets()
3948 static int validate_retpoline(struct objtool_file *file) in validate_retpoline() argument
3953 for_each_insn(file, insn) { in validate_retpoline()
3994 static bool ignore_unreachable_insn(struct objtool_file *file, struct instruction *insn) in ignore_unreachable_insn() argument
4028 sec_for_each_insn_continue(file, insn) { in ignore_unreachable_insn()
4045 func_for_each_insn(file, insn_func(dest), dest) in ignore_unreachable_insn()
4067 prev_insn = prev_insn_same_sec(file, insn); in ignore_unreachable_insn()
4098 insn = next_insn_same_sec(file, insn); in ignore_unreachable_insn()
4104 static int add_prefix_symbol(struct objtool_file *file, struct symbol *func) in add_prefix_symbol() argument
4109 insn = find_insn(file, func->sec, func->offset); in add_prefix_symbol()
4113 for (prev = prev_insn_same_sec(file, insn); in add_prefix_symbol()
4115 prev = prev_insn_same_sec(file, prev)) { in add_prefix_symbol()
4129 elf_create_prefix_symbol(file->elf, func, opts.prefix); in add_prefix_symbol()
4146 for (; prev != insn; prev = next_insn_same_sec(file, prev)) in add_prefix_symbol()
4152 static int add_prefix_symbols(struct objtool_file *file) in add_prefix_symbols() argument
4157 for_each_sec(file, sec) { in add_prefix_symbols()
4165 add_prefix_symbol(file, func); in add_prefix_symbols()
4172 static int validate_symbol(struct objtool_file *file, struct section *sec, in validate_symbol() argument
4186 insn = find_insn(file, sec, sym->offset); in validate_symbol()
4192 ret = validate_branch(file, insn_func(insn), insn, *state); in validate_symbol()
4198 static int validate_section(struct objtool_file *file, struct section *sec) in validate_section() argument
4208 init_insn_state(file, &state, sec); in validate_section()
4211 warnings += validate_symbol(file, sec, func, &state); in validate_section()
4217 static int validate_noinstr_sections(struct objtool_file *file) in validate_noinstr_sections() argument
4222 sec = find_section_by_name(file->elf, ".noinstr.text"); in validate_noinstr_sections()
4224 warnings += validate_section(file, sec); in validate_noinstr_sections()
4225 warnings += validate_unwind_hints(file, sec); in validate_noinstr_sections()
4228 sec = find_section_by_name(file->elf, ".entry.text"); in validate_noinstr_sections()
4230 warnings += validate_section(file, sec); in validate_noinstr_sections()
4231 warnings += validate_unwind_hints(file, sec); in validate_noinstr_sections()
4234 sec = find_section_by_name(file->elf, ".cpuidle.text"); in validate_noinstr_sections()
4236 warnings += validate_section(file, sec); in validate_noinstr_sections()
4237 warnings += validate_unwind_hints(file, sec); in validate_noinstr_sections()
4243 static int validate_functions(struct objtool_file *file) in validate_functions() argument
4248 for_each_sec(file, sec) { in validate_functions()
4252 warnings += validate_section(file, sec); in validate_functions()
4264 static bool noendbr_range(struct objtool_file *file, struct instruction *insn) in noendbr_range() argument
4272 first = find_insn(file, sym->sec, sym->offset); in noendbr_range()
4282 static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn) in validate_ibt_insn() argument
4307 for (reloc = insn_reloc(file, insn); in validate_ibt_insn()
4309 reloc = find_reloc_by_dest_range(file->elf, insn->sec, in validate_ibt_insn()
4327 dest = find_insn(file, reloc->sym->sec, off); in validate_ibt_insn()
4366 if (noendbr_range(file, dest)) in validate_ibt_insn()
4377 static int validate_ibt_data_reloc(struct objtool_file *file, in validate_ibt_data_reloc() argument
4382 dest = find_insn(file, reloc->sym->sec, in validate_ibt_data_reloc()
4407 static int validate_ibt(struct objtool_file *file) in validate_ibt() argument
4414 for_each_insn(file, insn) in validate_ibt()
4415 warnings += validate_ibt_insn(file, insn); in validate_ibt()
4417 for_each_sec(file, sec) { in validate_ibt()
4451 warnings += validate_ibt_data_reloc(file, reloc); in validate_ibt()
4457 static int validate_sls(struct objtool_file *file) in validate_sls() argument
4462 for_each_insn(file, insn) { in validate_sls()
4463 next_insn = next_insn_same_sec(file, insn); in validate_sls()
4519 static int validate_reachable_instructions(struct objtool_file *file) in validate_reachable_instructions() argument
4525 if (file->ignore_unreachables) in validate_reachable_instructions()
4528 for_each_insn(file, insn) { in validate_reachable_instructions()
4529 if (insn->visited || ignore_unreachable_insn(file, insn)) in validate_reachable_instructions()
4532 prev_insn = prev_insn_same_sec(file, insn); in validate_reachable_instructions()
4600 static int disas_warned_funcs(struct objtool_file *file) in disas_warned_funcs() argument
4605 for_each_sym(file, sym) { in disas_warned_funcs()
4635 static void free_insns(struct objtool_file *file) in free_insns() argument
4640 for_each_insn(file, insn) { in free_insns()
4653 int check(struct objtool_file *file) in check() argument
4664 if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3))) in check()
4670 ret = decode_sections(file); in check()
4680 ret = validate_retpoline(file); in check()
4687 ret = validate_functions(file); in check()
4692 ret = validate_unwind_hints(file, NULL); in check()
4698 ret = validate_reachable_instructions(file); in check()
4705 ret = validate_noinstr_sections(file); in check()
4716 ret = validate_unrets(file); in check()
4723 ret = validate_ibt(file); in check()
4730 ret = validate_sls(file); in check()
4737 ret = create_static_call_sections(file); in check()
4744 ret = create_retpoline_sites_sections(file); in check()
4751 ret = create_cfi_sections(file); in check()
4758 ret = create_return_sites_sections(file); in check()
4764 ret = create_direct_call_sections(file); in check()
4772 ret = create_mcount_loc_sections(file); in check()
4779 ret = add_prefix_symbols(file); in check()
4786 ret = create_ibt_endbr_seal_sections(file); in check()
4793 ret = orc_create(file); in check()
4799 free_insns(file); in check()
4802 disas_warned_funcs(file); in check()