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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [dw2gencfi.c] - Blame information for rev 252

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

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

powered by: WebSVN 2.1.0

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