linux/arch/x86/kernel/step.c
<<
>>
Prefs
   1/*
   2 * x86 single-step support code, common to 32-bit and 64-bit.
   3 */
   4#include <linux/sched.h>
   5#include <linux/mm.h>
   6#include <linux/ptrace.h>
   7#include <asm/desc.h>
   8
   9unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs)
  10{
  11        unsigned long addr, seg;
  12
  13        addr = regs->ip;
  14        seg = regs->cs & 0xffff;
  15        if (v8086_mode(regs)) {
  16                addr = (addr & 0xffff) + (seg << 4);
  17                return addr;
  18        }
  19
  20        /*
  21         * We'll assume that the code segments in the GDT
  22         * are all zero-based. That is largely true: the
  23         * TLS segments are used for data, and the PNPBIOS
  24         * and APM bios ones we just ignore here.
  25         */
  26        if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
  27                struct desc_struct *desc;
  28                unsigned long base;
  29
  30                seg &= ~7UL;
  31
  32                mutex_lock(&child->mm->context.lock);
  33                if (unlikely((seg >> 3) >= child->mm->context.size))
  34                        addr = -1L; /* bogus selector, access would fault */
  35                else {
  36                        desc = child->mm->context.ldt + seg;
  37                        base = get_desc_base(desc);
  38
  39                        /* 16-bit code segment? */
  40                        if (!desc->d)
  41                                addr &= 0xffff;
  42                        addr += base;
  43                }
  44                mutex_unlock(&child->mm->context.lock);
  45        }
  46
  47        return addr;
  48}
  49
  50static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
  51{
  52        int i, copied;
  53        unsigned char opcode[15];
  54        unsigned long addr = convert_ip_to_linear(child, regs);
  55
  56        copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
  57        for (i = 0; i < copied; i++) {
  58                switch (opcode[i]) {
  59                /* popf and iret */
  60                case 0x9d: case 0xcf:
  61                        return 1;
  62
  63                        /* CHECKME: 64 65 */
  64
  65                /* opcode and address size prefixes */
  66                case 0x66: case 0x67:
  67                        continue;
  68                /* irrelevant prefixes (segment overrides and repeats) */
  69                case 0x26: case 0x2e:
  70                case 0x36: case 0x3e:
  71                case 0x64: case 0x65:
  72                case 0xf0: case 0xf2: case 0xf3:
  73                        continue;
  74
  75#ifdef CONFIG_X86_64
  76                case 0x40 ... 0x4f:
  77                        if (regs->cs != __USER_CS)
  78                                /* 32-bit mode: register increment */
  79                                return 0;
  80                        /* 64-bit mode: REX prefix */
  81                        continue;
  82#endif
  83
  84                        /* CHECKME: f2, f3 */
  85
  86                /*
  87                 * pushf: NOTE! We should probably not let
  88                 * the user see the TF bit being set. But
  89                 * it's more pain than it's worth to avoid
  90                 * it, and a debugger could emulate this
  91                 * all in user space if it _really_ cares.
  92                 */
  93                case 0x9c:
  94                default:
  95                        return 0;
  96                }
  97        }
  98        return 0;
  99}
 100
 101/*
 102 * Enable single-stepping.  Return nonzero if user mode is not using TF itself.
 103 */
 104static int enable_single_step(struct task_struct *child)
 105{
 106        struct pt_regs *regs = task_pt_regs(child);
 107        unsigned long oflags;
 108
 109        /*
 110         * If we stepped into a sysenter/syscall insn, it trapped in
 111         * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
 112         * If user-mode had set TF itself, then it's still clear from
 113         * do_debug() and we need to set it again to restore the user
 114         * state so we don't wrongly set TIF_FORCED_TF below.
 115         * If enable_single_step() was used last and that is what
 116         * set TIF_SINGLESTEP, then both TF and TIF_FORCED_TF are
 117         * already set and our bookkeeping is fine.
 118         */
 119        if (unlikely(test_tsk_thread_flag(child, TIF_SINGLESTEP)))
 120                regs->flags |= X86_EFLAGS_TF;
 121
 122        /*
 123         * Always set TIF_SINGLESTEP - this guarantees that
 124         * we single-step system calls etc..  This will also
 125         * cause us to set TF when returning to user mode.
 126         */
 127        set_tsk_thread_flag(child, TIF_SINGLESTEP);
 128
 129        oflags = regs->flags;
 130
 131        /* Set TF on the kernel stack.. */
 132        regs->flags |= X86_EFLAGS_TF;
 133
 134        /*
 135         * ..but if TF is changed by the instruction we will trace,
 136         * don't mark it as being "us" that set it, so that we
 137         * won't clear it by hand later.
 138         *
 139         * Note that if we don't actually execute the popf because
 140         * of a signal arriving right now or suchlike, we will lose
 141         * track of the fact that it really was "us" that set it.
 142         */
 143        if (is_setting_trap_flag(child, regs)) {
 144                clear_tsk_thread_flag(child, TIF_FORCED_TF);
 145                return 0;
 146        }
 147
 148        /*
 149         * If TF was already set, check whether it was us who set it.
 150         * If not, we should never attempt a block step.
 151         */
 152        if (oflags & X86_EFLAGS_TF)
 153                return test_tsk_thread_flag(child, TIF_FORCED_TF);
 154
 155        set_tsk_thread_flag(child, TIF_FORCED_TF);
 156
 157        return 1;
 158}
 159
 160/*
 161 * Install this value in MSR_IA32_DEBUGCTLMSR whenever child is running.
 162 */
 163static void write_debugctlmsr(struct task_struct *child, unsigned long val)
 164{
 165        if (child->thread.debugctlmsr == val)
 166                return;
 167
 168        child->thread.debugctlmsr = val;
 169
 170        if (child != current)
 171                return;
 172
 173        update_debugctlmsr(val);
 174}
 175
 176/*
 177 * Enable single or block step.
 178 */
 179static void enable_step(struct task_struct *child, bool block)
 180{
 181        /*
 182         * Make sure block stepping (BTF) is not enabled unless it should be.
 183         * Note that we don't try to worry about any is_setting_trap_flag()
 184         * instructions after the first when using block stepping.
 185         * So noone should try to use debugger block stepping in a program
 186         * that uses user-mode single stepping itself.
 187         */
 188        if (enable_single_step(child) && block) {
 189                set_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
 190                write_debugctlmsr(child,
 191                                  child->thread.debugctlmsr | DEBUGCTLMSR_BTF);
 192        } else {
 193                write_debugctlmsr(child,
 194                                  child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
 195
 196                if (!child->thread.debugctlmsr)
 197                        clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
 198        }
 199}
 200
 201void user_enable_single_step(struct task_struct *child)
 202{
 203        enable_step(child, 0);
 204}
 205
 206void user_enable_block_step(struct task_struct *child)
 207{
 208        enable_step(child, 1);
 209}
 210
 211void user_disable_single_step(struct task_struct *child)
 212{
 213        /*
 214         * Make sure block stepping (BTF) is disabled.
 215         */
 216        write_debugctlmsr(child,
 217                          child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
 218
 219        if (!child->thread.debugctlmsr)
 220                clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
 221
 222        /* Always clear TIF_SINGLESTEP... */
 223        clear_tsk_thread_flag(child, TIF_SINGLESTEP);
 224
 225        /* But touch TF only if it was set by us.. */
 226        if (test_and_clear_tsk_thread_flag(child, TIF_FORCED_TF))
 227                task_pt_regs(child)->flags &= ~X86_EFLAGS_TF;
 228}
 229