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

VxWorks

开发平台:

C/C++

  1. /* dbgArchLib.c - i80x86 architecture-specific debugging facilities */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01h,20nov01,hdn  doc clean up for 5.5.  revived edi() - eflags().
  8. 01g,08jan98,dbt  modified for new breakpoint scheme
  9. 01f,10feb95,jdi  doc tweak for 5.2.
  10. 01e,14dec93,hdn  added _archHelp_msg.
  11. 01d,29nov93,hdn  added eax() - eflags().
  12. 01c,27aug93,hdn  added _dbgTaskPCSet().
  13. 01b,16jun93,hdn  updated to 5.1.
  14.   - changed functions to ansi style
  15.   - changed VOID to void
  16.   - changed copyright notice
  17. 01a,08jul92,hdn  written based on tron/dbgLib.c.
  18. */
  19. /*
  20. DESCRIPTION
  21. This module provides the architecture dependent support functions for
  22. dbgLib. 
  23. x86 including P5(Pentium), P6(PentiumPro, II, III), and P7(Pentium4) family
  24. processors have four breakpoint registers and the following types of 
  25. hardware breakpoint:
  26. .CS
  27.    BRK_INST             /@ instruction hardware breakpoint @/
  28.    BRK_DATAW1           /@ data write 1 byte breakpoint @/
  29.    BRK_DATAW2           /@ data write 2 byte breakpoint @/
  30.    BRK_DATAW4           /@ data write 4 byte breakpoint @/
  31.    BRK_DATARW1          /@ data read-write 1 byte breakpoint @/
  32.    BRK_DATARW2          /@ data read-write 2 byte breakpoint @/
  33.    BRK_DATARW4          /@ data read-write 4 byte breakpoint @/
  34. .CE
  35. NOMANUAL
  36. */
  37. /* LINTLIBRARY */
  38. #include "vxWorks.h"
  39. #include "taskLib.h"
  40. #include "taskArchLib.h"
  41. #include "intLib.h"
  42. #include "regs.h"
  43. #include "iv.h"
  44. #include "cacheLib.h"
  45. #include "ioLib.h"
  46. #include "dsmLib.h"
  47. #include "vxLib.h"
  48. #include "usrLib.h"
  49. #include "stdio.h"
  50. #include "dbgLib.h"
  51. /* defines */
  52. #define DSM(addr,inst,mask)     ((*(addr) & (mask)) == (inst))
  53. /* externals */
  54. IMPORT int  dsmInst ();
  55. /* globals */
  56. char * _archHelp_msg = 
  57. #ifdef  DBG_HARDWARE_BP
  58.     "bh addr[,access[,task[,count[,quiet]]]] Set hardware breakpointn"
  59.     "         access :      0 - instruction        1 - write 1 byten"
  60.     "                       3 - read/write 1 byte  5 - write 2 bytesn"
  61.     "                       7 - read/write 2 bytes d - write 4 bytesn"
  62.     "                       f - read/write 4 bytes"
  63. #endif /* DBG_HARDWARE_BP */
  64.     "n";
  65. /* forward declarations */
  66. LOCAL int getOneReg (int taskId, int regCode);
  67. /*******************************************************************************
  68. *
  69. * _dbgArchInit - architecture dependent initialization routine
  70. *
  71. * This routine initialize global function pointers that are architecture 
  72. * specific.
  73. *
  74. * RETURNS: N/A
  75. *
  76. * NOMANUAL
  77. */
  78. void _dbgArchInit (void)
  79.     {
  80.     _dbgDsmInstRtn = (FUNCPTR) dsmInst;
  81.     }
  82. /*******************************************************************************
  83. *
  84. * _dbgRetAdrsGet - get a next instruction for cret ()
  85. *
  86. * if next instruction is a ENTER or RET, return address is on top of stack.
  87. * otherwise it follows saved frame pointer.
  88. *
  89. *
  90. * NOMANUAL
  91. */
  92. INSTR * _dbgRetAdrsGet
  93.     (
  94.     REG_SET * pRegSet /* register set */
  95.     )
  96.     {
  97.     INSTR *returnAddress;
  98.     if (DSM(pRegSet->pc,   PUSH_EBP, PUSH_EBP_MASK) && 
  99. DSM(pRegSet->pc+1, MOV_ESP0, MOV_ESP0_MASK) &&
  100. DSM(pRegSet->pc+2, MOV_ESP1, MOV_ESP1_MASK))
  101. {
  102. returnAddress = *(INSTR **)pRegSet->spReg;
  103. }
  104.     else if (DSM(pRegSet->pc-1, PUSH_EBP, PUSH_EBP_MASK) && 
  105.      DSM(pRegSet->pc,   MOV_ESP0, MOV_ESP0_MASK) &&
  106.      DSM(pRegSet->pc+1, MOV_ESP1, MOV_ESP1_MASK))
  107. {
  108. returnAddress = *((INSTR **)pRegSet->spReg + 1);
  109. }
  110.     else if (DSM(pRegSet->pc, ENTER, ENTER_MASK))
  111. {
  112. returnAddress = *(INSTR **)pRegSet->spReg;
  113. }
  114.     else if ((DSM(pRegSet->pc, RET,    RET_MASK)) ||
  115.      (DSM(pRegSet->pc, RETADD, RETADD_MASK)))
  116. {
  117. returnAddress = *(INSTR **)pRegSet->spReg;
  118. }
  119.     else
  120. {
  121. returnAddress = *((INSTR **)pRegSet->fpReg + 1);
  122. }
  123.     return (returnAddress);
  124.     }
  125. /*******************************************************************************
  126. *
  127. * _dbgFuncCallCheck - check next instruction
  128. *
  129. * This routine checks to see if the next instruction is a CALL
  130. * If it is, it returns TRUE, otherwise, returns FALSE.
  131. *
  132. * RETURNS: TRUE if next instruction is a CALL, or FALSE otherwise.
  133. *
  134. * NOMANUAL
  135. */
  136. BOOL _dbgFuncCallCheck
  137.     (
  138.     INSTR * addr /* pointer to instruction */
  139.     )
  140.     {
  141.     return ((DSM (addr, CALL_INDIR0, CALL_INDIR0_MASK) &&
  142.      DSM (addr + 1, CALL_INDIR1, CALL_INDIR1_MASK)) || 
  143.     (DSM (addr, CALL_DIR, CALL_DIR_MASK)));
  144.     }
  145. /*******************************************************************************
  146. *
  147. * _dbgInstSizeGet - set up the breakpoint instruction
  148. *
  149. * RETURNS: size of the instruction at specified location.
  150. *
  151. * NOMANUAL
  152. */
  153. int _dbgInstSizeGet
  154.     (
  155.     INSTR * pBrkInst /* pointer to hold breakpoint instruction */
  156.     )
  157.     {
  158.     return (dsmNbytes (pBrkInst));
  159.     }
  160. /*******************************************************************************
  161. *
  162. * _dbgTaskPCGet - get task's program counter PC
  163. *
  164. * RETURNS:task's program counter
  165. *
  166. * NOMANUAL
  167. */
  168. INSTR * _dbgTaskPCGet
  169.     (
  170.     int tid /* task's id */
  171.     )
  172.     {
  173.     REG_SET regSet;
  174.     (void) taskRegsGet (tid, &regSet);
  175.     return ((INSTR *) regSet.pc);
  176.     }
  177. /*******************************************************************************
  178. *
  179. * _dbgTaskPCSet - set task's program counter PC
  180. *
  181. * RETURNS: N/A
  182. *
  183. * NOMANUAL
  184. */
  185. void _dbgTaskPCSet
  186.     (
  187.     int task, /* task id */
  188.     INSTR * pc, /* new PC */
  189.     INSTR * npc /* not supported on I80X86 */
  190.     )
  191.     {
  192.     REG_SET regSet;
  193.     if (taskRegsGet (task, &regSet) != OK)
  194.         return;
  195.     regSet.pc = pc;
  196.     (void)taskRegsSet (task, &regSet);
  197.     }
  198. #ifdef DBG_HARDWARE_BP
  199. /*******************************************************************************
  200. *
  201. * _dbgBrkDisplayHard - display a hardware breakpoint
  202. *
  203. * This routine displays a hardware breakpoint.
  204. *
  205. * NOMANUAL
  206. */
  207. void _dbgBrkDisplayHard
  208.     (
  209.     BRKPT * pBp /* breakpoint table entry */
  210.     )
  211.     {
  212.     int type;
  213.     if ((pBp->bp_flags & BRK_HARDWARE) == 0)
  214. return;
  215.     type = pBp->bp_flags & BRK_HARDMASK;
  216.     printf (" (hard-");
  217.     switch (type)
  218. {
  219. case BRK_INST:
  220.     printf ("inst)");
  221.     break;
  222. case BRK_DATAW1:
  223.     printf ("dataw1)");
  224. break;
  225. case BRK_DATAW2:
  226.     printf ("dataw2)");
  227.     break;
  228. case BRK_DATAW4:
  229.     printf ("dataw4)");
  230.     break;
  231. case BRK_DATARW1:
  232.     printf ("datarw1)");
  233.     break;
  234. case BRK_DATARW2:
  235.     printf ("datarw2)");
  236.     break;
  237. case BRK_DATARW4:
  238.     printf ("datarw4)");
  239.     break;
  240. default:
  241.     printf ("unknown)");
  242.     break;
  243. }
  244.     }
  245. #endif /* DBG_HARDWARE_BP */
  246. /*******************************************************************************
  247. *
  248. * getOneReg - return the contents of one register
  249. *
  250. * Given a task's ID, this routine returns the contents of the register
  251. * specified by the register code.  This routine is used by eax, edx, etc.
  252. * The register codes are defined in dbgI86Lib.h.
  253. *
  254. * RETURNS: register contents, or ERROR.
  255. */
  256. LOCAL int getOneReg (taskId, regCode)
  257.     int taskId; /* task's id, 0 means default task */
  258.     int regCode; /* code for specifying register */
  259.     {
  260.     REG_SET regSet; /* get task's regs into here */
  261.     taskId = taskIdFigure (taskId); /* translate super name to id */
  262.     if (taskId == ERROR) /* couldn't figure out super name */
  263. return (ERROR);
  264.     taskId = taskIdDefault (taskId); /* set the default id */
  265.     if (taskRegsGet (taskId, &regSet) != OK)
  266. return (ERROR);
  267.     switch (regCode)
  268. {
  269. case EDI: return (regSet.edi);
  270. case ESI: return (regSet.esi);
  271. case EBP: return (regSet.ebp);
  272. case ESP: return (regSet.esp);
  273. case EBX: return (regSet.ebx);
  274. case EDX: return (regSet.edx);
  275. case ECX: return (regSet.ecx);
  276. case EAX: return (regSet.eax);
  277. case EFLAGS: return (regSet.eflags);
  278. }
  279.     return (ERROR); /* unknown regCode */
  280.     }
  281. /*******************************************************************************
  282. *
  283. * edi - return the contents of register `edi' (also `esi' - `eax') (x86)
  284. *
  285. * This command extracts the contents of register `edi' from the TCB of a
  286. * specified task.  If <taskId> is omitted or zero, the last task
  287. * referenced is assumed.
  288. *
  289. * Similar routines are provided for all general registers (`edi' - `eax'):
  290. * edi() - eax().
  291. *
  292. * The stack pointer is accessed via eax().
  293. *
  294. * RETURNS: The contents of register `edi' (or the requested register).
  295. *
  296. * SEE ALSO:
  297. * .pG "Debugging"
  298. */
  299. int edi
  300.     (
  301.     int taskId /* task ID, 0 means default task */
  302.     )
  303.     {
  304.     return (getOneReg (taskId, EDI));
  305.     }
  306. int esi (taskId) int taskId; { return (getOneReg (taskId, ESI)); }
  307. int ebp (taskId) int taskId; { return (getOneReg (taskId, EBP)); }
  308. int esp (taskId) int taskId; { return (getOneReg (taskId, ESP)); }
  309. int ebx (taskId) int taskId; { return (getOneReg (taskId, EBX)); }
  310. int edx (taskId) int taskId; { return (getOneReg (taskId, EDX)); }
  311. int ecx (taskId) int taskId; { return (getOneReg (taskId, ECX)); }
  312. int eax (taskId) int taskId; { return (getOneReg (taskId, EAX)); }
  313. /*******************************************************************************
  314. *
  315. * eflags - return the contents of the status register (x86)
  316. *
  317. * This command extracts the contents of the status register from the TCB of a
  318. * specified task.  If <taskId> is omitted or zero, the last task referenced is
  319. * assumed.
  320. *
  321. * RETURNS: The contents of the status register.
  322. *
  323. * SEE ALSO:
  324. * .pG "Debugging"
  325. */
  326. int eflags
  327.     (
  328.     int taskId /* task ID, 0 means default task */
  329.     )
  330.     {
  331.     return (getOneReg (taskId, EFLAGS));
  332.     }