home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <io.h>
- #include <string.h>
- #include <dos.h>
-
- #include "gotypes.h"
- #include "aout.h"
- #include "extdebug.h"
- #include "dpmi.h"
- #include "paging.h"
- #include "tss.h"
- #include "exphdlr.h"
- #include "mswitch.h"
- #include "utils.h"
- #include "gdt.h"
- #include "utils.h"
- #include "eventque.h"
-
- extern EventQueue *event_queue;
- extern word32 dr[8];
- extern word32 dr0, dr1, dr2, dr3, dr6, dr7;
- extern DPMImemory DPMImem; /* DPMI arena address from paging.c */
-
- static ExternalDebuggerInfo ext_debug_info;
- int using_external_debugger = 0;
- static word16 ourDSsel;
- static int breakhandle[4],nset; /* for DPMI breakpoints */
-
- #define VCPI_ED 1
-
- void load_external_debugger(char *fn, char *running_fname, char *argv0)
- {
- FILEHDR eh;
- GNU_AOUT gah;
- #if VCPI_ED
- word32 edb_base;
- #endif
- int fd;
- char fn2[100], *fns;
-
- fd = _open(fn, O_RDONLY);
-
- if (fd < 0)
- {
- char *cp;
- strcpy(fn2, argv0);
- fns = 0;
- for (cp=fn2; *cp; cp++)
- if (strchr(":\\/", *cp))
- fns = cp;
- if (fns)
- {
- strcpy(fns+1, fn);
- fd = _open(fn2, O_RDONLY);
- if (fd >= 0)
- fn = fn2;
- }
- }
-
- if (fd < 0)
- {
- char *path = getenv("PATH");
- char *pathbeg=path, *pathsep;
- while (1)
- {
- pathsep = pathbeg;
- while (*pathsep && *pathsep != ';')
- pathsep++;
- strncpy(fn2, pathbeg, pathsep-pathbeg);
- fn2[pathsep-pathbeg] = '/';
- strcpy(fn2+(pathsep-pathbeg)+1, fn);
- fd = _open(fn2, O_RDONLY);
- if (fd >= 0)
- {
- fn = fn2;
- break;
- }
- if (*pathsep == 0)
- break;
- pathbeg = pathsep+1;
- }
- }
-
- if (fd < 0)
- {
- fprintf(stderr, "Error: cannot open external debugger file %s\n", fn);
- perror("The error was");
- exit(1);
- }
- read(fd, &eh, sizeof(eh));
- if (eh.f_magic != 0x14c)
- {
- fprintf(stderr, "Invalid external debugger %s - not COFF binary\n", fn);
- exit(1);
- }
- read(fd, &gah, sizeof(gah));
-
- #if VCPI_ED
- if (use_DPMI)
- edb_base = 0;
- else
- edb_base = 0x90000000L;
-
- if (gah.entry != edb_base+0x0a8L)
- {
- fprintf(stderr, "Invalid external debugger %s - entry point not 0x%lx (is 0x%lx)\n", fn, edb_base+0xa8L, gah.entry);
- if (gah.entry == 0x900000a8L)
- fprintf(stderr, "Try using the DPMI binary - ed32-dpmi - instead\n");
- if (gah.entry == 0xa8)
- fprintf(stderr, "Try using the non-DPMI binary - edebug32 - instead\n");
- exit(1);
- }
- #endif
-
- memcpy(&ed_tss, &a_tss, sizeof(TSS)); /* clone a_tss */
- tss_ptr = &ed_tss;
- ed_tss.tss_eip = gah.entry;
-
- if (use_DPMI) {
- AREAS dbgarea;
- word32 newbytes;
- DPMImemory dbgmem;
- int dbgselect;
-
- dbgarea.first_addr = 0;
- dbgarea.last_addr = gah.tsize + gah.dsize + 0xa7;
- dbgarea.foffset = 0;
- dbgarea.fileno = fd;
-
- newbytes = (dbgarea.last_addr + 0x100fffL) & ~0xfff; /* 1Mb extra */
- DPMIprotectedMode();
- if (! DPMIalloc(&dbgmem, newbytes)) {
- DPMIrealMode();
- fprintf(stderr,"DPMI: Not enough memory for debugger (0x%08lx bytes).\n", newbytes);
- exit(1);
- }
-
- ourDSsel = _DS; /* in protected mode, of course */
- dbgselect = DPMIselector(2); /* one for CS, one for SS/DS */
-
- DPMIassignSelector(dbgselect, 0xc0b3, dbgmem.address, dbgmem.bytes - 1 );
- DPMIassignSelector(dbgselect+8, 0xc0bb, dbgmem.address, dbgmem.bytes - 1 );
- DPMIrealMode();
-
- ed_tss.tss_ds = ed_tss.tss_es = ed_tss.tss_fs =
- ed_tss.tss_ss = dbgselect;
- ed_tss.tss_cs = dbgselect + 8;
- ed_tss.tss_esp = dbgmem.bytes - 12;
- ed_tss.tss_eflags = 0x0202;
-
- loadAout(&dbgarea);
- Pmemset(dbgselect, dbgarea.last_addr+1, 0, dbgmem.bytes-dbgarea.last_addr-1);
-
- close(fd);
- } else {
-
- #if VCPI_ED
- areas[A_syms].first_addr = 0xa0000000L;
- areas[A_syms].last_addr = 0xa00000a7L + gah.tsize + gah.dsize;
- #else
- areas[A_syms].first_addr = 0xa0001000L;
- areas[A_syms].last_addr = 0xa00010a7L + gah.tsize + gah.dsize;
- #endif
- areas[A_syms].foffset = 0;
- areas[A_syms].fileno = fd;
-
- areas[A_syms2].first_addr = areas[A_syms].last_addr+1;
- areas[A_syms2].last_addr = 0xafffffffL;
- areas[A_syms2].foffset = -1;
-
- #if !VCPI_ED
- ed_tss.tss_esp = 0x0ffffff4l;
- ed_tss.tss_ds = g_edds * 8;
- ed_tss.tss_es = g_edds * 8;
- ed_tss.tss_ss = g_edds * 8;
- ed_tss.tss_cs = g_edcs * 8;
- ed_tss.tss_edi = 0;
- ed_tss.tss_ebx = 0;
- ed_tss.tss_ebp = 0;
- #else
- ed_tss.tss_esp = 0x9ffffff4l;
- #endif
- ourDSsel = g_rdata * 8;
- }
-
- ext_debug_info.version = EXTERNAL_DEBUGGER_VERSION;
-
- ext_debug_info.a_tss_ofs = FP_OFF(&a_tss);
- ext_debug_info.a_tss_seg = ourDSsel;
-
- ext_debug_info.filename_ofs = FP_OFF(running_fname);
- ext_debug_info.filename_seg = ourDSsel;
- ext_debug_info.filename_len = strlen(running_fname);
-
- ext_debug_info.areas_ofs = FP_OFF(&areas);
- ext_debug_info.areas_seg = ourDSsel;
-
- ext_debug_info.app_base = ARENA;
- ext_debug_info.ansi_mode = use_ansi;
-
- memset(ext_debug_info.dr, 32, 0);
-
- using_external_debugger = 1;
- }
-
- void set_break_DPMI(void)
- {
- int i,enabled,extract;
- word16 sizetype;
- word32 br_addr;
-
- enabled = (int)dr[7];
- extract = (int)(dr[7] >> 16);
- nset = 0;
-
- for(i=0;i<4;i++)
- if( (enabled >> (i*2))&3 ) {
- sizetype = (extract >> (i*4)) & 3; /* extract the type */
- if(sizetype == 3) sizetype = 2; /* convert for DPMI brain damage */
- sizetype = (sizetype << 8) + ((extract >> (i*4+2)) & 3) + 1; /* & size */
- br_addr = dr[i] + DPMImem.address;
- breakhandle[i] = DPMIsetBreak(sizetype, br_addr);
- if(breakhandle[i] == -1)
- fprintf(stderr,"Error allocating DPMI breakpoint at address 0x%08lx\n",dr[i]);
- else
- nset++;
- } else
- breakhandle[i] = -1;
- return;
- }
-
- void clear_break_DPMI(void)
- {
- int i,bt;
-
- if(!nset) {
- dr[6] = 0L;
- return;
- }
-
- bt = 0;
- for(i=3;i>=0;i--) {
- bt = bt << 1; /* Shift for next bit */
- if(breakhandle[i] != -1)
- bt |= DPMIcancelBreak(breakhandle[i]); /* Set low bit if active */
- }
-
- dr[6] = (word32)bt;
- }
-
- int external_debugger_handler(void)
- {
- static unsigned char old_enable;
- if (tss_ptr != &ed_tss)
- return 1;
- switch ((word8)(tss_ptr->tss_eax))
- {
- case EXTERNAL_DEBUGGER_EXECUTE:
- if(event_queue != NULL) /* enable events */
- event_queue->evq_enable = old_enable;
- tss_ptr = &a_tss;
- memcpy(dr, ext_debug_info.dr, 32);
- if (use_DPMI)
- set_break_DPMI();
- go_til_stop();
- if (use_DPMI)
- clear_break_DPMI();
- memcpy(ext_debug_info.dr, dr, 32);
- if(event_queue != NULL) { /* disable events */
- old_enable = event_queue->evq_enable;
- event_queue->evq_enable = 0;
- }
- if (a_tss.tss_irqn <= hard_master_hi && a_tss.tss_irqn >= hard_master_lo)
- a_tss.tss_irqn -= hard_master_lo - 8;
- if (a_tss.tss_irqn <= hard_slave_hi && a_tss.tss_irqn >= hard_slave_lo)
- a_tss.tss_irqn -= hard_slave_lo - 0x70;
- tss_ptr = &ed_tss;
- return 0;
-
- case EXTERNAL_DEBUGGER_GETINFOPTR:
- tss_ptr->tss_eax = FP_OFF(&ext_debug_info);
- tss_ptr->tss_edx = ourDSsel;
- return 0;
-
- default:
- return 1;
- }
- }
-
-