diff options
| author | Eduard Zingerman <eddyz87@gmail.com> | 2026-09-04 01:33:23 -0700 |
|---|---|---|
| committer | Kumar Kartikeya Dwivedi <memxor@gmail.com> | 2026-09-04 12:58:04 +0200 |
| commit | 836b2fe544a5e9b5ce116622cb36fba33838c6fd (patch) | |
| tree | 95e38e4aaa0a6a78e373148b3d0af4aa2ab3d371 /tools/perf/util/disasm.h | |
| download | linux-stable-836b2fe544a5e9b5ce116622cb36fba33838c6fd.tar.gz linux-stable-836b2fe544a5e9b5ce116622cb36fba33838c6fd.zip | |
selftests/bpf: Check that JMP32 pointer vs zero jumps are not predictedgrafted
Add jmp32_ptr_vs_zero_jne: the fall-through of the 32-bit compare, which
the verifier used to skip, contains an out of bounds map value access,
hence w/o the previous patch the program is accepted. See previous patch
for detailed description.
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260904083325.2083493-6-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Diffstat (limited to 'tools/perf/util/disasm.h')
| -rw-r--r-- | tools/perf/util/disasm.h | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h new file mode 100644 index 000000000..25756e3f4 --- /dev/null +++ b/tools/perf/util/disasm.h @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __PERF_UTIL_DISASM_H +#define __PERF_UTIL_DISASM_H + +#include "map_symbol.h" + +#ifdef HAVE_LIBDW_SUPPORT +#include "dwarf-aux.h" +#endif + +struct annotation_options; +struct disasm_line; +struct ins; +struct evsel; +struct symbol; +struct data_loc_info; +struct type_state; +struct disasm_line; + +struct e_machine_and_e_flags { + uint32_t e_flags; + uint16_t e_machine; +}; + +struct arch { + /** @name: name such as "x86" or "powerpc". */ + const char *name; + const struct ins *instructions; + size_t nr_instructions; + size_t nr_instructions_allocated; + const char *insn_suffix; + unsigned int model; + unsigned int family; + /** @id: ELF machine and flags associated with arch. */ + struct e_machine_and_e_flags id; + bool sorted_instructions; + struct { + char comment_char; + char skip_functions_char; + char register_char; + char memory_ref_char; + char imm_char; + } objdump; + bool (*ins_is_fused)(const struct arch *arch, const char *ins1, + const char *ins2); + const struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); +#ifdef HAVE_LIBDW_SUPPORT + void (*update_insn_state)(struct type_state *state, + struct data_loc_info *dloc, Dwarf_Die *cu_die, + struct disasm_line *dl); +#endif +}; + +struct ins { + const char *name; + const struct ins_ops *ops; +}; + +struct ins_operands { + char *raw; + struct { + char *raw; + char *name; + struct symbol *sym; + u64 addr; + s64 offset; + bool offset_avail; + bool outside; + bool multi_regs; + bool mem_ref; + } target; + union { + struct { + char *raw; + char *name; + u64 addr; + bool multi_regs; + bool mem_ref; + } source; + struct { + struct ins ins; + struct ins_operands *ops; + } locked; + struct { + char *raw_comment; + char *raw_func_start; + } jump; + }; +}; + +struct ins_ops { + void (*free)(struct ins_operands *ops); + int (*parse)(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, + struct disasm_line *dl); + int (*scnprintf)(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); + bool is_jump; + bool is_call; +}; + +struct annotate_args { + const struct arch *arch; + struct map_symbol *ms; + struct annotation_options *options; + s64 offset; + char *line; + int line_nr; + char *fileloc; +}; + +const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const char *cpuid); +bool arch__is_x86(const struct arch *arch); +bool arch__is_powerpc(const struct arch *arch); + +extern const struct ins_ops call_ops; +extern const struct ins_ops dec_ops; +extern const struct ins_ops jump_ops; +extern const struct ins_ops mov_ops; +extern const struct ins_ops nop_ops; +extern const struct ins_ops lock_ops; +extern const struct ins_ops ret_ops; + +int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops); + +const struct arch *arch__new_arc(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_arm(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_csky(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_loongarch(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_mips(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_riscv64(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_s390(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_sparc(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, const char *cpuid); + +const struct ins_ops *ins__find(const struct arch *arch, const char *name, struct disasm_line *dl); + +bool ins__is_call(const struct ins *ins); +bool ins__is_jump(const struct ins *ins); +bool ins__is_fused(const struct arch *arch, const char *ins1, const char *ins2); +bool ins__is_ret(const struct ins *ins); +bool ins__is_lock(const struct ins *ins); + +const struct ins_ops *check_ppc_insn(struct disasm_line *dl); + +struct disasm_line *disasm_line__new(struct annotate_args *args); +void disasm_line__free(struct disasm_line *dl); + +int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, + bool raw, int max_ins_name); + +int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int ins__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int call__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int jump__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int mov__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); + +void jump__delete(struct ins_operands *ops); + +int symbol__disassemble(struct symbol *sym, struct annotate_args *args); + +char *expand_tabs(char *line, char **storage, size_t *storage_len); + +#endif /* __PERF_UTIL_DISASM_H */ |
