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_constu] = OPND1 (ULEB128),
64 [DW_OP_consts] = OPND1 (SLEB128),
65 [DW_OP_pick] = OPND1 (VAL8),
66 [DW_OP_plus_uconst] = OPND1 (ULEB128),
67 [DW_OP_skip] = OPND1 (VAL16),
68 [DW_OP_bra] = OPND1 (VAL16),
69 [DW_OP_breg0 + 0] = OPND1 (SLEB128),
70 [DW_OP_breg0 + 1] = OPND1 (SLEB128),
71 [DW_OP_breg0 + 2] = OPND1 (SLEB128),
72 [DW_OP_breg0 + 3] = OPND1 (SLEB128),
73 [DW_OP_breg0 + 4] = OPND1 (SLEB128),
74 [DW_OP_breg0 + 5] = OPND1 (SLEB128),
75 [DW_OP_breg0 + 6] = OPND1 (SLEB128),
76 [DW_OP_breg0 + 7] = OPND1 (SLEB128),
77 [DW_OP_breg0 + 8] = OPND1 (SLEB128),
78 [DW_OP_breg0 + 9] = OPND1 (SLEB128),
79 [DW_OP_breg0 + 10] = OPND1 (SLEB128),
80 [DW_OP_breg0 + 11] = OPND1 (SLEB128),
81 [DW_OP_breg0 + 12] = OPND1 (SLEB128),
82 [DW_OP_breg0 + 13] = OPND1 (SLEB128),
83 [DW_OP_breg0 + 14] = OPND1 (SLEB128),
84 [DW_OP_breg0 + 15] = OPND1 (SLEB128),
85 [DW_OP_breg0 + 16] = OPND1 (SLEB128),
86 [DW_OP_breg0 + 17] = OPND1 (SLEB128),
87 [DW_OP_breg0 + 18] = OPND1 (SLEB128),
88 [DW_OP_breg0 + 19] = OPND1 (SLEB128),
89 [DW_OP_breg0 + 20] = OPND1 (SLEB128),
90 [DW_OP_breg0 + 21] = OPND1 (SLEB128),
91 [DW_OP_breg0 + 22] = OPND1 (SLEB128),
92 [DW_OP_breg0 + 23] = OPND1 (SLEB128),
93 [DW_OP_breg0 + 24] = OPND1 (SLEB128),
94 [DW_OP_breg0 + 25] = OPND1 (SLEB128),
95 [DW_OP_breg0 + 26] = OPND1 (SLEB128),
96 [DW_OP_breg0 + 27] = OPND1 (SLEB128),
97 [DW_OP_breg0 + 28] = OPND1 (SLEB128),
98 [DW_OP_breg0 + 29] = OPND1 (SLEB128),
99 [DW_OP_breg0 + 30] = OPND1 (SLEB128),
100 [DW_OP_breg0 + 31] = OPND1 (SLEB128),
101 [DW_OP_regx] = OPND1 (ULEB128),
102 [DW_OP_fbreg] = OPND1 (SLEB128),
103 [DW_OP_bregx] = OPND2 (ULEB128, SLEB128),
104 [DW_OP_piece] = OPND1 (ULEB128),
105 [DW_OP_deref_size] = OPND1 (VAL8),
106 [DW_OP_xderef_size] = OPND1 (VAL8),
107 [DW_OP_call2] = OPND1 (VAL16),
108 [DW_OP_call4] = OPND1 (VAL32),
109 [DW_OP_call_ref] = OPND1 (OFFSET)
110 };
111
112 static inline unw_sword_t
sword(unw_addr_space_t as,unw_word_t val)113 sword (unw_addr_space_t as, unw_word_t val)
114 {
115 switch (dwarf_addr_size (as))
116 {
117 case 1: return (int8_t) val;
118 case 2: return (int16_t) val;
119 case 4: return (int32_t) val;
120 case 8: return (int64_t) val;
121 default: abort ();
122 }
123 }
124
125 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)126 read_operand (unw_addr_space_t as, unw_accessors_t *a,
127 unw_word_t *addr, int operand_type, unw_word_t *val, void *arg)
128 {
129 uint8_t u8;
130 uint16_t u16;
131 uint32_t u32;
132 uint64_t u64;
133 int ret;
134
135 if (operand_type == ADDR)
136 switch (dwarf_addr_size (as))
137 {
138 case 1: operand_type = VAL8; break;
139 case 2: operand_type = VAL16; break;
140 case 4: operand_type = VAL32; break;
141 case 8: operand_type = VAL64; break;
142 default: abort ();
143 }
144
145 switch (operand_type)
146 {
147 case VAL8:
148 ret = dwarf_readu8 (as, a, addr, &u8, arg);
149 if (ret < 0)
150 return ret;
151 *val = u8;
152 break;
153
154 case VAL16:
155 ret = dwarf_readu16 (as, a, addr, &u16, arg);
156 if (ret < 0)
157 return ret;
158 *val = u16;
159 break;
160
161 case VAL32:
162 ret = dwarf_readu32 (as, a, addr, &u32, arg);
163 if (ret < 0)
164 return ret;
165 *val = u32;
166 break;
167
168 case VAL64:
169 ret = dwarf_readu64 (as, a, addr, &u64, arg);
170 if (ret < 0)
171 return ret;
172 *val = u64;
173 break;
174
175 case ULEB128:
176 ret = dwarf_read_uleb128 (as, a, addr, val, arg);
177 break;
178
179 case SLEB128:
180 ret = dwarf_read_sleb128 (as, a, addr, val, arg);
181 break;
182
183 case OFFSET: /* only used by DW_OP_call_ref, which we don't implement */
184 default:
185 Debug (1, "Unexpected operand type %d\n", operand_type);
186 ret = -UNW_EINVAL;
187 }
188 return ret;
189 }
190
191 HIDDEN int
dwarf_stack_aligned(struct dwarf_cursor * c,unw_word_t cfa_addr,unw_word_t rbp_addr,unw_word_t * cfa_offset)192 dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr,
193 unw_word_t rbp_addr, unw_word_t *cfa_offset) {
194 unw_accessors_t *a;
195 int ret;
196 void *arg;
197 unw_word_t len;
198 uint8_t opcode;
199 unw_word_t operand1;
200
201 a = unw_get_accessors_int (c->as);
202 arg = c->as_arg;
203
204 ret = dwarf_read_uleb128(c->as, a, &rbp_addr, &len, arg);
205 if (len != 2 || ret < 0)
206 return 0;
207
208 ret = dwarf_readu8(c->as, a, &rbp_addr, &opcode, arg);
209 if (ret < 0 || opcode != DW_OP_breg6)
210 return 0;
211
212 ret = read_operand(c->as, a, &rbp_addr,
213 OPND1_TYPE(operands[opcode]), &operand1, arg);
214
215 if (ret < 0 || operand1 != 0)
216 return 0;
217
218 ret = dwarf_read_uleb128(c->as, a, &cfa_addr, &len, arg);
219 if (ret < 0 || len != 3)
220 return 0;
221
222 ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg);
223 if (ret < 0 || opcode != DW_OP_breg6)
224 return 0;
225
226 ret = read_operand(c->as, a, &cfa_addr,
227 OPND1_TYPE(operands[opcode]), &operand1, arg);
228 if (ret < 0)
229 return 0;
230
231 ret = dwarf_readu8(c->as, a, &cfa_addr, &opcode, arg);
232 if (ret < 0 || opcode != DW_OP_deref)
233 return 0;
234
235 *cfa_offset = operand1;
236 return 1;
237 }
238
239 HIDDEN int
dwarf_eval_expr(struct dwarf_cursor * c,unw_word_t stack_val,unw_word_t * addr,unw_word_t len,unw_word_t * valp,int * is_register)240 dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr,
241 unw_word_t len, unw_word_t *valp, int *is_register)
242 {
243 unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr;
244 uint8_t opcode, operands_signature, u8;
245 unw_addr_space_t as;
246 unw_accessors_t *a;
247 void *arg;
248 unw_word_t stack[MAX_EXPR_STACK_SIZE];
249 unsigned int tos = 0;
250 uint16_t u16;
251 uint32_t u32;
252 uint64_t u64;
253 int ret;
254 unw_word_t stackerror = 0;
255
256 // pop() is either followed by a semicolon or
257 // used in a push() macro
258 // In either case we can sneak in an extra statement
259 # define pop() \
260 (((tos - 1) >= MAX_EXPR_STACK_SIZE) ? \
261 stackerror++ : stack[--tos]); \
262 if (stackerror) \
263 { \
264 Debug (1, "Stack underflow\n"); \
265 return -UNW_EINVAL; \
266 }
267
268 // Removed the parentheses on the assignment
269 // to allow the extra stack error check
270 // when x is evaluated
271 # define push(x) \
272 do { \
273 unw_word_t _x = x; \
274 if (tos >= MAX_EXPR_STACK_SIZE) \
275 { \
276 Debug (1, "Stack overflow\n"); \
277 return -UNW_EINVAL; \
278 } \
279 stack[tos++] = _x; \
280 } while (0)
281
282 // Pick is always used in a push() macro
283 // In either case we can sneak in an extra statement
284 # define pick(n) \
285 (((tos - 1 - (n)) >= MAX_EXPR_STACK_SIZE) ? \
286 stackerror++ : stack[tos - 1 - (n)]); \
287 if (stackerror) \
288 { \
289 Debug (1, "Out-of-stack pick\n"); \
290 return -UNW_EINVAL; \
291 }
292
293 as = c->as;
294 arg = c->as_arg;
295 a = unw_get_accessors_int (as);
296 end_addr = *addr + len;
297 *is_register = 0;
298
299 Debug (14, "len=%lu, pushing initial value=0x%lx\n",
300 (unsigned long) len, (unsigned long) stack_val);
301
302 /* The DWARF standard requires the current CFA to be pushed onto the stack */
303 /* before evaluating DW_CFA_expression and DW_CFA_val_expression programs. */
304 /* DW_CFA_def_cfa_expressions do not take an initial value, but we push on */
305 /* a dummy value to keep this logic consistent. */
306 push (stack_val);
307
308 while (*addr < end_addr)
309 {
310 if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0)
311 return ret;
312
313 operands_signature = operands[opcode];
314
315 if (unlikely (NUM_OPERANDS (operands_signature) > 0))
316 {
317 if ((ret = read_operand (as, a, addr,
318 OPND1_TYPE (operands_signature),
319 &operand1, arg)) < 0)
320 return ret;
321 if (NUM_OPERANDS (operands_signature) > 1)
322 if ((ret = read_operand (as, a, addr,
323 OPND2_TYPE (operands_signature),
324 &operand2, arg)) < 0)
325 return ret;
326 }
327
328 switch ((dwarf_expr_op_t) opcode)
329 {
330 case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2:
331 case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5:
332 case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8:
333 case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11:
334 case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14:
335 case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17:
336 case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20:
337 case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23:
338 case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26:
339 case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29:
340 case DW_OP_lit30: case DW_OP_lit31:
341 Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0);
342 push (opcode - DW_OP_lit0);
343 break;
344
345 case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2:
346 case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5:
347 case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8:
348 case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11:
349 case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14:
350 case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17:
351 case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20:
352 case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
353 case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26:
354 case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29:
355 case DW_OP_breg30: case DW_OP_breg31:
356 Debug (15, "OP_breg(r%d,0x%lx)\n",
357 (int) opcode - DW_OP_breg0, (unsigned long) operand1);
358 if ((ret = unw_get_reg (dwarf_to_cursor (c),
359 dwarf_to_unw_regnum (opcode - DW_OP_breg0),
360 &tmp1)) < 0)
361 return ret;
362 push (tmp1 + operand1);
363 break;
364
365 case DW_OP_bregx:
366 Debug (15, "OP_bregx(r%d,0x%lx)\n",
367 (int) operand1, (unsigned long) operand2);
368 if ((ret = unw_get_reg (dwarf_to_cursor (c),
369 dwarf_to_unw_regnum (operand1), &tmp1)) < 0)
370 return ret;
371 push (tmp1 + operand2);
372 break;
373
374 case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2:
375 case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5:
376 case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8:
377 case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11:
378 case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14:
379 case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17:
380 case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20:
381 case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
382 case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26:
383 case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29:
384 case DW_OP_reg30: case DW_OP_reg31:
385 Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0);
386 *valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0);
387 *is_register = 1;
388 return 0;
389
390 case DW_OP_regx:
391 Debug (15, "OP_regx(r%d)\n", (int) operand1);
392 *valp = dwarf_to_unw_regnum (operand1);
393 *is_register = 1;
394 return 0;
395
396 case DW_OP_addr:
397 case DW_OP_const1u:
398 case DW_OP_const2u:
399 case DW_OP_const4u:
400 case DW_OP_const8u:
401 case DW_OP_constu:
402 case DW_OP_const8s:
403 case DW_OP_consts:
404 Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1);
405 push (operand1);
406 break;
407
408 case DW_OP_const1s:
409 if (operand1 & 0x80)
410 operand1 |= ((unw_word_t) -1) << 8;
411 Debug (15, "OP_const1s(%ld)\n", (long) operand1);
412 push (operand1);
413 break;
414
415 case DW_OP_const2s:
416 if (operand1 & 0x8000)
417 operand1 |= ((unw_word_t) -1) << 16;
418 Debug (15, "OP_const2s(%ld)\n", (long) operand1);
419 push (operand1);
420 break;
421
422 case DW_OP_const4s:
423 if (operand1 & 0x80000000)
424 operand1 |= (((unw_word_t) -1) << 16) << 16;
425 Debug (15, "OP_const4s(%ld)\n", (long) operand1);
426 push (operand1);
427 break;
428
429 case DW_OP_deref:
430 Debug (15, "OP_deref\n");
431 tmp1 = pop ();
432 if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0)
433 return ret;
434 push (tmp2);
435 break;
436
437 case DW_OP_deref_size:
438 Debug (15, "OP_deref_size(%d)\n", (int) operand1);
439 tmp1 = pop ();
440 switch (operand1)
441 {
442 default:
443 Debug (1, "Unexpected DW_OP_deref_size size %d\n",
444 (int) operand1);
445 return -UNW_EINVAL;
446
447 case 1:
448 if ((ret = dwarf_readu8 (as, a, &tmp1, &u8, arg)) < 0)
449 return ret;
450 tmp2 = u8;
451 break;
452
453 case 2:
454 if ((ret = dwarf_readu16 (as, a, &tmp1, &u16, arg)) < 0)
455 return ret;
456 tmp2 = u16;
457 break;
458
459 case 3:
460 case 4:
461 if ((ret = dwarf_readu32 (as, a, &tmp1, &u32, arg)) < 0)
462 return ret;
463 tmp2 = u32;
464 if (operand1 == 3)
465 {
466 if (dwarf_is_big_endian (as))
467 tmp2 >>= 8;
468 else
469 tmp2 &= 0xffffff;
470 }
471 break;
472 case 5:
473 case 6:
474 case 7:
475 case 8:
476 if ((ret = dwarf_readu64 (as, a, &tmp1, &u64, arg)) < 0)
477 return ret;
478 tmp2 = u64;
479 if (operand1 != 8)
480 {
481 if (dwarf_is_big_endian (as))
482 tmp2 >>= 64 - 8 * operand1;
483 else
484 tmp2 &= (~ (unw_word_t) 0) << (8 * operand1);
485 }
486 break;
487 }
488 push (tmp2);
489 break;
490
491 case DW_OP_dup:
492 Debug (15, "OP_dup\n");
493 push (pick (0));
494 break;
495
496 case DW_OP_drop:
497 Debug (15, "OP_drop\n");
498 (void) pop ();
499 break;
500
501 case DW_OP_pick:
502 Debug (15, "OP_pick(%d)\n", (int) operand1);
503 push (pick (operand1));
504 break;
505
506 case DW_OP_over:
507 Debug (15, "OP_over\n");
508 push (pick (1));
509 break;
510
511 case DW_OP_swap:
512 Debug (15, "OP_swap\n");
513 tmp1 = pop ();
514 tmp2 = pop ();
515 push (tmp1);
516 push (tmp2);
517 break;
518
519 case DW_OP_rot:
520 Debug (15, "OP_rot\n");
521 tmp1 = pop ();
522 tmp2 = pop ();
523 tmp3 = pop ();
524 push (tmp1);
525 push (tmp3);
526 push (tmp2);
527 break;
528
529 case DW_OP_abs:
530 Debug (15, "OP_abs\n");
531 tmp1 = pop ();
532 if (tmp1 & ((unw_word_t) 1 << (8 * dwarf_addr_size (as) - 1)))
533 tmp1 = (~tmp1 + 1);
534 push (tmp1);
535 break;
536
537 case DW_OP_and:
538 Debug (15, "OP_and\n");
539 tmp1 = pop ();
540 tmp2 = pop ();
541 push (tmp1 & tmp2);
542 break;
543
544 case DW_OP_div:
545 Debug (15, "OP_div\n");
546 tmp1 = pop ();
547 tmp2 = pop ();
548 if (tmp1)
549 tmp1 = sword (as, tmp2) / sword (as, tmp1);
550 push (tmp1);
551 break;
552
553 case DW_OP_minus:
554 Debug (15, "OP_minus\n");
555 tmp1 = pop ();
556 tmp2 = pop ();
557 tmp1 = tmp2 - tmp1;
558 push (tmp1);
559 break;
560
561 case DW_OP_mod:
562 Debug (15, "OP_mod\n");
563 tmp1 = pop ();
564 tmp2 = pop ();
565 if (tmp1)
566 tmp1 = tmp2 % tmp1;
567 push (tmp1);
568 break;
569
570 case DW_OP_mul:
571 Debug (15, "OP_mul\n");
572 tmp1 = pop ();
573 tmp2 = pop ();
574 if (tmp1)
575 tmp1 = tmp2 * tmp1;
576 push (tmp1);
577 break;
578
579 case DW_OP_neg:
580 Debug (15, "OP_neg\n");
581 tmp1 = pop ();
582 push (~tmp1 + 1);
583 break;
584
585 case DW_OP_not:
586 Debug (15, "OP_not\n");
587 push (~pop ());
588 break;
589
590 case DW_OP_or:
591 Debug (15, "OP_or\n");
592 tmp1 = pop ();
593 tmp2 = pop ();
594 push (tmp1 | tmp2);
595 break;
596
597 case DW_OP_plus:
598 Debug (15, "OP_plus\n");
599 tmp1 = pop ();
600 tmp2 = pop ();
601 push (tmp1 + tmp2);
602 break;
603
604 case DW_OP_plus_uconst:
605 Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1);
606 tmp1 = pop ();
607 push (tmp1 + operand1);
608 break;
609
610 case DW_OP_shl:
611 Debug (15, "OP_shl\n");
612 tmp1 = pop ();
613 tmp2 = pop ();
614 push (tmp2 << tmp1);
615 break;
616
617 case DW_OP_shr:
618 Debug (15, "OP_shr\n");
619 tmp1 = pop ();
620 tmp2 = pop ();
621 push (tmp2 >> tmp1);
622 break;
623
624 case DW_OP_shra:
625 Debug (15, "OP_shra\n");
626 tmp1 = pop ();
627 tmp2 = pop ();
628 push (sword (as, tmp2) >> tmp1);
629 break;
630
631 case DW_OP_xor:
632 Debug (15, "OP_xor\n");
633 tmp1 = pop ();
634 tmp2 = pop ();
635 push (tmp1 ^ tmp2);
636 break;
637
638 case DW_OP_le:
639 Debug (15, "OP_le\n");
640 tmp1 = pop ();
641 tmp2 = pop ();
642 push (sword (as, tmp2) <= sword (as, tmp1));
643 break;
644
645 case DW_OP_ge:
646 Debug (15, "OP_ge\n");
647 tmp1 = pop ();
648 tmp2 = pop ();
649 push (sword (as, tmp2) >= sword (as, tmp1));
650 break;
651
652 case DW_OP_eq:
653 Debug (15, "OP_eq\n");
654 tmp1 = pop ();
655 tmp2 = pop ();
656 push (sword (as, tmp2) == sword (as, tmp1));
657 break;
658
659 case DW_OP_lt:
660 Debug (15, "OP_lt\n");
661 tmp1 = pop ();
662 tmp2 = pop ();
663 push (sword (as, tmp2) < sword (as, tmp1));
664 break;
665
666 case DW_OP_gt:
667 Debug (15, "OP_gt\n");
668 tmp1 = pop ();
669 tmp2 = pop ();
670 push (sword (as, tmp2) > sword (as, tmp1));
671 break;
672
673 case DW_OP_ne:
674 Debug (15, "OP_ne\n");
675 tmp1 = pop ();
676 tmp2 = pop ();
677 push (sword (as, tmp2) != sword (as, tmp1));
678 break;
679
680 case DW_OP_skip:
681 Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
682 *addr += (int16_t) operand1;
683 break;
684
685 case DW_OP_bra:
686 Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
687 tmp1 = pop ();
688 if (tmp1)
689 *addr += (int16_t) operand1;
690 break;
691
692 case DW_OP_nop:
693 Debug (15, "OP_nop\n");
694 break;
695
696 case DW_OP_call2:
697 case DW_OP_call4:
698 case DW_OP_call_ref:
699 case DW_OP_fbreg:
700 case DW_OP_piece:
701 case DW_OP_push_object_address:
702 case DW_OP_xderef:
703 case DW_OP_xderef_size:
704 default:
705 Debug (1, "Unexpected opcode 0x%x\n", opcode);
706 return -UNW_EINVAL;
707 }
708 }
709 *valp = pop ();
710 Debug (14, "final value = 0x%lx\n", (unsigned long) *valp);
711 return 0;
712 }
713