Leaked source code of windows server 2003
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.

399 lines
12 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Expression evaluation.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #ifndef _EXPR_H_
  9. #define _EXPR_H_
  10. #include <alloc.hpp>
  11. #define DEFAULT_RANGE_LIMIT 0x100000
  12. // Evaluator indices are in dbgeng.h:DEBUG_EXPR_*.
  13. #define EVAL_COUNT 2
  14. class EvalExpression;
  15. extern ULONG g_EvalSyntax;
  16. extern EvalExpression* g_EvalReleaseChain;
  17. extern TypedData g_LastEvalResult;
  18. EvalExpression* GetEvaluator(ULONG Syntax, BOOL RetFail);
  19. #define GetCurEvaluator() GetEvaluator(g_EvalSyntax, FALSE)
  20. void ReleaseEvaluator(EvalExpression* Eval);
  21. void ReleaseEvaluators(void);
  22. HRESULT GetEvaluatorByName(PCSTR AbbrevName, BOOL RetFail,
  23. EvalExpression** EvalRet);
  24. CHAR PeekChar(void);
  25. BOOL GetRange(PADDR Addr, PULONG64 Value,
  26. ULONG Size, ULONG SegReg, ULONG SizeLimit);
  27. ULONG64 EvalStringNumAndCatch(PCSTR String);
  28. ULONG64 GetExpression(void);
  29. ULONG64 GetExpressionDesc(PCSTR Desc);
  30. ULONG64 GetTermExpression(PCSTR Desc);
  31. void GetAddrExpression(ULONG SegReg, PADDR Addr);
  32. // The recursive descent parsers can take a considerable amount
  33. // of stack for just a simple expression due to the many layers
  34. // of calls on the stack. As most of the layers have trivial
  35. // frames they respond well to optimization and fastcall to
  36. // avoid using stack. However, we don't currently build
  37. // optimized binaries so this is useless and just makes the
  38. // code harder to understand.
  39. #if 1
  40. #define EECALL
  41. #else
  42. #define EECALL FASTCALL
  43. #endif
  44. //----------------------------------------------------------------------------
  45. //
  46. // TypedDataStackAllocator.
  47. //
  48. // Specialized allocator for getting TypedData during evaluation.
  49. // This is much more space-efficient than using the stack as
  50. // many layers of the recursive decent will not need results of
  51. // their own.
  52. //
  53. // Allocator throws NOMEMORY when out of memory.
  54. //
  55. //----------------------------------------------------------------------------
  56. class TypedDataStackAllocator : public FixedSizeStackAllocator
  57. {
  58. public:
  59. TypedDataStackAllocator(EvalExpression* Eval)
  60. : FixedSizeStackAllocator(sizeof(TypedData), 64, TRUE)
  61. {
  62. m_Eval = Eval;
  63. }
  64. private:
  65. virtual void* RawAlloc(ULONG Bytes);
  66. EvalExpression* m_Eval;
  67. };
  68. //----------------------------------------------------------------------------
  69. //
  70. // EvalExpression.
  71. //
  72. //----------------------------------------------------------------------------
  73. enum EVAL_RESULT_KIND
  74. {
  75. ERES_UNKNOWN,
  76. ERES_SYMBOL,
  77. ERES_TYPE,
  78. ERES_EXPRESSION,
  79. };
  80. #define EXPRF_DEFAULT 0x000000000
  81. // In the MASM evaluator this indicates whether to evaluate
  82. // symbols as their values or their addresses. No effect
  83. // on the C++ evaluator.
  84. #define EXPRF_PREFER_SYMBOL_VALUES 0x000000001
  85. // Evaluate just a single term. Currently the term
  86. // is always bracketed by '[' and ']'.
  87. #define EXPRF_SINGLE_TERM 0x000000002
  88. #define EvalCheck(Expr) \
  89. if (m_Err = (Expr)) EvalError(m_Err); else 0
  90. class EvalExpression
  91. {
  92. public:
  93. EvalExpression(ULONG Syntax, PCSTR FullName, PCSTR AbbrevName);
  94. virtual ~EvalExpression(void);
  95. virtual PCSTR Evaluate(PCSTR Expr, PCSTR Desc, ULONG Flags,
  96. TypedData* Result) = 0;
  97. virtual PCSTR EvaluateAddr(PCSTR Expr, PCSTR Desc,
  98. ULONG SegReg, PADDR Addr) = 0;
  99. PCSTR EvalString(PCSTR String, TypedData* Result)
  100. {
  101. return Evaluate(String, NULL, EXPRF_DEFAULT, Result);
  102. }
  103. void EvalCurrent(TypedData* Result);
  104. void EvalCurAddrDesc(ULONG SegReg, PCSTR Desc, PADDR Addr);
  105. void EvalCurAddr(ULONG SegReg, PADDR Addr)
  106. {
  107. EvalCurAddrDesc(SegReg, NULL, Addr);
  108. }
  109. ULONG64 EvalStringNum(PCSTR String);
  110. ULONG64 EvalCurNumDesc(PCSTR Desc);
  111. ULONG64 EvalCurNum(void)
  112. {
  113. return EvalCurNumDesc(NULL);
  114. }
  115. ULONG64 EvalCurTermNumDesc(PCSTR Desc);
  116. void DECLSPEC_NORETURN EvalErrorDesc(ULONG Error, PCSTR Desc);
  117. void DECLSPEC_NORETURN EvalError(ULONG Error)
  118. {
  119. EvalErrorDesc(Error, NULL);
  120. }
  121. void Reset(void);
  122. void InheritStart(EvalExpression* Parent);
  123. void InheritEnd(EvalExpression* Parent);
  124. ULONG m_Syntax;
  125. PCSTR m_FullName;
  126. PCSTR m_AbbrevName;
  127. ULONG m_ParseOnly;
  128. ULONG m_AllowUnresolvedSymbols;
  129. ULONG m_NumUnresolvedSymbols;
  130. EvalExpression* m_ReleaseChain;
  131. BOOL m_ChainTop;
  132. protected:
  133. void StartLexer(PCSTR Expr);
  134. void Start(PCSTR Expr, PCSTR Desc, ULONG Flags);
  135. void End(TypedData* Result);
  136. void StartLexeme(void)
  137. {
  138. m_LexemeStart = m_LexemeRestart;
  139. m_LexemeChar = m_LexemeStart;
  140. *m_LexemeChar = 0;
  141. }
  142. void AddLexeme(char Ch);
  143. TypedData* NewResult(void)
  144. {
  145. return (TypedData*)m_ResultAlloc.Alloc();
  146. }
  147. void DelResult(TypedData* Result)
  148. {
  149. m_ResultAlloc.Free(Result);
  150. }
  151. PCSTR m_ExprDesc;
  152. ULONG m_Flags;
  153. ProcessInfo* m_Process;
  154. MachineInfo* m_Machine;
  155. PCSTR m_Lex;
  156. char m_LexemeBuffer[1024];
  157. PSTR m_LexemeRestart;
  158. PSTR m_LexemeStart;
  159. PSTR m_LexemeChar;
  160. PCSTR m_LexemeSourceStart;
  161. TypedData m_TokenValue;
  162. BOOL m_AllowUnaryOp;
  163. ULONG m_PtrSize;
  164. TypedDataStackAllocator m_ResultAlloc;
  165. // Temporary local storage to avoid using space
  166. // for short-lived data.
  167. TypedData m_Tmp;
  168. ULONG m_Err;
  169. };
  170. //----------------------------------------------------------------------------
  171. //
  172. // MasmEvalExpression.
  173. //
  174. //----------------------------------------------------------------------------
  175. class MasmEvalExpression : public EvalExpression
  176. {
  177. public:
  178. MasmEvalExpression(void);
  179. virtual ~MasmEvalExpression(void);
  180. virtual PCSTR Evaluate(PCSTR Expr, PCSTR Desc, ULONG Flags,
  181. TypedData* Result);
  182. virtual PCSTR EvaluateAddr(PCSTR Expr, PCSTR Desc,
  183. ULONG SegReg, PADDR Addr);
  184. private:
  185. void ForceAddrExpression(ULONG SegReg, PADDR Address, ULONG64 Value);
  186. LONG64 GetTypedExpression(void);
  187. BOOL GetSymValue(PSTR Symbol, PULONG64 Value);
  188. char Peek(void);
  189. ULONG64 GetCommonExpression(void);
  190. LONG64 StartExpr(void);
  191. LONG64 GetLRterm(void);
  192. LONG64 GetLterm(void);
  193. LONG64 GetShiftTerm(void);
  194. LONG64 GetAterm(void);
  195. LONG64 GetMterm(void);
  196. LONG64 GetTerm(void);
  197. ULONG GetRegToken(PCHAR Str, PULONG64 Value);
  198. ULONG PeekToken(PLONG64 Value);
  199. void AcceptToken(void);
  200. ULONG GetTokenSym(PLONG64 Value);
  201. ULONG EvalSymbol(PSTR Name, PULONG64 Value);
  202. ULONG NextToken(PLONG64 Value);
  203. ULONG m_SavedClass;
  204. LONG64 m_SavedValue;
  205. PCSTR m_SavedCommand;
  206. BOOL m_ForcePositiveNumber;
  207. USHORT m_AddrExprType;
  208. ADDR m_TempAddr;
  209. // Syms in a expression evaluate to values rather than address
  210. BOOL m_TypedExpr;
  211. };
  212. //----------------------------------------------------------------------------
  213. //
  214. // CppEvalExpression.
  215. //
  216. //----------------------------------------------------------------------------
  217. #define CPP_TOKEN_MULTI 256
  218. #define CPP_KEYWORD_FIRST CppTokenSizeof
  219. #define CPP_KEYWORD_LAST CppTokenTypeid
  220. enum CppToken
  221. {
  222. CppTokenError = 0,
  223. // Single-character tokens use the character value.
  224. CppTokenPeriod = '.', CppTokenQuestionMark = '?',
  225. CppTokenColon = ':', CppTokenComma = ',',
  226. CppTokenOpenParen = '(', CppTokenCloseParen = ')',
  227. CppTokenOpenBracket = '[', CppTokenCloseBracket = ']',
  228. CppTokenOpenAngle = '<', CppTokenCloseAngle = '>',
  229. CppTokenEof = CPP_TOKEN_MULTI,
  230. // Literals.
  231. CppTokenIdentifier, CppTokenInteger, CppTokenFloat,
  232. CppTokenCharString, CppTokenChar, CppTokenWcharString, CppTokenWchar,
  233. CppTokenDebugRegister, CppTokenModule, CppTokenSwitchEvalExpression,
  234. CppTokenPreprocFunction,
  235. // Relational operators.
  236. CppTokenEqual, CppTokenNotEqual, CppTokenLessEqual,
  237. CppTokenGreaterEqual,
  238. // Logical operators.
  239. CppTokenLogicalAnd, CppTokenLogicalOr,
  240. // Unary operators.
  241. CppTokenUnaryPlus, CppTokenUnaryMinus,
  242. // Shifts.
  243. CppTokenLeftShift, CppTokenRightShift,
  244. // Addresses.
  245. CppTokenAddressOf, CppTokenDereference, CppTokenPointerMember,
  246. CppTokenClassDereference, CppTokenClassPointerMember,
  247. // Assignment operators.
  248. CppTokenDivideAssign, CppTokenMultiplyAssign, CppTokenModuloAssign,
  249. CppTokenAddAssign, CppTokenSubtractAssign,
  250. CppTokenLeftShiftAssign, CppTokenRightShiftAssign,
  251. CppTokenAndAssign, CppTokenOrAssign, CppTokenExclusiveOrAssign,
  252. // Increments and decrements.
  253. CppTokenPreIncrement, CppTokenPreDecrement,
  254. CppTokenPostIncrement, CppTokenPostDecrement,
  255. // Namespaces.
  256. CppTokenNameQualifier, CppTokenDestructor,
  257. // Keywords.
  258. CppTokenSizeof, CppTokenThis, CppTokenOperator,
  259. CppTokenNew, CppTokenDelete,
  260. // Keep type keywords together for easy identification.
  261. CppTokenConst, CppTokenStruct, CppTokenClass, CppTokenUnion,
  262. CppTokenEnum, CppTokenVolatile, CppTokenSigned, CppTokenUnsigned,
  263. CppTokenDynamicCast, CppTokenStaticCast, CppTokenConstCast,
  264. CppTokenReinterpretCast, CppTokenTypeid,
  265. CppTokenCount
  266. };
  267. class CppEvalExpression : public EvalExpression
  268. {
  269. public:
  270. CppEvalExpression(void);
  271. virtual ~CppEvalExpression(void);
  272. PCSTR TokenImage(CppToken Token);
  273. CppToken Lex(void);
  274. virtual PCSTR Evaluate(PCSTR Expr, PCSTR Desc, ULONG Flags,
  275. TypedData* Result);
  276. virtual PCSTR EvaluateAddr(PCSTR Expr, PCSTR Desc,
  277. ULONG SegReg, PADDR Addr);
  278. private:
  279. char GetStringChar(PBOOL Escaped);
  280. void FinishFloat(LONG64 IntPart, int Sign);
  281. CppToken ReadNumber(int Sign);
  282. void NextToken(void);
  283. void Match(CppToken Token);
  284. void Accept(void)
  285. {
  286. Match(m_Token);
  287. }
  288. void EECALL Expression(TypedData* Result);
  289. void EECALL Assignment(TypedData* Result);
  290. void EECALL Conditional(TypedData* Result);
  291. void EECALL LogicalOr(TypedData* Result);
  292. void EECALL LogicalAnd(TypedData* Result);
  293. void EECALL BitwiseOr(TypedData* Result);
  294. void EECALL BitwiseXor(TypedData* Result);
  295. void EECALL BitwiseAnd(TypedData* Result);
  296. void EECALL Equality(TypedData* Result);
  297. void EECALL Relational(TypedData* Result);
  298. void EECALL Shift(TypedData* Result);
  299. void EECALL Additive(TypedData* Result);
  300. void EECALL Multiplicative(TypedData* Result);
  301. void EECALL ClassMemberRef(TypedData* Result);
  302. void EECALL Cast(TypedData* Result);
  303. void EECALL Unary(TypedData* Result);
  304. void EECALL Postfix(TypedData* Result);
  305. void EECALL Term(TypedData* Result);
  306. EVAL_RESULT_KIND EECALL TryTypeName(TypedData* Result);
  307. EVAL_RESULT_KIND EECALL CollectTypeOrSymbolName(TypedData* Result);
  308. EVAL_RESULT_KIND EECALL CollectTemplateName(void);
  309. void EECALL CollectOperatorName(void);
  310. void EECALL UdtMember(TypedData* Result);
  311. void EECALL PreprocFunction(TypedData* Result);
  312. BOOL IsTypeKeyword(CppToken Token)
  313. {
  314. return Token >= CppTokenConst && Token <= CppTokenUnsigned;
  315. }
  316. BOOL IsAssignOp(CppToken Token)
  317. {
  318. return Token == '=' ||
  319. (Token >= CppTokenDivideAssign &&
  320. Token <= CppTokenExclusiveOrAssign);
  321. }
  322. TypedDataAccess CurrentAccess(void)
  323. {
  324. if (m_ParseOnly > 0)
  325. {
  326. return TDACC_NONE;
  327. }
  328. else if (m_PreprocEval)
  329. {
  330. return TDACC_ATTEMPT;
  331. }
  332. else
  333. {
  334. return TDACC_REQUIRE;
  335. }
  336. }
  337. static char s_EscapeChars[];
  338. static char s_EscapeCharValues[];
  339. static PCSTR s_MultiTokens[];
  340. CppToken m_Token;
  341. ULONG m_SwitchEvalSyntax;
  342. BOOL m_PreprocEval;
  343. };
  344. #endif // #ifndef _EXPR_H_