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