Ignore:
Timestamp:
Feb 6, 2017, 1:00:00 PM (8 years ago)
Author:
Silvan Scherrer
Message:

binutils: update trunk to version 2.27

Location:
binutils/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • binutils/trunk

  • TabularUnified binutils/trunk/gas/dw2gencfi.c

    r970 r1973  
    11/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
    2    Copyright (C) 2003-2014 Free Software Foundation, Inc.
     2   Copyright (C) 2003-2016 Free Software Foundation, Inc.
    33   Contributed by Michal Ludvig <mludvig@suse.cz>
    44
     
    7676#endif
    7777
     78#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh)
     79
    7880#ifndef DWARF2_FORMAT
    7981#define DWARF2_FORMAT(SEC) dwarf2_format_32bit
     
    8486#endif
    8587
    86 #if SUPPORT_FRAME_LINKONCE
     88#if MULTIPLE_FRAME_SECTIONS
    8789#define CUR_SEG(structp) structp->cur_seg
    8890#define SET_CUR_SEG(structp, seg) structp->cur_seg = seg
     
    9698#endif
    9799
     100#ifndef tc_cfi_reloc_for_encoding
     101#define tc_cfi_reloc_for_encoding(e) BFD_RELOC_NONE
     102#endif
     103
    98104/* Private segment collection list.  */
    99105struct dwcfi_seg_list
     
    104110};
    105111
    106 #define FRAME_NAME ".eh_frame"
     112#ifdef SUPPORT_COMPACT_EH
     113static bfd_boolean compact_eh;
     114#else
     115#define compact_eh 0
     116#endif
    107117
    108118static struct hash_control *dwcfi_hash;
     119
     120
     121/* Emit a single byte into the current segment.  */
     122
     123static inline void
     124out_one (int byte)
     125{
     126  FRAG_APPEND_1_CHAR (byte);
     127}
     128
     129/* Emit a two-byte word into the current segment.  */
     130
     131static inline void
     132out_two (int data)
     133{
     134  md_number_to_chars (frag_more (2), data, 2);
     135}
     136
     137/* Emit a four byte word into the current segment.  */
     138
     139static inline void
     140out_four (int data)
     141{
     142  md_number_to_chars (frag_more (4), data, 4);
     143}
     144
     145/* Emit an unsigned "little-endian base 128" number.  */
     146
     147static void
     148out_uleb128 (addressT value)
     149{
     150  output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
     151}
     152
     153/* Emit an unsigned "little-endian base 128" number.  */
     154
     155static void
     156out_sleb128 (offsetT value)
     157{
     158  output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
     159}
     160
     161static offsetT
     162encoding_size (unsigned char encoding)
     163{
     164  if (encoding == DW_EH_PE_omit)
     165    return 0;
     166  switch (encoding & 0x7)
     167    {
     168    case 0:
     169      return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
     170    case DW_EH_PE_udata2:
     171      return 2;
     172    case DW_EH_PE_udata4:
     173      return 4;
     174    case DW_EH_PE_udata8:
     175      return 8;
     176    default:
     177      abort ();
     178    }
     179}
     180
     181/* Emit expression EXP in ENCODING.  If EMIT_ENCODING is true, first
     182   emit a byte containing ENCODING.  */
     183
     184static void
     185emit_expr_encoded (expressionS *exp, int encoding, bfd_boolean emit_encoding)
     186{
     187  offsetT size = encoding_size (encoding);
     188  bfd_reloc_code_real_type code;
     189
     190  if (encoding == DW_EH_PE_omit)
     191    return;
     192
     193  if (emit_encoding)
     194    out_one (encoding);
     195
     196  code = tc_cfi_reloc_for_encoding (encoding);
     197  if (code != BFD_RELOC_NONE)
     198    {
     199      reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
     200      char *p = frag_more (size);
     201      md_number_to_chars (p, 0, size);
     202      fix_new (frag_now, p - frag_now->fr_literal, size, exp->X_add_symbol,
     203               exp->X_add_number, howto->pc_relative, code);
     204    }
     205  else if ((encoding & 0x70) == DW_EH_PE_pcrel)
     206    {
     207#if CFI_DIFF_EXPR_OK
     208      expressionS tmp = *exp;
     209      tmp.X_op = O_subtract;
     210      tmp.X_op_symbol = symbol_temp_new_now ();
     211      emit_expr (&tmp, size);
     212#elif defined (tc_cfi_emit_pcrel_expr)
     213      tc_cfi_emit_pcrel_expr (exp, size);
     214#else
     215      abort ();
     216#endif
     217    }
     218  else
     219    emit_expr (exp, size);
     220}
     221
    109222
    110223/* Build based on segment the derived .debug_...
     
    129242
    130243      if (!dollar && !dot)
    131         name = "";
     244        {
     245          if (!strcmp (base_name, ".eh_frame_entry")
     246              && strcmp (name, ".text") != 0)
     247            return concat (base_name, ".", name, NULL);
     248
     249          name = "";
     250        }
    132251      else if (!dollar)
    133252        name = dot;
     
    161280is_now_linkonce_segment (void)
    162281{
     282  if (compact_eh)
     283    return now_seg;
     284
    163285  if ((bfd_get_section_flags (stdoutput, now_seg)
    164286       & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
     
    273395{
    274396  struct cie_entry *next;
    275 #if SUPPORT_FRAME_LINKONCE
     397#if MULTIPLE_FRAME_SECTIONS
    276398  segT cur_seg;
    277399#endif
     
    279401  unsigned int return_column;
    280402  unsigned int signal_frame;
     403  unsigned char fde_encoding;
    281404  unsigned char per_encoding;
    282405  unsigned char lsda_encoding;
     
    315438alloc_fde_entry (void)
    316439{
    317   struct fde_entry *fde = (struct fde_entry *)
    318       xcalloc (1, sizeof (struct fde_entry));
    319 
    320   frchain_now->frch_cfi_data = (struct frch_cfi_data *)
    321       xcalloc (1, sizeof (struct frch_cfi_data));
     440  struct fde_entry *fde = XCNEW (struct fde_entry);
     441
     442  frchain_now->frch_cfi_data = XCNEW (struct frch_cfi_data);
    322443  frchain_now->frch_cfi_data->cur_fde_data = fde;
    323444  *last_fde_data = fde;
     
    329450  fde->per_encoding = DW_EH_PE_omit;
    330451  fde->lsda_encoding = DW_EH_PE_omit;
     452  fde->eh_header_type = EH_COMPACT_UNKNOWN;
    331453
    332454  return fde;
     
    339461   for the currently active FDE.  */
    340462
     463static bfd_boolean cfi_sections_set = FALSE;
     464static int cfi_sections = CFI_EMIT_eh_frame;
     465int all_cfi_sections = 0;
     466static struct fde_entry *last_fde;
     467
    341468static struct cfi_insn_data *
    342469alloc_cfi_insn_data (void)
    343470{
    344   struct cfi_insn_data *insn = (struct cfi_insn_data *)
    345       xcalloc (1, sizeof (struct cfi_insn_data));
     471  struct cfi_insn_data *insn = XCNEW (struct cfi_insn_data);
    346472  struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
    347473
     
    380506}
    381507
     508void
     509cfi_set_sections (void)
     510{
     511  frchain_now->frch_cfi_data->cur_fde_data->sections = all_cfi_sections;
     512  cfi_sections_set = TRUE;
     513}
     514
    382515/* Universal functions to store new instructions.  */
    383516
     
    440573
    441574  frchain_now->frch_cfi_data->last_address = label;
     575}
     576
     577/* Add a CFI insn to label the current position in the CFI segment.  */
     578
     579void
     580cfi_add_label (const char *name)
     581{
     582  unsigned int len = strlen (name) + 1;
     583  struct cfi_insn_data *insn = alloc_cfi_insn_data ();
     584
     585  insn->insn = CFI_label;
     586  obstack_grow (&notes, name, len);
     587  insn->u.sym_name = (char *) obstack_finish (&notes);
    442588}
    443589
     
    517663  cfi_add_CFA_insn (DW_CFA_remember_state);
    518664
    519   p = (struct cfa_save_data *) xmalloc (sizeof (*p));
     665  p = XNEW (struct cfa_save_data);
    520666  p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
    521667  p->next = frchain_now->frch_cfi_data->cfa_save_stack;
     
    550696static void dot_cfi_startproc (int);
    551697static void dot_cfi_endproc (int);
     698static void dot_cfi_fde_data (int);
    552699static void dot_cfi_personality (int);
     700static void dot_cfi_personality_id (int);
    553701static void dot_cfi_lsda (int);
    554702static void dot_cfi_val_encoded_addr (int);
     703static void dot_cfi_inline_lsda (int);
     704static void dot_cfi_label (int);
    555705
    556706const pseudo_typeS cfi_pseudo_table[] =
     
    559709    { "cfi_startproc", dot_cfi_startproc, 0 },
    560710    { "cfi_endproc", dot_cfi_endproc, 0 },
     711    { "cfi_fde_data", dot_cfi_fde_data, 0 },
    561712    { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
    562713    { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
     
    576727    { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
    577728    { "cfi_personality", dot_cfi_personality, 0 },
     729    { "cfi_personality_id", dot_cfi_personality_id, 0 },
    578730    { "cfi_lsda", dot_cfi_lsda, 0 },
    579731    { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
     732    { "cfi_inline_lsda", dot_cfi_inline_lsda, 0 },
     733    { "cfi_label", dot_cfi_label, 0 },
    580734    { NULL, NULL, 0 }
    581735  };
     
    603757      char *name, c;
    604758
    605       name = input_line_pointer;
    606       c = get_symbol_end ();
     759      c = get_symbol_name (& name);
    607760
    608761      exp->X_op = O_constant;
    609762      exp->X_add_number = tc_regname_to_dw2regnum (name);
    610763
    611       *input_line_pointer = c;
     764      restore_line_pointer (c);
    612765    }
    613766  else
     
    796949  do
    797950    {
    798       e = (struct cfi_escape_data *) xmalloc (sizeof (*e));
     951      e = XNEW (struct cfi_escape_data);
    799952      do_parse_cons_expression (&e->exp, 1);
    800953      *tail = e;
     
    835988
    836989  if ((encoding & 0xff) != encoding
    837       || ((encoding & 0x70) != 0
     990      || ((((encoding & 0x70) != 0
    838991#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
    839           && (encoding & 0x70) != DW_EH_PE_pcrel
     992           && (encoding & 0x70) != DW_EH_PE_pcrel
    840993#endif
    841994          )
    842995         /* leb128 can be handled, but does something actually need it?  */
    843       || (encoding & 7) == DW_EH_PE_uleb128
    844       || (encoding & 7) > DW_EH_PE_udata8)
     996           || (encoding & 7) == DW_EH_PE_uleb128
     997           || (encoding & 7) > DW_EH_PE_udata8)
     998        && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
    845999    {
    8461000      as_bad (_("invalid or unsupported encoding in .cfi_personality"));
     
    9051059
    9061060  if ((encoding & 0xff) != encoding
    907       || ((encoding & 0x70) != 0
     1061      || ((((encoding & 0x70) != 0
    9081062#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
    909           && (encoding & 0x70) != DW_EH_PE_pcrel
    910 #endif
    911           )
     1063            && (encoding & 0x70) != DW_EH_PE_pcrel
     1064#endif
     1065           )
    9121066         /* leb128 can be handled, but does something actually need it?  */
    913       || (encoding & 7) == DW_EH_PE_uleb128
    914       || (encoding & 7) > DW_EH_PE_udata8)
     1067           || (encoding & 7) == DW_EH_PE_uleb128
     1068           || (encoding & 7) > DW_EH_PE_udata8)
     1069          && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
    9151070    {
    9161071      as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
     
    10191174}
    10201175
    1021 /* By default emit .eh_frame only, not .debug_frame.  */
    1022 #define CFI_EMIT_eh_frame       (1 << 0)
    1023 #define CFI_EMIT_debug_frame    (1 << 1)
    1024 #define CFI_EMIT_target         (1 << 2)
    1025 static int cfi_sections = CFI_EMIT_eh_frame;
     1176static void
     1177dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
     1178{
     1179  char *name = read_symbol_name ();
     1180
     1181  if (name == NULL)
     1182    return;
     1183
     1184  /* If the last address was not at the current PC, advance to current.  */
     1185  if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
     1186      || S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
     1187         != frag_now_fix ())
     1188    cfi_add_advance_loc (symbol_temp_new_now ());
     1189
     1190  cfi_add_label (name);
     1191  free (name);
     1192
     1193  demand_empty_rest_of_line ();
     1194}
    10261195
    10271196static void
     
    10311200
    10321201  SKIP_WHITESPACE ();
    1033   if (is_name_beginner (*input_line_pointer))
     1202  if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
    10341203    while (1)
    10351204      {
     1205        char * saved_ilp;
    10361206        char *name, c;
    10371207
    1038         name = input_line_pointer;
    1039         c = get_symbol_end ();
     1208        saved_ilp = input_line_pointer;
     1209        c = get_symbol_name (& name);
    10401210
    10411211        if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0
     
    10441214        else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0)
    10451215          sections |= CFI_EMIT_debug_frame;
     1216#if SUPPORT_COMPACT_EH
     1217        else if (strncmp (name, ".eh_frame_entry", sizeof ".eh_frame_entry") == 0)
     1218          {
     1219            compact_eh = TRUE;
     1220            sections |= CFI_EMIT_eh_frame_compact;
     1221          }
     1222#endif
    10461223#ifdef tc_cfi_section_name
    10471224        else if (strcmp (name, tc_cfi_section_name) == 0)
     
    10511228          {
    10521229            *input_line_pointer = c;
    1053             input_line_pointer = name;
     1230            input_line_pointer = saved_ilp;
    10541231            break;
    10551232          }
    10561233
    10571234        *input_line_pointer = c;
    1058         SKIP_WHITESPACE ();
     1235        SKIP_WHITESPACE_AFTER_NAME ();
    10591236        if (*input_line_pointer == ',')
    10601237          {
    10611238            name = input_line_pointer++;
    10621239            SKIP_WHITESPACE ();
    1063             if (!is_name_beginner (*input_line_pointer))
     1240            if (!is_name_beginner (*input_line_pointer) && *input_line_pointer != '"')
    10641241              {
    10651242                input_line_pointer = name;
     
    10671244              }
    10681245          }
    1069         else if (is_name_beginner (*input_line_pointer))
     1246        else if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
    10701247          break;
    10711248      }
    10721249
    10731250  demand_empty_rest_of_line ();
     1251  if (cfi_sections_set && cfi_sections != sections)
     1252    as_bad (_("inconsistent uses of .cfi_sections"));
    10741253  cfi_sections = sections;
    10751254}
     
    10901269
    10911270  SKIP_WHITESPACE ();
    1092   if (is_name_beginner (*input_line_pointer))
    1093     {
     1271  if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
     1272    {
     1273      char * saved_ilp = input_line_pointer;
    10941274      char *name, c;
    10951275
    1096       name = input_line_pointer;
    1097       c = get_symbol_end ();
     1276      c = get_symbol_name (& name);
    10981277
    10991278      if (strcmp (name, "simple") == 0)
    11001279        {
    11011280          simple = 1;
    1102           *input_line_pointer = c;
     1281          restore_line_pointer (c);
    11031282        }
    11041283      else
    1105         input_line_pointer = name;
     1284        input_line_pointer = saved_ilp;
    11061285    }
    11071286  demand_empty_rest_of_line ();
    11081287
     1288  cfi_sections_set = TRUE;
     1289  all_cfi_sections |= cfi_sections;
     1290  cfi_set_sections ();
    11091291  frchain_now->frch_cfi_data->cur_cfa_offset = 0;
    11101292  if (!simple)
     
    11181300dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
    11191301{
    1120   struct fde_entry *fde;
    1121 
    11221302  if (frchain_now->frch_cfi_data == NULL)
    11231303    {
     
    11271307    }
    11281308
     1309  last_fde = frchain_now->frch_cfi_data->cur_fde_data;
     1310
     1311  cfi_end_fde (symbol_temp_new_now ());
     1312
     1313  demand_empty_rest_of_line ();
     1314
     1315  cfi_sections_set = TRUE;
     1316  if ((cfi_sections & CFI_EMIT_target) != 0)
     1317    tc_cfi_endproc (last_fde);
     1318}
     1319
     1320static segT
     1321get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
     1322{
     1323  /* Exclude .debug_frame sections for Compact EH.  */
     1324  if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh))
     1325    {
     1326      struct dwcfi_seg_list *l;
     1327
     1328      l = dwcfi_hash_find_or_make (cseg, base, flags);
     1329
     1330      cseg = l->seg;
     1331      subseg_set (cseg, l->subseg);
     1332    }
     1333  else
     1334    {
     1335      cseg = subseg_new (base, 0);
     1336      bfd_set_section_flags (stdoutput, cseg, flags);
     1337    }
     1338  record_alignment (cseg, align);
     1339  return cseg;
     1340}
     1341
     1342#if SUPPORT_COMPACT_EH
     1343static void
     1344dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
     1345{
     1346  struct fde_entry *fde;
     1347
     1348  if (frchain_now->frch_cfi_data == NULL)
     1349    {
     1350      as_bad (_("CFI instruction used without previous .cfi_startproc"));
     1351      ignore_rest_of_line ();
     1352      return;
     1353    }
     1354
    11291355  fde = frchain_now->frch_cfi_data->cur_fde_data;
    1130 
    1131   cfi_end_fde (symbol_temp_new_now ());
    1132 
     1356  fde->personality_id = cfi_parse_const ();
    11331357  demand_empty_rest_of_line ();
    11341358
    1135   if ((cfi_sections & CFI_EMIT_target) != 0)
    1136     tc_cfi_endproc (fde);
    1137 }
    1138 
    1139 
    1140 
    1141 /* Emit a single byte into the current segment.  */
    1142 
    1143 static inline void
    1144 out_one (int byte)
    1145 {
    1146   FRAG_APPEND_1_CHAR (byte);
    1147 }
    1148 
    1149 /* Emit a two-byte word into the current segment.  */
    1150 
    1151 static inline void
    1152 out_two (int data)
    1153 {
    1154   md_number_to_chars (frag_more (2), data, 2);
    1155 }
    1156 
    1157 /* Emit a four byte word into the current segment.  */
    1158 
    1159 static inline void
    1160 out_four (int data)
    1161 {
    1162   md_number_to_chars (frag_more (4), data, 4);
    1163 }
    1164 
    1165 /* Emit an unsigned "little-endian base 128" number.  */
    1166 
    1167 static void
    1168 out_uleb128 (addressT value)
    1169 {
    1170   output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
    1171 }
    1172 
    1173 /* Emit an unsigned "little-endian base 128" number.  */
    1174 
    1175 static void
    1176 out_sleb128 (offsetT value)
    1177 {
    1178   output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
    1179 }
     1359  if (fde->personality_id == 0 || fde->personality_id > 3)
     1360    {
     1361      as_bad (_("wrong argument to .cfi_personality_id"));
     1362      return;
     1363    }
     1364}
     1365
     1366static void
     1367dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
     1368{
     1369  if (frchain_now->frch_cfi_data == NULL)
     1370    {
     1371      as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
     1372      ignore_rest_of_line ();
     1373      return;
     1374    }
     1375
     1376  last_fde = frchain_now->frch_cfi_data->cur_fde_data;
     1377
     1378  cfi_sections_set = TRUE;
     1379  if ((cfi_sections & CFI_EMIT_target) != 0
     1380      || (cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
     1381    {
     1382      struct cfi_escape_data *head, **tail, *e;
     1383      int num_ops = 0;
     1384
     1385      tail = &head;
     1386      if (!is_it_end_of_statement ())
     1387        {
     1388          num_ops = 0;
     1389          do
     1390            {
     1391              e = XNEW (struct cfi_escape_data);
     1392              do_parse_cons_expression (&e->exp, 1);
     1393              *tail = e;
     1394              tail = &e->next;
     1395              num_ops++;
     1396            }
     1397          while (*input_line_pointer++ == ',');
     1398          --input_line_pointer;
     1399        }
     1400      *tail = NULL;
     1401
     1402      if (last_fde->lsda_encoding != DW_EH_PE_omit)
     1403        last_fde->eh_header_type = EH_COMPACT_HAS_LSDA;
     1404      else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit)
     1405        last_fde->eh_header_type = EH_COMPACT_INLINE;
     1406      else
     1407        last_fde->eh_header_type = EH_COMPACT_OUTLINE;
     1408
     1409      if (last_fde->eh_header_type == EH_COMPACT_INLINE)
     1410        num_ops = 3;
     1411
     1412      last_fde->eh_data_size = num_ops;
     1413      last_fde->eh_data =  XNEWVEC (bfd_byte, num_ops);
     1414      num_ops = 0;
     1415      while (head)
     1416        {
     1417          e = head;
     1418          head = e->next;
     1419          last_fde->eh_data[num_ops++] = e->exp.X_add_number;
     1420          free (e);
     1421        }
     1422      if (last_fde->eh_header_type == EH_COMPACT_INLINE)
     1423        while (num_ops < 3)
     1424          last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop;
     1425    }
     1426
     1427  demand_empty_rest_of_line ();
     1428}
     1429
     1430/* Function to emit the compact unwinding opcodes stored in the
     1431   fde's eh_data field.  The end of the opcode data will be
     1432   padded to the value in align.  */
     1433
     1434static void
     1435output_compact_unwind_data (struct fde_entry *fde, int align)
     1436{
     1437  int data_size = fde->eh_data_size + 2;
     1438  int align_padding;
     1439  int amask;
     1440  char *p;
     1441
     1442  fde->eh_loc = symbol_temp_new_now ();
     1443
     1444  p = frag_more (1);
     1445  if (fde->personality_id != 0)
     1446    *p = fde->personality_id;
     1447  else if (fde->per_encoding != DW_EH_PE_omit)
     1448    {
     1449      *p = 0;
     1450      emit_expr_encoded (&fde->personality, fde->per_encoding, FALSE);
     1451      data_size += encoding_size (fde->per_encoding);
     1452    }
     1453  else
     1454    *p = 1;
     1455
     1456  amask = (1 << align) - 1;
     1457  align_padding = ((data_size + amask) & ~amask) - data_size;
     1458
     1459  p = frag_more (fde->eh_data_size + 1 + align_padding);
     1460  memcpy (p, fde->eh_data, fde->eh_data_size);
     1461  p += fde->eh_data_size;
     1462
     1463  while (align_padding-- > 0)
     1464    *(p++) = tc_compact_eh_opcode_pad;
     1465
     1466  *(p++) = tc_compact_eh_opcode_stop;
     1467  fde->eh_header_type = EH_COMPACT_OUTLINE_DONE;
     1468}
     1469
     1470/* Handle the .cfi_inline_lsda directive.  */
     1471static void
     1472dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
     1473{
     1474  segT ccseg;
     1475  int align;
     1476  long max_alignment = 28;
     1477
     1478  if (!last_fde)
     1479    {
     1480      as_bad (_("unexpected .cfi_inline_lsda"));
     1481      ignore_rest_of_line ();
     1482      return;
     1483    }
     1484
     1485  if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0)
     1486    {
     1487      as_bad (_(".cfi_inline_lsda not valid for this frame"));
     1488      ignore_rest_of_line ();
     1489      return;
     1490    }
     1491
     1492  if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN
     1493      && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA)
     1494    {
     1495      as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda"));
     1496      ignore_rest_of_line ();
     1497      return;
     1498    }
     1499
     1500#ifdef md_flush_pending_output
     1501  md_flush_pending_output ();
     1502#endif
     1503
     1504  align = get_absolute_expression ();
     1505  if (align > max_alignment)
     1506    {
     1507      align = max_alignment;
     1508      as_bad (_("Alignment too large: %d. assumed."), align);
     1509    }
     1510  else if (align < 0)
     1511    {
     1512      as_warn (_("Alignment negative: 0 assumed."));
     1513      align = 0;
     1514    }
     1515
     1516  demand_empty_rest_of_line ();
     1517  ccseg = CUR_SEG (last_fde);
     1518
     1519  /* Open .gnu_extab section.  */
     1520  get_cfi_seg (ccseg, ".gnu_extab",
     1521               (SEC_ALLOC | SEC_LOAD | SEC_DATA
     1522                | DWARF2_EH_FRAME_READ_ONLY),
     1523               1);
     1524
     1525  frag_align (align, 0, 0);
     1526  record_alignment (now_seg, align);
     1527  if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA)
     1528    output_compact_unwind_data (last_fde, align);
     1529
     1530  last_fde = NULL;
     1531
     1532  return;
     1533}
     1534#else /* !SUPPORT_COMPACT_EH */
     1535static void
     1536dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
     1537{
     1538  as_bad (_(".cfi_inline_lsda is not supported for this target"));
     1539  ignore_rest_of_line ();
     1540}
     1541
     1542static void
     1543dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
     1544{
     1545  as_bad (_(".cfi_fde_data is not supported for this target"));
     1546  ignore_rest_of_line ();
     1547}
     1548
     1549static void
     1550dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
     1551{
     1552  as_bad (_(".cfi_personality_id is not supported for this target"));
     1553  ignore_rest_of_line ();
     1554}
     1555#endif
     1556
    11801557
    11811558static void
     
    13351712      {
    13361713        unsigned encoding = insn->u.ea.encoding;
    1337         offsetT encoding_size;
     1714        offsetT enc_size;
    13381715
    13391716        if (encoding == DW_EH_PE_omit)
     
    13451722          {
    13461723          case DW_EH_PE_absptr:
    1347             encoding_size = DWARF2_ADDR_SIZE (stdoutput);
     1724            enc_size = DWARF2_ADDR_SIZE (stdoutput);
    13481725            break;
    13491726          case DW_EH_PE_udata2:
    1350             encoding_size = 2;
     1727            enc_size = 2;
    13511728            break;
    13521729          case DW_EH_PE_udata4:
    1353             encoding_size = 4;
     1730            enc_size = 4;
    13541731            break;
    13551732          case DW_EH_PE_udata8:
    1356             encoding_size = 8;
     1733            enc_size = 8;
    13571734            break;
    13581735          default:
     
    13641741        if (insn->u.ea.encoding == DW_EH_PE_absptr)
    13651742          {
    1366             out_uleb128 (1 + encoding_size);
     1743            out_uleb128 (1 + enc_size);
    13671744            out_one (DW_OP_addr);
    13681745          }
    13691746        else
    13701747          {
    1371             out_uleb128 (1 + 1 + encoding_size);
     1748            out_uleb128 (1 + 1 + enc_size);
    13721749            out_one (DW_OP_GNU_encoded_addr);
    13731750            out_one (encoding);
     
    13791756                insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
    13801757#elif defined (tc_cfi_emit_pcrel_expr)
    1381                 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, encoding_size);
     1758                tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size);
    13821759                break;
    13831760#else
     
    13861763              }
    13871764          }
    1388         emit_expr (&insn->u.ea.exp, encoding_size);
     1765        emit_expr (&insn->u.ea.exp, enc_size);
    13891766      }
    13901767      break;
    13911768
    1392     default:
    1393       abort ();
    1394     }
    1395 }
    1396 
    1397 static offsetT
    1398 encoding_size (unsigned char encoding)
    1399 {
    1400   if (encoding == DW_EH_PE_omit)
    1401     return 0;
    1402   switch (encoding & 0x7)
    1403     {
    1404     case 0:
    1405       return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
    1406     case DW_EH_PE_udata2:
    1407       return 2;
    1408     case DW_EH_PE_udata4:
    1409       return 4;
    1410     case DW_EH_PE_udata8:
    1411       return 8;
     1769    case CFI_label:
     1770      colon (insn->u.sym_name);
     1771      break;
     1772
    14121773    default:
    14131774      abort ();
     
    14771838      out_uleb128 (augmentation_size);          /* Augmentation size.  */
    14781839
    1479       if (cie->per_encoding != DW_EH_PE_omit)
    1480         {
    1481           offsetT size = encoding_size (cie->per_encoding);
    1482           out_one (cie->per_encoding);
    1483           exp = cie->personality;
    1484           if ((cie->per_encoding & 0x70) == DW_EH_PE_pcrel)
    1485             {
    1486 #if CFI_DIFF_EXPR_OK
    1487               exp.X_op = O_subtract;
    1488               exp.X_op_symbol = symbol_temp_new_now ();
    1489               emit_expr (&exp, size);
    1490 #elif defined (tc_cfi_emit_pcrel_expr)
    1491               tc_cfi_emit_pcrel_expr (&exp, size);
    1492 #else
    1493               abort ();
    1494 #endif
    1495             }
    1496           else
    1497             emit_expr (&exp, size);
    1498         }
     1840      emit_expr_encoded (&cie->personality, cie->per_encoding, TRUE);
    14991841
    15001842      if (cie->lsda_encoding != DW_EH_PE_omit)
     
    15191861  enc |= DW_EH_PE_pcrel;
    15201862#endif
     1863#ifdef DWARF2_FDE_RELOC_ENCODING
     1864  /* Allow target to override encoding.  */
     1865  enc = DWARF2_FDE_RELOC_ENCODING (enc);
     1866#endif
     1867  cie->fde_encoding = enc;
    15211868  if (eh_frame)
    15221869    out_one (enc);
     
    15791926    }
    15801927
     1928  exp.X_op = O_symbol;
    15811929  if (eh_frame)
    15821930    {
    1583       exp.X_op = O_subtract;
     1931      bfd_reloc_code_real_type code
     1932        = tc_cfi_reloc_for_encoding (cie->fde_encoding);
     1933      if (code != BFD_RELOC_NONE)
     1934        {
     1935          reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
     1936          char *p = frag_more (4);
     1937          md_number_to_chars (p, 0, 4);
     1938          fix_new (frag_now, p - frag_now->fr_literal, 4, fde->start_address,
     1939                   0, howto->pc_relative, code);
     1940        }
     1941      else
     1942        {
     1943          exp.X_op = O_subtract;
     1944          exp.X_add_number = 0;
     1945#if CFI_DIFF_EXPR_OK
     1946          exp.X_add_symbol = fde->start_address;
     1947          exp.X_op_symbol = symbol_temp_new_now ();
     1948          emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);      /* Code offset.  */
     1949#else
     1950          exp.X_op = O_symbol;
     1951          exp.X_add_symbol = fde->start_address;
     1952
     1953#if defined(tc_cfi_emit_pcrel_expr)
     1954          tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE);  /* Code offset.  */
     1955#else
     1956          emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);      /* Code offset.  */
     1957#endif
     1958#endif
     1959        }
     1960      addr_size = DWARF2_FDE_RELOC_SIZE;
     1961    }
     1962  else
     1963    {
    15841964      exp.X_add_number = 0;
    1585 #if CFI_DIFF_EXPR_OK
    15861965      exp.X_add_symbol = fde->start_address;
    1587       exp.X_op_symbol = symbol_temp_new_now ();
    1588       emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);  /* Code offset.  */
    1589 #else
    1590       exp.X_op = O_symbol;
    1591       exp.X_add_symbol = fde->start_address;
    1592 #ifdef tc_cfi_emit_pcrel_expr
    1593       tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE);      /* Code offset.  */
    1594 #else
    1595       emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);  /* Code offset.  */
    1596 #endif
    1597 #endif
    1598       addr_size = DWARF2_FDE_RELOC_SIZE;
    1599     }
    1600   else
    1601     {
    1602       exp.X_op = O_symbol;
    1603       exp.X_add_symbol = fde->start_address;
    1604       exp.X_add_number = 0;
    16051966      addr_size = DWARF2_ADDR_SIZE (stdoutput);
    16061967      emit_expr (&exp, addr_size);
     
    16171978    out_uleb128 (augmentation_size);            /* Augmentation size.  */
    16181979
    1619   if (fde->lsda_encoding != DW_EH_PE_omit)
    1620     {
    1621       exp = fde->lsda;
    1622       if ((fde->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
    1623         {
    1624 #if CFI_DIFF_LSDA_OK
    1625           exp.X_op = O_subtract;
    1626           exp.X_op_symbol = symbol_temp_new_now ();
    1627           emit_expr (&exp, augmentation_size);
    1628 #elif defined (tc_cfi_emit_pcrel_expr)
    1629           tc_cfi_emit_pcrel_expr (&exp, augmentation_size);
    1630 #else
    1631           abort ();
    1632 #endif
    1633         }
    1634       else
    1635         emit_expr (&exp, augmentation_size);
    1636     }
     1980  emit_expr_encoded (&fde->lsda, cie->lsda_encoding, FALSE);
    16371981
    16381982  for (; first; first = first->next)
     
    17252069            case CFI_escape:
    17262070            case CFI_val_encoded_addr:
     2071            case CFI_label:
    17272072              /* Don't bother matching these for now.  */
    17282073              goto fail;
     
    17412086              || j->insn == DW_CFA_remember_state
    17422087              || j->insn == CFI_escape
    1743               || j->insn == CFI_val_encoded_addr))
     2088              || j->insn == CFI_val_encoded_addr
     2089              || j->insn == CFI_label))
    17442090        {
    17452091          *pfirst = j;
     
    17502096    }
    17512097
    1752   cie = (struct cie_entry *) xmalloc (sizeof (struct cie_entry));
     2098  cie = XNEW (struct cie_entry);
    17532099  cie->next = cie_root;
    17542100  cie_root = cie;
     
    17652111        || i->insn == DW_CFA_remember_state
    17662112        || i->insn == CFI_escape
    1767         || i->insn == CFI_val_encoded_addr)
     2113        || i->insn == CFI_val_encoded_addr
     2114        || i->insn == CFI_label)
    17682115      break;
    17692116
     
    17922139        case DW_CFA_GNU_window_save:
    17932140        case CFI_escape:
     2141        case CFI_label:
    17942142          break;
    17952143
     
    18242172#endif
    18252173
    1826 static segT
    1827 get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
    1828 {
    1829   if (SUPPORT_FRAME_LINKONCE)
    1830     {
    1831       struct dwcfi_seg_list *l;
    1832 
    1833       l = dwcfi_hash_find_or_make (cseg, base, flags);
    1834 
    1835       cseg = l->seg;
    1836       subseg_set (cseg, l->subseg);
    1837     }
     2174#if SUPPORT_COMPACT_EH
     2175static void
     2176cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
     2177{
     2178  expressionS exp;
     2179
     2180  exp.X_add_number = addend;
     2181  exp.X_add_symbol = sym;
     2182  emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, FALSE);
     2183}
     2184
     2185static void
     2186output_eh_header (struct fde_entry *fde)
     2187{
     2188  char *p;
     2189  bfd_vma addend;
     2190
     2191  if (fde->eh_header_type == EH_COMPACT_INLINE)
     2192    addend = 0;
    18382193  else
    1839     {
    1840       cseg = subseg_new (base, 0);
    1841       bfd_set_section_flags (stdoutput, cseg, flags);
    1842     }
    1843   record_alignment (cseg, align);
    1844   return cseg;
    1845 }
     2194    addend = 1;
     2195
     2196  cfi_emit_eh_header (fde->start_address, addend);
     2197
     2198  if (fde->eh_header_type == EH_COMPACT_INLINE)
     2199    {
     2200      p = frag_more (4);
     2201      /* Inline entries always use PR1.  */
     2202      *(p++) = 1;
     2203      memcpy(p, fde->eh_data, 3);
     2204    }
     2205  else
     2206    {
     2207      if (fde->eh_header_type == EH_COMPACT_LEGACY)
     2208        addend = 1;
     2209      else if (fde->eh_header_type == EH_COMPACT_OUTLINE
     2210               || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
     2211        addend = 0;
     2212      else
     2213        abort ();
     2214      cfi_emit_eh_header (fde->eh_loc, addend);
     2215    }
     2216}
     2217#endif
    18462218
    18472219void
     
    18572229    return;
    18582230
    1859   if ((cfi_sections & CFI_EMIT_eh_frame) != 0)
     2231  cfi_sections_set = TRUE;
     2232  if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
     2233      || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
    18602234    {
    18612235      /* Make sure check_eh_frame doesn't do anything with our output.  */
     
    18632237      flag_traditional_format = 1;
    18642238
    1865       if (!SUPPORT_FRAME_LINKONCE)
     2239      if (!EH_FRAME_LINKONCE)
    18662240        {
    18672241          /* Open .eh_frame section.  */
     
    18912265          for (fde = all_fde_data; fde ; fde = fde->next)
    18922266            {
    1893               if (SUPPORT_FRAME_LINKONCE)
     2267              if ((fde->sections & CFI_EMIT_eh_frame) == 0
     2268                  && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
     2269                continue;
     2270
     2271#if SUPPORT_COMPACT_EH
     2272              /* Emit a LEGACY format header if we have processed all
     2273                 of the .cfi directives without encountering either inline or
     2274                 out-of-line compact unwinding opcodes.  */
     2275              if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
     2276                  || fde->eh_header_type == EH_COMPACT_UNKNOWN)
     2277                fde->eh_header_type = EH_COMPACT_LEGACY;
     2278
     2279              if (fde->eh_header_type != EH_COMPACT_LEGACY)
     2280                continue;
     2281#endif
     2282              if (EH_FRAME_LINKONCE)
    18942283                {
    18952284                  if (HANDLED (fde))
     
    19252314
    19262315              cie = select_cie_for_fde (fde, TRUE, &first, 2);
     2316              fde->eh_loc = symbol_temp_new_now ();
    19272317              output_fde (fde, cie, TRUE, first,
    19282318                          fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
    19292319            }
    19302320        }
    1931       while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
    1932 
    1933       if (SUPPORT_FRAME_LINKONCE)
     2321      while (EH_FRAME_LINKONCE && seek_next_seg == 2);
     2322
     2323      if (EH_FRAME_LINKONCE)
    19342324        for (fde = all_fde_data; fde ; fde = fde->next)
    19352325          SET_HANDLED (fde, 0);
    19362326
     2327#if SUPPORT_COMPACT_EH
     2328      if (compact_eh)
     2329        {
     2330          /* Create remaining out of line table entries.  */
     2331          do
     2332            {
     2333              ccseg = NULL;
     2334              seek_next_seg = 0;
     2335
     2336              for (fde = all_fde_data; fde ; fde = fde->next)
     2337                {
     2338                  if ((fde->sections & CFI_EMIT_eh_frame) == 0
     2339                      && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
     2340                    continue;
     2341
     2342                  if (fde->eh_header_type != EH_COMPACT_OUTLINE)
     2343                    continue;
     2344                  if (HANDLED (fde))
     2345                    continue;
     2346                  if (seek_next_seg && CUR_SEG (fde) != ccseg)
     2347                    {
     2348                      seek_next_seg = 2;
     2349                      continue;
     2350                    }
     2351                  if (!seek_next_seg)
     2352                    {
     2353                      ccseg = CUR_SEG (fde);
     2354                      /* Open .gnu_extab section.  */
     2355                      get_cfi_seg (ccseg, ".gnu_extab",
     2356                                   (SEC_ALLOC | SEC_LOAD | SEC_DATA
     2357                                    | DWARF2_EH_FRAME_READ_ONLY),
     2358                                   1);
     2359                      seek_next_seg = 1;
     2360                    }
     2361                  SET_HANDLED (fde, 1);
     2362
     2363                  frag_align (1, 0, 0);
     2364                  record_alignment (now_seg, 1);
     2365                  output_compact_unwind_data (fde, 1);
     2366                }
     2367            }
     2368          while (EH_FRAME_LINKONCE && seek_next_seg == 2);
     2369
     2370          for (fde = all_fde_data; fde ; fde = fde->next)
     2371            SET_HANDLED (fde, 0);
     2372
     2373          /* Create index table fragments.  */
     2374          do
     2375            {
     2376              ccseg = NULL;
     2377              seek_next_seg = 0;
     2378
     2379              for (fde = all_fde_data; fde ; fde = fde->next)
     2380                {
     2381                  if ((fde->sections & CFI_EMIT_eh_frame) == 0
     2382                      && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
     2383                    continue;
     2384
     2385                  if (HANDLED (fde))
     2386                    continue;
     2387                  if (seek_next_seg && CUR_SEG (fde) != ccseg)
     2388                    {
     2389                      seek_next_seg = 2;
     2390                      continue;
     2391                    }
     2392                  if (!seek_next_seg)
     2393                    {
     2394                      ccseg = CUR_SEG (fde);
     2395                      /* Open .eh_frame_entry section.  */
     2396                      cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
     2397                                             (SEC_ALLOC | SEC_LOAD | SEC_DATA
     2398                                              | DWARF2_EH_FRAME_READ_ONLY),
     2399                                             2);
     2400                      seek_next_seg = 1;
     2401                    }
     2402                  SET_HANDLED (fde, 1);
     2403
     2404                  output_eh_header (fde);
     2405                }
     2406            }
     2407          while (seek_next_seg == 2);
     2408
     2409          for (fde = all_fde_data; fde ; fde = fde->next)
     2410            SET_HANDLED (fde, 0);
     2411        }
     2412#endif /* SUPPORT_COMPACT_EH */
     2413
    19372414      flag_traditional_format = save_flag_traditional_format;
    19382415    }
    19392416
    1940   if ((cfi_sections & CFI_EMIT_debug_frame) != 0)
     2417  cfi_sections_set = TRUE;
     2418  if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
    19412419    {
    19422420      int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
     
    19612439          for (fde = all_fde_data; fde ; fde = fde->next)
    19622440            {
     2441              if ((fde->sections & CFI_EMIT_debug_frame) == 0)
     2442                continue;
     2443
    19632444              if (SUPPORT_FRAME_LINKONCE)
    19642445                {
     
    20182499    { "cfi_startproc", dot_cfi_dummy, 0 },
    20192500    { "cfi_endproc", dot_cfi_dummy, 0 },
     2501    { "cfi_fde_data", dot_cfi_dummy, 0 },
    20202502    { "cfi_def_cfa", dot_cfi_dummy, 0 },
    20212503    { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
     
    20352517    { "cfi_signal_frame", dot_cfi_dummy, 0 },
    20362518    { "cfi_personality", dot_cfi_dummy, 0 },
     2519    { "cfi_personality_id", dot_cfi_dummy, 0 },
    20372520    { "cfi_lsda", dot_cfi_dummy, 0 },
    20382521    { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
     2522    { "cfi_label", dot_cfi_dummy, 0 },
     2523    { "cfi_inline_lsda", dot_cfi_dummy, 0 },
    20392524    { NULL, NULL, 0 }
    20402525  };
Note: See TracChangeset for help on using the changeset viewer.