Correct initial display of file listing.
[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       rtn = DEBUG_EvalExpr(exp->un.cast.expr);
325       rtn.type = exp->un.cast.cast;
326       if (!rtn.type)
327       {
328           DEBUG_Printf(DBG_CHN_MESG, "Can't cast to unknown type\n");
329           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
330       }
331       if (DEBUG_GetType(rtn.type) == DT_POINTER)
332          rtn.cookie = DV_TARGET;
333       break;
334     case EXPR_TYPE_STRING:
335       rtn.type = DEBUG_GetBasicType(DT_BASIC_STRING);
336       rtn.cookie = DV_HOST;
337       rtn.addr.off = (unsigned int) &exp->un.string.str;
338       rtn.addr.seg = 0;
339       break;
340     case EXPR_TYPE_CONST:
341       rtn.type = DEBUG_GetBasicType(DT_BASIC_CONST_INT);
342       rtn.cookie = DV_HOST;
343       rtn.addr.off = (unsigned int) &exp->un.constant.value;
344       rtn.addr.seg = 0;
345       break;
346     case EXPR_TYPE_US_CONST:
347       rtn.type = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
348       rtn.cookie = DV_HOST;
349       rtn.addr.off = (unsigned int) &exp->un.u_const.value;
350       rtn.addr.seg = 0;
351       break;
352     case EXPR_TYPE_SYMBOL:
353       switch (DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE))
354       {
355       case gsv_found:
356           break;
357       case gsv_unknown:
358           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
359           /* should never be here */
360       case gsv_aborted:
361           RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
362           /* should never be here */
363       }
364       break;
365     case EXPR_TYPE_PSTRUCT:
366       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
367       if( exp1.type == NULL )
368         {
369            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
370         }
371       rtn.cookie = DV_TARGET;
372       rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &rtn.type);
373       if( rtn.type == NULL )
374         {
375           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
376         }
377       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
378                                    &exp->un.structure.result))
379       {
380           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
381           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
382       }
383
384       break;
385     case EXPR_TYPE_STRUCT:
386       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
387       if( exp1.type == NULL )
388       {
389           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
390       }
391       rtn = exp1;
392       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
393                                    &exp->un.structure.result))
394       {
395           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
396           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
397       }
398       break;
399     case EXPR_TYPE_CALL:
400       /*
401        * First, evaluate all of the arguments.  If any of them are not
402        * evaluable, then bail.
403        */
404       for(i=0; i < exp->un.call.nargs; i++)
405         {
406           exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
407           if( exp1.type == NULL )
408             {
409               return rtn;
410             }
411           cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
412         }
413
414       /*
415        * Now look up the address of the function itself.
416        */
417       switch (DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ))
418       {
419       case gsv_found:
420           break;
421       case gsv_unknown:
422           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
423           /* should never be here */
424       case gsv_aborted:
425           RaiseException(DEBUG_STATUS_ABORT, 0, 0, NULL);
426           /* should never be here */
427       }
428
429 #if 0
430       /* FIXME: NEWDBG NIY */
431       /* Anyway, I wonder how this could work depending on the calling order of
432        * the function (cdecl vs pascal for example)
433        */
434       int               (*fptr)();
435
436       fptr = (int (*)()) rtn.addr.off;
437       switch(exp->un.call.nargs)
438         {
439         case 0:
440           exp->un.call.result = (*fptr)();
441           break;
442         case 1:
443           exp->un.call.result = (*fptr)(cexp[0]);
444           break;
445         case 2:
446           exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
447           break;
448         case 3:
449           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
450           break;
451         case 4:
452           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
453           break;
454         case 5:
455           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
456           break;
457         }
458 #else
459       DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
460       /* would need to set up a call to this function, and then restore the current
461        * context afterwards...
462        */
463       exp->un.call.result = 0;
464 #endif
465       rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
466       rtn.cookie = DV_HOST;
467       rtn.addr.off = (unsigned int) &exp->un.call.result;
468
469       break;
470     case EXPR_TYPE_INTVAR:
471       {
472
473          DBG_INTVAR*    div = DEBUG_GetIntVar(exp->un.intvar.name);
474
475          if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
476          rtn.cookie = DV_HOST;
477          rtn.type = div->type;
478          rtn.addr.off = (unsigned int)div->pval;
479          /* EPP FIXME rtn.addr.seg = ?? */
480       }
481       break;
482     case EXPR_TYPE_BINOP:
483       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
484       exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
485       rtn.cookie = DV_HOST;
486       if( exp1.type == NULL || exp2.type == NULL )
487         {
488           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
489         }
490       if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) &&
491           exp2.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
492         {
493           rtn.type = exp1.type;
494         }
495       else
496         {
497           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
498         }
499       rtn.addr.seg = 0;
500       rtn.addr.off = (unsigned int) &exp->un.binop.result;
501       switch(exp->un.binop.binop_type)
502         {
503         case EXP_OP_ADD:
504           type1 = DEBUG_GetPointerType(exp1.type);
505           type2 = DEBUG_GetPointerType(exp2.type);
506           scale1 = 1;
507           scale2 = 1;
508           if( type1 != NULL && type2 != NULL )
509             {
510               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
511             }
512           else if( type1 != NULL )
513             {
514               scale2 = DEBUG_GetObjectSize(type1);
515               rtn.type = exp1.type;
516             }
517           else if( type2 != NULL )
518             {
519               scale1 = DEBUG_GetObjectSize(type2);
520               rtn.type = exp2.type;
521             }
522           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
523           break;
524         case EXP_OP_SUB:
525           type1 = DEBUG_GetPointerType(exp1.type);
526           type2 = DEBUG_GetPointerType(exp2.type);
527           scale1 = 1;
528           scale2 = 1;
529           scale3 = 1;
530           if( type1 != NULL && type2 != NULL )
531             {
532               if( type1 != type2 )
533                 {
534                   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
535                 }
536               scale3 = DEBUG_GetObjectSize(type1);
537             }
538           else if( type1 != NULL )
539             {
540               scale2 = DEBUG_GetObjectSize(type1);
541               rtn.type = exp1.type;
542             }
543
544           else if( type2 != NULL )
545             {
546               scale1 = DEBUG_GetObjectSize(type2);
547               rtn.type = exp2.type;
548             }
549           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
550           break;
551         case EXP_OP_SEG:
552           rtn.cookie = DV_TARGET;
553           rtn.type = NULL;
554           rtn.addr.seg = VAL(exp1);
555           rtn.addr.off = VAL(exp2);
556           break;
557         case EXP_OP_LOR:
558           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
559           break;
560         case EXP_OP_LAND:
561           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
562           break;
563         case EXP_OP_OR:
564           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
565           break;
566         case EXP_OP_AND:
567           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
568           break;
569         case EXP_OP_XOR:
570           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
571           break;
572         case EXP_OP_EQ:
573           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
574           break;
575         case EXP_OP_GT:
576           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
577           break;
578         case EXP_OP_LT:
579           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
580           break;
581         case EXP_OP_GE:
582           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
583           break;
584         case EXP_OP_LE:
585           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
586           break;
587         case EXP_OP_NE:
588           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
589           break;
590         case EXP_OP_SHL:
591           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
592           break;
593         case EXP_OP_SHR:
594           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
595           break;
596         case EXP_OP_MUL:
597           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
598           break;
599         case EXP_OP_DIV:
600           if( VAL(exp2) == 0 )
601             {
602                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
603             }
604           exp->un.binop.result = (VAL(exp1) / VAL(exp2));
605           break;
606         case EXP_OP_REM:
607           if( VAL(exp2) == 0 )
608             {
609                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
610             }
611           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
612           break;
613         case EXP_OP_ARR:
614           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
615           break;
616         default:
617           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
618           break;
619         }
620       break;
621     case EXPR_TYPE_UNOP:
622       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
623       rtn.cookie = DV_HOST;
624       if( exp1.type == NULL )
625         {
626           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
627         }
628       rtn.addr.seg = 0;
629       rtn.addr.off = (unsigned int) &exp->un.unop.result;
630       if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
631         {
632           rtn.type = exp1.type;
633         }
634       else
635         {
636           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
637         }
638       switch(exp->un.unop.unop_type)
639         {
640         case EXP_OP_NEG:
641           exp->un.unop.result = -VAL(exp1);
642           break;
643         case EXP_OP_NOT:
644           exp->un.unop.result = !VAL(exp1);
645           break;
646         case EXP_OP_LNOT:
647           exp->un.unop.result = ~VAL(exp1);
648           break;
649         case EXP_OP_DEREF:
650           /* FIXME: this is currently buggy.
651            * there is no way to tell were the deref:ed value is...
652            * for example:
653            *    x is a pointer to struct s, x being on the stack
654            *            => exp1 is target, result is target
655            *    x is a pointer to struct s, x being optimized into a reg
656            *            => exp1 is host, result is target
657            *    x is a pointer to internal variable x
658            *            => exp1 is host, result is host
659            * so we force DV_TARGET, because dereferencing pointers to
660            * internal variables is very unlikely. a correct fix would be
661            * rather large.
662            */
663           rtn.cookie = DV_TARGET;
664           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
665           if (!rtn.type)
666             {
667               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
668             }
669           break;
670         case EXP_OP_FORCE_DEREF:
671           rtn.cookie = exp1.cookie;
672           rtn.addr.seg = exp1.addr.seg;
673           if (exp1.cookie == DV_TARGET)
674              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
675           else
676              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
677           break;
678         case EXP_OP_ADDR:
679           /* FIXME: even for a 16 bit entity ? */
680           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
681           exp->un.unop.result = exp1.addr.off;
682           break;
683         default:
684            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
685         }
686       break;
687     default:
688       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
689       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
690       break;
691     }
692
693   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
694
695   return rtn;
696 }
697
698
699 int
700 DEBUG_DisplayExpr(const struct expr * exp)
701 {
702   int           i;
703
704   switch(exp->type)
705     {
706     case EXPR_TYPE_CAST:
707       DEBUG_Printf(DBG_CHN_MESG, "((");
708       DEBUG_PrintTypeCast(exp->un.cast.cast);
709       DEBUG_Printf(DBG_CHN_MESG, ")");
710       DEBUG_DisplayExpr(exp->un.cast.expr);
711       DEBUG_Printf(DBG_CHN_MESG, ")");
712       break;
713     case EXPR_TYPE_INTVAR:
714       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
715       break;
716     case EXPR_TYPE_US_CONST:
717       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
718       break;
719     case EXPR_TYPE_CONST:
720       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
721       break;
722     case EXPR_TYPE_STRING:
723       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str);
724       break;
725     case EXPR_TYPE_SYMBOL:
726       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
727       break;
728     case EXPR_TYPE_PSTRUCT:
729       DEBUG_DisplayExpr(exp->un.structure.exp1);
730       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
731       break;
732     case EXPR_TYPE_STRUCT:
733       DEBUG_DisplayExpr(exp->un.structure.exp1);
734       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
735       break;
736     case EXPR_TYPE_CALL:
737       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
738       for(i=0; i < exp->un.call.nargs; i++)
739         {
740           DEBUG_DisplayExpr(exp->un.call.arg[i]);
741           if( i != exp->un.call.nargs - 1 )
742             {
743               DEBUG_Printf(DBG_CHN_MESG, ", ");
744             }
745         }
746       DEBUG_Printf(DBG_CHN_MESG, ")");
747       break;
748     case EXPR_TYPE_BINOP:
749       DEBUG_Printf(DBG_CHN_MESG, "( ");
750       DEBUG_DisplayExpr(exp->un.binop.exp1);
751       switch(exp->un.binop.binop_type)
752         {
753         case EXP_OP_ADD:
754           DEBUG_Printf(DBG_CHN_MESG, " + ");
755           break;
756         case EXP_OP_SUB:
757           DEBUG_Printf(DBG_CHN_MESG, " - ");
758           break;
759         case EXP_OP_SEG:
760           DEBUG_Printf(DBG_CHN_MESG, ":");
761           break;
762         case EXP_OP_LOR:
763           DEBUG_Printf(DBG_CHN_MESG, " || ");
764           break;
765         case EXP_OP_LAND:
766           DEBUG_Printf(DBG_CHN_MESG, " && ");
767           break;
768         case EXP_OP_OR:
769           DEBUG_Printf(DBG_CHN_MESG, " | ");
770           break;
771         case EXP_OP_AND:
772           DEBUG_Printf(DBG_CHN_MESG, " & ");
773           break;
774         case EXP_OP_XOR:
775           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
776           break;
777         case EXP_OP_EQ:
778           DEBUG_Printf(DBG_CHN_MESG, " == ");
779           break;
780         case EXP_OP_GT:
781           DEBUG_Printf(DBG_CHN_MESG, " > ");
782           break;
783         case EXP_OP_LT:
784           DEBUG_Printf(DBG_CHN_MESG, " < ");
785           break;
786         case EXP_OP_GE:
787           DEBUG_Printf(DBG_CHN_MESG, " >= ");
788           break;
789         case EXP_OP_LE:
790           DEBUG_Printf(DBG_CHN_MESG, " <= ");
791           break;
792         case EXP_OP_NE:
793           DEBUG_Printf(DBG_CHN_MESG, " != ");
794           break;
795         case EXP_OP_SHL:
796           DEBUG_Printf(DBG_CHN_MESG, " << ");
797           break;
798         case EXP_OP_SHR:
799           DEBUG_Printf(DBG_CHN_MESG, " >> ");
800           break;
801         case EXP_OP_MUL:
802           DEBUG_Printf(DBG_CHN_MESG, " * ");
803           break;
804         case EXP_OP_DIV:
805           DEBUG_Printf(DBG_CHN_MESG, " / ");
806           break;
807         case EXP_OP_REM:
808           DEBUG_Printf(DBG_CHN_MESG, " %% ");
809           break;
810         case EXP_OP_ARR:
811           DEBUG_Printf(DBG_CHN_MESG, "[");
812           break;
813         default:
814           break;
815         }
816       DEBUG_DisplayExpr(exp->un.binop.exp2);
817       if( exp->un.binop.binop_type == EXP_OP_ARR )
818         {
819           DEBUG_Printf(DBG_CHN_MESG, "]");
820         }
821       DEBUG_Printf(DBG_CHN_MESG, " )");
822       break;
823     case EXPR_TYPE_UNOP:
824       switch(exp->un.unop.unop_type)
825         {
826         case EXP_OP_NEG:
827           DEBUG_Printf(DBG_CHN_MESG, "-");
828           break;
829         case EXP_OP_NOT:
830           DEBUG_Printf(DBG_CHN_MESG, "!");
831           break;
832         case EXP_OP_LNOT:
833           DEBUG_Printf(DBG_CHN_MESG, "~");
834           break;
835         case EXP_OP_DEREF:
836           DEBUG_Printf(DBG_CHN_MESG, "*");
837           break;
838         case EXP_OP_ADDR:
839           DEBUG_Printf(DBG_CHN_MESG, "&");
840           break;
841         }
842       DEBUG_DisplayExpr(exp->un.unop.exp1);
843       break;
844     default:
845       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
846       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
847       break;
848     }
849
850   return TRUE;
851 }
852
853 struct expr *
854 DEBUG_CloneExpr(const struct expr * exp)
855 {
856   int           i;
857   struct expr * rtn;
858
859   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
860
861   /*
862    * First copy the contents of the expression itself.
863    */
864   *rtn = *exp;
865
866
867   switch(exp->type)
868     {
869     case EXPR_TYPE_CAST:
870       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
871       break;
872     case EXPR_TYPE_INTVAR:
873       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
874       break;
875     case EXPR_TYPE_US_CONST:
876     case EXPR_TYPE_CONST:
877       break;
878     case EXPR_TYPE_STRING:
879       rtn->un.string.str = DBG_strdup(exp->un.string.str);
880       break;
881     case EXPR_TYPE_SYMBOL:
882       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
883       break;
884     case EXPR_TYPE_PSTRUCT:
885     case EXPR_TYPE_STRUCT:
886       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
887       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
888       break;
889     case EXPR_TYPE_CALL:
890       for(i=0; i < exp->un.call.nargs; i++)
891         {
892           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
893         }
894       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
895       break;
896     case EXPR_TYPE_BINOP:
897       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
898       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
899       break;
900     case EXPR_TYPE_UNOP:
901       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
902       break;
903     default:
904       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
905       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
906       break;
907     }
908
909   return rtn;
910 }
911
912
913 /*
914  * Recursively go through an expression tree and free all memory associated
915  * with it.
916  */
917 int
918 DEBUG_FreeExpr(struct expr * exp)
919 {
920   int i;
921
922   switch(exp->type)
923     {
924     case EXPR_TYPE_CAST:
925       DEBUG_FreeExpr(exp->un.cast.expr);
926       break;
927     case EXPR_TYPE_INTVAR:
928       DBG_free((char *) exp->un.intvar.name);
929       break;
930     case EXPR_TYPE_US_CONST:
931     case EXPR_TYPE_CONST:
932       break;
933     case EXPR_TYPE_STRING:
934       DBG_free((char *) exp->un.string.str);
935       break;
936     case EXPR_TYPE_SYMBOL:
937       DBG_free((char *) exp->un.symbol.name);
938       break;
939     case EXPR_TYPE_PSTRUCT:
940     case EXPR_TYPE_STRUCT:
941       DEBUG_FreeExpr(exp->un.structure.exp1);
942       DBG_free((char *) exp->un.structure.element_name);
943       break;
944     case EXPR_TYPE_CALL:
945       for(i=0; i < exp->un.call.nargs; i++)
946         {
947           DEBUG_FreeExpr(exp->un.call.arg[i]);
948         }
949       DBG_free((char *) exp->un.call.funcname);
950       break;
951     case EXPR_TYPE_BINOP:
952       DEBUG_FreeExpr(exp->un.binop.exp1);
953       DEBUG_FreeExpr(exp->un.binop.exp2);
954       break;
955     case EXPR_TYPE_UNOP:
956       DEBUG_FreeExpr(exp->un.unop.exp1);
957       break;
958     default:
959       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
960       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
961       break;
962     }
963
964   DBG_free(exp);
965   return TRUE;
966 }