arm, objdump: Make objdump use bfd's machine detection to drive disassembly
[binutils-gdb.git] / gas / scfi.c
blob6c59a8eeabc9a2aa19d50b325fa1b5913f595861
1 /* scfi.c - Support for synthesizing DWARF CFI for hand-written asm.
2 Copyright (C) 2023 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #include "as.h"
22 #include "scfi.h"
23 #include "subsegs.h"
24 #include "scfidw2gen.h"
25 #include "dw2gencfi.h"
27 #if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN)
29 /* Beyond the target defined number of registers to be tracked
30 (SCFI_MAX_REG_ID), keep the next register ID, in sequence, for REG_CFA. */
31 #define REG_CFA (SCFI_MAX_REG_ID+1)
32 /* Define the total number of registers being tracked.
33 Used as index into an array of cfi_reglocS. Note that a ginsn may carry a
34 register number greater than MAX_NUM_SCFI_REGS, e.g., for the ginsns
35 corresponding to push fs/gs in AMD64. */
36 #define MAX_NUM_SCFI_REGS (REG_CFA+1)
38 #define REG_INVALID ((unsigned int)-1)
40 enum cfi_reglocstate
42 CFI_UNDEFINED,
43 CFI_IN_REG,
44 CFI_ON_STACK
47 /* Location at which CFI register is saved.
49 A CFI register (callee-saved registers, RA/LR) are always an offset from
50 the CFA. REG_CFA itself, however, may have REG_SP or REG_FP as base
51 register. Hence, keep the base reg ID and offset per tracked register. */
53 struct cfi_regloc
55 /* Base reg ID (DWARF register number). */
56 unsigned int base;
57 /* Location as offset from the CFA. */
58 offsetT offset;
59 /* Current state of the CFI register. */
60 enum cfi_reglocstate state;
63 typedef struct cfi_regloc cfi_reglocS;
65 struct scfi_op_data
67 const char *name;
70 typedef struct scfi_op_data scfi_op_dataS;
72 /* SCFI operation.
74 An SCFI operation represents a single atomic change to the SCFI state.
75 This can also be understood as an abstraction for what eventually gets
76 emitted as a DWARF CFI operation. */
78 struct scfi_op
80 /* An SCFI op updates the state of either the CFA or other tracked
81 (callee-saved, REG_SP etc) registers. 'reg' is in the DWARF register
82 number space and must be strictly less than MAX_NUM_SCFI_REGS. */
83 unsigned int reg;
84 /* Location of the reg. */
85 cfi_reglocS loc;
86 /* DWARF CFI opcode. */
87 uint32_t dw2cfi_op;
88 /* Some SCFI ops, e.g., for CFI_label, may need to carry additional data. */
89 scfi_op_dataS *op_data;
90 /* A linked list. */
91 struct scfi_op *next;
94 /* SCFI State - accumulated unwind information at a PC.
96 SCFI state is the accumulated unwind information encompassing:
97 - REG_SP, REG_FP,
98 - RA, and
99 - all callee-saved registers.
101 Note that SCFI_MAX_REG_ID is target/ABI dependent and is provided by the
102 backends. The backend must also identify the DWARF register numbers for
103 the REG_SP, and REG_FP registers. */
105 struct scfi_state
107 cfi_reglocS regs[MAX_NUM_SCFI_REGS];
108 cfi_reglocS scratch[MAX_NUM_SCFI_REGS];
109 /* Current stack size. */
110 offsetT stack_size;
111 /* Whether the stack size is known.
112 Stack size may become untraceable depending on the specific stack
113 manipulation machine instruction, e.g., rsp = rsp op reg instruction
114 makes the stack size untraceable. */
115 bool traceable_p;
118 /* Initialize a new SCFI op. */
120 static scfi_opS *
121 init_scfi_op (void)
123 scfi_opS *op = XCNEW (scfi_opS);
125 return op;
128 /* Free the SCFI ops, given the HEAD of the list. */
130 void
131 scfi_ops_cleanup (scfi_opS **head)
133 scfi_opS *op;
134 scfi_opS *next;
136 if (!head || !*head)
137 return;
139 op = *head;
140 next = op->next;
142 while (op)
144 free (op->op_data);
145 free (op);
146 op = next;
147 next = op ? op->next : NULL;
150 free (head);
153 /* Compare two SCFI states. */
155 static int
156 cmp_scfi_state (scfi_stateS *state1, scfi_stateS *state2)
158 int ret;
160 if (!state1 || !state2)
161 return 1;
163 /* Skip comparing the scratch[] value of registers. The user visible
164 unwind information is derived from the regs[] from the SCFI state. */
165 ret = memcmp (state1->regs, state2->regs,
166 sizeof (cfi_reglocS) * MAX_NUM_SCFI_REGS);
168 /* For user functions which perform dynamic stack allocation, after switching
169 t REG_FP based CFA tracking, it is perfectly possible to have stack usage
170 in some control flows. Further, the different control flows may even not
171 have the same idea of CFA tracking (likely later necessitating generation
172 of .cfi_remember_state / .cfi_restore_state pair). */
173 ret |= state1->regs[REG_CFA].base != state2->regs[REG_CFA].base;
175 if (!ret && state1->regs[REG_CFA].base == REG_SP)
176 ret |= state1->stack_size != state2->stack_size;
178 ret |= state1->traceable_p != state2->traceable_p;
180 return ret;
183 #if 0
184 static void
185 scfi_state_update_reg (scfi_stateS *state, uint32_t dst, uint32_t base,
186 int32_t offset)
188 if (dst >= MAX_NUM_SCFI_REGS)
189 return;
191 state->regs[dst].base = base;
192 state->regs[dst].offset = offset;
194 #endif
196 /* Update the SCFI state of REG as available on execution stack at OFFSET
197 from REG_CFA (BASE).
199 Note that BASE must be REG_CFA, because any other base (REG_SP, REG_FP)
200 is by definition transitory in the function. */
202 static void
203 scfi_state_save_reg (scfi_stateS *state, unsigned int reg, unsigned int base,
204 offsetT offset)
206 if (reg >= MAX_NUM_SCFI_REGS)
207 return;
209 gas_assert (base == REG_CFA);
211 state->regs[reg].base = base;
212 state->regs[reg].offset = offset;
213 state->regs[reg].state = CFI_ON_STACK;
216 static void
217 scfi_state_restore_reg (scfi_stateS *state, unsigned int reg)
219 if (reg >= MAX_NUM_SCFI_REGS)
220 return;
222 /* Sanity check. See Rule 4. */
223 gas_assert (state->regs[reg].state == CFI_ON_STACK);
224 gas_assert (state->regs[reg].base == REG_CFA);
226 /* PS: the register may still be on stack much after the restore. Reset the
227 SCFI state to CFI_UNDEFINED, however, to indicate that the most updated
228 source of value is register itself from here onwards. */
229 state->regs[reg].base = 0;
230 state->regs[reg].offset = 0;
231 state->regs[reg].state = CFI_UNDEFINED;
234 /* Identify if the given GAS instruction GINSN saves a register
235 (of interest) on stack. */
237 static bool
238 ginsn_scfi_save_reg_p (ginsnS *ginsn, scfi_stateS *state)
240 bool save_reg_p = false;
241 struct ginsn_src *src;
242 struct ginsn_dst *dst;
244 src = ginsn_get_src1 (ginsn);
245 dst = ginsn_get_dst (ginsn);
247 /* The first save to stack of callee-saved register is deemed as
248 register save. */
249 if (!ginsn_track_reg_p (ginsn_get_src_reg (src), GINSN_GEN_SCFI)
250 || state->regs[ginsn_get_src_reg (src)].state == CFI_ON_STACK)
251 return save_reg_p;
253 /* A register save insn may be an indirect mov. */
254 if (ginsn->type == GINSN_TYPE_MOV
255 && ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT
256 && (ginsn_get_dst_reg (dst) == REG_SP
257 || (ginsn_get_dst_reg (dst) == REG_FP
258 && state->regs[REG_CFA].base == REG_FP)))
259 save_reg_p = true;
260 /* or an explicit store to stack. */
261 else if (ginsn->type == GINSN_TYPE_STORE
262 && ginsn_get_dst_type (dst) == GINSN_DST_INDIRECT
263 && ginsn_get_dst_reg (dst) == REG_SP)
264 save_reg_p = true;
266 return save_reg_p;
269 /* Identify if the given GAS instruction GINSN restores a register
270 (of interest) on stack. */
272 static bool
273 ginsn_scfi_restore_reg_p (ginsnS *ginsn, scfi_stateS *state)
275 bool restore_reg_p = false;
276 struct ginsn_dst *dst;
277 struct ginsn_src *src1;
279 dst = ginsn_get_dst (ginsn);
280 src1 = ginsn_get_src1 (ginsn);
282 if (!ginsn_track_reg_p (ginsn_get_dst_reg (dst), GINSN_GEN_SCFI))
283 return restore_reg_p;
285 /* A register restore insn may be an indirect mov... */
286 if (ginsn->type == GINSN_TYPE_MOV
287 && ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
288 && (ginsn_get_src_reg (src1) == REG_SP
289 || (ginsn_get_src_reg (src1) == REG_FP
290 && state->regs[REG_CFA].base == REG_FP)))
291 restore_reg_p = true;
292 /* ...or an explicit load from stack. */
293 else if (ginsn->type == GINSN_TYPE_LOAD
294 && ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
295 && ginsn_get_src_reg (src1) == REG_SP)
296 restore_reg_p = true;
298 return restore_reg_p;
301 /* Append the SCFI operation OP to the list of SCFI operations in the
302 given GINSN. */
304 static int
305 ginsn_append_scfi_op (ginsnS *ginsn, scfi_opS *op)
307 scfi_opS *sop;
309 if (!ginsn || !op)
310 return 1;
312 if (!ginsn->scfi_ops)
314 ginsn->scfi_ops = XCNEW (scfi_opS *);
315 *ginsn->scfi_ops = op;
317 else
319 /* Add to tail. Most ginsns have a single SCFI operation,
320 so this traversal for every insertion is acceptable for now. */
321 sop = *ginsn->scfi_ops;
322 while (sop->next)
323 sop = sop->next;
325 sop->next = op;
327 ginsn->num_scfi_ops++;
329 return 0;
332 static void
333 scfi_op_add_def_cfa_reg (scfi_stateS *state, ginsnS *ginsn, unsigned int reg)
335 scfi_opS *op = NULL;
337 state->regs[REG_CFA].base = reg;
339 op = init_scfi_op ();
341 op->dw2cfi_op = DW_CFA_def_cfa_register;
342 op->reg = REG_CFA;
343 op->loc = state->regs[REG_CFA];
345 ginsn_append_scfi_op (ginsn, op);
348 static void
349 scfi_op_add_cfa_offset_inc (scfi_stateS *state, ginsnS *ginsn, offsetT num)
351 scfi_opS *op = NULL;
353 state->regs[REG_CFA].offset -= num;
355 op = init_scfi_op ();
357 op->dw2cfi_op = DW_CFA_def_cfa_offset;
358 op->reg = REG_CFA;
359 op->loc = state->regs[REG_CFA];
361 ginsn_append_scfi_op (ginsn, op);
364 static void
365 scfi_op_add_cfa_offset_dec (scfi_stateS *state, ginsnS *ginsn, offsetT num)
367 scfi_opS *op = NULL;
369 state->regs[REG_CFA].offset += num;
371 op = init_scfi_op ();
373 op->dw2cfi_op = DW_CFA_def_cfa_offset;
374 op->reg = REG_CFA;
375 op->loc = state->regs[REG_CFA];
377 ginsn_append_scfi_op (ginsn, op);
380 static void
381 scfi_op_add_def_cfa (scfi_stateS *state, ginsnS *ginsn, unsigned int reg,
382 offsetT num)
384 scfi_opS *op = NULL;
386 state->regs[REG_CFA].base = reg;
387 state->regs[REG_CFA].offset = num;
389 op = init_scfi_op ();
391 op->dw2cfi_op = DW_CFA_def_cfa;
392 op->reg = REG_CFA;
393 op->loc = state->regs[REG_CFA];
395 ginsn_append_scfi_op (ginsn, op);
398 static void
399 scfi_op_add_cfi_offset (scfi_stateS *state, ginsnS *ginsn, unsigned int reg)
401 scfi_opS *op = NULL;
403 op = init_scfi_op ();
405 op->dw2cfi_op = DW_CFA_offset;
406 op->reg = reg;
407 op->loc = state->regs[reg];
409 ginsn_append_scfi_op (ginsn, op);
412 static void
413 scfi_op_add_cfa_restore (ginsnS *ginsn, unsigned int reg)
415 scfi_opS *op = NULL;
417 op = init_scfi_op ();
419 op->dw2cfi_op = DW_CFA_restore;
420 op->reg = reg;
421 op->loc.base = REG_INVALID;
422 op->loc.offset = 0;
424 ginsn_append_scfi_op (ginsn, op);
427 static void
428 scfi_op_add_cfi_remember_state (ginsnS *ginsn)
430 scfi_opS *op = NULL;
432 op = init_scfi_op ();
434 op->dw2cfi_op = DW_CFA_remember_state;
436 ginsn_append_scfi_op (ginsn, op);
439 static void
440 scfi_op_add_cfi_restore_state (ginsnS *ginsn)
442 scfi_opS *op = NULL;
444 op = init_scfi_op ();
446 op->dw2cfi_op = DW_CFA_restore_state;
448 /* FIXME - add to the beginning of the scfi_ops. */
449 ginsn_append_scfi_op (ginsn, op);
452 void
453 scfi_op_add_cfi_label (ginsnS *ginsn, const char *name)
455 scfi_opS *op = NULL;
457 op = init_scfi_op ();
458 op->dw2cfi_op = CFI_label;
459 op->op_data = XCNEW (scfi_op_dataS);
460 op->op_data->name = name;
462 ginsn_append_scfi_op (ginsn, op);
465 void
466 scfi_op_add_signal_frame (ginsnS *ginsn)
468 scfi_opS *op = NULL;
470 op = init_scfi_op ();
471 op->dw2cfi_op = CFI_signal_frame;
473 ginsn_append_scfi_op (ginsn, op);
476 static int
477 verify_heuristic_traceable_reg_fp (ginsnS *ginsn, scfi_stateS *state)
479 /* The function uses this variable to issue error to user right away. */
480 int fp_traceable_p = 0;
481 enum ginsn_type gtype;
482 struct ginsn_src *src1;
483 struct ginsn_src *src2;
484 struct ginsn_dst *dst;
485 unsigned int src1_reg;
486 unsigned int dst_reg;
487 enum ginsn_src_type src1_type;
488 enum ginsn_src_type src2_type;
489 enum ginsn_dst_type dst_type;
491 gtype = ginsn->type;
493 src1 = ginsn_get_src1 (ginsn);
494 src2 = ginsn_get_src2 (ginsn);
495 dst = ginsn_get_dst (ginsn);
497 src1_reg = ginsn_get_src_reg (src1);
498 dst_reg = ginsn_get_dst_reg (dst);
500 src1_type = ginsn_get_src_type (src1);
501 src2_type = ginsn_get_src_type (src2);
502 dst_type = ginsn_get_dst_type (dst);
504 /* Stack manipulation can be done in a variety of ways. A program may
505 allocate stack statically or may perform dynamic stack allocation in
506 the prologue.
508 The SCFI machinery in GAS is based on some heuristics:
510 - Rule 3 If the base register for CFA tracking is REG_FP, the program
511 must not clobber REG_FP, unless it is for switch to REG_SP based CFA
512 tracking (via say, a pop %rbp in X86). */
514 /* Check all applicable instructions with dest REG_FP, when the CFA base
515 register is REG_FP. */
516 if (state->regs[REG_CFA].base == REG_FP
517 && (dst_type == GINSN_DST_REG || dst_type == GINSN_DST_INDIRECT)
518 && dst_reg == REG_FP)
520 /* Excuse the add/sub with imm usage: They are OK. */
521 if ((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB)
522 && src1_type == GINSN_SRC_REG && src1_reg == REG_FP
523 && src2_type == GINSN_SRC_IMM)
524 fp_traceable_p = 0;
525 /* REG_FP restore is OK too. */
526 else if (ginsn->type == GINSN_TYPE_LOAD)
527 fp_traceable_p = 0;
528 /* mov's to memory with REG_FP base do not make REG_FP untraceable. */
529 else if (dst_type == GINSN_DST_INDIRECT
530 && (gtype == GINSN_TYPE_MOV || gtype == GINSN_TYPE_STORE))
531 fp_traceable_p = 0;
532 /* Manipulations of the values possibly on stack are OK too. */
533 else if ((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB
534 || gtype == GINSN_TYPE_AND)
535 && dst_type == GINSN_DST_INDIRECT)
536 fp_traceable_p = 0;
537 /* All other ginsns with REG_FP as destination make REG_FP not
538 traceable. */
539 else
540 fp_traceable_p = 1;
543 if (fp_traceable_p)
544 as_bad_where (ginsn->file, ginsn->line,
545 _("SCFI: usage of REG_FP as scratch not supported"));
547 return fp_traceable_p;
550 static int
551 verify_heuristic_traceable_stack_manipulation (ginsnS *ginsn,
552 scfi_stateS *state)
554 /* The function uses this variable to issue error to user right away. */
555 int sp_untraceable_p = 0;
556 bool possibly_untraceable = false;
557 enum ginsn_type gtype;
558 struct ginsn_dst *dst;
559 struct ginsn_src *src1;
560 struct ginsn_src *src2;
561 unsigned int src1_reg;
562 unsigned int dst_reg;
563 enum ginsn_src_type src1_type;
564 enum ginsn_src_type src2_type;
565 enum ginsn_dst_type dst_type;
567 gtype = ginsn->type;
569 src1 = ginsn_get_src1 (ginsn);
570 src2 = ginsn_get_src2 (ginsn);
571 dst = ginsn_get_dst (ginsn);
573 src1_reg = ginsn_get_src_reg (src1);
574 dst_reg = ginsn_get_dst_reg (dst);
576 src1_type = ginsn_get_src_type (src1);
577 src2_type = ginsn_get_src_type (src2);
578 dst_type = ginsn_get_dst_type (dst);
580 /* Stack manipulation can be done in a variety of ways. A program may
581 allocate stack statically in prologue or may need to do dynamic stack
582 allocation.
584 The SCFI machinery in GAS is based on some heuristics:
586 - Rule 1 The base register for CFA tracking may be either REG_SP or
587 REG_FP.
589 - Rule 2 If the base register for CFA tracking is REG_SP, the precise
590 amount of stack usage (and hence, the value of rsp) must be known at
591 all times. */
593 if (gtype == GINSN_TYPE_MOV
594 && dst_type == GINSN_DST_REG && dst_reg == REG_SP
595 /* Exclude mov %rbp, %rsp from this check. */
596 && src1_type == GINSN_SRC_REG && src1_reg != REG_FP)
598 /* A previous mov %rsp, %reg must have been seen earlier for this to be
599 an OK for stack manipulation. */
600 if (state->scratch[src1_reg].base != REG_CFA
601 || state->scratch[src1_reg].state != CFI_IN_REG)
602 possibly_untraceable = true;
604 /* Check add/sub/and insn usage when CFA base register is REG_SP.
605 Any stack size manipulation, including stack realignment is not allowed
606 if CFA base register is REG_SP. */
607 else if (dst_type == GINSN_DST_REG && dst_reg == REG_SP
608 && (((gtype == GINSN_TYPE_ADD || gtype == GINSN_TYPE_SUB)
609 && src2_type != GINSN_SRC_IMM)
610 || gtype == GINSN_TYPE_AND || gtype == GINSN_TYPE_OTHER))
611 possibly_untraceable = true;
612 /* If a register save operation is seen when REG_SP is untraceable,
613 CFI cannot be synthesized for register saves, hence bail out. */
614 else if (ginsn_scfi_save_reg_p (ginsn, state) && !state->traceable_p)
616 sp_untraceable_p = 1;
617 /* If, however, the register save is an REG_FP-based, indirect mov
618 like: mov reg, disp(%rbp) and CFA base register is REG_BP,
619 untraceable REG_SP is not a problem. */
620 if (gtype == GINSN_TYPE_MOV && state->regs[REG_CFA].base == REG_FP
621 && dst_type == GINSN_DST_INDIRECT && dst_reg == REG_FP)
622 sp_untraceable_p = 0;
624 else if (ginsn_scfi_restore_reg_p (ginsn, state) && !state->traceable_p)
626 if (gtype == GINSN_TYPE_MOV && dst_type == GINSN_DST_INDIRECT
627 && (src1_reg == REG_SP
628 || (src1_reg == REG_FP && state->regs[REG_CFA].base != REG_FP)))
629 sp_untraceable_p = 1;
632 if (possibly_untraceable)
634 /* See Rule 2. For SP-based CFA, this makes CFA tracking not possible.
635 Propagate now to caller. */
636 if (state->regs[REG_CFA].base == REG_SP)
637 sp_untraceable_p = 1;
638 else if (state->traceable_p)
640 /* An extension of Rule 2.
641 For FP-based CFA, this may be a problem *if* certain specific
642 changes to the SCFI state are seen beyond this point, e.g.,
643 register save / restore from stack. */
644 gas_assert (state->regs[REG_CFA].base == REG_FP);
645 /* Simply make a note in the SCFI state object for now and
646 continue. Indicate an error when register save / restore
647 for callee-saved registers is seen. */
648 sp_untraceable_p = 0;
649 state->traceable_p = false;
653 if (sp_untraceable_p)
654 as_bad_where (ginsn->file, ginsn->line,
655 _("SCFI: unsupported stack manipulation pattern"));
657 return sp_untraceable_p;
660 static int
661 verify_heuristic_symmetrical_restore_reg (scfi_stateS *state, ginsnS* ginsn)
663 int sym_restore = true;
664 offsetT expected_offset = 0;
665 struct ginsn_src *src1;
666 struct ginsn_dst *dst;
667 unsigned int reg;
669 /* Rule 4: Save and Restore of callee-saved registers must be symmetrical.
670 It is expected that value of the saved register is restored correctly.
671 E.g.,
672 push reg1
673 push reg2
675 body of func which uses reg1 , reg2 as scratch,
676 and may be even spills them to stack.
678 pop reg2
679 pop reg1
680 It is difficult to verify the Rule 4 in all cases. For the SCFI machinery,
681 it is difficult to separate prologue-epilogue from the body of the function
683 Hence, the SCFI machinery at this time, should only warn on an asymetrical
684 restore. */
685 src1 = ginsn_get_src1 (ginsn);
686 dst = ginsn_get_dst (ginsn);
687 reg = ginsn_get_dst_reg (dst);
689 /* For non callee-saved registers, calling the API is meaningless. */
690 if (!ginsn_track_reg_p (ginsn_get_dst_reg (dst), GINSN_GEN_SCFI))
691 return sym_restore;
693 /* The register must have been saved on stack, for sure. */
694 gas_assert (state->regs[reg].state == CFI_ON_STACK);
695 gas_assert (state->regs[reg].base == REG_CFA);
697 if ((ginsn->type == GINSN_TYPE_MOV
698 || ginsn->type == GINSN_TYPE_LOAD)
699 && ginsn_get_src_type (src1) == GINSN_SRC_INDIRECT
700 && (ginsn_get_src_reg (src1) == REG_SP
701 || (ginsn_get_src_reg (src1) == REG_FP
702 && state->regs[REG_CFA].base == REG_FP)))
704 /* mov disp(%rsp), reg. */
705 /* mov disp(%rbp), reg. */
706 expected_offset = (((ginsn_get_src_reg (src1) == REG_SP)
707 ? -state->stack_size
708 : state->regs[REG_FP].offset)
709 + ginsn_get_src_disp (src1));
712 sym_restore = (expected_offset == state->regs[reg].offset);
714 return sym_restore;
717 /* Perform symbolic execution of the GINSN and update its list of scfi_ops.
718 scfi_ops are later used to directly generate the DWARF CFI directives.
719 Also update the SCFI state object STATE for the caller. */
721 static int
722 gen_scfi_ops (ginsnS *ginsn, scfi_stateS *state)
724 int ret = 0;
725 offsetT offset;
726 struct ginsn_src *src1;
727 struct ginsn_src *src2;
728 struct ginsn_dst *dst;
729 unsigned int src1_reg;
730 unsigned int dst_reg;
731 enum ginsn_src_type src1_type;
732 enum ginsn_src_type src2_type;
733 enum ginsn_dst_type dst_type;
735 if (!ginsn || !state)
736 ret = 1;
738 /* For the first ginsn (of type GINSN_TYPE_SYMBOL) in the gbb, generate
739 the SCFI op with DW_CFA_def_cfa. Note that the register and offset are
740 target-specific. */
741 if (GINSN_F_FUNC_BEGIN_P (ginsn))
743 scfi_op_add_def_cfa (state, ginsn, REG_SP, SCFI_INIT_CFA_OFFSET);
744 state->stack_size += SCFI_INIT_CFA_OFFSET;
745 return ret;
748 src1 = ginsn_get_src1 (ginsn);
749 src2 = ginsn_get_src2 (ginsn);
750 dst = ginsn_get_dst (ginsn);
752 src1_reg = ginsn_get_src_reg (src1);
753 dst_reg = ginsn_get_dst_reg (dst);
755 src1_type = ginsn_get_src_type (src1);
756 src2_type = ginsn_get_src_type (src2);
757 dst_type = ginsn_get_dst_type (dst);
759 ret = verify_heuristic_traceable_stack_manipulation (ginsn, state);
760 if (ret)
761 return ret;
763 ret = verify_heuristic_traceable_reg_fp (ginsn, state);
764 if (ret)
765 return ret;
767 switch (dst_type)
769 case GINSN_DST_REG:
770 switch (ginsn->type)
772 case GINSN_TYPE_MOV:
773 if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
774 && dst_type == GINSN_DST_REG && dst_reg == REG_FP
775 && state->regs[REG_CFA].base == REG_SP)
777 /* mov %rsp, %rbp. */
778 scfi_op_add_def_cfa_reg (state, ginsn, dst_reg);
780 else if (src1_type == GINSN_SRC_REG && src1_reg == REG_FP
781 && dst_type == GINSN_DST_REG && dst_reg == REG_SP
782 && state->regs[REG_CFA].base == REG_FP)
784 /* mov %rbp, %rsp. */
785 state->stack_size = -state->regs[REG_FP].offset;
786 scfi_op_add_def_cfa_reg (state, ginsn, dst_reg);
787 state->traceable_p = true;
789 else if (src1_type == GINSN_SRC_INDIRECT
790 && (src1_reg == REG_SP || src1_reg == REG_FP)
791 && ginsn_track_reg_p (dst_reg, GINSN_GEN_SCFI))
793 /* mov disp(%rsp), reg. */
794 /* mov disp(%rbp), reg. */
795 if (verify_heuristic_symmetrical_restore_reg (state, ginsn))
797 scfi_state_restore_reg (state, dst_reg);
798 scfi_op_add_cfa_restore (ginsn, dst_reg);
800 else
801 as_warn_where (ginsn->file, ginsn->line,
802 _("SCFI: asymetrical register restore"));
804 else if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
805 && dst_type == GINSN_DST_REG)
807 /* mov %rsp, %reg. */
808 /* The value of rsp is taken directly from state->stack_size.
809 IMP: The workflow in gen_scfi_ops must keep it updated.
810 PS: Not taking the value from state->scratch[REG_SP] is
811 intentional. */
812 state->scratch[dst_reg].base = REG_CFA;
813 state->scratch[dst_reg].offset = -state->stack_size;
814 state->scratch[dst_reg].state = CFI_IN_REG;
816 else if (src1_type == GINSN_SRC_REG
817 && dst_type == GINSN_DST_REG && dst_reg == REG_SP)
819 /* mov %reg, %rsp. */
820 /* Keep the value of REG_SP updated. */
821 if (state->scratch[src1_reg].state == CFI_IN_REG)
823 state->stack_size = -state->scratch[src1_reg].offset;
824 state->traceable_p = true;
826 # if 0
827 scfi_state_update_reg (state, ginsn_get_dst_reg (dst),
828 state->scratch[ginsn_get_src_reg (src1)].base,
829 state->scratch[ginsn_get_src_reg (src1)].offset);
830 #endif
833 break;
834 case GINSN_TYPE_SUB:
835 if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
836 && dst_type == GINSN_DST_REG && dst_reg == REG_SP
837 && src2_type == GINSN_SRC_IMM)
839 /* Stack inc/dec offset, when generated due to stack push and pop is
840 target-specific. Use the value encoded in the ginsn. */
841 state->stack_size += ginsn_get_src_imm (src2);
842 if (state->regs[REG_CFA].base == REG_SP)
844 /* push reg. */
845 scfi_op_add_cfa_offset_dec (state, ginsn, ginsn_get_src_imm (src2));
848 break;
849 case GINSN_TYPE_ADD:
850 if (src1_type == GINSN_SRC_REG && src1_reg == REG_SP
851 && dst_type == GINSN_DST_REG && dst_reg == REG_SP
852 && src2_type == GINSN_SRC_IMM)
854 /* Stack inc/dec offset is target-specific. Use the value
855 encoded in the ginsn. */
856 state->stack_size -= ginsn_get_src_imm (src2);
857 /* pop %reg affects CFA offset only if CFA is currently
858 stack-pointer based. */
859 if (state->regs[REG_CFA].base == REG_SP)
861 scfi_op_add_cfa_offset_inc (state, ginsn, ginsn_get_src_imm (src2));
864 else if (src1_type == GINSN_SRC_REG && src1_reg == REG_FP
865 && dst_type == GINSN_DST_REG && dst_reg == REG_SP
866 && state->regs[REG_CFA].base == REG_FP)
868 /* FIXME - what is this for ? */
869 state->stack_size = 0 - (state->regs[REG_FP].offset + ginsn_get_src_imm (src2));
871 break;
872 case GINSN_TYPE_LOAD:
873 /* If this is a load from stack. */
874 if (src1_type == GINSN_SRC_INDIRECT
875 && ((src1_reg == REG_FP && state->regs[REG_CFA].base == REG_FP)
876 || src1_reg == REG_SP))
879 /* pop %rbp when CFA tracking is REG_FP based. */
880 if (dst_reg == REG_FP && state->regs[REG_CFA].base == REG_FP)
882 scfi_op_add_def_cfa_reg (state, ginsn, REG_SP);
883 if (state->regs[REG_CFA].offset != state->stack_size)
884 scfi_op_add_cfa_offset_inc (state, ginsn,
885 (state->regs[REG_CFA].offset - state->stack_size));
887 if (ginsn_track_reg_p (dst_reg, GINSN_GEN_SCFI))
889 if (verify_heuristic_symmetrical_restore_reg (state, ginsn))
891 scfi_state_restore_reg (state, dst_reg);
892 scfi_op_add_cfa_restore (ginsn, dst_reg);
894 else
895 as_warn_where (ginsn->file, ginsn->line,
896 _("SCFI: asymetrical register restore"));
899 break;
900 default:
901 break;
903 break;
905 case GINSN_DST_INDIRECT:
906 /* Some operations with an indirect access to memory (or even to stack)
907 may still be uninteresting for SCFI purpose (e.g, addl %edx, -32(%rsp)
908 in x86). In case of x86_64, these can neither be a register
909 save / unsave, nor can alter the stack size.
910 PS: This condition may need to be revisited for other arches. */
911 if (ginsn->type == GINSN_TYPE_ADD || ginsn->type == GINSN_TYPE_SUB
912 || ginsn->type == GINSN_TYPE_AND)
913 break;
914 gas_assert (ginsn->type == GINSN_TYPE_MOV
915 || ginsn->type == GINSN_TYPE_STORE
916 || ginsn->type == GINSN_TYPE_LOAD);
917 /* mov reg, disp(%rbp) */
918 /* mov reg, disp(%rsp) */
919 if (ginsn_scfi_save_reg_p (ginsn, state))
921 if (dst_reg == REG_SP)
923 /* mov reg, disp(%rsp) */
924 offset = 0 - state->stack_size + ginsn_get_dst_disp (dst);
925 scfi_state_save_reg (state, src1_reg, REG_CFA, offset);
926 scfi_op_add_cfi_offset (state, ginsn, src1_reg);
928 else if (dst_reg == REG_FP)
930 gas_assert (state->regs[REG_CFA].base == REG_FP);
931 /* mov reg, disp(%rbp) */
932 offset = 0 - state->regs[REG_CFA].offset + ginsn_get_dst_disp (dst);
933 scfi_state_save_reg (state, src1_reg, REG_CFA, offset);
934 scfi_op_add_cfi_offset (state, ginsn, src1_reg);
937 break;
939 default:
940 /* Skip GINSN_DST_UNKNOWN and GINSN_DST_MEM as they are uninteresting
941 currently for SCFI. */
942 break;
945 return ret;
948 /* Recursively perform forward flow of the (unwind information) SCFI STATE
949 starting at basic block GBB.
951 The core of forward flow process takes the SCFI state at the entry of a bb
952 and updates it incrementally as per the semantics of each ginsn in the bb.
954 Returns error code, if any. */
956 static int
957 forward_flow_scfi_state (gcfgS *gcfg, gbbS *gbb, scfi_stateS *state)
959 ginsnS *ginsn;
960 gbbS *prev_bb;
961 gedgeS *gedge = NULL;
962 int ret = 0;
964 if (gbb->visited)
966 /* Check that the SCFI state is the same as previous. */
967 ret = cmp_scfi_state (state, gbb->entry_state);
968 if (ret)
969 as_bad (_("SCFI: Bad CFI propagation perhaps"));
970 return ret;
973 gbb->visited = true;
975 gbb->entry_state = XCNEW (scfi_stateS);
976 memcpy (gbb->entry_state, state, sizeof (scfi_stateS));
978 /* Perform symbolic execution of each ginsn in the gbb and update the
979 scfi_ops list of each ginsn (and also update the STATE object). */
980 bb_for_each_insn(gbb, ginsn)
982 ret = gen_scfi_ops (ginsn, state);
983 if (ret)
984 goto fail;
987 gbb->exit_state = XCNEW (scfi_stateS);
988 memcpy (gbb->exit_state, state, sizeof (scfi_stateS));
990 /* Forward flow the SCFI state. Currently, we process the next basic block
991 in DFS order. But any forward traversal order should be fine. */
992 prev_bb = gbb;
993 if (gbb->num_out_gedges)
995 bb_for_each_edge(gbb, gedge)
997 gbb = gedge->dst_bb;
998 /* Ensure that the state is the one from the exit of the prev bb. */
999 memcpy (state, prev_bb->exit_state, sizeof (scfi_stateS));
1000 if (gbb->visited)
1002 ret = cmp_scfi_state (gbb->entry_state, state);
1003 if (ret)
1004 goto fail;
1007 if (!gedge->visited)
1009 gedge->visited = true;
1011 /* Entry SCFI state for the destination bb of the edge is the
1012 same as the exit SCFI state of the source bb of the edge. */
1013 memcpy (state, prev_bb->exit_state, sizeof (scfi_stateS));
1014 ret = forward_flow_scfi_state (gcfg, gbb, state);
1015 if (ret)
1016 goto fail;
1021 return 0;
1023 fail:
1025 if (gedge)
1026 gedge->visited = true;
1027 return 1;
1030 static int
1031 backward_flow_scfi_state (const symbolS *func ATTRIBUTE_UNUSED, gcfgS *gcfg)
1033 gbbS **prog_order_bbs;
1034 gbbS **restore_bbs;
1035 gbbS *current_bb;
1036 gbbS *prev_bb;
1037 gbbS *dst_bb;
1038 ginsnS *ginsn;
1039 gedgeS *gedge = NULL;
1041 int ret = 0;
1042 uint64_t i, j;
1044 /* Basic blocks in reverse program order. */
1045 prog_order_bbs = XCNEWVEC (gbbS *, gcfg->num_gbbs);
1046 /* Basic blocks for which CFI remember op needs to be generated. */
1047 restore_bbs = XCNEWVEC (gbbS *, gcfg->num_gbbs);
1049 gcfg_get_bbs_in_prog_order (gcfg, prog_order_bbs);
1051 i = gcfg->num_gbbs - 1;
1052 /* Traverse in reverse program order. */
1053 while (i > 0)
1055 current_bb = prog_order_bbs[i];
1056 prev_bb = prog_order_bbs[i-1];
1057 if (cmp_scfi_state (prev_bb->exit_state, current_bb->entry_state))
1059 /* Candidate for .cfi_restore_state found. */
1060 ginsn = bb_get_first_ginsn (current_bb);
1061 scfi_op_add_cfi_restore_state (ginsn);
1062 /* Memorize current_bb now to find location for its remember state
1063 later. */
1064 restore_bbs[i] = current_bb;
1066 else
1068 bb_for_each_edge (current_bb, gedge)
1070 dst_bb = gedge->dst_bb;
1071 for (j = 0; j < gcfg->num_gbbs; j++)
1072 if (restore_bbs[j] == dst_bb)
1074 ginsn = bb_get_last_ginsn (current_bb);
1075 scfi_op_add_cfi_remember_state (ginsn);
1076 /* Remove the memorised restore_bb from the list. */
1077 restore_bbs[j] = NULL;
1078 break;
1082 i--;
1085 /* All .cfi_restore_state pseudo-ops must have a corresponding
1086 .cfi_remember_state by now. */
1087 for (j = 0; j < gcfg->num_gbbs; j++)
1088 if (restore_bbs[j] != NULL)
1090 ret = 1;
1091 break;
1094 free (restore_bbs);
1095 free (prog_order_bbs);
1097 return ret;
1100 /* Synthesize DWARF CFI for a function. */
1103 scfi_synthesize_dw2cfi (const symbolS *func, gcfgS *gcfg, gbbS *root_bb)
1105 int ret;
1106 scfi_stateS *init_state;
1108 init_state = XCNEW (scfi_stateS);
1109 init_state->traceable_p = true;
1111 /* Traverse the input GCFG and perform forward flow of information.
1112 Update the scfi_op(s) per ginsn. */
1113 ret = forward_flow_scfi_state (gcfg, root_bb, init_state);
1114 if (ret)
1116 as_bad (_("SCFI: forward pass failed for func '%s'"), S_GET_NAME (func));
1117 goto end;
1120 ret = backward_flow_scfi_state (func, gcfg);
1121 if (ret)
1123 as_bad (_("SCFI: backward pass failed for func '%s'"), S_GET_NAME (func));
1124 goto end;
1127 end:
1128 free (init_state);
1129 return ret;
1132 static int
1133 handle_scfi_dot_cfi (ginsnS *ginsn)
1135 scfi_opS *op;
1137 /* Nothing to do. */
1138 if (!ginsn->scfi_ops)
1139 return 0;
1141 op = *ginsn->scfi_ops;
1142 if (!op)
1143 goto bad;
1145 while (op)
1147 switch (op->dw2cfi_op)
1149 case DW_CFA_def_cfa_register:
1150 scfi_dot_cfi (DW_CFA_def_cfa_register, op->loc.base, 0, 0, NULL,
1151 ginsn->sym);
1152 break;
1153 case DW_CFA_def_cfa_offset:
1154 scfi_dot_cfi (DW_CFA_def_cfa_offset, op->loc.base, 0,
1155 op->loc.offset, NULL, ginsn->sym);
1156 break;
1157 case DW_CFA_def_cfa:
1158 scfi_dot_cfi (DW_CFA_def_cfa, op->loc.base, 0, op->loc.offset,
1159 NULL, ginsn->sym);
1160 break;
1161 case DW_CFA_offset:
1162 scfi_dot_cfi (DW_CFA_offset, op->reg, 0, op->loc.offset, NULL,
1163 ginsn->sym);
1164 break;
1165 case DW_CFA_restore:
1166 scfi_dot_cfi (DW_CFA_restore, op->reg, 0, 0, NULL, ginsn->sym);
1167 break;
1168 case DW_CFA_remember_state:
1169 scfi_dot_cfi (DW_CFA_remember_state, 0, 0, 0, NULL, ginsn->sym);
1170 break;
1171 case DW_CFA_restore_state:
1172 scfi_dot_cfi (DW_CFA_restore_state, 0, 0, 0, NULL, ginsn->sym);
1173 break;
1174 case CFI_label:
1175 scfi_dot_cfi (CFI_label, 0, 0, 0, op->op_data->name, ginsn->sym);
1176 free ((char *) op->op_data->name);
1177 break;
1178 case CFI_signal_frame:
1179 scfi_dot_cfi (CFI_signal_frame, 0, 0, 0, NULL, ginsn->sym);
1180 break;
1181 default:
1182 goto bad;
1183 break;
1185 op = op->next;
1188 return 0;
1189 bad:
1190 as_bad (_("SCFI: Invalid DWARF CFI opcode data"));
1191 return 1;
1194 /* Emit Synthesized DWARF CFI. */
1197 scfi_emit_dw2cfi (const symbolS *func)
1199 struct frch_ginsn_data *frch_gdata;
1200 ginsnS* ginsn = NULL;
1202 frch_gdata = frchain_now->frch_ginsn_data;
1203 ginsn = frch_gdata->gins_rootP;
1205 while (ginsn)
1207 switch (ginsn->type)
1209 case GINSN_TYPE_SYMBOL:
1210 /* .cfi_startproc and .cfi_endproc pseudo-ops. */
1211 if (GINSN_F_FUNC_BEGIN_P (ginsn))
1213 scfi_dot_cfi_startproc (frch_gdata->start_addr);
1214 break;
1216 else if (GINSN_F_FUNC_END_P (ginsn))
1218 scfi_dot_cfi_endproc (ginsn->sym);
1219 break;
1221 /* Fall through. */
1222 case GINSN_TYPE_ADD:
1223 case GINSN_TYPE_AND:
1224 case GINSN_TYPE_CALL:
1225 case GINSN_TYPE_JUMP:
1226 case GINSN_TYPE_JUMP_COND:
1227 case GINSN_TYPE_MOV:
1228 case GINSN_TYPE_LOAD:
1229 case GINSN_TYPE_PHANTOM:
1230 case GINSN_TYPE_STORE:
1231 case GINSN_TYPE_SUB:
1232 case GINSN_TYPE_OTHER:
1233 case GINSN_TYPE_RETURN:
1235 /* For all other SCFI ops, invoke the handler. */
1236 if (ginsn->scfi_ops)
1237 handle_scfi_dot_cfi (ginsn);
1238 break;
1240 default:
1241 /* No other GINSN_TYPE_* expected. */
1242 as_bad (_("SCFI: bad ginsn for func '%s'"),
1243 S_GET_NAME (func));
1244 break;
1246 ginsn = ginsn->next;
1248 return 0;
1251 #else
1254 scfi_emit_dw2cfi (const symbolS *func ATTRIBUTE_UNUSED)
1256 as_bad (_("SCFI: unsupported for target"));
1257 return 1;
1261 scfi_synthesize_dw2cfi (const symbolS *func ATTRIBUTE_UNUSED,
1262 gcfgS *gcfg ATTRIBUTE_UNUSED,
1263 gbbS *root_bb ATTRIBUTE_UNUSED)
1265 as_bad (_("SCFI: unsupported for target"));
1266 return 1;
1269 #endif /* defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN). */