Avoid crash in WCMD_run_program when no extension was specified.
[wine] / programs / winedbg / expr.c
1 /*
2  * File expr.c - expression handling for Wine internal debugger.
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include <stdlib.h>
23 #include <string.h>
24 #include "winbase.h"
25 #include "wine/winbase16.h"
26 #include "debugger.h"
27 #include "expr.h"
28
29 #include <stdarg.h>
30
31 struct expr
32 {
33   unsigned int  perm;
34   unsigned int  type:31;
35   union
36   {
37     struct
38     {
39       int value;
40     } constant;
41
42     struct
43     {
44       const char * str;
45     } string;
46
47     struct
48     {
49       unsigned int value;
50     } u_const;
51
52     struct
53     {
54       const char * name;
55     } symbol;
56
57     struct
58     {
59       const char * name;
60     } intvar;
61
62     struct
63     {
64       int unop_type;
65       struct expr * exp1;
66       int             result;
67     } unop;
68
69     struct
70     {
71       int binop_type;
72       int result;
73       struct expr * exp1;
74       struct expr * exp2;
75     } binop;
76
77     struct
78     {
79       struct datatype * cast;
80       struct expr     * expr;
81     } cast;
82
83     struct
84     {
85       struct expr * exp1;
86       const char * element_name;
87       int result;
88     } structure;
89
90     struct
91     {
92       struct expr * base;
93       struct expr * index;
94     } array;
95
96     struct
97     {
98       const char  * funcname;
99       int           nargs;
100       int           result;
101       struct expr * arg[5];
102     } call;
103
104   } un;
105 };
106
107 #define EXPR_TYPE_CONST         0
108 #define EXPR_TYPE_US_CONST      1
109 #define EXPR_TYPE_SYMBOL        2
110 #define EXPR_TYPE_INTVAR        3
111 #define EXPR_TYPE_BINOP         4
112 #define EXPR_TYPE_UNOP          5
113 #define EXPR_TYPE_STRUCT        6
114 #define EXPR_TYPE_PSTRUCT       7
115 #define EXPR_TYPE_ARRAY         8
116 #define EXPR_TYPE_CALL          9
117 #define EXPR_TYPE_STRING        10
118 #define EXPR_TYPE_CAST          11
119
120 static char expr_list[4096];
121 static unsigned int next_expr_free = 0;
122
123 /*
124  * This is how we turn an expression address into the actual value.
125  * This works well in the 32 bit domain - not sure at all about the
126  * 16 bit world.
127  */
128 #define VAL(_exp)       DEBUG_GetExprValue(&_exp, NULL)
129
130 static
131 struct expr *
132 DEBUG_GetFreeExpr(void)
133 {
134   struct expr * rtn;
135
136   rtn =  (struct expr *) &expr_list[next_expr_free];
137
138   next_expr_free += sizeof(struct expr);
139   assert(next_expr_free < sizeof(expr_list));
140
141   return rtn;
142 }
143
144 void
145 DEBUG_FreeExprMem(void)
146 {
147   next_expr_free = 0;
148 }
149
150 struct expr *
151 DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
152 {
153   struct expr * ex;
154
155   ex = DEBUG_GetFreeExpr();
156
157   ex->type        = EXPR_TYPE_CAST;
158   ex->un.cast.cast = dt;
159   ex->un.cast.expr = exp;
160   return ex;
161 }
162
163 struct expr *
164 DEBUG_IntVarExpr(const char* name)
165 {
166   struct expr * ex;
167
168   ex = DEBUG_GetFreeExpr();
169
170   ex->type        = EXPR_TYPE_INTVAR;
171   ex->un.intvar.name = name;
172   return ex;
173 }
174
175 struct expr *
176 DEBUG_SymbolExpr(const char * name)
177 {
178   struct expr * ex;
179
180   ex = DEBUG_GetFreeExpr();
181
182   ex->type        = EXPR_TYPE_SYMBOL;
183   ex->un.symbol.name = name;
184   return ex;
185 }
186
187 struct expr *
188 DEBUG_ConstExpr(int value)
189 {
190   struct expr * ex;
191
192   ex = DEBUG_GetFreeExpr();
193
194   ex->type        = EXPR_TYPE_CONST;
195   ex->un.constant.value = value;
196   return ex;
197 }
198
199 struct expr *
200 DEBUG_StringExpr(const char * str)
201 {
202   struct expr * ex;
203   char * pnt;
204   ex = DEBUG_GetFreeExpr();
205
206   ex->type        = EXPR_TYPE_STRING;
207   ex->un.string.str = str+1;
208   pnt = strrchr(ex->un.string.str, '"');
209   if( pnt != NULL )
210     {
211       *pnt =  '\0';
212     }
213   return ex;
214 }
215
216 struct expr *
217 DEBUG_USConstExpr(unsigned int value)
218 {
219   struct expr * ex;
220
221   ex = DEBUG_GetFreeExpr();
222
223   ex->type           = EXPR_TYPE_CONST;
224   ex->un.u_const.value = value;
225   return ex;
226 }
227
228 struct expr *
229 DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
230 {
231   struct expr * ex;
232
233   ex = DEBUG_GetFreeExpr();
234
235   ex->type           = EXPR_TYPE_BINOP;
236   ex->un.binop.binop_type = operator_type;
237   ex->un.binop.exp1     = exp1;
238   ex->un.binop.exp2     = exp2;
239   return ex;
240 }
241
242 struct expr *
243 DEBUG_UnopExpr(int operator_type, struct expr * exp1)
244 {
245   struct expr * ex;
246
247   ex = DEBUG_GetFreeExpr();
248
249   ex->type           = EXPR_TYPE_UNOP;
250   ex->un.unop.unop_type = operator_type;
251   ex->un.unop.exp1      = exp1;
252   return ex;
253 }
254
255 struct expr *
256 DEBUG_StructExpr(struct expr * exp, const char * element)
257 {
258   struct expr * ex;
259
260   ex = DEBUG_GetFreeExpr();
261
262   ex->type           = EXPR_TYPE_STRUCT;
263   ex->un.structure.exp1 = exp;
264   ex->un.structure.element_name = element;
265   return ex;
266 }
267
268 struct expr *
269 DEBUG_StructPExpr(struct expr * exp, const char * element)
270 {
271   struct expr * ex;
272
273   ex = DEBUG_GetFreeExpr();
274
275   ex->type           = EXPR_TYPE_PSTRUCT;
276   ex->un.structure.exp1 = exp;
277   ex->un.structure.element_name = element;
278   return ex;
279 }
280
281 struct expr *
282 DEBUG_CallExpr(const char * funcname, int nargs, ...)
283 {
284   struct expr * ex;
285   va_list ap;
286   int i;
287
288   ex = DEBUG_GetFreeExpr();
289
290   ex->type           = EXPR_TYPE_CALL;
291   ex->un.call.funcname = funcname;
292   ex->un.call.nargs = nargs;
293
294   va_start(ap, nargs);
295   for(i=0; i < nargs; i++)
296     {
297       ex->un.call.arg[i] = va_arg(ap, struct expr *);
298     }
299   va_end(ap);
300   return ex;
301 }
302
303 DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
304 {
305   DBG_VALUE     rtn;
306   int           i;
307   DBG_VALUE     exp1;
308   DBG_VALUE     exp2;
309   unsigned int  cexp[5];
310   int               scale1;
311   int               scale2;
312   int               scale3;
313   struct datatype * type1;
314   struct datatype * type2;
315
316   rtn.type = NULL;
317   rtn.cookie = DV_INVALID;
318   rtn.addr.off = 0;
319   rtn.addr.seg = 0;
320
321   switch(exp->type)
322     {
323     case EXPR_TYPE_CAST:
324       if (!exp->un.cast.cast)
325       {
326           DEBUG_Printf(DBG_CHN_MESG, "Can't cast to unknown type\n");
327           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
328       }
329       rtn = DEBUG_EvalExpr(exp->un.cast.expr);
330       rtn.type = exp->un.cast.cast;
331       break;
332     case EXPR_TYPE_STRING:
333       rtn.type = DEBUG_GetBasicType(DT_BASIC_STRING);
334       rtn.cookie = DV_HOST;
335       rtn.addr.off = (unsigned int) &exp->un.string.str;
336       rtn.addr.seg = 0;
337       break;
338     case EXPR_TYPE_CONST:
339       rtn.type = DEBUG_GetBasicType(DT_BASIC_CONST_INT);
340       rtn.cookie = DV_HOST;
341       rtn.addr.off = (unsigned int) &exp->un.constant.value;
342       rtn.addr.seg = 0;
343       break;
344     case EXPR_TYPE_US_CONST:
345       rtn.type = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
346       rtn.cookie = DV_HOST;
347       rtn.addr.off = (unsigned int) &exp->un.u_const.value;
348       rtn.addr.seg = 0;
349       break;
350     case EXPR_TYPE_SYMBOL:
351       switch (DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE))
352       {
353       case gsv_found:
354           break;
355       case gsv_unknown:
356           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
357           /* should never be here */
358       case gsv_aborted:
359           RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
360           /* should never be here */
361       }
362       break;
363     case EXPR_TYPE_PSTRUCT:
364       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
365       if( exp1.type == NULL )
366         {
367            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
368         }
369       rtn.cookie = DV_TARGET;
370       rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &rtn.type);
371       if( rtn.type == NULL )
372         {
373           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
374         }
375       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
376                                    &exp->un.structure.result))
377       {
378           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
379           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
380       }
381
382       break;
383     case EXPR_TYPE_STRUCT:
384       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
385       if( exp1.type == NULL )
386       {
387           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
388       }
389       rtn = exp1;
390       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
391                                    &exp->un.structure.result))
392       {
393           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
394           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
395       }
396       break;
397     case EXPR_TYPE_CALL:
398       /*
399        * First, evaluate all of the arguments.  If any of them are not
400        * evaluable, then bail.
401        */
402       for(i=0; i < exp->un.call.nargs; i++)
403         {
404           exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
405           if( exp1.type == NULL )
406             {
407               return rtn;
408             }
409           cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
410         }
411
412       /*
413        * Now look up the address of the function itself.
414        */
415       switch (DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ))
416       {
417       case gsv_found:
418           break;
419       case gsv_unknown:
420           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
421           /* should never be here */
422       case gsv_aborted:
423           RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
424           /* should never be here */
425       }
426
427 #if 0
428       /* FIXME: NEWDBG NIY */
429       /* Anyway, I wonder how this could work depending on the calling order of
430        * the function (cdecl vs pascal for example)
431        */
432       int               (*fptr)();
433
434       fptr = (int (*)()) rtn.addr.off;
435       switch(exp->un.call.nargs)
436         {
437         case 0:
438           exp->un.call.result = (*fptr)();
439           break;
440         case 1:
441           exp->un.call.result = (*fptr)(cexp[0]);
442           break;
443         case 2:
444           exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
445           break;
446         case 3:
447           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
448           break;
449         case 4:
450           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
451           break;
452         case 5:
453           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
454           break;
455         }
456 #else
457       DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
458       /* would need to set up a call to this function, and then restore the current
459        * context afterwards...
460        */
461       exp->un.call.result = 0;
462 #endif
463       rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
464       rtn.cookie = DV_HOST;
465       rtn.addr.off = (unsigned int) &exp->un.call.result;
466
467       break;
468     case EXPR_TYPE_INTVAR:
469       {
470
471          DBG_INTVAR*    div = DEBUG_GetIntVar(exp->un.intvar.name);
472
473          if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
474          rtn.cookie = DV_HOST;
475          rtn.type = div->type;
476          rtn.addr.off = (unsigned int)div->pval;
477          /* EPP FIXME rtn.addr.seg = ?? */
478       }
479       break;
480     case EXPR_TYPE_BINOP:
481       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
482       exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
483       rtn.cookie = DV_HOST;
484       if( exp1.type == NULL || exp2.type == NULL )
485         {
486           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
487         }
488       if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) &&
489           exp2.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
490         {
491           rtn.type = exp1.type;
492         }
493       else
494         {
495           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
496         }
497       rtn.addr.seg = 0;
498       rtn.addr.off = (unsigned int) &exp->un.binop.result;
499       switch(exp->un.binop.binop_type)
500         {
501         case EXP_OP_ADD:
502           type1 = DEBUG_GetPointerType(exp1.type);
503           type2 = DEBUG_GetPointerType(exp2.type);
504           scale1 = 1;
505           scale2 = 1;
506           if( type1 != NULL && type2 != NULL )
507             {
508               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
509             }
510           else if( type1 != NULL )
511             {
512               scale2 = DEBUG_GetObjectSize(type1);
513               rtn.type = exp1.type;
514             }
515           else if( type2 != NULL )
516             {
517               scale1 = DEBUG_GetObjectSize(type2);
518               rtn.type = exp2.type;
519             }
520           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
521           break;
522         case EXP_OP_SUB:
523           type1 = DEBUG_GetPointerType(exp1.type);
524           type2 = DEBUG_GetPointerType(exp2.type);
525           scale1 = 1;
526           scale2 = 1;
527           scale3 = 1;
528           if( type1 != NULL && type2 != NULL )
529             {
530               if( type1 != type2 )
531                 {
532                   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
533                 }
534               scale3 = DEBUG_GetObjectSize(type1);
535             }
536           else if( type1 != NULL )
537             {
538               scale2 = DEBUG_GetObjectSize(type1);
539               rtn.type = exp1.type;
540             }
541
542           else if( type2 != NULL )
543             {
544               scale1 = DEBUG_GetObjectSize(type2);
545               rtn.type = exp2.type;
546             }
547           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
548           break;
549         case EXP_OP_SEG:
550           rtn.cookie = DV_TARGET;
551           rtn.type = NULL;
552           rtn.addr.seg = VAL(exp1);
553           rtn.addr.off = VAL(exp2);
554           break;
555         case EXP_OP_LOR:
556           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
557           break;
558         case EXP_OP_LAND:
559           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
560           break;
561         case EXP_OP_OR:
562           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
563           break;
564         case EXP_OP_AND:
565           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
566           break;
567         case EXP_OP_XOR:
568           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
569           break;
570         case EXP_OP_EQ:
571           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
572           break;
573         case EXP_OP_GT:
574           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
575           break;
576         case EXP_OP_LT:
577           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
578           break;
579         case EXP_OP_GE:
580           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
581           break;
582         case EXP_OP_LE:
583           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
584           break;
585         case EXP_OP_NE:
586           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
587           break;
588         case EXP_OP_SHL:
589           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
590           break;
591         case EXP_OP_SHR:
592           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
593           break;
594         case EXP_OP_MUL:
595           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
596           break;
597         case EXP_OP_DIV:
598           if( VAL(exp2) == 0 )
599             {
600                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
601             }
602           exp->un.binop.result = (VAL(exp1) / VAL(exp2));
603           break;
604         case EXP_OP_REM:
605           if( VAL(exp2) == 0 )
606             {
607                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
608             }
609           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
610           break;
611         case EXP_OP_ARR:
612           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
613           break;
614         default:
615           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
616           break;
617         }
618       break;
619     case EXPR_TYPE_UNOP:
620       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
621       rtn.cookie = DV_HOST;
622       if( exp1.type == NULL )
623         {
624           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
625         }
626       rtn.addr.seg = 0;
627       rtn.addr.off = (unsigned int) &exp->un.unop.result;
628       if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
629         {
630           rtn.type = exp1.type;
631         }
632       else
633         {
634           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
635         }
636       switch(exp->un.unop.unop_type)
637         {
638         case EXP_OP_NEG:
639           exp->un.unop.result = -VAL(exp1);
640           break;
641         case EXP_OP_NOT:
642           exp->un.unop.result = !VAL(exp1);
643           break;
644         case EXP_OP_LNOT:
645           exp->un.unop.result = ~VAL(exp1);
646           break;
647         case EXP_OP_DEREF:
648           /* FIXME: this is currently buggy.
649            * there is no way to tell were the deref:ed value is...
650            * for example:
651            *    x is a pointer to struct s, x being on the stack
652            *            => exp1 is target, result is target
653            *    x is a pointer to struct s, x being optimized into a reg
654            *            => exp1 is host, result is target
655            *    x is a pointer to internal variable x
656            *            => exp1 is host, result is host
657            * so we force DV_TARGET, because dereferencing pointers to
658            * internal variables is very unlikely. a correct fix would be
659            * rather large.
660            */
661           rtn.cookie = DV_TARGET;
662           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
663           if (!rtn.type)
664             {
665               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
666             }
667           break;
668         case EXP_OP_FORCE_DEREF:
669           rtn.cookie = exp1.cookie;
670           rtn.addr.seg = exp1.addr.seg;
671           if (exp1.cookie == DV_TARGET)
672              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
673           else
674              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
675           break;
676         case EXP_OP_ADDR:
677           /* FIXME: even for a 16 bit entity ? */
678           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
679           exp->un.unop.result = exp1.addr.off;
680           break;
681         default:
682            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
683         }
684       break;
685     default:
686       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
687       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
688       break;
689     }
690
691   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
692
693   return rtn;
694 }
695
696
697 int
698 DEBUG_DisplayExpr(const struct expr * exp)
699 {
700   int           i;
701
702   switch(exp->type)
703     {
704     case EXPR_TYPE_CAST:
705       DEBUG_Printf(DBG_CHN_MESG, "((");
706       DEBUG_PrintTypeCast(exp->un.cast.cast);
707       DEBUG_Printf(DBG_CHN_MESG, ")");
708       DEBUG_DisplayExpr(exp->un.cast.expr);
709       DEBUG_Printf(DBG_CHN_MESG, ")");
710       break;
711     case EXPR_TYPE_INTVAR:
712       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
713       break;
714     case EXPR_TYPE_US_CONST:
715       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
716       break;
717     case EXPR_TYPE_CONST:
718       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
719       break;
720     case EXPR_TYPE_STRING:
721       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str);
722       break;
723     case EXPR_TYPE_SYMBOL:
724       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
725       break;
726     case EXPR_TYPE_PSTRUCT:
727       DEBUG_DisplayExpr(exp->un.structure.exp1);
728       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
729       break;
730     case EXPR_TYPE_STRUCT:
731       DEBUG_DisplayExpr(exp->un.structure.exp1);
732       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
733       break;
734     case EXPR_TYPE_CALL:
735       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
736       for(i=0; i < exp->un.call.nargs; i++)
737         {
738           DEBUG_DisplayExpr(exp->un.call.arg[i]);
739           if( i != exp->un.call.nargs - 1 )
740             {
741               DEBUG_Printf(DBG_CHN_MESG, ", ");
742             }
743         }
744       DEBUG_Printf(DBG_CHN_MESG, ")");
745       break;
746     case EXPR_TYPE_BINOP:
747       DEBUG_Printf(DBG_CHN_MESG, "( ");
748       DEBUG_DisplayExpr(exp->un.binop.exp1);
749       switch(exp->un.binop.binop_type)
750         {
751         case EXP_OP_ADD:
752           DEBUG_Printf(DBG_CHN_MESG, " + ");
753           break;
754         case EXP_OP_SUB:
755           DEBUG_Printf(DBG_CHN_MESG, " - ");
756           break;
757         case EXP_OP_SEG:
758           DEBUG_Printf(DBG_CHN_MESG, ":");
759           break;
760         case EXP_OP_LOR:
761           DEBUG_Printf(DBG_CHN_MESG, " || ");
762           break;
763         case EXP_OP_LAND:
764           DEBUG_Printf(DBG_CHN_MESG, " && ");
765           break;
766         case EXP_OP_OR:
767           DEBUG_Printf(DBG_CHN_MESG, " | ");
768           break;
769         case EXP_OP_AND:
770           DEBUG_Printf(DBG_CHN_MESG, " & ");
771           break;
772         case EXP_OP_XOR:
773           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
774           break;
775         case EXP_OP_EQ:
776           DEBUG_Printf(DBG_CHN_MESG, " == ");
777           break;
778         case EXP_OP_GT:
779           DEBUG_Printf(DBG_CHN_MESG, " > ");
780           break;
781         case EXP_OP_LT:
782           DEBUG_Printf(DBG_CHN_MESG, " < ");
783           break;
784         case EXP_OP_GE:
785           DEBUG_Printf(DBG_CHN_MESG, " >= ");
786           break;
787         case EXP_OP_LE:
788           DEBUG_Printf(DBG_CHN_MESG, " <= ");
789           break;
790         case EXP_OP_NE:
791           DEBUG_Printf(DBG_CHN_MESG, " != ");
792           break;
793         case EXP_OP_SHL:
794           DEBUG_Printf(DBG_CHN_MESG, " << ");
795           break;
796         case EXP_OP_SHR:
797           DEBUG_Printf(DBG_CHN_MESG, " >> ");
798           break;
799         case EXP_OP_MUL:
800           DEBUG_Printf(DBG_CHN_MESG, " * ");
801           break;
802         case EXP_OP_DIV:
803           DEBUG_Printf(DBG_CHN_MESG, " / ");
804           break;
805         case EXP_OP_REM:
806           DEBUG_Printf(DBG_CHN_MESG, " %% ");
807           break;
808         case EXP_OP_ARR:
809           DEBUG_Printf(DBG_CHN_MESG, "[");
810           break;
811         default:
812           break;
813         }
814       DEBUG_DisplayExpr(exp->un.binop.exp2);
815       if( exp->un.binop.binop_type == EXP_OP_ARR )
816         {
817           DEBUG_Printf(DBG_CHN_MESG, "]");
818         }
819       DEBUG_Printf(DBG_CHN_MESG, " )");
820       break;
821     case EXPR_TYPE_UNOP:
822       switch(exp->un.unop.unop_type)
823         {
824         case EXP_OP_NEG:
825           DEBUG_Printf(DBG_CHN_MESG, "-");
826           break;
827         case EXP_OP_NOT:
828           DEBUG_Printf(DBG_CHN_MESG, "!");
829           break;
830         case EXP_OP_LNOT:
831           DEBUG_Printf(DBG_CHN_MESG, "~");
832           break;
833         case EXP_OP_DEREF:
834           DEBUG_Printf(DBG_CHN_MESG, "*");
835           break;
836         case EXP_OP_ADDR:
837           DEBUG_Printf(DBG_CHN_MESG, "&");
838           break;
839         }
840       DEBUG_DisplayExpr(exp->un.unop.exp1);
841       break;
842     default:
843       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
844       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
845       break;
846     }
847
848   return TRUE;
849 }
850
851 struct expr *
852 DEBUG_CloneExpr(const struct expr * exp)
853 {
854   int           i;
855   struct expr * rtn;
856
857   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
858
859   /*
860    * First copy the contents of the expression itself.
861    */
862   *rtn = *exp;
863
864
865   switch(exp->type)
866     {
867     case EXPR_TYPE_CAST:
868       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
869       break;
870     case EXPR_TYPE_INTVAR:
871       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
872       break;
873     case EXPR_TYPE_US_CONST:
874     case EXPR_TYPE_CONST:
875       break;
876     case EXPR_TYPE_STRING:
877       rtn->un.string.str = DBG_strdup(exp->un.string.str);
878       break;
879     case EXPR_TYPE_SYMBOL:
880       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
881       break;
882     case EXPR_TYPE_PSTRUCT:
883     case EXPR_TYPE_STRUCT:
884       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
885       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
886       break;
887     case EXPR_TYPE_CALL:
888       for(i=0; i < exp->un.call.nargs; i++)
889         {
890           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
891         }
892       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
893       break;
894     case EXPR_TYPE_BINOP:
895       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
896       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
897       break;
898     case EXPR_TYPE_UNOP:
899       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
900       break;
901     default:
902       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
903       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
904       break;
905     }
906
907   return rtn;
908 }
909
910
911 /*
912  * Recursively go through an expression tree and free all memory associated
913  * with it.
914  */
915 int
916 DEBUG_FreeExpr(struct expr * exp)
917 {
918   int i;
919
920   switch(exp->type)
921     {
922     case EXPR_TYPE_CAST:
923       DEBUG_FreeExpr(exp->un.cast.expr);
924       break;
925     case EXPR_TYPE_INTVAR:
926       DBG_free((char *) exp->un.intvar.name);
927       break;
928     case EXPR_TYPE_US_CONST:
929     case EXPR_TYPE_CONST:
930       break;
931     case EXPR_TYPE_STRING:
932       DBG_free((char *) exp->un.string.str);
933       break;
934     case EXPR_TYPE_SYMBOL:
935       DBG_free((char *) exp->un.symbol.name);
936       break;
937     case EXPR_TYPE_PSTRUCT:
938     case EXPR_TYPE_STRUCT:
939       DEBUG_FreeExpr(exp->un.structure.exp1);
940       DBG_free((char *) exp->un.structure.element_name);
941       break;
942     case EXPR_TYPE_CALL:
943       for(i=0; i < exp->un.call.nargs; i++)
944         {
945           DEBUG_FreeExpr(exp->un.call.arg[i]);
946         }
947       DBG_free((char *) exp->un.call.funcname);
948       break;
949     case EXPR_TYPE_BINOP:
950       DEBUG_FreeExpr(exp->un.binop.exp1);
951       DEBUG_FreeExpr(exp->un.binop.exp2);
952       break;
953     case EXPR_TYPE_UNOP:
954       DEBUG_FreeExpr(exp->un.unop.exp1);
955       break;
956     default:
957       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
958       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
959       break;
960     }
961
962   DBG_free(exp);
963   return TRUE;
964 }