ReactOS 0.4.15-dev-5893-g1bb4167
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#define NDEBUG
38#include <debug.h>
39
40/* TYPES *********************************************************************/
41typedef enum _RPN_OP_TYPE
42{
50
52
53typedef struct _RPN_OP
54{
57 union
58 {
59 /* RpnOpBinaryOperator */
61 /* RpnOpImmediate */
63 /* RpnOpRegister */
65 /* RpnOpDereference */
67 }
69}
71
72typedef struct _RPN_STACK
73{
74 ULONG Size; /* Number of RPN_OPs on Ops */
75 ULONG Sp; /* Stack pointer */
76 RPN_OP Ops[1]; /* Array of RPN_OPs */
77}
79
80/* DEFINES *******************************************************************/
81#define stricmp _stricmp
82
83#ifndef RTL_FIELD_SIZE
84# define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
85#endif
86
87#define CONST_STRCPY(dst, src) \
88 do { if ((dst)) { memcpy(dst, src, sizeof(src)); } } while (0);
89
90#define RPN_OP_STACK_SIZE 256
91#define RPN_VALUE_STACK_SIZE 256
92
93/* GLOBALS *******************************************************************/
94static struct
95{
99}
100RpnStack =
101{
103 0
105
106static const struct
107{
110 UCHAR Size;
111}
113{
114 /* FIXME: X86 only */
115#ifdef _M_IX86
117#else
119#endif
120 {"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, EFlags)},
121#ifdef _M_IX86
130#else
139#endif
140 {"cs", FIELD_OFFSET(KDB_KTRAP_FRAME, SegCs), 2 }, /* Use only the lower 2 bytes */
154
155/* FUNCTIONS *****************************************************************/
156
159 ULONGLONG a,
160 ULONGLONG b)
161{
162 return a + b;
163}
164
167 ULONGLONG a,
168 ULONGLONG b)
169{
170 return a - b;
171}
172
175 ULONGLONG a,
176 ULONGLONG b)
177{
178 return a * b;
179}
180
183 ULONGLONG a,
184 ULONGLONG b)
185{
186 return a / b;
187}
188
191 ULONGLONG a,
192 ULONGLONG b)
193{
194 return a % b;
195}
196
199 ULONGLONG a,
200 ULONGLONG b)
201{
202 return (a == b);
203}
204
207 ULONGLONG a,
208 ULONGLONG b)
209{
210 return (a != b);
211}
212
215 ULONGLONG a,
216 ULONGLONG b)
217{
218 return (a < b);
219}
220
223 ULONGLONG a,
224 ULONGLONG b)
225{
226 return (a <= b);
227}
228
231 ULONGLONG a,
232 ULONGLONG b)
233{
234 return (a > b);
235}
236
239 ULONGLONG a,
240 ULONGLONG b)
241{
242 return (a >= b);
243}
244
249VOID
252{
253 ULONG ul;
254
255 ASSERT(Stack);
256 KdpDprintf("\nStack size: %ld\n", Stack->Sp);
257
258 for (ul = 0; ul < Stack->Sp; ul++)
259 {
260 PRPN_OP Op = Stack->Ops + ul;
261 switch (Op->Type)
262 {
263 case RpnOpNop:
264 KdpDprintf("NOP,");
265 break;
266
267 case RpnOpImmediate:
268 KdpDprintf("0x%I64x,", Op->Data.Immediate);
269 break;
270
273 KdpDprintf("+,");
275 KdpDprintf("-,");
277 KdpDprintf("*,");
279 KdpDprintf("/,");
281 KdpDprintf("%%,");
283 KdpDprintf("==,");
285 KdpDprintf("!=,");
287 KdpDprintf("<,");
289 KdpDprintf("<=,");
291 KdpDprintf(">,");
293 KdpDprintf(">=,");
294 else
295 KdpDprintf("UNKNOWN OP,");
296
297 break;
298
299 case RpnOpRegister:
301 break;
302
303 case RpnOpDereference:
304 KdpDprintf("[%s],",
305 (Op->Data.DerefMemorySize == 1) ? ("byte") :
306 ((Op->Data.DerefMemorySize == 2) ? ("word") :
307 ((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword"))));
308 break;
309
310 default:
311 KdpDprintf("\nUnsupported Type: %d\n", Op->Type);
312 ul = Stack->Sp;
313 break;
314 }
315 }
316
317 KdpDprintf("\n");
318}
319
324static VOID
327{
328 ASSERT(Stack);
329 Stack->Sp = 0;
330}
331
337static BOOLEAN
340 IN PRPN_OP Op)
341{
342 ASSERT(Stack);
343 ASSERT(Op);
344
345 if (Stack->Sp >= Stack->Size)
346 return FALSE;
347
348 memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP));
349 Stack->Sp++;
350
351 return TRUE;
352}
353
362static BOOLEAN
366{
367 ASSERT(Stack);
368
369 if (Stack->Sp == 0)
370 return FALSE;
371
372 Stack->Sp--;
373 if (Op)
374 memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP));
375
376 return TRUE;
377}
378
387static BOOLEAN
390 OUT PRPN_OP Op)
391{
392 ASSERT(Stack);
393 ASSERT(Op);
394
395 if (Stack->Sp == 0)
396 return FALSE;
397
398 memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP));
399
400 return TRUE;
401}
402
421static BOOLEAN
425 OUT PCHAR *End OPTIONAL,
426 IN ULONG CharacterOffset,
427 OUT PLONG ErrOffset OPTIONAL,
428 OUT PCHAR ErrMsg OPTIONAL)
429{
431 PCHAR pend;
433 LONG OperatorOffset = -1;
434 RPN_OP RpnOp;
435 RPN_OP PoppedOperator;
436 BOOLEAN HavePoppedOperator = FALSE;
437 RPN_OP ComparativeOp;
438 BOOLEAN ComparativeOpFilled = FALSE;
439 BOOLEAN IsComparativeOp;
440 INT_PTR i, i2;
441 ULONG64 ull;
443 CHAR Buffer[16];
445
446 ASSERT(Stack);
448
449 First = TRUE;
450 for (;;)
451 {
452 /* Skip whitespace */
453 while (isspace(*p))
454 {
455 p++;
456 CharacterOffset++;
457 }
458
459 /* Check for end of expression */
460 if (p[0] == '\0' || p[0] == ')' || p[0] == ']')
461 break;
462
463 if (!First)
464 {
465 /* Remember operator */
466 Operator = p++;
467 OperatorOffset = CharacterOffset++;
468
469 /* Pop operator (to get the right operator precedence) */
470 HavePoppedOperator = FALSE;
471 if (*Operator == '*' || *Operator == '/' || *Operator == '%')
472 {
473 if (RpnpTopStack(Stack, &PoppedOperator) &&
474 PoppedOperator.Type == RpnOpBinaryOperator &&
475 (PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorAdd ||
476 PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorSub))
477 {
479 HavePoppedOperator = TRUE;
480 }
481 else if (PoppedOperator.Type == RpnOpNop)
482 {
484 /* Discard the NOP - it was only pushed to indicate there was a
485 * closing brace, so the previous operator shouldn't be popped.
486 */
487 }
488 }
489 else if ((Operator[0] == '=' && Operator[1] == '=') ||
490 (Operator[0] == '!' && Operator[1] == '=') ||
491 Operator[0] == '<' || Operator[0] == '>')
492 {
493 if (Operator[0] == '=' || Operator[0] == '!' ||
494 (Operator[0] == '<' && Operator[1] == '=') ||
495 (Operator[0] == '>' && Operator[1] == '='))
496 {
497 p++;
498 CharacterOffset++;
499 }
500#if 0
501 /* Parse rest of expression */
502 if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,
503 ErrOffset, ErrMsg))
504 {
505 return FALSE;
506 }
507 else if (pend == p + 1)
508 {
509 CONST_STRCPY(ErrMsg, "Expression expected");
510
511 if (ErrOffset)
512 *ErrOffset = CharacterOffset + 1;
513
514 return FALSE;
515 }
516
517 goto end_of_expression; /* return */
518#endif
519 }
520 else if (Operator[0] != '+' && Operator[0] != '-')
521 {
522 CONST_STRCPY(ErrMsg, "Operator expected");
523
524 if (ErrOffset)
525 *ErrOffset = OperatorOffset;
526
527 return FALSE;
528 }
529
530 /* Skip whitespace */
531 while (isspace(*p))
532 {
533 p++;
534 CharacterOffset++;
535 }
536 }
537
538 /* Get operand */
539 MemorySize = sizeof(ULONG_PTR); /* default to pointer size */
540
541get_operand:
542 i = strcspn(p, "+-*/%()[]<>!=");
543 if (i > 0)
544 {
545 i2 = i;
546
547 /* Copy register name/memory size */
548 while (isspace(p[--i2]));
549
550 i2 = min(i2 + 1, (INT)sizeof (Buffer) - 1);
551 strncpy(Buffer, p, i2);
552 Buffer[i2] = '\0';
553
554 /* Memory size prefix */
555 if (p[i] == '[')
556 {
557 if (stricmp(Buffer, "byte") == 0)
558 MemorySize = 1;
559 else if (stricmp(Buffer, "word") == 0)
560 MemorySize = 2;
561 else if (stricmp(Buffer, "dword") == 0)
562 MemorySize = 4;
563 else if (stricmp(Buffer, "qword") == 0)
564 MemorySize = 8;
565 else
566 {
567 CONST_STRCPY(ErrMsg, "Invalid memory size prefix");
568
569 if (ErrOffset)
570 *ErrOffset = CharacterOffset;
571
572 return FALSE;
573 }
574
575 p += i;
576 CharacterOffset += i;
577 goto get_operand;
578 }
579
580 /* Try to find register */
581 for (i = 0; i < RegisterToTrapFrameCount; i++)
582 {
584 break;
585 }
586
588 {
589 RpnOp.Type = RpnOpRegister;
590 RpnOp.CharacterOffset = CharacterOffset;
591 RpnOp.Data.Register = i;
593 CharacterOffset += i;
594 p += i;
595 }
596 else
597 {
598 /* Immediate value */
599 ull = strtoull(p, &pend, 0);
600 if (p != pend)
601 {
602 RpnOp.Type = RpnOpImmediate;
603 RpnOp.CharacterOffset = CharacterOffset;
604 RpnOp.Data.Immediate = ull;
605 CharacterOffset += pend - p;
606 p = pend;
607 }
608 else
609 {
610 CONST_STRCPY(ErrMsg, "Operand expected");
611
612 if (ErrOffset)
613 *ErrOffset = CharacterOffset;
614
615 return FALSE;
616 }
617 }
618
619 /* Push operand */
620 if (!RpnpPushStack(Stack, &RpnOp))
621 {
622 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
623
624 if (ErrOffset)
625 *ErrOffset = -1;
626
627 return FALSE;
628 }
629 }
630 else if (i == 0)
631 {
632 if (p[0] == '(' || p[0] == '[') /* subexpression */
633 {
634 if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,
635 ErrOffset, ErrMsg))
636 {
637 return FALSE;
638 }
639 else if (pend == p + 1)
640 {
641 CONST_STRCPY(ErrMsg, "Expression expected");
642
643 if (ErrOffset)
644 *ErrOffset = CharacterOffset + 1;
645
646 return FALSE;
647 }
648
649 if (p[0] == '[') /* dereference */
650 {
651 ASSERT(MemorySize == 1 || MemorySize == 2 ||
652 MemorySize == 4 || MemorySize == 8);
653
654 if (pend[0] != ']')
655 {
656 CONST_STRCPY(ErrMsg, "']' expected");
657
658 if (ErrOffset)
659 *ErrOffset = CharacterOffset + (pend - p);
660
661 return FALSE;
662 }
663
664 RpnOp.Type = RpnOpDereference;
665 RpnOp.CharacterOffset = CharacterOffset;
667
668 if (!RpnpPushStack(Stack, &RpnOp))
669 {
670 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
671
672 if (ErrOffset)
673 *ErrOffset = -1;
674
675 return FALSE;
676 }
677 }
678 else /* p[0] == '(' */
679 {
680 if (pend[0] != ')')
681 {
682 CONST_STRCPY(ErrMsg, "')' expected");
683
684 if (ErrOffset)
685 *ErrOffset = CharacterOffset + (pend - p);
686
687 return FALSE;
688 }
689 }
690
691 /* Push a "nop" to prevent popping of the + operator (which would
692 * result in (10+10)/2 beeing evaluated as 15)
693 */
694 RpnOp.Type = RpnOpNop;
695 if (!RpnpPushStack(Stack, &RpnOp))
696 {
697 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
698
699 if (ErrOffset)
700 *ErrOffset = -1;
701
702 return FALSE;
703 }
704
705 /* Skip closing brace/bracket */
706 pend++;
707
708 CharacterOffset += pend - p;
709 p = pend;
710 }
711 else if (First && p[0] == '-') /* Allow expressions like "- eax" */
712 {
713 RpnOp.Type = RpnOpImmediate;
714 RpnOp.CharacterOffset = CharacterOffset;
715 RpnOp.Data.Immediate = 0;
716
717 if (!RpnpPushStack(Stack, &RpnOp))
718 {
719 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
720
721 if (ErrOffset)
722 *ErrOffset = -1;
723
724 return FALSE;
725 }
726 }
727 else
728 {
729 CONST_STRCPY(ErrMsg, "Operand expected");
730
731 if (ErrOffset)
732 *ErrOffset = CharacterOffset;
733
734 return FALSE;
735 }
736 }
737 else
738 {
739 CONST_STRCPY(ErrMsg, "strcspn() failed");
740
741 if (ErrOffset)
742 *ErrOffset = -1;
743
744 return FALSE;
745 }
746
747 if (!First)
748 {
749 /* Push operator */
750 RpnOp.CharacterOffset = OperatorOffset;
752 IsComparativeOp = FALSE;
753
754 switch (*Operator)
755 {
756 case '+':
758 break;
759
760 case '-':
762 break;
763
764 case '*':
766 break;
767
768 case '/':
770 break;
771
772 case '%':
774 break;
775
776 case '=':
777 ASSERT(Operator[1] == '=');
778 IsComparativeOp = TRUE;
780 break;
781
782 case '!':
783 ASSERT(Operator[1] == '=');
784 IsComparativeOp = TRUE;
786 break;
787
788 case '<':
789 IsComparativeOp = TRUE;
790
791 if (Operator[1] == '=')
793 else
795
796 break;
797
798 case '>':
799 IsComparativeOp = TRUE;
800
801 if (Operator[1] == '=')
803 else
805
806 break;
807
808 default:
809 ASSERT(0);
810 break;
811 }
812
813 if (IsComparativeOp)
814 {
815 if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
816 {
817 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
818
819 if (ErrOffset)
820 *ErrOffset = -1;
821
822 return FALSE;
823 }
824
825 memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP));
826 ComparativeOpFilled = TRUE;
827 }
828 else if (!RpnpPushStack(Stack, &RpnOp))
829 {
830 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
831
832 if (ErrOffset)
833 *ErrOffset = -1;
834
835 return FALSE;
836 }
837
838 /* Push popped operator */
839 if (HavePoppedOperator)
840 {
841 if (!RpnpPushStack(Stack, &PoppedOperator))
842 {
843 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
844
845 if (ErrOffset)
846 *ErrOffset = -1;
847
848 return FALSE;
849 }
850 }
851 }
852
853 First = FALSE;
854 }
855
856//end_of_expression:
857
858 if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
859 {
860 CONST_STRCPY(ErrMsg, "RPN op stack overflow");
861
862 if (ErrOffset)
863 *ErrOffset = -1;
864
865 return FALSE;
866 }
867
868 /* Skip whitespace */
869 while (isspace(*p))
870 {
871 p++;
872 CharacterOffset++;
873 }
874
875 if (End)
876 *End = p;
877
878 return TRUE;
879}
880
892static BOOLEAN
895 IN PKDB_KTRAP_FRAME TrapFrame,
897 OUT PLONG ErrOffset OPTIONAL,
898 OUT PCHAR ErrMsg OPTIONAL)
899{
901 ULONG ValueStackPointer = 0;
902 ULONG index;
903 ULONGLONG ull;
904 ULONG ul;
905 USHORT us;
906 UCHAR uc;
907 PVOID p;
908 BOOLEAN Ok;
909#ifdef DEBUG_RPN
910 ULONG ValueStackPointerMax = 0;
911#endif
912
913 ASSERT(Stack);
914 ASSERT(TrapFrame);
915 ASSERT(Result);
916
917 for (index = 0; index < Stack->Sp; index++)
918 {
919 PRPN_OP Op = Stack->Ops + index;
920
921#ifdef DEBUG_RPN
922 ValueStackPointerMax = max(ValueStackPointerMax, ValueStackPointer);
923#endif
924
925 switch (Op->Type)
926 {
927 case RpnOpNop:
928 /* No operation */
929 break;
930
931 case RpnOpImmediate:
932 if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
933 {
934 CONST_STRCPY(ErrMsg, "Value stack overflow");
935
936 if (ErrOffset)
937 *ErrOffset = -1;
938
939 return FALSE;
940 }
941
942 ValueStack[ValueStackPointer++] = Op->Data.Immediate;
943 break;
944
945 case RpnOpRegister:
946 if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
947 {
948 CONST_STRCPY(ErrMsg, "Value stack overflow");
949
950 if (ErrOffset)
951 *ErrOffset = -1;
952
953 return FALSE;
954 }
955
956 ul = Op->Data.Register;
957 p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset);
958
959 switch (RegisterToTrapFrame[ul].Size)
960 {
961 case 1: ull = (ULONGLONG)(*(PUCHAR)p); break;
962 case 2: ull = (ULONGLONG)(*(PUSHORT)p); break;
963 case 4: ull = (ULONGLONG)(*(PULONG)p); break;
964 case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break;
965 default: ASSERT(0); return FALSE; break;
966 }
967
968 ValueStack[ValueStackPointer++] = ull;
969 break;
970
971 case RpnOpDereference:
972 if (ValueStackPointer < 1)
973 {
974 CONST_STRCPY(ErrMsg, "Value stack underflow");
975
976 if (ErrOffset)
977 *ErrOffset = -1;
978
979 return FALSE;
980 }
981
982 /* FIXME: Print a warning when address is out of range */
983 p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1];
984 Ok = FALSE;
985
986 switch (Op->Data.DerefMemorySize)
987 {
988 case 1:
989 if (NT_SUCCESS(KdbpSafeReadMemory(&uc, p, sizeof (uc))))
990 {
991 Ok = TRUE;
992 ull = (ULONGLONG)uc;
993 }
994 break;
995
996 case 2:
997 if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us))))
998 {
999 Ok = TRUE;
1000 ull = (ULONGLONG)us;
1001 }
1002 break;
1003
1004 case 4:
1005 if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul))))
1006 {
1007 Ok = TRUE;
1008 ull = (ULONGLONG)ul;
1009 }
1010 break;
1011
1012 case 8:
1013 if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull))))
1014 {
1015 Ok = TRUE;
1016 }
1017 break;
1018
1019 default:
1020 ASSERT(0);
1021 return FALSE;
1022 break;
1023 }
1024
1025 if (!Ok)
1026 {
1027 _snprintf(ErrMsg, 128, "Couldn't access memory at 0x%p", p);
1028
1029 if (ErrOffset)
1030 *ErrOffset = Op->CharacterOffset;
1031
1032 return FALSE;
1033 }
1034
1035 ValueStack[ValueStackPointer - 1] = ull;
1036 break;
1037
1039 if (ValueStackPointer < 2)
1040 {
1041 CONST_STRCPY(ErrMsg, "Value stack underflow");
1042
1043 if (ErrOffset)
1044 *ErrOffset = -1;
1045
1046 return FALSE;
1047 }
1048
1049 ValueStackPointer--;
1050 ull = ValueStack[ValueStackPointer];
1051
1052 if (ull == 0 && Op->Data.BinaryOperator == RpnBinaryOperatorDiv)
1053 {
1054 CONST_STRCPY(ErrMsg, "Division by zero");
1055
1056 if (ErrOffset)
1057 *ErrOffset = Op->CharacterOffset;
1058
1059 return FALSE;
1060 }
1061
1062 ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull);
1063 ValueStack[ValueStackPointer - 1] = ull;
1064 break;
1065
1066 default:
1067 ASSERT(0);
1068 return FALSE;
1069 }
1070 }
1071
1072#ifdef DEBUG_RPN
1073 DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax);
1074#endif
1075
1076 if (ValueStackPointer != 1)
1077 {
1078 CONST_STRCPY(ErrMsg, "Stack not empty after evaluation");
1079
1080 if (ErrOffset)
1081 *ErrOffset = -1;
1082
1083 return FALSE;
1084 }
1085
1086 *Result = ValueStack[0];
1087 return TRUE;
1088}
1089
1101BOOLEAN
1104 IN PKDB_KTRAP_FRAME TrapFrame,
1106 OUT PLONG ErrOffset OPTIONAL,
1107 OUT PCHAR ErrMsg OPTIONAL)
1108{
1110
1112 ASSERT(TrapFrame);
1113 ASSERT(Result);
1114
1115 /* Clear the stack and parse the expression */
1117 if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
1118 return FALSE;
1119
1120#ifdef DEBUG_RPN
1122#endif
1123
1124 /* Evaluate the stack */
1125 if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg))
1126 return FALSE;
1127
1128 return TRUE;
1129}
1130
1141PVOID
1144 OUT PLONG ErrOffset OPTIONAL,
1145 OUT PCHAR ErrMsg OPTIONAL)
1146{
1147 LONG Size;
1149 PRPN_STACK NewStack;
1150
1152
1153 /* Clear the stack and parse the expression */
1155 if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
1156 return FALSE;
1157
1158#ifdef DEBUG_RPN
1160#endif
1161
1162 /* Duplicate the stack and return a pointer/handle to it */
1163 ASSERT(Stack->Sp >= 1);
1164 Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1));
1166
1167 if (!NewStack)
1168 {
1169 CONST_STRCPY(ErrMsg, "Out of memory");
1170
1171 if (ErrOffset)
1172 *ErrOffset = -1;
1173
1174 return NULL;
1175 }
1176
1177 memcpy(NewStack, Stack, Size);
1178 NewStack->Size = NewStack->Sp;
1179
1180 return NewStack;
1181}
1182
1195BOOLEAN
1198 IN PKDB_KTRAP_FRAME TrapFrame,
1200 OUT PLONG ErrOffset OPTIONAL,
1201 OUT PCHAR ErrMsg OPTIONAL)
1202{
1204
1206 ASSERT(TrapFrame);
1207 ASSERT(Result);
1208
1209 /* Evaluate the stack */
1210 return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg);
1211}
1212
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:1648
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
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:422
static BOOLEAN RpnpPushStack(IN OUT PRPN_STACK Stack, IN PRPN_OP Op)
Pushes an RPN_OP onto the stack.
Definition: kdb_expr.c:338
ULONGLONG RpnBinaryOperatorSub(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:166
ULONGLONG RpnBinaryOperatorGreaterThanOrEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:238
UCHAR Offset
Definition: kdb_expr.c:109
ULONGLONG RpnBinaryOperatorDiv(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:182
static const INT RegisterToTrapFrameCount
Definition: kdb_expr.c:153
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:1142
ULONG Sp
Definition: kdb_expr.c:97
PCHAR Name
Definition: kdb_expr.c:108
ULONGLONG RpnBinaryOperatorGreaterThan(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:230
#define stricmp
Definition: kdb_expr.c:81
RPN_OP Ops[RPN_OP_STACK_SIZE]
Definition: kdb_expr.c:98
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:1102
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:1196
ULONGLONG RpnBinaryOperatorMod(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:190
static VOID RpnpClearStack(OUT PRPN_STACK Stack)
Clears the given RPN stack.
Definition: kdb_expr.c:325
ULONGLONG RpnBinaryOperatorLessThanOrEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:222
static BOOLEAN RpnpPopStack(IN OUT PRPN_STACK Stack, OUT PRPN_OP Op OPTIONAL)
Pops the top op from the stack.
Definition: kdb_expr.c:363
#define RPN_VALUE_STACK_SIZE
Definition: kdb_expr.c:91
struct _RPN_STACK RPN_STACK
_RPN_OP_TYPE
Definition: kdb_expr.c:42
@ RpnOpNop
Definition: kdb_expr.c:43
@ RpnOpBinaryOperator
Definition: kdb_expr.c:44
@ RpnOpRegister
Definition: kdb_expr.c:47
@ RpnOpDereference
Definition: kdb_expr.c:48
@ RpnOpUnaryOperator
Definition: kdb_expr.c:45
@ RpnOpImmediate
Definition: kdb_expr.c:46
ULONGLONG RpnBinaryOperatorNotEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:206
struct _RPN_STACK * PRPN_STACK
struct _RPN_OP * PRPN_OP
ULONG Size
Definition: kdb_expr.c:96
ULONGLONG(* RPN_BINARY_OPERATOR)(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:51
struct _RPN_OP RPN_OP
#define CONST_STRCPY(dst, src)
Definition: kdb_expr.c:87
static struct @1794 RpnStack
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:388
ULONGLONG RpnBinaryOperatorAdd(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:158
ULONGLONG RpnBinaryOperatorMul(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:174
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:893
#define RPN_OP_STACK_SIZE
Definition: kdb_expr.c:90
VOID RpnpDumpStack(IN PRPN_STACK Stack)
Dumps the given RPN stack content.
Definition: kdb_expr.c:250
static const struct @1795 RegisterToTrapFrame[]
ULONGLONG RpnBinaryOperatorLessThan(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:214
ULONGLONG RpnBinaryOperatorEquals(ULONGLONG a, ULONGLONG b)
Definition: kdb_expr.c:198
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define KdpDprintf(...)
Definition: mmdbg.c:19
#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:55
RPN_BINARY_OPERATOR BinaryOperator
Definition: kdb_expr.c:60
ULONG CharacterOffset
Definition: kdb_expr.c:56
UCHAR DerefMemorySize
Definition: kdb_expr.c:66
ULONGLONG Immediate
Definition: kdb_expr.c:62
union _RPN_OP::@1796 Data
UCHAR Register
Definition: kdb_expr.c:64
ULONG Size
Definition: kdb_expr.c:74
RPN_OP Ops[1]
Definition: kdb_expr.c:76
ULONG Sp
Definition: kdb_expr.c:75
#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:426
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