blob: 2804848e628e3718d37e27ca0f19001ba80764f8 [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001/* SPDX-License-Identifier: GPL-2.0-or-later */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002/*
3 * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004 */
5
6#ifndef _CHECK_H
7#define _CHECK_H
8
9#include <stdbool.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010#include "cfi.h"
11#include "arch.h"
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000012
13struct insn_state {
Olivier Deprez157378f2022-04-04 15:47:50 +020014 struct cfi_state cfi;
David Brazdil0f672f62019-12-10 10:32:29 +000015 unsigned int uaccess_stack;
Olivier Deprez157378f2022-04-04 15:47:50 +020016 bool uaccess;
17 bool df;
18 bool noinstr;
19 s8 instr;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000020};
21
22struct instruction {
23 struct list_head list;
24 struct hlist_node hash;
Olivier Deprez157378f2022-04-04 15:47:50 +020025 struct list_head static_call_node;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000026 struct section *sec;
27 unsigned long offset;
28 unsigned int len;
David Brazdil0f672f62019-12-10 10:32:29 +000029 enum insn_type type;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000030 unsigned long immediate;
Olivier Deprez157378f2022-04-04 15:47:50 +020031 bool dead_end, ignore, ignore_alts;
32 bool hint;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000033 bool retpoline_safe;
Olivier Deprez157378f2022-04-04 15:47:50 +020034 s8 instr;
David Brazdil0f672f62019-12-10 10:32:29 +000035 u8 visited;
Olivier Deprez157378f2022-04-04 15:47:50 +020036 u8 ret_offset;
37 int alt_group;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000038 struct symbol *call_dest;
39 struct instruction *jump_dest;
40 struct instruction *first_jump_src;
Olivier Deprez157378f2022-04-04 15:47:50 +020041 struct reloc *jump_table;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000042 struct list_head alts;
43 struct symbol *func;
Olivier Deprez157378f2022-04-04 15:47:50 +020044 struct list_head stack_ops;
45 struct cfi_state cfi;
46#ifdef INSN_USE_ORC
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000047 struct orc_entry orc;
Olivier Deprez157378f2022-04-04 15:47:50 +020048#endif
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000049};
50
Olivier Deprez157378f2022-04-04 15:47:50 +020051static inline bool is_static_jump(struct instruction *insn)
52{
53 return insn->type == INSN_JUMP_CONDITIONAL ||
54 insn->type == INSN_JUMP_UNCONDITIONAL;
55}
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000056
Olivier Deprez157378f2022-04-04 15:47:50 +020057static inline bool is_dynamic_jump(struct instruction *insn)
58{
59 return insn->type == INSN_JUMP_DYNAMIC ||
60 insn->type == INSN_JUMP_DYNAMIC_CONDITIONAL;
61}
62
63static inline bool is_jump(struct instruction *insn)
64{
65 return is_static_jump(insn) || is_dynamic_jump(insn);
66}
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000067
68struct instruction *find_insn(struct objtool_file *file,
69 struct section *sec, unsigned long offset);
70
71#define for_each_insn(file, insn) \
72 list_for_each_entry(insn, &file->insn_list, list)
73
74#define sec_for_each_insn(file, sec, insn) \
75 for (insn = find_insn(file, sec, 0); \
76 insn && &insn->list != &file->insn_list && \
77 insn->sec == sec; \
78 insn = list_next_entry(insn, list))
79
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000080#endif /* _CHECK_H */