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
5This file is part of libunwind.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH 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
52static 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
110static inline unw_sword_t
111sword (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
123static inline unw_word_t
124read_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
189HIDDEN int
190dwarf_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
237HIDDEN int
238dwarf_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) \
262do { \
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}
697