Branch data Line data Source code
1 : : /* CFI program execution.
2 : : Copyright (C) 2009-2010, 2014, 2015 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 <dwarf.h>
34 : : #include "../libebl/libebl.h"
35 : : #include "cfi.h"
36 : : #include "memory-access.h"
37 : : #include "encoded-value.h"
38 : : #include "system.h"
39 : : #include <assert.h>
40 : : #include <stdlib.h>
41 : : #include <string.h>
42 : :
43 : : #define CFI_PRIMARY_MAX 0x3f
44 : :
45 : : static Dwarf_Frame *
46 : 6352 : duplicate_frame_state (const Dwarf_Frame *original,
47 : : Dwarf_Frame *prev)
48 : : {
49 : 6352 : size_t size = offsetof (Dwarf_Frame, regs[original->nregs]);
50 : 6352 : Dwarf_Frame *copy = malloc (size);
51 [ + - ]: 6352 : if (likely (copy != NULL))
52 : : {
53 : 6352 : memcpy (copy, original, size);
54 : 6352 : copy->prev = prev;
55 : : }
56 : 6352 : return copy;
57 : : }
58 : :
59 : : static inline bool
60 : 2085 : enough_registers (Dwarf_Word reg, Dwarf_Frame **pfs, int *result)
61 : : {
62 : : /* Don't allow insanely large register numbers. 268435456 registers
63 : : should be enough for anybody. And very large values might overflow
64 : : the array size and offsetof calculations below. */
65 [ - + ]: 2085 : if (unlikely (reg >= INT32_MAX / sizeof ((*pfs)->regs[0])))
66 : : {
67 : 0 : *result = DWARF_E_INVALID_CFI;
68 : 0 : return false;
69 : : }
70 : :
71 [ + + ]: 2085 : if ((*pfs)->nregs <= reg)
72 : : {
73 : 1292 : size_t size = offsetof (Dwarf_Frame, regs[reg + 1]);
74 : 1292 : Dwarf_Frame *bigger = realloc (*pfs, size);
75 [ - + ]: 1292 : if (unlikely (bigger == NULL))
76 : : {
77 : 0 : *result = DWARF_E_NOMEM;
78 : 0 : return false;
79 : : }
80 : : else
81 : : {
82 : 1292 : eu_static_assert (reg_unspecified == 0);
83 : 1292 : memset (bigger->regs + bigger->nregs, 0,
84 : 1292 : (reg + 1 - bigger->nregs) * sizeof bigger->regs[0]);
85 : 1292 : bigger->nregs = reg + 1;
86 : 1292 : *pfs = bigger;
87 : : }
88 : : }
89 : : return true;
90 : : }
91 : :
92 : : static inline void
93 : 227 : require_cfa_offset (Dwarf_Frame *fs)
94 : : {
95 : 227 : if (unlikely (fs->cfa_rule != cfa_offset))
96 : 0 : fs->cfa_rule = cfa_invalid;
97 : : }
98 : :
99 : : /* Returns a DWARF_E_* error code, usually NOERROR or INVALID_CFI.
100 : : Frees *STATE on failure. */
101 : : static int
102 : 6521 : execute_cfi (Dwarf_CFI *cache,
103 : : const struct dwarf_cie *cie,
104 : : Dwarf_Frame **state,
105 : : const uint8_t *program, const uint8_t *const end, bool abi_cfi,
106 : : Dwarf_Addr loc, Dwarf_Addr find_pc)
107 : : {
108 : : /* The caller should not give us anything out of range. */
109 [ - + ]: 6521 : assert (loc <= find_pc);
110 : :
111 : 6521 : int result = DWARF_E_NOERROR;
112 : :
113 : : #define cfi_assert(ok) do { \
114 : : if (likely (ok)) break; \
115 : : result = DWARF_E_INVALID_CFI; \
116 : : goto out; \
117 : : } while (0)
118 : :
119 : 6521 : Dwarf_Frame *fs = *state;
120 : :
121 : : #define register_rule(regno, r_rule, r_value) do { \
122 : : if (unlikely (! enough_registers (regno, &fs, &result))) \
123 : : goto out; \
124 : : fs->regs[regno].rule = reg_##r_rule; \
125 : : fs->regs[regno].value = (r_value); \
126 : : } while (0)
127 : :
128 [ + + ]: 15656 : while (program < end)
129 : : {
130 : 13487 : uint8_t opcode = *program++;
131 : 13487 : Dwarf_Word regno;
132 : 13487 : Dwarf_Word offset;
133 : 13487 : Dwarf_Word sf_offset;
134 : 13487 : Dwarf_Word operand = opcode & CFI_PRIMARY_MAX;
135 [ + + + - : 13487 : switch (opcode)
- - + + -
+ - - + +
- + + - +
- + - - -
+ + + + +
- - ]
136 : : {
137 : : /* These cases move LOC, i.e. "create a new table row". */
138 : :
139 : 37 : case DW_CFA_advance_loc1:
140 : 37 : operand = *program++;
141 : 4672 : FALLTHROUGH;
142 : : case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX:
143 : 4672 : advance_loc:
144 : 4672 : loc += operand * cie->code_alignment_factor;
145 : 4672 : break;
146 : :
147 : 5 : case DW_CFA_advance_loc2:
148 [ - + ]: 5 : cfi_assert (program + 2 <= end);
149 [ + + ]: 5 : operand = read_2ubyte_unaligned_inc (cache, program);
150 : 5 : goto advance_loc;
151 : 0 : case DW_CFA_advance_loc4:
152 [ # # ]: 0 : cfi_assert (program + 4 <= end);
153 [ # # ]: 0 : operand = read_4ubyte_unaligned_inc (cache, program);
154 : 0 : goto advance_loc;
155 : 0 : case DW_CFA_MIPS_advance_loc8:
156 [ # # ]: 0 : cfi_assert (program + 8 <= end);
157 [ # # ]: 0 : operand = read_8ubyte_unaligned_inc (cache, program);
158 : 0 : goto advance_loc;
159 : :
160 : 0 : case DW_CFA_set_loc:
161 [ # # ]: 0 : if (likely (!read_encoded_value (cache, cie->fde_encoding,
162 : : &program, &loc)))
163 : : break;
164 : 0 : result = INTUSE(dwarf_errno) ();
165 : 0 : goto out;
166 : :
167 : : /* Now all following cases affect this row, but do not touch LOC.
168 : : These cases end with 'continue'. We only get out of the
169 : : switch block for the row-copying (LOC-moving) cases above. */
170 : :
171 : 128 : case DW_CFA_def_cfa:
172 : 128 : get_uleb128 (operand, program, end);
173 [ - + ]: 128 : cfi_assert (program < end);
174 : 128 : get_uleb128 (offset, program, end);
175 : 128 : def_cfa:
176 : 128 : fs->cfa_rule = cfa_offset;
177 : 128 : fs->cfa_val_reg = operand;
178 : 128 : fs->cfa_val_offset = offset;
179 : : /* Prime the rest of the Dwarf_Op so dwarf_frame_cfa can use it. */
180 : 128 : fs->cfa_data.offset.atom = DW_OP_bregx;
181 : 128 : fs->cfa_data.offset.offset = 0;
182 : 128 : continue;
183 : :
184 : 59 : case DW_CFA_def_cfa_register:
185 : 59 : get_uleb128 (regno, program, end);
186 [ - + ]: 59 : require_cfa_offset (fs);
187 : 59 : fs->cfa_val_reg = regno;
188 : 59 : continue;
189 : :
190 : 0 : case DW_CFA_def_cfa_sf:
191 : 0 : get_uleb128 (operand, program, end);
192 [ # # ]: 0 : cfi_assert (program < end);
193 : 0 : get_sleb128 (sf_offset, program, end);
194 : 0 : offset = sf_offset * cie->data_alignment_factor;
195 : 0 : goto def_cfa;
196 : :
197 : 168 : case DW_CFA_def_cfa_offset:
198 : 168 : get_uleb128 (offset, program, end);
199 : 168 : def_cfa_offset:
200 [ - + ]: 168 : require_cfa_offset (fs);
201 : 168 : fs->cfa_val_offset = offset;
202 : 168 : continue;
203 : :
204 : 0 : case DW_CFA_def_cfa_offset_sf:
205 : 0 : get_sleb128 (sf_offset, program, end);
206 : 0 : offset = sf_offset * cie->data_alignment_factor;
207 : 0 : goto def_cfa_offset;
208 : :
209 : 0 : case DW_CFA_def_cfa_expression:
210 : : /* DW_FORM_block is a ULEB128 length followed by that many bytes. */
211 : 0 : get_uleb128 (operand, program, end);
212 [ # # ]: 0 : cfi_assert (operand <= (Dwarf_Word) (end - program));
213 : 0 : fs->cfa_rule = cfa_expr;
214 : 0 : fs->cfa_data.expr.data = (unsigned char *) program;
215 : 0 : fs->cfa_data.expr.length = operand;
216 : 0 : program += operand;
217 : 0 : continue;
218 : :
219 : 8 : case DW_CFA_undefined:
220 : 8 : get_uleb128 (regno, program, end);
221 [ - + ]: 8 : register_rule (regno, undefined, 0);
222 : 8 : continue;
223 : :
224 : 1462 : case DW_CFA_same_value:
225 : 1462 : get_uleb128 (regno, program, end);
226 [ - + ]: 1462 : register_rule (regno, same_value, 0);
227 : 1462 : continue;
228 : :
229 : 0 : case DW_CFA_offset_extended:
230 : 0 : get_uleb128 (operand, program, end);
231 [ # # ]: 0 : cfi_assert (program < end);
232 : 442 : FALLTHROUGH;
233 : : case DW_CFA_offset + 0 ... DW_CFA_offset + CFI_PRIMARY_MAX:
234 : 442 : get_uleb128 (offset, program, end);
235 : 442 : offset *= cie->data_alignment_factor;
236 : 453 : offset_extended:
237 [ - + ]: 453 : register_rule (operand, offset, offset);
238 : 453 : continue;
239 : :
240 : 11 : case DW_CFA_offset_extended_sf:
241 : 11 : get_uleb128 (operand, program, end);
242 : 11 : get_sleb128 (sf_offset, program, end);
243 : 11 : offset_extended_sf:
244 : 11 : offset = sf_offset * cie->data_alignment_factor;
245 : 11 : goto offset_extended;
246 : :
247 : 0 : case DW_CFA_GNU_negative_offset_extended:
248 : : /* GNU extension obsoleted by DW_CFA_offset_extended_sf. */
249 : 0 : get_uleb128 (operand, program, end);
250 [ # # ]: 0 : cfi_assert (program < end);
251 : 0 : get_uleb128 (offset, program, end);
252 : 0 : sf_offset = -offset;
253 : 0 : goto offset_extended_sf;
254 : :
255 : 84 : case DW_CFA_val_offset:
256 : 84 : get_uleb128 (operand, program, end);
257 [ - + ]: 84 : cfi_assert (program < end);
258 : 84 : get_uleb128 (offset, program, end);
259 : 84 : offset *= cie->data_alignment_factor;
260 : 84 : val_offset:
261 [ - + ]: 84 : register_rule (operand, val_offset, offset);
262 : 84 : continue;
263 : :
264 : 0 : case DW_CFA_val_offset_sf:
265 : 0 : get_uleb128 (operand, program, end);
266 [ # # ]: 0 : cfi_assert (program < end);
267 : 0 : get_sleb128 (sf_offset, program, end);
268 : 0 : offset = sf_offset * cie->data_alignment_factor;
269 : 0 : goto val_offset;
270 : :
271 : 13 : case DW_CFA_register:
272 : 13 : get_uleb128 (regno, program, end);
273 [ - + ]: 13 : cfi_assert (program < end);
274 : 13 : get_uleb128 (operand, program, end);
275 [ - + ]: 13 : register_rule (regno, register, operand);
276 : 13 : continue;
277 : :
278 : 0 : case DW_CFA_expression:
279 : : /* Expression rule relies on section data, abi_cfi cannot use it. */
280 [ # # ]: 0 : assert (! abi_cfi);
281 : 0 : get_uleb128 (regno, program, end);
282 : 0 : offset = program - (const uint8_t *) cache->data->d.d_buf;
283 : : /* DW_FORM_block is a ULEB128 length followed by that many bytes. */
284 [ # # ]: 0 : cfi_assert (program < end);
285 : 0 : get_uleb128 (operand, program, end);
286 [ # # ]: 0 : cfi_assert (operand <= (Dwarf_Word) (end - program));
287 : 0 : program += operand;
288 [ # # ]: 0 : register_rule (regno, expression, offset);
289 : 0 : continue;
290 : :
291 : 0 : case DW_CFA_val_expression:
292 : : /* Expression rule relies on section data, abi_cfi cannot use it. */
293 [ # # ]: 0 : assert (! abi_cfi);
294 : 0 : get_uleb128 (regno, program, end);
295 : : /* DW_FORM_block is a ULEB128 length followed by that many bytes. */
296 : 0 : offset = program - (const uint8_t *) cache->data->d.d_buf;
297 : 0 : get_uleb128 (operand, program, end);
298 [ # # ]: 0 : cfi_assert (operand <= (Dwarf_Word) (end - program));
299 : 0 : program += operand;
300 [ # # ]: 0 : register_rule (regno, val_expression, offset);
301 : 0 : continue;
302 : :
303 : 0 : case DW_CFA_restore_extended:
304 : 0 : get_uleb128 (operand, program, end);
305 : 56 : FALLTHROUGH;
306 : 56 : case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX:
307 : :
308 [ - + - - ]: 56 : if (unlikely (abi_cfi) && likely (opcode == DW_CFA_restore))
309 : : {
310 : : /* Special case hack to give backend abi_cfi a shorthand. */
311 : 0 : cache->default_same_value = true;
312 : 0 : continue;
313 : : }
314 : :
315 : : /* This can't be used in the CIE's own initial instructions. */
316 [ - + ]: 56 : cfi_assert (cie->initial_state != NULL);
317 : :
318 : : /* Restore the CIE's initial rule for this register. */
319 [ - + ]: 56 : if (unlikely (! enough_registers (operand, &fs, &result)))
320 : 0 : goto out;
321 [ + - ]: 56 : if (cie->initial_state->nregs > operand)
322 : 56 : fs->regs[operand] = cie->initial_state->regs[operand];
323 : : else
324 : 0 : fs->regs[operand].rule = reg_unspecified;
325 : 56 : continue;
326 : :
327 : 11 : case DW_CFA_remember_state:
328 : : {
329 : : /* Duplicate the state and chain the copy on. */
330 : 11 : Dwarf_Frame *copy = duplicate_frame_state (fs, fs);
331 [ - + ]: 11 : if (unlikely (copy == NULL))
332 : : {
333 : 0 : result = DWARF_E_NOMEM;
334 : 0 : goto out;
335 : : }
336 : 11 : fs = copy;
337 : 11 : continue;
338 : : }
339 : :
340 : 11 : case DW_CFA_restore_state:
341 : : {
342 : : /* Pop the current state off and use the old one instead. */
343 : 11 : Dwarf_Frame *prev = fs->prev;
344 [ - + ]: 11 : cfi_assert (prev != NULL);
345 : 11 : free (fs);
346 : 11 : fs = prev;
347 : 11 : continue;
348 : : }
349 : :
350 : 6353 : case DW_CFA_nop:
351 : 6353 : continue;
352 : :
353 : 9 : case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */
354 [ + - ]: 9 : if (cache->e_machine == EM_AARCH64)
355 : : {
356 : : /* Toggles the return address state, indicating whether
357 : : the return address is encrypted or not on
358 : : aarch64. XXX not handled yet. */
359 : : }
360 : : else
361 : : {
362 : : /* This is magic shorthand used only by SPARC. It's
363 : : equivalent to a bunch of DW_CFA_register and
364 : : DW_CFA_offset operations. */
365 [ - + ]: 9 : if (unlikely (! enough_registers (31, &fs, &result)))
366 : 0 : goto out;
367 [ + + ]: 81 : for (regno = 8; regno < 16; ++regno)
368 : : {
369 : : /* Find each %oN in %iN. */
370 : 72 : fs->regs[regno].rule = reg_register;
371 : 72 : fs->regs[regno].value = regno + 16;
372 : : }
373 : 9 : unsigned int address_size;
374 : 18 : address_size = (cache->e_ident[EI_CLASS] == ELFCLASS32
375 [ + - ]: 9 : ? 4 : 8);
376 [ + + ]: 153 : for (; regno < 32; ++regno)
377 : : {
378 : : /* Find %l0..%l7 and %i0..%i7 in a block at the CFA. */
379 : 144 : fs->regs[regno].rule = reg_offset;
380 : 144 : fs->regs[regno].value = (regno - 16) * address_size;
381 : : }
382 : : }
383 : 9 : continue;
384 : :
385 : 0 : case DW_CFA_GNU_args_size:
386 : : /* XXX is this useful for anything? */
387 : 0 : get_uleb128 (operand, program, end);
388 : 0 : continue;
389 : :
390 : : default:
391 : 0 : cfi_assert (false);
392 : : continue;
393 : : }
394 : :
395 : : /* We get here only for the cases that have just moved LOC. */
396 [ - + ]: 4672 : cfi_assert (cie->initial_state != NULL);
397 [ + + ]: 4672 : if (find_pc >= loc)
398 : : /* This advance has not yet reached FIND_PC. */
399 : 320 : fs->start = loc;
400 : : else
401 : : {
402 : : /* We have just advanced past the address we're looking for.
403 : : The state currently described is what we want to see. */
404 : 4352 : fs->end = loc;
405 : 4352 : break;
406 : : }
407 : : }
408 : :
409 : : /* "The end of the instruction stream can be thought of as a
410 : : DW_CFA_set_loc (initial_location + address_range) instruction."
411 : : (DWARF 3.0 Section 6.4.3)
412 : :
413 : : When we fall off the end of the program without an advance_loc/set_loc
414 : : that put us past FIND_PC, the final state left by the FDE program
415 : : applies to this address (the caller ensured it was inside the FDE).
416 : : This address (FDE->end) is already in FS->end as set by the caller. */
417 : :
418 : : #undef register_rule
419 : : #undef cfi_assert
420 : :
421 : 2169 : out:
422 : :
423 : : /* Pop any remembered states left on the stack. */
424 [ - + ]: 6521 : while (fs->prev != NULL)
425 : : {
426 : 0 : Dwarf_Frame *prev = fs->prev;
427 : 0 : fs->prev = prev->prev;
428 : 0 : free (prev);
429 : : }
430 : :
431 [ + - ]: 6521 : if (likely (result == DWARF_E_NOERROR))
432 : 6521 : *state = fs;
433 : : else
434 : 0 : free (fs);
435 : :
436 : 6521 : return result;
437 : : }
438 : :
439 : : static int
440 : 6341 : cie_cache_initial_state (Dwarf_CFI *cache, struct dwarf_cie *cie)
441 : : {
442 : 6341 : int result = DWARF_E_NOERROR;
443 : :
444 [ + + ]: 6341 : if (likely (cie->initial_state != NULL))
445 : : return result;
446 : :
447 : : /* This CIE has not been used before. Play out its initial
448 : : instructions and cache the initial state that results.
449 : : First we'll let the backend fill in the default initial
450 : : state for this machine's ABI. */
451 : :
452 : 90 : Dwarf_CIE abi_info = { DW_CIE_ID_64, NULL, NULL, 1, 1, -1, "", NULL, 0, 0 };
453 : :
454 : : /* Make sure we have a backend handle cached. */
455 [ + + ]: 90 : if (unlikely (cache->ebl == NULL))
456 : : {
457 : 6 : cache->ebl = ebl_openbackend (cache->data->s->elf);
458 [ - + ]: 6 : if (unlikely (cache->ebl == NULL))
459 : 0 : cache->ebl = (void *) -1l;
460 : : }
461 : :
462 : : /* Fetch the ABI's default CFI program. */
463 [ + - ]: 90 : if (likely (cache->ebl != (void *) -1l)
464 [ + - ]: 90 : && unlikely (ebl_abi_cfi (cache->ebl, &abi_info) < 0))
465 : : return DWARF_E_UNKNOWN_ERROR;
466 : :
467 : 90 : Dwarf_Frame *cie_fs = calloc (1, sizeof (Dwarf_Frame));
468 [ + - ]: 90 : if (unlikely (cie_fs == NULL))
469 : : return DWARF_E_NOMEM;
470 : :
471 : : /* If the default state of any register is not "undefined"
472 : : (i.e. call-clobbered), then the backend supplies instructions
473 : : for the standard initial state. */
474 [ + - ]: 90 : if (abi_info.initial_instructions_end > abi_info.initial_instructions)
475 : : {
476 : : /* Dummy CIE for backend's instructions. */
477 : 90 : struct dwarf_cie abi_cie =
478 : : {
479 : 90 : .code_alignment_factor = abi_info.code_alignment_factor,
480 : 90 : .data_alignment_factor = abi_info.data_alignment_factor,
481 : : };
482 : 90 : result = execute_cfi (cache, &abi_cie, &cie_fs,
483 : : abi_info.initial_instructions,
484 : : abi_info.initial_instructions_end, true,
485 : : 0, (Dwarf_Addr) -1l);
486 : : }
487 : :
488 : : /* Now run the CIE's initial instructions. */
489 [ + - ]: 90 : if (cie->initial_instructions_end > cie->initial_instructions
490 [ + - ]: 90 : && likely (result == DWARF_E_NOERROR))
491 : 90 : result = execute_cfi (cache, cie, &cie_fs,
492 : : cie->initial_instructions,
493 : : cie->initial_instructions_end, false,
494 : : 0, (Dwarf_Addr) -1l);
495 : :
496 [ + - ]: 90 : if (likely (result == DWARF_E_NOERROR))
497 : : {
498 : : /* Now we have the initial state of things that all
499 : : FDEs using this CIE will start from. */
500 : 90 : cie_fs->cache = cache;
501 : 90 : cie->initial_state = cie_fs;
502 : : }
503 : :
504 : : return result;
505 : : }
506 : :
507 : : int
508 : : internal_function
509 : 6341 : __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
510 : : Dwarf_Addr address, Dwarf_Frame **frame)
511 : : {
512 : 6341 : int result = cie_cache_initial_state (cache, fde->cie);
513 [ + - ]: 6341 : if (likely (result == DWARF_E_NOERROR))
514 : : {
515 : 6341 : Dwarf_Frame *fs = duplicate_frame_state (fde->cie->initial_state, NULL);
516 [ - + ]: 6341 : if (unlikely (fs == NULL))
517 : 0 : return DWARF_E_NOMEM;
518 : :
519 : 6341 : fs->fde = fde;
520 : 6341 : fs->start = fde->start;
521 : 6341 : fs->end = fde->end;
522 : :
523 : 6341 : result = execute_cfi (cache, fde->cie, &fs,
524 : : fde->instructions, fde->instructions_end, false,
525 : : fde->start, address);
526 [ + - ]: 6341 : if (likely (result == DWARF_E_NOERROR))
527 : 6341 : *frame = fs;
528 : : }
529 : : return result;
530 : : }
|