• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
sword(unw_addr_space_t as,unw_word_t val)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
read_operand(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,int operand_type,unw_word_t * val,void * arg)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
dwarf_eval_expr(struct dwarf_cursor * c,unw_word_t * addr,unw_word_t len,unw_word_t * valp,int * is_register)190 dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len,
191 		 unw_word_t *valp, int *is_register)
192 {
193   unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2, tmp3, end_addr;
194   uint8_t opcode, operands_signature, u8;
195   unw_addr_space_t as;
196   unw_accessors_t *a;
197   void *arg;
198   unw_word_t stack[MAX_EXPR_STACK_SIZE];
199   unsigned int tos = 0;
200   uint16_t u16;
201   uint32_t u32;
202   uint64_t u64;
203   int ret;
204 # define pop()					\
205 ({						\
206   if ((tos - 1) >= MAX_EXPR_STACK_SIZE)		\
207     {						\
208       Debug (1, "Stack underflow\n");		\
209       return -UNW_EINVAL;			\
210     }						\
211   stack[--tos];					\
212 })
213 # define push(x)				\
214 do {						\
215   if (tos >= MAX_EXPR_STACK_SIZE)		\
216     {						\
217       Debug (1, "Stack overflow\n");		\
218       return -UNW_EINVAL;			\
219     }						\
220   stack[tos++] = (x);				\
221 } while (0)
222 # define pick(n)				\
223 ({						\
224   unsigned int _index = tos - 1 - (n);		\
225   if (_index >= MAX_EXPR_STACK_SIZE)		\
226     {						\
227       Debug (1, "Out-of-stack pick\n");		\
228       return -UNW_EINVAL;			\
229     }						\
230   stack[_index];				\
231 })
232 
233   as = c->as;
234   arg = c->as_arg;
235   a = unw_get_accessors (as);
236   end_addr = *addr + len;
237   *is_register = 0;
238 
239   Debug (14, "len=%lu, pushing cfa=0x%lx\n",
240 	 (unsigned long) len, (unsigned long) c->cfa);
241 
242   push (c->cfa);	/* push current CFA as required by DWARF spec */
243 
244   while (*addr < end_addr)
245     {
246       if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0)
247 	return ret;
248 
249       operands_signature = operands[opcode];
250 
251       if (unlikely (NUM_OPERANDS (operands_signature) > 0))
252 	{
253 	  if ((ret = read_operand (as, a, addr,
254 				   OPND1_TYPE (operands_signature),
255 				   &operand1, arg)) < 0)
256 	    return ret;
257 	  if (NUM_OPERANDS (operands_signature) > 1)
258 	    if ((ret = read_operand (as, a, addr,
259 				     OPND2_TYPE (operands_signature),
260 				     &operand2, arg)) < 0)
261 	      return ret;
262 	}
263 
264       switch ((dwarf_expr_op_t) opcode)
265 	{
266 	case DW_OP_lit0:  case DW_OP_lit1:  case DW_OP_lit2:
267 	case DW_OP_lit3:  case DW_OP_lit4:  case DW_OP_lit5:
268 	case DW_OP_lit6:  case DW_OP_lit7:  case DW_OP_lit8:
269 	case DW_OP_lit9:  case DW_OP_lit10: case DW_OP_lit11:
270 	case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14:
271 	case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17:
272 	case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20:
273 	case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23:
274 	case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26:
275 	case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29:
276 	case DW_OP_lit30: case DW_OP_lit31:
277 	  Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0);
278 	  push (opcode - DW_OP_lit0);
279 	  break;
280 
281 	case DW_OP_breg0:  case DW_OP_breg1:  case DW_OP_breg2:
282 	case DW_OP_breg3:  case DW_OP_breg4:  case DW_OP_breg5:
283 	case DW_OP_breg6:  case DW_OP_breg7:  case DW_OP_breg8:
284 	case DW_OP_breg9:  case DW_OP_breg10: case DW_OP_breg11:
285 	case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14:
286 	case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17:
287 	case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20:
288 	case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
289 	case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26:
290 	case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29:
291 	case DW_OP_breg30: case DW_OP_breg31:
292 	  Debug (15, "OP_breg(r%d,0x%lx)\n",
293 		 (int) opcode - DW_OP_breg0, (unsigned long) operand1);
294 	  if ((ret = unw_get_reg (dwarf_to_cursor (c),
295 				  dwarf_to_unw_regnum (opcode - DW_OP_breg0),
296 				  &tmp1)) < 0)
297 	    return ret;
298 	  push (tmp1 + operand1);
299 	  break;
300 
301 	case DW_OP_bregx:
302 	  Debug (15, "OP_bregx(r%d,0x%lx)\n",
303 		 (int) operand1, (unsigned long) operand2);
304 	  if ((ret = unw_get_reg (dwarf_to_cursor (c),
305 				  dwarf_to_unw_regnum (operand1), &tmp1)) < 0)
306 	    return ret;
307 	  push (tmp1 + operand2);
308 	  break;
309 
310 	case DW_OP_reg0:  case DW_OP_reg1:  case DW_OP_reg2:
311 	case DW_OP_reg3:  case DW_OP_reg4:  case DW_OP_reg5:
312 	case DW_OP_reg6:  case DW_OP_reg7:  case DW_OP_reg8:
313 	case DW_OP_reg9:  case DW_OP_reg10: case DW_OP_reg11:
314 	case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14:
315 	case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17:
316 	case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20:
317 	case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
318 	case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26:
319 	case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29:
320 	case DW_OP_reg30: case DW_OP_reg31:
321 	  Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0);
322 	  *valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0);
323 	  *is_register = 1;
324 	  return 0;
325 
326 	case DW_OP_regx:
327 	  Debug (15, "OP_regx(r%d)\n", (int) operand1);
328 	  *valp = dwarf_to_unw_regnum (operand1);
329 	  *is_register = 1;
330 	  return 0;
331 
332 	case DW_OP_addr:
333 	case DW_OP_const1u:
334 	case DW_OP_const2u:
335 	case DW_OP_const4u:
336 	case DW_OP_const8u:
337 	case DW_OP_constu:
338 	case DW_OP_const8s:
339 	case DW_OP_consts:
340 	  Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1);
341 	  push (operand1);
342 	  break;
343 
344 	case DW_OP_const1s:
345 	  if (operand1 & 0x80)
346 	    operand1 |= ((unw_word_t) -1) << 8;
347 	  Debug (15, "OP_const1s(%ld)\n", (long) operand1);
348 	  push (operand1);
349 	  break;
350 
351 	case DW_OP_const2s:
352 	  if (operand1 & 0x8000)
353 	    operand1 |= ((unw_word_t) -1) << 16;
354 	  Debug (15, "OP_const2s(%ld)\n", (long) operand1);
355 	  push (operand1);
356 	  break;
357 
358 	case DW_OP_const4s:
359 	  if (operand1 & 0x80000000)
360 	    operand1 |= (((unw_word_t) -1) << 16) << 16;
361 	  Debug (15, "OP_const4s(%ld)\n", (long) operand1);
362 	  push (operand1);
363 	  break;
364 
365 	case DW_OP_deref:
366 	  Debug (15, "OP_deref\n");
367 	  tmp1 = pop ();
368 	  if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0)
369 	    return ret;
370 	  push (tmp2);
371 	  break;
372 
373 	case DW_OP_deref_size:
374 	  Debug (15, "OP_deref_size(%d)\n", (int) operand1);
375 	  tmp1 = pop ();
376 	  switch (operand1)
377 	    {
378 	    default:
379 	      Debug (1, "Unexpected DW_OP_deref_size size %d\n",
380 		     (int) operand1);
381 	      return -UNW_EINVAL;
382 
383 	    case 1:
384 	      if ((ret = dwarf_readu8 (as, a, &tmp1, &u8, arg)) < 0)
385 		return ret;
386 	      tmp2 = u8;
387 	      break;
388 
389 	    case 2:
390 	      if ((ret = dwarf_readu16 (as, a, &tmp1, &u16, arg)) < 0)
391 		return ret;
392 	      tmp2 = u16;
393 	      break;
394 
395 	    case 3:
396 	    case 4:
397 	      if ((ret = dwarf_readu32 (as, a, &tmp1, &u32, arg)) < 0)
398 		return ret;
399 	      tmp2 = u32;
400 	      if (operand1 == 3)
401 		{
402 		  if (dwarf_is_big_endian (as))
403 		    tmp2 >>= 8;
404 		  else
405 		    tmp2 &= 0xffffff;
406 		}
407 	      break;
408 	    case 5:
409 	    case 6:
410 	    case 7:
411 	    case 8:
412 	      if ((ret = dwarf_readu64 (as, a, &tmp1, &u64, arg)) < 0)
413 		return ret;
414 	      tmp2 = u64;
415 	      if (operand1 != 8)
416 		{
417 		  if (dwarf_is_big_endian (as))
418 		    tmp2 >>= 64 - 8 * operand1;
419 		  else
420 		    tmp2 &= (~ (unw_word_t) 0) << (8 * operand1);
421 		}
422 	      break;
423 	    }
424 	  push (tmp2);
425 	  break;
426 
427 	case DW_OP_dup:
428 	  Debug (15, "OP_dup\n");
429 	  push (pick (0));
430 	  break;
431 
432 	case DW_OP_drop:
433 	  Debug (15, "OP_drop\n");
434 	  (void) pop ();
435 	  break;
436 
437 	case DW_OP_pick:
438 	  Debug (15, "OP_pick(%d)\n", (int) operand1);
439 	  push (pick (operand1));
440 	  break;
441 
442 	case DW_OP_over:
443 	  Debug (15, "OP_over\n");
444 	  push (pick (1));
445 	  break;
446 
447 	case DW_OP_swap:
448 	  Debug (15, "OP_swap\n");
449 	  tmp1 = pop ();
450 	  tmp2 = pop ();
451 	  push (tmp1);
452 	  push (tmp2);
453 	  break;
454 
455 	case DW_OP_rot:
456 	  Debug (15, "OP_rot\n");
457 	  tmp1 = pop ();
458 	  tmp2 = pop ();
459 	  tmp3 = pop ();
460 	  push (tmp1);
461 	  push (tmp3);
462 	  push (tmp2);
463 	  break;
464 
465 	case DW_OP_abs:
466 	  Debug (15, "OP_abs\n");
467 	  tmp1 = pop ();
468 	  if (tmp1 & ((unw_word_t) 1 << (8 * dwarf_addr_size (as) - 1)))
469 	    tmp1 = -tmp1;
470 	  push (tmp1);
471 	  break;
472 
473 	case DW_OP_and:
474 	  Debug (15, "OP_and\n");
475 	  tmp1 = pop ();
476 	  tmp2 = pop ();
477 	  push (tmp1 & tmp2);
478 	  break;
479 
480 	case DW_OP_div:
481 	  Debug (15, "OP_div\n");
482 	  tmp1 = pop ();
483 	  tmp2 = pop ();
484 	  if (tmp1)
485 	    tmp1 = sword (as, tmp2) / sword (as, tmp1);
486 	  push (tmp1);
487 	  break;
488 
489 	case DW_OP_minus:
490 	  Debug (15, "OP_minus\n");
491 	  tmp1 = pop ();
492 	  tmp2 = pop ();
493 	  tmp1 = tmp2 - tmp1;
494 	  push (tmp1);
495 	  break;
496 
497 	case DW_OP_mod:
498 	  Debug (15, "OP_mod\n");
499 	  tmp1 = pop ();
500 	  tmp2 = pop ();
501 	  if (tmp1)
502 	    tmp1 = tmp2 % tmp1;
503 	  push (tmp1);
504 	  break;
505 
506 	case DW_OP_mul:
507 	  Debug (15, "OP_mul\n");
508 	  tmp1 = pop ();
509 	  tmp2 = pop ();
510 	  if (tmp1)
511 	    tmp1 = tmp2 * tmp1;
512 	  push (tmp1);
513 	  break;
514 
515 	case DW_OP_neg:
516 	  Debug (15, "OP_neg\n");
517 	  push (-pop ());
518 	  break;
519 
520 	case DW_OP_not:
521 	  Debug (15, "OP_not\n");
522 	  push (~pop ());
523 	  break;
524 
525 	case DW_OP_or:
526 	  Debug (15, "OP_or\n");
527 	  tmp1 = pop ();
528 	  tmp2 = pop ();
529 	  push (tmp1 | tmp2);
530 	  break;
531 
532 	case DW_OP_plus:
533 	  Debug (15, "OP_plus\n");
534 	  tmp1 = pop ();
535 	  tmp2 = pop ();
536 	  push (tmp1 + tmp2);
537 	  break;
538 
539 	case DW_OP_plus_uconst:
540 	  Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1);
541 	  tmp1 = pop ();
542 	  push (tmp1 + operand1);
543 	  break;
544 
545 	case DW_OP_shl:
546 	  Debug (15, "OP_shl\n");
547 	  tmp1 = pop ();
548 	  tmp2 = pop ();
549 	  push (tmp2 << tmp1);
550 	  break;
551 
552 	case DW_OP_shr:
553 	  Debug (15, "OP_shr\n");
554 	  tmp1 = pop ();
555 	  tmp2 = pop ();
556 	  push (tmp2 >> tmp1);
557 	  break;
558 
559 	case DW_OP_shra:
560 	  Debug (15, "OP_shra\n");
561 	  tmp1 = pop ();
562 	  tmp2 = pop ();
563 	  push (sword (as, tmp2) >> tmp1);
564 	  break;
565 
566 	case DW_OP_xor:
567 	  Debug (15, "OP_xor\n");
568 	  tmp1 = pop ();
569 	  tmp2 = pop ();
570 	  push (tmp1 ^ tmp2);
571 	  break;
572 
573 	case DW_OP_le:
574 	  Debug (15, "OP_le\n");
575 	  tmp1 = pop ();
576 	  tmp2 = pop ();
577 	  push (sword (as, tmp2) <= sword (as, tmp1));
578 	  break;
579 
580 	case DW_OP_ge:
581 	  Debug (15, "OP_ge\n");
582 	  tmp1 = pop ();
583 	  tmp2 = pop ();
584 	  push (sword (as, tmp2) >= sword (as, tmp1));
585 	  break;
586 
587 	case DW_OP_eq:
588 	  Debug (15, "OP_eq\n");
589 	  tmp1 = pop ();
590 	  tmp2 = pop ();
591 	  push (sword (as, tmp2) == sword (as, tmp1));
592 	  break;
593 
594 	case DW_OP_lt:
595 	  Debug (15, "OP_lt\n");
596 	  tmp1 = pop ();
597 	  tmp2 = pop ();
598 	  push (sword (as, tmp2) < sword (as, tmp1));
599 	  break;
600 
601 	case DW_OP_gt:
602 	  Debug (15, "OP_gt\n");
603 	  tmp1 = pop ();
604 	  tmp2 = pop ();
605 	  push (sword (as, tmp2) > sword (as, tmp1));
606 	  break;
607 
608 	case DW_OP_ne:
609 	  Debug (15, "OP_ne\n");
610 	  tmp1 = pop ();
611 	  tmp2 = pop ();
612 	  push (sword (as, tmp2) != sword (as, tmp1));
613 	  break;
614 
615 	case DW_OP_skip:
616 	  Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
617 	  *addr += (int16_t) operand1;
618 	  break;
619 
620 	case DW_OP_bra:
621 	  Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
622 	  tmp1 = pop ();
623 	  if (tmp1)
624 	    *addr += (int16_t) operand1;
625 	  break;
626 
627 	case DW_OP_nop:
628 	  Debug (15, "OP_nop\n");
629 	  break;
630 
631 	case DW_OP_call2:
632 	case DW_OP_call4:
633 	case DW_OP_call_ref:
634 	case DW_OP_fbreg:
635 	case DW_OP_piece:
636 	case DW_OP_push_object_address:
637 	case DW_OP_xderef:
638 	case DW_OP_xderef_size:
639 	default:
640 	  Debug (1, "Unexpected opcode 0x%x\n", opcode);
641 	  return -UNW_EINVAL;
642 	}
643     }
644   *valp = pop ();
645   Debug (14, "final value = 0x%lx\n", (unsigned long) *valp);
646   return 0;
647 }
648