blob: 632e91d3873dde36aa55fedf6525cc6787b77cbd [file] [log] [blame]
Ben Cheng25b3c042013-11-20 14:45:36 -08001/* CFI program execution.
Elliott Hughes03333822015-02-18 22:19:45 -08002 Copyright (C) 2009-2010, 2014 Red Hat, Inc.
3 This file is part of elfutils.
Ben Cheng25b3c042013-11-20 14:45:36 -08004
Elliott Hughes03333822015-02-18 22:19:45 -08005 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
Ben Cheng25b3c042013-11-20 14:45:36 -08007
Elliott Hughes03333822015-02-18 22:19:45 -08008 * 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
Ben Cheng25b3c042013-11-20 14:45:36 -080021 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
Elliott Hughes03333822015-02-18 22:19:45 -080025 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/>. */
Ben Cheng25b3c042013-11-20 14:45:36 -080028
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"
Elliott Hughes03333822015-02-18 22:19:45 -080038#include "system.h"
Ben Cheng25b3c042013-11-20 14:45:36 -080039#include <assert.h>
40#include <stdlib.h>
41#include <string.h>
42
43#define CFI_PRIMARY_MAX 0x3f
44
45static Dwarf_Frame *
46duplicate_frame_state (const Dwarf_Frame *original,
47 Dwarf_Frame *prev)
48{
49 size_t size = offsetof (Dwarf_Frame, regs[original->nregs]);
50 Dwarf_Frame *copy = malloc (size);
51 if (likely (copy != NULL))
52 {
53 memcpy (copy, original, size);
54 copy->prev = prev;
55 }
56 return copy;
57}
58
59/* Returns a DWARF_E_* error code, usually NOERROR or INVALID_CFI.
60 Frees *STATE on failure. */
61static int
62execute_cfi (Dwarf_CFI *cache,
63 const struct dwarf_cie *cie,
64 Dwarf_Frame **state,
65 const uint8_t *program, const uint8_t *const end, bool abi_cfi,
66 Dwarf_Addr loc, Dwarf_Addr find_pc)
67{
68 /* The caller should not give us anything out of range. */
69 assert (loc <= find_pc);
70
71 int result = DWARF_E_NOERROR;
72
73#define cfi_assert(ok) do { \
74 if (likely (ok)) break; \
75 result = DWARF_E_INVALID_CFI; \
76 goto out; \
77 } while (0)
78
79 Dwarf_Frame *fs = *state;
80 inline bool enough_registers (Dwarf_Word reg)
81 {
82 if (fs->nregs <= reg)
83 {
84 size_t size = offsetof (Dwarf_Frame, regs[reg + 1]);
85 Dwarf_Frame *bigger = realloc (fs, size);
86 if (unlikely (bigger == NULL))
87 {
88 result = DWARF_E_NOMEM;
89 return false;
90 }
91 else
92 {
Elliott Hughes03333822015-02-18 22:19:45 -080093 eu_static_assert (reg_unspecified == 0);
94 memset (bigger->regs + bigger->nregs, 0,
95 (reg + 1 - bigger->nregs) * sizeof bigger->regs[0]);
Ben Cheng25b3c042013-11-20 14:45:36 -080096 bigger->nregs = reg + 1;
97 fs = bigger;
98 }
99 }
100 return true;
101 }
102
103 inline void require_cfa_offset (void)
104 {
105 if (unlikely (fs->cfa_rule != cfa_offset))
106 fs->cfa_rule = cfa_invalid;
107 }
108
109#define register_rule(regno, r_rule, r_value) do { \
110 if (unlikely (! enough_registers (regno))) \
111 goto out; \
112 fs->regs[regno].rule = reg_##r_rule; \
113 fs->regs[regno].value = (r_value); \
114 } while (0)
115
116 while (program < end)
117 {
118 uint8_t opcode = *program++;
119 Dwarf_Word regno;
120 Dwarf_Word offset;
121 Dwarf_Word sf_offset;
122 Dwarf_Word operand = opcode & CFI_PRIMARY_MAX;
123 switch (opcode)
124 {
125 /* These cases move LOC, i.e. "create a new table row". */
126
127 case DW_CFA_advance_loc1:
128 operand = *program++;
129 case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX:
130 advance_loc:
131 loc += operand * cie->code_alignment_factor;
132 break;
133
134 case DW_CFA_advance_loc2:
Elliott Hughes03333822015-02-18 22:19:45 -0800135 cfi_assert (program + 2 <= end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800136 operand = read_2ubyte_unaligned_inc (cache, program);
137 goto advance_loc;
138 case DW_CFA_advance_loc4:
Elliott Hughes03333822015-02-18 22:19:45 -0800139 cfi_assert (program + 4 <= end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800140 operand = read_4ubyte_unaligned_inc (cache, program);
141 goto advance_loc;
142 case DW_CFA_MIPS_advance_loc8:
Elliott Hughes03333822015-02-18 22:19:45 -0800143 cfi_assert (program + 8 <= end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800144 operand = read_8ubyte_unaligned_inc (cache, program);
145 goto advance_loc;
146
147 case DW_CFA_set_loc:
148 if (likely (!read_encoded_value (cache, cie->fde_encoding,
149 &program, &loc)))
150 break;
151 result = INTUSE(dwarf_errno) ();
152 goto out;
153
154 /* Now all following cases affect this row, but do not touch LOC.
155 These cases end with 'continue'. We only get out of the
156 switch block for the row-copying (LOC-moving) cases above. */
157
158 case DW_CFA_def_cfa:
Elliott Hughes03333822015-02-18 22:19:45 -0800159 get_uleb128 (operand, program, end);
160 cfi_assert (program < end);
161 get_uleb128 (offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800162 def_cfa:
163 fs->cfa_rule = cfa_offset;
164 fs->cfa_val_reg = operand;
165 fs->cfa_val_offset = offset;
166 /* Prime the rest of the Dwarf_Op so dwarf_frame_cfa can use it. */
167 fs->cfa_data.offset.atom = DW_OP_bregx;
168 fs->cfa_data.offset.offset = 0;
169 continue;
170
171 case DW_CFA_def_cfa_register:
Elliott Hughes03333822015-02-18 22:19:45 -0800172 get_uleb128 (regno, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800173 require_cfa_offset ();
174 fs->cfa_val_reg = regno;
175 continue;
176
177 case DW_CFA_def_cfa_sf:
Elliott Hughes03333822015-02-18 22:19:45 -0800178 get_uleb128 (operand, program, end);
179 cfi_assert (program < end);
180 get_sleb128 (sf_offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800181 offset = sf_offset * cie->data_alignment_factor;
182 goto def_cfa;
183
184 case DW_CFA_def_cfa_offset:
Elliott Hughes03333822015-02-18 22:19:45 -0800185 get_uleb128 (offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800186 def_cfa_offset:
187 require_cfa_offset ();
188 fs->cfa_val_offset = offset;
189 continue;
190
191 case DW_CFA_def_cfa_offset_sf:
Elliott Hughes03333822015-02-18 22:19:45 -0800192 get_sleb128 (sf_offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800193 offset = sf_offset * cie->data_alignment_factor;
194 goto def_cfa_offset;
195
196 case DW_CFA_def_cfa_expression:
197 /* DW_FORM_block is a ULEB128 length followed by that many bytes. */
Elliott Hughes03333822015-02-18 22:19:45 -0800198 get_uleb128 (operand, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800199 cfi_assert (operand <= (Dwarf_Word) (end - program));
200 fs->cfa_rule = cfa_expr;
201 fs->cfa_data.expr.data = (unsigned char *) program;
202 fs->cfa_data.expr.length = operand;
203 program += operand;
204 continue;
205
206 case DW_CFA_undefined:
Elliott Hughes03333822015-02-18 22:19:45 -0800207 get_uleb128 (regno, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800208 register_rule (regno, undefined, 0);
209 continue;
210
211 case DW_CFA_same_value:
Elliott Hughes03333822015-02-18 22:19:45 -0800212 get_uleb128 (regno, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800213 register_rule (regno, same_value, 0);
214 continue;
215
216 case DW_CFA_offset_extended:
Elliott Hughes03333822015-02-18 22:19:45 -0800217 get_uleb128 (operand, program, end);
218 cfi_assert (program < end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800219 case DW_CFA_offset + 0 ... DW_CFA_offset + CFI_PRIMARY_MAX:
Elliott Hughes03333822015-02-18 22:19:45 -0800220 get_uleb128 (offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800221 offset *= cie->data_alignment_factor;
222 offset_extended:
223 register_rule (operand, offset, offset);
224 continue;
225
226 case DW_CFA_offset_extended_sf:
Elliott Hughes03333822015-02-18 22:19:45 -0800227 get_uleb128 (operand, program, end);
228 get_sleb128 (sf_offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800229 offset_extended_sf:
230 offset = sf_offset * cie->data_alignment_factor;
231 goto offset_extended;
232
233 case DW_CFA_GNU_negative_offset_extended:
234 /* GNU extension obsoleted by DW_CFA_offset_extended_sf. */
Elliott Hughes03333822015-02-18 22:19:45 -0800235 get_uleb128 (operand, program, end);
236 cfi_assert (program < end);
237 get_uleb128 (offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800238 sf_offset = -offset;
239 goto offset_extended_sf;
240
241 case DW_CFA_val_offset:
Elliott Hughes03333822015-02-18 22:19:45 -0800242 get_uleb128 (operand, program, end);
243 cfi_assert (program < end);
244 get_uleb128 (offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800245 offset *= cie->data_alignment_factor;
246 val_offset:
247 register_rule (operand, val_offset, offset);
248 continue;
249
250 case DW_CFA_val_offset_sf:
Elliott Hughes03333822015-02-18 22:19:45 -0800251 get_uleb128 (operand, program, end);
252 cfi_assert (program < end);
253 get_sleb128 (sf_offset, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800254 offset = sf_offset * cie->data_alignment_factor;
255 goto val_offset;
256
257 case DW_CFA_register:
Elliott Hughes03333822015-02-18 22:19:45 -0800258 get_uleb128 (regno, program, end);
259 cfi_assert (program < end);
260 get_uleb128 (operand, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800261 register_rule (regno, register, operand);
262 continue;
263
264 case DW_CFA_expression:
Elliott Hughes03333822015-02-18 22:19:45 -0800265 /* Expression rule relies on section data, abi_cfi cannot use it. */
266 assert (! abi_cfi);
267 get_uleb128 (regno, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800268 offset = program - (const uint8_t *) cache->data->d.d_buf;
269 /* DW_FORM_block is a ULEB128 length followed by that many bytes. */
Elliott Hughes03333822015-02-18 22:19:45 -0800270 cfi_assert (program < end);
271 get_uleb128 (operand, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800272 cfi_assert (operand <= (Dwarf_Word) (end - program));
273 program += operand;
274 register_rule (regno, expression, offset);
275 continue;
276
277 case DW_CFA_val_expression:
Elliott Hughes03333822015-02-18 22:19:45 -0800278 /* Expression rule relies on section data, abi_cfi cannot use it. */
279 assert (! abi_cfi);
280 get_uleb128 (regno, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800281 /* DW_FORM_block is a ULEB128 length followed by that many bytes. */
282 offset = program - (const uint8_t *) cache->data->d.d_buf;
Elliott Hughes03333822015-02-18 22:19:45 -0800283 get_uleb128 (operand, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800284 cfi_assert (operand <= (Dwarf_Word) (end - program));
285 program += operand;
286 register_rule (regno, val_expression, offset);
287 continue;
288
289 case DW_CFA_restore_extended:
Elliott Hughes03333822015-02-18 22:19:45 -0800290 get_uleb128 (operand, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800291 case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX:
292
293 if (unlikely (abi_cfi) && likely (opcode == DW_CFA_restore))
294 {
295 /* Special case hack to give backend abi_cfi a shorthand. */
296 cache->default_same_value = true;
297 continue;
298 }
299
300 /* This can't be used in the CIE's own initial instructions. */
301 cfi_assert (cie->initial_state != NULL);
302
303 /* Restore the CIE's initial rule for this register. */
304 if (unlikely (! enough_registers (operand)))
305 goto out;
306 if (cie->initial_state->nregs > operand)
307 fs->regs[operand] = cie->initial_state->regs[operand];
308 else
309 fs->regs[operand].rule = reg_unspecified;
310 continue;
311
312 case DW_CFA_remember_state:
313 {
314 /* Duplicate the state and chain the copy on. */
315 Dwarf_Frame *copy = duplicate_frame_state (fs, fs);
316 if (unlikely (copy == NULL))
317 {
318 result = DWARF_E_NOMEM;
319 goto out;
320 }
321 fs = copy;
322 continue;
323 }
324
325 case DW_CFA_restore_state:
326 {
327 /* Pop the current state off and use the old one instead. */
328 Dwarf_Frame *prev = fs->prev;
329 cfi_assert (prev != NULL);
330 free (fs);
331 fs = prev;
332 continue;
333 }
334
335 case DW_CFA_nop:
336 continue;
337
338 case DW_CFA_GNU_window_save:
339 /* This is magic shorthand used only by SPARC. It's equivalent
340 to a bunch of DW_CFA_register and DW_CFA_offset operations. */
341 if (unlikely (! enough_registers (31)))
342 goto out;
343 for (regno = 8; regno < 16; ++regno)
344 {
345 /* Find each %oN in %iN. */
346 fs->regs[regno].rule = reg_register;
347 fs->regs[regno].value = regno + 16;
348 }
349 unsigned int address_size = (cache->e_ident[EI_CLASS] == ELFCLASS32
350 ? 4 : 8);
351 for (; regno < 32; ++regno)
352 {
353 /* Find %l0..%l7 and %i0..%i7 in a block at the CFA. */
354 fs->regs[regno].rule = reg_offset;
355 fs->regs[regno].value = (regno - 16) * address_size;
356 }
357 continue;
358
359 case DW_CFA_GNU_args_size:
360 /* XXX is this useful for anything? */
Elliott Hughes03333822015-02-18 22:19:45 -0800361 get_uleb128 (operand, program, end);
Ben Cheng25b3c042013-11-20 14:45:36 -0800362 continue;
363
364 default:
365 cfi_assert (false);
366 continue;
367 }
368
369 /* We get here only for the cases that have just moved LOC. */
370 cfi_assert (cie->initial_state != NULL);
371 if (find_pc >= loc)
372 /* This advance has not yet reached FIND_PC. */
373 fs->start = loc;
374 else
375 {
376 /* We have just advanced past the address we're looking for.
377 The state currently described is what we want to see. */
378 fs->end = loc;
379 break;
380 }
381 }
382
383 /* "The end of the instruction stream can be thought of as a
384 DW_CFA_set_loc (initial_location + address_range) instruction."
385 (DWARF 3.0 Section 6.4.3)
386
387 When we fall off the end of the program without an advance_loc/set_loc
388 that put us past FIND_PC, the final state left by the FDE program
389 applies to this address (the caller ensured it was inside the FDE).
390 This address (FDE->end) is already in FS->end as set by the caller. */
391
392#undef register_rule
393#undef cfi_assert
394
395 out:
396
397 /* Pop any remembered states left on the stack. */
398 while (fs->prev != NULL)
399 {
400 Dwarf_Frame *prev = fs->prev;
401 fs->prev = prev->prev;
402 free (prev);
403 }
404
405 if (likely (result == DWARF_E_NOERROR))
406 *state = fs;
407 else
408 free (fs);
409
410 return result;
411}
412
413static int
414cie_cache_initial_state (Dwarf_CFI *cache, struct dwarf_cie *cie)
415{
416 int result = DWARF_E_NOERROR;
417
418 if (likely (cie->initial_state != NULL))
419 return result;
420
421 /* This CIE has not been used before. Play out its initial
422 instructions and cache the initial state that results.
423 First we'll let the backend fill in the default initial
424 state for this machine's ABI. */
425
426 Dwarf_CIE abi_info = { DW_CIE_ID_64, NULL, NULL, 1, 1, -1, "", NULL, 0, 0 };
427
428 /* Make sure we have a backend handle cached. */
429 if (unlikely (cache->ebl == NULL))
430 {
431 cache->ebl = ebl_openbackend (cache->data->s->elf);
432 if (unlikely (cache->ebl == NULL))
433 cache->ebl = (void *) -1l;
434 }
435
436 /* Fetch the ABI's default CFI program. */
437 if (likely (cache->ebl != (void *) -1l)
438 && unlikely (ebl_abi_cfi (cache->ebl, &abi_info) < 0))
439 return DWARF_E_UNKNOWN_ERROR;
440
441 Dwarf_Frame *cie_fs = calloc (1, sizeof (Dwarf_Frame));
442 if (unlikely (cie_fs == NULL))
443 return DWARF_E_NOMEM;
444
445 /* If the default state of any register is not "undefined"
446 (i.e. call-clobbered), then the backend supplies instructions
447 for the standard initial state. */
448 if (abi_info.initial_instructions_end > abi_info.initial_instructions)
449 {
450 /* Dummy CIE for backend's instructions. */
451 struct dwarf_cie abi_cie =
452 {
453 .code_alignment_factor = abi_info.code_alignment_factor,
454 .data_alignment_factor = abi_info.data_alignment_factor,
455 };
456 result = execute_cfi (cache, &abi_cie, &cie_fs,
457 abi_info.initial_instructions,
458 abi_info.initial_instructions_end, true,
459 0, (Dwarf_Addr) -1l);
460 }
461
462 /* Now run the CIE's initial instructions. */
463 if (cie->initial_instructions_end > cie->initial_instructions
464 && likely (result == DWARF_E_NOERROR))
465 result = execute_cfi (cache, cie, &cie_fs,
466 cie->initial_instructions,
467 cie->initial_instructions_end, false,
468 0, (Dwarf_Addr) -1l);
469
470 if (likely (result == DWARF_E_NOERROR))
471 {
472 /* Now we have the initial state of things that all
473 FDEs using this CIE will start from. */
474 cie_fs->cache = cache;
475 cie->initial_state = cie_fs;
476 }
477
478 return result;
479}
480
481int
482internal_function
483__libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
484 Dwarf_Addr address, Dwarf_Frame **frame)
485{
486 int result = cie_cache_initial_state (cache, fde->cie);
487 if (likely (result == DWARF_E_NOERROR))
488 {
489 Dwarf_Frame *fs = duplicate_frame_state (fde->cie->initial_state, NULL);
490 if (unlikely (fs == NULL))
491 return DWARF_E_NOMEM;
492
493 fs->fde = fde;
494 fs->start = fde->start;
495 fs->end = fde->end;
496
497 result = execute_cfi (cache, fde->cie, &fs,
498 fde->instructions, fde->instructions_end, false,
499 fde->start, address);
500 if (likely (result == DWARF_E_NOERROR))
501 *frame = fs;
502 }
503 return result;
504}