xref: /netbsd-src/external/gpl3/binutils/dist/gas/dw2gencfi.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
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