Message-Id: <199910220740.JAA04714@cerbere.u-strasbg.fr> X-Sender: muller AT ics DOT u-strasbg DOT fr X-Mailer: QUALCOMM Windows Eudora Pro Version 4.0.2 Date: Fri, 22 Oct 1999 09:30:34 +0200 To: djgpp-workers AT delorie DOT com From: Pierre Muller Subject: Patch for GDB v4.18 adding two new features References: <380F2594 DOT 4C8BB384 AT softhome DOT net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_53596692==_" Reply-To: djgpp-workers AT delorie DOT com --=====================_53596692==_ Content-Type: text/plain; charset="us-ascii" After a mail to Eli Zaretskii I send here diffs to official GDB v4.18 sources for addition of two features : -- I added the "xx" command that allows to look at data in a different selector ! xx $ds:0x4158 would normally give the same as x 0x4158 but when debugging signal support for GDB I had to be able to see whats in other selectors also (this is why I added the read_sel_addr in dbgcom.c) This works without any protection as some selectors have no zero page protection ! -- I also added a allow_zero_page boolean that allows to put a watchpoint in the zero page under Win95 (allowed me to find out some bugs without going back to raw DOS) But of course it only catches reading in the first four bytes not the whole page ! Please note that go32-nat.c diff is relative to gdb418s from the DJGPP distrib printcmd.c and valprint.h are relative to the official GDB 4.18 distribution and dbgcom.c diff is relative to DJGPP CVS version 1.17 21/10/1999 All code relative to the "xx" command are enclosed into a #ifdef other_sel so you will need to recompile the patched files with -Dother_sel in command line ! Eli, I don't know if anyone else will try this patch but I expect tthat you will try it. Could you please inform me about any problem you encountered ? --=====================_53596692==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="sel.dif" *** gdbsave/go32-nat.c Wed Jul 28 21:57:48 1999 --- gdb/go32-nat.c Thu Oct 21 14:40:50 1999 *************** *** 28,33 **** --- 28,36 ---- #include "gdbcore.h" #include "command.h" #include "floatformat.h" + #ifdef other_sel + #include "valprint.h" + #endif /* other_sel */ #include /* required for __DJGPP_MINOR__ */ #include *************** *** 42,48 **** #include #endif ! #if __DJGPP_MINOR__ < 3 /* This code will be provided from DJGPP 2.03 on. Until then I code it here */ typedef struct { --- 45,51 ---- #include #endif ! #if ((__DJGPP_MINOR__ < 3) && !(__NEW_DBGCOM__)) /* This code will be provided from DJGPP 2.03 on. Until then I code it here */ typedef struct { *************** *** 433,439 **** --- 436,466 ---- int i; if (resume_is_step) + { + /* if the next instruction is int we should place a int3 + right after because otherwise the stepping is only effective after + that instruction as the int instruction resets the trace flag */ + /* this does not solve the same problem that could + appear for INTO */ + read_child(a_tss.tss_eip,&b,1); + if (b==0xCD) + { + stepping_over_interrupt=1; + stored_addr=a_tss.tss_eip+2; + read_child(stored_addr,&b,1); + write_child(stored_addr,&int3_code,1); + } + /* this solves the same problem that could + appear for INTO */ + else if (b==0xCE) + { + stepping_over_interrupt=1; + stored_addr=a_tss.tss_eip+1; + read_child(stored_addr,&b,1); + write_child(stored_addr,&int3_code,1); + } a_tss.tss_eflags |= 0x0100; + } else a_tss.tss_eflags &= 0xfeff; if (resume_signal <= -1) *************** *** 455,468 **** run it. */ chdir (child_cwd); ! #if __DJGPP_MINOR__ < 3 ! load_npx (); ! #endif run_child (); #if __DJGPP_MINOR__ < 3 ! save_npx (); #endif getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */ chdir (current_directory); --- 482,512 ---- run it. */ chdir (child_cwd); ! if (go32_signal != -1) ! { ! a_tss.tss_irqn = go32_signal; ! /* tell run_child() it should handle this signal */ ! a_tss.tss_trap = 0xffff; ! } ! else ! a_tss.tss_irqn = 0xff; ! run_child (); #if __DJGPP_MINOR__ < 3 ! load_npx (); #endif + /* eip points to after int3 or into instruction */ + if (stepping_over_interrupt && (a_tss.tss_eip==stored_addr+1)) + { + /* restore code */ + a_tss.tss_eip--; + write_child(a_tss.tss_eip,&b,1); + /* stopped by int3 instead of int1 */ + /* does not matter as both are converted to SIG_TRAP */ + a_tss.tss_irqn=1; + } + getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */ chdir (current_directory); *************** *** 564,569 **** --- 608,623 ---- { if (write) { + #ifdef other_sel + if (use_sel) + { + if (write_sel_addr(memaddr, myaddr, len,last_sel)) + return 0; + else + return len; + } + else + #endif if (write_child (memaddr, myaddr, len)) { return 0; *************** *** 575,580 **** --- 629,644 ---- } else { + #ifdef other_sel + if (use_sel) + { + if (read_sel_addr(memaddr, myaddr, len,last_sel)) + return 0; + else + return len; + } + else + #endif if (read_child (memaddr, myaddr, len)) { return 0; *************** *** 682,687 **** --- 746,788 ---- return 1; } + void go32_sel_info(int sel) + { + char read_allowed = 0; + char write_allowed = 0; + unsigned long limit,vbase; + + asm(" + movw %2,%%ax + verr %%ax + jnz .Ldoes_not_has_read_right + movb $1,%0 + .Ldoes_not_has_read_right: + verrw %%ax + jnz .Ldoes_not_has_write_right + movb $1,%1 + .Ldoes_not_has_write_right: " + : "=g" (read_allowed), "=g" (write_allowed) + : "g" (sel) + ); + if (!read_allowed && !write_allowed) + { + printf_unfiltered("Invalid selector %04x\n", sel); + return; + } + if (read_allowed) + printf_unfiltered("R"); + else + printf_unfiltered(" "); + if (write_allowed) + printf_unfiltered("W "); + else + printf_unfiltered(" "); + __dpmi_get_segment_base_address(sel, &vbase); + limit=__dpmi_get_segment_limit(sel); + printf_unfiltered(" base %08x\t limit %08x\n",vbase,limit); + } + static void ignore (void) { *************** *** 1115,1118 **** --- 1216,1226 ---- { init_go32_ops (); add_target (&go32_ops); + + add_show_from_set + (add_set_cmd ("allowzeropage", no_class, var_boolean, + (char *)&allow_zeropage, + "Set allowzeropage ", + &setlist), + &showlist); } *** gdbsave/printcmd.c Tue Feb 02 22:11:24 1999 --- gdb/printcmd.c Tue Sep 07 13:40:20 1999 *************** *** 36,41 **** --- 36,49 ---- #include "symfile.h" /* for overlay functions */ #include "objfiles.h" /* ditto */ + #ifdef other_sel + + int use_sel; + int last_sel; + + #endif /* other_sel */ + + extern int asm_demangle; /* Whether to demangle syms in asm printouts */ extern int addressprint; /* Whether to print hex addresses in HLL " */ *************** *** 114,120 **** static struct display *display_chain; ! static int display_number; /* Prototypes for exported functions. */ --- 122,128 ---- static struct display *display_chain; ! /* static */ int display_number; /* Prototypes for exported functions. */ *************** *** 149,154 **** --- 157,166 ---- void x_command PARAMS ((char *, int)); + #ifdef other_sel + static void xx_command PARAMS ((char *, int)); + #endif /* other_sel */ + static void address_info PARAMS ((char *, int)); static void set_command PARAMS ((char *, int)); *************** *** 681,686 **** --- 693,703 ---- GDB_FILE *stream; { print_address_numeric (addr, 1, stream); + #ifdef other_sel + /* no symbols for other selectors */ + if (use_sel) + return; + #endif /* other_sel */ print_address_symbolic (addr, stream, asm_demangle, " "); } *************** *** 1341,1346 **** --- 1358,1458 ---- } + #ifdef other_sel + /* no symbols for other selectors */ + static void + xx_command (exp, from_tty) + char *exp; + int from_tty; + { + struct expression *expr,*expr2; + struct format_data fmt; + struct cleanup *old_chain; + struct value *val; + struct value *selval; + short sel; + CORE_ADDR addr; + + use_sel=1; + fmt.format = last_format; + fmt.size = last_size; + fmt.count = 1; + + if (exp && *exp == '/') + { + exp++; + fmt = decode_format (&exp, last_format, last_size); + } + + /* If we have an expression, evaluate it and use it as the address. */ + + if (exp != 0 && *exp != 0) + { + char * p = strchr(exp,':'); + if (*p==0) + return; + *p = 0; + expr = parse_expression (exp); + /* Cause expression not to be there any more + if this command is repeated with Newline. + But don't clobber a user-defined command's definition. */ + if (from_tty) + *exp = 0; + old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr); + selval = evaluate_expression (expr); + if (TYPE_CODE (VALUE_TYPE (selval)) == TYPE_CODE_REF) + selval = value_ind (selval); + sel = value_as_pointer (selval); + if (sel!=last_sel) + go32_sel_info(sel); + last_sel = sel; + exp = p+1; + expr2 = parse_expression (exp); + /* Cause expression not to be there any more + if this command is repeated with Newline. + But don't clobber a user-defined command's definition. */ + if (from_tty) + *exp = 0; + /* old_chain = */ + make_cleanup ((make_cleanup_func) free_current_contents, &expr2); + val = evaluate_expression (expr2); + if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF) + val = value_ind (val); + /* In rvalue contexts, such as this, functions are coerced into + pointers to functions. This makes "x/i main" work. */ + if (/* last_format == 'i' + && */ TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC + && VALUE_LVAL (val) == lval_memory) + addr = VALUE_ADDRESS (val); + else + addr = value_as_pointer (val); + do_cleanups (old_chain); + } + + do_examine (fmt, addr, NULL); + use_sel=0; + + /* If the examine succeeds, we remember its size and format for next time. */ + last_size = fmt.size; + last_format = fmt.format; + + /* Set a couple of internal variables if appropriate. */ + if (last_examine_value) + { + /* Make last address examined available to the user as $_. Use + the correct pointer type. */ + set_internalvar (lookup_internalvar ("_"), + value_from_longest ( + lookup_pointer_type (VALUE_TYPE (last_examine_value)), + (LONGEST) last_examine_address)); + + /* Make contents of last address examined available to the user as $__.*/ + set_internalvar (lookup_internalvar ("__"), last_examine_value); + } + + } + + #endif /* other_sel */ /* Add an expression to the auto-display chain. Specify the expression. */ *************** *** 2423,2428 **** --- 2535,2556 ---- Defaults for format and size letters are those previously used.\n\ Default count is 1. Default address is following last thing printed\n\ with this command or \"print\".", NULL)); + + #ifdef other_sel + add_com ("xx", class_vars, xx_command, + concat ("Examine memory with selectors : x/FMT SEL:ADDRESS.\n\ + ADDRESS is an expression for the memory address to examine.\n\ + SEL is the selector for ADDRESS\n\ + FMT is a repeat count followed by a format letter and a size letter.\n\ + Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\ + t(binary), f(float), a(address), i(instruction), c(char) and s(string).\n", + "Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\ + The specified number of objects of the specified size are printed\n\ + according to the format.\n\n\ + Defaults for format and size letters are those previously used.\n\ + Default count is 1. Default address is following last thing printed\n\ + with this command or \"print\".", NULL)); + #endif /* other_sel */ add_com ("disassemble", class_vars, disassemble_command, "Disassemble a specified section of memory.\n\ *** gdbsave/valprint.h Thu Dec 10 22:25:42 1998 --- gdb/valprint.h Tue Sep 07 13:40:22 1999 *************** *** 29,34 **** --- 29,41 ---- extern int objectprint; /* Controls looking up an object's derived type using what we find in its vtables. */ + #ifdef other_sel + + extern int use_sel; + extern int last_sel; + + #endif /* other_sel */ + extern unsigned int print_max; /* Max # of chars for strings/vectors */ extern int output_format; *** dbgcom.c Thu Oct 21 19:07:56 1999 --- gdb\dbgcom.c Tue Sep 7 13:40:16 1999 *************** *** 17,23 **** #include #include #include ! #include #include #include --- 17,23 ---- #include #include #include ! #include #include #include *************** *** 59,64 **** --- 59,65 ---- ExternalDebuggerInfo edi; TSS a_tss; + char allow_zeropage; static jmp_buf jumper; *************** *** 297,304 **** static __dpmi_paddr old_i31,old_i21,user_i31,user_i21; static int user_int_set = 0; static __dpmi_paddr my_i9,user_i9,my_i8,user_i8; - static void (*oldNOFP)(int); - static void dbgsig(int); static void hook_dpmi(void) { --- 298,303 ---- *************** *** 343,349 **** __dpmi_set_processor_exception_handler_vector(i,&app_handler[i]); } */ load_npx(); - oldNOFP = signal(SIGNOFP, dbgsig); /* if we run under FP emulation */ /* Crtl-C renders app code unreadable */ __djgpp_app_DS = app_ds; } --- 342,347 ---- *************** *** 396,402 **** asm("\n\ .text \n\ ! .balign 16,,7 \n\ _change_exception_handler: \n\ pushl %eax \n\ push %es \n\ --- 394,400 ---- asm("\n\ .text \n\ ! .align 2,0x90 \n\ _change_exception_handler: \n\ pushl %eax \n\ push %es \n\ *************** *** 454,460 **** /* otherwise we can get into troubles */ asm("\n\ .text \n\ ! .balign 16,,7 \n\ _get_exception_handler: \n\ pushl %eax \n\ pushf \n\ --- 452,458 ---- /* otherwise we can get into troubles */ asm("\n\ .text \n\ ! .align 2,0x90 \n\ _get_exception_handler: \n\ pushl %eax \n\ pushf \n\ *************** *** 496,502 **** /* for changing a value, we need our ds, because cs has no write access */ asm( "\n\ .text \n\ ! .balign 16,,7 \n\ _change_handle: \n\ pushl %ecx \n\ xorl %ecx,%ecx \n\ --- 494,500 ---- /* for changing a value, we need our ds, because cs has no write access */ asm( "\n\ .text \n\ ! .align 2,0x90 \n\ _change_handle: \n\ pushl %ecx \n\ xorl %ecx,%ecx \n\ *************** *** 524,530 **** /* for changing a value, we need our ds, because cs has no write access */ asm( "\n\ .text \n\ ! .balign 16,,7 \n\ _change_descriptor: \n\ pushl %ecx \n\ pushl %eax \n\ --- 522,528 ---- /* for changing a value, we need our ds, because cs has no write access */ asm( "\n\ .text \n\ ! .align 2,0x90 \n\ _change_descriptor: \n\ pushl %ecx \n\ pushl %eax \n\ *************** *** 554,560 **** /* Add descriptors to the list: AX is the first, CX is the count */ asm( "\n\ .text \n\ ! .balign 16,,7 \n\ _add_descriptors: \n\ pushl %edx \n\ pushl %ecx \n\ --- 552,558 ---- /* Add descriptors to the list: AX is the first, CX is the count */ asm( "\n\ .text \n\ ! .align 2,0x90 \n\ _add_descriptors: \n\ pushl %edx \n\ pushl %ecx \n\ *************** *** 584,590 **** /* for changing a value, we need our ds, because cs has no write access */ asm( "\n\ .text \n\ ! .balign 16,,7 \n\ _change_dos_descriptor: \n\ pushl %eax \n\ pushl %ecx \n\ --- 582,588 ---- /* for changing a value, we need our ds, because cs has no write access */ asm( "\n\ .text \n\ ! .align 2,0x90 \n\ _change_dos_descriptor: \n\ pushl %eax \n\ pushl %ecx \n\ *************** *** 654,660 **** */ asm( "\n\ .text \n\ ! .balign 16,,7 \n\ .globl _dbgcom_hook_i31 \n\ _dbgcom_hook_i31: \n\ _i31_hook: \n\ --- 652,658 ---- */ asm( "\n\ .text \n\ ! .align 2,0x90 \n\ .globl _dbgcom_hook_i31 \n\ _dbgcom_hook_i31: \n\ _i31_hook: \n\ *************** *** 748,755 **** Lc31_set_protected_mode_interrupt: \n\ cmpb $0x75,%bl \n\ je Lc31_iret \n\ - /*cmpb $0x09,%bl*/ \n\ - /*je Lc31_iret*/ \n\ jmp L_jmp_to_old_i31 \n\ Lc31_alloc_mem: \n\ pushf \n\ --- 746,751 ---- *************** *** 877,883 **** .byte 0x2e \n\ lcall _old_i31 \n\ jmp Lc31_set_flags_and_iret \n\ ! .balign 16,,7 \n\ .globl _dbgcom_hook_i21 \n\ _dbgcom_hook_i21: \n\ _i21_hook: \n\ --- 873,879 ---- .byte 0x2e \n\ lcall _old_i31 \n\ jmp Lc31_set_flags_and_iret \n\ ! .align 2,0x90 \n\ .globl _dbgcom_hook_i21 \n\ _dbgcom_hook_i21: \n\ _i21_hook: \n\ *************** *** 912,921 **** ); /* 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 */ --- 908,914 ---- ); /* complete code to return from an exception */ ! /* don't forget to increment cur_pos */ /* we must also switch stack back !! */ /* relative to ebp */ /* 0 previous ebp */ *************** *** 928,933 **** --- 921,930 ---- /* -4 stored ds */ /* -8 stored eax */ /* -12 stored esi */ + asm ( ".text + .align 2,0x90 + .globl _dbgcom_exception_return_to_debuggee + _dbgcom_exception_return_to_debuggee: /* remove errorcode from stack */ pushl %ebp movl %esp,%ebp pushl %ds *************** *** 940,974 **** 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 --- 937,961 ---- *************** *** 981,988 **** /* 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 */ movl %cs:___djgpp_our_DS,%eax \n\ --- 968,976 ---- /* simple code to return from an exception */ /* don't forget to increment cur_pos */ + asm ( ".text ! .align 2,0x90 .globl _dbgcom_exception_return_to_here _dbgcom_exception_return_to_here: /* remove errorcode from stack */ movl %cs:___djgpp_our_DS,%eax \n\ *************** *** 1012,1018 **** int i; /* Crtl-C renders debugger code unreadable */ __djgpp_app_DS = __djgpp_our_DS; - signal(SIGNOFP, oldNOFP); /* in case we run under FP emulation */ save_npx(); /* save app i31 and i21 if changed */ __dpmi_get_protected_mode_interrupt_vector(0x31, &user_i31); --- 1000,1005 ---- *************** *** 1059,1078 **** eflags = load_state->__eflags; /* reset the debug trace bit */ /* we don't want to step inside the exception_table code */ ! load_state->__eflags &= 0xfffffeffU; errcode = load_state->__sigmask; load_state->__eip=app_handler[signum].offset32; load_state->__cs=app_handler[signum].selector; /* use our own exception stack */ child_exception_level++; cur_pos -= 8; ! if (cur_pos < &excep_stack[0]) { ! /* We have a problem here, but this should never happen. */ ! fprintf (stderr, ! "Level of nesting in debugger exceptions too high: %d\n", child_exception_level); - exit(-1); } load_state->__ss = my_ds; load_state->__esp= (int) cur_pos; --- 1046,1064 ---- eflags = load_state->__eflags; /* reset the debug trace bit */ /* we don't want to step inside the exception_table code */ ! load_state->__eflags &= 0xfffffeff; errcode = load_state->__sigmask; load_state->__eip=app_handler[signum].offset32; load_state->__cs=app_handler[signum].selector; /* use our own exception stack */ child_exception_level++; + /* cur_pos = &excep_stack[1000-40] - 8; */ cur_pos -= 8; ! if (cur_pos < (int *) &excep_stack) { ! /* We have a problem here, but this should never happen */ ! fprintf(stderr,"Level of imbrication in exceptions too high %d", child_exception_level); } load_state->__ss = my_ds; load_state->__esp= (int) cur_pos; *************** *** 1131,1137 **** load_state->__signum = 0xc; /* longjmp returns eax value */ load_state->__eax = 1; ! call_app_exception(__djgpp_exception_state->__signum, RETURN_TO_HERE); } __djgpp_exception_state->__signum=signum; } --- 1117,1123 ---- load_state->__signum = 0xc; /* longjmp returns eax value */ load_state->__eax = 1; ! call_app_exception(__djgpp_exception_state->__signum,RETURN_TO_HERE); } __djgpp_exception_state->__signum=signum; } *************** *** 1166,1174 **** our_handler[signum].selector))) { *load_state = *__djgpp_exception_state; ! /* This exception was in other process, so the debuggee should ! handle it. */ ! call_app_exception(signum, RETURN_TO_DEBUGGEE); } /* else { --- 1152,1161 ---- our_handler[signum].selector))) { *load_state = *__djgpp_exception_state; ! /* exception was in other process ! so the debuggee should handle this ! like gdb debugging itself */ ! call_app_exception(signum,RETURN_TO_DEBUGGEE); } /* else { *************** *** 1209,1231 **** the child when it is resumed. */ if (a_tss.tss_irqn >= DPMI_EXCEPTION_COUNT && forced_address_known) { ! unsigned app_ds_size = __dpmi_get_segment_limit (app_ds); if (app_ds_size > 0xfff) { ! /* This is a fake exception (SIGINT, SIGALRM, etc.). ! We need to poke the `forced' variable in the child ! with the fake exception number. */ ! _farpokel (app_ds, forced_address, a_tss.tss_irqn); ! ! /* We also need to save the child's DS limit in the ! child's ds_limit variable, because the child's fake ! exception handling code will try to restore the DS ! limit from the value of ds_limit. ds_limit is ! defined in exceptn.S at offset -4 relative to the ! forced variable (PM). */ ! _farpokel (app_ds, forced_address - 4, app_ds_size); } ! a_tss.tss_irqn = 0x0d; /* simulate a GPF in the child */ } if ((a_tss.tss_irqn < DPMI_EXCEPTION_COUNT) && (app_handler[a_tss.tss_irqn].offset32) --- 1196,1213 ---- the child when it is resumed. */ if (a_tss.tss_irqn >= DPMI_EXCEPTION_COUNT && forced_address_known) { ! /* This is a fake exception (SIGINT, SIGALRM, etc.). */ ! #if 1 ! /* We also need to set ds_limit in exceptn.S code ! this is at offset -4 relative to forced variable (PM) */ ! int app_ds_size = __dpmi_get_segment_limit(app_ds); if (app_ds_size > 0xfff) { ! movedata(my_ds, (int)&app_ds_size, app_ds, forced_address-4, 4); ! movedata(my_ds, (int)&a_tss.tss_irqn, app_ds, forced_address, 4); } ! #endif ! a_tss.tss_irqn = 0x0d; } if ((a_tss.tss_irqn < DPMI_EXCEPTION_COUNT) && (app_handler[a_tss.tss_irqn].offset32) *************** *** 1233,1239 **** && !invalid_sel_addr(app_handler[a_tss.tss_irqn].selector, app_handler[a_tss.tss_irqn].offset32,1,0)) { ! call_app_exception(a_tss.tss_irqn, RETURN_TO_DEBUGGEE); } else { --- 1215,1221 ---- && !invalid_sel_addr(app_handler[a_tss.tss_irqn].selector, app_handler[a_tss.tss_irqn].offset32,1,0)) { ! call_app_exception(a_tss.tss_irqn,RETURN_TO_DEBUGGEE); } else { *************** *** 1277,1285 **** unsigned limit; limit = __dpmi_get_segment_limit(app_ds); ! if(4096 <= a /* First page is used for NULL pointer detection. */ ! && a <= limit /* To guard against limit < len. */ ! && a - 1 <= limit - len /* To guard against limit <= a + len - 1. */ ) return 0; /* printf("Invalid access to child, address %#x length %#x limit: %#x\n", a, len, limit); --- 1259,1268 ---- unsigned limit; limit = __dpmi_get_segment_limit(app_ds); ! if (a<4096 && !allow_zeropage) /* First page is used for NULL pointer detection. */ ! return 1; ! if ( a <= limit /* To guard against limit < len. */ ! && a +len - 1 <= limit /* To guard against limit <= a + len - 1. */ ) return 0; /* printf("Invalid access to child, address %#x length %#x limit: %#x\n", a, len, limit); *************** *** 1401,1408 **** app_ds = a_tss.tss_ds; app_cs = a_tss.tss_cs; ! if (__dpmi_get_segment_base_address(app_ds, &edi.app_base) == -1) ! abort (); /* Save debugger's FPU state. */ asm ("fnsave %0" : :"m" (debugger_npx)); /* Fill the debuggee's FPU state with the default values, taken from --- 1384,1390 ---- app_ds = a_tss.tss_ds; app_cs = a_tss.tss_cs; ! edi.app_base = 0; /* Save debugger's FPU state. */ asm ("fnsave %0" : :"m" (debugger_npx)); /* Fill the debuggee's FPU state with the default values, taken from --=====================_53596692==_ Content-Type: text/plain; charset="us-ascii" Pierre Muller Institut Charles Sadron 6,rue Boussingault F 67083 STRASBOURG CEDEX (France) mailto:muller AT ics DOT u-strasbg DOT fr Phone : (33)-3-88-41-40-07 Fax : (33)-3-88-41-40-99 --=====================_53596692==_--