Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

469 lines
12 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Breakpoint support.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #ifndef _BRKPT_HPP_
  9. #define _BRKPT_HPP_
  10. // Ways in which a breakpoint can be hit. There's full
  11. // match, hit but ignored and not hit.
  12. #define BREAKPOINT_HIT 0
  13. #define BREAKPOINT_HIT_IGNORED 1
  14. #define BREAKPOINT_NOT_HIT 2
  15. //----------------------------------------------------------------------------
  16. //
  17. // Breakpoint.
  18. //
  19. //----------------------------------------------------------------------------
  20. #define BREAKPOINT_EXTERNAL_MODIFY_FLAGS \
  21. (DEBUG_BREAKPOINT_GO_ONLY | DEBUG_BREAKPOINT_ENABLED | \
  22. DEBUG_BREAKPOINT_ADDER_ONLY)
  23. #define BREAKPOINT_EXTERNAL_FLAGS \
  24. (BREAKPOINT_EXTERNAL_MODIFY_FLAGS | DEBUG_BREAKPOINT_DEFERRED)
  25. // Internal flags.
  26. #define BREAKPOINT_KD_INTERNAL 0x80000000
  27. #define BREAKPOINT_KD_COUNT_ONLY 0x40000000
  28. #define BREAKPOINT_VIRT_ADDR 0x20000000
  29. #define BREAKPOINT_INSERTED 0x10000000
  30. #define BREAKPOINT_IN_LIST 0x08000000
  31. #define BREAKPOINT_HIDDEN 0x04000000
  32. #define BREAKPOINT_NOTIFY 0x02000000
  33. // Internal types.
  34. #define EXBS_NONE 0x00000000
  35. #define EXBS_BREAKPOINT_DATA 0x00000001
  36. #define EXBS_BREAKPOINT_CODE 0x00000002
  37. #define EXBS_BREAKPOINT_ANY 0x00000003
  38. #define EXBS_STEP_INSTRUCTION 0x00000004
  39. #define EXBS_STEP_BRANCH 0x00000008
  40. #define EXBS_STEP_ANY 0x0000000c
  41. #define EXBS_ANY 0xffffffff
  42. enum BreakpointMatchAction
  43. {
  44. BREAKPOINT_ALLOW_MATCH,
  45. BREAKPOINT_WARN_MATCH,
  46. BREAKPOINT_REMOVE_MATCH
  47. };
  48. class Breakpoint
  49. : public IDebugBreakpoint
  50. {
  51. public:
  52. Breakpoint* m_Next;
  53. Breakpoint* m_Prev;
  54. ULONG m_Id;
  55. ULONG m_BreakType;
  56. ULONG m_Flags;
  57. ULONG m_DataSize;
  58. ULONG m_DataAccessType;
  59. ULONG m_PassCount;
  60. ULONG m_CurPassCount;
  61. PCSTR m_Command;
  62. PTHREAD_INFO m_MatchThread;
  63. PPROCESS_INFO m_Process;
  64. PCSTR m_OffsetExpr;
  65. DebugClient* m_Adder;
  66. ULONG64 m_MatchThreadData;
  67. ULONG64 m_MatchProcessData;
  68. Breakpoint(DebugClient* Adder, ULONG Id, ULONG Type, ULONG ProcType);
  69. ~Breakpoint(void);
  70. // IUnknown.
  71. STDMETHOD(QueryInterface)(
  72. THIS_
  73. IN REFIID InterfaceId,
  74. OUT PVOID* Interface
  75. );
  76. STDMETHOD_(ULONG, AddRef)(
  77. THIS
  78. );
  79. STDMETHOD_(ULONG, Release)(
  80. THIS
  81. );
  82. // IDebugBreakpoint.
  83. STDMETHOD(GetId)(
  84. THIS_
  85. OUT PULONG Id
  86. );
  87. STDMETHOD(GetType)(
  88. THIS_
  89. OUT PULONG BreakType,
  90. OUT PULONG ProcType
  91. );
  92. STDMETHOD(GetAdder)(
  93. THIS_
  94. OUT PDEBUG_CLIENT* Adder
  95. );
  96. STDMETHOD(GetFlags)(
  97. THIS_
  98. OUT PULONG Flags
  99. );
  100. STDMETHOD(AddFlags)(
  101. THIS_
  102. IN ULONG Flags
  103. );
  104. STDMETHOD(RemoveFlags)(
  105. THIS_
  106. IN ULONG Flags
  107. );
  108. STDMETHOD(SetFlags)(
  109. THIS_
  110. IN ULONG Flags
  111. );
  112. STDMETHOD(GetOffset)(
  113. THIS_
  114. OUT PULONG64 Offset
  115. );
  116. STDMETHOD(SetOffset)(
  117. THIS_
  118. IN ULONG64 Offset
  119. );
  120. STDMETHOD(GetDataParameters)(
  121. THIS_
  122. OUT PULONG Size,
  123. OUT PULONG AccessType
  124. );
  125. STDMETHOD(SetDataParameters)(
  126. THIS_
  127. IN ULONG Size,
  128. IN ULONG AccessType
  129. );
  130. STDMETHOD(GetPassCount)(
  131. THIS_
  132. OUT PULONG Count
  133. );
  134. STDMETHOD(SetPassCount)(
  135. THIS_
  136. IN ULONG Count
  137. );
  138. STDMETHOD(GetCurrentPassCount)(
  139. THIS_
  140. OUT PULONG Count
  141. );
  142. STDMETHOD(GetMatchThreadId)(
  143. THIS_
  144. OUT PULONG Id
  145. );
  146. STDMETHOD(SetMatchThreadId)(
  147. THIS_
  148. IN ULONG Id
  149. );
  150. STDMETHOD(GetCommand)(
  151. THIS_
  152. OUT OPTIONAL PSTR Buffer,
  153. IN ULONG BufferSize,
  154. OUT OPTIONAL PULONG CommandSize
  155. );
  156. STDMETHOD(SetCommand)(
  157. THIS_
  158. IN PCSTR Command
  159. );
  160. STDMETHOD(GetOffsetExpression)(
  161. THIS_
  162. OUT OPTIONAL PSTR Buffer,
  163. IN ULONG BufferSize,
  164. OUT OPTIONAL PULONG ExpressionSize
  165. );
  166. STDMETHOD(SetOffsetExpression)(
  167. THIS_
  168. IN PCSTR Expression
  169. );
  170. STDMETHOD(GetParameters)(
  171. THIS_
  172. OUT PDEBUG_BREAKPOINT_PARAMETERS Params
  173. );
  174. // Breakpoint.
  175. virtual HRESULT Validate(void) = 0;
  176. virtual HRESULT Insert(void) = 0;
  177. virtual HRESULT Remove(void) = 0;
  178. virtual ULONG IsHit(PADDR Addr) = 0;
  179. // Must resturn true if in case of THIS breakpoint hit
  180. // Pc points to the instruction caused the hit
  181. virtual BOOL PcAtHit() = 0;
  182. PADDR GetAddr(void)
  183. {
  184. return &m_Addr;
  185. }
  186. BOOL PassHit(void)
  187. {
  188. if (--m_CurPassCount == 0)
  189. {
  190. m_CurPassCount = 1;
  191. return TRUE;
  192. }
  193. else
  194. {
  195. return FALSE;
  196. }
  197. }
  198. ULONG GetProcType(void)
  199. {
  200. return m_ProcType;
  201. }
  202. void SetProcType(ULONG ProcType)
  203. {
  204. m_ProcType = ProcType;
  205. m_ProcIndex = MachineTypeIndex(ProcType);
  206. }
  207. ULONG GetProcIndex(void)
  208. {
  209. return m_ProcIndex;
  210. }
  211. void ForceFlatAddr(void)
  212. {
  213. NotFlat(m_Addr);
  214. ComputeFlatAddress(&m_Addr, NULL);
  215. }
  216. // Breakpoint is enabled, not deferred, not internal.
  217. BOOL IsNormalEnabled(void)
  218. {
  219. return (m_Flags & (DEBUG_BREAKPOINT_ENABLED |
  220. BREAKPOINT_KD_INTERNAL |
  221. DEBUG_BREAKPOINT_DEFERRED)) ==
  222. DEBUG_BREAKPOINT_ENABLED;
  223. }
  224. void LinkIntoList(void);
  225. void UnlinkFromList(void);
  226. void UpdateInternal(void);
  227. BOOL EvalOffsetExpr(void);
  228. HRESULT SetAddr(PADDR Addr, BreakpointMatchAction MatchAction);
  229. // Matches breakpoints if they have the same insertion effect.
  230. // Used when determining whether a breakpoint needs to be
  231. // inserted or if another breakpoint is already covering the break.
  232. BOOL IsInsertionMatch(Breakpoint* Match);
  233. // Matches breakpoints if they have an insertion match and
  234. // if they match publicly, such as between flags, hiddenness
  235. // and so on. Used when determining whether a user breakpoint
  236. // redefines an existing breakpoint.
  237. BOOL IsPublicMatch(Breakpoint* Match);
  238. // Check m_Match* fields against current state.
  239. BOOL MatchesCurrentState(void);
  240. protected:
  241. // ProcType is private so that ProcType and ProcIndex can
  242. // be kept in sync.
  243. ULONG m_ProcType;
  244. MachineIndex m_ProcIndex;
  245. // Address is private to force users to go through SetAddr.
  246. ADDR m_Addr;
  247. ULONG m_CommandLen;
  248. ULONG m_OffsetExprLen;
  249. UCHAR m_InsertStorage[MAX_BREAKPOINT_LENGTH];
  250. };
  251. //----------------------------------------------------------------------------
  252. //
  253. // CodeBreakpoint.
  254. //
  255. //----------------------------------------------------------------------------
  256. class CodeBreakpoint :
  257. public Breakpoint
  258. {
  259. public:
  260. CodeBreakpoint(DebugClient* Adder, ULONG Id, ULONG ProcType)
  261. : Breakpoint(Adder, Id, DEBUG_BREAKPOINT_CODE, ProcType)
  262. {
  263. m_Flags |= BREAKPOINT_VIRT_ADDR;
  264. }
  265. // Breakpoint.
  266. virtual HRESULT Validate(void);
  267. virtual HRESULT Insert(void);
  268. virtual HRESULT Remove(void);
  269. virtual ULONG IsHit(PADDR Addr);
  270. virtual BOOL PcAtHit()
  271. {
  272. return TRUE;
  273. }
  274. };
  275. //----------------------------------------------------------------------------
  276. //
  277. // DataBreakpoint.
  278. //
  279. //----------------------------------------------------------------------------
  280. class DataBreakpoint :
  281. public Breakpoint
  282. {
  283. public:
  284. DataBreakpoint(DebugClient* Adder, ULONG Id, ULONG ProcType)
  285. : Breakpoint(Adder, Id, DEBUG_BREAKPOINT_DATA, ProcType) {}
  286. // Breakpoint.
  287. virtual HRESULT Insert(void);
  288. virtual HRESULT Remove(void);
  289. // DataBreakpoint.
  290. static void ClearThreadDataBreaks(PTHREAD_INFO Thread);
  291. void AddToThread(PTHREAD_INFO Thread);
  292. };
  293. //----------------------------------------------------------------------------
  294. //
  295. // X86DataBreakpoint.
  296. //
  297. //----------------------------------------------------------------------------
  298. class X86DataBreakpoint :
  299. public DataBreakpoint
  300. {
  301. public:
  302. X86DataBreakpoint(DebugClient* Adder, ULONG Id,
  303. ULONG Cr4Reg, ULONG Dr6Reg, ULONG ProcType)
  304. : DataBreakpoint(Adder, Id, ProcType)
  305. {
  306. m_Dr7Bits = 0;
  307. m_Cr4Reg = Cr4Reg;
  308. m_Dr6Reg = Dr6Reg;
  309. }
  310. // Breakpoint.
  311. virtual HRESULT Validate(void);
  312. virtual ULONG IsHit(PADDR Addr);
  313. virtual BOOL PcAtHit()
  314. {
  315. return FALSE;
  316. }
  317. private:
  318. // Precomputed enable bits.
  319. ULONG m_Dr7Bits;
  320. // Register indices for getting breakpoint-related information.
  321. ULONG m_Cr4Reg;
  322. ULONG m_Dr6Reg;
  323. friend class X86MachineInfo;
  324. friend class Amd64MachineInfo;
  325. };
  326. //----------------------------------------------------------------------------
  327. //
  328. // Ia64DataBreakpoint.
  329. //
  330. //----------------------------------------------------------------------------
  331. class Ia64DataBreakpoint :
  332. public DataBreakpoint
  333. {
  334. public:
  335. Ia64DataBreakpoint(DebugClient* Adder, ULONG Id)
  336. : DataBreakpoint(Adder, Id, IMAGE_FILE_MACHINE_IA64)
  337. {
  338. m_Control = 0;
  339. }
  340. // Breakpoint.
  341. virtual HRESULT Validate(void);
  342. virtual ULONG IsHit(PADDR Addr);
  343. virtual BOOL PcAtHit()
  344. {
  345. return TRUE;
  346. }
  347. static ULONG64 GetControl(ULONG AccessType, ULONG Size);
  348. private:
  349. ULONG64 m_Control;
  350. friend class Ia64MachineInfo;
  351. };
  352. //----------------------------------------------------------------------------
  353. //
  354. // X86OnIa64DataBreakpoint.
  355. //
  356. //----------------------------------------------------------------------------
  357. class X86OnIa64DataBreakpoint :
  358. public X86DataBreakpoint
  359. {
  360. public:
  361. X86OnIa64DataBreakpoint(DebugClient* Adder, ULONG Id);
  362. // Breakpoint.
  363. virtual HRESULT Validate(void);
  364. virtual ULONG IsHit(PADDR Addr);
  365. private:
  366. ULONG64 m_Control;
  367. friend class Ia64MachineInfo;
  368. };
  369. extern BOOL g_BreakpointListChanged;
  370. extern BOOL g_UpdateDataBreakpoints;
  371. extern BOOL g_DataBreakpointsChanged;
  372. extern BOOL g_BreakpointsSuspended;
  373. extern BOOL g_DeferDefined;
  374. extern Breakpoint* g_DeferBp;
  375. extern Breakpoint* g_StepTraceBp;
  376. extern CHAR g_StepTraceCmdState;
  377. extern ADDR g_PrevRelatedPc;
  378. HRESULT BreakpointInit(void);
  379. HRESULT InsertBreakpoints(void);
  380. BOOL RemoveBreakpoints(void);
  381. HRESULT AddBreakpoint(DebugClient* Client,
  382. ULONG Type,
  383. ULONG DesiredId,
  384. Breakpoint** Bp);
  385. void RemoveBreakpoint(Breakpoint* Bp);
  386. void RemoveProcessBreakpoints(PPROCESS_INFO Process);
  387. void RemoveThreadBreakpoints(PTHREAD_INFO Thread);
  388. void RemoveAllKernelBreakpoints(void);
  389. void RemoveAllBreakpoints(ULONG Reason);
  390. Breakpoint* GetBreakpointByIndex(DebugClient* Client, ULONG Index);
  391. Breakpoint* GetBreakpointById(DebugClient* Client, ULONG Id);
  392. Breakpoint* CheckMatchingBreakpoints(Breakpoint* Match, BOOL PUBLIC,
  393. ULONG IncFlags);
  394. Breakpoint* CheckBreakpointHit(PPROCESS_INFO Process,
  395. Breakpoint* Start, PADDR Addr,
  396. ULONG ExbsType, ULONG IncFlags, ULONG ExcFlags,
  397. PULONG HitType,
  398. BOOL SetLastBreakpointHit);
  399. ULONG NotifyHitBreakpoints(ULONG EventStatus);
  400. void EvaluateOffsetExpressions(PPROCESS_INFO Process, ULONG Flags);
  401. #define BPCMDS_FORCE_DISABLE 0x00000001
  402. #define BPCMDS_ONE_LINE 0x00000002
  403. #define BPCMDS_EXPR_ONLY 0x00000004
  404. #define BPCMDS_MODULE_HINT 0x00000008
  405. void ChangeBreakpointState(DebugClient* Client, PPROCESS_INFO ForProcess,
  406. ULONG Id, UCHAR StateChange);
  407. void ListBreakpoints(DebugClient* Client, PPROCESS_INFO ForProcess,
  408. ULONG Id);
  409. void ListBreakpointsAsCommands(DebugClient* Client, PPROCESS_INFO Process,
  410. ULONG Flags);
  411. PDEBUG_BREAKPOINT ParseBpCmd(DebugClient* Client, UCHAR Type,
  412. PTHREAD_INFO Thread);
  413. BOOL CheckBreakpointInsertedInRange(PPROCESS_INFO Process,
  414. ULONG64 Start, ULONG64 End);
  415. void DbgKdpAcquireHardwareBp(PDBGKD_CONTROL_REQUEST BpRequest);
  416. void DbgKdpReleaseHardwareBp(PDBGKD_CONTROL_REQUEST BpRequest);
  417. #endif // #ifndef _BRKPT_HPP_