Subversion Repositories Kolibri OS

Rev

Rev 5222 | Details | Compare with Previous | Last modification | View Log | RSS feed

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