Imported Upstream version 1.3.1
[platform/upstream/libunwind.git] / src / dwarf / Gexpr.c
1 /* libunwind - a platform-independent unwind library
2    Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P.
3         Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is part of libunwind.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
25
26 #include "dwarf_i.h"
27 #include "libunwind_i.h"
28
29 /* The "pick" operator provides an index range of 0..255 indicating
30    that the stack could at least have a depth of up to 256 elements,
31    but the GCC unwinder restricts the depth to 64, which seems
32    reasonable so we use the same value here.  */
33 #define MAX_EXPR_STACK_SIZE     64
34
35 #define NUM_OPERANDS(signature) (((signature) >> 6) & 0x3)
36 #define OPND1_TYPE(signature)   (((signature) >> 3) & 0x7)
37 #define OPND2_TYPE(signature)   (((signature) >> 0) & 0x7)
38
39 #define OPND_SIGNATURE(n, t1, t2) (((n) << 6) | ((t1) << 3) | ((t2) << 0))
40 #define OPND1(t1)               OPND_SIGNATURE(1, t1, 0)
41 #define OPND2(t1, t2)           OPND_SIGNATURE(2, t1, t2)
42
43 #define VAL8    0x0
44 #define VAL16   0x1
45 #define VAL32   0x2
46 #define VAL64   0x3
47 #define ULEB128 0x4
48 #define SLEB128 0x5
49 #define OFFSET  0x6     /* 32-bit offset for 32-bit DWARF, 64-bit otherwise */
50 #define ADDR    0x7     /* Machine address.  */
51
52 static const uint8_t operands[256] =
53   {
54     [DW_OP_addr] =              OPND1 (ADDR),
55     [DW_OP_const1u] =           OPND1 (VAL8),
56     [DW_OP_const1s] =           OPND1 (VAL8),
57     [DW_OP_const2u] =           OPND1 (VAL16),
58     [DW_OP_const2s] =           OPND1 (VAL16),
59     [DW_OP_const4u] =           OPND1 (VAL32),
60     [DW_OP_const4s] =           OPND1 (VAL32),
61     [DW_OP_const8u] =           OPND1 (VAL64),
62     [DW_OP_const8s] =           OPND1 (VAL64),
63     [DW_OP_pick] =              OPND1 (VAL8),
64     [DW_OP_plus_uconst] =       OPND1 (ULEB128),
65     [DW_OP_skip] =              OPND1 (VAL16),
66     [DW_OP_bra] =               OPND1 (VAL16),
67     [DW_OP_breg0 +  0] =        OPND1 (SLEB128),
68     [DW_OP_breg0 +  1] =        OPND1 (SLEB128),
69     [DW_OP_breg0 +  2] =        OPND1 (SLEB128),
70     [DW_OP_breg0 +  3] =        OPND1 (SLEB128),
71     [DW_OP_breg0 +  4] =        OPND1 (SLEB128),
72     [DW_OP_breg0 +  5] =        OPND1 (SLEB128),
73     [DW_OP_breg0 +  6] =        OPND1 (SLEB128),
74     [DW_OP_breg0 +  7] =        OPND1 (SLEB128),
75     [DW_OP_breg0 +  8] =        OPND1 (SLEB128),
76     [DW_OP_breg0 +  9] =        OPND1 (SLEB128),
77     [DW_OP_breg0 + 10] =        OPND1 (SLEB128),
78     [DW_OP_breg0 + 11] =        OPND1 (SLEB128),
79     [DW_OP_breg0 + 12] =        OPND1 (SLEB128),
80     [DW_OP_breg0 + 13] =        OPND1 (SLEB128),
81     [DW_OP_breg0 + 14] =        OPND1 (SLEB128),
82     [DW_OP_breg0 + 15] =        OPND1 (SLEB128),
83     [DW_OP_breg0 + 16] =        OPND1 (SLEB128),
84     [DW_OP_breg0 + 17] =        OPND1 (SLEB128),
85     [DW_OP_breg0 + 18] =        OPND1 (SLEB128),
86     [DW_OP_breg0 + 19] =        OPND1 (SLEB128),
87     [DW_OP_breg0 + 20] =        OPND1 (SLEB128),
88     [DW_OP_breg0 + 21] =        OPND1 (SLEB128),
89     [DW_OP_breg0 + 22] =        OPND1 (SLEB128),
90     [DW_OP_breg0 + 23] =        OPND1 (SLEB128),
91     [DW_OP_breg0 + 24] =        OPND1 (SLEB128),
92     [DW_OP_breg0 + 25] =        OPND1 (SLEB128),
93     [DW_OP_breg0 + 26] =        OPND1 (SLEB128),
94     [DW_OP_breg0 + 27] =        OPND1 (SLEB128),
95     [DW_OP_breg0 + 28] =        OPND1 (SLEB128),
96     [DW_OP_breg0 + 29] =        OPND1 (SLEB128),
97     [DW_OP_breg0 + 30] =        OPND1 (SLEB128),
98     [DW_OP_breg0 + 31] =        OPND1 (SLEB128),
99     [DW_OP_regx] =              OPND1 (ULEB128),
100     [DW_OP_fbreg] =             OPND1 (SLEB128),
101     [DW_OP_bregx] =             OPND2 (ULEB128, SLEB128),
102     [DW_OP_piece] =             OPND1 (ULEB128),
103     [DW_OP_deref_size] =        OPND1 (VAL8),
104     [DW_OP_xderef_size] =       OPND1 (VAL8),
105     [DW_OP_call2] =             OPND1 (VAL16),
106     [DW_OP_call4] =             OPND1 (VAL32),
107     [DW_OP_call_ref] =          OPND1 (OFFSET)
108   };
109
110 static inline unw_sword_t
111 sword (unw_addr_space_t as, unw_word_t val)
112 {
113   switch (dwarf_addr_size (as))
114     {
115     case 1: return (int8_t) val;
116     case 2: return (int16_t) val;
117     case 4: return (int32_t) val;
118     case 8: return (int64_t) val;
119     default: abort ();
120     }
121 }
122
123 static inline unw_word_t
124 read_operand (unw_addr_space_t as, unw_accessors_t *a,
125               unw_word_t *addr, int operand_type, unw_word_t *val, void *arg)
126 {
127   uint8_t u8;
128   uint16_t u16;
129   uint32_t u32;
130   uint64_t u64;
131   int ret;
132
133   if (operand_type == ADDR)
134     switch (dwarf_addr_size (as))
135       {
136       case 1: operand_type = VAL8; break;
137       case 2: operand_type = VAL16; break;
138       case 4: operand_type = VAL32; break;
139       case 8: operand_type = VAL64; break;
140       default: abort ();
141       }
142
143   switch (operand_type)
144     {
145     case VAL8:
146       ret = dwarf_readu8 (as, a, addr, &u8, arg);
147       if (ret < 0)
148         return ret;
149       *val = u8;
150       break;
151
152     case VAL16:
153       ret = dwarf_readu16 (as, a, addr, &u16, arg);
154       if (ret < 0)
155         return ret;
156       *val = u16;
157       break;
158
159     case VAL32:
160       ret = dwarf_readu32 (as, a, addr, &u32, arg);
161       if (ret < 0)
162         return ret;
163       *val = u32;
164       break;
165
166     case VAL64:
167       ret = dwarf_readu64 (as, a, addr, &u64, arg);
168       if (ret < 0)
169         return ret;
170       *val = u64;
171       break;
172
173     case ULEB128:
174       ret = dwarf_read_uleb128 (as, a, addr, val, arg);
175       break;
176
177     case SLEB128:
178       ret = dwarf_read_sleb128 (as, a, addr, val, arg);
179       break;
180
181     case OFFSET: /* only used by DW_OP_call_ref, which we don't implement */
182     default:
183       Debug (1, "Unexpected operand type %d\n", operand_type);
184       ret = -UNW_EINVAL;
185     }
186   return ret;
187 }
188
189 HIDDEN int
190 dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr,
191                     unw_word_t rbp_addr, unw_word_t *cfa_offset) {
192   unw_accessors_t *a;
193   int ret;
194   void *arg;
195   unw_word_t len;
196   uint8_t opcode;
197   unw_word_t operand1;
198
199   a = unw_get_accessors_int (c->as);
200   arg = c->as_arg;
201
202   ret = dwarf_read_uleb128(c->as, a, &rbp_addr, &len, arg);
203   if (len != 2 || ret < 0)
204     return 0;
205
206   ret = dwarf_readu8(c->as, a, &rbp_addr, &opcode, arg);
207   if (ret < 0 || opcode != DW_OP_breg6)
208     return 0;
209
210   ret = read_operand(c->as, a, &rbp_addr,
211                      OPND1_TYPE(operands[opcode]), &operand1, arg);
212
213   if (ret < 0 || operand1 != 0)
214     return 0;
215
216   ret = dwarf_read_uleb128(c->as, a, &cfa_addr, &len, arg);
217   if (ret < 0 || len != 3)
218     return 0;
219
220   ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg);
221   if (ret < 0 || opcode != DW_OP_breg6)
222     return 0;
223
224   ret = read_operand(c->as, a, &cfa_addr,
225                      OPND1_TYPE(operands[opcode]), &operand1, arg);
226   if (ret < 0)
227     return 0;
228
229   ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg);
230   if (ret < 0 || opcode != DW_OP_deref)
231     return 0;
232
233   *cfa_offset = operand1;
234   return 1;
235 }
236
237 HIDDEN int
238 dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len,
239                  unw_word_t *valp, int *is_register)
240 {
241   unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr;
242   uint8_t opcode, operands_signature, u8;
243   unw_addr_space_t as;
244   unw_accessors_t *a;
245   void *arg;
246   unw_word_t stack[MAX_EXPR_STACK_SIZE];
247   unsigned int tos = 0;
248   uint16_t u16;
249   uint32_t u32;
250   uint64_t u64;
251   int ret;
252 # define pop()                                  \
253 ({                                              \
254   if ((tos - 1) >= MAX_EXPR_STACK_SIZE)         \
255     {                                           \
256       Debug (1, "Stack underflow\n");           \
257       return -UNW_EINVAL;                       \
258     }                                           \
259   stack[--tos];                                 \
260 })
261 # define push(x)                                \
262 do {                                            \
263   unw_word_t _x = (x);                          \
264   if (tos >= MAX_EXPR_STACK_SIZE)               \
265     {                                           \
266       Debug (1, "Stack overflow\n");            \
267       return -UNW_EINVAL;                       \
268     }                                           \
269   stack[tos++] = _x;                            \
270 } while (0)
271 # define pick(n)                                \
272 ({                                              \
273   unsigned int _index = tos - 1 - (n);          \
274   if (_index >= MAX_EXPR_STACK_SIZE)            \
275     {                                           \
276       Debug (1, "Out-of-stack pick\n");         \
277       return -UNW_EINVAL;                       \
278     }                                           \
279   stack[_index];                                \
280 })
281
282   as = c->as;
283   arg = c->as_arg;
284   a = unw_get_accessors_int (as);
285   end_addr = *addr + len;
286   *is_register = 0;
287
288   Debug (14, "len=%lu, pushing cfa=0x%lx\n",
289          (unsigned long) len, (unsigned long) c->cfa);
290
291   push (c->cfa);        /* push current CFA as required by DWARF spec */
292
293   while (*addr < end_addr)
294     {
295       if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0)
296         return ret;
297
298       operands_signature = operands[opcode];
299
300       if (unlikely (NUM_OPERANDS (operands_signature) > 0))
301         {
302           if ((ret = read_operand (as, a, addr,
303                                    OPND1_TYPE (operands_signature),
304                                    &operand1, arg)) < 0)
305             return ret;
306           if (NUM_OPERANDS (operands_signature) > 1)
307             if ((ret = read_operand (as, a, addr,
308                                      OPND2_TYPE (operands_signature),
309                                      &operand2, arg)) < 0)
310               return ret;
311         }
312
313       switch ((dwarf_expr_op_t) opcode)
314         {
315         case DW_OP_lit0:  case DW_OP_lit1:  case DW_OP_lit2:
316         case DW_OP_lit3:  case DW_OP_lit4:  case DW_OP_lit5:
317         case DW_OP_lit6:  case DW_OP_lit7:  case DW_OP_lit8:
318         case DW_OP_lit9:  case DW_OP_lit10: case DW_OP_lit11:
319         case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14:
320         case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17:
321         case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20:
322         case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23:
323         case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26:
324         case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29:
325         case DW_OP_lit30: case DW_OP_lit31:
326           Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0);
327           push (opcode - DW_OP_lit0);
328           break;
329
330         case DW_OP_breg0:  case DW_OP_breg1:  case DW_OP_breg2:
331         case DW_OP_breg3:  case DW_OP_breg4:  case DW_OP_breg5:
332         case DW_OP_breg6:  case DW_OP_breg7:  case DW_OP_breg8:
333         case DW_OP_breg9:  case DW_OP_breg10: case DW_OP_breg11:
334         case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14:
335         case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17:
336         case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20:
337         case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
338         case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26:
339         case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29:
340         case DW_OP_breg30: case DW_OP_breg31:
341           Debug (15, "OP_breg(r%d,0x%lx)\n",
342                  (int) opcode - DW_OP_breg0, (unsigned long) operand1);
343           if ((ret = unw_get_reg (dwarf_to_cursor (c),
344                                   dwarf_to_unw_regnum (opcode - DW_OP_breg0),
345                                   &tmp1)) < 0)
346             return ret;
347           push (tmp1 + operand1);
348           break;
349
350         case DW_OP_bregx:
351           Debug (15, "OP_bregx(r%d,0x%lx)\n",
352                  (int) operand1, (unsigned long) operand2);
353           if ((ret = unw_get_reg (dwarf_to_cursor (c),
354                                   dwarf_to_unw_regnum (operand1), &tmp1)) < 0)
355             return ret;
356           push (tmp1 + operand2);
357           break;
358
359         case DW_OP_reg0:  case DW_OP_reg1:  case DW_OP_reg2:
360         case DW_OP_reg3:  case DW_OP_reg4:  case DW_OP_reg5:
361         case DW_OP_reg6:  case DW_OP_reg7:  case DW_OP_reg8:
362         case DW_OP_reg9:  case DW_OP_reg10: case DW_OP_reg11:
363         case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14:
364         case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17:
365         case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20:
366         case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
367         case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26:
368         case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29:
369         case DW_OP_reg30: case DW_OP_reg31:
370           Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0);
371           *valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0);
372           *is_register = 1;
373           return 0;
374
375         case DW_OP_regx:
376           Debug (15, "OP_regx(r%d)\n", (int) operand1);
377           *valp = dwarf_to_unw_regnum (operand1);
378           *is_register = 1;
379           return 0;
380
381         case DW_OP_addr:
382         case DW_OP_const1u:
383         case DW_OP_const2u:
384         case DW_OP_const4u:
385         case DW_OP_const8u:
386         case DW_OP_constu:
387         case DW_OP_const8s:
388         case DW_OP_consts:
389           Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1);
390           push (operand1);
391           break;
392
393         case DW_OP_const1s:
394           if (operand1 & 0x80)
395             operand1 |= ((unw_word_t) -1) << 8;
396           Debug (15, "OP_const1s(%ld)\n", (long) operand1);
397           push (operand1);
398           break;
399
400         case DW_OP_const2s:
401           if (operand1 & 0x8000)
402             operand1 |= ((unw_word_t) -1) << 16;
403           Debug (15, "OP_const2s(%ld)\n", (long) operand1);
404           push (operand1);
405           break;
406
407         case DW_OP_const4s:
408           if (operand1 & 0x80000000)
409             operand1 |= (((unw_word_t) -1) << 16) << 16;
410           Debug (15, "OP_const4s(%ld)\n", (long) operand1);
411           push (operand1);
412           break;
413
414         case DW_OP_deref:
415           Debug (15, "OP_deref\n");
416           tmp1 = pop ();
417           if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0)
418             return ret;
419           push (tmp2);
420           break;
421
422         case DW_OP_deref_size:
423           Debug (15, "OP_deref_size(%d)\n", (int) operand1);
424           tmp1 = pop ();
425           switch (operand1)
426             {
427             default:
428               Debug (1, "Unexpected DW_OP_deref_size size %d\n",
429                      (int) operand1);
430               return -UNW_EINVAL;
431
432             case 1:
433               if ((ret = dwarf_readu8 (as, a, &tmp1, &u8, arg)) < 0)
434                 return ret;
435               tmp2 = u8;
436               break;
437
438             case 2:
439               if ((ret = dwarf_readu16 (as, a, &tmp1, &u16, arg)) < 0)
440                 return ret;
441               tmp2 = u16;
442               break;
443
444             case 3:
445             case 4:
446               if ((ret = dwarf_readu32 (as, a, &tmp1, &u32, arg)) < 0)
447                 return ret;
448               tmp2 = u32;
449               if (operand1 == 3)
450                 {
451                   if (dwarf_is_big_endian (as))
452                     tmp2 >>= 8;
453                   else
454                     tmp2 &= 0xffffff;
455                 }
456               break;
457             case 5:
458             case 6:
459             case 7:
460             case 8:
461               if ((ret = dwarf_readu64 (as, a, &tmp1, &u64, arg)) < 0)
462                 return ret;
463               tmp2 = u64;
464               if (operand1 != 8)
465                 {
466                   if (dwarf_is_big_endian (as))
467                     tmp2 >>= 64 - 8 * operand1;
468                   else
469                     tmp2 &= (~ (unw_word_t) 0) << (8 * operand1);
470                 }
471               break;
472             }
473           push (tmp2);
474           break;
475
476         case DW_OP_dup:
477           Debug (15, "OP_dup\n");
478           push (pick (0));
479           break;
480
481         case DW_OP_drop:
482           Debug (15, "OP_drop\n");
483           (void) pop ();
484           break;
485
486         case DW_OP_pick:
487           Debug (15, "OP_pick(%d)\n", (int) operand1);
488           push (pick (operand1));
489           break;
490
491         case DW_OP_over:
492           Debug (15, "OP_over\n");
493           push (pick (1));
494           break;
495
496         case DW_OP_swap:
497           Debug (15, "OP_swap\n");
498           tmp1 = pop ();
499           tmp2 = pop ();
500           push (tmp1);
501           push (tmp2);
502           break;
503
504         case DW_OP_rot:
505           Debug (15, "OP_rot\n");
506           tmp1 = pop ();
507           tmp2 = pop ();
508           tmp3 = pop ();
509           push (tmp1);
510           push (tmp3);
511           push (tmp2);
512           break;
513
514         case DW_OP_abs:
515           Debug (15, "OP_abs\n");
516           tmp1 = pop ();
517           if (tmp1 & ((unw_word_t) 1 << (8 * dwarf_addr_size (as) - 1)))
518             tmp1 = -tmp1;
519           push (tmp1);
520           break;
521
522         case DW_OP_and:
523           Debug (15, "OP_and\n");
524           tmp1 = pop ();
525           tmp2 = pop ();
526           push (tmp1 & tmp2);
527           break;
528
529         case DW_OP_div:
530           Debug (15, "OP_div\n");
531           tmp1 = pop ();
532           tmp2 = pop ();
533           if (tmp1)
534             tmp1 = sword (as, tmp2) / sword (as, tmp1);
535           push (tmp1);
536           break;
537
538         case DW_OP_minus:
539           Debug (15, "OP_minus\n");
540           tmp1 = pop ();
541           tmp2 = pop ();
542           tmp1 = tmp2 - tmp1;
543           push (tmp1);
544           break;
545
546         case DW_OP_mod:
547           Debug (15, "OP_mod\n");
548           tmp1 = pop ();
549           tmp2 = pop ();
550           if (tmp1)
551             tmp1 = tmp2 % tmp1;
552           push (tmp1);
553           break;
554
555         case DW_OP_mul:
556           Debug (15, "OP_mul\n");
557           tmp1 = pop ();
558           tmp2 = pop ();
559           if (tmp1)
560             tmp1 = tmp2 * tmp1;
561           push (tmp1);
562           break;
563
564         case DW_OP_neg:
565           Debug (15, "OP_neg\n");
566           push (-pop ());
567           break;
568
569         case DW_OP_not:
570           Debug (15, "OP_not\n");
571           push (~pop ());
572           break;
573
574         case DW_OP_or:
575           Debug (15, "OP_or\n");
576           tmp1 = pop ();
577           tmp2 = pop ();
578           push (tmp1 | tmp2);
579           break;
580
581         case DW_OP_plus:
582           Debug (15, "OP_plus\n");
583           tmp1 = pop ();
584           tmp2 = pop ();
585           push (tmp1 + tmp2);
586           break;
587
588         case DW_OP_plus_uconst:
589           Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1);
590           tmp1 = pop ();
591           push (tmp1 + operand1);
592           break;
593
594         case DW_OP_shl:
595           Debug (15, "OP_shl\n");
596           tmp1 = pop ();
597           tmp2 = pop ();
598           push (tmp2 << tmp1);
599           break;
600
601         case DW_OP_shr:
602           Debug (15, "OP_shr\n");
603           tmp1 = pop ();
604           tmp2 = pop ();
605           push (tmp2 >> tmp1);
606           break;
607
608         case DW_OP_shra:
609           Debug (15, "OP_shra\n");
610           tmp1 = pop ();
611           tmp2 = pop ();
612           push (sword (as, tmp2) >> tmp1);
613           break;
614
615         case DW_OP_xor:
616           Debug (15, "OP_xor\n");
617           tmp1 = pop ();
618           tmp2 = pop ();
619           push (tmp1 ^ tmp2);
620           break;
621
622         case DW_OP_le:
623           Debug (15, "OP_le\n");
624           tmp1 = pop ();
625           tmp2 = pop ();
626           push (sword (as, tmp2) <= sword (as, tmp1));
627           break;
628
629         case DW_OP_ge:
630           Debug (15, "OP_ge\n");
631           tmp1 = pop ();
632           tmp2 = pop ();
633           push (sword (as, tmp2) >= sword (as, tmp1));
634           break;
635
636         case DW_OP_eq:
637           Debug (15, "OP_eq\n");
638           tmp1 = pop ();
639           tmp2 = pop ();
640           push (sword (as, tmp2) == sword (as, tmp1));
641           break;
642
643         case DW_OP_lt:
644           Debug (15, "OP_lt\n");
645           tmp1 = pop ();
646           tmp2 = pop ();
647           push (sword (as, tmp2) < sword (as, tmp1));
648           break;
649
650         case DW_OP_gt:
651           Debug (15, "OP_gt\n");
652           tmp1 = pop ();
653           tmp2 = pop ();
654           push (sword (as, tmp2) > sword (as, tmp1));
655           break;
656
657         case DW_OP_ne:
658           Debug (15, "OP_ne\n");
659           tmp1 = pop ();
660           tmp2 = pop ();
661           push (sword (as, tmp2) != sword (as, tmp1));
662           break;
663
664         case DW_OP_skip:
665           Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
666           *addr += (int16_t) operand1;
667           break;
668
669         case DW_OP_bra:
670           Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
671           tmp1 = pop ();
672           if (tmp1)
673             *addr += (int16_t) operand1;
674           break;
675
676         case DW_OP_nop:
677           Debug (15, "OP_nop\n");
678           break;
679
680         case DW_OP_call2:
681         case DW_OP_call4:
682         case DW_OP_call_ref:
683         case DW_OP_fbreg:
684         case DW_OP_piece:
685         case DW_OP_push_object_address:
686         case DW_OP_xderef:
687         case DW_OP_xderef_size:
688         default:
689           Debug (1, "Unexpected opcode 0x%x\n", opcode);
690           return -UNW_EINVAL;
691         }
692     }
693   *valp = pop ();
694   Debug (14, "final value = 0x%lx\n", (unsigned long) *valp);
695   return 0;
696 }