1 /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
2    Copyright (C) 2003-2014 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 
27 #ifdef TARGET_USE_CFIPOP
28 
29 /* By default, use difference expressions if DIFF_EXPR_OK is defined.  */
30 #ifndef CFI_DIFF_EXPR_OK
31 # ifdef DIFF_EXPR_OK
32 #  define CFI_DIFF_EXPR_OK 1
33 # else
34 #  define CFI_DIFF_EXPR_OK 0
35 # endif
36 #endif
37 
38 #ifndef CFI_DIFF_LSDA_OK
39 #define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
40 #endif
41 
42 #if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
43 # error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
44 #endif
45 
46 /* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
47    of the CIE.  Default to 1 if not otherwise specified.  */
48 #ifndef DWARF2_LINE_MIN_INSN_LENGTH
49 #define DWARF2_LINE_MIN_INSN_LENGTH 1
50 #endif
51 
52 /* By default, use 32-bit relocations from .eh_frame into .text.  */
53 #ifndef DWARF2_FDE_RELOC_SIZE
54 #define DWARF2_FDE_RELOC_SIZE 4
55 #endif
56 
57 /* By default, use a read-only .eh_frame section.  */
58 #ifndef DWARF2_EH_FRAME_READ_ONLY
59 #define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
60 #endif
61 
62 #ifndef EH_FRAME_ALIGNMENT
63 #define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
64 #endif
65 
66 #ifndef tc_cfi_frame_initial_instructions
67 #define tc_cfi_frame_initial_instructions() ((void)0)
68 #endif
69 
70 #ifndef tc_cfi_startproc
71 # define tc_cfi_startproc() ((void)0)
72 #endif
73 
74 #ifndef tc_cfi_endproc
75 # define tc_cfi_endproc(fde) ((void) (fde))
76 #endif
77 
78 #ifndef DWARF2_FORMAT
79 #define DWARF2_FORMAT(SEC) dwarf2_format_32bit
80 #endif
81 
82 #ifndef DWARF2_ADDR_SIZE
83 #define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
84 #endif
85 
86 #if SUPPORT_FRAME_LINKONCE
87 #define CUR_SEG(structp) structp->cur_seg
88 #define SET_CUR_SEG(structp, seg) structp->cur_seg = seg
89 #define HANDLED(structp) structp->handled
90 #define SET_HANDLED(structp, val) structp->handled = val
91 #else
92 #define CUR_SEG(structp) NULL
93 #define SET_CUR_SEG(structp, seg) (void) (0 && seg)
94 #define HANDLED(structp) 0
95 #define SET_HANDLED(structp, val) (void) (0 && val)
96 #endif
97 
98 /* Private segment collection list.  */
99 struct dwcfi_seg_list
100 {
101   segT   seg;
102   int    subseg;
103   char * seg_name;
104 };
105 
106 #define FRAME_NAME ".eh_frame"
107 
108 static struct hash_control *dwcfi_hash;
109 
110 /* Build based on segment the derived .debug_...
111    segment name containing origin segment's postfix name part.  */
112 
113 static char *
get_debugseg_name(segT seg,const char * base_name)114 get_debugseg_name (segT seg, const char *base_name)
115 {
116   const char *name;
117 
118   if (!seg)
119     name = "";
120   else
121     {
122       const char * dollar;
123       const char * dot;
124 
125       name = bfd_get_section_name (stdoutput, seg);
126 
127       dollar = strchr (name, '$');
128       dot = strchr (name + 1, '.');
129 
130       if (!dollar && !dot)
131 	name = "";
132       else if (!dollar)
133 	name = dot;
134       else if (!dot)
135 	name = dollar;
136       else if (dot < dollar)
137 	name = dot;
138       else
139 	name = dollar;
140     }
141 
142   return concat (base_name, name, NULL);
143 }
144 
145 /* Allocate a dwcfi_seg_list structure.  */
146 
147 static struct dwcfi_seg_list *
alloc_debugseg_item(segT seg,int subseg,char * name)148 alloc_debugseg_item (segT seg, int subseg, char *name)
149 {
150   struct dwcfi_seg_list *r;
151 
152   r = (struct dwcfi_seg_list *)
153     xmalloc (sizeof (struct dwcfi_seg_list) + strlen (name));
154   r->seg = seg;
155   r->subseg = subseg;
156   r->seg_name = name;
157   return r;
158 }
159 
160 static segT
is_now_linkonce_segment(void)161 is_now_linkonce_segment (void)
162 {
163   if ((bfd_get_section_flags (stdoutput, now_seg)
164        & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
165 	  | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
166 	  | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0)
167     return now_seg;
168   return NULL;
169 }
170 
171 /* Generate debug... segment with same linkonce properties
172    of based segment.  */
173 
174 static segT
make_debug_seg(segT cseg,char * name,int sflags)175 make_debug_seg (segT cseg, char *name, int sflags)
176 {
177   segT save_seg = now_seg;
178   int save_subseg = now_subseg;
179   segT r;
180   flagword flags;
181 
182   r = subseg_new (name, 0);
183 
184   /* Check if code segment is marked as linked once.  */
185   if (!cseg)
186     flags = 0;
187   else
188     flags = bfd_get_section_flags (stdoutput, cseg)
189       & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
190 	 | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
191 	 | SEC_LINK_DUPLICATES_SAME_CONTENTS);
192 
193   /* Add standard section flags.  */
194   flags |= sflags;
195 
196   /* Apply possibly linked once flags to new generated segment, too.  */
197   if (!bfd_set_section_flags (stdoutput, r, flags))
198     as_bad (_("bfd_set_section_flags: %s"),
199 	    bfd_errmsg (bfd_get_error ()));
200 
201   /* Restore to previous segment.  */
202   if (save_seg != NULL)
203     subseg_set (save_seg, save_subseg);
204   return r;
205 }
206 
207 static void
dwcfi_hash_insert(const char * name,struct dwcfi_seg_list * item)208 dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item)
209 {
210   const char *error_string;
211 
212   if ((error_string = hash_jam (dwcfi_hash, name, (char *) item)))
213     as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
214 	      name, error_string);
215 }
216 
217 static struct dwcfi_seg_list *
dwcfi_hash_find(char * name)218 dwcfi_hash_find (char *name)
219 {
220   return (struct dwcfi_seg_list *) hash_find (dwcfi_hash, name);
221 }
222 
223 static struct dwcfi_seg_list *
dwcfi_hash_find_or_make(segT cseg,const char * base_name,int flags)224 dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags)
225 {
226   struct dwcfi_seg_list *item;
227   char *name;
228 
229   /* Initialize dwcfi_hash once.  */
230   if (!dwcfi_hash)
231     dwcfi_hash = hash_new ();
232 
233   name = get_debugseg_name (cseg, base_name);
234 
235   item = dwcfi_hash_find (name);
236   if (!item)
237     {
238       item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name);
239 
240       dwcfi_hash_insert (item->seg_name, item);
241     }
242   else
243     free (name);
244 
245   return item;
246 }
247 
248 /* ??? Share this with dwarf2cfg.c.  */
249 #ifndef TC_DWARF2_EMIT_OFFSET
250 #define TC_DWARF2_EMIT_OFFSET  generic_dwarf2_emit_offset
251 
252 /* Create an offset to .dwarf2_*.  */
253 
254 static void
generic_dwarf2_emit_offset(symbolS * symbol,unsigned int size)255 generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
256 {
257   expressionS exp;
258 
259   exp.X_op = O_symbol;
260   exp.X_add_symbol = symbol;
261   exp.X_add_number = 0;
262   emit_expr (&exp, size);
263 }
264 #endif
265 
266 struct cfi_escape_data
267 {
268   struct cfi_escape_data *next;
269   expressionS exp;
270 };
271 
272 struct cie_entry
273 {
274   struct cie_entry *next;
275 #if SUPPORT_FRAME_LINKONCE
276   segT cur_seg;
277 #endif
278   symbolS *start_address;
279   unsigned int return_column;
280   unsigned int signal_frame;
281   unsigned char per_encoding;
282   unsigned char lsda_encoding;
283   expressionS personality;
284   struct cfi_insn_data *first, *last;
285 };
286 
287 /* List of FDE entries.  */
288 
289 struct fde_entry *all_fde_data;
290 static struct fde_entry **last_fde_data = &all_fde_data;
291 
292 /* List of CIEs so that they could be reused.  */
293 static struct cie_entry *cie_root;
294 
295 /* Stack of old CFI data, for save/restore.  */
296 struct cfa_save_data
297 {
298   struct cfa_save_data *next;
299   offsetT cfa_offset;
300 };
301 
302 /* Current open FDE entry.  */
303 struct frch_cfi_data
304 {
305   struct fde_entry *cur_fde_data;
306   symbolS *last_address;
307   offsetT cur_cfa_offset;
308   struct cfa_save_data *cfa_save_stack;
309 };
310 
311 /* Construct a new FDE structure and add it to the end of the fde list.  */
312 
313 static struct fde_entry *
alloc_fde_entry(void)314 alloc_fde_entry (void)
315 {
316   struct fde_entry *fde = (struct fde_entry *)
317       xcalloc (1, sizeof (struct fde_entry));
318 
319   frchain_now->frch_cfi_data = (struct frch_cfi_data *)
320       xcalloc (1, sizeof (struct frch_cfi_data));
321   frchain_now->frch_cfi_data->cur_fde_data = fde;
322   *last_fde_data = fde;
323   last_fde_data = &fde->next;
324   SET_CUR_SEG (fde, is_now_linkonce_segment ());
325   SET_HANDLED (fde, 0);
326   fde->last = &fde->data;
327   fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
328   fde->per_encoding = DW_EH_PE_omit;
329   fde->lsda_encoding = DW_EH_PE_omit;
330 
331   return fde;
332 }
333 
334 /* The following functions are available for a backend to construct its
335    own unwind information, usually from legacy unwind directives.  */
336 
337 /* Construct a new INSN structure and add it to the end of the insn list
338    for the currently active FDE.  */
339 
340 static struct cfi_insn_data *
alloc_cfi_insn_data(void)341 alloc_cfi_insn_data (void)
342 {
343   struct cfi_insn_data *insn = (struct cfi_insn_data *)
344       xcalloc (1, sizeof (struct cfi_insn_data));
345   struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
346 
347   *cur_fde_data->last = insn;
348   cur_fde_data->last = &insn->next;
349   SET_CUR_SEG (insn, is_now_linkonce_segment ());
350   return insn;
351 }
352 
353 /* Construct a new FDE structure that begins at LABEL.  */
354 
355 void
cfi_new_fde(symbolS * label)356 cfi_new_fde (symbolS *label)
357 {
358   struct fde_entry *fde = alloc_fde_entry ();
359   fde->start_address = label;
360   frchain_now->frch_cfi_data->last_address = label;
361 }
362 
363 /* End the currently open FDE.  */
364 
365 void
cfi_end_fde(symbolS * label)366 cfi_end_fde (symbolS *label)
367 {
368   frchain_now->frch_cfi_data->cur_fde_data->end_address = label;
369   free (frchain_now->frch_cfi_data);
370   frchain_now->frch_cfi_data = NULL;
371 }
372 
373 /* Set the return column for the current FDE.  */
374 
375 void
cfi_set_return_column(unsigned regno)376 cfi_set_return_column (unsigned regno)
377 {
378   frchain_now->frch_cfi_data->cur_fde_data->return_column = regno;
379 }
380 
381 /* Universal functions to store new instructions.  */
382 
383 static void
cfi_add_CFA_insn(int insn)384 cfi_add_CFA_insn (int insn)
385 {
386   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
387 
388   insn_ptr->insn = insn;
389 }
390 
391 static void
cfi_add_CFA_insn_reg(int insn,unsigned regno)392 cfi_add_CFA_insn_reg (int insn, unsigned regno)
393 {
394   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
395 
396   insn_ptr->insn = insn;
397   insn_ptr->u.r = regno;
398 }
399 
400 static void
cfi_add_CFA_insn_offset(int insn,offsetT offset)401 cfi_add_CFA_insn_offset (int insn, offsetT offset)
402 {
403   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
404 
405   insn_ptr->insn = insn;
406   insn_ptr->u.i = offset;
407 }
408 
409 static void
cfi_add_CFA_insn_reg_reg(int insn,unsigned reg1,unsigned reg2)410 cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
411 {
412   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
413 
414   insn_ptr->insn = insn;
415   insn_ptr->u.rr.reg1 = reg1;
416   insn_ptr->u.rr.reg2 = reg2;
417 }
418 
419 static void
cfi_add_CFA_insn_reg_offset(int insn,unsigned regno,offsetT offset)420 cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
421 {
422   struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
423 
424   insn_ptr->insn = insn;
425   insn_ptr->u.ri.reg = regno;
426   insn_ptr->u.ri.offset = offset;
427 }
428 
429 /* Add a CFI insn to advance the PC from the last address to LABEL.  */
430 
431 void
cfi_add_advance_loc(symbolS * label)432 cfi_add_advance_loc (symbolS *label)
433 {
434   struct cfi_insn_data *insn = alloc_cfi_insn_data ();
435 
436   insn->insn = DW_CFA_advance_loc;
437   insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address;
438   insn->u.ll.lab2 = label;
439 
440   frchain_now->frch_cfi_data->last_address = label;
441 }
442 
443 /* Add a DW_CFA_offset record to the CFI data.  */
444 
445 void
cfi_add_CFA_offset(unsigned regno,offsetT offset)446 cfi_add_CFA_offset (unsigned regno, offsetT offset)
447 {
448   unsigned int abs_data_align;
449 
450   gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
451   cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
452 
453   abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
454 		    ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
455   if (offset % abs_data_align)
456     as_bad (_("register save offset not a multiple of %u"), abs_data_align);
457 }
458 
459 /* Add a DW_CFA_def_cfa record to the CFI data.  */
460 
461 void
cfi_add_CFA_def_cfa(unsigned regno,offsetT offset)462 cfi_add_CFA_def_cfa (unsigned regno, offsetT offset)
463 {
464   cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
465   frchain_now->frch_cfi_data->cur_cfa_offset = offset;
466 }
467 
468 /* Add a DW_CFA_register record to the CFI data.  */
469 
470 void
cfi_add_CFA_register(unsigned reg1,unsigned reg2)471 cfi_add_CFA_register (unsigned reg1, unsigned reg2)
472 {
473   cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
474 }
475 
476 /* Add a DW_CFA_def_cfa_register record to the CFI data.  */
477 
478 void
cfi_add_CFA_def_cfa_register(unsigned regno)479 cfi_add_CFA_def_cfa_register (unsigned regno)
480 {
481   cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
482 }
483 
484 /* Add a DW_CFA_def_cfa_offset record to the CFI data.  */
485 
486 void
cfi_add_CFA_def_cfa_offset(offsetT offset)487 cfi_add_CFA_def_cfa_offset (offsetT offset)
488 {
489   cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
490   frchain_now->frch_cfi_data->cur_cfa_offset = offset;
491 }
492 
493 void
cfi_add_CFA_restore(unsigned regno)494 cfi_add_CFA_restore (unsigned regno)
495 {
496   cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
497 }
498 
499 void
cfi_add_CFA_undefined(unsigned regno)500 cfi_add_CFA_undefined (unsigned regno)
501 {
502   cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
503 }
504 
505 void
cfi_add_CFA_same_value(unsigned regno)506 cfi_add_CFA_same_value (unsigned regno)
507 {
508   cfi_add_CFA_insn_reg (DW_CFA_same_value, regno);
509 }
510 
511 void
cfi_add_CFA_remember_state(void)512 cfi_add_CFA_remember_state (void)
513 {
514   struct cfa_save_data *p;
515 
516   cfi_add_CFA_insn (DW_CFA_remember_state);
517 
518   p = (struct cfa_save_data *) xmalloc (sizeof (*p));
519   p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
520   p->next = frchain_now->frch_cfi_data->cfa_save_stack;
521   frchain_now->frch_cfi_data->cfa_save_stack = p;
522 }
523 
524 void
cfi_add_CFA_restore_state(void)525 cfi_add_CFA_restore_state (void)
526 {
527   struct cfa_save_data *p;
528 
529   cfi_add_CFA_insn (DW_CFA_restore_state);
530 
531   p = frchain_now->frch_cfi_data->cfa_save_stack;
532   if (p)
533     {
534       frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset;
535       frchain_now->frch_cfi_data->cfa_save_stack = p->next;
536       free (p);
537     }
538   else
539     as_bad (_("CFI state restore without previous remember"));
540 }
541 
542 
543 /* Parse CFI assembler directives.  */
544 
545 static void dot_cfi (int);
546 static void dot_cfi_escape (int);
547 static void dot_cfi_sections (int);
548 static void dot_cfi_startproc (int);
549 static void dot_cfi_endproc (int);
550 static void dot_cfi_personality (int);
551 static void dot_cfi_lsda (int);
552 static void dot_cfi_val_encoded_addr (int);
553 
554 const pseudo_typeS cfi_pseudo_table[] =
555   {
556     { "cfi_sections", dot_cfi_sections, 0 },
557     { "cfi_startproc", dot_cfi_startproc, 0 },
558     { "cfi_endproc", dot_cfi_endproc, 0 },
559     { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
560     { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
561     { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset },
562     { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
563     { "cfi_offset", dot_cfi, DW_CFA_offset },
564     { "cfi_rel_offset", dot_cfi, CFI_rel_offset },
565     { "cfi_register", dot_cfi, DW_CFA_register },
566     { "cfi_return_column", dot_cfi, CFI_return_column },
567     { "cfi_restore", dot_cfi, DW_CFA_restore },
568     { "cfi_undefined", dot_cfi, DW_CFA_undefined },
569     { "cfi_same_value", dot_cfi, DW_CFA_same_value },
570     { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
571     { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
572     { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
573     { "cfi_escape", dot_cfi_escape, 0 },
574     { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
575     { "cfi_personality", dot_cfi_personality, 0 },
576     { "cfi_lsda", dot_cfi_lsda, 0 },
577     { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
578     { NULL, NULL, 0 }
579   };
580 
581 static void
cfi_parse_separator(void)582 cfi_parse_separator (void)
583 {
584   SKIP_WHITESPACE ();
585   if (*input_line_pointer == ',')
586     input_line_pointer++;
587   else
588     as_bad (_("missing separator"));
589 }
590 
591 #ifndef tc_parse_to_dw2regnum
592 static void
tc_parse_to_dw2regnum(expressionS * exp)593 tc_parse_to_dw2regnum (expressionS *exp)
594 {
595 # ifdef tc_regname_to_dw2regnum
596   SKIP_WHITESPACE ();
597   if (is_name_beginner (*input_line_pointer)
598       || (*input_line_pointer == '%'
599 	  && is_name_beginner (*++input_line_pointer)))
600     {
601       char *name, c;
602 
603       name = input_line_pointer;
604       c = get_symbol_end ();
605 
606       exp->X_op = O_constant;
607       exp->X_add_number = tc_regname_to_dw2regnum (name);
608 
609       *input_line_pointer = c;
610     }
611   else
612 # endif
613     expression_and_evaluate (exp);
614 }
615 #endif
616 
617 static unsigned
cfi_parse_reg(void)618 cfi_parse_reg (void)
619 {
620   int regno;
621   expressionS exp;
622 
623   tc_parse_to_dw2regnum (&exp);
624   switch (exp.X_op)
625     {
626     case O_register:
627     case O_constant:
628       regno = exp.X_add_number;
629       break;
630 
631     default:
632       regno = -1;
633       break;
634     }
635 
636   if (regno < 0)
637     {
638       as_bad (_("bad register expression"));
639       regno = 0;
640     }
641 
642   return regno;
643 }
644 
645 static offsetT
cfi_parse_const(void)646 cfi_parse_const (void)
647 {
648   return get_absolute_expression ();
649 }
650 
651 static void
dot_cfi(int arg)652 dot_cfi (int arg)
653 {
654   offsetT offset;
655   unsigned reg1, reg2;
656 
657   if (frchain_now->frch_cfi_data == NULL)
658     {
659       as_bad (_("CFI instruction used without previous .cfi_startproc"));
660       ignore_rest_of_line ();
661       return;
662     }
663 
664   /* If the last address was not at the current PC, advance to current.  */
665   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
666       || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
667 	 != frag_now_fix ())
668     cfi_add_advance_loc (symbol_temp_new_now ());
669 
670   switch (arg)
671     {
672     case DW_CFA_offset:
673       reg1 = cfi_parse_reg ();
674       cfi_parse_separator ();
675       offset = cfi_parse_const ();
676       cfi_add_CFA_offset (reg1, offset);
677       break;
678 
679     case CFI_rel_offset:
680       reg1 = cfi_parse_reg ();
681       cfi_parse_separator ();
682       offset = cfi_parse_const ();
683       cfi_add_CFA_offset (reg1,
684 			  offset - frchain_now->frch_cfi_data->cur_cfa_offset);
685       break;
686 
687     case DW_CFA_def_cfa:
688       reg1 = cfi_parse_reg ();
689       cfi_parse_separator ();
690       offset = cfi_parse_const ();
691       cfi_add_CFA_def_cfa (reg1, offset);
692       break;
693 
694     case DW_CFA_register:
695       reg1 = cfi_parse_reg ();
696       cfi_parse_separator ();
697       reg2 = cfi_parse_reg ();
698       cfi_add_CFA_register (reg1, reg2);
699       break;
700 
701     case DW_CFA_def_cfa_register:
702       reg1 = cfi_parse_reg ();
703       cfi_add_CFA_def_cfa_register (reg1);
704       break;
705 
706     case DW_CFA_def_cfa_offset:
707       offset = cfi_parse_const ();
708       cfi_add_CFA_def_cfa_offset (offset);
709       break;
710 
711     case CFI_adjust_cfa_offset:
712       offset = cfi_parse_const ();
713       cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
714 				  + offset);
715       break;
716 
717     case DW_CFA_restore:
718       for (;;)
719 	{
720 	  reg1 = cfi_parse_reg ();
721 	  cfi_add_CFA_restore (reg1);
722 	  SKIP_WHITESPACE ();
723 	  if (*input_line_pointer != ',')
724 	    break;
725 	  ++input_line_pointer;
726 	}
727       break;
728 
729     case DW_CFA_undefined:
730       for (;;)
731 	{
732 	  reg1 = cfi_parse_reg ();
733 	  cfi_add_CFA_undefined (reg1);
734 	  SKIP_WHITESPACE ();
735 	  if (*input_line_pointer != ',')
736 	    break;
737 	  ++input_line_pointer;
738 	}
739       break;
740 
741     case DW_CFA_same_value:
742       reg1 = cfi_parse_reg ();
743       cfi_add_CFA_same_value (reg1);
744       break;
745 
746     case CFI_return_column:
747       reg1 = cfi_parse_reg ();
748       cfi_set_return_column (reg1);
749       break;
750 
751     case DW_CFA_remember_state:
752       cfi_add_CFA_remember_state ();
753       break;
754 
755     case DW_CFA_restore_state:
756       cfi_add_CFA_restore_state ();
757       break;
758 
759     case DW_CFA_GNU_window_save:
760       cfi_add_CFA_insn (DW_CFA_GNU_window_save);
761       break;
762 
763     case CFI_signal_frame:
764       frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
765       break;
766 
767     default:
768       abort ();
769     }
770 
771   demand_empty_rest_of_line ();
772 }
773 
774 static void
dot_cfi_escape(int ignored ATTRIBUTE_UNUSED)775 dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
776 {
777   struct cfi_escape_data *head, **tail, *e;
778   struct cfi_insn_data *insn;
779 
780   if (frchain_now->frch_cfi_data == NULL)
781     {
782       as_bad (_("CFI instruction used without previous .cfi_startproc"));
783       ignore_rest_of_line ();
784       return;
785     }
786 
787   /* If the last address was not at the current PC, advance to current.  */
788   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
789       || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
790 	 != frag_now_fix ())
791     cfi_add_advance_loc (symbol_temp_new_now ());
792 
793   tail = &head;
794   do
795     {
796       e = (struct cfi_escape_data *) xmalloc (sizeof (*e));
797       do_parse_cons_expression (&e->exp, 1);
798       *tail = e;
799       tail = &e->next;
800     }
801   while (*input_line_pointer++ == ',');
802   *tail = NULL;
803 
804   insn = alloc_cfi_insn_data ();
805   insn->insn = CFI_escape;
806   insn->u.esc = head;
807 
808   --input_line_pointer;
809   demand_empty_rest_of_line ();
810 }
811 
812 static void
dot_cfi_personality(int ignored ATTRIBUTE_UNUSED)813 dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
814 {
815   struct fde_entry *fde;
816   offsetT encoding;
817 
818   if (frchain_now->frch_cfi_data == NULL)
819     {
820       as_bad (_("CFI instruction used without previous .cfi_startproc"));
821       ignore_rest_of_line ();
822       return;
823     }
824 
825   fde = frchain_now->frch_cfi_data->cur_fde_data;
826   encoding = cfi_parse_const ();
827   if (encoding == DW_EH_PE_omit)
828     {
829       demand_empty_rest_of_line ();
830       fde->per_encoding = encoding;
831       return;
832     }
833 
834   if ((encoding & 0xff) != encoding
835       || ((encoding & 0x70) != 0
836 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
837 	  && (encoding & 0x70) != DW_EH_PE_pcrel
838 #endif
839 	  )
840 	 /* leb128 can be handled, but does something actually need it?  */
841       || (encoding & 7) == DW_EH_PE_uleb128
842       || (encoding & 7) > DW_EH_PE_udata8)
843     {
844       as_bad (_("invalid or unsupported encoding in .cfi_personality"));
845       ignore_rest_of_line ();
846       return;
847     }
848 
849   if (*input_line_pointer++ != ',')
850     {
851       as_bad (_(".cfi_personality requires encoding and symbol arguments"));
852       ignore_rest_of_line ();
853       return;
854     }
855 
856   expression_and_evaluate (&fde->personality);
857   switch (fde->personality.X_op)
858     {
859     case O_symbol:
860       break;
861     case O_constant:
862       if ((encoding & 0x70) == DW_EH_PE_pcrel)
863 	encoding = DW_EH_PE_omit;
864       break;
865     default:
866       encoding = DW_EH_PE_omit;
867       break;
868     }
869 
870   fde->per_encoding = encoding;
871 
872   if (encoding == DW_EH_PE_omit)
873     {
874       as_bad (_("wrong second argument to .cfi_personality"));
875       ignore_rest_of_line ();
876       return;
877     }
878 
879   demand_empty_rest_of_line ();
880 }
881 
882 static void
dot_cfi_lsda(int ignored ATTRIBUTE_UNUSED)883 dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
884 {
885   struct fde_entry *fde;
886   offsetT encoding;
887 
888   if (frchain_now->frch_cfi_data == NULL)
889     {
890       as_bad (_("CFI instruction used without previous .cfi_startproc"));
891       ignore_rest_of_line ();
892       return;
893     }
894 
895   fde = frchain_now->frch_cfi_data->cur_fde_data;
896   encoding = cfi_parse_const ();
897   if (encoding == DW_EH_PE_omit)
898     {
899       demand_empty_rest_of_line ();
900       fde->lsda_encoding = encoding;
901       return;
902     }
903 
904   if ((encoding & 0xff) != encoding
905       || ((encoding & 0x70) != 0
906 #if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
907 	  && (encoding & 0x70) != DW_EH_PE_pcrel
908 #endif
909 	  )
910 	 /* leb128 can be handled, but does something actually need it?  */
911       || (encoding & 7) == DW_EH_PE_uleb128
912       || (encoding & 7) > DW_EH_PE_udata8)
913     {
914       as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
915       ignore_rest_of_line ();
916       return;
917     }
918 
919   if (*input_line_pointer++ != ',')
920     {
921       as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
922       ignore_rest_of_line ();
923       return;
924     }
925 
926   fde->lsda_encoding = encoding;
927 
928   expression_and_evaluate (&fde->lsda);
929   switch (fde->lsda.X_op)
930     {
931     case O_symbol:
932       break;
933     case O_constant:
934       if ((encoding & 0x70) == DW_EH_PE_pcrel)
935 	encoding = DW_EH_PE_omit;
936       break;
937     default:
938       encoding = DW_EH_PE_omit;
939       break;
940     }
941 
942   fde->lsda_encoding = encoding;
943 
944   if (encoding == DW_EH_PE_omit)
945     {
946       as_bad (_("wrong second argument to .cfi_lsda"));
947       ignore_rest_of_line ();
948       return;
949     }
950 
951   demand_empty_rest_of_line ();
952 }
953 
954 static void
dot_cfi_val_encoded_addr(int ignored ATTRIBUTE_UNUSED)955 dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
956 {
957   struct cfi_insn_data *insn_ptr;
958   offsetT encoding;
959 
960   if (frchain_now->frch_cfi_data == NULL)
961     {
962       as_bad (_("CFI instruction used without previous .cfi_startproc"));
963       ignore_rest_of_line ();
964       return;
965     }
966 
967   /* If the last address was not at the current PC, advance to current.  */
968   if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
969       || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
970 	 != frag_now_fix ())
971     cfi_add_advance_loc (symbol_temp_new_now ());
972 
973   insn_ptr = alloc_cfi_insn_data ();
974   insn_ptr->insn = CFI_val_encoded_addr;
975 
976   insn_ptr->u.ea.reg = cfi_parse_reg ();
977 
978   cfi_parse_separator ();
979   encoding = cfi_parse_const ();
980   if ((encoding & 0xff) != encoding
981       || ((encoding & 0x70) != 0
982 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
983 	  && (encoding & 0x70) != DW_EH_PE_pcrel
984 #endif
985 	  )
986 	 /* leb128 can be handled, but does something actually need it?  */
987       || (encoding & 7) == DW_EH_PE_uleb128
988       || (encoding & 7) > DW_EH_PE_udata8)
989     {
990       as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
991       encoding = DW_EH_PE_omit;
992     }
993 
994   cfi_parse_separator ();
995   expression_and_evaluate (&insn_ptr->u.ea.exp);
996   switch (insn_ptr->u.ea.exp.X_op)
997     {
998     case O_symbol:
999       break;
1000     case O_constant:
1001       if ((encoding & 0x70) != DW_EH_PE_pcrel)
1002 	break;
1003     default:
1004       encoding = DW_EH_PE_omit;
1005       break;
1006     }
1007 
1008   insn_ptr->u.ea.encoding = encoding;
1009   if (encoding == DW_EH_PE_omit)
1010     {
1011       as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1012       ignore_rest_of_line ();
1013       return;
1014     }
1015 
1016   demand_empty_rest_of_line ();
1017 }
1018 
1019 /* By default emit .eh_frame only, not .debug_frame.  */
1020 #define CFI_EMIT_eh_frame	(1 << 0)
1021 #define CFI_EMIT_debug_frame	(1 << 1)
1022 #define CFI_EMIT_target		(1 << 2)
1023 static int cfi_sections = CFI_EMIT_eh_frame;
1024 
1025 static void
dot_cfi_sections(int ignored ATTRIBUTE_UNUSED)1026 dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1027 {
1028   int sections = 0;
1029 
1030   SKIP_WHITESPACE ();
1031   if (is_name_beginner (*input_line_pointer))
1032     while (1)
1033       {
1034 	char *name, c;
1035 
1036 	name = input_line_pointer;
1037 	c = get_symbol_end ();
1038 
1039 	if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0
1040 	    && name[9] != '_')
1041 	  sections |= CFI_EMIT_eh_frame;
1042 	else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0)
1043 	  sections |= CFI_EMIT_debug_frame;
1044 #ifdef tc_cfi_section_name
1045 	else if (strcmp (name, tc_cfi_section_name) == 0)
1046 	  sections |= CFI_EMIT_target;
1047 #endif
1048 	else
1049 	  {
1050 	    *input_line_pointer = c;
1051 	    input_line_pointer = name;
1052 	    break;
1053 	  }
1054 
1055 	*input_line_pointer = c;
1056 	SKIP_WHITESPACE ();
1057 	if (*input_line_pointer == ',')
1058 	  {
1059 	    name = input_line_pointer++;
1060 	    SKIP_WHITESPACE ();
1061 	    if (!is_name_beginner (*input_line_pointer))
1062 	      {
1063 		input_line_pointer = name;
1064 		break;
1065 	      }
1066 	  }
1067 	else if (is_name_beginner (*input_line_pointer))
1068 	  break;
1069       }
1070 
1071   demand_empty_rest_of_line ();
1072   cfi_sections = sections;
1073 }
1074 
1075 static void
dot_cfi_startproc(int ignored ATTRIBUTE_UNUSED)1076 dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
1077 {
1078   int simple = 0;
1079 
1080   if (frchain_now->frch_cfi_data != NULL)
1081     {
1082       as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
1083       ignore_rest_of_line ();
1084       return;
1085     }
1086 
1087   cfi_new_fde (symbol_temp_new_now ());
1088 
1089   SKIP_WHITESPACE ();
1090   if (is_name_beginner (*input_line_pointer))
1091     {
1092       char *name, c;
1093 
1094       name = input_line_pointer;
1095       c = get_symbol_end ();
1096 
1097       if (strcmp (name, "simple") == 0)
1098 	{
1099 	  simple = 1;
1100 	  *input_line_pointer = c;
1101 	}
1102       else
1103 	input_line_pointer = name;
1104     }
1105   demand_empty_rest_of_line ();
1106 
1107   frchain_now->frch_cfi_data->cur_cfa_offset = 0;
1108   if (!simple)
1109     tc_cfi_frame_initial_instructions ();
1110 
1111   if ((cfi_sections & CFI_EMIT_target) != 0)
1112     tc_cfi_startproc ();
1113 }
1114 
1115 static void
dot_cfi_endproc(int ignored ATTRIBUTE_UNUSED)1116 dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1117 {
1118   struct fde_entry *fde;
1119 
1120   if (frchain_now->frch_cfi_data == NULL)
1121     {
1122       as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
1123       ignore_rest_of_line ();
1124       return;
1125     }
1126 
1127   fde = frchain_now->frch_cfi_data->cur_fde_data;
1128 
1129   cfi_end_fde (symbol_temp_new_now ());
1130 
1131   demand_empty_rest_of_line ();
1132 
1133   if ((cfi_sections & CFI_EMIT_target) != 0)
1134     tc_cfi_endproc (fde);
1135 }
1136 
1137 
1138 /* Emit a single byte into the current segment.  */
1139 
1140 static inline void
out_one(int byte)1141 out_one (int byte)
1142 {
1143   FRAG_APPEND_1_CHAR (byte);
1144 }
1145 
1146 /* Emit a two-byte word into the current segment.  */
1147 
1148 static inline void
out_two(int data)1149 out_two (int data)
1150 {
1151   md_number_to_chars (frag_more (2), data, 2);
1152 }
1153 
1154 /* Emit a four byte word into the current segment.  */
1155 
1156 static inline void
out_four(int data)1157 out_four (int data)
1158 {
1159   md_number_to_chars (frag_more (4), data, 4);
1160 }
1161 
1162 /* Emit an unsigned "little-endian base 128" number.  */
1163 
1164 static void
out_uleb128(addressT value)1165 out_uleb128 (addressT value)
1166 {
1167   output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
1168 }
1169 
1170 /* Emit an unsigned "little-endian base 128" number.  */
1171 
1172 static void
out_sleb128(offsetT value)1173 out_sleb128 (offsetT value)
1174 {
1175   output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
1176 }
1177 
1178 static void
output_cfi_insn(struct cfi_insn_data * insn)1179 output_cfi_insn (struct cfi_insn_data *insn)
1180 {
1181   offsetT offset;
1182   unsigned int regno;
1183 
1184   switch (insn->insn)
1185     {
1186     case DW_CFA_advance_loc:
1187       {
1188 	symbolS *from = insn->u.ll.lab1;
1189 	symbolS *to = insn->u.ll.lab2;
1190 
1191 	if (symbol_get_frag (to) == symbol_get_frag (from))
1192 	  {
1193 	    addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1194 	    addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1195 
1196 	    if (scaled <= 0x3F)
1197 	      out_one (DW_CFA_advance_loc + scaled);
1198 	    else if (scaled <= 0xFF)
1199 	      {
1200 		out_one (DW_CFA_advance_loc1);
1201 		out_one (scaled);
1202 	      }
1203 	    else if (scaled <= 0xFFFF)
1204 	      {
1205 		out_one (DW_CFA_advance_loc2);
1206 		out_two (scaled);
1207 	      }
1208 	    else
1209 	      {
1210 		out_one (DW_CFA_advance_loc4);
1211 		out_four (scaled);
1212 	      }
1213 	  }
1214 	else
1215 	  {
1216 	    expressionS exp;
1217 
1218 	    exp.X_op = O_subtract;
1219 	    exp.X_add_symbol = to;
1220 	    exp.X_op_symbol = from;
1221 	    exp.X_add_number = 0;
1222 
1223 	    /* The code in ehopt.c expects that one byte of the encoding
1224 	       is already allocated to the frag.  This comes from the way
1225 	       that it scans the .eh_frame section looking first for the
1226 	       .byte DW_CFA_advance_loc4.  */
1227 	    *frag_more (1) = DW_CFA_advance_loc4;
1228 
1229 	    frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1230 		      make_expr_symbol (&exp), frag_now_fix () - 1,
1231 		      (char *) frag_now);
1232 	  }
1233       }
1234       break;
1235 
1236     case DW_CFA_def_cfa:
1237       offset = insn->u.ri.offset;
1238       if (offset < 0)
1239 	{
1240 	  out_one (DW_CFA_def_cfa_sf);
1241 	  out_uleb128 (insn->u.ri.reg);
1242 	  out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1243 	}
1244       else
1245 	{
1246 	  out_one (DW_CFA_def_cfa);
1247 	  out_uleb128 (insn->u.ri.reg);
1248 	  out_uleb128 (offset);
1249 	}
1250       break;
1251 
1252     case DW_CFA_def_cfa_register:
1253     case DW_CFA_undefined:
1254     case DW_CFA_same_value:
1255       out_one (insn->insn);
1256       out_uleb128 (insn->u.r);
1257       break;
1258 
1259     case DW_CFA_def_cfa_offset:
1260       offset = insn->u.i;
1261       if (offset < 0)
1262 	{
1263 	  out_one (DW_CFA_def_cfa_offset_sf);
1264 	  out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1265 	}
1266       else
1267 	{
1268 	  out_one (DW_CFA_def_cfa_offset);
1269 	  out_uleb128 (offset);
1270 	}
1271       break;
1272 
1273     case DW_CFA_restore:
1274       regno = insn->u.r;
1275       if (regno <= 0x3F)
1276 	{
1277 	  out_one (DW_CFA_restore + regno);
1278 	}
1279       else
1280 	{
1281 	  out_one (DW_CFA_restore_extended);
1282 	  out_uleb128 (regno);
1283 	}
1284       break;
1285 
1286     case DW_CFA_offset:
1287       regno = insn->u.ri.reg;
1288       offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1289       if (offset < 0)
1290 	{
1291 	  out_one (DW_CFA_offset_extended_sf);
1292 	  out_uleb128 (regno);
1293 	  out_sleb128 (offset);
1294 	}
1295       else if (regno <= 0x3F)
1296 	{
1297 	  out_one (DW_CFA_offset + regno);
1298 	  out_uleb128 (offset);
1299 	}
1300       else
1301 	{
1302 	  out_one (DW_CFA_offset_extended);
1303 	  out_uleb128 (regno);
1304 	  out_uleb128 (offset);
1305 	}
1306       break;
1307 
1308     case DW_CFA_register:
1309       out_one (DW_CFA_register);
1310       out_uleb128 (insn->u.rr.reg1);
1311       out_uleb128 (insn->u.rr.reg2);
1312       break;
1313 
1314     case DW_CFA_remember_state:
1315     case DW_CFA_restore_state:
1316       out_one (insn->insn);
1317       break;
1318 
1319     case DW_CFA_GNU_window_save:
1320       out_one (DW_CFA_GNU_window_save);
1321       break;
1322 
1323     case CFI_escape:
1324       {
1325 	struct cfi_escape_data *e;
1326 	for (e = insn->u.esc; e ; e = e->next)
1327 	  emit_expr (&e->exp, 1);
1328 	break;
1329       }
1330 
1331     case CFI_val_encoded_addr:
1332       {
1333 	unsigned encoding = insn->u.ea.encoding;
1334 	offsetT encoding_size;
1335 
1336 	if (encoding == DW_EH_PE_omit)
1337 	  break;
1338 	out_one (DW_CFA_val_expression);
1339 	out_uleb128 (insn->u.ea.reg);
1340 
1341 	switch (encoding & 0x7)
1342 	  {
1343 	  case DW_EH_PE_absptr:
1344 	    encoding_size = DWARF2_ADDR_SIZE (stdoutput);
1345 	    break;
1346 	  case DW_EH_PE_udata2:
1347 	    encoding_size = 2;
1348 	    break;
1349 	  case DW_EH_PE_udata4:
1350 	    encoding_size = 4;
1351 	    break;
1352 	  case DW_EH_PE_udata8:
1353 	    encoding_size = 8;
1354 	    break;
1355 	  default:
1356 	    abort ();
1357 	  }
1358 
1359 	/* If the user has requested absolute encoding,
1360 	   then use the smaller DW_OP_addr encoding.  */
1361 	if (insn->u.ea.encoding == DW_EH_PE_absptr)
1362 	  {
1363 	    out_uleb128 (1 + encoding_size);
1364 	    out_one (DW_OP_addr);
1365 	  }
1366 	else
1367 	  {
1368 	    out_uleb128 (1 + 1 + encoding_size);
1369 	    out_one (DW_OP_GNU_encoded_addr);
1370 	    out_one (encoding);
1371 
1372 	    if ((encoding & 0x70) == DW_EH_PE_pcrel)
1373 	      {
1374 #if CFI_DIFF_EXPR_OK
1375 		insn->u.ea.exp.X_op = O_subtract;
1376 		insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1377 #elif defined (tc_cfi_emit_pcrel_expr)
1378 		tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, encoding_size);
1379 		break;
1380 #else
1381 		abort ();
1382 #endif
1383 	      }
1384 	  }
1385 	emit_expr (&insn->u.ea.exp, encoding_size);
1386       }
1387       break;
1388 
1389     default:
1390       abort ();
1391     }
1392 }
1393 
1394 static offsetT
encoding_size(unsigned char encoding)1395 encoding_size (unsigned char encoding)
1396 {
1397   if (encoding == DW_EH_PE_omit)
1398     return 0;
1399   switch (encoding & 0x7)
1400     {
1401     case 0:
1402       return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
1403     case DW_EH_PE_udata2:
1404       return 2;
1405     case DW_EH_PE_udata4:
1406       return 4;
1407     case DW_EH_PE_udata8:
1408       return 8;
1409     default:
1410       abort ();
1411     }
1412 }
1413 
1414 static void
output_cie(struct cie_entry * cie,bfd_boolean eh_frame,int align)1415 output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
1416 {
1417   symbolS *after_size_address, *end_address;
1418   expressionS exp;
1419   struct cfi_insn_data *i;
1420   offsetT augmentation_size;
1421   int enc;
1422   enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1423 
1424   cie->start_address = symbol_temp_new_now ();
1425   after_size_address = symbol_temp_make ();
1426   end_address = symbol_temp_make ();
1427 
1428   exp.X_op = O_subtract;
1429   exp.X_add_symbol = end_address;
1430   exp.X_op_symbol = after_size_address;
1431   exp.X_add_number = 0;
1432 
1433   if (eh_frame || fmt == dwarf2_format_32bit)
1434     emit_expr (&exp, 4);			/* Length.  */
1435   else
1436     {
1437       if (fmt == dwarf2_format_64bit)
1438 	out_four (-1);
1439       emit_expr (&exp, 8);			/* Length.  */
1440     }
1441   symbol_set_value_now (after_size_address);
1442   if (eh_frame)
1443     out_four (0);				/* CIE id.  */
1444   else
1445     {
1446       out_four (-1);				/* CIE id.  */
1447       if (fmt != dwarf2_format_32bit)
1448 	out_four (-1);
1449     }
1450   out_one (DW_CIE_VERSION);			/* Version.  */
1451   if (eh_frame)
1452     {
1453       out_one ('z');				/* Augmentation.  */
1454       if (cie->per_encoding != DW_EH_PE_omit)
1455 	out_one ('P');
1456       if (cie->lsda_encoding != DW_EH_PE_omit)
1457 	out_one ('L');
1458       out_one ('R');
1459     }
1460   if (cie->signal_frame)
1461     out_one ('S');
1462   out_one (0);
1463   out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH);	/* Code alignment.  */
1464   out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT);	/* Data alignment.  */
1465   if (DW_CIE_VERSION == 1)			/* Return column.  */
1466     out_one (cie->return_column);
1467   else
1468     out_uleb128 (cie->return_column);
1469   if (eh_frame)
1470     {
1471       augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1472       if (cie->per_encoding != DW_EH_PE_omit)
1473 	augmentation_size += 1 + encoding_size (cie->per_encoding);
1474       out_uleb128 (augmentation_size);		/* Augmentation size.  */
1475 
1476       if (cie->per_encoding != DW_EH_PE_omit)
1477 	{
1478 	  offsetT size = encoding_size (cie->per_encoding);
1479 	  out_one (cie->per_encoding);
1480 	  exp = cie->personality;
1481 	  if ((cie->per_encoding & 0x70) == DW_EH_PE_pcrel)
1482 	    {
1483 #if CFI_DIFF_EXPR_OK
1484 	      exp.X_op = O_subtract;
1485 	      exp.X_op_symbol = symbol_temp_new_now ();
1486 	      emit_expr (&exp, size);
1487 #elif defined (tc_cfi_emit_pcrel_expr)
1488 	      tc_cfi_emit_pcrel_expr (&exp, size);
1489 #else
1490 	      abort ();
1491 #endif
1492 	    }
1493 	  else
1494 	    emit_expr (&exp, size);
1495 	}
1496 
1497       if (cie->lsda_encoding != DW_EH_PE_omit)
1498 	out_one (cie->lsda_encoding);
1499     }
1500 
1501   switch (DWARF2_FDE_RELOC_SIZE)
1502     {
1503     case 2:
1504       enc = DW_EH_PE_sdata2;
1505       break;
1506     case 4:
1507       enc = DW_EH_PE_sdata4;
1508       break;
1509     case 8:
1510       enc = DW_EH_PE_sdata8;
1511       break;
1512     default:
1513       abort ();
1514     }
1515 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1516   enc |= DW_EH_PE_pcrel;
1517 #endif
1518   if (eh_frame)
1519     out_one (enc);
1520 
1521   if (cie->first)
1522     {
1523       for (i = cie->first; i != cie->last; i = i->next)
1524 	{
1525 	  if (CUR_SEG (i) != CUR_SEG (cie))
1526 	    continue;
1527 	  output_cfi_insn (i);
1528 	}
1529     }
1530 
1531   frag_align (align, DW_CFA_nop, 0);
1532   symbol_set_value_now (end_address);
1533 }
1534 
1535 static void
output_fde(struct fde_entry * fde,struct cie_entry * cie,bfd_boolean eh_frame,struct cfi_insn_data * first,int align)1536 output_fde (struct fde_entry *fde, struct cie_entry *cie,
1537 	    bfd_boolean eh_frame, struct cfi_insn_data *first,
1538 	    int align)
1539 {
1540   symbolS *after_size_address, *end_address;
1541   expressionS exp;
1542   offsetT augmentation_size;
1543   enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1544   int offset_size;
1545   int addr_size;
1546 
1547   after_size_address = symbol_temp_make ();
1548   end_address = symbol_temp_make ();
1549 
1550   exp.X_op = O_subtract;
1551   exp.X_add_symbol = end_address;
1552   exp.X_op_symbol = after_size_address;
1553   exp.X_add_number = 0;
1554   if (eh_frame || fmt == dwarf2_format_32bit)
1555     offset_size = 4;
1556   else
1557     {
1558       if (fmt == dwarf2_format_64bit)
1559 	out_four (-1);
1560       offset_size = 8;
1561     }
1562   emit_expr (&exp, offset_size);		/* Length.  */
1563   symbol_set_value_now (after_size_address);
1564 
1565   if (eh_frame)
1566     {
1567       exp.X_op = O_subtract;
1568       exp.X_add_symbol = after_size_address;
1569       exp.X_op_symbol = cie->start_address;
1570       exp.X_add_number = 0;
1571       emit_expr (&exp, offset_size);		/* CIE offset.  */
1572     }
1573   else
1574     {
1575       TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
1576     }
1577 
1578   if (eh_frame)
1579     {
1580       exp.X_op = O_subtract;
1581       exp.X_add_number = 0;
1582 #if CFI_DIFF_EXPR_OK
1583       exp.X_add_symbol = fde->start_address;
1584       exp.X_op_symbol = symbol_temp_new_now ();
1585       emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);	/* Code offset.  */
1586 #else
1587       exp.X_op = O_symbol;
1588       exp.X_add_symbol = fde->start_address;
1589 #ifdef tc_cfi_emit_pcrel_expr
1590       tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE);	 /* Code offset.  */
1591 #else
1592       emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);	/* Code offset.  */
1593 #endif
1594 #endif
1595       addr_size = DWARF2_FDE_RELOC_SIZE;
1596     }
1597   else
1598     {
1599       exp.X_op = O_symbol;
1600       exp.X_add_symbol = fde->start_address;
1601       exp.X_add_number = 0;
1602       addr_size = DWARF2_ADDR_SIZE (stdoutput);
1603       emit_expr (&exp, addr_size);
1604     }
1605 
1606   exp.X_op = O_subtract;
1607   exp.X_add_symbol = fde->end_address;
1608   exp.X_op_symbol = fde->start_address;		/* Code length.  */
1609   exp.X_add_number = 0;
1610   emit_expr (&exp, addr_size);
1611 
1612   augmentation_size = encoding_size (fde->lsda_encoding);
1613   if (eh_frame)
1614     out_uleb128 (augmentation_size);		/* Augmentation size.  */
1615 
1616   if (fde->lsda_encoding != DW_EH_PE_omit)
1617     {
1618       exp = fde->lsda;
1619       if ((fde->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
1620 	{
1621 #if CFI_DIFF_LSDA_OK
1622 	  exp.X_op = O_subtract;
1623 	  exp.X_op_symbol = symbol_temp_new_now ();
1624 	  emit_expr (&exp, augmentation_size);
1625 #elif defined (tc_cfi_emit_pcrel_expr)
1626 	  tc_cfi_emit_pcrel_expr (&exp, augmentation_size);
1627 #else
1628 	  abort ();
1629 #endif
1630 	}
1631       else
1632 	emit_expr (&exp, augmentation_size);
1633     }
1634 
1635   for (; first; first = first->next)
1636     if (CUR_SEG (first) == CUR_SEG (fde))
1637       output_cfi_insn (first);
1638 
1639   frag_align (align, DW_CFA_nop, 0);
1640   symbol_set_value_now (end_address);
1641 }
1642 
1643 static struct cie_entry *
select_cie_for_fde(struct fde_entry * fde,bfd_boolean eh_frame,struct cfi_insn_data ** pfirst,int align)1644 select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
1645 		    struct cfi_insn_data **pfirst, int align)
1646 {
1647   struct cfi_insn_data *i, *j;
1648   struct cie_entry *cie;
1649 
1650   for (cie = cie_root; cie; cie = cie->next)
1651     {
1652       if (CUR_SEG (cie) != CUR_SEG (fde))
1653 	continue;
1654       if (cie->return_column != fde->return_column
1655 	  || cie->signal_frame != fde->signal_frame
1656 	  || cie->per_encoding != fde->per_encoding
1657 	  || cie->lsda_encoding != fde->lsda_encoding)
1658 	continue;
1659       if (cie->per_encoding != DW_EH_PE_omit)
1660 	{
1661 	  if (cie->personality.X_op != fde->personality.X_op
1662 	      || cie->personality.X_add_number
1663 		 != fde->personality.X_add_number)
1664 	    continue;
1665 	  switch (cie->personality.X_op)
1666 	    {
1667 	    case O_constant:
1668 	      if (cie->personality.X_unsigned != fde->personality.X_unsigned)
1669 		continue;
1670 	      break;
1671 	    case O_symbol:
1672 	      if (cie->personality.X_add_symbol
1673 		  != fde->personality.X_add_symbol)
1674 		continue;
1675 	      break;
1676 	    default:
1677 	      abort ();
1678 	    }
1679 	}
1680       for (i = cie->first, j = fde->data;
1681 	   i != cie->last && j != NULL;
1682 	   i = i->next, j = j->next)
1683 	{
1684 	  if (i->insn != j->insn)
1685 	    goto fail;
1686 	  switch (i->insn)
1687 	    {
1688 	    case DW_CFA_advance_loc:
1689 	    case DW_CFA_remember_state:
1690 	      /* We reached the first advance/remember in the FDE,
1691 		 but did not reach the end of the CIE list.  */
1692 	      goto fail;
1693 
1694 	    case DW_CFA_offset:
1695 	    case DW_CFA_def_cfa:
1696 	      if (i->u.ri.reg != j->u.ri.reg)
1697 		goto fail;
1698 	      if (i->u.ri.offset != j->u.ri.offset)
1699 		goto fail;
1700 	      break;
1701 
1702 	    case DW_CFA_register:
1703 	      if (i->u.rr.reg1 != j->u.rr.reg1)
1704 		goto fail;
1705 	      if (i->u.rr.reg2 != j->u.rr.reg2)
1706 		goto fail;
1707 	      break;
1708 
1709 	    case DW_CFA_def_cfa_register:
1710 	    case DW_CFA_restore:
1711 	    case DW_CFA_undefined:
1712 	    case DW_CFA_same_value:
1713 	      if (i->u.r != j->u.r)
1714 		goto fail;
1715 	      break;
1716 
1717 	    case DW_CFA_def_cfa_offset:
1718 	      if (i->u.i != j->u.i)
1719 		goto fail;
1720 	      break;
1721 
1722 	    case CFI_escape:
1723 	    case CFI_val_encoded_addr:
1724 	      /* Don't bother matching these for now.  */
1725 	      goto fail;
1726 
1727 	    default:
1728 	      abort ();
1729 	    }
1730 	}
1731 
1732       /* Success if we reached the end of the CIE list, and we've either
1733 	 run out of FDE entries or we've encountered an advance,
1734 	 remember, or escape.  */
1735       if (i == cie->last
1736 	  && (!j
1737 	      || j->insn == DW_CFA_advance_loc
1738 	      || j->insn == DW_CFA_remember_state
1739 	      || j->insn == CFI_escape
1740 	      || j->insn == CFI_val_encoded_addr))
1741 	{
1742 	  *pfirst = j;
1743 	  return cie;
1744 	}
1745 
1746     fail:;
1747     }
1748 
1749   cie = (struct cie_entry *) xmalloc (sizeof (struct cie_entry));
1750   cie->next = cie_root;
1751   cie_root = cie;
1752   SET_CUR_SEG (cie, CUR_SEG (fde));
1753   cie->return_column = fde->return_column;
1754   cie->signal_frame = fde->signal_frame;
1755   cie->per_encoding = fde->per_encoding;
1756   cie->lsda_encoding = fde->lsda_encoding;
1757   cie->personality = fde->personality;
1758   cie->first = fde->data;
1759 
1760   for (i = cie->first; i ; i = i->next)
1761     if (i->insn == DW_CFA_advance_loc
1762 	|| i->insn == DW_CFA_remember_state
1763 	|| i->insn == CFI_escape
1764 	|| i->insn == CFI_val_encoded_addr)
1765       break;
1766 
1767   cie->last = i;
1768   *pfirst = i;
1769 
1770   output_cie (cie, eh_frame, align);
1771 
1772   return cie;
1773 }
1774 
1775 #ifdef md_reg_eh_frame_to_debug_frame
1776 static void
cfi_change_reg_numbers(struct cfi_insn_data * insn,segT ccseg)1777 cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
1778 {
1779   for (; insn; insn = insn->next)
1780     {
1781       if (CUR_SEG (insn) != ccseg)
1782 	continue;
1783       switch (insn->insn)
1784 	{
1785 	case DW_CFA_advance_loc:
1786 	case DW_CFA_def_cfa_offset:
1787 	case DW_CFA_remember_state:
1788 	case DW_CFA_restore_state:
1789 	case DW_CFA_GNU_window_save:
1790 	case CFI_escape:
1791 	  break;
1792 
1793 	case DW_CFA_def_cfa:
1794 	case DW_CFA_offset:
1795 	  insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
1796 	  break;
1797 
1798 	case DW_CFA_def_cfa_register:
1799 	case DW_CFA_undefined:
1800 	case DW_CFA_same_value:
1801 	case DW_CFA_restore:
1802 	  insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
1803 	  break;
1804 
1805 	case DW_CFA_register:
1806 	  insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
1807 	  insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
1808 	  break;
1809 
1810 	case CFI_val_encoded_addr:
1811 	  insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
1812 	  break;
1813 
1814 	default:
1815 	  abort ();
1816 	}
1817     }
1818 }
1819 #else
1820 #define cfi_change_reg_numbers(insn, cseg) do { } while (0)
1821 #endif
1822 
1823 static segT
get_cfi_seg(segT cseg,const char * base,flagword flags,int align)1824 get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
1825 {
1826   if (SUPPORT_FRAME_LINKONCE)
1827     {
1828       struct dwcfi_seg_list *l;
1829 
1830       l = dwcfi_hash_find_or_make (cseg, base, flags);
1831 
1832       cseg = l->seg;
1833       subseg_set (cseg, l->subseg);
1834     }
1835   else
1836     {
1837       cseg = subseg_new (base, 0);
1838       bfd_set_section_flags (stdoutput, cseg, flags);
1839     }
1840   record_alignment (cseg, align);
1841   return cseg;
1842 }
1843 
1844 void
cfi_finish(void)1845 cfi_finish (void)
1846 {
1847   struct cie_entry *cie, *cie_next;
1848   segT cfi_seg, ccseg;
1849   struct fde_entry *fde;
1850   struct cfi_insn_data *first;
1851   int save_flag_traditional_format, seek_next_seg;
1852 
1853   if (all_fde_data == 0)
1854     return;
1855 
1856   if ((cfi_sections & CFI_EMIT_eh_frame) != 0)
1857     {
1858       /* Make sure check_eh_frame doesn't do anything with our output.  */
1859       save_flag_traditional_format = flag_traditional_format;
1860       flag_traditional_format = 1;
1861 
1862       if (!SUPPORT_FRAME_LINKONCE)
1863 	{
1864 	  /* Open .eh_frame section.  */
1865 	  cfi_seg = get_cfi_seg (NULL, ".eh_frame",
1866 				 (SEC_ALLOC | SEC_LOAD | SEC_DATA
1867 				  | DWARF2_EH_FRAME_READ_ONLY),
1868 				 EH_FRAME_ALIGNMENT);
1869 #ifdef md_fix_up_eh_frame
1870 	  md_fix_up_eh_frame (cfi_seg);
1871 #else
1872 	  (void) cfi_seg;
1873 #endif
1874 	}
1875 
1876       do
1877 	{
1878 	  ccseg = NULL;
1879 	  seek_next_seg = 0;
1880 
1881 	  for (cie = cie_root; cie; cie = cie_next)
1882 	    {
1883 	      cie_next = cie->next;
1884 	      free ((void *) cie);
1885 	    }
1886 	  cie_root = NULL;
1887 
1888 	  for (fde = all_fde_data; fde ; fde = fde->next)
1889 	    {
1890 	      if (SUPPORT_FRAME_LINKONCE)
1891 		{
1892 		  if (HANDLED (fde))
1893 		    continue;
1894 		  if (seek_next_seg && CUR_SEG (fde) != ccseg)
1895 		    {
1896 		      seek_next_seg = 2;
1897 		      continue;
1898 		    }
1899 		  if (!seek_next_seg)
1900 		    {
1901 		      ccseg = CUR_SEG (fde);
1902 		      /* Open .eh_frame section.  */
1903 		      cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
1904 					     (SEC_ALLOC | SEC_LOAD | SEC_DATA
1905 					      | DWARF2_EH_FRAME_READ_ONLY),
1906 					     EH_FRAME_ALIGNMENT);
1907 #ifdef md_fix_up_eh_frame
1908 		      md_fix_up_eh_frame (cfi_seg);
1909 #else
1910 		      (void) cfi_seg;
1911 #endif
1912 		      seek_next_seg = 1;
1913 		    }
1914 		  SET_HANDLED (fde, 1);
1915 		}
1916 
1917 	      if (fde->end_address == NULL)
1918 		{
1919 		  as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
1920 		  fde->end_address = fde->start_address;
1921 		}
1922 
1923 	      cie = select_cie_for_fde (fde, TRUE, &first, 2);
1924 	      output_fde (fde, cie, TRUE, first,
1925 			  fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
1926 	    }
1927 	}
1928       while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
1929 
1930       if (SUPPORT_FRAME_LINKONCE)
1931 	for (fde = all_fde_data; fde ; fde = fde->next)
1932 	  SET_HANDLED (fde, 0);
1933 
1934       flag_traditional_format = save_flag_traditional_format;
1935     }
1936 
1937   if ((cfi_sections & CFI_EMIT_debug_frame) != 0)
1938     {
1939       int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
1940 
1941       if (!SUPPORT_FRAME_LINKONCE)
1942 	get_cfi_seg (NULL, ".debug_frame",
1943 		     SEC_READONLY | SEC_DEBUGGING,
1944 		     alignment);
1945 
1946       do
1947 	{
1948 	  ccseg = NULL;
1949 	  seek_next_seg = 0;
1950 
1951 	  for (cie = cie_root; cie; cie = cie_next)
1952 	    {
1953 	      cie_next = cie->next;
1954 	      free ((void *) cie);
1955 	    }
1956 	  cie_root = NULL;
1957 
1958 	  for (fde = all_fde_data; fde ; fde = fde->next)
1959 	    {
1960 	      if (SUPPORT_FRAME_LINKONCE)
1961 		{
1962 		  if (HANDLED (fde))
1963 		    continue;
1964 		  if (seek_next_seg && CUR_SEG (fde) != ccseg)
1965 		    {
1966 		      seek_next_seg = 2;
1967 		      continue;
1968 		    }
1969 		  if (!seek_next_seg)
1970 		    {
1971 		      ccseg = CUR_SEG (fde);
1972 		      /* Open .debug_frame section.  */
1973 		      get_cfi_seg (ccseg, ".debug_frame",
1974 				   SEC_READONLY | SEC_DEBUGGING,
1975 				   alignment);
1976 		      seek_next_seg = 1;
1977 		    }
1978 		  SET_HANDLED (fde, 1);
1979 		}
1980 	      if (fde->end_address == NULL)
1981 		{
1982 		  as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
1983 		  fde->end_address = fde->start_address;
1984 		}
1985 
1986 	      fde->per_encoding = DW_EH_PE_omit;
1987 	      fde->lsda_encoding = DW_EH_PE_omit;
1988 	      cfi_change_reg_numbers (fde->data, ccseg);
1989 	      cie = select_cie_for_fde (fde, FALSE, &first, alignment);
1990 	      output_fde (fde, cie, FALSE, first, alignment);
1991 	    }
1992 	}
1993       while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
1994 
1995       if (SUPPORT_FRAME_LINKONCE)
1996 	for (fde = all_fde_data; fde ; fde = fde->next)
1997 	  SET_HANDLED (fde, 0);
1998     }
1999 }
2000 
2001 #else /* TARGET_USE_CFIPOP */
2002 
2003 /* Emit an intelligible error message for missing support.  */
2004 
2005 static void
dot_cfi_dummy(int ignored ATTRIBUTE_UNUSED)2006 dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2007 {
2008   as_bad (_("CFI is not supported for this target"));
2009   ignore_rest_of_line ();
2010 }
2011 
2012 const pseudo_typeS cfi_pseudo_table[] =
2013   {
2014     { "cfi_sections", dot_cfi_dummy, 0 },
2015     { "cfi_startproc", dot_cfi_dummy, 0 },
2016     { "cfi_endproc", dot_cfi_dummy, 0 },
2017     { "cfi_def_cfa", dot_cfi_dummy, 0 },
2018     { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2019     { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2020     { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2021     { "cfi_offset", dot_cfi_dummy, 0 },
2022     { "cfi_rel_offset", dot_cfi_dummy, 0 },
2023     { "cfi_register", dot_cfi_dummy, 0 },
2024     { "cfi_return_column", dot_cfi_dummy, 0 },
2025     { "cfi_restore", dot_cfi_dummy, 0 },
2026     { "cfi_undefined", dot_cfi_dummy, 0 },
2027     { "cfi_same_value", dot_cfi_dummy, 0 },
2028     { "cfi_remember_state", dot_cfi_dummy, 0 },
2029     { "cfi_restore_state", dot_cfi_dummy, 0 },
2030     { "cfi_window_save", dot_cfi_dummy, 0 },
2031     { "cfi_escape", dot_cfi_dummy, 0 },
2032     { "cfi_signal_frame", dot_cfi_dummy, 0 },
2033     { "cfi_personality", dot_cfi_dummy, 0 },
2034     { "cfi_lsda", dot_cfi_dummy, 0 },
2035     { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
2036     { NULL, NULL, 0 }
2037   };
2038 
2039 void
cfi_finish(void)2040 cfi_finish (void)
2041 {
2042 }
2043 #endif /* TARGET_USE_CFIPOP */
2044