wdbDbgArchLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:10k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* wdbDbgArchLib.c - i86 specific debug support */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01f,30may02,hdn  added wdbDbgCtxPc/Cs/Esp to save the state (spr 75694)
  7. 01e,29aug01,hdn  replaced intVecSet with intVecSet2
  8.  doc: cleanup.
  9. 01d,08jan98,dbt  modified for new breakpoint scheme. Added hardware
  10.  breakpoints support
  11. 01c,15jun95,ms  removed sigCtxIntLock. Made traceModeSet/Clear use intRegsLock.
  12. 01b,25may95,ms  cleaned up + added _sigCtxIntLock.
  13. 01a,18jan94,rrr  written.
  14. */
  15. /*
  16. DESCPRIPTION
  17. Arch-specific debug support.
  18. i80386 has four breakpoint registers and the following types of hardware
  19. breakpoint:
  20. .CS
  21.    BRK_INST /@ instruction hardware breakpoint @/
  22.    BRK_DATAW1 /@ data write 1 byte breakpoint @/
  23.    BRK_DATAW2 /@ data write 2 byte breakpoint @/
  24.    BRK_DATAW4 /@ data write 4 byte breakpoint @/
  25.    BRK_DATARW1 /@ data read-write 1 byte breakpoint @/
  26.    BRK_DATARW2 /@ data read-write 2 byte breakpoint @/
  27.    BRK_DATARW4 /@ data read-write 4 byte breakpoint @/
  28. .CE
  29. NOMANUAL
  30. */
  31. #include "vxWorks.h"
  32. #include "regs.h"
  33. #include "iv.h"
  34. #include "intLib.h"
  35. #include "esf.h"
  36. #include "wdb/wdbDbgLib.h"
  37. /* externals */
  38. extern void wdbDbgBpStub(void);
  39. extern void wdbDbgTraceStub(void);
  40. extern int  sysCsExc;
  41. /* globals */
  42. UINT32 wdbDbgCtxCs = 0; /* old CS */
  43. UINT32 wdbDbgCtxPc = 0; /* old PC */
  44. UINT32 wdbDbgCtxEsp = 0; /* old ESP */
  45. /* forward declaration */
  46. static void wdbDbgArchRegsGet (TRACE_ESF * info, int * regs, REG_SET * pRegSet,
  47. DBG_REGS * pDbgRegSet, BOOL traceException);
  48. /*******************************************************************************
  49. *
  50. * wdbDbgArchInit - set exception handlers for the break and the trace.
  51. *
  52. * This routine set exception handlers for the break and the trace.
  53. * And also make a break instruction.
  54. *
  55. * NOMANUAL
  56. */
  57. void wdbDbgArchInit
  58.     (
  59.     void
  60.     )
  61.     {
  62.     /* Insert the new breakpoint and trace vectors */
  63.     intVecSet2 ((FUNCPTR *)IV_BREAKPOINT, (FUNCPTR) wdbDbgBpStub,
  64.                    IDT_INT_GATE, sysCsExc);
  65.     intVecSet2 ((FUNCPTR *)IV_DEBUG, (FUNCPTR) wdbDbgTraceStub,
  66.            IDT_INT_GATE, sysCsExc);
  67.     }
  68. /*******************************************************************************
  69. *
  70. * wdbDbgTraceModeSet - set a debug-mode or a trace-mode
  71. *
  72. * This routine make CPU trace-enable.
  73. *
  74. * NOMANUAL
  75. */
  76. int wdbDbgTraceModeSet
  77.     (
  78.     REG_SET * pRegs
  79.     )
  80.     {
  81.     int tmp;
  82.     tmp = intRegsLock (pRegs);
  83.     pRegs->eflags |= TRACE_FLAG;
  84.     return (tmp);
  85.     }
  86. /*******************************************************************************
  87. *
  88. * wdbDbgTraceModeClear - clear a trace-mode
  89. *
  90. * This routine make CPU trace-disable.
  91. *
  92. * NOMANUAL
  93. */
  94. void wdbDbgTraceModeClear
  95.     (
  96.     REG_SET * pRegs,
  97.     int arg
  98.     )
  99.     {
  100.     intRegsUnlock (pRegs, arg);
  101.     pRegs->eflags &= ~TRACE_FLAG;
  102.     }
  103. /*******************************************************************************
  104. *
  105. * wdbDbgArchRegsGet - get a register set from saved registers on stack
  106. *
  107. * This routine gets a register set from saved registers on stack.
  108. *
  109. * RETURNS: N/A
  110. *
  111. * NOMANUAL
  112. */
  113. static void wdbDbgArchRegsGet
  114.     (
  115.     TRACE_ESF * info, /* pointer to esf info saved on stack */
  116.     int *  regs, /* pointer to regs saved on stack */
  117.     REG_SET * pRegSet, /* pointer to register set */
  118.     DBG_REGS * pDbgRegSet, /* pointer to register set */
  119.     BOOL traceException /* TRUE if this was a trace exception */
  120.     )
  121.     {
  122.     if (pDbgRegSet != NULL)
  123. {
  124. pDbgRegSet->db0 = *regs++; /* read the debug registers */
  125. pDbgRegSet->db1 = *regs++;
  126. pDbgRegSet->db2 = *regs++;
  127. pDbgRegSet->db3 = *regs++;
  128. pDbgRegSet->db6 = *regs++;
  129. pDbgRegSet->db7 = *regs++;
  130. }
  131.     else
  132. regs += 6;
  133.     pRegSet->edi = *regs++; /* read the global registers */
  134.     pRegSet->esi = *regs++;
  135.     pRegSet->ebp = *regs++;
  136.     regs++;
  137.     pRegSet->ebx = *regs++;
  138.     pRegSet->edx = *regs++;
  139.     pRegSet->ecx = *regs++;
  140.     pRegSet->eax = *regs++;
  141.     pRegSet->spReg = (ULONG) ((char *)info + sizeof (ESF0));
  142.     pRegSet->pc  = info->pc;
  143.     pRegSet->eflags = info->eflags;
  144.     }
  145. /******************************************************************************
  146. *
  147. * wdbDbgPreBreakpoint - handle a breakpoint
  148. *
  149. * This routine is the I86 specific handler for breakpoints (soft and hardware).
  150. *
  151. * RETURNS: N/A
  152. *
  153. * NOMANUAL
  154. */ 
  155. void wdbDbgPreBreakpoint
  156.     (
  157.     BREAK_ESF * info, /* pointer to info saved on stack */
  158.     int * regs, /* pointer to saved registers */
  159.     BOOL hardware /* TRUE if it is hardware breakpoint */
  160.     )
  161.     {
  162.     REG_SET regSet;
  163.     DBG_REGS dbgRegSet;
  164.     wdbDbgArchRegsGet (info, regs, &regSet, &dbgRegSet, FALSE);
  165.     /* save the CS in ESF, to restore it in _wdbDbgCtxLoad() */
  166.     wdbDbgCtxCs  = info->cs;
  167.     wdbDbgCtxPc  = (UINT32)regSet.pc;
  168.     wdbDbgCtxEsp = regSet.esp;
  169.     wdbDbgBreakpoint((void *)info, &regSet, &dbgRegSet, hardware);
  170.     }
  171. /******************************************************************************
  172. *
  173. * wdbDbgPreTrace - handle a single step
  174. *
  175. * This routine is the I86 specific handler for single steps.
  176. *
  177. * RETURNS: N/A
  178. *
  179. * NOMANUAL
  180. */ 
  181. void wdbDbgPreTrace
  182.     (
  183.     BREAK_ESF * info, /* pointer to info saved on stack */
  184.     int * regs, /* pointer to saved registers */
  185.     BOOL hardware /* TRUE if it is a hardware breakpoint */
  186.     )
  187.     {
  188.     REG_SET regSet;
  189.     wdbDbgArchRegsGet (info, regs, &regSet, NULL, FALSE);
  190.     /* save the CS in ESF, to restore it in _wdbDbgCtxLoad() */
  191.     wdbDbgCtxCs  = info->cs;
  192.     wdbDbgCtxPc  = (UINT32)regSet.pc;
  193.     wdbDbgCtxEsp = regSet.esp;
  194.     wdbDbgTrace((void *)info, &regSet);
  195.     }
  196. #if DBG_HARDWARE_BP
  197. /*******************************************************************************
  198. *
  199. * wdbDbgHwAddrCheck - check the address for the hardware breakpoint.
  200. *
  201. * This routine check the address for the hardware breakpoint.
  202. *
  203. * RETURNS: OK or ERROR if the address is not appropriate.
  204. *
  205. * NOMANUAL
  206. */
  207. STATUS wdbDbgHwAddrCheck
  208.     (
  209.     UINT32  addr, /* address for hardware breakpoint */
  210.     UINT32 type, /* hardware breakpoint type */
  211.     FUNCPTR memProbeRtn /* memProbe routine */
  212.     )
  213.     {
  214.     ULONG dummy;
  215.     type &= BRK_HARDMASK;
  216.     /* be sure address isn't odd, or beyond end of memory */
  217.     if ((type == BRK_DATAW1) || (type == BRK_DATARW1))
  218.         {
  219.         if (memProbeRtn ((char *) addr, READ, 1, (char*)&dummy) != OK)
  220.             return (ERROR);
  221.         }
  222.     else if ((type == BRK_DATAW2) || (type == BRK_DATARW2))
  223.         {
  224.         if (((int)addr & 1) ||
  225.             memProbeRtn ((char *) addr, READ, 2, (char*)&dummy) != OK)
  226.     {
  227.             return (ERROR);
  228.             }
  229.         }
  230.     else if ((type == BRK_DATAW4) || (type == BRK_DATARW4))
  231.         {
  232.         if ((addr & 3) ||
  233.             memProbeRtn ((char *) addr, READ, 4, (char*)&dummy) != OK)
  234.             {
  235.             return (ERROR);
  236.             }
  237.         }
  238.     return (OK);
  239.     }
  240. /******************************************************************************
  241. *
  242. * wdbDbgHwBpSet - set a data breakpoint register
  243. *
  244. * type is the type of access that will generate a breakpoint.
  245. *
  246. * NOMANUAL
  247. */
  248. STATUS wdbDbgHwBpSet 
  249.     (
  250.     DBG_REGS * pDbgRegs, /* debug registers */
  251.     UINT32 access, /* access type */
  252.     UINT32  addr /* breakpoint addr */
  253.     )
  254.     {
  255.     switch (access)
  256. {
  257. case BRK_INST:
  258. case BRK_DATAW1:
  259. case BRK_DATAW2:
  260. case BRK_DATAW4:
  261. case BRK_DATARW1:
  262. case BRK_DATARW2:
  263. case BRK_DATARW4:
  264.     break;
  265. default:
  266.     return (WDB_ERR_INVALID_HW_BP);
  267. }
  268.     if (pDbgRegs->db0 == 0)
  269. {
  270. pDbgRegs->db0 = addr;
  271. pDbgRegs->db7 |= (access << 16) | 0x02;
  272. }
  273.     else if (pDbgRegs->db1 == 0)
  274. {
  275. pDbgRegs->db1 = addr;
  276. pDbgRegs->db7 |= (access << 20) | 0x08;
  277. }
  278.     else if (pDbgRegs->db2 == 0)
  279. {
  280. pDbgRegs->db2 = addr;
  281. pDbgRegs->db7 |= (access << 24) | 0x20;
  282. }
  283.     else if (pDbgRegs->db3 == 0)
  284. {
  285. pDbgRegs->db3 = addr;
  286. pDbgRegs->db7 |= (access << 28) | 0x80;
  287. }
  288.     else
  289. return (WDB_ERR_HW_REGS_EXHAUSTED);
  290.     /* set GE bit if it is data breakpoint */
  291.     if (access & 0x300)
  292. pDbgRegs->db7 |= 0x200;
  293.     return (OK);
  294.     }
  295. /******************************************************************************
  296. *
  297. * wdbDbgHwBpFind - Find the hardware breakpoint
  298. *
  299. * This routines find the type and the address of the address of the 
  300. * hardware breakpoint that is set in the DBG_REGS structure.
  301. * Those informations are stored in the breakpoint structure that is passed
  302. * in parameter.
  303. *
  304. * RETURNS : OK or ERROR if unable to find a hardware breakpoint
  305. *
  306. * NOMANUAL
  307. */ 
  308. STATUS wdbDbgHwBpFind
  309.     (
  310.     DBG_REGS * pDbgRegs, /* debug registers */
  311.     UINT32 * pType, /* return type info via this pointer */
  312.     UINT32 * pAddr /* return address info via this pointer */
  313.     )
  314.     {
  315.     int ix;
  316.     int type = 0;
  317.     int addr = 0;
  318.     int statusBit, enableBit;
  319.     /* get address and type of breakpoint from DR6 and DR7 */
  320.     for (ix=0; ix<4; ix++)
  321. {
  322. statusBit = 1 << ix;
  323. enableBit = 2 << (ix << 1);
  324. if ((pDbgRegs->db6 & statusBit) && (pDbgRegs->db7 & enableBit))
  325.     {
  326.     switch (ix)
  327. {
  328. case 0:
  329.     addr = pDbgRegs->db0;
  330.     type = (pDbgRegs->db7 & 0x000f0000) >> 16 | BRK_HARDWARE;
  331.     break;
  332. case 1:
  333.     addr = pDbgRegs->db1;
  334.     type = (pDbgRegs->db7 & 0x00f00000) >> 20 | BRK_HARDWARE;
  335.     break;
  336. case 2:
  337.     addr = pDbgRegs->db2;
  338.     type = (pDbgRegs->db7 & 0x0f000000) >> 24 | BRK_HARDWARE;
  339.     break;
  340. case 3:
  341.     addr = pDbgRegs->db3;
  342.     type = (pDbgRegs->db7 & 0xf0000000) >> 28 | BRK_HARDWARE;
  343.     break;
  344. }
  345.     }
  346. }
  347.     if ((addr == 0) && (type == 0))
  348. return (ERROR);
  349.     *pType = type;
  350.     *pAddr = addr;
  351.     return (OK);
  352.     }
  353. /*******************************************************************************
  354. *
  355. * wdbDbgRegsClear - clear hardware break point registers
  356. *
  357. * This routine cleans hardware breakpoint registers.
  358. *
  359. * RETURNS : N/A.
  360. *
  361. * NOMANUAL
  362. */
  363. void wdbDbgRegsClear
  364.     (
  365.     void
  366.     )
  367.     {
  368.     DBG_REGS dbgRegs;
  369.     dbgRegs.db0 = 0;
  370.     dbgRegs.db1 = 0;
  371.     dbgRegs.db2 = 0;
  372.     dbgRegs.db6 = 0;
  373.     dbgRegs.db7 = 0;
  374.     wdbDbgRegsSet (&dbgRegs);
  375.     }
  376. #endif /* DBG_HARDWARE_BP */