Jason Wessel wrote:

> I rolled up several patches along with my changes to fix HW breakpoints 
> on x86_64 and i386.   I also deprecated some of the #defines in favor of 
> using the kgdb_ops to control the HW breakpoints for other non IA archs 
> at the point that these are implemented.
> 
> Until such time that there is a common interface for kernel HW 
> breakpoints, if a user space application uses HW breakpoints the kernel 
> breakpoints will disappear.  I tested execution, data access and data 
> write breakpoints and all work with gdb 6.6.
> 
> If there are no objections, I am going to replace the i386.patch with 
> i386_hw_breakpoints.patch and x86_64_breakpoints.patch and merge the 
> core changes for arch breakpoints to core-lite.patch.

    There *are* objections now -- belated as usual. :-<

> Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>
> Index: linux-2.6.21.1/arch/i386/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21.1.orig/arch/i386/kernel/kgdb.c
> +++ linux-2.6.21.1/arch/i386/kernel/kgdb.c
> @@ -14,12 +14,14 @@
>  
>  /*
>   * Copyright (C) 2000-2001 VERITAS Software Corporation.
> + * Copyright (C) 2007 Wind River Systems, Inc.
>   */
>  /*
>   *  Contributor:     Lake Stevens Instrument Division$
>   *  Written by:      Glenn Engel $
>   *  Updated by:           Amit Kale<[EMAIL PROTECTED]>
>   *  Updated by:           Tom Rini <[EMAIL PROTECTED]>
> + *  Updated by:           Jason Wessel <[EMAIL PROTECTED]>
>   *  Modified for 386 by Jim Kingdon, Cygnus Support.
>   *  Origianl kgdb, compatibility with 2.1.xx kernel by
>   *  David Grothe <[EMAIL PROTECTED]>
> @@ -126,8 +128,53 @@ static struct hw_breakpoint {
>       { .enabled = 0 },
>  };
>  
> -#ifdef CONFIG_KGDB_ARCH_HAS_HARDWARE_BREAKPOINTS
> -int kgdb_remove_hw_break(unsigned long addr)
> +static void kgdb_correct_hw_break(void)
> +{
> +     int breakno;
> +     int correctit;
> +     int breakbit;
> +     unsigned long dr7;
> +
> +     get_debugreg(dr7, 7);
> +     correctit = 0;
> +     for (breakno = 0; breakno < 3; breakno++) {

    Hm, why not breakno < 4 if we have 4 breakpoint regs? :-O

> +             breakbit = 2 << (breakno << 1);
> +             if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
> +                     correctit = 1;
> +                     dr7 |= breakbit;
> +                     dr7 &= ~(0xf0000 << (breakno << 2));
> +                     dr7 |= (((breakinfo[breakno].len << 2) |

    We should shift .len by 18, otherwise the local/global enable bits are 
being corrupt. :-/

> +                              breakinfo[breakno].type) << 16) <<
> +                         (breakno << 2);
> +                     switch (breakno) {
> +                     case 0:
> +                             set_debugreg(breakinfo[breakno].addr, 0);
> +                             break;
> +
> +                     case 1:
> +                             set_debugreg(breakinfo[breakno].addr, 1);
> +                             break;
> +
> +                     case 2:
> +                             set_debugreg(breakinfo[breakno].addr, 2);
> +                             break;
> +
> +                     case 3:

    This case is never hit due to a wrong loop condition.

> +                             set_debugreg(breakinfo[breakno].addr, 3);
> +                             break;
> +                     }
> +             } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
> +                     correctit = 1;
> +                     dr7 &= ~breakbit;
> +                     dr7 &= ~(0xf0000 << (breakno << 2));
> +             }
> +     }
> +     if (correctit)
> +             set_debugreg(dr7, 7);
> +}
> +
> Index: linux-2.6.21.1/arch/x86_64/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21.1.orig/arch/x86_64/kernel/kgdb.c
> +++ linux-2.6.21.1/arch/x86_64/kernel/kgdb.c
> @@ -17,6 +17,7 @@
>   * Copyright (C) 2000-2001 VERITAS Software Corporation.
>   * Copyright (C) 2002 Andi Kleen, SuSE Labs
>   * Copyright (C) 2004 LinSysSoft Technologies Pvt. Ltd.
> + * Copyright (C) 2007 Jason Wessel, Wind River Systems, Inc.
>   */
>  /****************************************************************************
>   *  Contributor:     Lake Stevens Instrument Division$
> @@ -136,10 +137,115 @@ enabled:0}, {
>  enabled:0}, {
>  enabled:0}};
>  
> +static void kgdb_correct_hw_break(void)
> +{
> +     int breakno;
> +     int correctit;
> +     int breakbit;
> +     unsigned long dr7;
> +
> +     get_debugreg(dr7, 7);
> +     correctit = 0;
> +     for (breakno = 0; breakno < 3; breakno++) {

    The same wrong condition here.

> +             breakbit = 2 << (breakno << 1);
> +             if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
> +                     correctit = 1;
> +                     dr7 |= breakbit;
> +                     dr7 &= ~(0xf0000 << (breakno << 2));
> +                     dr7 |= (((breakinfo[breakno].len << 2) |

    And the same wrong shift here.

> +                              breakinfo[breakno].type) << 16) <<
> +                         (breakno << 2);
> +                     switch (breakno) {
> +                     case 0:
> +                             set_debugreg(breakinfo[breakno].addr, 0);
> +                             break;
> +
> +                     case 1:
> +                             set_debugreg(breakinfo[breakno].addr, 1);
> +                             break;
> +
> +                     case 2:
> +                             set_debugreg(breakinfo[breakno].addr, 2);
> +                             break;
> +
> +                     case 3:
> +                             set_debugreg(breakinfo[breakno].addr, 3);
> +                             break;
> +                     }
> +             } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
> +                     correctit = 1;
> +                     dr7 &= ~breakbit;
> +                     dr7 &= ~(0xf0000 << (breakno << 2));
> +             }
> +     }
> +     if (correctit)
> +             set_debugreg(dr7, 7);
> +}
> +
> +static int kgdb_remove_hw_break(unsigned long addr, int len,
> +                                              enum kgdb_bptype bptype)
> +{
> +     int i, idx = -1;
> +     for (i = 0; i < 4; i++) {
> +             if (breakinfo[i].addr == addr && breakinfo[i].enabled) {
> +                     idx = i;
> +                     break;
> +             }
> +     }
> +     if (idx == -1)
> +             return -1;
> +
> +     breakinfo[idx].enabled = 0;
> +     return 0;
> +}
> +
> +static void kgdb_remove_all_hw_break(void)
> +{
> +     int i;
> +
> +     for (i = 0; i < 4; i++) {
> +             memset(&breakinfo[i], 0, sizeof(struct hw_breakpoint));
> +     }
> +}
> +
> +static int kgdb_set_hw_break(unsigned long addr, int len,
> +                                       enum kgdb_bptype bptype)
> +{
> +     int i, idx = -1;
> +     for (i = 0; i < 4; i++) {
> +             if (!breakinfo[i].enabled) {
> +                     idx = i;
> +                     break;
> +             }
> +     }
> +     if (idx == -1)
> +             return -1;
> +     if (bptype == bp_hardware_breakpoint) {
> +             breakinfo[idx].type = 0;
> +             breakinfo[idx].len = 0;
> +     } else if (bptype == bp_write_watchpoint) {
> +             breakinfo[idx].type = 1;
> +             if (len == 1 || len == 2 || len == 4)
> +                     breakinfo[idx].len = len - 1;
> +             else
> +                     return -1;
> +     } else if (bptype == bp_access_watchpoint) {
> +             breakinfo[idx].type = 3;
> +             if (len == 1 || len == 2 || len == 4)
> +                     breakinfo[idx].len = len - 1;
> +             else
> +                     return -1;
> +     } else
> +             return -1;

    Well, this deserves to be handled by switch stmt. :-)

> +     breakinfo[idx].enabled = 1;
> +     breakinfo[idx].addr = addr;
> +     return 0;
> +}
> +

    Well, maybe I'll cook a patch over the weekend...

WBR, Sergei

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to