1 /* 2 * Copyright (C) 2017 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 #ifndef _CHECK_H 19 #define _CHECK_H 20 21 #include <stdbool.h> 22 #include "elf.h" 23 #include "cfi.h" 24 #include "arch.h" 25 #include "orc.h" 26 #include <linux/hashtable.h> 27 28 struct insn_state { 29 struct cfi_reg cfa; 30 struct cfi_reg regs[CFI_NUM_REGS]; 31 int stack_size; 32 unsigned char type; 33 bool bp_scratch; 34 bool drap, end; 35 int drap_reg, drap_offset; 36 struct cfi_reg vals[CFI_NUM_REGS]; 37 }; 38 39 struct instruction { 40 struct list_head list; 41 struct hlist_node hash; 42 struct section *sec; 43 unsigned long offset; 44 unsigned int len; 45 unsigned char type; 46 unsigned long immediate; 47 bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; 48 bool retpoline_safe; 49 struct symbol *call_dest; 50 struct instruction *jump_dest; 51 struct instruction *first_jump_src; 52 struct list_head alts; 53 struct symbol *func; 54 struct stack_op stack_op; 55 struct insn_state state; 56 struct orc_entry orc; 57 }; 58 59 struct objtool_file { 60 struct elf *elf; 61 struct list_head insn_list; 62 DECLARE_HASHTABLE(insn_hash, 16); 63 struct section *rodata, *whitelist; 64 bool ignore_unreachables, c_file, hints; 65 }; 66 67 int check(const char *objname, bool orc); 68 69 struct instruction *find_insn(struct objtool_file *file, 70 struct section *sec, unsigned long offset); 71 72 #define for_each_insn(file, insn) \ 73 list_for_each_entry(insn, &file->insn_list, list) 74 75 #define sec_for_each_insn(file, sec, insn) \ 76 for (insn = find_insn(file, sec, 0); \ 77 insn && &insn->list != &file->insn_list && \ 78 insn->sec == sec; \ 79 insn = list_next_entry(insn, list)) 80 81 82 #endif /* _CHECK_H */ 83