Made the winedbg an external and WineLib program.
[wine] / debugger / expr.c
1 /*
2  * File expr.c - expression handling for Wine internal debugger.
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  *
6  */
7
8 #include "config.h"
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "winbase.h"
13 #include "wine/winbase16.h"
14 #include "task.h"
15 #include "debugger.h"
16 #include "expr.h"
17
18 #include <stdarg.h>
19
20 struct expr
21 {
22   unsigned int  perm;
23   unsigned int  type:31;
24   union
25   {
26     struct
27     {
28       int value;
29     } constant;
30
31     struct
32     {
33       const char * str;
34     } string;
35
36     struct
37     {
38       unsigned int value;
39     } u_const;
40
41     struct
42     {
43       const char * name;
44     } symbol;
45
46     struct
47     {
48       enum debug_regs reg;
49       int             result;
50     } rgister;
51
52     struct
53     {
54       int unop_type;
55       struct expr * exp1;
56       int             result;
57     } unop;
58
59     struct
60     {
61       int binop_type;
62       int result;
63       struct expr * exp1;
64       struct expr * exp2;
65     } binop;
66
67     struct
68     {
69       struct datatype * cast;
70       struct expr     * expr;
71     } cast;
72
73     struct
74     {
75       struct expr * exp1;
76       const char * element_name;
77       int result;
78     } structure;
79
80     struct
81     {
82       struct expr * base;
83       struct expr * index;
84     } array;
85
86     struct
87     {
88       const char  * funcname;
89       int           nargs;
90       int           result;
91       struct expr * arg[5];
92     } call;
93
94   } un;
95 };
96
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
109
110 static char expr_list[4096];
111 static int next_expr_free = 0;
112
113 /*
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
116  * 16 bit world.
117  */
118 #define VAL(_exp)       DEBUG_GetExprValue(&_exp, NULL)
119
120 static
121 struct expr *
122 DEBUG_GetFreeExpr(void)
123 {
124   struct expr * rtn;
125
126   rtn =  (struct expr *) &expr_list[next_expr_free];
127
128   next_expr_free += sizeof(struct expr);
129   assert(next_expr_free < sizeof(expr_list));
130
131   return rtn;
132 }
133
134 void
135 DEBUG_FreeExprMem(void)
136 {
137   next_expr_free = 0;
138 }
139
140 struct expr *
141 DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
142 {
143   struct expr * ex;
144
145   ex = DEBUG_GetFreeExpr();
146
147   ex->type        = EXPR_TYPE_CAST;
148   ex->un.cast.cast = dt;
149   ex->un.cast.expr = exp;
150   return ex;
151 }
152
153 struct expr *
154 DEBUG_RegisterExpr(enum debug_regs regno)
155 {
156   struct expr * ex;
157
158   ex = DEBUG_GetFreeExpr();
159
160   ex->type        = EXPR_TYPE_REGISTER;
161   ex->un.rgister.reg = regno;
162   return ex;
163 }
164
165 struct expr *
166 DEBUG_SymbolExpr(const char * name)
167 {
168   struct expr * ex;
169
170   ex = DEBUG_GetFreeExpr();
171
172   ex->type        = EXPR_TYPE_SYMBOL;
173   ex->un.symbol.name = name;
174   return ex;
175 }
176
177 struct expr *
178 DEBUG_ConstExpr(int value)
179 {
180   struct expr * ex;
181
182   ex = DEBUG_GetFreeExpr();
183
184   ex->type        = EXPR_TYPE_CONST;
185   ex->un.constant.value = value;
186   return ex;
187 }
188
189 struct expr *
190 DEBUG_StringExpr(const char * str)
191 {
192   struct expr * ex;
193   char * pnt;
194   ex = DEBUG_GetFreeExpr();
195
196   ex->type        = EXPR_TYPE_STRING;
197   ex->un.string.str = str+1;
198   pnt = strrchr(ex->un.string.str, '"');
199   if( pnt != NULL )
200     {
201       *pnt =  '\0';
202     }
203   return ex;
204 }
205
206 struct expr *
207 DEBUG_USConstExpr(unsigned int value)
208 {
209   struct expr * ex;
210
211   ex = DEBUG_GetFreeExpr();
212
213   ex->type           = EXPR_TYPE_CONST;
214   ex->un.u_const.value = value;
215   return ex;
216 }
217
218 struct expr *
219 DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
220 {
221   struct expr * ex;
222
223   ex = DEBUG_GetFreeExpr();
224
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;
229   return ex;
230 }
231
232 struct expr *
233 DEBUG_UnopExpr(int operator_type, struct expr * exp1)
234 {
235   struct expr * ex;
236
237   ex = DEBUG_GetFreeExpr();
238
239   ex->type           = EXPR_TYPE_UNOP;
240   ex->un.unop.unop_type = operator_type;
241   ex->un.unop.exp1      = exp1;
242   return ex;
243 }
244
245 struct expr *
246 DEBUG_StructExpr(struct expr * exp, const char * element)
247 {
248   struct expr * ex;
249
250   ex = DEBUG_GetFreeExpr();
251
252   ex->type           = EXPR_TYPE_STRUCT;
253   ex->un.structure.exp1 = exp;
254   ex->un.structure.element_name = element;
255   return ex;
256 }
257
258 struct expr *
259 DEBUG_StructPExpr(struct expr * exp, const char * element)
260 {
261   struct expr * ex;
262
263   ex = DEBUG_GetFreeExpr();
264
265   ex->type           = EXPR_TYPE_PSTRUCT;
266   ex->un.structure.exp1 = exp;
267   ex->un.structure.element_name = element;
268   return ex;
269 }
270
271 struct expr *
272 DEBUG_CallExpr(const char * funcname, int nargs, ...)
273 {
274   struct expr * ex;
275   va_list ap;
276   int i;
277
278   ex = DEBUG_GetFreeExpr();
279
280   ex->type           = EXPR_TYPE_CALL;
281   ex->un.call.funcname = funcname;
282   ex->un.call.nargs = nargs;
283
284   va_start(ap, nargs);
285   for(i=0; i < nargs; i++)
286     {
287       ex->un.call.arg[i] = va_arg(ap, struct expr *);
288     }
289   va_end(ap);
290   return ex;
291 }
292
293 DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
294 {
295   DBG_VALUE     rtn;
296   int           i;
297   DBG_VALUE     exp1;
298   DBG_VALUE     exp2;
299   unsigned int  cexp[5];
300   int               scale1;
301   int               scale2;
302   int               scale3;
303   struct datatype * type1;
304   struct datatype * type2;
305
306   rtn.type = NULL;
307   rtn.addr.off = 0;
308   rtn.addr.seg = 0;
309
310   switch(exp->type)
311     {
312     case EXPR_TYPE_CAST:
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;
317       break;
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;
322       rtn.addr.seg = 0;
323       break;
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;
328       rtn.addr.seg = 0;
329       break;
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;
334       rtn.addr.seg = 0;
335       break;
336     case EXPR_TYPE_SYMBOL:
337       if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
338         {    
339            RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
340         }
341       break;
342     case EXPR_TYPE_PSTRUCT:
343       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
344       if( exp1.type == NULL )
345         {
346            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
347         }
348       rtn.cookie = DV_TARGET;
349       rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &type1);
350       if( type1 == NULL )
351         {
352           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
353         }
354       rtn.type = type1;
355       DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
356                               &exp->un.structure.result);
357       break;
358     case EXPR_TYPE_STRUCT:
359       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
360       if( exp1.type == NULL )
361         {
362           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
363         }
364       rtn = exp1;
365       DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
366                               &exp->un.structure.result);
367       break;
368     case EXPR_TYPE_CALL:
369       /*
370        * First, evaluate all of the arguments.  If any of them are not
371        * evaluable, then bail.
372        */
373       for(i=0; i < exp->un.call.nargs; i++)
374         {
375           exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
376           if( exp1.type == NULL )
377             {
378               return rtn;
379             }
380           cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
381         }
382
383       /*
384        * Now look up the address of the function itself.
385        */
386       if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
387         {
388           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
389         }
390
391 #if 0
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)
395        */
396       int               (*fptr)();
397
398       fptr = (int (*)()) rtn.addr.off;
399       switch(exp->un.call.nargs)
400         {
401         case 0:
402           exp->un.call.result = (*fptr)();
403           break;
404         case 1:
405           exp->un.call.result = (*fptr)(cexp[0]);
406           break;
407         case 2:
408           exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
409           break;
410         case 3:
411           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
412           break;
413         case 4:
414           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
415           break;
416         case 5:
417           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
418           break;
419         }
420 #else
421       DEBUG_Printf(DBG_CHN_MESG, "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...
424        */
425       exp->un.call.result = 0;
426 #endif
427       rtn.type = DEBUG_TypeInt;
428       rtn.cookie = DV_HOST;
429       rtn.addr.off = (unsigned int) &exp->un.call.result;
430
431       break;
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;
437 #ifdef __i386__
438       if( exp->un.rgister.reg == REG_EIP )
439           rtn.addr.seg = DEBUG_context.SegCs;
440       else
441           rtn.addr.seg = DEBUG_context.SegDs;
442 #endif
443       DEBUG_FixAddress( &rtn.addr, 0 );
444       break;
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 )
450         {
451           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
452         }
453       if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
454         {
455           rtn.type = exp1.type;
456         }
457       else
458         {
459           rtn.type = DEBUG_TypeInt;
460         }
461       rtn.addr.seg = 0;
462       rtn.addr.off = (unsigned int) &exp->un.binop.result;
463       switch(exp->un.binop.binop_type)
464         {
465         case EXP_OP_ADD:
466           type1 = DEBUG_GetPointerType(exp1.type);
467           type2 = DEBUG_GetPointerType(exp2.type);
468           scale1 = 1;
469           scale2 = 1;
470           if( type1 != NULL && type2 != NULL )
471             {
472               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
473             }
474           else if( type1 != NULL )
475             {
476               scale2 = DEBUG_GetObjectSize(type1);
477               rtn.type = exp1.type;
478             }
479           else if( type2 != NULL )
480             {
481               scale1 = DEBUG_GetObjectSize(type2);
482               rtn.type = exp2.type;
483             }
484           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
485           break;
486         case EXP_OP_SUB:
487           type1 = DEBUG_GetPointerType(exp1.type);
488           type2 = DEBUG_GetPointerType(exp2.type);
489           scale1 = 1;
490           scale2 = 1;
491           scale3 = 1;
492           if( type1 != NULL && type2 != NULL )
493             {
494               if( type1 != type2 )
495                 {
496                   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
497                 }
498               scale3 = DEBUG_GetObjectSize(type1);
499             }
500           else if( type1 != NULL )
501             {
502               scale2 = DEBUG_GetObjectSize(type1);
503               rtn.type = exp1.type;
504             }
505
506           else if( type2 != NULL )
507             {
508               scale1 = DEBUG_GetObjectSize(type2);
509               rtn.type = exp2.type;
510             }
511           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
512           break;
513         case EXP_OP_SEG:
514           rtn.cookie = DV_TARGET;
515           rtn.addr.seg = VAL(exp1);
516           exp->un.binop.result = VAL(exp2);
517 #ifdef __i386__
518           DEBUG_FixSegment(&rtn.addr);
519 #endif
520           break;
521         case EXP_OP_LOR:
522           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
523           break;
524         case EXP_OP_LAND:
525           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
526           break;
527         case EXP_OP_OR:
528           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
529           break;
530         case EXP_OP_AND:
531           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
532           break;
533         case EXP_OP_XOR:
534           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
535           break;
536         case EXP_OP_EQ:
537           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
538           break;
539         case EXP_OP_GT:
540           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
541           break;
542         case EXP_OP_LT:
543           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
544           break;
545         case EXP_OP_GE:
546           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
547           break;
548         case EXP_OP_LE:
549           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
550           break;
551         case EXP_OP_NE:
552           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
553           break;
554         case EXP_OP_SHL:
555           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
556           break;
557         case EXP_OP_SHR:
558           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
559           break;
560         case EXP_OP_MUL:
561           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
562           break;
563         case EXP_OP_DIV:
564           if( VAL(exp2) == 0 )
565             {
566                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
567             }
568           exp->un.binop.result = (VAL(exp1) / VAL(exp2));
569           break;
570         case EXP_OP_REM:
571           if( VAL(exp2) == 0 )
572             {
573                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
574             }
575           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
576           break;
577         case EXP_OP_ARR:
578           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
579           break;
580         default:
581           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
582           break;
583         }
584       break;
585     case EXPR_TYPE_UNOP:
586       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
587       rtn.cookie = DV_HOST;
588       if( exp1.type == NULL )
589         {
590           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
591         }
592       rtn.addr.seg = 0;
593       rtn.addr.off = (unsigned int) &exp->un.unop.result;
594       if( exp1.type == DEBUG_TypeIntConst )
595         {
596           rtn.type = exp1.type;
597         }
598       else
599         {
600           rtn.type = DEBUG_TypeInt;
601         }
602       switch(exp->un.unop.unop_type)
603         {
604         case EXP_OP_NEG:
605           exp->un.unop.result = -VAL(exp1);
606           break;
607         case EXP_OP_NOT:
608           exp->un.unop.result = !VAL(exp1);
609           break;
610         case EXP_OP_LNOT:
611           exp->un.unop.result = ~VAL(exp1);
612           break;
613         case EXP_OP_DEREF:
614           rtn.cookie = exp1.cookie;
615           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
616           if (!rtn.type)
617             {
618               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
619             }
620           break;
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));
626           else
627              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
628           break;
629         case EXP_OP_ADDR:
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;
634           break;
635         default:
636            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
637         }
638       break;
639     default:
640       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
641       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
642       break;
643     }
644
645   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
646
647   return rtn;
648 }
649
650
651 int
652 DEBUG_DisplayExpr(const struct expr * exp)
653 {
654   int           i;
655
656   switch(exp->type)
657     {
658     case EXPR_TYPE_CAST:
659       DEBUG_Printf(DBG_CHN_MESG, "((");
660       DEBUG_PrintTypeCast(exp->un.cast.cast);
661       DEBUG_Printf(DBG_CHN_MESG, ")");
662       DEBUG_DisplayExpr(exp->un.cast.expr);
663       DEBUG_Printf(DBG_CHN_MESG, ")");
664       break;
665     case EXPR_TYPE_REGISTER:
666       DEBUG_PrintRegister(exp->un.rgister.reg);
667       break;
668     case EXPR_TYPE_US_CONST:
669       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
670       break;
671     case EXPR_TYPE_CONST:
672       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
673       break;
674     case EXPR_TYPE_STRING:
675       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
676       break;
677     case EXPR_TYPE_SYMBOL:
678       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
679       break;
680     case EXPR_TYPE_PSTRUCT:
681       DEBUG_DisplayExpr(exp->un.structure.exp1);
682       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
683       break;
684     case EXPR_TYPE_STRUCT:
685       DEBUG_DisplayExpr(exp->un.structure.exp1);
686       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
687       break;
688     case EXPR_TYPE_CALL:
689       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
690       for(i=0; i < exp->un.call.nargs; i++)
691         {
692           DEBUG_DisplayExpr(exp->un.call.arg[i]);
693           if( i != exp->un.call.nargs - 1 )
694             {
695               DEBUG_Printf(DBG_CHN_MESG, ", ");
696             }
697         }
698       DEBUG_Printf(DBG_CHN_MESG, ")");
699       break;
700     case EXPR_TYPE_BINOP:
701       DEBUG_Printf(DBG_CHN_MESG, "( ");
702       DEBUG_DisplayExpr(exp->un.binop.exp1);
703       switch(exp->un.binop.binop_type)
704         {
705         case EXP_OP_ADD:
706           DEBUG_Printf(DBG_CHN_MESG, " + ");
707           break;
708         case EXP_OP_SUB:
709           DEBUG_Printf(DBG_CHN_MESG, " - ");
710           break;
711         case EXP_OP_SEG:
712           DEBUG_Printf(DBG_CHN_MESG, ":");
713           break;
714         case EXP_OP_LOR:
715           DEBUG_Printf(DBG_CHN_MESG, " || ");
716           break;
717         case EXP_OP_LAND:
718           DEBUG_Printf(DBG_CHN_MESG, " && ");
719           break;
720         case EXP_OP_OR:
721           DEBUG_Printf(DBG_CHN_MESG, " | ");
722           break;
723         case EXP_OP_AND:
724           DEBUG_Printf(DBG_CHN_MESG, " & ");
725           break;
726         case EXP_OP_XOR:
727           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
728           break;
729         case EXP_OP_EQ:
730           DEBUG_Printf(DBG_CHN_MESG, " == ");
731           break;
732         case EXP_OP_GT:
733           DEBUG_Printf(DBG_CHN_MESG, " > ");
734           break;
735         case EXP_OP_LT:
736           DEBUG_Printf(DBG_CHN_MESG, " < ");
737           break;
738         case EXP_OP_GE:
739           DEBUG_Printf(DBG_CHN_MESG, " >= ");
740           break;
741         case EXP_OP_LE:
742           DEBUG_Printf(DBG_CHN_MESG, " <= ");
743           break;
744         case EXP_OP_NE:
745           DEBUG_Printf(DBG_CHN_MESG, " != ");
746           break;
747         case EXP_OP_SHL:
748           DEBUG_Printf(DBG_CHN_MESG, " << ");
749           break;
750         case EXP_OP_SHR:
751           DEBUG_Printf(DBG_CHN_MESG, " >> ");
752           break;
753         case EXP_OP_MUL:
754           DEBUG_Printf(DBG_CHN_MESG, " * ");
755           break;
756         case EXP_OP_DIV:
757           DEBUG_Printf(DBG_CHN_MESG, " / ");
758           break;
759         case EXP_OP_REM:
760           DEBUG_Printf(DBG_CHN_MESG, " %% ");
761           break;
762         case EXP_OP_ARR:
763           DEBUG_Printf(DBG_CHN_MESG, "[");
764           break;
765         default:
766           break;
767         }
768       DEBUG_DisplayExpr(exp->un.binop.exp2);
769       if( exp->un.binop.binop_type == EXP_OP_ARR )
770         {
771           DEBUG_Printf(DBG_CHN_MESG, "]");
772         }
773       DEBUG_Printf(DBG_CHN_MESG, " )");
774       break;
775     case EXPR_TYPE_UNOP:
776       switch(exp->un.unop.unop_type)
777         {
778         case EXP_OP_NEG:
779           DEBUG_Printf(DBG_CHN_MESG, "-");
780           break;
781         case EXP_OP_NOT:
782           DEBUG_Printf(DBG_CHN_MESG, "!");
783           break;
784         case EXP_OP_LNOT:
785           DEBUG_Printf(DBG_CHN_MESG, "~");
786           break;
787         case EXP_OP_DEREF:
788           DEBUG_Printf(DBG_CHN_MESG, "*");
789           break;
790         case EXP_OP_ADDR:
791           DEBUG_Printf(DBG_CHN_MESG, "&");
792           break;
793         }
794       DEBUG_DisplayExpr(exp->un.unop.exp1);
795       break;
796     default:
797       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
798       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
799       break;
800     }
801
802   return TRUE;
803 }
804
805 struct expr *
806 DEBUG_CloneExpr(const struct expr * exp)
807 {
808   int           i;
809   struct expr * rtn;
810
811   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
812
813   /*
814    * First copy the contents of the expression itself.
815    */
816   *rtn = *exp;
817
818
819   switch(exp->type)
820     {
821     case EXPR_TYPE_CAST:
822       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
823       break;
824     case EXPR_TYPE_REGISTER:
825     case EXPR_TYPE_US_CONST:
826     case EXPR_TYPE_CONST:
827       break;
828     case EXPR_TYPE_STRING:
829       rtn->un.string.str = DBG_strdup(exp->un.string.str);
830       break;
831     case EXPR_TYPE_SYMBOL:
832       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
833       break;
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);
838       break;
839     case EXPR_TYPE_CALL:
840       for(i=0; i < exp->un.call.nargs; i++)
841         {
842           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
843         }
844       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
845       break;
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);
849       break;
850     case EXPR_TYPE_UNOP:
851       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
852       break;
853     default:
854       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
855       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
856       break;
857     }
858
859   return rtn;
860 }
861
862
863 /*
864  * Recursively go through an expression tree and free all memory associated
865  * with it.
866  */
867 int
868 DEBUG_FreeExpr(struct expr * exp)
869 {
870   int i;
871
872   switch(exp->type)
873     {
874     case EXPR_TYPE_CAST:
875       DEBUG_FreeExpr(exp->un.cast.expr);
876       break;
877     case EXPR_TYPE_REGISTER:
878     case EXPR_TYPE_US_CONST:
879     case EXPR_TYPE_CONST:
880       break;
881     case EXPR_TYPE_STRING:
882       DBG_free((char *) exp->un.string.str);
883       break;
884     case EXPR_TYPE_SYMBOL:
885       DBG_free((char *) exp->un.symbol.name);
886       break;
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);
891       break;
892     case EXPR_TYPE_CALL:
893       for(i=0; i < exp->un.call.nargs; i++)
894         {
895           DEBUG_FreeExpr(exp->un.call.arg[i]);
896         }
897       DBG_free((char *) exp->un.call.funcname);
898       break;
899     case EXPR_TYPE_BINOP:
900       DEBUG_FreeExpr(exp->un.binop.exp1);
901       DEBUG_FreeExpr(exp->un.binop.exp2);
902       break;
903     case EXPR_TYPE_UNOP:
904       DEBUG_FreeExpr(exp->un.unop.exp1);
905       break;
906     default:
907       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
908       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
909       break;
910     }
911
912   DBG_free(exp);
913   return TRUE;
914 }