void __kprobes arch_arm_kprobe(struct kprobe *p) { unsigned int brkp; void *addr; if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) { /* Remove any Thumb flag */ addr = (void *)((uintptr_t)p->addr & ~1); if (is_wide_instruction(p->opcode)) brkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION; else brkp = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION; } else { kprobe_opcode_t insn = p->opcode; addr = p->addr; brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION; if (insn >= 0xe0000000) brkp |= 0xe0000000; /* Unconditional instruction */ else brkp |= insn & 0xf0000000; /* Copy condition from insn */ } patch_text(addr, brkp); }
int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) { int err; /* patch_text() only supports int-sized breakpoints */ BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE); err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE); if (err) return err; patch_text((void *)bpt->bpt_addr, *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr); return err; }
static void __arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type, bool is_static) { void *addr = (void *)entry->code; unsigned int insn; if (type == JUMP_LABEL_ENABLE) insn = arm_gen_branch(entry->code, entry->target); else insn = arm_gen_nop(); if (is_static) __patch_text_early(addr, insn); else patch_text(addr, insn); }
int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) { patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr); return 0; }