home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / debug / common / dbgcom.c next >
Encoding:
C/C++ Source or Header  |  1996-08-13  |  17.6 KB  |  663 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <libc/stubs.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <dpmi.h>
  9. #include <crt0.h>
  10. #include <go32.h>
  11. #include <signal.h>
  12. #include <setjmp.h>
  13. #include <debug/dbgcom.h>
  14. #include <sys/exceptn.h>
  15. #include <stubinfo.h>
  16. #include <sys/farptr.h>
  17.  
  18. extern char __libdbg_ident_string[];
  19. static char *id = __libdbg_ident_string;
  20.  
  21. #define MEM_HANDLE_COUNT    256
  22. #define DESCRIPTOR_COUNT    128
  23. #define DOS_DESCRIPTOR_COUNT    128
  24.  
  25. long mem_handles[MEM_HANDLE_COUNT];
  26. unsigned short descriptors[DESCRIPTOR_COUNT];
  27. unsigned short dos_descriptors[DOS_DESCRIPTOR_COUNT];
  28.  
  29. /* ARGSUSED */
  30. char **
  31. __crt0_glob_function(char *foo)
  32. {
  33.   id = 0;
  34.   return 0;
  35. }
  36.  
  37. ExternalDebuggerInfo edi;
  38. TSS a_tss;
  39. static jmp_buf jumper;
  40.  
  41. static int my_ds,my_cs,app_cs;
  42. static jmp_buf load_state;
  43.  
  44. static int nset, breakhandle[4];
  45.  
  46. static int _DPMIsetBreak(unsigned short sizetype, unsigned vaddr)
  47. {
  48.     int handle;
  49.  
  50.     asm volatile(                               "\n\
  51.         movw   %1,%%dx                        \n\
  52.         movl   %2,%%ecx                        \n\
  53.         movl   %%ecx,%%ebx                        \n\
  54.         shrl   $16,%%ebx                        \n\
  55.         movw   $0x0b00,%%ax                        \n\
  56.         int    $0x31                        \n\
  57.         jnc    3f                            \n\
  58.         xorl   %%ebx,%%ebx                        \n\
  59.         decl   %%ebx                        \n\
  60.         jmp    1f                            \n\
  61. 3:          movzwl %%bx,%%ebx                        \n\
  62. 1:        movl   %%ebx,%0                        \n\
  63.         "
  64.         : "=g" (handle)            /* outputs */
  65.         : "g" (sizetype), "g"  (vaddr)    /* inputs */
  66.         : "ax", "bx", "cx", "dx"        /* regs used */
  67.     );
  68.     return handle;
  69. }
  70.  
  71. static int _DPMIcancelBreak(int handle)
  72. {
  73.     unsigned state;
  74.  
  75.     asm volatile(                               "\n\
  76.         movl   %1,%%ebx                        \n\
  77.         movw   $0x0b02,%%ax                        \n\
  78.         int    $0x31                        \n\
  79.         jnc    2f                            \n\
  80.         xorl   %%eax,%%eax                                          \n\
  81. 2:        andl   $1,%%eax                        \n\
  82.         pushl  %%eax                        \n\
  83.         movw   $0x0b01,%%ax                        \n\
  84.         int    $0x31                        \n\
  85.         popl   %0                            \n\
  86.         "
  87.         : "=g" (state)            /* outputs */
  88.         : "g"  (handle)            /* inputs */
  89.         : "ax", "bx"            /* regs used */
  90.     );
  91.     return state;
  92. }
  93.  
  94. /* Can't be static because called in asm below; -O3 inlines if static */
  95. void _set_break_DPMI(void);
  96. void _set_break_DPMI(void)
  97. {
  98.   int i;
  99.   unsigned extract;
  100.   unsigned short sizetype;
  101.   unsigned long vbase;
  102.   
  103.   if(__dpmi_get_segment_base_address(__djgpp_app_DS, &vbase) == -1)
  104.     return;
  105.   extract = edi.dr[7] >> 16;
  106.   nset = 0;
  107.  
  108.   for(i=0;i<4;i++)
  109.     if( (edi.dr[7] >> (i*2))&3 ) {        /* enabled? */
  110.       sizetype = (extract >> (i*4)) & 3;    /* extract the type */
  111.       if(sizetype == 3) sizetype = 2;       /* convert for DPMI brain damage */
  112.       sizetype = (sizetype << 8) + ((extract >> (i*4+2)) & 3) + 1; /* & size */
  113.       breakhandle[i] = _DPMIsetBreak(sizetype, edi.dr[i]+vbase);
  114.       if(breakhandle[i] == -1)
  115.         printf("Error allocating DPMI breakpoint at address 0x%08lx\n",edi.dr[i]);
  116.       else
  117.         nset++;
  118.     } else
  119.       breakhandle[i] = -1;
  120.   return;
  121. }
  122.  
  123. /* Can't be static because called in asm below; -O3 inlines if static */
  124. void _clear_break_DPMI(void);
  125. void _clear_break_DPMI(void)
  126. {
  127.   int i,bt;
  128.  
  129.   if(!nset) {
  130.     edi.dr[6] = 0;
  131.     return;
  132.   }
  133.  
  134.   bt = 0;
  135.   for(i=3;i>=0;i--) {
  136.     bt = bt << 1;                             /* Shift for next bit */
  137.     if(breakhandle[i] != -1)
  138.       bt |= _DPMIcancelBreak(breakhandle[i]);  /* Set low bit if active */
  139.   }
  140.  
  141.   edi.dr[6] = bt;
  142. }
  143.  
  144. static __dpmi_paddr old_i31,old_i21;
  145.  
  146. static void hook_dpmi(void)
  147. {
  148.   __dpmi_paddr new_int;
  149.   extern void i21_hook(void),i31_hook(void);
  150.  
  151.   __dpmi_get_protected_mode_interrupt_vector(0x21, &old_i21);
  152.   __dpmi_get_protected_mode_interrupt_vector(0x31, &old_i31);
  153.  
  154.   asm("mov %%cs,%0" : "=g" (new_int.selector) );
  155.   new_int.offset32 = (unsigned long)i21_hook;
  156.   __dpmi_set_protected_mode_interrupt_vector(0x21, &new_int);
  157.   new_int.offset32 = (unsigned long)i31_hook;
  158.   __dpmi_set_protected_mode_interrupt_vector(0x31, &new_int);
  159. }
  160.  
  161. /* Change a handle in the list: EAX is the old handle, EDX is the new */
  162. /* for changing a value, we need our ds, because cs has no write access */
  163. asm(                                           "\n\
  164.     .text                                \n\
  165.     .align  2,0x90                            \n\
  166. _change_handle:                                \n\
  167.     pushl    %ecx                            \n\
  168.     xorl    %ecx,%ecx                        \n\
  169. CL1:                                    \n\
  170.     .byte    0x2e                             \n\
  171.     cmpl    %eax,_mem_handles(,%ecx,4)                \n\
  172.     jne    CL2                            \n\
  173.     push    %ds                            \n\
  174.     .byte    0x2e                            \n\
  175.     movw    _my_ds,%ax                        \n\
  176.     movw    %ax,%ds                            \n\
  177.     movl    %edx,_mem_handles(,%ecx,4)                \n\
  178.     pop    %ds                            \n\
  179.     popl    %ecx                            \n\
  180.     ret                                \n\
  181. CL2:                                    \n\
  182.     incl    %ecx                            \n\
  183.     cmpl    $256,%ecx    /* MEM_HANDLE_COUNT */            \n\
  184.     jl    CL1                            \n\
  185.     popl    %ecx                            \n\
  186.     ret                                \n"
  187. );
  188.  
  189. /* Change a descriptor in the list: AX is the old, DX is the new */
  190. /* for changing a value, we need our ds, because cs has no write access */
  191. asm(                                           "\n\
  192.     .text                                \n\
  193.     .align  2,0x90                            \n\
  194. _change_descriptor:                            \n\
  195.     pushl    %ecx                            \n\
  196.     pushl    %eax                            \n\
  197.     xorl    %ecx,%ecx                        \n\
  198. CL3:                                    \n\
  199.     .byte    0x2e                             \n\
  200.     cmpw    %ax,_descriptors(,%ecx,2)                \n\
  201.     jne    CL4                            \n\
  202.     push    %ds                            \n\
  203.     .byte    0x2e                            \n\
  204.     movw    _my_ds,%ax                        \n\
  205.     movw    %ax,%ds                            \n\
  206.     movw    %dx,_descriptors(,%ecx,2)                \n\
  207.     pop    %ds                            \n\
  208.     popl    %eax                            \n\
  209.     popl    %ecx                            \n\
  210.     ret                                \n\
  211. CL4:                                    \n\
  212.     incl    %ecx                            \n\
  213.     cmpl    $128,%ecx    /* DESCRIPTOR_COUNT */            \n\
  214.     jl    CL3                            \n\
  215.     popl    %eax                            \n\
  216.     popl    %ecx                            \n\
  217.     ret                                \n"
  218. );
  219.  
  220. /* Add descriptors to the list: AX is the first, CX is the count */
  221. asm(                                    "\n\
  222.     .text                                \n\
  223.     .align  2,0x90                            \n\
  224. _add_descriptors:                            \n\
  225.     pushl    %edx                            \n\
  226.     pushl    %ecx                            \n\
  227.     pushl    %ebx                            \n\
  228.     pushl    %eax                            \n\
  229.     movw    $0x0003,%ax                        \n\
  230.     pushf                                \n\
  231.     .byte    0x2e                            \n\
  232.     lcall    _old_i31                        \n\
  233.     movw    %ax,%bx                            \n\
  234.     popl    %eax                            \n\
  235.     pushl    %eax                            \n\
  236.     movw    %ax,%dx                            \n\
  237.     xorw    %ax,%ax                            \n\
  238. CL5:                                    \n\
  239.     call    _change_descriptor                    \n\
  240.     addw    %bx,%dx                            \n\
  241.     loop    CL5                            \n\
  242.     popl    %eax                            \n\
  243.     popl    %ebx                            \n\
  244.     popl    %ecx                            \n\
  245.     popl    %edx                            \n\
  246.     ret                                \n"
  247. );
  248.  
  249. /* Change a dos_descriptor in the list: AX is the old, DX is the new */
  250. /* for changing a value, we need our ds, because cs has no write access */
  251. asm(                                           "\n\
  252.     .text                                \n\
  253.     .align  2,0x90                            \n\
  254. _change_dos_descriptor:                            \n\
  255.     pushl    %eax                            \n\
  256.     pushl    %ecx                            \n\
  257.     xorl    %ecx,%ecx                        \n\
  258. CL6:                                    \n\
  259.     .byte    0x2e                             \n\
  260.     cmpw    %ax,_dos_descriptors(,%ecx,2)                \n\
  261.     jne    CL7                            \n\
  262.     push    %ds                            \n\
  263.     .byte    0x2e                            \n\
  264.     movw    _my_ds,%ax                        \n\
  265.     movw    %ax,%ds                            \n\
  266.     movw    %dx,_dos_descriptors(,%ecx,2)                \n\
  267.     pop    %ds                            \n\
  268.     popl    %ecx                            \n\
  269.     popl    %eax                            \n\
  270.     ret                                \n\
  271. CL7:                                    \n\
  272.     incl    %ecx                            \n\
  273.     cmpl    $128,%ecx    /* DOS_DESCRIPTOR_COUNT */        \n\
  274.     jl    CL6                            \n\
  275.     popl    %ecx                            \n\
  276.     popl    %eax                            \n\
  277.     ret                                \n"
  278. );
  279.  
  280. /* BUGS: We ignore the exception handlers for the child process, so signals
  281.    do not work.  We also disable the hooking of HW interrupts that might
  282.    cause the HW-interrupt-to-limit exceptions, since they can never be fixed.
  283.    Byproduct:  You can't debug code which hooks int 9, since it's keyboard
  284.    routine never gets called.  Eventually, we should save the exception and
  285.    interrupt hooks and then chain to them on the next execution.  Someday. */
  286.  
  287. /* Watch set selector base, if it is __djgpp_app_DS then reset breakpoints */
  288.  
  289. /* Watch the following DPMI-functions: (added by RH)
  290.  
  291.   0x0000   : __dpmi_allocate_ldt_descriptors
  292.   0x0001   : __dpmi_free_ldt_descriptor
  293.   0x000A   : __dpmi_create_alias_descriptor
  294.   
  295.   0x0100   : __dpmi_allocate_dos_memory
  296.   0x0101   : __dpmi_free_dos_memory
  297.   
  298.   0x0501   : __dpmi_allocate_memory
  299.   0x0501   : __dpmi_free_memory
  300.   0x0503   : __dpmi_resize_memory
  301.   
  302. */ 
  303. asm(                                           "\n\
  304.     .text                                \n\
  305.     .align  2,0x90                            \n\
  306. _i31_hook:                                \n\
  307.     cmpw    $0x0000,%ax                        \n\
  308.     je    Lc31_alloc_descriptors                    \n\
  309.     cmpw    $0x0001,%ax                        \n\
  310.     je    Lc31_free_descriptor                    \n\
  311.     cmpw    $0x000A,%ax                        \n\
  312.     je    Lc31_create_alias_descriptor                \n\
  313.     cmpw    $0x0100,%ax                        \n\
  314.     je    Lc31_allocate_dos_memory                \n\
  315.     cmpw    $0x0101,%ax                        \n\
  316.     je    Lc31_free_dos_memory                    \n\
  317.     cmpw    $0x0501,%ax                        \n\
  318.     je    Lc31_alloc_mem                        \n\
  319.     cmpw    $0x0502,%ax                        \n\
  320.     je    Lc31_free_mem                        \n\
  321.     cmpw    $0x0503,%ax                        \n\
  322.     je    Lc31_resize_mem                        \n\
  323.     cmpw    $0x0203,%ax                        \n\
  324.     je    Lc31a                            \n\
  325.     cmpw    $0x0007,%ax                        \n\
  326.     je    Lc31b                            \n\
  327.     cmpw    $0x0205,%ax                        \n\
  328.     je    Lc31d                            \n\
  329. Lc31c:    .byte    0x2e                            \n\
  330.     ljmp    _old_i31                        \n\
  331. Lc31a_:    pushl    %eax                            \n\
  332.     pushf                                \n\
  333.     popl    %eax        /* store the right flags for iret */    \n\
  334.     movl    %eax,12(%esp)                        \n\
  335.     popl    %eax                            \n\
  336. Lc31a:    iret                                \n\
  337. Lc31b:    .byte    0x2e                            \n\
  338.     cmpw    ___djgpp_app_DS,%bx                    \n\
  339.     jne    Lc31c                            \n\
  340.     pushf                                \n\
  341.     .byte    0x2e                            \n\
  342.     lcall    _old_i31                        \n\
  343.     call    ___djgpp_save_interrupt_regs                \n\
  344.     call    __clear_break_DPMI                    \n\
  345.     call    __set_break_DPMI                    \n\
  346.     movl    ___djgpp_exception_state_ptr,%eax            \n\
  347.     pushl    (%eax)                            \n\
  348.     pushl    %eax                            \n\
  349.     call    _longjmp                        \n\
  350. Lc31d:    cmpb    $9,%bl                            \n\
  351.     je    Lc31a                            \n\
  352.     cmpb    $0x75,%bl                        \n\
  353.     je    Lc31a                            \n\
  354.     jmp    Lc31c                            \n\
  355. Lc31_alloc_mem:                                \n\
  356.     pushf                                \n\
  357.     .byte    0x2e                            \n\
  358.     lcall    _old_i31                        \n\
  359.     jc    Lc31a_                            \n\
  360.     pushf                                \n\
  361.     pushl    %edx                            \n\
  362.     pushw    %si                            \n\
  363.     pushw    %di                            \n\
  364.     popl    %edx                            \n\
  365.     xorl    %eax,%eax                        \n\
  366.     call    _change_handle                        \n\
  367.     popl    %edx                            \n\
  368.     popf                                \n\
  369.     clc                                \n\
  370.     jmp    Lc31a_                            \n\
  371. Lc31_free_mem:                                \n\
  372.     pushw    %si                            \n\
  373.     pushw    %di                            \n\
  374.     pushf                                \n\
  375.     .byte    0x2e                            \n\
  376.     lcall    _old_i31                        \n\
  377.     jc    Lc31_resize_mem_error                    \n\
  378.     popl    %eax                            \n\
  379.     xorl    %edx,%edx                        \n\
  380.     call    _change_handle                        \n\
  381.     xorl    %eax,%eax                        \n\
  382.     jmp    Lc31a_                            \n\
  383. Lc31_resize_mem:                            \n\
  384.     pushw    %si                            \n\
  385.     pushw    %di                            \n\
  386.     pushf                                \n\
  387.     .byte    0x2e                            \n\
  388.     lcall    _old_i31                        \n\
  389.     jnc    Lc31_resize_mem_ok                    \n\
  390. Lc31_resize_mem_error:                            \n\
  391.     addl    $4,%esp                            \n\
  392.     stc                                \n\
  393.     jmp    Lc31a_                            \n\
  394. Lc31_resize_mem_ok:                            \n\
  395.     popl    %eax                            \n\
  396.     pushw    %si                            \n\
  397.     pushw    %di                            \n\
  398.     popl    %edx                            \n\
  399.     call    _change_handle                        \n\
  400.     xorl    %eax,%eax                        \n\
  401.     jmp    Lc31a_                            \n\
  402. Lc31_alloc_descriptors:                            \n\
  403.     pushl    %ecx                            \n\
  404.     pushf                                \n\
  405.     .byte    0x2e                            \n\
  406.     lcall    _old_i31                        \n\
  407.     popl    %ecx                            \n\
  408.     jc    Lc31a_                            \n\
  409.     call    _add_descriptors                    \n\
  410.     clc                                \n\
  411.     jmp    Lc31a_                            \n\
  412. Lc31_free_descriptor:                            \n\
  413.     pushl    %ebx                            \n\
  414.     pushf                                \n\
  415.     .byte    0x2e                            \n\
  416.     lcall    _old_i31                        \n\
  417.     popl    %edx                            \n\
  418.     jc    Lc31a_                            \n\
  419.     xorw    %ax,%ax                            \n\
  420.     call    _change_descriptor                    \n\
  421.     clc                                \n\
  422.     jmp    Lc31a_                            \n\
  423. Lc31_create_alias_descriptor:                        \n\
  424.     pushf                                \n\
  425.     .byte    0x2e                            \n\
  426.     lcall    _old_i31                        \n\
  427.     jc    Lc31a_                            \n\
  428.     pushl    %eax                            \n\
  429.     movw    %ax,%dx                            \n\
  430.     xorw    %ax,%ax                            \n\
  431.     call    _change_descriptor                    \n\
  432.     popl    %eax                            \n\
  433.     clc                                \n\
  434.     jmp    Lc31a_                            \n\
  435. Lc31_allocate_dos_memory:                        \n\
  436.     pushf                                \n\
  437.     .byte    0x2e                            \n\
  438.     lcall    _old_i31                        \n\
  439.     jc    Lc31a_                            \n\
  440.     pushl    %eax                            \n\
  441.     xorl    %eax,%eax                        \n\
  442.     call    _change_dos_descriptor                    \n\
  443.     popl    %eax                            \n\
  444.     clc                                \n\
  445.     jmp    Lc31a_                            \n\
  446. Lc31_free_dos_memory:                            \n\
  447.     pushl    %edx                            \n\
  448.     pushf                                \n\
  449.     .byte    0x2e                            \n\
  450.     lcall    _old_i31                        \n\
  451.     popl    %eax                            \n\
  452.     jc    Lc31a_                            \n\
  453.     xorw    %dx,%dx                            \n\
  454.     call    _change_dos_descriptor                    \n\
  455.     clc                                \n\
  456.     jmp    Lc31a_                            \n\
  457.     .align  2,0x90                            \n\
  458. _i21_hook:                                \n\
  459.     cmpb    $0x4c,%ah                        \n\
  460.     je    Lc21                            \n\
  461. Lc21j:    .byte    0x2e                            \n\
  462.     ljmp    _old_i21                        \n\
  463. Lc21:    push    %eax                            \n\
  464.     movl    8(%esp),%eax                        \n\
  465.     cs                                \n\
  466.     cmpw    _app_cs,%ax                        \n\
  467.     pop    %eax                            \n\
  468.     jg    Lc21j                            \n\
  469.     call    ___djgpp_save_interrupt_regs                \n\
  470.     movl    ___djgpp_exception_state_ptr,%esi            \n\
  471.     movl    $0x21,56(%esi)                        \n\
  472.     movl    $_load_state,%edi                    \n\
  473.     movl    $43,%ecx                        \n\
  474.     rep                                \n\
  475.     movsl                                \n\
  476.     pushl    $1                            \n\
  477.     pushl    $_jumper                        \n\
  478.     call    _longjmp                        \n\
  479.     "
  480.     );
  481.  
  482. /*    movw    %cs:__go32_info_block+26, %fs                \n\
  483.     .byte    0x64                            \n\
  484.     movw    $0x7021,0xb0f00                        \n\ */
  485.  
  486. static void unhook_dpmi(void)
  487. {
  488.   __dpmi_set_protected_mode_interrupt_vector(0x31, &old_i31);
  489.   __dpmi_set_protected_mode_interrupt_vector(0x21, &old_i21);
  490. }
  491.  
  492. static void dbgsig(int sig)
  493. {
  494.   if(__djgpp_exception_state->__cs != my_cs || sig == SIGTRAP) {
  495.     *load_state = *__djgpp_exception_state;    /* exception was in other process */
  496.     longjmp(jumper, 1);
  497.   }
  498. }
  499.  
  500. void run_child(void)
  501. {
  502.   load_state->__cs = a_tss.tss_cs;
  503.   load_state->__ss = a_tss.tss_ss;
  504.   load_state->__ds = a_tss.tss_ds;
  505.   load_state->__es = a_tss.tss_es;
  506.   load_state->__fs = a_tss.tss_fs;
  507.   load_state->__gs = a_tss.tss_gs;
  508.   load_state->__eip = a_tss.tss_eip;
  509.   load_state->__eflags = a_tss.tss_eflags;
  510.   load_state->__eax = a_tss.tss_eax;
  511.   load_state->__ebx = a_tss.tss_ebx;
  512.   load_state->__ecx = a_tss.tss_ecx;
  513.   load_state->__edx = a_tss.tss_edx;
  514.   load_state->__esp = a_tss.tss_esp;
  515.   load_state->__ebp = a_tss.tss_ebp;
  516.   load_state->__esi = a_tss.tss_esi;
  517.   load_state->__edi = a_tss.tss_edi;
  518.   if(!setjmp(jumper)){
  519.     /* jump to tss */
  520.     _set_break_DPMI();
  521.     hook_dpmi();
  522.     longjmp(load_state, load_state->__eax);
  523.     /* we never return here, execption routine will longjump */
  524.   }
  525.   /* exception routine:  save state, copy to tss, return */
  526.   a_tss.tss_cs = load_state->__cs;
  527.   a_tss.tss_ss = load_state->__ss;
  528.   a_tss.tss_ds = load_state->__ds;
  529.   a_tss.tss_es = load_state->__es;
  530.   a_tss.tss_fs = load_state->__fs;
  531.   a_tss.tss_gs = load_state->__gs;
  532.   a_tss.tss_eip = load_state->__eip;
  533.   a_tss.tss_esp = load_state->__esp;
  534.   a_tss.tss_eflags = load_state->__eflags;
  535.   a_tss.tss_eax = load_state->__eax;
  536.   a_tss.tss_ebx = load_state->__ebx;
  537.   a_tss.tss_ecx = load_state->__ecx;
  538.   a_tss.tss_edx = load_state->__edx;
  539.   a_tss.tss_esi = load_state->__esi;
  540.   a_tss.tss_edi = load_state->__edi;
  541.   a_tss.tss_ebp = load_state->__ebp;
  542.   a_tss.tss_irqn = load_state->__signum;
  543.   a_tss.tss_error = load_state->__sigmask;
  544.   unhook_dpmi();
  545.   _clear_break_DPMI();
  546. }
  547.  
  548. static int invalid_addr(unsigned a, unsigned len)
  549. {
  550.   /* Here we assume expand up writable code.  We could check the rights to
  551.      be sure, but that's a waste unless *_child routines fixed to know about
  552.      different selectors. */
  553.  
  554.   unsigned limit;
  555.   limit = __dpmi_get_segment_limit(__djgpp_app_DS);
  556.   if(a >= 4096 && (a+len-1) <= limit)
  557.     return 0;
  558. /*  printf("Invalid access to child, address %#x length %#x  limit: %#x\n", a, len, limit);
  559.   if (can_longjmp)
  560.     longjmp(debugger_jmpbuf, 1); */
  561.   return 1;
  562. }
  563.  
  564. int read_child(unsigned child_addr, void *buf, unsigned len)
  565. {
  566.   if (invalid_addr(child_addr, len))
  567.     return 1;
  568.   movedata(__djgpp_app_DS, child_addr, my_ds, (int)buf, len);
  569.   return 0;
  570. }
  571.  
  572. int write_child(unsigned child_addr, void *buf, unsigned len)
  573. {
  574.   if (invalid_addr(child_addr, len))
  575.     return 1;
  576.   movedata(my_ds, (int)buf, __djgpp_app_DS, child_addr, len);
  577.   return 0;
  578. }
  579.  
  580. static _GO32_StubInfo si;
  581.  
  582. static void (*oldTRAP)(int);
  583. static void (*oldSEGV)(int);
  584. static void (*oldFPE)(int);
  585. static void (*oldINT)(int);
  586.  
  587. void edi_init(jmp_buf start_state)
  588. {
  589.   my_ds = 0;
  590.   asm("mov %%ds,%0" : "=g" (my_ds) );
  591.   my_cs = 0;
  592.   asm("mov %%cs,%0" : "=g" (my_cs) );
  593.  
  594.   *load_state = *start_state;
  595.   a_tss.tss_cs = load_state->__cs;
  596.   a_tss.tss_ss = load_state->__ss;
  597.   a_tss.tss_ds = load_state->__ds;
  598.   a_tss.tss_es = load_state->__es;
  599.   a_tss.tss_fs = load_state->__fs;
  600.   a_tss.tss_gs = load_state->__gs;
  601.   a_tss.tss_eip = load_state->__eip;
  602.   a_tss.tss_esp = load_state->__esp;
  603.   a_tss.tss_eflags = load_state->__eflags;
  604.  
  605.   __djgpp_app_DS = a_tss.tss_ds;
  606.   app_cs = a_tss.tss_cs;
  607.   edi.app_base = 0;
  608.   oldTRAP = signal(SIGTRAP, dbgsig);
  609.   oldSEGV = signal(SIGSEGV, dbgsig);
  610.   oldFPE = signal(SIGFPE, dbgsig);
  611.   oldINT = signal(SIGINT, dbgsig);
  612.   movedata(a_tss.tss_fs,0,my_ds,(unsigned)&si,sizeof(si));
  613.   memset(mem_handles,0,sizeof(mem_handles));
  614.   mem_handles[0] = si.memory_handle;
  615.   memset(descriptors,0,sizeof(descriptors));
  616.   descriptors[0] = si.cs_selector;
  617.   descriptors[1] = si.ds_selector;
  618.   descriptors[2] = __djgpp_app_DS;
  619.   descriptors[3] = app_cs; 
  620.   memset(dos_descriptors,0,sizeof(dos_descriptors));
  621.   dos_descriptors[0] = _farpeekw(si.psp_selector,0x2c);
  622.   dos_descriptors[1] = si.psp_selector; 
  623. }
  624.  
  625. void cleanup_client(void)
  626. {
  627.   int i;
  628.   for (i=0;i<DOS_DESCRIPTOR_COUNT;i++)
  629.   {
  630.     if (dos_descriptors[i])
  631.     {
  632. #ifdef DEBUG_DBGCOM
  633.       fprintf(stderr,"free dos memory: %08x\n",dos_descriptors[i]);
  634. #endif
  635.       __dpmi_free_dos_memory(dos_descriptors[i]);
  636.     }
  637.   }
  638.   for (i=0;i<MEM_HANDLE_COUNT;i++)
  639.   {
  640.     if (mem_handles[i])
  641.     {
  642. #ifdef DEBUG_DBGCOM
  643.       fprintf(stderr,"free mem : %08lx\n",mem_handles[i]);
  644. #endif
  645.       __dpmi_free_memory(mem_handles[i]);
  646.     }
  647.   }
  648.   for (i=0;i<DESCRIPTOR_COUNT;i++)
  649.   {
  650.     if (descriptors[i])
  651.     {
  652. #ifdef DEBUG_DBGCOM
  653.       fprintf(stderr,"free descriptor: %08x\n",descriptors[i]);
  654. #endif
  655.       __dpmi_free_ldt_descriptor(descriptors[i]);
  656.     }
  657.   }
  658.   signal(SIGTRAP, oldTRAP);
  659.   signal(SIGSEGV, oldSEGV);
  660.   signal(SIGFPE, oldFPE);
  661.   signal(SIGINT, oldINT);
  662. }
  663.