1 /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
2    Copyright (C) 2003-2024 Free Software Foundation, Inc.
3    Contributed by Michal Ludvig <mludvig@suse.cz>
4 
5    This file is part of GAS, the GNU Assembler.
6 
7    GAS is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11 
12    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free
19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21 
22 #include "as.h"
23 #include "dw2gencfi.h"
24 #include "subsegs.h"
25 #include "dwarf2dbg.h"
26 #include "gen-sframe.h"
27 
28 #ifdef TARGET_USE_CFIPOP
29 
30 /* By default, use difference expressions if DIFF_EXPR_OK is defined.  */
31 #ifndef CFI_DIFF_EXPR_OK
32 # ifdef DIFF_EXPR_OK
33 #  define CFI_DIFF_EXPR_OK 1
34 # else
35 #  define CFI_DIFF_EXPR_OK 0
36 # endif
37 #endif
38 
39 #ifndef CFI_DIFF_LSDA_OK
40 #define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
41 #endif
42 
43 #if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
44 # error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
45 #endif
46 
47 /* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
48    of the CIE.  Default to 1 if not otherwise specified.  */
49 #ifndef DWARF2_LINE_MIN_INSN_LENGTH
50 #define DWARF2_LINE_MIN_INSN_LENGTH 1
51 #endif
52 
53 /* By default, use 32-bit relocations from .eh_frame into .text.  */
54 #ifndef DWARF2_FDE_RELOC_SIZE
55 #define DWARF2_FDE_RELOC_SIZE 4
56 #endif
57 
58 /* By default, use a read-only .eh_frame section.  */
59 #ifndef DWARF2_EH_FRAME_READ_ONLY
60 #define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
61 #endif
62 
63 #ifndef EH_FRAME_ALIGNMENT
64 #define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
65 #endif
66 
67 #define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh \
68                                  || TARGET_MULTIPLE_EH_FRAME_SECTIONS)
69 
70 #ifndef DWARF2_FORMAT
71 #define DWARF2_FORMAT(SEC) dwarf2_format_32bit
72 #endif
73 
74 #ifndef DWARF2_ADDR_SIZE
75 #define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
76 #endif
77 
78 #if MULTIPLE_FRAME_SECTIONS
79 #define CUR_SEG(structp) structp->cur_seg
80 #define SET_CUR_SEG(structp, seg) structp->cur_seg = seg
81 #define HANDLED(structp) structp->handled
82 #define SET_HANDLED(structp, val) structp->handled = val
83 #else
84 #define CUR_SEG(structp) NULL
85 #define SET_CUR_SEG(structp, seg) (void) (0 && seg)
86 #define HANDLED(structp) 0
87 #define SET_HANDLED(structp, val) (void) (0 && val)
88 #endif
89 
90 #ifndef tc_cfi_reloc_for_encoding
91 #define tc_cfi_reloc_for_encoding(e) BFD_RELOC_NONE
92 #endif
93 
94 /* Targets which support SFrame format will define this and return true.  */
95 #ifndef support_sframe_p
96 # define support_sframe_p() false
97 #endif
98 
99 /* Private segment collection list.  */
100 struct dwcfi_seg_list
101 {
102   segT   seg;
103   int    subseg;
104   char * seg_name;
105 };
106 
107 #ifdef SUPPORT_COMPACT_EH
108 static bool compact_eh;
109 #else
110 #define compact_eh 0
111 #endif
112 
113 static htab_t dwcfi_hash;
114 
115 /* Emit a single byte into the current segment.  */
116 
117 static inline void
out_one(int byte)118 out_one (int byte)
119 {
120   FRAG_APPEND_1_CHAR (byte);
121 }
122 
123 /* Emit a two-byte word into the current segment.  */
124 
125 static inline void
out_two(int data)126 out_two (int data)
127 {
128   md_number_to_chars (frag_more (2), data, 2);
129 }
130 
131 /* Emit a four byte word into the current segment.  */
132 
133 static inline void
out_four(int data)134 out_four (int data)
135 {
136   md_number_to_chars (frag_more (4), data, 4);
137 }
138 
139 /* Emit an unsigned "little-endian base 128" number.  */
140 
141 static void
out_uleb128(addressT value)142 out_uleb128 (addressT value)
143 {
144   output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
145 }
146 
147 /* Emit an unsigned "little-endian base 128" number.  */
148 
149 static void
out_sleb128(offsetT value)150 out_sleb128 (offsetT value)
151 {
152   output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
153 }
154 
155 static unsigned int
encoding_size(unsigned char encoding)156 encoding_size (unsigned char encoding)
157 {
158   if (encoding == DW_EH_PE_omit)
159     return 0;
160   switch (encoding & 0x7)
161     {
162     case 0:
163       return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
164     case DW_EH_PE_udata2:
165       return 2;
166     case DW_EH_PE_udata4:
167       return 4;
168     case DW_EH_PE_udata8:
169       return 8;
170     default:
171       abort ();
172     }
173 }
174 
175 /* Emit expression EXP in ENCODING.  If EMIT_ENCODING is true, first
176    emit a byte containing ENCODING.  */
177 
178 static void
emit_expr_encoded(expressionS * exp,int encoding,bool emit_encoding)179 emit_expr_encoded (expressionS *exp, int encoding, bool emit_encoding)
180 {
181   unsigned int size = encoding_size (encoding);
182   bfd_reloc_code_real_type code;
183 
184   if (encoding == DW_EH_PE_omit)
185     return;
186 
187   if (emit_encoding)
188     out_one (encoding);
189 
190   code = tc_cfi_reloc_for_encoding (encoding);
191   if (code != BFD_RELOC_NONE)
192     {
193       reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
194       char *p = frag_more (size);
195       gas_assert (size == (unsigned) howto->bitsize / 8);
196       md_number_to_chars (p, 0, size);
197       fix_new (frag_now, p - frag_now->fr_literal, size, exp->X_add_symbol,
198                  exp->X_add_number, howto->pc_relative, code);
199     }
200   else if ((encoding & 0x70) == DW_EH_PE_pcrel)
201     {
202 #if CFI_DIFF_EXPR_OK
203       expressionS tmp = *exp;
204       tmp.X_op = O_subtract;
205       tmp.X_op_symbol = symbol_temp_new_now ();
206       emit_expr (&tmp, size);
207 #elif defined (tc_cfi_emit_pcrel_expr)
208       tc_cfi_emit_pcrel_expr (exp, size);
209 #else
210       abort ();
211 #endif
212     }
213   else
214     emit_expr (exp, size);
215 }
216 
217 /* Build based on segment the derived .debug_...
218    segment name containing origin segment's postfix name part.  */
219 
220 static char *
get_debugseg_name(segT seg,const char * base_name)221 get_debugseg_name (segT seg, const char *base_name)
222 {
223   const char * name;
224   const char * dollar;
225   const char * dot;
226 
227   if (!seg
228       || (name = bfd_section_name (seg)) == NULL
229       || *name == 0)
230     return notes_strdup (base_name);
231 
232   dollar = strchr (name, '$');
233   dot = strchr (name + 1, '.');
234 
235   if (!dollar && !dot)
236     {
237       if (!strcmp (base_name, ".eh_frame_entry")
238             && strcmp (name, ".text") != 0)
239           return notes_concat (base_name, ".", name, NULL);
240 
241       name = "";
242     }
243   else if (!dollar)
244     name = dot;
245   else if (!dot)
246     name = dollar;
247   else if (dot < dollar)
248     name = dot;
249   else
250     name = dollar;
251 
252   return notes_concat (base_name, name, NULL);
253 }
254 
255 /* Allocate a dwcfi_seg_list structure.  */
256 
257 static struct dwcfi_seg_list *
alloc_debugseg_item(segT seg,int subseg,char * name)258 alloc_debugseg_item (segT seg, int subseg, char *name)
259 {
260   struct dwcfi_seg_list *r;
261 
262   r = notes_alloc (sizeof (*r) + strlen (name));
263   r->seg = seg;
264   r->subseg = subseg;
265   r->seg_name = name;
266   return r;
267 }
268 
269 static segT
is_now_linkonce_segment(void)270 is_now_linkonce_segment (void)
271 {
272   if (compact_eh)
273     return now_seg;
274 
275   if (TARGET_MULTIPLE_EH_FRAME_SECTIONS)
276     return now_seg;
277 
278   if ((bfd_section_flags (now_seg)
279        & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
280             | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
281             | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0)
282     return now_seg;
283   return NULL;
284 }
285 
286 /* Generate debug... segment with same linkonce properties
287    of based segment.  */
288 
289 static segT
make_debug_seg(segT cseg,char * name,int sflags)290 make_debug_seg (segT cseg, char *name, int sflags)
291 {
292   segT save_seg = now_seg;
293   int save_subseg = now_subseg;
294   segT r;
295   flagword flags;
296 
297   r = subseg_new (name, 0);
298 
299   /* Check if code segment is marked as linked once.  */
300   if (!cseg)
301     flags = 0;
302   else
303     flags = (bfd_section_flags (cseg)
304                & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
305                     | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
306                     | SEC_LINK_DUPLICATES_SAME_CONTENTS));
307 
308   /* Add standard section flags.  */
309   flags |= sflags;
310 
311   /* Apply possibly linked once flags to new generated segment, too.  */
312   if (!bfd_set_section_flags (r, flags))
313     as_bad (_("bfd_set_section_flags: %s"),
314               bfd_errmsg (bfd_get_error ()));
315 
316   /* Restore to previous segment.  */
317   if (save_seg != NULL)
318     subseg_set (save_seg, save_subseg);
319   return r;
320 }
321 
322 static struct dwcfi_seg_list *
dwcfi_hash_find(char * name)323 dwcfi_hash_find (char *name)
324 {
325   return (struct dwcfi_seg_list *) str_hash_find (dwcfi_hash, name);
326 }
327 
328 static struct dwcfi_seg_list *
dwcfi_hash_find_or_make(segT cseg,const char * base_name,int flags)329 dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags)
330 {
331   struct dwcfi_seg_list *item;
332   char *name;
333 
334   /* Initialize dwcfi_hash once.  */
335   if (!dwcfi_hash)
336     dwcfi_hash = str_htab_create ();
337 
338   name = get_debugseg_name (cseg, base_name);
339 
340   item = dwcfi_hash_find (name);
341   if (!item)
342     {
343       item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name);
344 
345       str_hash_insert (dwcfi_hash, item->seg_name, item, 0);
346     }
347   else
348     notes_free (name);
349 
350   return item;
351 }
352 
353 /* ??? Share this with dwarf2cfg.c.  */
354 #ifndef TC_DWARF2_EMIT_OFFSET
355 #define TC_DWARF2_EMIT_OFFSET  generic_dwarf2_emit_offset
356 
357 /* Create an offset to .dwarf2_*.  */
358 
359 static void
generic_dwarf2_emit_offset(symbolS * symbol,unsigned int size)360 generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
361 {
362   expressionS exp;
363 
364   exp.X_op = O_symbol;
365   exp.X_add_symbol = symbol;
366   exp.X_add_number = 0;
367   emit_expr (&exp, size);
368 }
369 #endif
370 
371 struct cfi_escape_data
372 {
373   struct cfi_escape_data *next;
374   expressionS exp;
375 };
376 
377 struct cie_entry
378 {
379   struct cie_entry *next;
380 #if MULTIPLE_FRAME_SECTIONS
381   segT cur_seg;
382 #endif
383   symbolS *start_address;
384   unsigned int return_column;
385   unsigned int signal_frame;
386   unsigned char fde_encoding;
387   unsigned char per_encoding;
388   unsigned char lsda_encoding;
389   expressionS personality;
390 #ifdef tc_cie_entry_extras
391   tc_cie_entry_extras
392 #endif
393   struct cfi_insn_data *first, *last;
394 };
395 
396 /* List of FDE entries.  */
397 
398 struct fde_entry *all_fde_data;
399 static struct fde_entry **last_fde_data = &all_fde_data;
400 
401 /* List of CIEs so that they could be reused.  */
402 static struct cie_entry *cie_root;
403 
404 /* Construct a new FDE structure and add it to the end of the fde list.  */
405 
406 static struct fde_entry *
alloc_fde_entry(void)407 alloc_fde_entry (void)
408 {
409   struct fde_entry *fde = XCNEW (struct fde_entry);
410 
411   frchain_now->frch_cfi_data = XCNEW (struct frch_cfi_data);
412   frchain_now->frch_cfi_data->cur_fde_data = fde;
413   *last_fde_data = fde;
414   last_fde_data = &fde->next;
415   SET_CUR_SEG (fde, is_now_linkonce_segment ());
416   SET_HANDLED (fde, 0);
417   fde->last = &fde->data;
418   fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
419   fde->per_encoding = DW_EH_PE_omit;
420   fde->lsda_encoding = DW_EH_PE_omit;
421   fde->eh_header_type = EH_COMPACT_UNKNOWN;
422 #ifdef tc_fde_entry_init_extra
423   tc_fde_entry_init_extra (fde)
424 #endif
425 
426   return fde;
427 }
428 
429 /* The following functions are available for a backend to construct its
430    own unwind information, usually from legacy unwind directives.  */
431 
432 /* Construct a new INSN structure and add it to the end of the insn list
433    for the currently active FDE.  */
434 
435 static bool cfi_sections_set = false;
436 static int cfi_sections = CFI_EMIT_eh_frame;
437 int all_cfi_sections = 0;
438 static struct fde_entry *last_fde;
439 
440 static struct cfi_insn_data *
alloc_cfi_insn_data(void)441 alloc_cfi_insn_data (void)
442 {
443   struct cfi_insn_data *insn = XCNEW (struct cfi_insn_data);
444   struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
445 
446   *cur_fde_data->last = insn;
447   cur_fde_data->last = &insn->next;
448   SET_CUR_SEG (insn, is_now_linkonce_segment ());
449   return insn;
450 }
451 
452 /* Construct a new FDE structure that begins at LABEL.  */
453 
454 void
cfi_new_fde(symbolS * label)455 cfi_new_fde (symbolS *label)
456 {
457   struct fde_entry *fde = alloc_fde_entry ();
458   fde->start_address = label;
459   frchain_now->frch_cfi_data->last_address = label;
460 }
461 
462 /* End the currently open FDE.  */
463 
464 void
cfi_end_fde(symbolS * label)465 cfi_end_fde (symbolS *label)
466 {
467   frchain_now->frch_cfi_data->cur_fde_data->end_address = label;
468   free (frchain_now->frch_cfi_data);
469   frchain_now->frch_cfi_data = NULL;
470 }
471 
472 /* Set the last FDE  .*/
473 void
cfi_set_last_fde(struct fde_entry * fde)474 cfi_set_last_fde (struct fde_entry *fde)
475 {
476   last_fde = fde;
477 }
478 
479 /* Set the return column for the current FDE.  */
480 
481 void
cfi_set_return_column(unsigned regno)482 cfi_set_return_column (unsigned regno)
483 {
484   frchain_now->frch_cfi_data->cur_fde_data->return_column = regno;
485 }
486 
487 void
cfi_set_sections(void)488 cfi_set_sections (void)
489 {
490   all_cfi_sections |= cfi_sections;
491   frchain_now->frch_cfi_data->cur_fde_data->sections = all_cfi_sections;
492   cfi_sections_set = true;
493 }
494 
495 /* Universal functions to store new instructions.  */
496 
497 static void
cfi_add_CFA_insn(int insn)498 cfi_add_CFA_insn (int insn)
499 {
500   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
501 
502   insn_ptr->insn = insn;
503 }
504 
505 static void
cfi_add_CFA_insn_reg(int insn,unsigned regno)506 cfi_add_CFA_insn_reg (int insn, unsigned regno)
507 {
508   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
509 
510   insn_ptr->insn = insn;
511   insn_ptr->u.r = regno;
512 }
513 
514 static void
cfi_add_CFA_insn_offset(int insn,offsetT offset)515 cfi_add_CFA_insn_offset (int insn, offsetT offset)
516 {
517   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
518 
519   insn_ptr->insn = insn;
520   insn_ptr->u.i = offset;
521 }
522 
523 static void
cfi_add_CFA_insn_reg_reg(int insn,unsigned reg1,unsigned reg2)524 cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
525 {
526   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
527 
528   insn_ptr->insn = insn;
529   insn_ptr->u.rr.reg1 = reg1;
530   insn_ptr->u.rr.reg2 = reg2;
531 }
532 
533 static void
cfi_add_CFA_insn_reg_offset(int insn,unsigned regno,offsetT offset)534 cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
535 {
536   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
537 
538   insn_ptr->insn = insn;
539   insn_ptr->u.ri.reg = regno;
540   insn_ptr->u.ri.offset = offset;
541 }
542 
543 /* Add a CFI insn to advance the PC from the last address to LABEL.  */
544 
545 void
cfi_add_advance_loc(symbolS * label)546 cfi_add_advance_loc (symbolS *label)
547 {
548   struct cfi_insn_data *insn = alloc_cfi_insn_data ();
549 
550   insn->insn = DW_CFA_advance_loc;
551   insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address;
552   insn->u.ll.lab2 = label;
553 
554   frchain_now->frch_cfi_data->last_address = label;
555 }
556 
557 /* Add a CFI insn to label the current position in the CFI segment.  */
558 
559 void
cfi_add_label(const char * name)560 cfi_add_label (const char *name)
561 {
562   unsigned int len = strlen (name) + 1;
563   struct cfi_insn_data *insn = alloc_cfi_insn_data ();
564 
565   insn->insn = CFI_label;
566   obstack_grow (&notes, name, len);
567   insn->u.sym_name = (char *) obstack_finish (&notes);
568 }
569 
570 /* Add a DW_CFA_offset record to the CFI data.  */
571 
572 void
cfi_add_CFA_offset(unsigned regno,offsetT offset)573 cfi_add_CFA_offset (unsigned regno, offsetT offset)
574 {
575   unsigned int abs_data_align;
576 
577   gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
578   cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
579 
580   abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
581                         ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
582   if (offset % abs_data_align)
583     as_bad (_("register save offset not a multiple of %u"), abs_data_align);
584 }
585 
586 /* Add a DW_CFA_val_offset record to the CFI data.  */
587 
588 void
cfi_add_CFA_val_offset(unsigned regno,offsetT offset)589 cfi_add_CFA_val_offset (unsigned regno, offsetT offset)
590 {
591   unsigned int abs_data_align;
592 
593   gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
594   cfi_add_CFA_insn_reg_offset (DW_CFA_val_offset, regno, offset);
595 
596   abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
597                         ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
598   if (offset % abs_data_align)
599     as_bad (_("register save offset not a multiple of %u"), abs_data_align);
600 }
601 
602 /* Add a DW_CFA_def_cfa record to the CFI data.  */
603 
604 void
cfi_add_CFA_def_cfa(unsigned regno,offsetT offset)605 cfi_add_CFA_def_cfa (unsigned regno, offsetT offset)
606 {
607   cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
608   frchain_now->frch_cfi_data->cur_cfa_offset = offset;
609 }
610 
611 /* Add a DW_CFA_register record to the CFI data.  */
612 
613 void
cfi_add_CFA_register(unsigned reg1,unsigned reg2)614 cfi_add_CFA_register (unsigned reg1, unsigned reg2)
615 {
616   cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
617 }
618 
619 /* Add a DW_CFA_def_cfa_register record to the CFI data.  */
620 
621 void
cfi_add_CFA_def_cfa_register(unsigned regno)622 cfi_add_CFA_def_cfa_register (unsigned regno)
623 {
624   cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
625 }
626 
627 /* Add a DW_CFA_def_cfa_offset record to the CFI data.  */
628 
629 void
cfi_add_CFA_def_cfa_offset(offsetT offset)630 cfi_add_CFA_def_cfa_offset (offsetT offset)
631 {
632   cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
633   frchain_now->frch_cfi_data->cur_cfa_offset = offset;
634 }
635 
636 void
cfi_add_CFA_restore(unsigned regno)637 cfi_add_CFA_restore (unsigned regno)
638 {
639   cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
640 }
641 
642 void
cfi_add_CFA_undefined(unsigned regno)643 cfi_add_CFA_undefined (unsigned regno)
644 {
645   cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
646 }
647 
648 void
cfi_add_CFA_same_value(unsigned regno)649 cfi_add_CFA_same_value (unsigned regno)
650 {
651   cfi_add_CFA_insn_reg (DW_CFA_same_value, regno);
652 }
653 
654 void
cfi_add_CFA_remember_state(void)655 cfi_add_CFA_remember_state (void)
656 {
657   struct cfa_save_data *p;
658 
659   cfi_add_CFA_insn (DW_CFA_remember_state);
660 
661   p = XNEW (struct cfa_save_data);
662   p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
663   p->next = frchain_now->frch_cfi_data->cfa_save_stack;
664   frchain_now->frch_cfi_data->cfa_save_stack = p;
665 }
666 
667 void
cfi_add_CFA_restore_state(void)668 cfi_add_CFA_restore_state (void)
669 {
670   struct cfa_save_data *p;
671 
672   cfi_add_CFA_insn (DW_CFA_restore_state);
673 
674   p = frchain_now->frch_cfi_data->cfa_save_stack;
675   if (p)
676     {
677       frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset;
678       frchain_now->frch_cfi_data->cfa_save_stack = p->next;
679       free (p);
680     }
681   else
682     as_bad (_("CFI state restore without previous remember"));
683 }
684 
685 
686 /* Parse CFI assembler directives.  */
687 
688 static void dot_cfi (int);
689 static void dot_cfi_escape (int);
690 static void dot_cfi_startproc (int);
691 static void dot_cfi_endproc (int);
692 static void dot_cfi_fde_data (int);
693 static void dot_cfi_personality (int);
694 static void dot_cfi_personality_id (int);
695 static void dot_cfi_lsda (int);
696 static void dot_cfi_val_encoded_addr (int);
697 static void dot_cfi_inline_lsda (int);
698 static void dot_cfi_label (int);
699 
700 const pseudo_typeS cfi_pseudo_table[] =
701   {
702     { "cfi_sections", dot_cfi_sections, 0 },
703     { "cfi_startproc", dot_cfi_startproc, 0 },
704     { "cfi_endproc", dot_cfi_endproc, 0 },
705     { "cfi_fde_data", dot_cfi_fde_data, 0 },
706     { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
707     { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
708     { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset },
709     { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
710     { "cfi_offset", dot_cfi, DW_CFA_offset },
711     { "cfi_rel_offset", dot_cfi, CFI_rel_offset },
712     { "cfi_register", dot_cfi, DW_CFA_register },
713     { "cfi_return_column", dot_cfi, CFI_return_column },
714     { "cfi_restore", dot_cfi, DW_CFA_restore },
715     { "cfi_undefined", dot_cfi, DW_CFA_undefined },
716     { "cfi_same_value", dot_cfi, DW_CFA_same_value },
717     { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
718     { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
719     { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
720     { "cfi_negate_ra_state", dot_cfi, DW_CFA_AARCH64_negate_ra_state },
721     { "cfi_escape", dot_cfi_escape, 0 },
722     { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
723     { "cfi_personality", dot_cfi_personality, 0 },
724     { "cfi_personality_id", dot_cfi_personality_id, 0 },
725     { "cfi_lsda", dot_cfi_lsda, 0 },
726     { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
727     { "cfi_inline_lsda", dot_cfi_inline_lsda, 0 },
728     { "cfi_label", dot_cfi_label, 0 },
729     { "cfi_val_offset", dot_cfi, DW_CFA_val_offset },
730     { NULL, NULL, 0 }
731   };
732 
733 static void
cfi_parse_separator(void)734 cfi_parse_separator (void)
735 {
736   SKIP_WHITESPACE ();
737   if (*input_line_pointer == ',')
738     input_line_pointer++;
739   else
740     as_bad (_("missing separator"));
741 }
742 
743 #ifndef tc_parse_to_dw2regnum
744 static void
tc_parse_to_dw2regnum(expressionS * exp)745 tc_parse_to_dw2regnum (expressionS *exp)
746 {
747 # ifdef tc_regname_to_dw2regnum
748   SKIP_WHITESPACE ();
749   if (is_name_beginner (*input_line_pointer)
750       || (*input_line_pointer == '%'
751             && is_name_beginner (*++input_line_pointer)))
752     {
753       char *name, c;
754 
755       c = get_symbol_name (& name);
756 
757       exp->X_op = O_constant;
758       exp->X_add_number = tc_regname_to_dw2regnum (name);
759 
760       restore_line_pointer (c);
761     }
762   else
763 # endif
764     expression_and_evaluate (exp);
765 }
766 #endif
767 
768 static unsigned
cfi_parse_reg(void)769 cfi_parse_reg (void)
770 {
771   int regno;
772   expressionS exp;
773 
774   tc_parse_to_dw2regnum (&exp);
775   switch (exp.X_op)
776     {
777     case O_register:
778     case O_constant:
779       regno = exp.X_add_number;
780       break;
781 
782     default:
783       regno = -1;
784       break;
785     }
786 
787   if (regno < 0)
788     {
789       as_bad (_("bad register expression"));
790       regno = 0;
791     }
792 
793   return regno;
794 }
795 
796 static offsetT
cfi_parse_const(void)797 cfi_parse_const (void)
798 {
799   return get_absolute_expression ();
800 }
801 
802 static void
dot_cfi(int arg)803 dot_cfi (int arg)
804 {
805   offsetT offset;
806   unsigned reg1, reg2;
807 
808   if (frchain_now->frch_cfi_data == NULL)
809     {
810       as_bad (_("CFI instruction used without previous .cfi_startproc"));
811       ignore_rest_of_line ();
812       return;
813     }
814 
815   /* If the last address was not at the current PC, advance to current.  */
816   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
817       || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
818             != frag_now_fix ()))
819     cfi_add_advance_loc (symbol_temp_new_now ());
820 
821   switch (arg)
822     {
823     case DW_CFA_offset:
824       reg1 = cfi_parse_reg ();
825       cfi_parse_separator ();
826       offset = cfi_parse_const ();
827       cfi_add_CFA_offset (reg1, offset);
828       break;
829 
830     case DW_CFA_val_offset:
831       reg1 = cfi_parse_reg ();
832       cfi_parse_separator ();
833       offset = cfi_parse_const ();
834       cfi_add_CFA_val_offset (reg1, offset);
835       break;
836 
837     case CFI_rel_offset:
838       reg1 = cfi_parse_reg ();
839       cfi_parse_separator ();
840       offset = cfi_parse_const ();
841       cfi_add_CFA_offset (reg1,
842                                 offset - frchain_now->frch_cfi_data->cur_cfa_offset);
843       break;
844 
845     case DW_CFA_def_cfa:
846       reg1 = cfi_parse_reg ();
847       cfi_parse_separator ();
848       offset = cfi_parse_const ();
849       cfi_add_CFA_def_cfa (reg1, offset);
850       break;
851 
852     case DW_CFA_register:
853       reg1 = cfi_parse_reg ();
854       cfi_parse_separator ();
855       reg2 = cfi_parse_reg ();
856       cfi_add_CFA_register (reg1, reg2);
857       break;
858 
859     case DW_CFA_def_cfa_register:
860       reg1 = cfi_parse_reg ();
861       cfi_add_CFA_def_cfa_register (reg1);
862       break;
863 
864     case DW_CFA_def_cfa_offset:
865       offset = cfi_parse_const ();
866       cfi_add_CFA_def_cfa_offset (offset);
867       break;
868 
869     case CFI_adjust_cfa_offset:
870       offset = cfi_parse_const ();
871       cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
872                                           + offset);
873       break;
874 
875     case DW_CFA_restore:
876       for (;;)
877           {
878             reg1 = cfi_parse_reg ();
879             cfi_add_CFA_restore (reg1);
880             SKIP_WHITESPACE ();
881             if (*input_line_pointer != ',')
882               break;
883             ++input_line_pointer;
884           }
885       break;
886 
887     case DW_CFA_undefined:
888       for (;;)
889           {
890             reg1 = cfi_parse_reg ();
891             cfi_add_CFA_undefined (reg1);
892             SKIP_WHITESPACE ();
893             if (*input_line_pointer != ',')
894               break;
895             ++input_line_pointer;
896           }
897       break;
898 
899     case DW_CFA_same_value:
900       reg1 = cfi_parse_reg ();
901       cfi_add_CFA_same_value (reg1);
902       break;
903 
904     case CFI_return_column:
905       reg1 = cfi_parse_reg ();
906       cfi_set_return_column (reg1);
907       break;
908 
909     case DW_CFA_remember_state:
910       cfi_add_CFA_remember_state ();
911       break;
912 
913     case DW_CFA_restore_state:
914       cfi_add_CFA_restore_state ();
915       break;
916 
917     case DW_CFA_GNU_window_save:
918       cfi_add_CFA_insn (DW_CFA_GNU_window_save);
919       break;
920 
921     case CFI_signal_frame:
922       frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
923       break;
924 
925     default:
926       abort ();
927     }
928 
929   demand_empty_rest_of_line ();
930 }
931 
932 static void
dot_cfi_escape(int ignored ATTRIBUTE_UNUSED)933 dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
934 {
935   struct cfi_escape_data *head, **tail, *e;
936   struct cfi_insn_data *insn;
937 
938   if (frchain_now->frch_cfi_data == NULL)
939     {
940       as_bad (_("CFI instruction used without previous .cfi_startproc"));
941       ignore_rest_of_line ();
942       return;
943     }
944 
945   /* If the last address was not at the current PC, advance to current.  */
946   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
947       || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
948             != frag_now_fix ()))
949     cfi_add_advance_loc (symbol_temp_new_now ());
950 
951   tail = &head;
952   do
953     {
954       e = XNEW (struct cfi_escape_data);
955       do_parse_cons_expression (&e->exp, 1);
956       *tail = e;
957       tail = &e->next;
958     }
959   while (*input_line_pointer++ == ',');
960   *tail = NULL;
961 
962   insn = alloc_cfi_insn_data ();
963   insn->insn = CFI_escape;
964   insn->u.esc = head;
965 
966   --input_line_pointer;
967   demand_empty_rest_of_line ();
968 }
969 
970 static void
dot_cfi_personality(int ignored ATTRIBUTE_UNUSED)971 dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
972 {
973   struct fde_entry *fde;
974   offsetT encoding;
975 
976   if (frchain_now->frch_cfi_data == NULL)
977     {
978       as_bad (_("CFI instruction used without previous .cfi_startproc"));
979       ignore_rest_of_line ();
980       return;
981     }
982 
983   fde = frchain_now->frch_cfi_data->cur_fde_data;
984   encoding = cfi_parse_const ();
985   if (encoding == DW_EH_PE_omit)
986     {
987       demand_empty_rest_of_line ();
988       fde->per_encoding = encoding;
989       return;
990     }
991 
992   if ((encoding & 0xff) != encoding
993       || ((((encoding & 0x70) != 0
994 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
995               && (encoding & 0x70) != DW_EH_PE_pcrel
996 #endif
997               )
998              /* leb128 can be handled, but does something actually need it?  */
999              || (encoding & 7) == DW_EH_PE_uleb128
1000              || (encoding & 7) > DW_EH_PE_udata8)
1001             && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1002     {
1003       as_bad (_("invalid or unsupported encoding in .cfi_personality"));
1004       ignore_rest_of_line ();
1005       return;
1006     }
1007 
1008   if (*input_line_pointer++ != ',')
1009     {
1010       as_bad (_(".cfi_personality requires encoding and symbol arguments"));
1011       ignore_rest_of_line ();
1012       return;
1013     }
1014 
1015   expression_and_evaluate (&fde->personality);
1016   switch (fde->personality.X_op)
1017     {
1018     case O_symbol:
1019       break;
1020     case O_constant:
1021       if ((encoding & 0x70) == DW_EH_PE_pcrel)
1022           encoding = DW_EH_PE_omit;
1023       break;
1024     default:
1025       encoding = DW_EH_PE_omit;
1026       break;
1027     }
1028 
1029   fde->per_encoding = encoding;
1030 
1031   if (encoding == DW_EH_PE_omit)
1032     {
1033       as_bad (_("wrong second argument to .cfi_personality"));
1034       ignore_rest_of_line ();
1035       return;
1036     }
1037 
1038   demand_empty_rest_of_line ();
1039 }
1040 
1041 static void
dot_cfi_lsda(int ignored ATTRIBUTE_UNUSED)1042 dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
1043 {
1044   struct fde_entry *fde;
1045   offsetT encoding;
1046 
1047   if (frchain_now->frch_cfi_data == NULL)
1048     {
1049       as_bad (_("CFI instruction used without previous .cfi_startproc"));
1050       ignore_rest_of_line ();
1051       return;
1052     }
1053 
1054   fde = frchain_now->frch_cfi_data->cur_fde_data;
1055   encoding = cfi_parse_const ();
1056   if (encoding == DW_EH_PE_omit)
1057     {
1058       demand_empty_rest_of_line ();
1059       fde->lsda_encoding = encoding;
1060       return;
1061     }
1062 
1063   if ((encoding & 0xff) != encoding
1064       || ((((encoding & 0x70) != 0
1065 #if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
1066               && (encoding & 0x70) != DW_EH_PE_pcrel
1067 #endif
1068               )
1069              /* leb128 can be handled, but does something actually need it?  */
1070              || (encoding & 7) == DW_EH_PE_uleb128
1071              || (encoding & 7) > DW_EH_PE_udata8)
1072             && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1073     {
1074       as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1075       ignore_rest_of_line ();
1076       return;
1077     }
1078 
1079   if (*input_line_pointer++ != ',')
1080     {
1081       as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
1082       ignore_rest_of_line ();
1083       return;
1084     }
1085 
1086   fde->lsda_encoding = encoding;
1087 
1088   expression_and_evaluate (&fde->lsda);
1089   switch (fde->lsda.X_op)
1090     {
1091     case O_symbol:
1092       break;
1093     case O_constant:
1094       if ((encoding & 0x70) == DW_EH_PE_pcrel)
1095           encoding = DW_EH_PE_omit;
1096       break;
1097     default:
1098       encoding = DW_EH_PE_omit;
1099       break;
1100     }
1101 
1102   fde->lsda_encoding = encoding;
1103 
1104   if (encoding == DW_EH_PE_omit)
1105     {
1106       as_bad (_("wrong second argument to .cfi_lsda"));
1107       ignore_rest_of_line ();
1108       return;
1109     }
1110 
1111   demand_empty_rest_of_line ();
1112 }
1113 
1114 static void
dot_cfi_val_encoded_addr(int ignored ATTRIBUTE_UNUSED)1115 dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
1116 {
1117   struct cfi_insn_data *insn_ptr;
1118   offsetT encoding;
1119 
1120   if (frchain_now->frch_cfi_data == NULL)
1121     {
1122       as_bad (_("CFI instruction used without previous .cfi_startproc"));
1123       ignore_rest_of_line ();
1124       return;
1125     }
1126 
1127   /* If the last address was not at the current PC, advance to current.  */
1128   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1129       || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1130             != frag_now_fix ()))
1131     cfi_add_advance_loc (symbol_temp_new_now ());
1132 
1133   insn_ptr = alloc_cfi_insn_data ();
1134   insn_ptr->insn = CFI_val_encoded_addr;
1135 
1136   insn_ptr->u.ea.reg = cfi_parse_reg ();
1137 
1138   cfi_parse_separator ();
1139   encoding = cfi_parse_const ();
1140   if ((encoding & 0xff) != encoding
1141       || ((encoding & 0x70) != 0
1142 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1143             && (encoding & 0x70) != DW_EH_PE_pcrel
1144 #endif
1145             )
1146       /* leb128 can be handled, but does something actually need it?  */
1147       || (encoding & 7) == DW_EH_PE_uleb128
1148       || (encoding & 7) > DW_EH_PE_udata8)
1149     {
1150       as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1151       encoding = DW_EH_PE_omit;
1152     }
1153 
1154   cfi_parse_separator ();
1155   expression_and_evaluate (&insn_ptr->u.ea.exp);
1156   switch (insn_ptr->u.ea.exp.X_op)
1157     {
1158     case O_symbol:
1159       break;
1160     case O_constant:
1161       if ((encoding & 0x70) != DW_EH_PE_pcrel)
1162           break;
1163       /* Fall through.  */
1164     default:
1165       encoding = DW_EH_PE_omit;
1166       break;
1167     }
1168 
1169   insn_ptr->u.ea.encoding = encoding;
1170   if (encoding == DW_EH_PE_omit)
1171     {
1172       as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1173       ignore_rest_of_line ();
1174       return;
1175     }
1176 
1177   demand_empty_rest_of_line ();
1178 }
1179 
1180 static void
dot_cfi_label(int ignored ATTRIBUTE_UNUSED)1181 dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
1182 {
1183   char *name;
1184 
1185   if (frchain_now->frch_cfi_data == NULL)
1186     {
1187       as_bad (_("CFI instruction used without previous .cfi_startproc"));
1188       ignore_rest_of_line ();
1189       return;
1190     }
1191 
1192   name = read_symbol_name ();
1193   if (name == NULL)
1194     return;
1195 
1196   /* If the last address was not at the current PC, advance to current.  */
1197   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1198       || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1199             != frag_now_fix ()))
1200     cfi_add_advance_loc (symbol_temp_new_now ());
1201 
1202   cfi_add_label (name);
1203   free (name);
1204 
1205   demand_empty_rest_of_line ();
1206 }
1207 
1208 void
dot_cfi_sections(int ignored ATTRIBUTE_UNUSED)1209 dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1210 {
1211   int sections = 0;
1212 
1213   SKIP_WHITESPACE ();
1214   if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1215     while (1)
1216       {
1217           char * saved_ilp;
1218           char *name, c;
1219 
1220           saved_ilp = input_line_pointer;
1221           c = get_symbol_name (& name);
1222 
1223           if (startswith (name, ".eh_frame")
1224               && name[9] != '_')
1225             sections |= CFI_EMIT_eh_frame;
1226           else if (startswith (name, ".debug_frame"))
1227             sections |= CFI_EMIT_debug_frame;
1228 #if SUPPORT_COMPACT_EH
1229           else if (startswith (name, ".eh_frame_entry"))
1230             {
1231               compact_eh = true;
1232               sections |= CFI_EMIT_eh_frame_compact;
1233             }
1234 #endif
1235 #ifdef tc_cfi_section_name
1236           else if (strcmp (name, tc_cfi_section_name) == 0)
1237             sections |= CFI_EMIT_target;
1238 #endif
1239           else if (startswith (name, ".sframe"))
1240               sections |= CFI_EMIT_sframe;
1241           else
1242             {
1243               *input_line_pointer = c;
1244               input_line_pointer = saved_ilp;
1245               break;
1246             }
1247 
1248           *input_line_pointer = c;
1249           SKIP_WHITESPACE_AFTER_NAME ();
1250           if (*input_line_pointer == ',')
1251             {
1252               name = input_line_pointer++;
1253               SKIP_WHITESPACE ();
1254               if (!is_name_beginner (*input_line_pointer)
1255                     && *input_line_pointer != '"')
1256                 {
1257                     input_line_pointer = name;
1258                     break;
1259                 }
1260             }
1261           else if (is_name_beginner (*input_line_pointer)
1262                      || *input_line_pointer == '"')
1263             break;
1264       }
1265 
1266   demand_empty_rest_of_line ();
1267   if (cfi_sections_set
1268       && (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1269       && ((cfi_sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1270             != (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))))
1271     as_bad (_("inconsistent uses of .cfi_sections"));
1272   cfi_sections = sections;
1273 }
1274 
1275 static void
dot_cfi_startproc(int ignored ATTRIBUTE_UNUSED)1276 dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
1277 {
1278   int simple = 0;
1279 
1280   if (frchain_now->frch_cfi_data != NULL)
1281     {
1282       as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
1283       ignore_rest_of_line ();
1284       return;
1285     }
1286 
1287   cfi_new_fde (symbol_temp_new_now ());
1288 
1289   SKIP_WHITESPACE ();
1290   if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1291     {
1292       char * saved_ilp = input_line_pointer;
1293       char *name, c;
1294 
1295       c = get_symbol_name (& name);
1296 
1297       if (strcmp (name, "simple") == 0)
1298           {
1299             simple = 1;
1300             restore_line_pointer (c);
1301           }
1302       else
1303           input_line_pointer = saved_ilp;
1304     }
1305   demand_empty_rest_of_line ();
1306 
1307   cfi_set_sections ();
1308 
1309   frchain_now->frch_cfi_data->cur_cfa_offset = 0;
1310   if (!simple)
1311     tc_cfi_frame_initial_instructions ();
1312 
1313   if ((all_cfi_sections & CFI_EMIT_target) != 0)
1314     tc_cfi_startproc ();
1315 }
1316 
1317 static void
dot_cfi_endproc(int ignored ATTRIBUTE_UNUSED)1318 dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1319 {
1320   if (frchain_now->frch_cfi_data == NULL)
1321     {
1322       as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
1323       ignore_rest_of_line ();
1324       return;
1325     }
1326 
1327   cfi_set_last_fde (frchain_now->frch_cfi_data->cur_fde_data);
1328 
1329   cfi_end_fde (symbol_temp_new_now ());
1330 
1331   demand_empty_rest_of_line ();
1332 
1333   if ((all_cfi_sections & CFI_EMIT_target) != 0)
1334     tc_cfi_endproc (last_fde);
1335 }
1336 
1337 static segT
get_cfi_seg(segT cseg,const char * base,flagword flags,int align)1338 get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
1339 {
1340   /* Exclude .debug_frame sections for Compact EH.  */
1341   if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh)
1342       || ((flags & SEC_DEBUGGING) == 0 && TARGET_MULTIPLE_EH_FRAME_SECTIONS))
1343     {
1344       segT iseg = cseg;
1345       struct dwcfi_seg_list *l;
1346 
1347       l = dwcfi_hash_find_or_make (cseg, base, flags);
1348 
1349       cseg = l->seg;
1350       subseg_set (cseg, l->subseg);
1351 
1352       if (TARGET_MULTIPLE_EH_FRAME_SECTIONS
1353             && (flags & DWARF2_EH_FRAME_READ_ONLY))
1354           {
1355             const frchainS *ifrch = seg_info (iseg)->frchainP;
1356             const frchainS *frch = seg_info (cseg)->frchainP;
1357             expressionS exp;
1358 
1359             exp.X_op = O_symbol;
1360             exp.X_add_symbol = (symbolS *) local_symbol_make (cseg->name, cseg, frch->frch_root, 0);
1361             exp.X_add_number = 0;
1362             subseg_set (iseg, ifrch->frch_subseg);
1363             fix_new_exp (ifrch->frch_root, 0, 0, &exp, 0, BFD_RELOC_NONE);
1364 
1365             /* Restore the original segment info.  */
1366             subseg_set (cseg, l->subseg);
1367           }
1368     }
1369   else
1370     {
1371       cseg = subseg_new (base, 0);
1372       bfd_set_section_flags (cseg, flags);
1373     }
1374   record_alignment (cseg, align);
1375   return cseg;
1376 }
1377 
1378 #if SUPPORT_COMPACT_EH
1379 static void
dot_cfi_personality_id(int ignored ATTRIBUTE_UNUSED)1380 dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1381 {
1382   struct fde_entry *fde;
1383 
1384   if (frchain_now->frch_cfi_data == NULL)
1385     {
1386       as_bad (_("CFI instruction used without previous .cfi_startproc"));
1387       ignore_rest_of_line ();
1388       return;
1389     }
1390 
1391   fde = frchain_now->frch_cfi_data->cur_fde_data;
1392   fde->personality_id = cfi_parse_const ();
1393   demand_empty_rest_of_line ();
1394 
1395   if (fde->personality_id == 0 || fde->personality_id > 3)
1396     {
1397       as_bad (_("wrong argument to .cfi_personality_id"));
1398       return;
1399     }
1400 }
1401 
1402 static void
dot_cfi_fde_data(int ignored ATTRIBUTE_UNUSED)1403 dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
1404 {
1405   if (frchain_now->frch_cfi_data == NULL)
1406     {
1407       as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
1408       ignore_rest_of_line ();
1409       return;
1410     }
1411 
1412   cfi_set_last_fde (frchain_now->frch_cfi_data->cur_fde_data);
1413 
1414   if ((all_cfi_sections & CFI_EMIT_target) != 0
1415       || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
1416     {
1417       struct cfi_escape_data *head, **tail, *e;
1418       int num_ops = 0;
1419 
1420       tail = &head;
1421       if (!is_it_end_of_statement ())
1422           {
1423             num_ops = 0;
1424             do
1425               {
1426                 e = XNEW (struct cfi_escape_data);
1427                 do_parse_cons_expression (&e->exp, 1);
1428                 *tail = e;
1429                 tail = &e->next;
1430                 num_ops++;
1431               }
1432             while (*input_line_pointer++ == ',');
1433             --input_line_pointer;
1434           }
1435       *tail = NULL;
1436 
1437       if (last_fde->lsda_encoding != DW_EH_PE_omit)
1438           last_fde->eh_header_type = EH_COMPACT_HAS_LSDA;
1439       else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit)
1440           last_fde->eh_header_type = EH_COMPACT_INLINE;
1441       else
1442           last_fde->eh_header_type = EH_COMPACT_OUTLINE;
1443 
1444       if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1445           num_ops = 3;
1446 
1447       last_fde->eh_data_size = num_ops;
1448       last_fde->eh_data =  XNEWVEC (bfd_byte, num_ops);
1449       num_ops = 0;
1450       while (head)
1451           {
1452             e = head;
1453             head = e->next;
1454             last_fde->eh_data[num_ops++] = e->exp.X_add_number;
1455             free (e);
1456           }
1457       if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1458           while (num_ops < 3)
1459             last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop;
1460     }
1461 
1462   demand_empty_rest_of_line ();
1463 }
1464 
1465 /* Function to emit the compact unwinding opcodes stored in the
1466    fde's eh_data field.  The end of the opcode data will be
1467    padded to the value in align.  */
1468 
1469 static void
output_compact_unwind_data(struct fde_entry * fde,int align)1470 output_compact_unwind_data (struct fde_entry *fde, int align)
1471 {
1472   int data_size = fde->eh_data_size + 2;
1473   int align_padding;
1474   int amask;
1475   char *p;
1476 
1477   fde->eh_loc = symbol_temp_new_now ();
1478 
1479   p = frag_more (1);
1480   if (fde->personality_id != 0)
1481     *p = fde->personality_id;
1482   else if (fde->per_encoding != DW_EH_PE_omit)
1483     {
1484       *p = 0;
1485       emit_expr_encoded (&fde->personality, fde->per_encoding, false);
1486       data_size += encoding_size (fde->per_encoding);
1487     }
1488   else
1489     *p = 1;
1490 
1491   amask = (1 << align) - 1;
1492   align_padding = ((data_size + amask) & ~amask) - data_size;
1493 
1494   p = frag_more (fde->eh_data_size + 1 + align_padding);
1495   memcpy (p, fde->eh_data, fde->eh_data_size);
1496   p += fde->eh_data_size;
1497 
1498   while (align_padding-- > 0)
1499     *(p++) = tc_compact_eh_opcode_pad;
1500 
1501   *(p++) = tc_compact_eh_opcode_stop;
1502   fde->eh_header_type = EH_COMPACT_OUTLINE_DONE;
1503 }
1504 
1505 /* Handle the .cfi_inline_lsda directive.  */
1506 static void
dot_cfi_inline_lsda(int ignored ATTRIBUTE_UNUSED)1507 dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1508 {
1509   segT ccseg;
1510   int align;
1511   long max_alignment = 28;
1512 
1513   if (!last_fde)
1514     {
1515       as_bad (_("unexpected .cfi_inline_lsda"));
1516       ignore_rest_of_line ();
1517       return;
1518     }
1519 
1520   if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0)
1521     {
1522       as_bad (_(".cfi_inline_lsda not valid for this frame"));
1523       ignore_rest_of_line ();
1524       return;
1525     }
1526 
1527   if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN
1528       && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA)
1529     {
1530       as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda"));
1531       ignore_rest_of_line ();
1532       return;
1533     }
1534 
1535 #ifdef md_flush_pending_output
1536   md_flush_pending_output ();
1537 #endif
1538 
1539   align = get_absolute_expression ();
1540   if (align > max_alignment)
1541     {
1542       align = max_alignment;
1543       as_bad (_("Alignment too large: %d. assumed."), align);
1544     }
1545   else if (align < 0)
1546     {
1547       as_warn (_("Alignment negative: 0 assumed."));
1548       align = 0;
1549     }
1550 
1551   demand_empty_rest_of_line ();
1552   ccseg = CUR_SEG (last_fde);
1553 
1554   /* Open .gnu_extab section.  */
1555   get_cfi_seg (ccseg, ".gnu_extab",
1556                  (SEC_ALLOC | SEC_LOAD | SEC_DATA
1557                     | DWARF2_EH_FRAME_READ_ONLY),
1558                  1);
1559 
1560   frag_align (align, 0, 0);
1561   record_alignment (now_seg, align);
1562   if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA)
1563     output_compact_unwind_data (last_fde, align);
1564 
1565   cfi_set_last_fde (NULL);
1566 
1567   return;
1568 }
1569 #else /* !SUPPORT_COMPACT_EH */
1570 static void
dot_cfi_inline_lsda(int ignored ATTRIBUTE_UNUSED)1571 dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1572 {
1573   as_bad (_(".cfi_inline_lsda is not supported for this target"));
1574   ignore_rest_of_line ();
1575 }
1576 
1577 static void
dot_cfi_fde_data(int ignored ATTRIBUTE_UNUSED)1578 dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
1579 {
1580   as_bad (_(".cfi_fde_data is not supported for this target"));
1581   ignore_rest_of_line ();
1582 }
1583 
1584 static void
dot_cfi_personality_id(int ignored ATTRIBUTE_UNUSED)1585 dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1586 {
1587   as_bad (_(".cfi_personality_id is not supported for this target"));
1588   ignore_rest_of_line ();
1589 }
1590 #endif
1591 
1592 static void
output_cfi_insn(struct cfi_insn_data * insn)1593 output_cfi_insn (struct cfi_insn_data *insn)
1594 {
1595   offsetT offset;
1596   unsigned int regno;
1597 
1598   switch (insn->insn)
1599     {
1600     case DW_CFA_advance_loc:
1601       {
1602           symbolS *from = insn->u.ll.lab1;
1603           symbolS *to = insn->u.ll.lab2;
1604 
1605           if (symbol_get_frag (to) == symbol_get_frag (from))
1606             {
1607               addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1608               addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1609 
1610               if (scaled == 0)
1611                 ;
1612               else if (scaled <= 0x3F)
1613                 out_one (DW_CFA_advance_loc + scaled);
1614               else if (scaled <= 0xFF)
1615                 {
1616                     out_one (DW_CFA_advance_loc1);
1617                     out_one (scaled);
1618                 }
1619               else if (scaled <= 0xFFFF)
1620                 {
1621                     out_one (DW_CFA_advance_loc2);
1622                     out_two (scaled);
1623                 }
1624               else
1625                 {
1626                     out_one (DW_CFA_advance_loc4);
1627                     out_four (scaled);
1628                 }
1629             }
1630           else
1631             {
1632               expressionS exp;
1633 
1634               exp.X_op = O_subtract;
1635               exp.X_add_symbol = to;
1636               exp.X_op_symbol = from;
1637               exp.X_add_number = 0;
1638 
1639               /* The code in ehopt.c expects that one byte of the encoding
1640                  is already allocated to the frag.  This comes from the way
1641                  that it scans the .eh_frame section looking first for the
1642                  .byte DW_CFA_advance_loc4.  Call frag_grow with the sum of
1643                  room needed by frag_more and frag_var to preallocate space
1644                  ensuring that the DW_CFA_advance_loc4 is in the fixed part
1645                  of the rs_cfa frag, so that the relax machinery can remove
1646                  the advance_loc should it advance by zero.  */
1647               frag_grow (5);
1648               *frag_more (1) = DW_CFA_advance_loc4;
1649 
1650               frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1651                           make_expr_symbol (&exp), frag_now_fix () - 1,
1652                           (char *) frag_now);
1653             }
1654       }
1655       break;
1656 
1657     case DW_CFA_def_cfa:
1658       offset = insn->u.ri.offset;
1659       if (offset < 0)
1660           {
1661             out_one (DW_CFA_def_cfa_sf);
1662             out_uleb128 (insn->u.ri.reg);
1663             out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1664           }
1665       else
1666           {
1667             out_one (DW_CFA_def_cfa);
1668             out_uleb128 (insn->u.ri.reg);
1669             out_uleb128 (offset);
1670           }
1671       break;
1672 
1673     case DW_CFA_def_cfa_register:
1674     case DW_CFA_undefined:
1675     case DW_CFA_same_value:
1676       out_one (insn->insn);
1677       out_uleb128 (insn->u.r);
1678       break;
1679 
1680     case DW_CFA_def_cfa_offset:
1681       offset = insn->u.i;
1682       if (offset < 0)
1683           {
1684             out_one (DW_CFA_def_cfa_offset_sf);
1685             out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1686           }
1687       else
1688           {
1689             out_one (DW_CFA_def_cfa_offset);
1690             out_uleb128 (offset);
1691           }
1692       break;
1693 
1694     case DW_CFA_restore:
1695       regno = insn->u.r;
1696       if (regno <= 0x3F)
1697           {
1698             out_one (DW_CFA_restore + regno);
1699           }
1700       else
1701           {
1702             out_one (DW_CFA_restore_extended);
1703             out_uleb128 (regno);
1704           }
1705       break;
1706 
1707     case DW_CFA_offset:
1708       regno = insn->u.ri.reg;
1709       offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1710       if (offset < 0)
1711           {
1712             out_one (DW_CFA_offset_extended_sf);
1713             out_uleb128 (regno);
1714             out_sleb128 (offset);
1715           }
1716       else if (regno <= 0x3F)
1717           {
1718             out_one (DW_CFA_offset + regno);
1719             out_uleb128 (offset);
1720           }
1721       else
1722           {
1723             out_one (DW_CFA_offset_extended);
1724             out_uleb128 (regno);
1725             out_uleb128 (offset);
1726           }
1727       break;
1728 
1729     case DW_CFA_val_offset:
1730       regno = insn->u.ri.reg;
1731       offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1732       if (offset < 0)
1733           {
1734             out_one (DW_CFA_val_offset_sf);
1735             out_uleb128 (regno);
1736             out_sleb128 (offset);
1737           }
1738       else
1739           {
1740             out_one (DW_CFA_val_offset);
1741             out_uleb128 (regno);
1742             out_uleb128 (offset);
1743           }
1744       break;
1745 
1746     case DW_CFA_register:
1747       out_one (DW_CFA_register);
1748       out_uleb128 (insn->u.rr.reg1);
1749       out_uleb128 (insn->u.rr.reg2);
1750       break;
1751 
1752     case DW_CFA_remember_state:
1753     case DW_CFA_restore_state:
1754       out_one (insn->insn);
1755       break;
1756 
1757     case DW_CFA_GNU_window_save:
1758       out_one (DW_CFA_GNU_window_save);
1759       break;
1760 
1761     case CFI_escape:
1762       {
1763           struct cfi_escape_data *e;
1764           for (e = insn->u.esc; e ; e = e->next)
1765             emit_expr (&e->exp, 1);
1766           break;
1767       }
1768 
1769     case CFI_val_encoded_addr:
1770       {
1771           unsigned encoding = insn->u.ea.encoding;
1772           offsetT enc_size;
1773 
1774           if (encoding == DW_EH_PE_omit)
1775             break;
1776           out_one (DW_CFA_val_expression);
1777           out_uleb128 (insn->u.ea.reg);
1778 
1779           switch (encoding & 0x7)
1780             {
1781             case DW_EH_PE_absptr:
1782               enc_size = DWARF2_ADDR_SIZE (stdoutput);
1783               break;
1784             case DW_EH_PE_udata2:
1785               enc_size = 2;
1786               break;
1787             case DW_EH_PE_udata4:
1788               enc_size = 4;
1789               break;
1790             case DW_EH_PE_udata8:
1791               enc_size = 8;
1792               break;
1793             default:
1794               abort ();
1795             }
1796 
1797           /* If the user has requested absolute encoding,
1798              then use the smaller DW_OP_addr encoding.  */
1799           if (insn->u.ea.encoding == DW_EH_PE_absptr)
1800             {
1801               out_uleb128 (1 + enc_size);
1802               out_one (DW_OP_addr);
1803             }
1804           else
1805             {
1806               out_uleb128 (1 + 1 + enc_size);
1807               out_one (DW_OP_GNU_encoded_addr);
1808               out_one (encoding);
1809 
1810               if ((encoding & 0x70) == DW_EH_PE_pcrel)
1811                 {
1812 #if CFI_DIFF_EXPR_OK
1813                     insn->u.ea.exp.X_op = O_subtract;
1814                     insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1815 #elif defined (tc_cfi_emit_pcrel_expr)
1816                     tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size);
1817                     break;
1818 #else
1819                     abort ();
1820 #endif
1821                 }
1822             }
1823           emit_expr (&insn->u.ea.exp, enc_size);
1824       }
1825       break;
1826 
1827     case CFI_label:
1828       colon (insn->u.sym_name);
1829       break;
1830 
1831     default:
1832       abort ();
1833     }
1834 }
1835 
1836 static void
output_cie(struct cie_entry * cie,bool eh_frame,int align)1837 output_cie (struct cie_entry *cie, bool eh_frame, int align)
1838 {
1839   symbolS *after_size_address, *end_address;
1840   expressionS exp;
1841   struct cfi_insn_data *i;
1842   offsetT augmentation_size;
1843   int enc;
1844   enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1845 
1846   cie->start_address = symbol_temp_new_now ();
1847   after_size_address = symbol_temp_make ();
1848   end_address = symbol_temp_make ();
1849 
1850   exp.X_op = O_subtract;
1851   exp.X_add_symbol = end_address;
1852   exp.X_op_symbol = after_size_address;
1853   exp.X_add_number = 0;
1854 
1855   if (eh_frame || fmt == dwarf2_format_32bit)
1856     emit_expr (&exp, 4);                          /* Length.  */
1857   else
1858     {
1859       if (fmt == dwarf2_format_64bit)
1860           out_four (-1);
1861       emit_expr (&exp, 8);                        /* Length.  */
1862     }
1863   symbol_set_value_now (after_size_address);
1864   if (eh_frame)
1865     out_four (0);                                 /* CIE id.  */
1866   else
1867     {
1868       out_four (-1);                                        /* CIE id.  */
1869       if (fmt != dwarf2_format_32bit)
1870           out_four (-1);
1871     }
1872   out_one (flag_dwarf_cie_version);               /* Version.  */
1873   if (eh_frame)
1874     {
1875       out_one ('z');                                        /* Augmentation.  */
1876       if (cie->per_encoding != DW_EH_PE_omit)
1877           out_one ('P');
1878       if (cie->lsda_encoding != DW_EH_PE_omit)
1879           out_one ('L');
1880       out_one ('R');
1881 #ifdef tc_output_cie_extra
1882       tc_output_cie_extra (cie);
1883 #endif
1884     }
1885   if (cie->signal_frame)
1886     out_one ('S');
1887   out_one (0);
1888   if (flag_dwarf_cie_version >= 4)
1889     {
1890       /* For now we are assuming a flat address space with 4 or 8 byte
1891          addresses.  */
1892       int address_size = dwarf2_format_32bit ? 4 : 8;
1893       out_one (address_size);                     /* Address size.  */
1894       out_one (0);                                /* Segment size.  */
1895     }
1896   out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH);      /* Code alignment.  */
1897   out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT);        /* Data alignment.  */
1898   if (flag_dwarf_cie_version == 1)                /* Return column.  */
1899     {
1900       if ((cie->return_column & 0xff) != cie->return_column)
1901           as_bad (_("return column number %d overflows in CIE version 1"),
1902                     cie->return_column);
1903       out_one (cie->return_column);
1904     }
1905   else
1906     out_uleb128 (cie->return_column);
1907   if (eh_frame)
1908     {
1909       augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1910       if (cie->per_encoding != DW_EH_PE_omit)
1911           augmentation_size += 1 + encoding_size (cie->per_encoding);
1912       out_uleb128 (augmentation_size);            /* Augmentation size.  */
1913 
1914       emit_expr_encoded (&cie->personality, cie->per_encoding, true);
1915 
1916       if (cie->lsda_encoding != DW_EH_PE_omit)
1917           out_one (cie->lsda_encoding);
1918     }
1919 
1920   switch (DWARF2_FDE_RELOC_SIZE)
1921     {
1922     case 2:
1923       enc = DW_EH_PE_sdata2;
1924       break;
1925     case 4:
1926       enc = DW_EH_PE_sdata4;
1927       break;
1928     case 8:
1929       enc = DW_EH_PE_sdata8;
1930       break;
1931     default:
1932       abort ();
1933     }
1934 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1935   enc |= DW_EH_PE_pcrel;
1936 #endif
1937 #ifdef DWARF2_FDE_RELOC_ENCODING
1938   /* Allow target to override encoding.  */
1939   enc = DWARF2_FDE_RELOC_ENCODING (enc);
1940 #endif
1941   cie->fde_encoding = enc;
1942   if (eh_frame)
1943     out_one (enc);
1944 
1945   if (cie->first)
1946     {
1947       for (i = cie->first; i != cie->last; i = i->next)
1948           {
1949             if (CUR_SEG (i) != CUR_SEG (cie))
1950               continue;
1951             output_cfi_insn (i);
1952           }
1953     }
1954 
1955   frag_align (align, DW_CFA_nop, 0);
1956   symbol_set_value_now (end_address);
1957 }
1958 
1959 static void
output_fde(struct fde_entry * fde,struct cie_entry * cie,bool eh_frame,struct cfi_insn_data * first,int align)1960 output_fde (struct fde_entry *fde, struct cie_entry *cie,
1961               bool eh_frame, struct cfi_insn_data *first,
1962               int align)
1963 {
1964   symbolS *after_size_address, *end_address;
1965   expressionS exp;
1966   offsetT augmentation_size;
1967   enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1968   unsigned int offset_size;
1969   unsigned int addr_size;
1970 
1971   after_size_address = symbol_temp_make ();
1972   end_address = symbol_temp_make ();
1973 
1974   exp.X_op = O_subtract;
1975   exp.X_add_symbol = end_address;
1976   exp.X_op_symbol = after_size_address;
1977   exp.X_add_number = 0;
1978   if (eh_frame || fmt == dwarf2_format_32bit)
1979     offset_size = 4;
1980   else
1981     {
1982       if (fmt == dwarf2_format_64bit)
1983           out_four (-1);
1984       offset_size = 8;
1985     }
1986   emit_expr (&exp, offset_size);                  /* Length.  */
1987   symbol_set_value_now (after_size_address);
1988 
1989   if (eh_frame)
1990     {
1991       exp.X_op = O_subtract;
1992       exp.X_add_symbol = after_size_address;
1993       exp.X_op_symbol = cie->start_address;
1994       exp.X_add_number = 0;
1995       emit_expr (&exp, offset_size);              /* CIE offset.  */
1996     }
1997   else
1998     {
1999       TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
2000     }
2001 
2002   exp.X_op = O_symbol;
2003   if (eh_frame)
2004     {
2005       bfd_reloc_code_real_type code
2006           = tc_cfi_reloc_for_encoding (cie->fde_encoding);
2007       addr_size = DWARF2_FDE_RELOC_SIZE;
2008       if (code != BFD_RELOC_NONE)
2009           {
2010             reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
2011             char *p = frag_more (addr_size);
2012             gas_assert (addr_size == (unsigned) howto->bitsize / 8);
2013             md_number_to_chars (p, 0, addr_size);
2014             fix_new (frag_now, p - frag_now->fr_literal, addr_size,
2015                        fde->start_address, 0, howto->pc_relative, code);
2016           }
2017       else
2018           {
2019             exp.X_op = O_subtract;
2020             exp.X_add_number = 0;
2021 #if CFI_DIFF_EXPR_OK
2022             exp.X_add_symbol = fde->start_address;
2023             exp.X_op_symbol = symbol_temp_new_now ();
2024             emit_expr (&exp, addr_size);          /* Code offset.  */
2025 #else
2026             exp.X_op = O_symbol;
2027             exp.X_add_symbol = fde->start_address;
2028 
2029 #if defined(tc_cfi_emit_pcrel_expr)
2030             tc_cfi_emit_pcrel_expr (&exp, addr_size);        /* Code offset.  */
2031 #else
2032             emit_expr (&exp, addr_size);          /* Code offset.  */
2033 #endif
2034 #endif
2035           }
2036     }
2037   else
2038     {
2039       exp.X_add_number = 0;
2040       exp.X_add_symbol = fde->start_address;
2041       addr_size = DWARF2_ADDR_SIZE (stdoutput);
2042       emit_expr (&exp, addr_size);
2043     }
2044 
2045   exp.X_op = O_subtract;
2046   exp.X_add_symbol = fde->end_address;
2047   exp.X_op_symbol = fde->start_address;           /* Code length.  */
2048   exp.X_add_number = 0;
2049   emit_expr (&exp, addr_size);
2050 
2051   augmentation_size = encoding_size (fde->lsda_encoding);
2052   if (eh_frame)
2053     out_uleb128 (augmentation_size);              /* Augmentation size.  */
2054 
2055   emit_expr_encoded (&fde->lsda, cie->lsda_encoding, false);
2056 
2057   for (; first; first = first->next)
2058     if (CUR_SEG (first) == CUR_SEG (fde))
2059       output_cfi_insn (first);
2060 
2061   frag_align (align, DW_CFA_nop, 0);
2062   symbol_set_value_now (end_address);
2063 }
2064 
2065 /* Allow these insns to be put in the initial sequence of a CIE.
2066    If J is non-NULL, then compare I and J insns for a match.  */
2067 
2068 static inline bool
initial_cie_insn(const struct cfi_insn_data * i,const struct cfi_insn_data * j)2069 initial_cie_insn (const struct cfi_insn_data *i, const struct cfi_insn_data *j)
2070 {
2071   if (j && i->insn != j->insn)
2072     return false;
2073   switch (i->insn)
2074     {
2075     case DW_CFA_offset:
2076     case DW_CFA_def_cfa:
2077     case DW_CFA_val_offset:
2078       if (j)
2079           {
2080             if (i->u.ri.reg != j->u.ri.reg)
2081               return false;
2082             if (i->u.ri.offset != j->u.ri.offset)
2083               return false;
2084           }
2085       break;
2086 
2087     case DW_CFA_register:
2088       if (j)
2089           {
2090             if (i->u.rr.reg1 != j->u.rr.reg1)
2091               return false;
2092             if (i->u.rr.reg2 != j->u.rr.reg2)
2093               return false;
2094           }
2095       break;
2096 
2097     case DW_CFA_def_cfa_register:
2098     case DW_CFA_restore:
2099     case DW_CFA_undefined:
2100     case DW_CFA_same_value:
2101       if (j)
2102           {
2103             if (i->u.r != j->u.r)
2104               return false;
2105           }
2106       break;
2107 
2108     case DW_CFA_def_cfa_offset:
2109       if (j)
2110           {
2111             if (i->u.i != j->u.i)
2112               return false;
2113           }
2114       break;
2115 
2116     default:
2117       return false;
2118     }
2119   return true;
2120 }
2121 
2122 static struct cie_entry *
select_cie_for_fde(struct fde_entry * fde,bool eh_frame,struct cfi_insn_data ** pfirst,int align)2123 select_cie_for_fde (struct fde_entry *fde, bool eh_frame,
2124                         struct cfi_insn_data **pfirst, int align)
2125 {
2126   struct cfi_insn_data *i, *j;
2127   struct cie_entry *cie;
2128 
2129   for (cie = cie_root; cie; cie = cie->next)
2130     {
2131       if (CUR_SEG (cie) != CUR_SEG (fde))
2132           continue;
2133 #ifdef tc_cie_fde_equivalent_extra
2134       if (!tc_cie_fde_equivalent_extra (cie, fde))
2135           continue;
2136 #endif
2137       if (cie->return_column != fde->return_column
2138             || cie->signal_frame != fde->signal_frame
2139             || cie->per_encoding != fde->per_encoding
2140             || cie->lsda_encoding != fde->lsda_encoding)
2141           continue;
2142       if (cie->per_encoding != DW_EH_PE_omit)
2143           {
2144             if (cie->personality.X_op != fde->personality.X_op
2145                 || (cie->personality.X_add_number
2146                       != fde->personality.X_add_number))
2147               continue;
2148             switch (cie->personality.X_op)
2149               {
2150               case O_constant:
2151                 if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2152                     continue;
2153                 break;
2154               case O_symbol:
2155                 if (cie->personality.X_add_symbol
2156                       != fde->personality.X_add_symbol)
2157                     continue;
2158                 break;
2159               default:
2160                 abort ();
2161               }
2162           }
2163       for (i = cie->first, j = fde->data;
2164              i != cie->last && j != NULL;
2165              i = i->next, j = j->next)
2166           {
2167             if (!initial_cie_insn (i, j))
2168               break;
2169           }
2170 
2171       if (i == cie->last)
2172           {
2173             *pfirst = j;
2174             return cie;
2175           }
2176     }
2177 
2178   cie = XNEW (struct cie_entry);
2179   cie->next = cie_root;
2180   cie_root = cie;
2181   SET_CUR_SEG (cie, CUR_SEG (fde));
2182   cie->return_column = fde->return_column;
2183   cie->signal_frame = fde->signal_frame;
2184   cie->per_encoding = fde->per_encoding;
2185   cie->lsda_encoding = fde->lsda_encoding;
2186   cie->personality = fde->personality;
2187   cie->first = fde->data;
2188 #ifdef tc_cie_entry_init_extra
2189   tc_cie_entry_init_extra (cie, fde)
2190 #endif
2191 
2192   for (i = cie->first; i ; i = i->next)
2193     if (!initial_cie_insn (i, NULL))
2194       break;
2195 
2196   cie->last = i;
2197   *pfirst = i;
2198 
2199   output_cie (cie, eh_frame, align);
2200 
2201   return cie;
2202 }
2203 
2204 #ifdef md_reg_eh_frame_to_debug_frame
2205 static void
cfi_change_reg_numbers(struct cfi_insn_data * insn,segT ccseg)2206 cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
2207 {
2208   for (; insn; insn = insn->next)
2209     {
2210       if (CUR_SEG (insn) != ccseg)
2211           continue;
2212       switch (insn->insn)
2213           {
2214           case DW_CFA_advance_loc:
2215           case DW_CFA_def_cfa_offset:
2216           case DW_CFA_remember_state:
2217           case DW_CFA_restore_state:
2218           case DW_CFA_GNU_window_save:
2219           case CFI_escape:
2220           case CFI_label:
2221             break;
2222 
2223           case DW_CFA_def_cfa:
2224           case DW_CFA_offset:
2225             insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
2226             break;
2227 
2228           case DW_CFA_def_cfa_register:
2229           case DW_CFA_undefined:
2230           case DW_CFA_same_value:
2231           case DW_CFA_restore:
2232             insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
2233             break;
2234 
2235           case DW_CFA_register:
2236             insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
2237             insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
2238             break;
2239 
2240           case CFI_val_encoded_addr:
2241             insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
2242             break;
2243 
2244           default:
2245             abort ();
2246           }
2247     }
2248 }
2249 #else
2250 #define cfi_change_reg_numbers(insn, cseg) do { } while (0)
2251 #endif
2252 
2253 #if SUPPORT_COMPACT_EH
2254 static void
cfi_emit_eh_header(symbolS * sym,bfd_vma addend)2255 cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
2256 {
2257   expressionS exp;
2258 
2259   exp.X_add_number = addend;
2260   exp.X_add_symbol = sym;
2261   emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, false);
2262 }
2263 
2264 static void
output_eh_header(struct fde_entry * fde)2265 output_eh_header (struct fde_entry *fde)
2266 {
2267   char *p;
2268   bfd_vma addend;
2269 
2270   if (fde->eh_header_type == EH_COMPACT_INLINE)
2271     addend = 0;
2272   else
2273     addend = 1;
2274 
2275   cfi_emit_eh_header (fde->start_address, addend);
2276 
2277   if (fde->eh_header_type == EH_COMPACT_INLINE)
2278     {
2279       p = frag_more (4);
2280       /* Inline entries always use PR1.  */
2281       *(p++) = 1;
2282       memcpy(p, fde->eh_data, 3);
2283     }
2284   else
2285     {
2286       if (fde->eh_header_type == EH_COMPACT_LEGACY)
2287           addend = 1;
2288       else if (fde->eh_header_type == EH_COMPACT_OUTLINE
2289                  || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
2290           addend = 0;
2291       else
2292           abort ();
2293       cfi_emit_eh_header (fde->eh_loc, addend);
2294     }
2295 }
2296 #endif
2297 
2298 void
cfi_finish(void)2299 cfi_finish (void)
2300 {
2301   struct cie_entry *cie, *cie_next;
2302   segT cfi_seg, ccseg;
2303   struct fde_entry *fde;
2304   struct cfi_insn_data *first;
2305   int save_flag_traditional_format, seek_next_seg;
2306 
2307   if (all_fde_data == 0)
2308     return;
2309 
2310   if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2311       || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
2312     {
2313       /* Make sure check_eh_frame doesn't do anything with our output.  */
2314       save_flag_traditional_format = flag_traditional_format;
2315       flag_traditional_format = 1;
2316 
2317       if (!EH_FRAME_LINKONCE)
2318           {
2319             /* Open .eh_frame section.  */
2320             cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2321                                          (SEC_ALLOC | SEC_LOAD | SEC_DATA
2322                                           | DWARF2_EH_FRAME_READ_ONLY),
2323                                          EH_FRAME_ALIGNMENT);
2324 #ifdef md_fix_up_eh_frame
2325             md_fix_up_eh_frame (cfi_seg);
2326 #else
2327             (void) cfi_seg;
2328 #endif
2329           }
2330 
2331       do
2332           {
2333             ccseg = NULL;
2334             seek_next_seg = 0;
2335 
2336             for (cie = cie_root; cie; cie = cie_next)
2337               {
2338                 cie_next = cie->next;
2339                 free ((void *) cie);
2340               }
2341             cie_root = NULL;
2342 
2343             for (fde = all_fde_data; fde ; fde = fde->next)
2344               {
2345                 if ((fde->sections & CFI_EMIT_eh_frame) == 0
2346                       && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2347                     continue;
2348 
2349 #if SUPPORT_COMPACT_EH
2350                 /* Emit a LEGACY format header if we have processed all
2351                      of the .cfi directives without encountering either inline or
2352                      out-of-line compact unwinding opcodes.  */
2353                 if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2354                       || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2355                     fde->eh_header_type = EH_COMPACT_LEGACY;
2356 
2357                 if (fde->eh_header_type != EH_COMPACT_LEGACY)
2358                     continue;
2359 #endif
2360                 if (EH_FRAME_LINKONCE)
2361                     {
2362                       if (HANDLED (fde))
2363                         continue;
2364                       if (seek_next_seg && CUR_SEG (fde) != ccseg)
2365                         {
2366                           seek_next_seg = 2;
2367                           continue;
2368                         }
2369                       if (!seek_next_seg)
2370                         {
2371                           ccseg = CUR_SEG (fde);
2372                           /* Open .eh_frame section.  */
2373                           cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2374                                                        (SEC_ALLOC | SEC_LOAD | SEC_DATA
2375                                                         | DWARF2_EH_FRAME_READ_ONLY),
2376                                                        EH_FRAME_ALIGNMENT);
2377 #ifdef md_fix_up_eh_frame
2378                           md_fix_up_eh_frame (cfi_seg);
2379 #else
2380                           (void) cfi_seg;
2381 #endif
2382                           seek_next_seg = 1;
2383                         }
2384                       SET_HANDLED (fde, 1);
2385                     }
2386 
2387                 if (fde->end_address == NULL)
2388                     {
2389                       as_bad (_("open CFI at the end of file; "
2390                                   "missing .cfi_endproc directive"));
2391                       fde->end_address = fde->start_address;
2392                     }
2393 
2394                 cie = select_cie_for_fde (fde, true, &first, 2);
2395                 fde->eh_loc = symbol_temp_new_now ();
2396                 output_fde (fde, cie, true, first,
2397                                 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2398               }
2399           }
2400       while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2401 
2402       if (EH_FRAME_LINKONCE)
2403           for (fde = all_fde_data; fde ; fde = fde->next)
2404             SET_HANDLED (fde, 0);
2405 
2406 #if SUPPORT_COMPACT_EH
2407       if (compact_eh)
2408           {
2409             /* Create remaining out of line table entries.  */
2410             do
2411               {
2412                 ccseg = NULL;
2413                 seek_next_seg = 0;
2414 
2415                 for (fde = all_fde_data; fde ; fde = fde->next)
2416                     {
2417                       if ((fde->sections & CFI_EMIT_eh_frame) == 0
2418                           && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2419                         continue;
2420 
2421                       if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2422                         continue;
2423                       if (HANDLED (fde))
2424                         continue;
2425                       if (seek_next_seg && CUR_SEG (fde) != ccseg)
2426                         {
2427                           seek_next_seg = 2;
2428                           continue;
2429                         }
2430                       if (!seek_next_seg)
2431                         {
2432                           ccseg = CUR_SEG (fde);
2433                           /* Open .gnu_extab section.  */
2434                           get_cfi_seg (ccseg, ".gnu_extab",
2435                                            (SEC_ALLOC | SEC_LOAD | SEC_DATA
2436                                             | DWARF2_EH_FRAME_READ_ONLY),
2437                                            1);
2438                           seek_next_seg = 1;
2439                         }
2440                       SET_HANDLED (fde, 1);
2441 
2442                       frag_align (1, 0, 0);
2443                       record_alignment (now_seg, 1);
2444                       output_compact_unwind_data (fde, 1);
2445                     }
2446               }
2447             while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2448 
2449             for (fde = all_fde_data; fde ; fde = fde->next)
2450               SET_HANDLED (fde, 0);
2451 
2452             /* Create index table fragments.  */
2453             do
2454               {
2455                 ccseg = NULL;
2456                 seek_next_seg = 0;
2457 
2458                 for (fde = all_fde_data; fde ; fde = fde->next)
2459                     {
2460                       if ((fde->sections & CFI_EMIT_eh_frame) == 0
2461                           && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2462                         continue;
2463 
2464                       if (HANDLED (fde))
2465                         continue;
2466                       if (seek_next_seg && CUR_SEG (fde) != ccseg)
2467                         {
2468                           seek_next_seg = 2;
2469                           continue;
2470                         }
2471                       if (!seek_next_seg)
2472                         {
2473                           ccseg = CUR_SEG (fde);
2474                           /* Open .eh_frame_entry section.  */
2475                           cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2476                                                        (SEC_ALLOC | SEC_LOAD | SEC_DATA
2477                                                         | DWARF2_EH_FRAME_READ_ONLY),
2478                                                        2);
2479                           seek_next_seg = 1;
2480                         }
2481                       SET_HANDLED (fde, 1);
2482 
2483                       output_eh_header (fde);
2484                     }
2485               }
2486             while (seek_next_seg == 2);
2487 
2488             for (fde = all_fde_data; fde ; fde = fde->next)
2489               SET_HANDLED (fde, 0);
2490           }
2491 #endif /* SUPPORT_COMPACT_EH */
2492 
2493       flag_traditional_format = save_flag_traditional_format;
2494     }
2495 
2496   /* Generate SFrame section if the user specifies:
2497           - the command line option to gas, or
2498           - .sframe in the .cfi_sections directive.  */
2499   if (flag_gen_sframe || (all_cfi_sections & CFI_EMIT_sframe) != 0)
2500     {
2501       if (support_sframe_p ())
2502           {
2503             segT sframe_seg;
2504             int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
2505 
2506             if (!SUPPORT_FRAME_LINKONCE)
2507               sframe_seg = get_cfi_seg (NULL, ".sframe",
2508                                                    (SEC_ALLOC | SEC_LOAD | SEC_DATA
2509                                                     | DWARF2_EH_FRAME_READ_ONLY),
2510                                                    alignment);
2511             output_sframe (sframe_seg);
2512           }
2513       else
2514           as_bad (_(".sframe not supported for target"));
2515     }
2516 
2517   if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
2518     {
2519       int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
2520 
2521       if (!SUPPORT_FRAME_LINKONCE)
2522           get_cfi_seg (NULL, ".debug_frame",
2523                          SEC_READONLY | SEC_DEBUGGING,
2524                          alignment);
2525 
2526       do
2527           {
2528             ccseg = NULL;
2529             seek_next_seg = 0;
2530 
2531             for (cie = cie_root; cie; cie = cie_next)
2532               {
2533                 cie_next = cie->next;
2534                 free ((void *) cie);
2535               }
2536             cie_root = NULL;
2537 
2538             for (fde = all_fde_data; fde ; fde = fde->next)
2539               {
2540                 if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2541                     continue;
2542 
2543                 if (SUPPORT_FRAME_LINKONCE)
2544                     {
2545                       if (HANDLED (fde))
2546                         continue;
2547                       if (seek_next_seg && CUR_SEG (fde) != ccseg)
2548                         {
2549                           seek_next_seg = 2;
2550                           continue;
2551                         }
2552                       if (!seek_next_seg)
2553                         {
2554                           ccseg = CUR_SEG (fde);
2555                           /* Open .debug_frame section.  */
2556                           get_cfi_seg (ccseg, ".debug_frame",
2557                                            SEC_READONLY | SEC_DEBUGGING,
2558                                            alignment);
2559                           seek_next_seg = 1;
2560                         }
2561                       SET_HANDLED (fde, 1);
2562                     }
2563                 if (fde->end_address == NULL)
2564                     {
2565                       as_bad (_("open CFI at the end of file; "
2566                                   "missing .cfi_endproc directive"));
2567                       fde->end_address = fde->start_address;
2568                     }
2569 
2570                 fde->per_encoding = DW_EH_PE_omit;
2571                 fde->lsda_encoding = DW_EH_PE_omit;
2572                 cfi_change_reg_numbers (fde->data, ccseg);
2573                 cie = select_cie_for_fde (fde, false, &first, alignment);
2574                 output_fde (fde, cie, false, first, alignment);
2575               }
2576           }
2577       while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
2578 
2579       if (SUPPORT_FRAME_LINKONCE)
2580           for (fde = all_fde_data; fde ; fde = fde->next)
2581             SET_HANDLED (fde, 0);
2582     }
2583   if (dwcfi_hash)
2584     htab_delete (dwcfi_hash);
2585 }
2586 
2587 #else /* TARGET_USE_CFIPOP */
2588 
2589 /* Emit an intelligible error message for missing support.  */
2590 
2591 static void
dot_cfi_dummy(int ignored ATTRIBUTE_UNUSED)2592 dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2593 {
2594   as_bad (_("CFI is not supported for this target"));
2595   ignore_rest_of_line ();
2596 }
2597 
2598 const pseudo_typeS cfi_pseudo_table[] =
2599   {
2600     { "cfi_sections", dot_cfi_dummy, 0 },
2601     { "cfi_startproc", dot_cfi_dummy, 0 },
2602     { "cfi_endproc", dot_cfi_dummy, 0 },
2603     { "cfi_fde_data", dot_cfi_dummy, 0 },
2604     { "cfi_def_cfa", dot_cfi_dummy, 0 },
2605     { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2606     { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2607     { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2608     { "cfi_offset", dot_cfi_dummy, 0 },
2609     { "cfi_rel_offset", dot_cfi_dummy, 0 },
2610     { "cfi_register", dot_cfi_dummy, 0 },
2611     { "cfi_return_column", dot_cfi_dummy, 0 },
2612     { "cfi_restore", dot_cfi_dummy, 0 },
2613     { "cfi_undefined", dot_cfi_dummy, 0 },
2614     { "cfi_same_value", dot_cfi_dummy, 0 },
2615     { "cfi_remember_state", dot_cfi_dummy, 0 },
2616     { "cfi_restore_state", dot_cfi_dummy, 0 },
2617     { "cfi_window_save", dot_cfi_dummy, 0 },
2618     { "cfi_escape", dot_cfi_dummy, 0 },
2619     { "cfi_signal_frame", dot_cfi_dummy, 0 },
2620     { "cfi_personality", dot_cfi_dummy, 0 },
2621     { "cfi_personality_id", dot_cfi_dummy, 0 },
2622     { "cfi_lsda", dot_cfi_dummy, 0 },
2623     { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
2624     { "cfi_label", dot_cfi_dummy, 0 },
2625     { "cfi_inline_lsda", dot_cfi_dummy, 0 },
2626     { "cfi_val_offset", dot_cfi_dummy, 0 },
2627     { NULL, NULL, 0 }
2628   };
2629 
2630 void
cfi_finish(void)2631 cfi_finish (void)
2632 {
2633 }
2634 #endif /* TARGET_USE_CFIPOP */
2635