Branch data Line data Source code
1 : : /* Get previous frame state for an existing frame state.
2 : : Copyright (C) 2013, 2014, 2016, 2024 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 : 7778 : __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
49 : : {
50 : 7778 : Ebl *ebl = state->thread->process->ebl;
51 [ + + ]: 7778 : if (! ebl_dwarf_to_regno (ebl, ®no))
52 : : return -1;
53 [ - + ]: 7762 : if (regno >= ebl_frame_nregs (ebl))
54 : : return -1;
55 : 7762 : if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
56 [ + + ]: 7762 : & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
57 : : return 1;
58 [ + - ]: 4232 : if (val)
59 : 4232 : *val = state->regs[regno];
60 : : return 0;
61 : : }
62 : :
63 : : bool
64 : : internal_function
65 : 5658 : __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
66 : : {
67 : 5658 : Ebl *ebl = state->thread->process->ebl;
68 [ + + ]: 5658 : if (! ebl_dwarf_to_regno (ebl, ®no))
69 : : return false;
70 [ - + ]: 5642 : if (regno >= ebl_frame_nregs (ebl))
71 : : return false;
72 : : /* For example i386 user_regs_struct has signed fields. */
73 [ + + ]: 5642 : if (ebl_get_elfclass (ebl) == ELFCLASS32)
74 : 1402 : val &= 0xffffffff;
75 : 5642 : state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
76 : 5642 : ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)));
77 : 5642 : state->regs[regno] = val;
78 : 5642 : return true;
79 : : }
80 : :
81 : : static int
82 : 936 : bra_compar (const void *key_voidp, const void *elem_voidp)
83 : : {
84 : 936 : Dwarf_Word offset = (uintptr_t) key_voidp;
85 : 936 : const Dwarf_Op *op = elem_voidp;
86 [ + + ]: 936 : 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 : 4948 : do_push (struct eval_stack *stack, Dwarf_Addr val)
97 : : {
98 [ - + ]: 4948 : if (stack->used >= DWARF_EXPR_STACK_MAX)
99 : : {
100 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
101 : 0 : return false;
102 : : }
103 [ + + ]: 4948 : if (stack->used == stack->allocated)
104 : : {
105 : 3168 : stack->allocated = MAX (stack->allocated * 2, 32);
106 : 3168 : Dwarf_Addr *new_addrs;
107 : 3168 : new_addrs = realloc (stack->addrs,
108 : : stack->allocated * sizeof (*stack->addrs));
109 [ - + ]: 3168 : if (new_addrs == NULL)
110 : : {
111 : 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
112 : 0 : return false;
113 : : }
114 : 3168 : stack->addrs = new_addrs;
115 : : }
116 : 4948 : stack->addrs[stack->used++] = val;
117 : 4948 : return true;
118 : : }
119 : :
120 : : static bool
121 : 4948 : do_pop (struct eval_stack *stack, Dwarf_Addr *val)
122 : : {
123 [ - + ]: 4948 : if (stack->used == 0)
124 : : {
125 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
126 : 0 : return false;
127 : : }
128 : 4948 : *val = stack->addrs[--stack->used];
129 : 4948 : 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 : 3188 : expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
137 : : size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
138 : : {
139 : 3188 : Dwfl_Process *process = state->thread->process;
140 [ - + ]: 3188 : if (nops == 0)
141 : : {
142 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
143 : 0 : return false;
144 : : }
145 : 3188 : 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 : 3188 : Dwarf_Addr val1, val2;
156 : 3188 : bool is_location = false;
157 : 3188 : size_t steps_count = 0;
158 [ + + ]: 8510 : for (const Dwarf_Op *op = ops; op < ops + nops; op++)
159 : : {
160 [ - + ]: 5342 : if (++steps_count > DWARF_EXPR_STEPS_MAX)
161 : : {
162 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
163 : 0 : return false;
164 : : }
165 [ + - - + : 5342 : switch (op->atom)
- + - + +
+ + + + +
- + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - +
+ - + ]
166 : : {
167 : : /* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op: */
168 : 228 : case DW_OP_lit0 ... DW_OP_lit31:
169 [ - + ]: 228 : if (! push (op->atom - DW_OP_lit0))
170 : : {
171 : 0 : free (stack.addrs);
172 : 20 : return false;
173 : : }
174 : 5322 : 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 : 70 : 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 [ - + ]: 70 : 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 : 144 : case DW_OP_regx:
211 [ + - - + ]: 144 : 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 : 0 : case DW_OP_breg0 ... DW_OP_breg31:
218 [ # # ]: 0 : 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 : 0 : val1 += op->number;
224 [ # # ]: 0 : if (! push (val1))
225 : : {
226 : 0 : free (stack.addrs);
227 : 0 : return false;
228 : : }
229 : : break;
230 : 1522 : case DW_OP_bregx:
231 [ + + ]: 1522 : if (INTUSE (dwfl_frame_reg) (state, op->number, &val1) != 0)
232 : : {
233 : 10 : free (stack.addrs);
234 : 10 : return false;
235 : : }
236 : 1512 : val1 += op->number2;
237 [ - + ]: 1512 : if (! push (val1))
238 : : {
239 : 0 : free (stack.addrs);
240 : 0 : return false;
241 : : }
242 : : break;
243 : 2 : case DW_OP_dup:
244 [ + - + - : 2 : if (! pop (&val1) || ! push (val1) || ! push (val1))
- + ]
245 : : {
246 : 0 : free (stack.addrs);
247 : 0 : return false;
248 : : }
249 : : break;
250 : 2 : case DW_OP_drop:
251 [ - + ]: 2 : if (! pop (&val1))
252 : : {
253 : 0 : free (stack.addrs);
254 : 0 : return false;
255 : : }
256 : : break;
257 : 4 : case DW_OP_pick:
258 [ - + ]: 4 : 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 [ - + ]: 4 : if (! push (stack.addrs[stack.used - 1 - op->number]))
265 : : {
266 : 0 : free (stack.addrs);
267 : 0 : return false;
268 : : }
269 : : break;
270 : 14 : case DW_OP_over:
271 [ + - + - ]: 14 : if (! pop (&val1) || ! pop (&val2)
272 [ + - + - : 14 : || ! push (val2) || ! push (val1) || ! push (val2))
- + ]
273 : : {
274 : 0 : free (stack.addrs);
275 : 0 : return false;
276 : : }
277 : : break;
278 : 2 : case DW_OP_swap:
279 [ + - + - : 2 : if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
+ - - + ]
280 : : {
281 : 0 : free (stack.addrs);
282 : 0 : return false;
283 : : }
284 : : break;
285 : 2 : case DW_OP_rot:
286 : : {
287 : 2 : Dwarf_Addr val3;
288 [ + - + - : 2 : if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
+ - ]
289 [ + - + - : 2 : || ! push (val1) || ! push (val3) || ! push (val2))
- + ]
290 : : {
291 : 0 : free (stack.addrs);
292 : 0 : return false;
293 : : }
294 : : }
295 : 2 : break;
296 : 0 : case DW_OP_deref:
297 : : case DW_OP_deref_size:
298 [ # # ]: 0 : 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 [ # # ]: 0 : if (! pop (&val1)
305 [ # # ]: 0 : || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
306 : : process->callbacks_arg))
307 : : {
308 : 0 : free (stack.addrs);
309 : 0 : return false;
310 : : }
311 [ # # ]: 0 : 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 [ # # ]: 0 : 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 [ + - - + ]: 4 : UNOP (DW_OP_abs, llabs ((int64_t) val1))
346 [ + - - + ]: 6 : UNOP (DW_OP_neg, -(int64_t) val1)
347 [ + - - + ]: 2 : UNOP (DW_OP_not, ~val1)
348 : : #undef UNOP
349 : 1216 : case DW_OP_plus_uconst:
350 [ + - - + ]: 1216 : 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 [ + - + - : 4 : BINOP (DW_OP_and, &)
- + ]
374 : 10 : case DW_OP_div:
375 [ + - - + ]: 10 : if (! pop (&val2) || ! pop (&val1))
376 : : {
377 : 0 : free (stack.addrs);
378 : 0 : return false;
379 : : }
380 [ - + ]: 10 : if (val2 == 0)
381 : : {
382 : 0 : free (stack.addrs);
383 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
384 : 0 : return false;
385 : : }
386 [ - + ]: 10 : if (! push ((int64_t) val1 / (int64_t) val2))
387 : : {
388 : 0 : free (stack.addrs);
389 : 0 : return false;
390 : : }
391 : : break;
392 [ + - + - : 10 : BINOP (DW_OP_minus, -)
- + ]
393 : 6 : case DW_OP_mod:
394 [ + - - + ]: 6 : if (! pop (&val2) || ! pop (&val1))
395 : : {
396 : 0 : free (stack.addrs);
397 : 0 : return false;
398 : : }
399 [ - + ]: 6 : if (val2 == 0)
400 : : {
401 : 0 : free (stack.addrs);
402 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
403 : 0 : return false;
404 : : }
405 [ - + ]: 6 : if (! push (val1 % val2))
406 : : {
407 : 0 : free (stack.addrs);
408 : 0 : return false;
409 : : }
410 : : break;
411 [ + - + - : 8 : BINOP (DW_OP_mul, *)
- + ]
412 [ + - + - : 2 : BINOP (DW_OP_or, |)
- + ]
413 [ + - + - : 4 : BINOP (DW_OP_plus, +)
- + ]
414 [ + - + - : 2 : BINOP (DW_OP_shl, <<)
- + ]
415 [ + - + - : 4 : BINOP (DW_OP_shr, >>)
- + ]
416 [ + - + - : 4 : BINOP_SIGNED (DW_OP_shra, >>)
- + ]
417 [ + - + - : 2 : BINOP (DW_OP_xor, ^)
- + ]
418 [ + - + - : 6 : BINOP_SIGNED (DW_OP_le, <=)
- + ]
419 [ + - + - : 6 : BINOP_SIGNED (DW_OP_ge, >=)
- + ]
420 [ + - + - : 104 : BINOP_SIGNED (DW_OP_eq, ==)
- + ]
421 [ + - + - : 8 : BINOP_SIGNED (DW_OP_lt, <)
- + ]
422 [ + - + - : 8 : BINOP_SIGNED (DW_OP_gt, >)
- + ]
423 [ + - + - : 6 : BINOP_SIGNED (DW_OP_ne, !=)
- + ]
424 : : #undef BINOP
425 : : #undef BINOP_SIGNED
426 : 122 : case DW_OP_bra:
427 [ - + ]: 122 : if (! pop (&val1))
428 : : {
429 : 0 : free (stack.addrs);
430 : 0 : return false;
431 : : }
432 [ + - ]: 122 : if (val1 == 0)
433 : : break;
434 : 122 : FALLTHROUGH;
435 : 122 : case DW_OP_skip:;
436 : 122 : Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
437 : 122 : const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
438 : : sizeof (*ops), bra_compar);
439 [ - + ]: 122 : 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 : 122 : op = found - 1;
448 : 122 : break;
449 : : case DW_OP_nop:
450 : : break;
451 : : /* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op: */
452 : 1522 : case DW_OP_call_frame_cfa:;
453 : : // Not used by CFI itself but it is synthetized by elfutils internation.
454 : 1522 : Dwarf_Op *cfa_ops;
455 : 1522 : size_t cfa_nops;
456 : 1522 : Dwarf_Addr cfa;
457 [ + - ]: 1522 : if (frame == NULL
458 [ + - ]: 1522 : || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
459 [ + + ]: 1522 : || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
460 [ - + ]: 1512 : || ! push (cfa))
461 : : {
462 : 10 : __libdwfl_seterrno (DWFL_E_LIBDW);
463 : 10 : free (stack.addrs);
464 : 10 : return false;
465 : : }
466 : : is_location = true;
467 : : break;
468 : 282 : case DW_OP_stack_value:
469 : : // Not used by CFI itself but it is synthetized by elfutils internation.
470 : 282 : is_location = false;
471 : 282 : break;
472 : 0 : default:
473 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
474 : 0 : return false;
475 : : }
476 : : }
477 [ - + ]: 3168 : if (! pop (result))
478 : : {
479 : 0 : free (stack.addrs);
480 : 0 : return false;
481 : : }
482 : 3168 : free (stack.addrs);
483 [ + + ]: 3168 : if (is_location)
484 : : {
485 [ - + ]: 1230 : if (process->callbacks->memory_read == NULL)
486 : : {
487 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
488 : 0 : return false;
489 : : }
490 [ + + ]: 1230 : if (! process->callbacks->memory_read (process->dwfl, *result, result,
491 : : process->callbacks_arg))
492 : : return false;
493 : : }
494 : : return true;
495 : : #undef push
496 : : #undef pop
497 : : }
498 : :
499 : : static Dwfl_Frame *
500 : 466 : new_unwound (Dwfl_Frame *state)
501 : : {
502 [ - + ]: 466 : assert (state->unwound == NULL);
503 : 466 : Dwfl_Thread *thread = state->thread;
504 : 466 : Dwfl_Process *process = thread->process;
505 : 466 : Ebl *ebl = process->ebl;
506 : 466 : size_t nregs = ebl_frame_nregs (ebl);
507 [ - + ]: 466 : assert (nregs > 0);
508 : 466 : Dwfl_Frame *unwound;
509 : 466 : unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
510 [ + - ]: 466 : if (unlikely (unwound == NULL))
511 : : return NULL;
512 : 466 : state->unwound = unwound;
513 : 466 : unwound->thread = thread;
514 : 466 : unwound->unwound = NULL;
515 : 466 : unwound->signal_frame = false;
516 : 466 : unwound->initial_frame = false;
517 : 466 : unwound->pc_state = DWFL_FRAME_STATE_ERROR;
518 : 466 : unwound->unwound_source = DWFL_UNWOUND_NONE;
519 : 466 : memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
520 : 466 : return unwound;
521 : : }
522 : :
523 : : /* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation
524 : : error so one can easily catch the problem with a debugger. Still there are
525 : : archs with invalid CFI for some registers where the registers are never used
526 : : later. Therefore we continue unwinding leaving the registers undefined. */
527 : :
528 : : static void
529 : 512 : handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
530 : : {
531 : 512 : Dwarf_Frame *frame;
532 [ + + ]: 512 : if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0)
533 : : {
534 : 174 : __libdwfl_seterrno (DWFL_E_LIBDW);
535 : 348 : return;
536 : : }
537 : :
538 : 338 : Dwfl_Frame *unwound = new_unwound (state);
539 [ - + ]: 338 : if (unwound == NULL)
540 : : {
541 : 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
542 : 0 : return;
543 : : }
544 : :
545 : 338 : unwound->signal_frame = frame->fde->cie->signal_frame;
546 : 338 : Dwfl_Thread *thread = state->thread;
547 : 338 : Dwfl_Process *process = thread->process;
548 : 338 : Ebl *ebl = process->ebl;
549 : 338 : size_t nregs = ebl_frame_nregs (ebl);
550 [ - + ]: 338 : assert (nregs > 0);
551 : :
552 : : /* The return register is special for setting the unwound->pc_state. */
553 : 338 : unsigned ra = frame->fde->cie->return_address_register;
554 : 338 : bool ra_set = false;
555 [ - + ]: 338 : if (! ebl_dwarf_to_regno (ebl, &ra))
556 : : {
557 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
558 : 0 : return;
559 : : }
560 : :
561 [ + + ]: 14716 : for (unsigned regno = 0; regno < nregs; regno++)
562 : : {
563 : 14378 : Dwarf_Op reg_ops_mem[3], *reg_ops;
564 : 14378 : size_t reg_nops;
565 [ - + ]: 14378 : if (dwarf_frame_register (frame, regno, reg_ops_mem, ®_ops,
566 : : ®_nops) != 0)
567 : : {
568 : 0 : __libdwfl_seterrno (DWFL_E_LIBDW);
569 : 10658 : continue;
570 : : }
571 : 14378 : Dwarf_Addr regval;
572 [ + + ]: 14378 : if (reg_nops == 0)
573 : : {
574 [ + + ]: 12712 : if (reg_ops == reg_ops_mem)
575 : : {
576 : : /* REGNO is undefined. */
577 [ + + ]: 8734 : if (regno == ra)
578 : 28 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
579 : 8734 : continue;
580 : : }
581 [ + - ]: 3978 : else if (reg_ops == NULL)
582 : : {
583 : : /* REGNO is same-value. */
584 [ + + ]: 3978 : if (INTUSE (dwfl_frame_reg) (state, regno, ®val) != 0)
585 : 1902 : continue;
586 : : }
587 : : else
588 : : {
589 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
590 : 0 : continue;
591 : : }
592 : : }
593 [ + + ]: 1666 : else if (! expr_eval (state, frame, reg_ops, reg_nops, ®val, bias))
594 : : {
595 : : /* PPC32 vDSO has various invalid operations, ignore them. The
596 : : register will look as unset causing an error later, if used.
597 : : But PPC32 does not use such registers. */
598 : 22 : continue;
599 : : }
600 : :
601 : : /* Some architectures encode some extra info in the return address. */
602 [ + + ]: 3720 : if (regno == frame->fde->cie->return_address_register)
603 : : {
604 : 306 : regval &= ebl_func_addr_mask (ebl);
605 : :
606 : : /* In aarch64, pseudo-register RA_SIGN_STATE indicates whether the
607 : : return address needs demangling using the PAC mask from the
608 : : thread. */
609 [ + + ]: 306 : if (cfi->e_machine == EM_AARCH64 &&
610 [ + - ]: 38 : frame->nregs > DW_AARCH64_RA_SIGN_STATE &&
611 [ + + ]: 38 : frame->regs[DW_AARCH64_RA_SIGN_STATE].value & 0x1)
612 : : {
613 : 14 : regval &= ~(state->thread->aarch64.pauth_insn_mask);
614 : : }
615 : : }
616 : :
617 : : /* This is another strange PPC[64] case. There are two
618 : : registers numbers that can represent the same DWARF return
619 : : register number. We only want one to actually set the return
620 : : register value. But we always want to override the value if
621 : : the register is the actual CIE return address register. */
622 [ + + + - ]: 3720 : if (ra_set && regno != frame->fde->cie->return_address_register)
623 : : {
624 : 434 : unsigned r = regno;
625 [ + - - + ]: 434 : if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
626 : 0 : continue;
627 : : }
628 : :
629 [ - + ]: 3720 : if (! __libdwfl_frame_reg_set (unwound, regno, regval))
630 : : {
631 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
632 : 0 : continue;
633 : : }
634 [ + + ]: 3720 : else if (! ra_set)
635 : : {
636 : 3286 : unsigned r = regno;
637 [ - + + + ]: 3286 : if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
638 : 3286 : ra_set = true;
639 : : }
640 : : }
641 [ + + ]: 338 : if (unwound->pc_state == DWFL_FRAME_STATE_ERROR)
642 : : {
643 : 620 : int res = INTUSE (dwfl_frame_reg) (unwound,
644 : 310 : frame->fde->cie->return_address_register,
645 : 310 : &unwound->pc);
646 [ + + ]: 310 : if (res == 0)
647 : : {
648 : : /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.
649 : : Currently none of the archs supported for unwinding have
650 : : zero as a valid PC. */
651 [ + + ]: 306 : if (unwound->pc == 0)
652 : 2 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
653 : : else
654 : : {
655 : 304 : unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
656 : : /* In SPARC the return address register actually contains
657 : : the address of the call instruction instead of the return
658 : : address. Therefore we add here an offset defined by the
659 : : backend. Most likely 0. */
660 : 304 : unwound->pc += ebl_ra_offset (ebl);
661 : : }
662 : : }
663 : : else
664 : : {
665 : : /* We couldn't set the return register, either it was bogus,
666 : : or the return pc is undefined, maybe end of call stack. */
667 : 4 : unsigned pcreg = frame->fde->cie->return_address_register;
668 [ + - ]: 4 : if (! ebl_dwarf_to_regno (ebl, &pcreg)
669 [ - + ]: 4 : || pcreg >= ebl_frame_nregs (ebl))
670 : 0 : __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
671 : : else
672 : 4 : unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
673 : : }
674 : : }
675 : 338 : free (frame);
676 : : }
677 : :
678 : : static bool
679 : 186 : setfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg)
680 : : {
681 : 186 : Dwfl_Frame *state = arg;
682 : 186 : Dwfl_Frame *unwound = state->unwound;
683 [ + + ]: 186 : if (firstreg < 0)
684 : : {
685 [ - + ]: 58 : assert (firstreg == -1);
686 [ - + ]: 58 : assert (nregs == 1);
687 [ - + ]: 58 : assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
688 : 58 : unwound->pc = *regs;
689 : 58 : unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
690 : 58 : return true;
691 : : }
692 [ + + ]: 266 : while (nregs--)
693 [ + - ]: 138 : if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++))
694 : : return false;
695 : : return true;
696 : : }
697 : :
698 : : static bool
699 : 176 : getfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg)
700 : : {
701 : 176 : Dwfl_Frame *state = arg;
702 [ - + ]: 176 : assert (firstreg >= 0);
703 [ + + ]: 370 : while (nregs--)
704 [ + - ]: 194 : if (INTUSE (dwfl_frame_reg) (state, firstreg++, regs++) != 0)
705 : : return false;
706 : : return true;
707 : : }
708 : :
709 : : static bool
710 : 132 : readfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg)
711 : : {
712 : 132 : Dwfl_Frame *state = arg;
713 : 132 : Dwfl_Thread *thread = state->thread;
714 : 132 : Dwfl_Process *process = thread->process;
715 : 132 : return process->callbacks->memory_read (process->dwfl, addr, datap,
716 : : process->callbacks_arg);
717 : : }
718 : :
719 : : void
720 : : internal_function
721 : 754 : __libdwfl_frame_unwind (Dwfl_Frame *state)
722 : : {
723 [ + + ]: 754 : if (state->unwound)
724 : 700 : return;
725 : : /* Do not ask dwfl_frame_pc for ISACTIVATION, it would try to unwind STATE
726 : : which would deadlock us. */
727 : 466 : Dwarf_Addr pc;
728 : 466 : bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL);
729 [ + - ]: 466 : if (!ok)
730 : : return;
731 : : /* Check whether this is the initial frame or a signal frame.
732 : : Then we need to unwind from the original, unadjusted PC. */
733 [ + + + - ]: 466 : if (! state->initial_frame && ! state->signal_frame)
734 : 380 : pc--;
735 : 466 : Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc);
736 [ + + ]: 466 : if (mod == NULL)
737 : 2 : __libdwfl_seterrno (DWFL_E_NO_DWARF);
738 : : else
739 : : {
740 : 464 : Dwarf_Addr bias;
741 : 464 : Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias);
742 [ + + ]: 464 : if (cfi_eh)
743 : : {
744 : 440 : handle_cfi (state, pc - bias, cfi_eh, bias);
745 [ + + ]: 440 : if (state->unwound)
746 : : {
747 : 304 : state->unwound->unwound_source = DWFL_UNWOUND_EH_CFI;
748 : 338 : return;
749 : : }
750 : : }
751 : 160 : Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias);
752 [ + + ]: 160 : if (cfi_dwarf)
753 : : {
754 : 72 : handle_cfi (state, pc - bias, cfi_dwarf, bias);
755 [ + + ]: 72 : if (state->unwound)
756 : : {
757 : 34 : state->unwound->unwound_source = DWFL_UNWOUND_DWARF_CFI;
758 : 34 : return;
759 : : }
760 : : }
761 : : }
762 [ - + ]: 128 : assert (state->unwound == NULL);
763 : 128 : Dwfl_Thread *thread = state->thread;
764 : 128 : Dwfl_Process *process = thread->process;
765 : 128 : Ebl *ebl = process->ebl;
766 [ - + ]: 128 : if (new_unwound (state) == NULL)
767 : : {
768 : 0 : __libdwfl_seterrno (DWFL_E_NOMEM);
769 : 0 : return;
770 : : }
771 : 128 : state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
772 : : // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield.
773 : 128 : bool signal_frame = false;
774 [ + + ]: 128 : if (! ebl_unwind (ebl, pc, setfunc, getfunc, readfunc, state, &signal_frame))
775 : : {
776 : : // Discard the unwind attempt. During next __libdwfl_frame_unwind call
777 : : // we may have for example the appropriate Dwfl_Module already mapped.
778 [ - + ]: 74 : assert (state->unwound->unwound == NULL);
779 : 74 : free (state->unwound);
780 : 74 : state->unwound = NULL;
781 : : // __libdwfl_seterrno has been called above.
782 : 74 : return;
783 : : }
784 : 54 : state->unwound->unwound_source = DWFL_UNWOUND_EBL;
785 [ - + ]: 54 : assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET);
786 : 54 : state->unwound->signal_frame = signal_frame;
787 : : }
|