Lines Matching full:file

41 struct instruction *find_insn(struct objtool_file *file,  in find_insn()  argument
46 hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, offset)) { in find_insn()
54 struct instruction *next_insn_same_sec(struct objtool_file *file, in next_insn_same_sec() argument
58 return find_insn(file, insn->sec, insn->offset + insn->len); in next_insn_same_sec()
67 static struct instruction *next_insn_same_func(struct objtool_file *file, in next_insn_same_func() argument
70 struct instruction *next = next_insn_same_sec(file, insn); in next_insn_same_func()
84 return find_insn(file, func->cfunc->sec, func->cfunc->offset); in next_insn_same_func()
87 static struct instruction *prev_insn_same_sec(struct objtool_file *file, in prev_insn_same_sec() argument
92 return find_insn(file, insn->sec, insn->offset - insn->prev_len); in prev_insn_same_sec()
99 static struct instruction *prev_insn_same_sym(struct objtool_file *file, in prev_insn_same_sym() argument
102 struct instruction *prev = prev_insn_same_sec(file, insn); in prev_insn_same_sym()
110 #define for_each_insn(file, insn) \ argument
113 for_each_sec(file->elf, __sec) \
114 sec_for_each_insn(file, __sec, insn)
116 #define func_for_each_insn(file, func, insn) \ argument
117 for (insn = find_insn(file, func->sec, func->offset); \
119 insn = next_insn_same_func(file, insn))
121 #define sym_for_each_insn(file, sym, insn) \ argument
122 for (insn = find_insn(file, sym->sec, sym->offset); \
124 insn = next_insn_same_sec(file, insn))
126 #define sym_for_each_insn_continue_reverse(file, sym, insn) \ argument
127 for (insn = prev_insn_same_sec(file, insn); \
129 insn = prev_insn_same_sec(file, insn))
131 #define sec_for_each_insn_from(file, insn) \ argument
132 for (; insn; insn = next_insn_same_sec(file, insn))
134 #define sec_for_each_insn_continue(file, insn) \ argument
135 for (insn = next_insn_same_sec(file, insn); insn; \
136 insn = next_insn_same_sec(file, insn))
224 * For global functions which are outside the scope of this object file, we
230 static bool __dead_end_function(struct objtool_file *file, struct symbol *func, in __dead_end_function() argument
261 insn = find_insn(file, func->sec, func->offset); in __dead_end_function()
265 func_for_each_insn(file, func, insn) { in __dead_end_function()
280 func_for_each_insn(file, func, insn) { in __dead_end_function()
285 /* sibling call to another file */ in __dead_end_function()
298 return __dead_end_function(file, insn_func(dest), recursion+1); in __dead_end_function()
305 static bool dead_end_function(struct objtool_file *file, struct symbol *func) in dead_end_function() argument
307 return __dead_end_function(file, func, 0); in dead_end_function()
323 static void init_insn_state(struct objtool_file *file, struct insn_state *state, in init_insn_state() argument
409 static int decode_instructions(struct objtool_file *file) in decode_instructions() argument
416 for_each_sec(file->elf, sec) { in decode_instructions()
463 if (arch_decode_instruction(file, sec, offset, sec_size(sec) - offset, insn)) in decode_instructions()
476 hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset)); in decode_instructions()
495 if (!find_insn(file, sec, func->offset)) { in decode_instructions()
500 sym_for_each_insn(file, func, insn) { in decode_instructions()
506 list_add_tail(&insn->call_node, &file->endbr_list); in decode_instructions()
507 file->nr_endbr++; in decode_instructions()
509 file->nr_endbr_int++; in decode_instructions()
525 static int add_pv_ops(struct objtool_file *file, const char *symname) in add_pv_ops() argument
532 sym = find_symbol_by_name(file->elf, symname); in add_pv_ops()
539 reloc = find_reloc_by_dest_range(file->elf, sym->sec, off, end - off); in add_pv_ops()
555 if (objtool_pv_add(file, idx, func)) in add_pv_ops()
567 * Allocate and initialize file->pv_ops[].
569 static int init_pv_ops(struct objtool_file *file) in init_pv_ops() argument
585 file->pv_ops = NULL; in init_pv_ops()
587 sym = find_symbol_by_name(file->elf, "pv_ops"); in init_pv_ops()
592 file->pv_ops = calloc(nr, sizeof(struct pv_state)); in init_pv_ops()
593 if (!file->pv_ops) { in init_pv_ops()
599 INIT_LIST_HEAD(&file->pv_ops[idx].targets); in init_pv_ops()
602 if (add_pv_ops(file, pv_ops)) in init_pv_ops()
609 static bool is_livepatch_module(struct objtool_file *file) in is_livepatch_module() argument
616 sec = find_section_by_name(file->elf, ".modinfo"); in is_livepatch_module()
623 static int create_static_call_sections(struct objtool_file *file) in create_static_call_sections() argument
632 sec = find_section_by_name(file->elf, ".static_call_sites"); in create_static_call_sections()
639 if (!file->klp) in create_static_call_sections()
640 WARN("file already has .static_call_sites section, skipping"); in create_static_call_sections()
645 if (list_empty(&file->static_call_list)) in create_static_call_sections()
649 list_for_each_entry(insn, &file->static_call_list, call_node) in create_static_call_sections()
652 sec = elf_create_section_pair(file->elf, ".static_call_sites", in create_static_call_sections()
661 list_for_each_entry(insn, &file->static_call_list, call_node) { in create_static_call_sections()
664 if (!elf_init_reloc_text_sym(file->elf, sec, in create_static_call_sections()
683 key_sym = find_symbol_by_name(file->elf, tmp); in create_static_call_sections()
685 if (!opts.module || file->klp) { in create_static_call_sections()
703 if (!elf_init_reloc_data_sym(file->elf, sec, in create_static_call_sections()
715 static int create_retpoline_sites_sections(struct objtool_file *file) in create_retpoline_sites_sections() argument
721 sec = find_section_by_name(file->elf, ".retpoline_sites"); in create_retpoline_sites_sections()
723 WARN("file already has .retpoline_sites, skipping"); in create_retpoline_sites_sections()
728 list_for_each_entry(insn, &file->retpoline_call_list, call_node) in create_retpoline_sites_sections()
734 sec = elf_create_section_pair(file->elf, ".retpoline_sites", in create_retpoline_sites_sections()
740 list_for_each_entry(insn, &file->retpoline_call_list, call_node) { in create_retpoline_sites_sections()
742 if (!elf_init_reloc_text_sym(file->elf, sec, in create_retpoline_sites_sections()
753 static int create_return_sites_sections(struct objtool_file *file) in create_return_sites_sections() argument
759 sec = find_section_by_name(file->elf, ".return_sites"); in create_return_sites_sections()
761 WARN("file already has .return_sites, skipping"); in create_return_sites_sections()
766 list_for_each_entry(insn, &file->return_thunk_list, call_node) in create_return_sites_sections()
772 sec = elf_create_section_pair(file->elf, ".return_sites", in create_return_sites_sections()
778 list_for_each_entry(insn, &file->return_thunk_list, call_node) { in create_return_sites_sections()
780 if (!elf_init_reloc_text_sym(file->elf, sec, in create_return_sites_sections()
791 static int create_ibt_endbr_seal_sections(struct objtool_file *file) in create_ibt_endbr_seal_sections() argument
797 sec = find_section_by_name(file->elf, ".ibt_endbr_seal"); in create_ibt_endbr_seal_sections()
799 WARN("file already has .ibt_endbr_seal, skipping"); in create_ibt_endbr_seal_sections()
804 list_for_each_entry(insn, &file->endbr_list, call_node) in create_ibt_endbr_seal_sections()
808 printf("ibt: ENDBR at function start: %d\n", file->nr_endbr); in create_ibt_endbr_seal_sections()
809 printf("ibt: ENDBR inside functions: %d\n", file->nr_endbr_int); in create_ibt_endbr_seal_sections()
816 sec = elf_create_section_pair(file->elf, ".ibt_endbr_seal", in create_ibt_endbr_seal_sections()
822 list_for_each_entry(insn, &file->endbr_list, call_node) { in create_ibt_endbr_seal_sections()
837 if (!elf_init_reloc_text_sym(file->elf, sec, in create_ibt_endbr_seal_sections()
848 static int create_cfi_sections(struct objtool_file *file) in create_cfi_sections() argument
854 sec = find_section_by_name(file->elf, ".cfi_sites"); in create_cfi_sections()
856 WARN("file already has .cfi_sites section, skipping"); in create_cfi_sections()
861 for_each_sym(file->elf, sym) { in create_cfi_sections()
871 sec = elf_create_section_pair(file->elf, ".cfi_sites", in create_cfi_sections()
877 for_each_sym(file->elf, sym) { in create_cfi_sections()
884 if (!elf_init_reloc_text_sym(file->elf, sec, in create_cfi_sections()
895 static int create_mcount_loc_sections(struct objtool_file *file) in create_mcount_loc_sections() argument
897 size_t addr_size = elf_addr_size(file->elf); in create_mcount_loc_sections()
902 sec = find_section_by_name(file->elf, "__mcount_loc"); in create_mcount_loc_sections()
908 if (!file->klp) in create_mcount_loc_sections()
909 WARN("file already has __mcount_loc section, skipping"); in create_mcount_loc_sections()
914 if (list_empty(&file->mcount_loc_list)) in create_mcount_loc_sections()
918 list_for_each_entry(insn, &file->mcount_loc_list, call_node) in create_mcount_loc_sections()
921 sec = elf_create_section_pair(file->elf, "__mcount_loc", addr_size, in create_mcount_loc_sections()
929 list_for_each_entry(insn, &file->mcount_loc_list, call_node) { in create_mcount_loc_sections()
933 reloc = elf_init_reloc_text_sym(file->elf, sec, idx * addr_size, idx, in create_mcount_loc_sections()
938 set_reloc_type(file->elf, reloc, addr_size == 8 ? R_ABS64 : R_ABS32); in create_mcount_loc_sections()
946 static int create_direct_call_sections(struct objtool_file *file) in create_direct_call_sections() argument
952 sec = find_section_by_name(file->elf, ".call_sites"); in create_direct_call_sections()
954 WARN("file already has .call_sites section, skipping"); in create_direct_call_sections()
958 if (list_empty(&file->call_list)) in create_direct_call_sections()
962 list_for_each_entry(insn, &file->call_list, call_node) in create_direct_call_sections()
965 sec = elf_create_section_pair(file->elf, ".call_sites", in create_direct_call_sections()
971 list_for_each_entry(insn, &file->call_list, call_node) { in create_direct_call_sections()
973 if (!elf_init_reloc_text_sym(file->elf, sec, in create_direct_call_sections()
985 static int create_sym_checksum_section(struct objtool_file *file) in create_sym_checksum_section() argument
993 sec = find_section_by_name(file->elf, ".discard.sym_checksum"); in create_sym_checksum_section()
996 WARN("file already has .discard.sym_checksum section, skipping"); in create_sym_checksum_section()
1001 for_each_sym(file->elf, sym) in create_sym_checksum_section()
1008 sec = elf_create_section_pair(file->elf, ".discard.sym_checksum", entsize, in create_sym_checksum_section()
1014 for_each_sym(file->elf, sym) { in create_sym_checksum_section()
1018 if (!elf_init_reloc(file->elf, sec->rsec, idx, idx * entsize, in create_sym_checksum_section()
1026 mark_sec_changed(file->elf, sec, true); in create_sym_checksum_section()
1034 static int create_sym_checksum_section(struct objtool_file *file) { return -EINVAL; } in create_sym_checksum_section() argument
1040 static int add_ignores(struct objtool_file *file) in add_ignores() argument
1046 rsec = find_section_by_name(file->elf, ".rela.discard.func_stack_frame_non_standard"); in add_ignores()
1266 static void add_uaccess_safe(struct objtool_file *file) in add_uaccess_safe() argument
1275 func = find_symbol_by_name(file->elf, *name); in add_uaccess_safe()
1310 static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn) in insn_reloc() argument
1317 if (!file) in insn_reloc()
1320 reloc = find_reloc_by_dest_range(file->elf, insn->sec, in insn_reloc()
1341 static int annotate_call_site(struct objtool_file *file, in annotate_call_site() argument
1344 struct reloc *reloc = insn_reloc(file, insn); in annotate_call_site()
1351 list_add_tail(&insn->call_node, &file->static_call_list); in annotate_call_site()
1356 list_add_tail(&insn->call_node, &file->retpoline_call_list); in annotate_call_site()
1367 set_reloc_type(file->elf, reloc, R_NONE); in annotate_call_site()
1369 if (elf_write_insn(file->elf, insn->sec, in annotate_call_site()
1396 set_reloc_type(file->elf, reloc, R_NONE); in annotate_call_site()
1398 if (elf_write_insn(file->elf, insn->sec, in annotate_call_site()
1407 list_add_tail(&insn->call_node, &file->mcount_loc_list); in annotate_call_site()
1413 list_add_tail(&insn->call_node, &file->call_list); in annotate_call_site()
1415 if (!sibling && dead_end_function(file, sym)) in annotate_call_site()
1421 static int add_call_dest(struct objtool_file *file, struct instruction *insn, in add_call_dest() argument
1437 return annotate_call_site(file, insn, sibling); in add_call_dest()
1440 static int add_retpoline_call(struct objtool_file *file, struct instruction *insn) in add_retpoline_call() argument
1471 return annotate_call_site(file, insn, false); in add_retpoline_call()
1474 static void add_return_call(struct objtool_file *file, struct instruction *insn, bool add) in add_return_call() argument
1484 list_add_tail(&insn->call_node, &file->return_thunk_list); in add_return_call()
1487 static bool is_first_func_insn(struct objtool_file *file, in is_first_func_insn() argument
1500 struct instruction *prev = prev_insn_same_sym(file, insn); in is_first_func_insn()
1513 static int add_jump_destinations(struct objtool_file *file) in add_jump_destinations() argument
1518 for_each_insn(file, insn) { in add_jump_destinations()
1536 reloc = insn_reloc(file, insn); in add_jump_destinations()
1545 if (add_retpoline_call(file, insn)) in add_jump_destinations()
1551 add_return_call(file, insn, true); in add_jump_destinations()
1558 if (add_call_dest(file, insn, dest_sym, true)) in add_jump_destinations()
1571 dest_insn = find_insn(file, dest_sec, dest_off); in add_jump_destinations()
1584 add_return_call(file, insn, false); in add_jump_destinations()
1592 if (file->ignore_unreachables && func && in add_jump_destinations()
1609 if (add_retpoline_call(file, insn)) in add_jump_destinations()
1615 add_return_call(file, insn, true); in add_jump_destinations()
1626 if (is_first_func_insn(file, dest_insn)) { in add_jump_destinations()
1628 if (add_call_dest(file, insn, dest_sym, true)) in add_jump_destinations()
1654 static int add_call_destinations(struct objtool_file *file) in add_call_destinations() argument
1661 for_each_insn(file, insn) { in add_call_destinations()
1666 reloc = insn_reloc(file, insn); in add_call_destinations()
1671 if (add_call_dest(file, insn, dest, false)) in add_call_destinations()
1696 if (add_call_dest(file, insn, dest, false)) in add_call_destinations()
1700 if (add_retpoline_call(file, insn)) in add_call_destinations()
1704 if (add_call_dest(file, insn, reloc->sym, false)) in add_call_destinations()
1716 static int handle_group_alt(struct objtool_file *file, in handle_group_alt() argument
1742 sec_for_each_insn_from(file, insn) { in handle_group_alt()
1803 sec_for_each_insn_from(file, insn) { in handle_group_alt()
1822 alt_reloc = insn_reloc(file, insn); in handle_group_alt()
1838 insn->jump_dest = next_insn_same_sec(file, orig_alt_group->last_insn); in handle_group_alt()
1868 static int handle_jump_alt(struct objtool_file *file, in handle_jump_alt() argument
1881 struct reloc *reloc = insn_reloc(file, orig_insn); in handle_jump_alt()
1884 set_reloc_type(file->elf, reloc, R_NONE); in handle_jump_alt()
1886 if (elf_write_insn(file->elf, orig_insn->sec, in handle_jump_alt()
1897 file->jl_nop_short++; in handle_jump_alt()
1899 file->jl_nop_long++; in handle_jump_alt()
1905 file->jl_short++; in handle_jump_alt()
1907 file->jl_long++; in handle_jump_alt()
1909 *new_insn = next_insn_same_sec(file, orig_insn); in handle_jump_alt()
1919 static int add_special_section_alts(struct objtool_file *file) in add_special_section_alts() argument
1928 if (special_get_alts(file->elf, &special_alts)) in add_special_section_alts()
1933 orig_insn = find_insn(file, special_alt->orig_sec, in add_special_section_alts()
1943 new_insn = find_insn(file, special_alt->new_sec, in add_special_section_alts()
1958 if (handle_group_alt(file, special_alt, orig_insn, &new_insn)) in add_special_section_alts()
1964 if (handle_jump_alt(file, special_alt, orig_insn, &new_insn)) in add_special_section_alts()
2000 printf("short:\t%ld\t%ld\n", file->jl_nop_short, file->jl_short); in add_special_section_alts()
2001 printf("long:\t%ld\t%ld\n", file->jl_nop_long, file->jl_long); in add_special_section_alts()
2012 static int add_jump_table(struct objtool_file *file, struct instruction *insn) in add_jump_table() argument
2053 dest_insn = find_insn(file, reloc->sym->sec, sym_offset); in add_jump_table()
2086 static void find_jump_table(struct objtool_file *file, struct symbol *func, in find_jump_table() argument
2101 insn = insn->first_jump_src ?: prev_insn_same_sym(file, insn)) { in find_jump_table()
2113 table_reloc = arch_find_switch_table(file, insn, &table_size); in find_jump_table()
2119 dest_insn = find_insn(file, table_reloc->sym->sec, sym_offset); in find_jump_table()
2135 static void mark_func_jump_tables(struct objtool_file *file, in mark_func_jump_tables() argument
2140 func_for_each_insn(file, func, insn) { in mark_func_jump_tables()
2161 find_jump_table(file, func, insn); in mark_func_jump_tables()
2165 static int add_func_jump_tables(struct objtool_file *file, in add_func_jump_tables() argument
2170 func_for_each_insn(file, func, insn) { in add_func_jump_tables()
2174 if (add_jump_table(file, insn)) in add_func_jump_tables()
2186 static int add_jump_table_alts(struct objtool_file *file) in add_jump_table_alts() argument
2190 if (!file->rodata) in add_jump_table_alts()
2193 for_each_sym(file->elf, func) { in add_jump_table_alts()
2197 mark_func_jump_tables(file, func); in add_jump_table_alts()
2198 if (add_func_jump_tables(file, func)) in add_jump_table_alts()
2214 static int read_unwind_hints(struct objtool_file *file) in read_unwind_hints() argument
2224 sec = find_section_by_name(file->elf, ".discard.unwind_hints"); in read_unwind_hints()
2238 file->hints = true; in read_unwind_hints()
2243 reloc = find_reloc_by_dest(file->elf, sec, i * sizeof(*hint)); in read_unwind_hints()
2251 insn = find_insn(file, reloc->sym->sec, offset); in read_unwind_hints()
2299 cfi.cfa.offset = bswap_if_needed(file->elf, hint->sp_offset); in read_unwind_hints()
2309 static int read_annotate(struct objtool_file *file, in read_annotate() argument
2310 int (*func)(struct objtool_file *file, int type, struct instruction *insn)) in read_annotate() argument
2318 sec = find_section_by_name(file->elf, ".discard.annotate_insn"); in read_annotate()
2340 type = annotype(file->elf, sec, reloc); in read_annotate()
2342 insn = find_insn(file, reloc->sym->sec, offset); in read_annotate()
2349 if (func(file, type, insn)) in read_annotate()
2356 static int __annotate_early(struct objtool_file *file, int type, struct instruction *insn) in __annotate_early() argument
2379 static int __annotate_ifc(struct objtool_file *file, int type, struct instruction *insn) in __annotate_ifc() argument
2399 insn->jump_dest = find_insn(file, insn->sec, dest_off); in __annotate_ifc()
2409 static int __annotate_late(struct objtool_file *file, int type, struct instruction *insn) in __annotate_late() argument
2486 static int classify_symbols(struct objtool_file *file) in classify_symbols() argument
2491 for_each_sym(file->elf, func) { in classify_symbols()
2525 static void mark_rodata(struct objtool_file *file) in mark_rodata() argument
2540 for_each_sec(file->elf, sec) { in mark_rodata()
2549 file->rodata = found; in mark_rodata()
2552 static void mark_holes(struct objtool_file *file) in mark_holes() argument
2565 for_each_insn(file, insn) { in mark_holes()
2598 static int decode_sections(struct objtool_file *file) in decode_sections() argument
2600 file->klp = is_livepatch_module(file); in decode_sections()
2602 mark_rodata(file); in decode_sections()
2604 if (init_pv_ops(file)) in decode_sections()
2610 if (classify_symbols(file)) in decode_sections()
2613 if (decode_instructions(file)) in decode_sections()
2616 if (add_ignores(file)) in decode_sections()
2619 add_uaccess_safe(file); in decode_sections()
2621 if (read_annotate(file, __annotate_early)) in decode_sections()
2629 if (add_special_section_alts(file)) in decode_sections()
2633 if (add_jump_destinations(file)) in decode_sections()
2640 if (read_annotate(file, __annotate_ifc)) in decode_sections()
2643 if (add_call_destinations(file)) in decode_sections()
2646 if (add_jump_table_alts(file)) in decode_sections()
2649 if (read_unwind_hints(file)) in decode_sections()
2653 mark_holes(file); in decode_sections()
2659 if (read_annotate(file, __annotate_late)) in decode_sections()
3254 static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn) in propagate_alt_cfi() argument
3409 static bool pv_call_dest(struct objtool_file *file, struct instruction *insn) in pv_call_dest() argument
3415 reloc = insn_reloc(file, insn); in pv_call_dest()
3421 if (file->pv_ops[idx].clean) in pv_call_dest()
3424 file->pv_ops[idx].clean = true; in pv_call_dest()
3426 list_for_each_entry(target, &file->pv_ops[idx].targets, pv_target) { in pv_call_dest()
3429 file->pv_ops[idx].clean = false; in pv_call_dest()
3433 return file->pv_ops[idx].clean; in pv_call_dest()
3436 static inline bool noinstr_call_dest(struct objtool_file *file, in noinstr_call_dest() argument
3445 if (file->pv_ops) in noinstr_call_dest()
3446 return pv_call_dest(file, insn); in noinstr_call_dest()
3474 static int validate_call(struct objtool_file *file, in validate_call() argument
3479 !noinstr_call_dest(file, insn, insn_call_dest(insn))) { in validate_call()
3497 static int validate_sibling_call(struct objtool_file *file, in validate_sibling_call() argument
3506 return validate_call(file, insn, state); in validate_sibling_call()
3544 static struct instruction *next_insn_to_validate(struct objtool_file *file, in next_insn_to_validate() argument
3571 return next_insn_same_sec(file, insn); in next_insn_to_validate()
3574 return next_insn_same_sec(file, alt_group->orig_group->last_insn); in next_insn_to_validate()
3596 * requested not to do that to avoid hurting .s file readability in skip_alt_group()
3610 static int checksum_debug_init(struct objtool_file *file) in checksum_debug_init() argument
3632 func = find_symbol_by_name(file->elf, s); in checksum_debug_init()
3648 static void checksum_update_insn(struct objtool_file *file, struct symbol *func, in checksum_update_insn() argument
3651 struct reloc *reloc = insn_reloc(file, insn); in checksum_update_insn()
3692 static int validate_branch(struct objtool_file *file, struct symbol *func,
3694 static int do_validate_branch(struct objtool_file *file, struct symbol *func,
3697 static int validate_insn(struct objtool_file *file, struct symbol *func, in validate_insn() argument
3736 sym_for_each_insn_continue_reverse(file, func, i) { in validate_insn()
3785 if (propagate_alt_cfi(file, insn)) in validate_insn()
3791 ret = validate_branch(file, func, alt->insn, *statep); in validate_insn()
3820 ret = validate_call(file, insn, statep); in validate_insn()
3836 ret = validate_sibling_call(file, insn, statep); in validate_insn()
3846 ret = validate_branch(file, func, insn->jump_dest, *statep); in validate_insn()
3863 ret = validate_sibling_call(file, insn, statep); in validate_insn()
3959 static int do_validate_branch(struct objtool_file *file, struct symbol *func, in do_validate_branch() argument
3971 next_insn = next_insn_to_validate(file, insn); in do_validate_branch()
3974 checksum_update_insn(file, func, insn); in do_validate_branch()
3981 if (file->ignore_unreachables) in do_validate_branch()
3991 ret = validate_insn(file, func, insn, &state, prev_insn, next_insn, in do_validate_branch()
4004 if (file->ignore_unreachables) in do_validate_branch()
4021 static int validate_branch(struct objtool_file *file, struct symbol *func, in validate_branch() argument
4027 ret = do_validate_branch(file, func, insn, state); in validate_branch()
4033 static int validate_unwind_hint(struct objtool_file *file, in validate_unwind_hint() argument
4044 ret = validate_branch(file, func, insn, *state); in validate_unwind_hint()
4053 static int validate_unwind_hints(struct objtool_file *file, struct section *sec) in validate_unwind_hints() argument
4059 if (!file->hints) in validate_unwind_hints()
4062 init_insn_state(file, &state, sec); in validate_unwind_hints()
4065 sec_for_each_insn(file, sec, insn) in validate_unwind_hints()
4066 warnings += validate_unwind_hint(file, insn, &state); in validate_unwind_hints()
4068 for_each_insn(file, insn) in validate_unwind_hints()
4069 warnings += validate_unwind_hint(file, insn, &state); in validate_unwind_hints()
4081 static int validate_unret(struct objtool_file *file, struct instruction *insn) in validate_unret() argument
4087 next = next_insn_to_validate(file, insn); in validate_unret()
4097 ret = validate_unret(file, alt->insn); in validate_unret()
4120 ret = validate_unret(file, insn->jump_dest); in validate_unret()
4135 dest = find_insn(file, insn_call_dest(insn)->sec, in validate_unret()
4143 ret = validate_unret(file, dest); in validate_unret()
4190 static int validate_unrets(struct objtool_file *file) in validate_unrets() argument
4195 for_each_insn(file, insn) { in validate_unrets()
4199 warnings += validate_unret(file, insn); in validate_unrets()
4205 static int validate_retpoline(struct objtool_file *file) in validate_retpoline() argument
4210 for_each_insn(file, insn) { in validate_retpoline()
4251 list_for_each_entry(insn, &file->retpoline_call_list, call_node) { in validate_retpoline()
4257 prev_insn_same_sym(file, insn); in validate_retpoline()
4282 static bool ignore_unreachable_insn(struct objtool_file *file, struct instruction *insn) in ignore_unreachable_insn() argument
4314 prev_insn = prev_insn_same_sec(file, insn); in ignore_unreachable_insn()
4345 insn = next_insn_same_sec(file, insn); in ignore_unreachable_insn()
4367 static int create_prefix_symbol(struct objtool_file *file, struct symbol *func) in create_prefix_symbol() argument
4386 if (file->klp) { in create_prefix_symbol()
4394 insn = find_insn(file, func->sec, func->offset); in create_prefix_symbol()
4400 for (prev = prev_insn_same_sec(file, insn); in create_prefix_symbol()
4402 prev = prev_insn_same_sec(file, prev)) { in create_prefix_symbol()
4416 if (!elf_create_symbol(file->elf, name, func->sec, in create_prefix_symbol()
4438 for (; prev != insn; prev = next_insn_same_sec(file, prev)) in create_prefix_symbol()
4444 static int create_prefix_symbols(struct objtool_file *file) in create_prefix_symbols() argument
4449 for_each_sec(file->elf, sec) { in create_prefix_symbols()
4454 if (create_prefix_symbol(file, func)) in create_prefix_symbols()
4462 static int validate_symbol(struct objtool_file *file, struct section *sec, in validate_symbol() argument
4477 insn = find_insn(file, sec, sym->offset); in validate_symbol()
4494 ret = validate_branch(file, func, insn, *state); in validate_symbol()
4507 static int validate_section(struct objtool_file *file, struct section *sec) in validate_section() argument
4517 init_insn_state(file, &state, sec); in validate_section()
4520 warnings += validate_symbol(file, sec, func, &state); in validate_section()
4526 static int validate_noinstr_sections(struct objtool_file *file) in validate_noinstr_sections() argument
4531 sec = find_section_by_name(file->elf, ".noinstr.text"); in validate_noinstr_sections()
4533 warnings += validate_section(file, sec); in validate_noinstr_sections()
4534 warnings += validate_unwind_hints(file, sec); in validate_noinstr_sections()
4537 sec = find_section_by_name(file->elf, ".entry.text"); in validate_noinstr_sections()
4539 warnings += validate_section(file, sec); in validate_noinstr_sections()
4540 warnings += validate_unwind_hints(file, sec); in validate_noinstr_sections()
4543 sec = find_section_by_name(file->elf, ".cpuidle.text"); in validate_noinstr_sections()
4545 warnings += validate_section(file, sec); in validate_noinstr_sections()
4546 warnings += validate_unwind_hints(file, sec); in validate_noinstr_sections()
4552 static int validate_functions(struct objtool_file *file) in validate_functions() argument
4557 for_each_sec(file->elf, sec) { in validate_functions()
4561 warnings += validate_section(file, sec); in validate_functions()
4573 static bool noendbr_range(struct objtool_file *file, struct instruction *insn) in noendbr_range() argument
4581 first = find_insn(file, sym->sec, sym->offset); in noendbr_range()
4591 static int __validate_ibt_insn(struct objtool_file *file, struct instruction *insn, in __validate_ibt_insn() argument
4629 if (noendbr_range(file, dest)) in __validate_ibt_insn()
4636 static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn) in validate_ibt_insn() argument
4660 if (!insn_reloc(file, insn)) { in validate_ibt_insn()
4665 dest = find_insn(file, insn->sec, off); in validate_ibt_insn()
4671 return __validate_ibt_insn(file, insn, dest); in validate_ibt_insn()
4679 for (reloc = insn_reloc(file, insn); in validate_ibt_insn()
4681 reloc = find_reloc_by_dest_range(file->elf, insn->sec, in validate_ibt_insn()
4687 dest = find_insn(file, reloc->sym->sec, off); in validate_ibt_insn()
4691 warnings += __validate_ibt_insn(file, insn, dest); in validate_ibt_insn()
4697 static int validate_ibt_data_reloc(struct objtool_file *file, in validate_ibt_data_reloc() argument
4702 dest = find_insn(file, reloc->sym->sec, in validate_ibt_data_reloc()
4726 static int validate_ibt(struct objtool_file *file) in validate_ibt() argument
4733 for_each_insn(file, insn) in validate_ibt()
4734 warnings += validate_ibt_insn(file, insn); in validate_ibt()
4736 for_each_sec(file->elf, sec) { in validate_ibt()
4775 warnings += validate_ibt_data_reloc(file, reloc); in validate_ibt()
4781 static int validate_sls(struct objtool_file *file) in validate_sls() argument
4786 for_each_insn(file, insn) { in validate_sls()
4787 next_insn = next_insn_same_sec(file, insn); in validate_sls()
4814 static int validate_reachable_instructions(struct objtool_file *file) in validate_reachable_instructions() argument
4820 if (file->ignore_unreachables) in validate_reachable_instructions()
4823 for_each_insn(file, insn) { in validate_reachable_instructions()
4824 if (insn->visited || ignore_unreachable_insn(file, insn)) in validate_reachable_instructions()
4827 prev_insn = prev_insn_same_sec(file, insn); in validate_reachable_instructions()
4853 static int check_abs_references(struct objtool_file *file) in check_abs_references() argument
4859 for_each_sec(file->elf, sec) { in check_abs_references()
4876 if (arch_absolute_reloc(file->elf, reloc)) { in check_abs_references()
4892 * Reduce peak RSS usage by freeing insns memory before writing the ELF file,
4896 static void free_insns(struct objtool_file *file) in free_insns() argument
4901 for_each_insn(file, insn) { in free_insns()
4925 int check(struct objtool_file *file) in check() argument
4935 disas_ctx = disas_context_create(file); in check()
4950 if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3))) { in check()
4958 ret = checksum_debug_init(file); in check()
4962 ret = decode_sections(file); in check()
4970 warnings += validate_retpoline(file); in check()
4975 w += validate_functions(file); in check()
4976 w += validate_unwind_hints(file, NULL); in check()
4978 w += validate_reachable_instructions(file); in check()
4983 warnings += validate_noinstr_sections(file); in check()
4991 warnings += validate_unrets(file); in check()
4995 warnings += validate_ibt(file); in check()
4998 warnings += validate_sls(file); in check()
5001 ret = create_static_call_sections(file); in check()
5007 ret = create_retpoline_sites_sections(file); in check()
5013 ret = create_cfi_sections(file); in check()
5019 ret = create_return_sites_sections(file); in check()
5024 ret = create_direct_call_sections(file); in check()
5031 ret = create_mcount_loc_sections(file); in check()
5037 ret = create_prefix_symbols(file); in check()
5043 ret = create_ibt_endbr_seal_sections(file); in check()
5049 warnings += check_abs_references(file); in check()
5052 ret = create_sym_checksum_section(file); in check()
5058 ret = orc_create(file); in check()
5090 free_insns(file); in check()