X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f X-Recipient: djgpp-workers AT delorie DOT com From: "Pierre Muller" To: Cc: "'Eli Zaretskii'" References: <001501c9e913$d9751830$8c5f4890$@u-strasbg.fr> In-Reply-To: Subject: RE: Patch for windows watchpoint bug Date: Thu, 11 Jun 2009 23:42:25 +0200 Message-ID: <002501c9eadd$8433d070$8c9b7150$@u-strasbg.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: AcnpoFqNCJUqM6UpSQiJwzitgA/H9ABPLLJQ Content-Language: en-us X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.0.1 (mailhost.u-strasbg.fr [IPv6:2001:660:2402::155]); Thu, 11 Jun 2009 23:42:25 +0200 (CEST) X-Virus-Scanned: ClamAV 0.94.2/9456/Thu Jun 11 19:43:13 2009 on mr5.u-strasbg.fr X-Virus-Status: Clean X-Spam-Status: No, score=-99.9 required=5.0 tests=RDNS_DYNAMIC, USER_IN_WHITELIST autolearn=disabled version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on mr5.u-strasbg.fr Reply-To: djgpp-workers AT delorie DOT com > -----Message d'origine----- > De=A0: Eli Zaretskii [mailto:eliz AT gnu DOT org] > Envoy=E9=A0: Wednesday, June 10, 2009 9:10 AM > =C0=A0: djgpp-workers AT delorie DOT com > Objet=A0: Re: Patch for windows watchpoint bug >=20 > > From: "Pierre Muller" > > Cc: "'Eli Zaretskii'" > > Date: Tue, 9 Jun 2009 17:06:21 +0200 > > Content-Language: en-us > > Reply-To: djgpp-workers AT delorie DOT com > > > > Using more than one watchpoints doesn't work > > on my Windows XP Pro SP3. > > > > I found a way to fix this: >=20 > Thanks. I'm traveling now with no access to DJGPP development > environment, but I will try to reproduce this when I'm back and test > your patch. >=20 > > I also have a patch for v2.03, but > > I don't know if this is still useful. >=20 > It is still useful, for example I'm using v2.03. So please send that > patch as well. Hi Eli, Here comes the diff to 2.03 release source, it is big because I needed to add lost of "\n\"=20 inside the assemble statements to be able to compile dbgcom.c with a recent GNU assembler. The spirit of the patch is the same, first iterate over valid handles to test=20 if watchpoint was hit, and disable watchpoints in a second pass. Pierre=20 --- dbgcom.c.ori 2001-09-08 23:11:34 +0000 +++ dbgcom.c.new 2009-06-09 12:13:46 +0000 @@ -99,18 +99,18 @@ void save_npx (void) int i; if ((__dpmi_get_coprocessor_status() & FPU_PRESENT) =3D=3D 0) return; - asm ("movb $0x0b, %%al - outb %%al, $0xa0 - inb $0xa0, %%al - testb $0x20, %%al - jz 1f - xorb %%al, %%al - outb %%al, $0xf0 - movb $0x20, %%al - outb %%al, $0xa0 - outb %%al, $0x20 -1: - fnsave %0 + asm ("movb $0x0b, %%al \n\ + outb %%al, $0xa0 \n\ + inb $0xa0, %%al \n\ + testb $0x20, %%al \n\ + jz 1f \n\ + xorb %%al, %%al \n\ + outb %%al, $0xf0 \n\ + movb $0x20, %%al \n\ + outb %%al, $0xa0 \n\ + outb %%al, $0x20 \n\ +1: \n\ + fnsave %0 \n\ fwait" : "=3Dm" (npx) : /* No input */ @@ -226,15 +226,31 @@ static int _DPMIcancelBreak(int handle) =20 asm volatile( "\n\ movl %1,%%ebx \n\ + movw $0x0b01,%%ax \n\ + int $0x31 \n\ + jc 1f \n\ + xorl %%eax,%%eax \n\ +1: movl %%eax,%0 \n\ + " + : "=3Dg" (state) /* outputs */ + : "g" (handle) /* inputs */ + : "ax", "bx" /* regs used */ + ); + return state; +} + +static int _DPMIhitBreak(int handle) +{ + unsigned state; + + asm volatile( "\n\ + movl %1,%%ebx \n\ movw $0x0b02,%%ax \n\ int $0x31 \n\ jnc 2f \n\ - xorl %%eax,%%eax \n\ + movl $0xffffffff,%%eax \n\ 2: andl $1,%%eax \n\ - pushl %%eax \n\ - movw $0x0b01,%%ax \n\ - int $0x31 \n\ - popl %0 \n\ + movl %%eax,%0 \n\ " : "=3Dg" (state) /* outputs */ : "g" (handle) /* inputs */ @@ -280,7 +296,7 @@ void _set_break_DPMI(void) void _clear_break_DPMI(void); void _clear_break_DPMI(void) { - int i,bt; + int i,bt,res; =20 if(!nset) { edi.dr[6] =3D 0; @@ -291,10 +307,27 @@ void _clear_break_DPMI(void) for(i=3D3;i>=3D0;i--) { bt =3D bt << 1; /* Shift for next bit = */ if(breakhandle[i] !=3D -1) - bt |=3D _DPMIcancelBreak(breakhandle[i]); /* Set low bit if = active */ + { + res =3D _DPMIhitBreak(breakhandle[i]); /* Set low bit if = active */ + if (res =3D=3D 1) + bt |=3D 1; + else if (res =3D=3D -1) + printf("Error checking DPMI hit status\n"); + } } =20 edi.dr[6] =3D bt; + for(i=3D3;i>=3D0;i--) { + bt =3D bt << 1; /* Shift for next bit = */ + if(breakhandle[i] !=3D -1) + { + res =3D _DPMIcancelBreak(breakhandle[i]); =20 + if (res)=20 + printf("Error resetting DPMI Debug Watchpoint\n"); + } + } + + } =20 static __dpmi_paddr old_i31,old_i21,user_i31,user_i21; @@ -915,79 +948,79 @@ Lc21_exit: =20 ); =20 /* complete code to return from an exception */ -asm ( ".text - .balign 16,,7 - .globl _dbgcom_exception_return_to_debuggee -_dbgcom_exception_return_to_debuggee: /* remove errorcode from = stack */ - /* we must also switch stack back !! */ - /* relative to ebp */ - /* 0 previous ebp */ - /* 4 exception number */ - /* 8 return eip */ - /* 12 return cs */ - /* 16 return eflags */ - /* 20 return esp */ - /* 24 return ss */ - /* -4 stored ds */ - /* -8 stored eax */ - /* -12 stored esi */ - pushl %ebp - movl %esp,%ebp - pushl %ds - pushl %eax - pushl %esi - movl %cs:___djgpp_our_DS,%eax - movw %ax,%ds - addl $32,_cur_pos - decl _child_exception_level - movl 24(%ebp),%eax - movw %ax,%ds - movl 20(%ebp),%esi - /* ds:esi points now to app stack */ - subl $28,%esi - movl %esi,20(%ebp) - /* eflags on app stack */ - movl 16(%ebp),%eax - movl %eax,%ds:24(%esi) - /* cs on app stack */ - movl 12(%ebp),%eax - movl %eax,%ds:20(%esi) - /* eip on app stack */ - movl 8(%ebp),%eax - movl %eax,%ds:16(%esi) - /* esi on app stack */ - movl -12(%ebp),%eax - movl %eax,%ds:12(%esi) - /* eax on app stack */ - movl -8(%ebp),%eax - movl %eax,%ds:8(%esi) - /* ds on app_stack */ - movl -4(%ebp),%eax - movl %eax,%ds:4(%esi) - /* ebp on app_stack */ - movl (%ebp),%eax - movl %eax,%ds:(%esi) - /* switch stack */ - movl 24(%ebp),%eax - movw %ax,%ss - movl %esi,%esp - /* now on app stack */ - popl %ebp - popl %eax - movw %ax,%ds - popl %eax - popl %esi - iret +asm ( ".text \n\ + .balign 16,,7 \n\ + .globl _dbgcom_exception_return_to_debuggee \n\ +_dbgcom_exception_return_to_debuggee: /* remove errorcode from = stack */ \n\ + /* we must also switch stack back !! */ \n\ + /* relative to ebp */ \n\ + /* 0 previous ebp */ \n\ + /* 4 exception number */ \n\ + /* 8 return eip */ \n\ + /* 12 return cs */ \n\ + /* 16 return eflags */ \n\ + /* 20 return esp */ \n\ + /* 24 return ss */ \n\ + /* -4 stored ds */ \n\ + /* -8 stored eax */ \n\ + /* -12 stored esi */ \n\ + pushl %ebp \n\ + movl %esp,%ebp \n\ + pushl %ds \n\ + pushl %eax \n\ + pushl %esi \n\ + movl %cs:___djgpp_our_DS,%eax \n\ + movw %ax,%ds \n\ + addl $32,_cur_pos \n\ + decl _child_exception_level \n\ + movl 24(%ebp),%eax \n\ + movw %ax,%ds \n\ + movl 20(%ebp),%esi \n\ + /* ds:esi points now to app stack */ \n\ + subl $28,%esi \n\ + movl %esi,20(%ebp) \n\ + /* eflags on app stack */ \n\ + movl 16(%ebp),%eax \n\ + movl %eax,%ds:24(%esi) \n\ + /* cs on app stack */ \n\ + movl 12(%ebp),%eax \n\ + movl %eax,%ds:20(%esi) \n\ + /* eip on app stack */ \n\ + movl 8(%ebp),%eax \n\ + movl %eax,%ds:16(%esi) \n\ + /* esi on app stack */ \n\ + movl -12(%ebp),%eax \n\ + movl %eax,%ds:12(%esi) \n\ + /* eax on app stack */ \n\ + movl -8(%ebp),%eax \n\ + movl %eax,%ds:8(%esi) \n\ + /* ds on app_stack */ \n\ + movl -4(%ebp),%eax \n\ + movl %eax,%ds:4(%esi) \n\ + /* ebp on app_stack */ \n\ + movl (%ebp),%eax \n\ + movl %eax,%ds:(%esi) \n\ + /* switch stack */ \n\ + movl 24(%ebp),%eax \n\ + movw %ax,%ss \n\ + movl %esi,%esp \n\ + /* now on app stack */ \n\ + popl %ebp \n\ + popl %eax \n\ + movw %ax,%ds \n\ + popl %eax \n\ + popl %esi \n\ + iret \n\ "); =20 static jmp_buf here; =20 /* simple code to return from an exception */ /* don't forget to increment cur_pos */ -asm ( ".text - .balign 16,,7 - .globl _dbgcom_exception_return_to_here -_dbgcom_exception_return_to_here: /* remove errorcode from stack = */ +asm ( ".text \n\ + .balign 16,,7 \n\ + .globl _dbgcom_exception_return_to_here \n\ +_dbgcom_exception_return_to_here: /* remove errorcode from stack = */ \n\ movl %cs:___djgpp_our_DS,%eax = \n\ movw %ax,%ds = \n\ movw %ax,%es = \n\ @@ -1003,9 +1036,9 @@ _dbgcom_exception_return_to_here: =20 movw $0x7021,0xb0f00 \n\ */ =20 /* do not set limit of ds selector two times */ -asm (".text - .global ___dbgcom_kbd_hdlr -___dbgcom_kbd_hdlr: +asm (".text \n\ + .global ___dbgcom_kbd_hdlr \n\ +___dbgcom_kbd_hdlr: \n\ ljmp %cs:___djgpp_old_kbd"); =20 =20 @@ -1100,8 +1133,8 @@ static void dbgsig(int sig) { unsigned int ds_size; int signum =3D __djgpp_exception_state->__signum; - asm ("movl _app_ds,%%eax - lsl %%eax,%%eax + asm ("movl _app_ds,%%eax \n\ + lsl %%eax,%%eax \n\ movl %%eax,%0" : "=3Dg" (ds_size) ); =20 @@ -1317,15 +1350,15 @@ int invalid_sel_addr(short sel, unsigned char read_allowed =3D 0; char write_allowed =3D 0; =20 - asm(" - movw %2,%%ax - verr %%ax - jnz .Ldoes_not_has_read_right - movb $1,%0 -.Ldoes_not_has_read_right: - verw %%ax - jnz .Ldoes_not_has_write_right - movb $1,%1 + asm(" \n\ + movw %2,%%ax \n\ + verr %%ax \n\ + jnz .Ldoes_not_has_read_right \n\ + movb $1,%0 \n\ +.Ldoes_not_has_read_right: \n\ + verw %%ax \n\ + jnz .Ldoes_not_has_write_right \n\ + movb $1,%1 \n\ .Ldoes_not_has_write_right: " : "=3Dg" (read_allowed), "=3Dg" (write_allowed) : "g" (sel) @@ -1617,7 +1650,8 @@ static void close_handles(void) static int dbg_fsext(__FSEXT_Fnumber _function_number, int *_rv, va_list _args) { - int attrib,oflag,retval =3D 0,handle; + int attrib,oflag,retval =3D 0; + int old_handle,handle; const char *filename; /* We are called from this function */ if (in_dbg_fsext) return 0; @@ -1669,6 +1703,29 @@ static int dbg_fsext(__FSEXT_Fnumber _fu __FSEXT_set_function(handle,NULL); } break; + case __FSEXT_dup: + old_handle =3D va_arg(_args,int); + handle =3D va_arg(_args,int); +#ifdef DEBUG_DBGCOM_FILES + fprintf(stderr,"dup(%d) =3D> %d\n",old_handle,handle); +#endif + if (handle >=3D 0) + { + handles[handle] =3D old_handle; + } + return 0; + case __FSEXT_dup2: + old_handle =3D va_arg(_args,int); + handle =3D va_arg(_args,int); + retval =3D va_arg(_args,int); +#ifdef DEBUG_DBGCOM_FILES + fprintf(stderr,"dup2(%d,%d) =3D> %d\n",old_handle,handle,retval); +#endif + if (retval >=3D 0) + { + handles[retval] =3D old_handle; + } + return 0; } *_rv =3D retval; return 1;