2 * File expr.c - expression handling for Wine internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
13 #include "wine/winbase16.h"
69 struct datatype
* cast
;
76 const char * element_name
;
88 const char * funcname
;
97 #define EXPR_TYPE_CONST 0
98 #define EXPR_TYPE_US_CONST 1
99 #define EXPR_TYPE_SYMBOL 2
100 #define EXPR_TYPE_REGISTER 3
101 #define EXPR_TYPE_BINOP 4
102 #define EXPR_TYPE_UNOP 5
103 #define EXPR_TYPE_STRUCT 6
104 #define EXPR_TYPE_PSTRUCT 7
105 #define EXPR_TYPE_ARRAY 8
106 #define EXPR_TYPE_CALL 9
107 #define EXPR_TYPE_STRING 10
108 #define EXPR_TYPE_CAST 11
110 static char expr_list
[4096];
111 static int next_expr_free
= 0;
114 * This is how we turn an expression address into the actual value.
115 * This works well in the 32 bit domain - not sure at all about the
118 #define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
122 DEBUG_GetFreeExpr(void)
126 rtn
= (struct expr
*) &expr_list
[next_expr_free
];
128 next_expr_free
+= sizeof(struct expr
);
129 assert(next_expr_free
< sizeof(expr_list
));
135 DEBUG_FreeExprMem(void)
141 DEBUG_TypeCastExpr(struct datatype
* dt
, struct expr
* exp
)
145 ex
= DEBUG_GetFreeExpr();
147 ex
->type
= EXPR_TYPE_CAST
;
148 ex
->un
.cast
.cast
= dt
;
149 ex
->un
.cast
.expr
= exp
;
154 DEBUG_RegisterExpr(enum debug_regs regno
)
158 ex
= DEBUG_GetFreeExpr();
160 ex
->type
= EXPR_TYPE_REGISTER
;
161 ex
->un
.rgister
.reg
= regno
;
166 DEBUG_SymbolExpr(const char * name
)
170 ex
= DEBUG_GetFreeExpr();
172 ex
->type
= EXPR_TYPE_SYMBOL
;
173 ex
->un
.symbol
.name
= name
;
178 DEBUG_ConstExpr(int value
)
182 ex
= DEBUG_GetFreeExpr();
184 ex
->type
= EXPR_TYPE_CONST
;
185 ex
->un
.constant
.value
= value
;
190 DEBUG_StringExpr(const char * str
)
194 ex
= DEBUG_GetFreeExpr();
196 ex
->type
= EXPR_TYPE_STRING
;
197 ex
->un
.string
.str
= str
+1;
198 pnt
= strrchr(ex
->un
.string
.str
, '"');
207 DEBUG_USConstExpr(unsigned int value
)
211 ex
= DEBUG_GetFreeExpr();
213 ex
->type
= EXPR_TYPE_CONST
;
214 ex
->un
.u_const
.value
= value
;
219 DEBUG_BinopExpr(int operator_type
, struct expr
* exp1
, struct expr
* exp2
)
223 ex
= DEBUG_GetFreeExpr();
225 ex
->type
= EXPR_TYPE_BINOP
;
226 ex
->un
.binop
.binop_type
= operator_type
;
227 ex
->un
.binop
.exp1
= exp1
;
228 ex
->un
.binop
.exp2
= exp2
;
233 DEBUG_UnopExpr(int operator_type
, struct expr
* exp1
)
237 ex
= DEBUG_GetFreeExpr();
239 ex
->type
= EXPR_TYPE_UNOP
;
240 ex
->un
.unop
.unop_type
= operator_type
;
241 ex
->un
.unop
.exp1
= exp1
;
246 DEBUG_StructExpr(struct expr
* exp
, const char * element
)
250 ex
= DEBUG_GetFreeExpr();
252 ex
->type
= EXPR_TYPE_STRUCT
;
253 ex
->un
.structure
.exp1
= exp
;
254 ex
->un
.structure
.element_name
= element
;
259 DEBUG_StructPExpr(struct expr
* exp
, const char * element
)
263 ex
= DEBUG_GetFreeExpr();
265 ex
->type
= EXPR_TYPE_PSTRUCT
;
266 ex
->un
.structure
.exp1
= exp
;
267 ex
->un
.structure
.element_name
= element
;
272 DEBUG_CallExpr(const char * funcname
, int nargs
, ...)
278 ex
= DEBUG_GetFreeExpr();
280 ex
->type
= EXPR_TYPE_CALL
;
281 ex
->un
.call
.funcname
= funcname
;
282 ex
->un
.call
.nargs
= nargs
;
285 for(i
=0; i
< nargs
; i
++)
287 ex
->un
.call
.arg
[i
] = va_arg(ap
, struct expr
*);
293 DBG_VALUE
DEBUG_EvalExpr(struct expr
* exp
)
299 unsigned int cexp
[5];
303 struct datatype
* type1
;
304 struct datatype
* type2
;
313 rtn
= DEBUG_EvalExpr(exp
->un
.cast
.expr
);
314 rtn
.type
= exp
->un
.cast
.cast
;
315 if (DEBUG_GetType(rtn
.type
) == DT_POINTER
)
316 rtn
.cookie
= DV_TARGET
;
318 case EXPR_TYPE_STRING
:
319 rtn
.type
= DEBUG_TypeString
;
320 rtn
.cookie
= DV_HOST
;
321 rtn
.addr
.off
= (unsigned int) &exp
->un
.string
.str
;
324 case EXPR_TYPE_CONST
:
325 rtn
.type
= DEBUG_TypeIntConst
;
326 rtn
.cookie
= DV_HOST
;
327 rtn
.addr
.off
= (unsigned int) &exp
->un
.constant
.value
;
330 case EXPR_TYPE_US_CONST
:
331 rtn
.type
= DEBUG_TypeUSInt
;
332 rtn
.cookie
= DV_HOST
;
333 rtn
.addr
.off
= (unsigned int) &exp
->un
.u_const
.value
;
336 case EXPR_TYPE_SYMBOL
:
337 if( !DEBUG_GetSymbolValue(exp
->un
.symbol
.name
, -1, &rtn
, FALSE
) )
339 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
342 case EXPR_TYPE_PSTRUCT
:
343 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
344 if( exp1
.type
== NULL
)
346 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
348 rtn
.cookie
= DV_TARGET
;
349 rtn
.addr
.off
= DEBUG_TypeDerefPointer(&exp1
, &type1
);
352 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
355 DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
356 &exp
->un
.structure
.result
);
358 case EXPR_TYPE_STRUCT
:
359 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
360 if( exp1
.type
== NULL
)
362 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
365 DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
366 &exp
->un
.structure
.result
);
370 * First, evaluate all of the arguments. If any of them are not
371 * evaluable, then bail.
373 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
375 exp1
= DEBUG_EvalExpr(exp
->un
.call
.arg
[i
]);
376 if( exp1
.type
== NULL
)
380 cexp
[i
] = DEBUG_GetExprValue(&exp1
, NULL
);
384 * Now look up the address of the function itself.
386 if( !DEBUG_GetSymbolValue(exp
->un
.call
.funcname
, -1, &rtn
, FALSE
) )
388 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
392 /* FIXME: NEWDBG NIY */
393 /* Anyway, I wonder how this could work depending on the calling order of
394 * the function (cdecl vs pascal for example)
398 fptr
= (int (*)()) rtn
.addr
.off
;
399 switch(exp
->un
.call
.nargs
)
402 exp
->un
.call
.result
= (*fptr
)();
405 exp
->un
.call
.result
= (*fptr
)(cexp
[0]);
408 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1]);
411 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2]);
414 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3]);
417 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3], cexp
[4]);
421 fprintf(stderr
, "Function call no longer implemented\n");
422 /* would need to set up a call to this function, and then restore the current
423 * context afterwards...
425 exp
->un
.call
.result
= 0;
427 rtn
.type
= DEBUG_TypeInt
;
428 rtn
.cookie
= DV_HOST
;
429 rtn
.addr
.off
= (unsigned int) &exp
->un
.call
.result
;
432 case EXPR_TYPE_REGISTER
:
433 rtn
.type
= DEBUG_TypeIntConst
;
434 rtn
.cookie
= DV_HOST
;
435 exp
->un
.rgister
.result
= DEBUG_GetRegister(exp
->un
.rgister
.reg
);
436 rtn
.addr
.off
= (unsigned int) &exp
->un
.rgister
.result
;
438 if( exp
->un
.rgister
.reg
== REG_EIP
)
439 rtn
.addr
.seg
= DEBUG_context
.SegCs
;
441 rtn
.addr
.seg
= DEBUG_context
.SegDs
;
443 DEBUG_FixAddress( &rtn
.addr
, 0 );
445 case EXPR_TYPE_BINOP
:
446 exp1
= DEBUG_EvalExpr(exp
->un
.binop
.exp1
);
447 exp2
= DEBUG_EvalExpr(exp
->un
.binop
.exp2
);
448 rtn
.cookie
= DV_HOST
;
449 if( exp1
.type
== NULL
|| exp2
.type
== NULL
)
451 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
453 if( exp1
.type
== DEBUG_TypeIntConst
&& exp2
.type
== DEBUG_TypeIntConst
)
455 rtn
.type
= exp1
.type
;
459 rtn
.type
= DEBUG_TypeInt
;
462 rtn
.addr
.off
= (unsigned int) &exp
->un
.binop
.result
;
463 switch(exp
->un
.binop
.binop_type
)
466 type1
= DEBUG_GetPointerType(exp1
.type
);
467 type2
= DEBUG_GetPointerType(exp2
.type
);
470 if( type1
!= NULL
&& type2
!= NULL
)
472 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
474 else if( type1
!= NULL
)
476 scale2
= DEBUG_GetObjectSize(type1
);
477 rtn
.type
= exp1
.type
;
479 else if( type2
!= NULL
)
481 scale1
= DEBUG_GetObjectSize(type2
);
482 rtn
.type
= exp2
.type
;
484 exp
->un
.binop
.result
= (VAL(exp1
) * scale1
+ scale2
* VAL(exp2
));
487 type1
= DEBUG_GetPointerType(exp1
.type
);
488 type2
= DEBUG_GetPointerType(exp2
.type
);
492 if( type1
!= NULL
&& type2
!= NULL
)
496 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
498 scale3
= DEBUG_GetObjectSize(type1
);
500 else if( type1
!= NULL
)
502 scale2
= DEBUG_GetObjectSize(type1
);
503 rtn
.type
= exp1
.type
;
506 else if( type2
!= NULL
)
508 scale1
= DEBUG_GetObjectSize(type2
);
509 rtn
.type
= exp2
.type
;
511 exp
->un
.binop
.result
= (VAL(exp1
) - VAL(exp2
)) / scale3
;
514 rtn
.cookie
= DV_TARGET
;
515 rtn
.addr
.seg
= VAL(exp1
);
516 exp
->un
.binop
.result
= VAL(exp2
);
518 DEBUG_FixSegment(&rtn
.addr
);
522 exp
->un
.binop
.result
= (VAL(exp1
) || VAL(exp2
));
525 exp
->un
.binop
.result
= (VAL(exp1
) && VAL(exp2
));
528 exp
->un
.binop
.result
= (VAL(exp1
) | VAL(exp2
));
531 exp
->un
.binop
.result
= (VAL(exp1
) & VAL(exp2
));
534 exp
->un
.binop
.result
= (VAL(exp1
) ^ VAL(exp2
));
537 exp
->un
.binop
.result
= (VAL(exp1
) == VAL(exp2
));
540 exp
->un
.binop
.result
= (VAL(exp1
) > VAL(exp2
));
543 exp
->un
.binop
.result
= (VAL(exp1
) < VAL(exp2
));
546 exp
->un
.binop
.result
= (VAL(exp1
) >= VAL(exp2
));
549 exp
->un
.binop
.result
= (VAL(exp1
) <= VAL(exp2
));
552 exp
->un
.binop
.result
= (VAL(exp1
) != VAL(exp2
));
555 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) << VAL(exp2
));
558 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) >> VAL(exp2
));
561 exp
->un
.binop
.result
= (VAL(exp1
) * VAL(exp2
));
566 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
568 exp
->un
.binop
.result
= (VAL(exp1
) / VAL(exp2
));
573 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
575 exp
->un
.binop
.result
= (VAL(exp1
) % VAL(exp2
));
578 DEBUG_ArrayIndex(&exp1
, &rtn
, VAL(exp2
));
581 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
586 exp1
= DEBUG_EvalExpr(exp
->un
.unop
.exp1
);
587 rtn
.cookie
= DV_HOST
;
588 if( exp1
.type
== NULL
)
590 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
593 rtn
.addr
.off
= (unsigned int) &exp
->un
.unop
.result
;
594 if( exp1
.type
== DEBUG_TypeIntConst
)
596 rtn
.type
= exp1
.type
;
600 rtn
.type
= DEBUG_TypeInt
;
602 switch(exp
->un
.unop
.unop_type
)
605 exp
->un
.unop
.result
= -VAL(exp1
);
608 exp
->un
.unop
.result
= !VAL(exp1
);
611 exp
->un
.unop
.result
= ~VAL(exp1
);
614 rtn
.cookie
= exp1
.cookie
;
615 rtn
.addr
.off
= (unsigned int) DEBUG_TypeDerefPointer(&exp1
, &rtn
.type
);
618 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
621 case EXP_OP_FORCE_DEREF
:
622 rtn
.cookie
= exp1
.cookie
;
623 rtn
.addr
.seg
= exp1
.addr
.seg
;
624 if (exp1
.cookie
== DV_TARGET
)
625 DEBUG_READ_MEM((void*)exp1
.addr
.off
, &rtn
.addr
.off
, sizeof(rtn
.addr
.off
));
627 memcpy(&rtn
.addr
.off
, (void*)exp1
.addr
.off
, sizeof(rtn
.addr
.off
));
630 /* FIXME: even for a 16 bit entity ? */
631 rtn
.cookie
= DV_TARGET
;
632 rtn
.type
= DEBUG_FindOrMakePointerType(exp1
.type
);
633 exp
->un
.unop
.result
= exp1
.addr
.off
;
636 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
640 fprintf(stderr
,"Unexpected expression (%d).\n", exp
->type
);
641 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
645 assert(rtn
.cookie
== DV_TARGET
|| rtn
.cookie
== DV_HOST
);
652 DEBUG_DisplayExpr(const struct expr
* exp
)
659 fprintf(stderr
, "((");
660 DEBUG_PrintTypeCast(exp
->un
.cast
.cast
);
661 fprintf(stderr
, ")");
662 DEBUG_DisplayExpr(exp
->un
.cast
.expr
);
663 fprintf(stderr
, ")");
665 case EXPR_TYPE_REGISTER
:
666 DEBUG_PrintRegister(exp
->un
.rgister
.reg
);
668 case EXPR_TYPE_US_CONST
:
669 fprintf(stderr
, "%ud", exp
->un
.u_const
.value
);
671 case EXPR_TYPE_CONST
:
672 fprintf(stderr
, "%d", exp
->un
.u_const
.value
);
674 case EXPR_TYPE_STRING
:
675 fprintf(stderr
, "\"%s\"", exp
->un
.string
.str
);
677 case EXPR_TYPE_SYMBOL
:
678 fprintf(stderr
, "%s" , exp
->un
.symbol
.name
);
680 case EXPR_TYPE_PSTRUCT
:
681 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
682 fprintf(stderr
, "->%s", exp
->un
.structure
.element_name
);
684 case EXPR_TYPE_STRUCT
:
685 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
686 fprintf(stderr
, ".%s", exp
->un
.structure
.element_name
);
689 fprintf(stderr
, "%s(",exp
->un
.call
.funcname
);
690 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
692 DEBUG_DisplayExpr(exp
->un
.call
.arg
[i
]);
693 if( i
!= exp
->un
.call
.nargs
- 1 )
695 fprintf(stderr
, ", ");
698 fprintf(stderr
, ")");
700 case EXPR_TYPE_BINOP
:
701 fprintf(stderr
, "( ");
702 DEBUG_DisplayExpr(exp
->un
.binop
.exp1
);
703 switch(exp
->un
.binop
.binop_type
)
706 fprintf(stderr
, " + ");
709 fprintf(stderr
, " - ");
712 fprintf(stderr
, ":");
715 fprintf(stderr
, " || ");
718 fprintf(stderr
, " && ");
721 fprintf(stderr
, " | ");
724 fprintf(stderr
, " & ");
727 fprintf(stderr
, " ^ ");
730 fprintf(stderr
, " == ");
733 fprintf(stderr
, " > ");
736 fprintf(stderr
, " < ");
739 fprintf(stderr
, " >= ");
742 fprintf(stderr
, " <= ");
745 fprintf(stderr
, " != ");
748 fprintf(stderr
, " << ");
751 fprintf(stderr
, " >> ");
754 fprintf(stderr
, " * ");
757 fprintf(stderr
, " / ");
760 fprintf(stderr
, " %% ");
763 fprintf(stderr
, "[");
768 DEBUG_DisplayExpr(exp
->un
.binop
.exp2
);
769 if( exp
->un
.binop
.binop_type
== EXP_OP_ARR
)
771 fprintf(stderr
, "]");
773 fprintf(stderr
, " )");
776 switch(exp
->un
.unop
.unop_type
)
779 fprintf(stderr
, "-");
782 fprintf(stderr
, "!");
785 fprintf(stderr
, "~");
788 fprintf(stderr
, "*");
791 fprintf(stderr
, "&");
794 DEBUG_DisplayExpr(exp
->un
.unop
.exp1
);
797 fprintf(stderr
,"Unexpected expression.\n");
798 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
806 DEBUG_CloneExpr(const struct expr
* exp
)
811 rtn
= (struct expr
*) DBG_alloc(sizeof(struct expr
));
814 * First copy the contents of the expression itself.
822 rtn
->un
.cast
.expr
= DEBUG_CloneExpr(exp
->un
.cast
.expr
);
824 case EXPR_TYPE_REGISTER
:
825 case EXPR_TYPE_US_CONST
:
826 case EXPR_TYPE_CONST
:
828 case EXPR_TYPE_STRING
:
829 rtn
->un
.string
.str
= DBG_strdup(exp
->un
.string
.str
);
831 case EXPR_TYPE_SYMBOL
:
832 rtn
->un
.symbol
.name
= DBG_strdup(exp
->un
.symbol
.name
);
834 case EXPR_TYPE_PSTRUCT
:
835 case EXPR_TYPE_STRUCT
:
836 rtn
->un
.structure
.exp1
= DEBUG_CloneExpr(exp
->un
.structure
.exp1
);
837 rtn
->un
.structure
.element_name
= DBG_strdup(exp
->un
.structure
.element_name
);
840 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
842 rtn
->un
.call
.arg
[i
] = DEBUG_CloneExpr(exp
->un
.call
.arg
[i
]);
844 rtn
->un
.call
.funcname
= DBG_strdup(exp
->un
.call
.funcname
);
846 case EXPR_TYPE_BINOP
:
847 rtn
->un
.binop
.exp1
= DEBUG_CloneExpr(exp
->un
.binop
.exp1
);
848 rtn
->un
.binop
.exp2
= DEBUG_CloneExpr(exp
->un
.binop
.exp2
);
851 rtn
->un
.unop
.exp1
= DEBUG_CloneExpr(exp
->un
.unop
.exp1
);
854 fprintf(stderr
,"Unexpected expression.\n");
855 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
864 * Recursively go through an expression tree and free all memory associated
868 DEBUG_FreeExpr(struct expr
* exp
)
875 DEBUG_FreeExpr(exp
->un
.cast
.expr
);
877 case EXPR_TYPE_REGISTER
:
878 case EXPR_TYPE_US_CONST
:
879 case EXPR_TYPE_CONST
:
881 case EXPR_TYPE_STRING
:
882 DBG_free((char *) exp
->un
.string
.str
);
884 case EXPR_TYPE_SYMBOL
:
885 DBG_free((char *) exp
->un
.symbol
.name
);
887 case EXPR_TYPE_PSTRUCT
:
888 case EXPR_TYPE_STRUCT
:
889 DEBUG_FreeExpr(exp
->un
.structure
.exp1
);
890 DBG_free((char *) exp
->un
.structure
.element_name
);
893 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
895 DEBUG_FreeExpr(exp
->un
.call
.arg
[i
]);
897 DBG_free((char *) exp
->un
.call
.funcname
);
899 case EXPR_TYPE_BINOP
:
900 DEBUG_FreeExpr(exp
->un
.binop
.exp1
);
901 DEBUG_FreeExpr(exp
->un
.binop
.exp2
);
904 DEBUG_FreeExpr(exp
->un
.unop
.exp1
);
907 fprintf(stderr
,"Unexpected expression.\n");
908 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);