ReactOS 0.4.15-dev-7788-g1ad9096
kdb_expr.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/kdbg/kdb_expr.c
22 * PURPOSE: Kernel debugger expression evaluation
23 * PROGRAMMER: Gregor Anich (blight@blight.eu.org)
24 * UPDATE HISTORY:
25 * Created 15/01/2005
26 */
27
28/* Note:
29 *
30 * The given expression is parsed and stored in reverse polish notation,
31 * then it is evaluated and the result is returned.
32 */
33
34/* INCLUDES ******************************************************************/
35
36#include <ntoskrnl.h>
37#include "kdb.h"
38
39#define NDEBUG
40#include "debug.h"
41
42/* TYPES *********************************************************************/
43typedef enum _RPN_OP_TYPE
44{
52
54
55typedef struct _RPN_OP
56{
59 union
60 {
61 /* RpnOpBinaryOperator */
63 /* RpnOpImmediate */
65 /* RpnOpRegister */
67 /* RpnOpDereference */
69 }
71}
73
74typedef struct _RPN_STACK
75{
76 ULONG Size; /* Number of RPN_OPs on Ops */
77 ULONG Sp; /* Stack pointer */
78 RPN_OP Ops[1]; /* Array of RPN_OPs */
79}
81
82/* DEFINES *******************************************************************/
83#define stricmp _stricmp
84
85#ifndef RTL_FIELD_SIZE
86# define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
87#endif
88
89#define CONST_STRCPY(dst, src) \
90 do { if ((dst)) { memcpy(dst, src, sizeof(src)); } } while (0);
91
92#define RPN_OP_STACK_SIZE 256
93#define RPN_VALUE_STACK_SIZE 256
94
95/* GLOBALS *******************************************************************/
96static struct
97{
101}
102RpnStack =
103{
105 0
107
108static const struct
109{
112 UCHAR Size;
113}
115{
116 /* FIXME: X86 only */
117#ifdef _M_IX86
119#else
121#endif
122 {"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, EFlags)},
123#ifdef _M_IX86
132#else
141#endif
142 {"cs", FIELD_OFFSET(KDB_KTRAP_FRAME, SegCs), 2 }, /* Use only the lower 2 bytes */
156
157/* FUNCTIONS *****************************************************************/
158
161 ULONGLONG a,
162 ULONGLONG b)
163{
164 return a + b;
165}
166
169 ULONGLONG a,
170 ULONGLONG b)
171{
172 return a - b;
173}
174
177 ULONGLONG a,
178 ULONGLONG b)
179{
180 return a * b;
181}
182
185 ULONGLONG a,
186 ULONGLONG b)
187{
188 return a / b;
189}
190
193 ULONGLONG a,
194 ULONGLONG b)
195{
196 return a % b;
197}
198
201 ULONGLONG a,
202 ULONGLONG b)
203{
204 return (a == b);
205}
206
209 ULONGLONG a,
210 ULONGLONG b)
211{
212 return (a != b);
213}
214
217 ULONGLONG a,
218 ULONGLONG b)
219{
220 return (a < b);
221}
222
225 ULONGLONG a,
226 ULONGLONG b)
227{
228 return (a <= b);
229}
230
233 ULONGLONG a,
234 ULONGLONG b)
235{
236 return (a > b);
237}
238
241 ULONGLONG a,
242 ULONGLONG b)
243{
244 return (a >= b);
245}
246
247#ifdef DEBUG_RPN
252VOID
253RpnpDumpStack(
255{
256 ULONG ul;
257
258 ASSERT(Stack);
259 KdbPrintf("\nStack size: %ld\n", Stack->Sp);
260
261 for (ul = 0; ul < Stack->Sp; ul++)
262 {
263 PRPN_OP Op = Stack->Ops + ul;
264 switch (Op->Type)
265 {
266 case RpnOpNop:
267 KdbPuts("NOP,");
268 break;
269
270 case RpnOpImmediate:
271 KdbPrintf("0x%I64x,", Op->Data.Immediate);
272 break;
273
276 KdbPuts("+,");
278 KdbPuts("-,");
280 KdbPuts("*,");
282 KdbPuts("/,");
284 KdbPuts("%%,");
286 KdbPuts("==,");
288 KdbPuts("!=,");
290 KdbPuts("<,");
292 KdbPuts("<=,");
294 KdbPuts(">,");
296 KdbPuts(">=,");
297 else
298 KdbPuts("UNKNOWN OP,");
299
300 break;
301
302 case RpnOpRegister:
303 KdbPrintf("%s,", RegisterToTrapFrame[Op->Data.Register].Name);
304 break;
305
306 case RpnOpDereference:
307 KdbPrintf("[%s],",
308 (Op->Data.DerefMemorySize == 1) ? ("byte") :
309 ((Op->Data.DerefMemorySize == 2) ? ("word") :
310 ((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword"))));
311 break;
312
313 default:
314 KdbPrintf("\nUnsupported Type: %d\n", Op->Type);
315 ul = Stack->Sp;
316 break;
317 }
318 }
319
320 KdbPuts("\n");
321}
322#endif // DEBUG_RPN
323
328static VOID
331{
332 ASSERT(Stack);
333 Stack->Sp = 0;
334}
335
341static BOOLEAN
344 IN PRPN_OP Op)
345{
346 ASSERT(Stack);
347 ASSERT(Op);
348
349 if (Stack->Sp >= Stack->Size)
350 return FALSE;
351
352 memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP));
353 Stack->Sp++;
354
355 return TRUE;
356}
357
366static BOOLEAN
370{
371 ASSERT(Stack);
372
373 if (Stack->Sp == 0)
374 return FALSE;
375
376 Stack->Sp--;
377 if (Op)
378 memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP));
379
380 return TRUE;
381}
382
391static BOOLEAN
394 OUT PRPN_OP Op)
395{
396 ASSERT(Stack);
397 ASSERT(Op);
398
399 if (Stack->Sp == 0)
400 return FALSE;
401
402 memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP));
403
404 return TRUE;
405}
406
425static BOOLEAN
429 OUT PCHAR *End OPTIONAL,
430 IN ULONG CharacterOffset,
431 OUT PLONG ErrOffset OPTIONAL,
432 OUT PCHAR ErrMsg OPTIONAL)
433{
435 PCHAR pend;
437 LONG OperatorOffset = -1;
438 RPN_OP RpnOp;
439 RPN_OP PoppedOperator;
440 BOOLEAN HavePoppedOperator = FALSE;
441 RPN_OP ComparativeOp;
442 BOOLEAN ComparativeOpFilled = FALSE;
443 BOOLEAN IsComparativeOp;
444 INT_PTR i, i2;
445 ULONG64 ull;
447 CHAR Buffer[16];
449
450 ASSERT(Stack);
452
453 First = TRUE;
454 for (;;)
455 {
456 /* Skip whitespace */
457 while (isspace(*p))
458 {
459 p++;
460 CharacterOffset++;
461 }
462
463 /* Check for end of expression */
464 if (p[0] == '\0' || p[0] == ')' || p[0] == ']')
465 break;
466
467 if (!First)
468 {
469 /* Remember operator */
470 Operator = p++;
471 OperatorOffset = CharacterOffset++;
472
473 /* Pop operator (to get the right operator precedence) */
474 HavePoppedOperator = FALSE;
475 if (*Operator == '*' || *Operator == '/' || *Operator == '%')
476 {
477 if (RpnpTopStack(Stack, &PoppedOperator) &&
478 PoppedOperator.Type == RpnOpBinaryOperator &&
479 (PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorAdd ||
480 PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorSub))
481 {
483 HavePoppedOperator = TRUE;
484 }
485 else if (PoppedOperator.Type == RpnOpNop)
486 {
488 /* Discard the NOP - it was only pushed to indicate there was a
489 * closing brace, so the previous operator shouldn't be popped.
490 */
491 }
492 }
493 else if ((Operator[0] == '=' && Operator[1] == '=') ||
494 (Operator[0] == '!' && Operator[1] == '=') ||
495 Operator[0] == '<' || Operator[0] == '>')
496 {
497 if (Operator[0] == '=' || Operator[0] == '!' ||
498 (Operator[0] == '<' && Operator[1] == '=') ||
499 (Operator[0] == '>' && Operator[1] == '='))
500 {
501 p++;
502 CharacterOffset++;
503 }
504#if 0
505 /* Parse rest of expression */
506 if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,
507 ErrOffset, ErrMsg))
508 {
509 return FALSE;
510 }
511 else if (pend == p + 1)
512 {
513 CONST_STRCPY(ErrMsg, "Expression expected");
514
515 if (ErrOffset)
516 *ErrOffset = CharacterOffset + 1;
517
518 return FALSE;
519 }
520
521 goto end_of_expression; /* return */
522#endif
523 }
524 else if (Operator[0] != '+' && Operator[0] != '-')
525 {
526 CONST_STRCPY(ErrMsg, "Operator expected");
527
528 if (ErrOffset)
529 *ErrOffset = OperatorOffset;
530
531 return FALSE;
532 }
533
534 /* Skip whitespace */
535 while (isspace(*p))
536 {
537 p++;
538 CharacterOffset++;
539 }
540 }
541
542 /* Get operand */
543 MemorySize = sizeof(ULONG_PTR); /* default to pointer size */
544
545get_operand:
546 i = strcspn(p, "+-*/%()[]<>!=");
547 if (i > 0)
548 {
549 i2 = i;
550
551 /* Copy register name/memory size */
552 while (isspace(p[--i2]));
553
554 i2 = min(i2 + 1, (INT)sizeof (Buffer) - 1);
555 strncpy(Buffer, p, i2);
556 Buffer[i2] = '\0';
557
558 /* Memory size prefix */
559 if (p[i] == '[')
560 {
561 if (stricmp(Buffer, "byte") == 0)
562 MemorySize = 1;
563 else if (stricmp(Buffer, "word") == 0)
564 MemorySize = 2;
565 else if (stricmp(Buffer, "dword") == 0)
566 MemorySize = 4;
567 else if (stricmp(Buffer, "qword") == 0)
568 MemorySize = 8;
569 else
570 {
571 CONST_STRCPY(ErrMsg, "Invalid memory size prefix");
572
573 if (ErrOffset)
574 *ErrOffset = CharacterOffset;
575
576 return FALSE;
577 }
578
579 p += i;
580 CharacterOffset += i;
581 goto get_operand;
582 }
583
584 /* Try to find register */
585 for (i = 0; i < RegisterToTrapFrameCount; i++)
586 {
588 break;
589 }
590
592 {
593 RpnOp.Type = RpnOpRegister;
594 RpnOp.CharacterOffset = CharacterOffset;
595 RpnOp.Data.Register = i;
597 CharacterOffset += i;
598 p += i;
599 }
600 else
601 {
602 /* Immediate value */
603 ull = strtoull(p, &pend, 0);
604 if (p != pend)
605 {
606 RpnOp.Type = RpnOpImmediate;
607 RpnOp.CharacterOffset = CharacterOffset;
608 RpnOp.Data.Immediate = ull;
609 CharacterOffset += pend - p;
610 p = pend;
611 }
612 else
613 {
614 CONST_STRCPY(ErrMsg, "Operand expected");
615
616 if (ErrOffset)
617 *ErrOffset = CharacterOffset;
618
619 return FALSE;
620 }
621 }
622
623 /* Push operand */
624 if (!RpnpPushStack(Stack, &RpnOp))
625 {
626 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
627
628 if (ErrOffset)
629 *ErrOffset = -1;
630
631 return FALSE;
632 }
633 }
634 else if (i == 0)
635 {
636 if (p[0] == '(' || p[0] == '[') /* subexpression */
637 {
638 if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,
639 ErrOffset, ErrMsg))
640 {
641 return FALSE;
642 }
643 else if (pend == p + 1)
644 {
645 CONST_STRCPY(ErrMsg, "Expression expected");
646
647 if (ErrOffset)
648 *ErrOffset = CharacterOffset + 1;
649
650 return FALSE;
651 }
652
653 if (p[0] == '[') /* dereference */
654 {
655 ASSERT(MemorySize == 1 || MemorySize == 2 ||
656 MemorySize == 4 || MemorySize == 8);
657
658 if (pend[0] != ']')
659 {
660 CONST_STRCPY(ErrMsg, "']' expected");
661
662 if (ErrOffset)
663 *ErrOffset = CharacterOffset + (pend - p);
664
665 return FALSE;
666 }
667
668 RpnOp.Type = RpnOpDereference;
669 RpnOp.CharacterOffset = CharacterOffset;
671
672 if (!RpnpPushStack(Stack, &RpnOp))
673 {
674 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
675
676 if (ErrOffset)
677 *ErrOffset = -1;
678
679 return FALSE;
680 }
681 }
682 else /* p[0] == '(' */
683 {
684 if (pend[0] != ')')
685 {
686 CONST_STRCPY(ErrMsg, "')' expected");
687
688 if (ErrOffset)
689 *ErrOffset = CharacterOffset + (pend - p);
690
691 return FALSE;
692 }
693 }
694
695 /* Push a "nop" to prevent popping of the + operator (which would
696 * result in (10+10)/2 beeing evaluated as 15)
697 */
698 RpnOp.Type = RpnOpNop;
699 if (!RpnpPushStack(Stack, &RpnOp))
700 {
701 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
702
703 if (ErrOffset)
704 *ErrOffset = -1;
705
706 return FALSE;
707 }
708
709 /* Skip closing brace/bracket */
710 pend++;
711
712 CharacterOffset += pend - p;
713 p = pend;
714 }
715 else if (First && p[0] == '-') /* Allow expressions like "- eax" */
716 {
717 RpnOp.Type = RpnOpImmediate;
718 RpnOp.CharacterOffset = CharacterOffset;
719 RpnOp.Data.Immediate = 0;
720
721 if (!RpnpPushStack(Stack, &RpnOp))
722 {
723 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
724
725 if (ErrOffset)
726 *ErrOffset = -1;
727
728 return FALSE;
729 }
730 }
731 else
732 {
733 CONST_STRCPY(ErrMsg, "Operand expected");
734
735 if (ErrOffset)
736 *ErrOffset = CharacterOffset;
737
738 return FALSE;
739 }
740 }
741 else
742 {
743 CONST_STRCPY(ErrMsg, "strcspn() failed");
744
745 if (ErrOffset)
746 *ErrOffset = -1;
747
748 return FALSE;
749 }
750
751 if (!First)
752 {
753 /* Push operator */
754 RpnOp.CharacterOffset = OperatorOffset;
756 IsComparativeOp = FALSE;
757
758 switch (*Operator)
759 {
760 case '+':
762 break;
763
764 case '-':
766 break;
767
768 case '*':
770 break;
771
772 case '/':
774 break;
775
776 case '%':
778 break;
779
780 case '=':
781 ASSERT(Operator[1] == '=');
782 IsComparativeOp = TRUE;
784 break;
785
786 case '!':
787 ASSERT(Operator[1] == '=');
788 IsComparativeOp = TRUE;
790 break;
791
792 case '<':
793 IsComparativeOp = TRUE;
794
795 if (Operator[1] == '=')
797 else
799
800 break;
801
802 case '>':
803 IsComparativeOp = TRUE;
804
805 if (Operator[1] == '=')
807 else
809
810 break;
811
812 default:
813 ASSERT(0);
814 break;
815 }
816
817 if (IsComparativeOp)
818 {
819 if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
820 {
821 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
822
823 if (ErrOffset)
824 *ErrOffset = -1;
825
826 return FALSE;
827 }
828
829 memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP));
830 ComparativeOpFilled = TRUE;
831 }
832 else if (!RpnpPushStack(Stack, &RpnOp))
833 {
834 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
835
836 if (ErrOffset)
837 *ErrOffset = -1;
838
839 return FALSE;
840 }
841
842 /* Push popped operator */
843 if (HavePoppedOperator)
844 {
845 if (!RpnpPushStack(Stack, &PoppedOperator))
846 {
847 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
848
849 if (ErrOffset)
850 *ErrOffset = -1;
851
852 return FALSE;
853 }
854 }
855 }
856
857 First = FALSE;
858 }
859
860//end_of_expression:
861
862 if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
863 {
864 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
865
866 if (ErrOffset)
867 *ErrOffset = -1;
868
869 return FALSE;
870 }
871
872 /* Skip whitespace */
873 while (isspace(*p))
874 {
875 p++;
876 CharacterOffset++;
877 }
878
879 if (End)
880 *End = p;
881
882 return TRUE;
883}
884
896static BOOLEAN
899 IN PKDB_KTRAP_FRAME TrapFrame,
901 OUT PLONG ErrOffset OPTIONAL,
902 OUT PCHAR ErrMsg OPTIONAL)
903{
905 ULONG ValueStackPointer = 0;
906 ULONG index;
907 ULONGLONG ull;
908 ULONG ul;
909 USHORT us;
910 UCHAR uc;
911 PVOID p;
912 BOOLEAN Ok;
913#ifdef DEBUG_RPN
914 ULONG ValueStackPointerMax = 0;
915#endif
916
917 ASSERT(Stack);
918 ASSERT(TrapFrame);
919 ASSERT(Result);
920
921 for (index = 0; index < Stack->Sp; index++)
922 {
923 PRPN_OP Op = Stack->Ops + index;
924
925#ifdef DEBUG_RPN
926 ValueStackPointerMax = max(ValueStackPointerMax, ValueStackPointer);
927#endif
928
929 switch (Op->Type)
930 {
931 case RpnOpNop:
932 /* No operation */
933 break;
934
935 case RpnOpImmediate:
936 if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
937 {
938 CONST_STRCPY(ErrMsg, "Value stack overflow");
939
940 if (ErrOffset)
941 *ErrOffset = -1;
942
943 return FALSE;
944 }
945
946 ValueStack[ValueStackPointer++] = Op->Data.Immediate;
947 break;
948
949 case RpnOpRegister:
950 if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
951 {
952 CONST_STRCPY(ErrMsg, "Value stack overflow");
953
954 if (ErrOffset)
955 *ErrOffset = -1;
956
957 return FALSE;
958 }
959
960 ul = Op->Data.Register;
961 p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset);
962
963 switch (RegisterToTrapFrame[ul].Size)
964 {
965 case 1: ull = (ULONGLONG)(*(PUCHAR)p); break;
966 case 2: ull = (ULONGLONG)(*(PUSHORT)p); break;
967 case 4: ull = (ULONGLONG)(*(PULONG)p); break;
968 case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break;
969 default: ASSERT(0); return FALSE; break;
970 }
971
972 ValueStack[ValueStackPointer++] = ull;
973 break;
974
975 case RpnOpDereference:
976 if (ValueStackPointer < 1)
977 {
978 CONST_STRCPY(ErrMsg, "Value stack underflow");
979
980 if (ErrOffset)
981 *ErrOffset = -1;
982
983 return FALSE;
984 }
985
986 /* FIXME: Print a warning when address is out of range */
987 p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1];
988 Ok = FALSE;
989
990 switch (Op->Data.DerefMemorySize)
991 {
992 case 1:
993 if (NT_SUCCESS(KdbpSafeReadMemory(&uc, p, sizeof (uc))))
994 {
995 Ok = TRUE;
996 ull = (ULONGLONG)uc;
997 }
998 break;
999
1000 case 2:
1001 if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us))))
1002 {
1003 Ok = TRUE;
1004 ull = (ULONGLONG)us;
1005 }
1006 break;
1007
1008 case 4:
1009 if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul))))
1010 {
1011 Ok = TRUE;
1012 ull = (ULONGLONG)ul;
1013 }
1014 break;
1015
1016 case 8:
1017 if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull))))
1018 {
1019 Ok = TRUE;
1020 }
1021 break;
1022
1023 default:
1024 ASSERT(0);
1025 return FALSE;
1026 break;
1027 }
1028
1029 if (!Ok)
1030 {
1031 _snprintf(ErrMsg, 128, "Couldn't access memory at 0x%p", p);
1032
1033 if (ErrOffset)
1034 *ErrOffset = Op->CharacterOffset;
1035
1036 return FALSE;
1037 }
1038
1039 ValueStack[ValueStackPointer - 1] = ull;
1040 break;
1041
1043 if (ValueStackPointer < 2)
1044 {
1045 CONST_STRCPY(ErrMsg, "Value stack underflow");
1046
1047 if (ErrOffset)
1048 *ErrOffset = -1;
1049
1050 return FALSE;
1051 }
1052
1053 ValueStackPointer--;
1054 ull = ValueStack[ValueStackPointer];
1055
1056 if (ull == 0 && Op->Data.BinaryOperator == RpnBinaryOperatorDiv)
1057 {
1058 CONST_STRCPY(ErrMsg, "Division by zero");
1059
1060 if (ErrOffset)
1061 *ErrOffset = Op->CharacterOffset;
1062
1063 return FALSE;
1064 }
1065
1066 ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull);
1067 ValueStack[ValueStackPointer - 1] = ull;
1068 break;
1069
1070 default:
1071 ASSERT(0);
1072 return FALSE;
1073 }
1074 }
1075
1076#ifdef DEBUG_RPN
1077 DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax);
1078#endif
1079
1080 if (ValueStackPointer != 1)
1081 {
1082 CONST_STRCPY(ErrMsg, "Stack not empty after evaluation");
1083
1084 if (ErrOffset)
1085 *ErrOffset = -1;
1086
1087 return FALSE;
1088 }
1089
1090 *Result = ValueStack[0];
1091 return TRUE;
1092}
1093
1105BOOLEAN
1108 IN PKDB_KTRAP_FRAME TrapFrame,
1110 OUT PLONG ErrOffset OPTIONAL,
1111 OUT PCHAR ErrMsg OPTIONAL)
1112{
1114
1116 ASSERT(TrapFrame);
1117 ASSERT(Result);
1118
1119 /* Clear the stack and parse the expression */
1121 if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
1122 return FALSE;
1123
1124#ifdef DEBUG_RPN
1125 RpnpDumpStack(Stack);
1126#endif
1127
1128 /* Evaluate the stack */
1129 if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg))
1130 return FALSE;
1131
1132 return TRUE;
1133}
1134
1145PVOID
1148 OUT PLONG ErrOffset OPTIONAL,
1149 OUT PCHAR ErrMsg OPTIONAL)
1150{
1151 LONG Size;
1153 PRPN_STACK NewStack;
1154
1156
1157 /* Clear the stack and parse the expression */
1159 if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
1160 return FALSE;
1161
1162#ifdef DEBUG_RPN
1163 RpnpDumpStack(Stack);
1164#endif
1165
1166 /* Duplicate the stack and return a pointer/handle to it */
1167 ASSERT(Stack->Sp >= 1);
1168 Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1));
1170
1171 if (!NewStack)
1172 {
1173 CONST_STRCPY(ErrMsg, "Out of memory");
1174
1175 if (ErrOffset)
1176 *ErrOffset = -1;
1177
1178 return NULL;
1179 }
1180
1181 memcpy(NewStack, Stack, Size);
1182 NewStack->Size = NewStack->Sp;
1183
1184 return NewStack;
1185}
1186
1199BOOLEAN
1202 IN PKDB_KTRAP_FRAME TrapFrame,
1204 OUT PLONG ErrOffset OPTIONAL,
1205 OUT PCHAR ErrMsg OPTIONAL)
1206{
1208
1210 ASSERT(TrapFrame);
1211 ASSERT(Result);
1212
1213 /* Evaluate the stack */
1214 return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg);
1215}
1216
WCHAR First[]
Definition: FormatMessage.c:11
PCWSTR Expression
unsigned char BOOLEAN
#define isspace(c)
Definition: acclib.h:69
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
@ Operator
Definition: asmpp.cpp:44
#define index(s, c)
Definition: various.h:29
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
@ Ok
Definition: gdiplustypes.h:26
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1643
VOID KdbPuts(_In_ PCSTR String)
Definition: kdb_print.c:152
VOID __cdecl KdbPrintf(_In_ PCSTR Format,...)
Definition: kdb_print.c:160
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
static BOOLEAN RpnpParseExpression(IN PRPN_STACK Stack, IN PCHAR Expression, OUT PCHAR *End OPTIONAL, IN ULONG CharacterOffset, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Parses an expression.
Definition: kdb_expr.c:426
static BOOLEAN RpnpPushStack(IN OUT PRPN_STACK Stack, IN PRPN_OP Op)
Pushes an RPN_OP onto the stack.
Definition: kdb_expr.c:342
ULONGLONG RpnBinaryOperatorSub(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:168
ULONGLONG RpnBinaryOperatorGreaterThanOrEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:240
UCHAR Offset
Definition: kdb_expr.c:111
static const struct @1813 RegisterToTrapFrame[]
ULONGLONG RpnBinaryOperatorDiv(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:184
static const INT RegisterToTrapFrameCount
Definition: kdb_expr.c:155
enum _RPN_OP_TYPE RPN_OP_TYPE
PVOID KdbpRpnParseExpression(IN PCHAR Expression, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Parses the given expression and returns a "handle" to it.
Definition: kdb_expr.c:1146
ULONG Sp
Definition: kdb_expr.c:99
PCHAR Name
Definition: kdb_expr.c:110
ULONGLONG RpnBinaryOperatorGreaterThan(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:232
#define stricmp
Definition: kdb_expr.c:83
RPN_OP Ops[RPN_OP_STACK_SIZE]
Definition: kdb_expr.c:100
BOOLEAN KdbpRpnEvaluateExpression(IN PCHAR Expression, IN PKDB_KTRAP_FRAME TrapFrame, OUT PULONGLONG Result, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Evaluates the given expression.
Definition: kdb_expr.c:1106
BOOLEAN KdbpRpnEvaluateParsedExpression(IN PVOID Expression, IN PKDB_KTRAP_FRAME TrapFrame, OUT PULONGLONG Result, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Evaluates the given expression and returns the result.
Definition: kdb_expr.c:1200
ULONGLONG RpnBinaryOperatorMod(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:192
static VOID RpnpClearStack(OUT PRPN_STACK Stack)
Clears the given RPN stack.
Definition: kdb_expr.c:329
ULONGLONG RpnBinaryOperatorLessThanOrEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:224
static BOOLEAN RpnpPopStack(IN OUT PRPN_STACK Stack, OUT PRPN_OP Op OPTIONAL)
Pops the top op from the stack.
Definition: kdb_expr.c:367
#define RPN_VALUE_STACK_SIZE
Definition: kdb_expr.c:93
struct _RPN_STACK RPN_STACK
_RPN_OP_TYPE
Definition: kdb_expr.c:44
@ RpnOpNop
Definition: kdb_expr.c:45
@ RpnOpBinaryOperator
Definition: kdb_expr.c:46
@ RpnOpRegister
Definition: kdb_expr.c:49
@ RpnOpDereference
Definition: kdb_expr.c:50
@ RpnOpUnaryOperator
Definition: kdb_expr.c:47
@ RpnOpImmediate
Definition: kdb_expr.c:48
ULONGLONG RpnBinaryOperatorNotEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:208
struct _RPN_STACK * PRPN_STACK
struct _RPN_OP * PRPN_OP
static struct @1812 RpnStack
ULONG Size
Definition: kdb_expr.c:98
ULONGLONG(* RPN_BINARY_OPERATOR)(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:53
struct _RPN_OP RPN_OP
#define CONST_STRCPY(dst, src)
Definition: kdb_expr.c:89
static BOOLEAN RpnpTopStack(IN PRPN_STACK Stack, OUT PRPN_OP Op)
Gets the top op from the stack (not popping it)
Definition: kdb_expr.c:392
ULONGLONG RpnBinaryOperatorAdd(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:160
ULONGLONG RpnBinaryOperatorMul(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:176
static BOOLEAN RpnpEvaluateStack(IN PRPN_STACK Stack, IN PKDB_KTRAP_FRAME TrapFrame, OUT PULONGLONG Result, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Evaluates the RPN op stack and returns the result.
Definition: kdb_expr.c:897
#define RPN_OP_STACK_SIZE
Definition: kdb_expr.c:92
ULONGLONG RpnBinaryOperatorLessThan(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:216
ULONGLONG RpnBinaryOperatorEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:200
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
static const BYTE us[]
Definition: encode.c:689
#define min(a, b)
Definition: monoChain.cc:55
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
#define strtoull
Definition: stabs.c:58
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
RPN_OP_TYPE Type
Definition: kdb_expr.c:57
RPN_BINARY_OPERATOR BinaryOperator
Definition: kdb_expr.c:62
ULONG CharacterOffset
Definition: kdb_expr.c:58
UCHAR DerefMemorySize
Definition: kdb_expr.c:68
ULONGLONG Immediate
Definition: kdb_expr.c:64
union _RPN_OP::@1814 Data
UCHAR Register
Definition: kdb_expr.c:66
ULONG Size
Definition: kdb_expr.c:76
RPN_OP Ops[1]
Definition: kdb_expr.c:78
ULONG Sp
Definition: kdb_expr.c:77
#define max(a, b)
Definition: svc.c:63
static CONST DWORD MemorySize[]
Definition: svga.c:32
#define TAG_KDBG
Definition: tag.h:38
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
int32_t INT
Definition: typedefs.h:58
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
unsigned char UCHAR
Definition: xmlstorage.h:181
#define _snprintf
Definition: xmlstorage.h:200
char CHAR
Definition: xmlstorage.h:175