OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [dw2gencfi.c] - Blame information for rev 249

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.