vfs: check userland buffers before reading them.
[haiku.git] / src / libs / libunwind / dwarf / Gexpr.c
blobb56bb317ab24493c06d1b406626680bd82e6ef70
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>
5 This file is part of libunwind.
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:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
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. */
26 #include "dwarf_i.h"
27 #include "libunwind_i.h"
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
35 #define NUM_OPERANDS(signature) (((signature) >> 6) & 0x3)
36 #define OPND1_TYPE(signature) (((signature) >> 3) & 0x7)
37 #define OPND2_TYPE(signature) (((signature) >> 0) & 0x7)
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)
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. */
52 static const uint8_t operands[256] =
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)
110 static inline unw_sword_t
111 sword (unw_addr_space_t as, unw_word_t val)
113 switch (dwarf_addr_size (as))
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 ();
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)
127 uint8_t u8;
128 uint16_t u16;
129 uint32_t u32;
130 uint64_t u64;
131 int ret;
133 if (operand_type == ADDR)
134 switch (dwarf_addr_size (as))
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 ();
143 switch (operand_type)
145 case VAL8:
146 ret = dwarf_readu8 (as, a, addr, &u8, arg);
147 if (ret < 0)
148 return ret;
149 *val = u8;
150 break;
152 case VAL16:
153 ret = dwarf_readu16 (as, a, addr, &u16, arg);
154 if (ret < 0)
155 return ret;
156 *val = u16;
157 break;
159 case VAL32:
160 ret = dwarf_readu32 (as, a, addr, &u32, arg);
161 if (ret < 0)
162 return ret;
163 *val = u32;
164 break;
166 case VAL64:
167 ret = dwarf_readu64 (as, a, addr, &u64, arg);
168 if (ret < 0)
169 return ret;
170 *val = u64;
171 break;
173 case ULEB128:
174 ret = dwarf_read_uleb128 (as, a, addr, val, arg);
175 break;
177 case SLEB128:
178 ret = dwarf_read_sleb128 (as, a, addr, val, arg);
179 break;
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;
186 return ret;
189 HIDDEN int
190 dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len,
191 unw_word_t *valp, int *is_register)
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) \
208 Debug (1, "Stack underflow\n"); \
209 return -UNW_EINVAL; \
211 stack[--tos]; \
213 # define push(x) \
214 do { \
215 unw_word_t _x = (x); \
216 if (tos >= MAX_EXPR_STACK_SIZE) \
218 Debug (1, "Stack overflow\n"); \
219 return -UNW_EINVAL; \
221 stack[tos++] = _x; \
222 } while (0)
223 # define pick(n) \
224 ({ \
225 unsigned int _index = tos - 1 - (n); \
226 if (_index >= MAX_EXPR_STACK_SIZE) \
228 Debug (1, "Out-of-stack pick\n"); \
229 return -UNW_EINVAL; \
231 stack[_index]; \
234 as = c->as;
235 arg = c->as_arg;
236 a = unw_get_accessors (as);
237 end_addr = *addr + len;
238 *is_register = 0;
240 Debug (14, "len=%lu, pushing cfa=0x%lx\n",
241 (unsigned long) len, (unsigned long) c->cfa);
243 push (c->cfa); /* push current CFA as required by DWARF spec */
245 while (*addr < end_addr)
247 if ((ret = dwarf_readu8 (as, a, addr, &opcode, arg)) < 0)
248 return ret;
250 operands_signature = operands[opcode];
252 if (unlikely (NUM_OPERANDS (operands_signature) > 0))
254 if ((ret = read_operand (as, a, addr,
255 OPND1_TYPE (operands_signature),
256 &operand1, arg)) < 0)
257 return ret;
258 if (NUM_OPERANDS (operands_signature) > 1)
259 if ((ret = read_operand (as, a, addr,
260 OPND2_TYPE (operands_signature),
261 &operand2, arg)) < 0)
262 return ret;
265 switch ((dwarf_expr_op_t) opcode)
267 case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2:
268 case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5:
269 case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8:
270 case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11:
271 case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14:
272 case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17:
273 case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20:
274 case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23:
275 case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26:
276 case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29:
277 case DW_OP_lit30: case DW_OP_lit31:
278 Debug (15, "OP_lit(%d)\n", (int) opcode - DW_OP_lit0);
279 push (opcode - DW_OP_lit0);
280 break;
282 case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2:
283 case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5:
284 case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8:
285 case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11:
286 case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14:
287 case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17:
288 case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20:
289 case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
290 case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26:
291 case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29:
292 case DW_OP_breg30: case DW_OP_breg31:
293 Debug (15, "OP_breg(r%d,0x%lx)\n",
294 (int) opcode - DW_OP_breg0, (unsigned long) operand1);
295 if ((ret = unw_get_reg (dwarf_to_cursor (c),
296 dwarf_to_unw_regnum (opcode - DW_OP_breg0),
297 &tmp1)) < 0)
298 return ret;
299 push (tmp1 + operand1);
300 break;
302 case DW_OP_bregx:
303 Debug (15, "OP_bregx(r%d,0x%lx)\n",
304 (int) operand1, (unsigned long) operand2);
305 if ((ret = unw_get_reg (dwarf_to_cursor (c),
306 dwarf_to_unw_regnum (operand1), &tmp1)) < 0)
307 return ret;
308 push (tmp1 + operand2);
309 break;
311 case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2:
312 case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5:
313 case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8:
314 case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11:
315 case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14:
316 case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17:
317 case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20:
318 case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
319 case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26:
320 case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29:
321 case DW_OP_reg30: case DW_OP_reg31:
322 Debug (15, "OP_reg(r%d)\n", (int) opcode - DW_OP_reg0);
323 *valp = dwarf_to_unw_regnum (opcode - DW_OP_reg0);
324 *is_register = 1;
325 return 0;
327 case DW_OP_regx:
328 Debug (15, "OP_regx(r%d)\n", (int) operand1);
329 *valp = dwarf_to_unw_regnum (operand1);
330 *is_register = 1;
331 return 0;
333 case DW_OP_addr:
334 case DW_OP_const1u:
335 case DW_OP_const2u:
336 case DW_OP_const4u:
337 case DW_OP_const8u:
338 case DW_OP_constu:
339 case DW_OP_const8s:
340 case DW_OP_consts:
341 Debug (15, "OP_const(0x%lx)\n", (unsigned long) operand1);
342 push (operand1);
343 break;
345 case DW_OP_const1s:
346 if (operand1 & 0x80)
347 operand1 |= ((unw_word_t) -1) << 8;
348 Debug (15, "OP_const1s(%ld)\n", (long) operand1);
349 push (operand1);
350 break;
352 case DW_OP_const2s:
353 if (operand1 & 0x8000)
354 operand1 |= ((unw_word_t) -1) << 16;
355 Debug (15, "OP_const2s(%ld)\n", (long) operand1);
356 push (operand1);
357 break;
359 case DW_OP_const4s:
360 if (operand1 & 0x80000000)
361 operand1 |= (((unw_word_t) -1) << 16) << 16;
362 Debug (15, "OP_const4s(%ld)\n", (long) operand1);
363 push (operand1);
364 break;
366 case DW_OP_deref:
367 Debug (15, "OP_deref\n");
368 tmp1 = pop ();
369 if ((ret = dwarf_readw (as, a, &tmp1, &tmp2, arg)) < 0)
370 return ret;
371 push (tmp2);
372 break;
374 case DW_OP_deref_size:
375 Debug (15, "OP_deref_size(%d)\n", (int) operand1);
376 tmp1 = pop ();
377 switch (operand1)
379 default:
380 Debug (1, "Unexpected DW_OP_deref_size size %d\n",
381 (int) operand1);
382 return -UNW_EINVAL;
384 case 1:
385 if ((ret = dwarf_readu8 (as, a, &tmp1, &u8, arg)) < 0)
386 return ret;
387 tmp2 = u8;
388 break;
390 case 2:
391 if ((ret = dwarf_readu16 (as, a, &tmp1, &u16, arg)) < 0)
392 return ret;
393 tmp2 = u16;
394 break;
396 case 3:
397 case 4:
398 if ((ret = dwarf_readu32 (as, a, &tmp1, &u32, arg)) < 0)
399 return ret;
400 tmp2 = u32;
401 if (operand1 == 3)
403 if (dwarf_is_big_endian (as))
404 tmp2 >>= 8;
405 else
406 tmp2 &= 0xffffff;
408 break;
409 case 5:
410 case 6:
411 case 7:
412 case 8:
413 if ((ret = dwarf_readu64 (as, a, &tmp1, &u64, arg)) < 0)
414 return ret;
415 tmp2 = u64;
416 if (operand1 != 8)
418 if (dwarf_is_big_endian (as))
419 tmp2 >>= 64 - 8 * operand1;
420 else
421 tmp2 &= (~ (unw_word_t) 0) << (8 * operand1);
423 break;
425 push (tmp2);
426 break;
428 case DW_OP_dup:
429 Debug (15, "OP_dup\n");
430 push (pick (0));
431 break;
433 case DW_OP_drop:
434 Debug (15, "OP_drop\n");
435 (void) pop ();
436 break;
438 case DW_OP_pick:
439 Debug (15, "OP_pick(%d)\n", (int) operand1);
440 push (pick (operand1));
441 break;
443 case DW_OP_over:
444 Debug (15, "OP_over\n");
445 push (pick (1));
446 break;
448 case DW_OP_swap:
449 Debug (15, "OP_swap\n");
450 tmp1 = pop ();
451 tmp2 = pop ();
452 push (tmp1);
453 push (tmp2);
454 break;
456 case DW_OP_rot:
457 Debug (15, "OP_rot\n");
458 tmp1 = pop ();
459 tmp2 = pop ();
460 tmp3 = pop ();
461 push (tmp1);
462 push (tmp3);
463 push (tmp2);
464 break;
466 case DW_OP_abs:
467 Debug (15, "OP_abs\n");
468 tmp1 = pop ();
469 if (tmp1 & ((unw_word_t) 1 << (8 * dwarf_addr_size (as) - 1)))
470 tmp1 = -tmp1;
471 push (tmp1);
472 break;
474 case DW_OP_and:
475 Debug (15, "OP_and\n");
476 tmp1 = pop ();
477 tmp2 = pop ();
478 push (tmp1 & tmp2);
479 break;
481 case DW_OP_div:
482 Debug (15, "OP_div\n");
483 tmp1 = pop ();
484 tmp2 = pop ();
485 if (tmp1)
486 tmp1 = sword (as, tmp2) / sword (as, tmp1);
487 push (tmp1);
488 break;
490 case DW_OP_minus:
491 Debug (15, "OP_minus\n");
492 tmp1 = pop ();
493 tmp2 = pop ();
494 tmp1 = tmp2 - tmp1;
495 push (tmp1);
496 break;
498 case DW_OP_mod:
499 Debug (15, "OP_mod\n");
500 tmp1 = pop ();
501 tmp2 = pop ();
502 if (tmp1)
503 tmp1 = tmp2 % tmp1;
504 push (tmp1);
505 break;
507 case DW_OP_mul:
508 Debug (15, "OP_mul\n");
509 tmp1 = pop ();
510 tmp2 = pop ();
511 if (tmp1)
512 tmp1 = tmp2 * tmp1;
513 push (tmp1);
514 break;
516 case DW_OP_neg:
517 Debug (15, "OP_neg\n");
518 push (-pop ());
519 break;
521 case DW_OP_not:
522 Debug (15, "OP_not\n");
523 push (~pop ());
524 break;
526 case DW_OP_or:
527 Debug (15, "OP_or\n");
528 tmp1 = pop ();
529 tmp2 = pop ();
530 push (tmp1 | tmp2);
531 break;
533 case DW_OP_plus:
534 Debug (15, "OP_plus\n");
535 tmp1 = pop ();
536 tmp2 = pop ();
537 push (tmp1 + tmp2);
538 break;
540 case DW_OP_plus_uconst:
541 Debug (15, "OP_plus_uconst(%lu)\n", (unsigned long) operand1);
542 tmp1 = pop ();
543 push (tmp1 + operand1);
544 break;
546 case DW_OP_shl:
547 Debug (15, "OP_shl\n");
548 tmp1 = pop ();
549 tmp2 = pop ();
550 push (tmp2 << tmp1);
551 break;
553 case DW_OP_shr:
554 Debug (15, "OP_shr\n");
555 tmp1 = pop ();
556 tmp2 = pop ();
557 push (tmp2 >> tmp1);
558 break;
560 case DW_OP_shra:
561 Debug (15, "OP_shra\n");
562 tmp1 = pop ();
563 tmp2 = pop ();
564 push (sword (as, tmp2) >> tmp1);
565 break;
567 case DW_OP_xor:
568 Debug (15, "OP_xor\n");
569 tmp1 = pop ();
570 tmp2 = pop ();
571 push (tmp1 ^ tmp2);
572 break;
574 case DW_OP_le:
575 Debug (15, "OP_le\n");
576 tmp1 = pop ();
577 tmp2 = pop ();
578 push (sword (as, tmp2) <= sword (as, tmp1));
579 break;
581 case DW_OP_ge:
582 Debug (15, "OP_ge\n");
583 tmp1 = pop ();
584 tmp2 = pop ();
585 push (sword (as, tmp2) >= sword (as, tmp1));
586 break;
588 case DW_OP_eq:
589 Debug (15, "OP_eq\n");
590 tmp1 = pop ();
591 tmp2 = pop ();
592 push (sword (as, tmp2) == sword (as, tmp1));
593 break;
595 case DW_OP_lt:
596 Debug (15, "OP_lt\n");
597 tmp1 = pop ();
598 tmp2 = pop ();
599 push (sword (as, tmp2) < sword (as, tmp1));
600 break;
602 case DW_OP_gt:
603 Debug (15, "OP_gt\n");
604 tmp1 = pop ();
605 tmp2 = pop ();
606 push (sword (as, tmp2) > sword (as, tmp1));
607 break;
609 case DW_OP_ne:
610 Debug (15, "OP_ne\n");
611 tmp1 = pop ();
612 tmp2 = pop ();
613 push (sword (as, tmp2) != sword (as, tmp1));
614 break;
616 case DW_OP_skip:
617 Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
618 *addr += (int16_t) operand1;
619 break;
621 case DW_OP_bra:
622 Debug (15, "OP_skip(%d)\n", (int16_t) operand1);
623 tmp1 = pop ();
624 if (tmp1)
625 *addr += (int16_t) operand1;
626 break;
628 case DW_OP_nop:
629 Debug (15, "OP_nop\n");
630 break;
632 case DW_OP_call2:
633 case DW_OP_call4:
634 case DW_OP_call_ref:
635 case DW_OP_fbreg:
636 case DW_OP_piece:
637 case DW_OP_push_object_address:
638 case DW_OP_xderef:
639 case DW_OP_xderef_size:
640 default:
641 Debug (1, "Unexpected opcode 0x%x\n", opcode);
642 return -UNW_EINVAL;
645 *valp = pop ();
646 Debug (14, "final value = 0x%lx\n", (unsigned long) *valp);
647 return 0;