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 asignment
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;
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 push (-pop ());
582 break;
583
584 case DW_OP_not:
585 Debug (15, "OP_not\n");
586 push (~pop ());
587 break;
588
589 case DW_OP_or:
590 Debug (15, "OP_or\n");
591 tmp1 = pop ();
592 tmp2 = pop ();
593 push (tmp1 | tmp2);
594 break;
595
596 case DW_OP_plus:
597 Debug (15, "OP_plus\n");
598 tmp1 = pop ();
599 tmp2 = pop ();
600 push (tmp1 + tmp2);
601 break;
602
603 case DW_OP_plus_uconst:
604 Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1);
605 tmp1 = pop ();
606 push (tmp1 + operand1);
607 break;
608
609 case DW_OP_shl:
610 Debug (15, "OP_shl\n");
611 tmp1 = pop ();
612 tmp2 = pop ();
613 push (tmp2 << tmp1);
614 break;
615
616 case DW_OP_shr:
617 Debug (15, "OP_shr\n");
618 tmp1 = pop ();
619 tmp2 = pop ();
620 push (tmp2 >> tmp1);
621 break;
622
623 case DW_OP_shra:
624 Debug (15, "OP_shra\n");
625 tmp1 = pop ();
626 tmp2 = pop ();
627 push (sword (as, tmp2) >> tmp1);
628 break;
629
630 case DW_OP_xor:
631 Debug (15, "OP_xor\n");
632 tmp1 = pop ();
633 tmp2 = pop ();
634 push (tmp1 ^ tmp2);
635 break;
636
637 case DW_OP_le:
638 Debug (15, "OP_le\n");
639 tmp1 = pop ();
640 tmp2 = pop ();
641 push (sword (as, tmp2) <= sword (as, tmp1));
642 break;
643
644 case DW_OP_ge:
645 Debug (15, "OP_ge\n");
646 tmp1 = pop ();
647 tmp2 = pop ();
648 push (sword (as, tmp2) >= sword (as, tmp1));
649 break;
650
651 case DW_OP_eq:
652 Debug (15, "OP_eq\n");
653 tmp1 = pop ();
654 tmp2 = pop ();
655 push (sword (as, tmp2) == sword (as, tmp1));
656 break;
657
658 case DW_OP_lt:
659 Debug (15, "OP_lt\n");
660 tmp1 = pop ();
661 tmp2 = pop ();
662 push (sword (as, tmp2) < sword (as, tmp1));
663 break;
664
665 case DW_OP_gt:
666 Debug (15, "OP_gt\n");
667 tmp1 = pop ();
668 tmp2 = pop ();
669 push (sword (as, tmp2) > sword (as, tmp1));
670 break;
671
672 case DW_OP_ne:
673 Debug (15, "OP_ne\n");
674 tmp1 = pop ();
675 tmp2 = pop ();
676 push (sword (as, tmp2) != sword (as, tmp1));
677 break;
678
679 case DW_OP_skip:
680 Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
681 *addr += (int16_t) operand1;
682 break;
683
684 case DW_OP_bra:
685 Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
686 tmp1 = pop ();
687 if (tmp1)
688 *addr += (int16_t) operand1;
689 break;
690
691 case DW_OP_nop:
692 Debug (15, "OP_nop\n");
693 break;
694
695 case DW_OP_call2:
696 case DW_OP_call4:
697 case DW_OP_call_ref:
698 case DW_OP_fbreg:
699 case DW_OP_piece:
700 case DW_OP_push_object_address:
701 case DW_OP_xderef:
702 case DW_OP_xderef_size:
703 default:
704 Debug (1, "Unexpected opcode 0x%x\n", opcode);
705 return -UNW_EINVAL;
706 }
707 }
708 *valp = pop ();
709 Debug (14, "final value = 0x%lx\n", (unsigned long) *valp);
710 return 0;
711 }
712