Branch data Line data Source code
1 : : /* Get previous frame state for an existing frame state.
2 : : Copyright (C) 2013, 2014, 2016 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : :
5 : : This file is free software; you can redistribute it and/or modify
6 : : it under the terms of either
7 : :
8 : : * the GNU Lesser General Public License as published by the Free
9 : : Software Foundation; either version 3 of the License, or (at
10 : : your option) any later version
11 : :
12 : : or
13 : :
14 : : * the GNU General Public License as published by the Free
15 : : Software Foundation; either version 2 of the License, or (at
16 : : your option) any later version
17 : :
18 : : or both in parallel, as here.
19 : :
20 : : elfutils is distributed in the hope that it will be useful, but
21 : : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : : General Public License for more details.
24 : :
25 : : You should have received copies of the GNU General Public License and
26 : : the GNU Lesser General Public License along with this program. If
27 : : not, see <http://www.gnu.org/licenses/>. */
28 : :
29 : : #ifdef HAVE_CONFIG_H
30 : : # include <config.h>
31 : : #endif
32 : :
33 : : #include "cfi.h"
34 : : #include <stdlib.h>
35 : : #include "libdwflP.h"
36 : : #include "dwarf.h"
37 : : #include <system.h>
38 : :
39 : : /* Maximum number of DWARF expression stack slots before returning an error. */
40 : : #define DWARF_EXPR_STACK_MAX 0x100
41 : :
42 : : /* Maximum number of DWARF expression executed operations before returning an
43 : : error. */
44 : : #define DWARF_EXPR_STEPS_MAX 0x1000
45 : :
46 : : int
47 : : internal_function
48 : 3650 : __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
49 : : {
50 : 3650 : Ebl *ebl = state->thread->process->ebl;
51 [ + + ]: 3650 : if (! ebl_dwarf_to_regno (ebl, ®no))
52 : : return -1;
53 [ + - ]: 3642 : if (regno >= ebl_frame_nregs (ebl))
54 : : return -1;
55 : 3642 : if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
56 [ + + ]: 3642 : & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
57 : : return 1;
58 [ + - ]: 1998 : if (val)
59 : 1998 : *val = state->regs[regno];
60 : : return 0;
61 : : }
62 : :
63 : : bool
64 : : internal_function
65 : 2686 : __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
66 : : {
67 : 2686 : Ebl *ebl = state->thread->process->ebl;
68 [ + + ]: 2686 : if (! ebl_dwarf_to_regno (ebl, ®no))
69 : : return false;
70 [ + - ]: 2678 : if (regno >= ebl_frame_nregs (ebl))
71 : : return false;
72 : : /* For example i386 user_regs_struct has signed fields. */
73 [ + + ]: 2678 : if (ebl_get_elfclass (ebl) == ELFCLASS32)
74 : 799 : val &= 0xffffffff;
75 : 2678 : state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
76 : 2678 : ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)));
77 : 2678 : state->regs[regno] = val;
78 : 2678 : return true;
79 : : }
80 : :
81 : : static int
82 : 468 : bra_compar (const void *key_voidp, const void *elem_voidp)
83 : : {
84 : 468 : Dwarf_Word offset = (uintptr_t) key_voidp;
85 : 468 : const Dwarf_Op *op = elem_voidp;
86 [ + + ]: 468 : return (offset > op->offset) - (offset < op->offset);
87 : : }
88 : :
89 : : struct eval_stack {
90 : : Dwarf_Addr *addrs;
91 : : size_t used;
92 : : size_t allocated;
93 : : };
94 : :
95 : : static bool
96 : 2380 : do_push (struct eval_stack *stack, Dwarf_Addr val)
97 : : {
98 [ - + ]: 2380 : if (stack->used >= DWARF_EXPR_STACK_MAX)
99 : : {
100 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
101 : 0 : return false;
102 : : }
103 [ + + ]: 2380 : if (stack->used == stack->allocated)
104 : : {
105 : 1514 : stack->allocated = MAX (stack->allocated * 2, 32);
106 : 1514 : Dwarf_Addr *new_addrs;
107 : 1514 : new_addrs = realloc (stack->addrs,
108 : : stack->allocated * sizeof (*stack->addrs));
109 [ - + ]: 1514 : if (new_addrs == NULL)
110 : : {
111 : 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
112 : 0 : return false;
113 : : }
114 : 1514 : stack->addrs = new_addrs;
115 : : }
116 : 2380 : stack->addrs[stack->used++] = val;
117 : 2380 : return true;
118 : : }
119 : :
120 : : static bool
121 : 2376 : do_pop (struct eval_stack *stack, Dwarf_Addr *val)
122 : : {
123 [ - + ]: 2376 : if (stack->used == 0)
124 : : {
125 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
126 : 0 : return false;
127 : : }
128 : 2376 : *val = stack->addrs[--stack->used];
129 : 2376 : return true;
130 : : }
131 : :
132 : : /* If FRAME is NULL is are computing CFI frame base. In such case another
133 : : DW_OP_call_frame_cfa is no longer permitted. */
134 : :
135 : : static bool
136 : 1524 : expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
137 : : size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
138 : : {
139 : 1524 : Dwfl_Process *process = state->thread->process;
140 [ - + ]: 1524 : if (nops == 0)
141 : : {
142 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
143 : 0 : return false;
144 : : }
145 : 1524 : struct eval_stack stack =
146 : : {
147 : : .addrs = NULL,
148 : : .used = 0,
149 : : .allocated = 0
150 : : };
151 : :
152 : : #define pop(x) do_pop(&stack, x)
153 : : #define push(x) do_push(&stack, x)
154 : :
155 : 1524 : Dwarf_Addr val1, val2;
156 : 1524 : bool is_location = false;
157 : 1524 : size_t steps_count = 0;
158 [ + + ]: 4086 : for (const Dwarf_Op *op = ops; op < ops + nops; op++)
159 : : {
160 [ - + ]: 2572 : if (++steps_count > DWARF_EXPR_STEPS_MAX)
161 : : {
162 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
163 : 0 : return false;
164 : : }
165 [ + - - + : 2572 : switch (op->atom)
- + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - +
+ - + ]
166 : : {
167 : : /* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op: */
168 : 114 : case DW_OP_lit0 ... DW_OP_lit31:
169 [ - + ]: 114 : if (! push (op->atom - DW_OP_lit0))
170 : : {
171 : 0 : free (stack.addrs);
172 : 10 : return false;
173 : : }
174 : 2562 : break;
175 : 0 : case DW_OP_addr:
176 [ # # ]: 0 : if (! push (op->number + bias))
177 : : {
178 : 0 : free (stack.addrs);
179 : 0 : return false;
180 : : }
181 : : break;
182 : 0 : case DW_OP_GNU_encoded_addr:
183 : : /* Missing support in the rest of elfutils. */
184 : 0 : __libdwfl_seterrno (DWFL_E_UNSUPPORTED_DWARF);
185 : 0 : return false;
186 : 35 : case DW_OP_const1u:
187 : : case DW_OP_const1s:
188 : : case DW_OP_const2u:
189 : : case DW_OP_const2s:
190 : : case DW_OP_const4u:
191 : : case DW_OP_const4s:
192 : : case DW_OP_const8u:
193 : : case DW_OP_const8s:
194 : : case DW_OP_constu:
195 : : case DW_OP_consts:
196 [ - + ]: 35 : if (! push (op->number))
197 : : {
198 : 0 : free (stack.addrs);
199 : 0 : return false;
200 : : }
201 : : break;
202 : 0 : case DW_OP_reg0 ... DW_OP_reg31:
203 [ # # ]: 0 : if (INTUSE (dwfl_frame_reg) (state, op->atom - DW_OP_reg0, &val1) != 0
204 [ # # ]: 0 : || ! push (val1))
205 : : {
206 : 0 : free (stack.addrs);
207 : 0 : return false;
208 : : }
209 : : break;
210 : 72 : case DW_OP_regx:
211 [ + - - + ]: 72 : if (INTUSE (dwfl_frame_reg) (state, op->number, &val1) != 0 || ! push (val1))
212 : : {
213 : 0 : free (stack.addrs);
214 : 0 : return false;
215 : : }
216 : : break;
217 : 10 : case DW_OP_breg0 ... DW_OP_breg31:
218 [ - + ]: 10 : if (INTUSE (dwfl_frame_reg) (state, op->atom - DW_OP_breg0, &val1) != 0)
219 : : {
220 : 0 : free (stack.addrs);
221 : 0 : return false;
222 : : }
223 : 10 : val1 += op->number;
224 [ - + ]: 10 : if (! push (val1))
225 : : {
226 : 0 : free (stack.addrs);
227 : 0 : return false;
228 : : }
229 : : break;
230 : 720 : case DW_OP_bregx:
231 [ + + ]: 720 : if (INTUSE (dwfl_frame_reg) (state, op->number, &val1) != 0)
232 : : {
233 : 5 : free (stack.addrs);
234 : 5 : return false;
235 : : }
236 : 715 : val1 += op->number2;
237 [ - + ]: 715 : if (! push (val1))
238 : : {
239 : 0 : free (stack.addrs);
240 : 0 : return false;
241 : : }
242 : : break;
243 : 1 : case DW_OP_dup:
244 [ + - + - : 1 : if (! pop (&val1) || ! push (val1) || ! push (val1))
- + ]
245 : : {
246 : 0 : free (stack.addrs);
247 : 0 : return false;
248 : : }
249 : : break;
250 : 1 : case DW_OP_drop:
251 [ - + ]: 1 : if (! pop (&val1))
252 : : {
253 : 0 : free (stack.addrs);
254 : 0 : return false;
255 : : }
256 : : break;
257 : 2 : case DW_OP_pick:
258 [ - + ]: 2 : if (stack.used <= op->number)
259 : : {
260 : 0 : free (stack.addrs);
261 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
262 : 0 : return false;
263 : : }
264 [ - + ]: 2 : if (! push (stack.addrs[stack.used - 1 - op->number]))
265 : : {
266 : 0 : free (stack.addrs);
267 : 0 : return false;
268 : : }
269 : : break;
270 : 7 : case DW_OP_over:
271 [ + - + - ]: 7 : if (! pop (&val1) || ! pop (&val2)
272 [ + - + - : 7 : || ! push (val2) || ! push (val1) || ! push (val2))
- + ]
273 : : {
274 : 0 : free (stack.addrs);
275 : 0 : return false;
276 : : }
277 : : break;
278 : 1 : case DW_OP_swap:
279 [ + - + - : 1 : if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
+ - - + ]
280 : : {
281 : 0 : free (stack.addrs);
282 : 0 : return false;
283 : : }
284 : : break;
285 : 1 : case DW_OP_rot:
286 : : {
287 : 1 : Dwarf_Addr val3;
288 [ + - + - : 1 : if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
+ - ]
289 [ + - + - : 1 : || ! push (val1) || ! push (val3) || ! push (val2))
- + ]
290 : : {
291 : 0 : free (stack.addrs);
292 : 0 : return false;
293 : : }
294 : : }
295 : 1 : break;
296 : 6 : case DW_OP_deref:
297 : : case DW_OP_deref_size:
298 [ - + ]: 6 : if (process->callbacks->memory_read == NULL)
299 : : {
300 : 0 : free (stack.addrs);
301 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
302 : 0 : return false;
303 : : }
304 [ + - ]: 6 : if (! pop (&val1)
305 [ - + ]: 6 : || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
306 : : process->callbacks_arg))
307 : : {
308 : 0 : free (stack.addrs);
309 : 0 : return false;
310 : : }
311 [ - + ]: 6 : if (op->atom == DW_OP_deref_size)
312 : : {
313 : 0 : const int elfclass = frame->cache->e_ident[EI_CLASS];
314 [ # # ]: 0 : const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
315 [ # # ]: 0 : if (op->number > addr_bytes)
316 : : {
317 : 0 : free (stack.addrs);
318 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
319 : 0 : return false;
320 : : }
321 : : #if BYTE_ORDER == BIG_ENDIAN
322 : : if (op->number == 0)
323 : : val1 = 0;
324 : : else
325 : : val1 >>= (addr_bytes - op->number) * 8;
326 : : #else
327 [ # # ]: 0 : if (op->number < 8)
328 : 0 : val1 &= (1ULL << (op->number * 8)) - 1;
329 : : #endif
330 : : }
331 [ - + ]: 6 : if (! push (val1))
332 : : {
333 : 0 : free (stack.addrs);
334 : 0 : return false;
335 : : }
336 : : break;
337 : : #define UNOP(atom, expr) \
338 : : case atom: \
339 : : if (! pop (&val1) || ! push (expr)) \
340 : : { \
341 : : free (stack.addrs); \
342 : : return false; \
343 : : } \
344 : : break;
345 [ + - - + ]: 2 : UNOP (DW_OP_abs, llabs ((int64_t) val1))
346 [ + - - + ]: 3 : UNOP (DW_OP_neg, -(int64_t) val1)
347 [ + - - + ]: 1 : UNOP (DW_OP_not, ~val1)
348 : : #undef UNOP
349 : 574 : case DW_OP_plus_uconst:
350 [ + - - + ]: 574 : if (! pop (&val1) || ! push (val1 + op->number))
351 : : {
352 : 0 : free (stack.addrs);
353 : 0 : return false;
354 : : }
355 : : break;
356 : : #define BINOP(atom, op) \
357 : : case atom: \
358 : : if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2)) \
359 : : { \
360 : : free (stack.addrs); \
361 : : return false; \
362 : : } \
363 : : break;
364 : : #define BINOP_SIGNED(atom, op) \
365 : : case atom: \
366 : : if (! pop (&val2) || ! pop (&val1) \
367 : : || ! push ((int64_t) val1 op (int64_t) val2)) \
368 : : { \
369 : : free (stack.addrs); \
370 : : return false; \
371 : : } \
372 : : break;
373 [ + - + - : 2 : BINOP (DW_OP_and, &)
- + ]
374 : 5 : case DW_OP_div:
375 [ + - - + ]: 5 : if (! pop (&val2) || ! pop (&val1))
376 : : {
377 : 0 : free (stack.addrs);
378 : 0 : return false;
379 : : }
380 [ - + ]: 5 : if (val2 == 0)
381 : : {
382 : 0 : free (stack.addrs);
383 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
384 : 0 : return false;
385 : : }
386 [ - + ]: 5 : if (! push ((int64_t) val1 / (int64_t) val2))
387 : : {
388 : 0 : free (stack.addrs);
389 : 0 : return false;
390 : : }
391 : : break;
392 [ + - + - : 5 : BINOP (DW_OP_minus, -)
- + ]
393 : 3 : case DW_OP_mod:
394 [ + - - + ]: 3 : if (! pop (&val2) || ! pop (&val1))
395 : : {
396 : 0 : free (stack.addrs);
397 : 0 : return false;
398 : : }
399 [ - + ]: 3 : if (val2 == 0)
400 : : {
401 : 0 : free (stack.addrs);
402 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
403 : 0 : return false;
404 : : }
405 [ - + ]: 3 : if (! push (val1 % val2))
406 : : {
407 : 0 : free (stack.addrs);
408 : 0 : return false;
409 : : }
410 : : break;
411 [ + - + - : 4 : BINOP (DW_OP_mul, *)
- + ]
412 [ + - + - : 1 : BINOP (DW_OP_or, |)
- + ]
413 [ + - + - : 2 : BINOP (DW_OP_plus, +)
- + ]
414 [ + - + - : 1 : BINOP (DW_OP_shl, <<)
- + ]
415 [ + - + - : 2 : BINOP (DW_OP_shr, >>)
- + ]
416 [ + - + - : 2 : BINOP_SIGNED (DW_OP_shra, >>)
- + ]
417 [ + - + - : 1 : BINOP (DW_OP_xor, ^)
- + ]
418 [ + - + - : 3 : BINOP_SIGNED (DW_OP_le, <=)
- + ]
419 [ + - + - : 3 : BINOP_SIGNED (DW_OP_ge, >=)
- + ]
420 [ + - + - : 52 : BINOP_SIGNED (DW_OP_eq, ==)
- + ]
421 [ + - + - : 4 : BINOP_SIGNED (DW_OP_lt, <)
- + ]
422 [ + - + - : 4 : BINOP_SIGNED (DW_OP_gt, >)
- + ]
423 [ + - + - : 3 : BINOP_SIGNED (DW_OP_ne, !=)
- + ]
424 : : #undef BINOP
425 : : #undef BINOP_SIGNED
426 : 61 : case DW_OP_bra:
427 [ - + ]: 61 : if (! pop (&val1))
428 : : {
429 : 0 : free (stack.addrs);
430 : 0 : return false;
431 : : }
432 [ + - ]: 61 : if (val1 == 0)
433 : : break;
434 : 61 : FALLTHROUGH;
435 : 61 : case DW_OP_skip:;
436 : 61 : Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
437 : 61 : const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
438 : : sizeof (*ops), bra_compar);
439 [ - + ]: 61 : if (found == NULL)
440 : : {
441 : 0 : free (stack.addrs);
442 : : /* PPC32 vDSO has such invalid operations. */
443 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
444 : 0 : return false;
445 : : }
446 : : /* Undo the 'for' statement increment. */
447 : 61 : op = found - 1;
448 : 61 : break;
449 : : case DW_OP_nop:
450 : : break;
451 : : /* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op: */
452 : 726 : case DW_OP_call_frame_cfa:;
453 : : // Not used by CFI itself but it is synthetized by elfutils internation.
454 : 726 : Dwarf_Op *cfa_ops;
455 : 726 : size_t cfa_nops;
456 : 726 : Dwarf_Addr cfa;
457 [ + - ]: 726 : if (frame == NULL
458 [ + - ]: 726 : || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
459 [ + + ]: 726 : || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
460 [ - + ]: 721 : || ! push (cfa))
461 : : {
462 : 5 : __libdwfl_seterrno (DWFL_E_LIBDW);
463 : 5 : free (stack.addrs);
464 : 5 : return false;
465 : : }
466 : : is_location = true;
467 : : break;
468 : 136 : case DW_OP_stack_value:
469 : : // Not used by CFI itself but it is synthetized by elfutils internation.
470 : 136 : is_location = false;
471 : 136 : break;
472 : 0 : default:
473 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
474 : 0 : return false;
475 : : }
476 : : }
477 [ - + ]: 1514 : if (! pop (result))
478 : : {
479 : 0 : free (stack.addrs);
480 : 0 : return false;
481 : : }
482 : 1514 : free (stack.addrs);
483 [ + + ]: 1514 : if (is_location)
484 : : {
485 [ - + ]: 585 : if (process->callbacks->memory_read == NULL)
486 : : {
487 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
488 : 0 : return false;
489 : : }
490 [ + + ]: 585 : if (! process->callbacks->memory_read (process->dwfl, *result, result,
491 : : process->callbacks_arg))
492 : 6 : return false;
493 : : }
494 : : return true;
495 : : #undef push
496 : : #undef pop
497 : : }
498 : :
499 : : static Dwfl_Frame *
500 : 227 : new_unwound (Dwfl_Frame *state)
501 : : {
502 [ - + ]: 227 : assert (state->unwound == NULL);
503 : 227 : Dwfl_Thread *thread = state->thread;
504 : 227 : Dwfl_Process *process = thread->process;
505 : 227 : Ebl *ebl = process->ebl;
506 : 227 : size_t nregs = ebl_frame_nregs (ebl);
507 [ - + ]: 227 : assert (nregs > 0);
508 : 227 : Dwfl_Frame *unwound;
509 : 227 : unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
510 [ + - ]: 227 : if (unlikely (unwound == NULL))
511 : : return NULL;
512 : 227 : state->unwound = unwound;
513 : 227 : unwound->thread = thread;
514 : 227 : unwound->unwound = NULL;
515 : 227 : unwound->signal_frame = false;
516 : 227 : unwound->initial_frame = false;
517 : 227 : unwound->pc_state = DWFL_FRAME_STATE_ERROR;
518 : 227 : memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
519 : 227 : return unwound;
520 : : }
521 : :
522 : : /* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation
523 : : error so one can easily catch the problem with a debugger. Still there are
524 : : archs with invalid CFI for some registers where the registers are never used
525 : : later. Therefore we continue unwinding leaving the registers undefined. */
526 : :
527 : : static void
528 : 251 : handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
529 : : {
530 : 251 : Dwarf_Frame *frame;
531 [ + + ]: 251 : if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0)
532 : : {
533 : 87 : __libdwfl_seterrno (DWFL_E_LIBDW);
534 : 174 : return;
535 : : }
536 : :
537 : 164 : Dwfl_Frame *unwound = new_unwound (state);
538 [ - + ]: 164 : if (unwound == NULL)
539 : : {
540 : 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
541 : 0 : return;
542 : : }
543 : :
544 : 164 : unwound->signal_frame = frame->fde->cie->signal_frame;
545 : 164 : Dwfl_Thread *thread = state->thread;
546 : 164 : Dwfl_Process *process = thread->process;
547 : 164 : Ebl *ebl = process->ebl;
548 : 164 : size_t nregs = ebl_frame_nregs (ebl);
549 [ - + ]: 164 : assert (nregs > 0);
550 : :
551 : : /* The return register is special for setting the unwound->pc_state. */
552 : 164 : unsigned ra = frame->fde->cie->return_address_register;
553 : 164 : bool ra_set = false;
554 [ - + ]: 164 : if (! ebl_dwarf_to_regno (ebl, &ra))
555 : : {
556 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
557 : 0 : return;
558 : : }
559 : :
560 [ + + ]: 6444 : for (unsigned regno = 0; regno < nregs; regno++)
561 : : {
562 : 6280 : Dwarf_Op reg_ops_mem[3], *reg_ops;
563 : 6280 : size_t reg_nops;
564 [ - + ]: 6280 : if (dwarf_frame_register (frame, regno, reg_ops_mem, ®_ops,
565 : : ®_nops) != 0)
566 : : {
567 : 0 : __libdwfl_seterrno (DWFL_E_LIBDW);
568 : 4536 : continue;
569 : : }
570 : 6280 : Dwarf_Addr regval;
571 [ + + ]: 6280 : if (reg_nops == 0)
572 : : {
573 [ + + ]: 5482 : if (reg_ops == reg_ops_mem)
574 : : {
575 : : /* REGNO is undefined. */
576 [ + + ]: 3646 : if (regno == ra)
577 : 15 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
578 : 3646 : continue;
579 : : }
580 [ + - ]: 1836 : else if (reg_ops == NULL)
581 : : {
582 : : /* REGNO is same-value. */
583 [ + + ]: 1836 : if (INTUSE (dwfl_frame_reg) (state, regno, ®val) != 0)
584 : 879 : continue;
585 : : }
586 : : else
587 : : {
588 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
589 : 0 : continue;
590 : : }
591 : : }
592 [ + + ]: 798 : else if (! expr_eval (state, frame, reg_ops, reg_nops, ®val, bias))
593 : : {
594 : : /* PPC32 vDSO has various invalid operations, ignore them. The
595 : : register will look as unset causing an error later, if used.
596 : : But PPC32 does not use such registers. */
597 : 11 : continue;
598 : : }
599 : :
600 : : /* Some architectures encode some extra info in the return address. */
601 [ + + ]: 1744 : if (regno == frame->fde->cie->return_address_register)
602 : 147 : regval &= ebl_func_addr_mask (ebl);
603 : :
604 : : /* This is another strange PPC[64] case. There are two
605 : : registers numbers that can represent the same DWARF return
606 : : register number. We only want one to actually set the return
607 : : register value. But we always want to override the value if
608 : : the register is the actual CIE return address register. */
609 [ + + + - ]: 1744 : if (ra_set && regno != frame->fde->cie->return_address_register)
610 : : {
611 : 209 : unsigned r = regno;
612 [ + - - + ]: 209 : if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
613 : 0 : continue;
614 : : }
615 : :
616 [ - + ]: 1744 : if (! __libdwfl_frame_reg_set (unwound, regno, regval))
617 : : {
618 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
619 : 0 : continue;
620 : : }
621 [ + + ]: 1744 : else if (! ra_set)
622 : : {
623 : 1535 : unsigned r = regno;
624 [ + - + + ]: 1535 : if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
625 : 147 : ra_set = true;
626 : : }
627 : : }
628 [ + + ]: 164 : if (unwound->pc_state == DWFL_FRAME_STATE_ERROR)
629 : : {
630 : 298 : int res = INTUSE (dwfl_frame_reg) (unwound,
631 : 149 : frame->fde->cie->return_address_register,
632 : 149 : &unwound->pc);
633 [ + + ]: 149 : if (res == 0)
634 : : {
635 : : /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.
636 : : Currently none of the archs supported for unwinding have
637 : : zero as a valid PC. */
638 [ + + ]: 147 : if (unwound->pc == 0)
639 : 1 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
640 : : else
641 : : {
642 : 146 : unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
643 : : /* In SPARC the return address register actually contains
644 : : the address of the call instruction instead of the return
645 : : address. Therefore we add here an offset defined by the
646 : : backend. Most likely 0. */
647 : 146 : unwound->pc += ebl_ra_offset (ebl);
648 : : }
649 : : }
650 : : else
651 : : {
652 : : /* We couldn't set the return register, either it was bogus,
653 : : or the return pc is undefined, maybe end of call stack. */
654 : 2 : unsigned pcreg = frame->fde->cie->return_address_register;
655 [ + - ]: 2 : if (! ebl_dwarf_to_regno (ebl, &pcreg)
656 [ - + ]: 2 : || pcreg >= ebl_frame_nregs (ebl))
657 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
658 : : else
659 : 2 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
660 : : }
661 : : }
662 : 164 : free (frame);
663 : : }
664 : :
665 : : static bool
666 : 99 : setfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg)
667 : : {
668 : 99 : Dwfl_Frame *state = arg;
669 : 99 : Dwfl_Frame *unwound = state->unwound;
670 [ + + ]: 99 : if (firstreg < 0)
671 : : {
672 [ - + ]: 31 : assert (firstreg == -1);
673 [ - + ]: 31 : assert (nregs == 1);
674 [ - + ]: 31 : assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
675 : 31 : unwound->pc = *regs;
676 : 31 : unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
677 : 31 : return true;
678 : : }
679 [ + + ]: 141 : while (nregs--)
680 [ + - ]: 73 : if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++))
681 : : return false;
682 : : return true;
683 : : }
684 : :
685 : : static bool
686 : 88 : getfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg)
687 : : {
688 : 88 : Dwfl_Frame *state = arg;
689 [ - + ]: 88 : assert (firstreg >= 0);
690 [ + + ]: 185 : while (nregs--)
691 [ + - ]: 97 : if (INTUSE (dwfl_frame_reg) (state, firstreg++, regs++) != 0)
692 : : return false;
693 : : return true;
694 : : }
695 : :
696 : : static bool
697 : 68 : readfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg)
698 : : {
699 : 68 : Dwfl_Frame *state = arg;
700 : 68 : Dwfl_Thread *thread = state->thread;
701 : 68 : Dwfl_Process *process = thread->process;
702 : 68 : return process->callbacks->memory_read (process->dwfl, addr, datap,
703 : : process->callbacks_arg);
704 : : }
705 : :
706 : : void
707 : : internal_function
708 : 365 : __libdwfl_frame_unwind (Dwfl_Frame *state)
709 : : {
710 [ + + ]: 365 : if (state->unwound)
711 : 338 : return;
712 : : /* Do not ask dwfl_frame_pc for ISACTIVATION, it would try to unwind STATE
713 : : which would deadlock us. */
714 : 227 : Dwarf_Addr pc;
715 : 227 : bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL);
716 [ + - ]: 227 : if (!ok)
717 : : return;
718 : : /* Check whether this is the initial frame or a signal frame.
719 : : Then we need to unwind from the original, unadjusted PC. */
720 [ + + + - ]: 227 : if (! state->initial_frame && ! state->signal_frame)
721 : 184 : pc--;
722 : 227 : Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc);
723 [ + + ]: 227 : if (mod == NULL)
724 : 2 : __libdwfl_seterrno (DWFL_E_NO_DWARF);
725 : : else
726 : : {
727 : 225 : Dwarf_Addr bias;
728 : 225 : Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias);
729 [ + + ]: 225 : if (cfi_eh)
730 : : {
731 : 215 : handle_cfi (state, pc - bias, cfi_eh, bias);
732 [ + + ]: 215 : if (state->unwound)
733 : 164 : return;
734 : : }
735 : 78 : Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias);
736 [ + + ]: 78 : if (cfi_dwarf)
737 : : {
738 : 36 : handle_cfi (state, pc - bias, cfi_dwarf, bias);
739 [ + + ]: 36 : if (state->unwound)
740 : : return;
741 : : }
742 : : }
743 [ - + ]: 63 : assert (state->unwound == NULL);
744 : 63 : Dwfl_Thread *thread = state->thread;
745 : 63 : Dwfl_Process *process = thread->process;
746 : 63 : Ebl *ebl = process->ebl;
747 [ - + ]: 63 : if (new_unwound (state) == NULL)
748 : : {
749 : 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
750 : 0 : return;
751 : : }
752 : 63 : state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
753 : : // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield.
754 : 63 : bool signal_frame = false;
755 [ + + ]: 63 : if (! ebl_unwind (ebl, pc, setfunc, getfunc, readfunc, state, &signal_frame))
756 : : {
757 : : // Discard the unwind attempt. During next __libdwfl_frame_unwind call
758 : : // we may have for example the appropriate Dwfl_Module already mapped.
759 [ - + ]: 36 : assert (state->unwound->unwound == NULL);
760 : 36 : free (state->unwound);
761 : 36 : state->unwound = NULL;
762 : : // __libdwfl_seterrno has been called above.
763 : 36 : return;
764 : : }
765 [ - + ]: 27 : assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET);
766 : 27 : state->unwound->signal_frame = signal_frame;
767 : : }
|