Changeset 1973 for binutils/trunk/gas/dw2gencfi.c
- Timestamp:
- Feb 6, 2017, 1:00:00 PM (8 years ago)
- Location:
- binutils/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
binutils/trunk ¶
-
Property svn:mergeinfo
set to
/binutils/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
TabularUnified binutils/trunk/gas/dw2gencfi.c ¶
r970 r1973 1 1 /* dw2gencfi.c - Support for generating Dwarf2 CFI information. 2 Copyright (C) 2003-201 4Free Software Foundation, Inc.2 Copyright (C) 2003-2016 Free Software Foundation, Inc. 3 3 Contributed by Michal Ludvig <mludvig@suse.cz> 4 4 … … 76 76 #endif 77 77 78 #define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh) 79 78 80 #ifndef DWARF2_FORMAT 79 81 #define DWARF2_FORMAT(SEC) dwarf2_format_32bit … … 84 86 #endif 85 87 86 #if SUPPORT_FRAME_LINKONCE88 #if MULTIPLE_FRAME_SECTIONS 87 89 #define CUR_SEG(structp) structp->cur_seg 88 90 #define SET_CUR_SEG(structp, seg) structp->cur_seg = seg … … 96 98 #endif 97 99 100 #ifndef tc_cfi_reloc_for_encoding 101 #define tc_cfi_reloc_for_encoding(e) BFD_RELOC_NONE 102 #endif 103 98 104 /* Private segment collection list. */ 99 105 struct dwcfi_seg_list … … 104 110 }; 105 111 106 #define FRAME_NAME ".eh_frame" 112 #ifdef SUPPORT_COMPACT_EH 113 static bfd_boolean compact_eh; 114 #else 115 #define compact_eh 0 116 #endif 107 117 108 118 static struct hash_control *dwcfi_hash; 119 120 121 /* Emit a single byte into the current segment. */ 122 123 static inline void 124 out_one (int byte) 125 { 126 FRAG_APPEND_1_CHAR (byte); 127 } 128 129 /* Emit a two-byte word into the current segment. */ 130 131 static inline void 132 out_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 139 static inline void 140 out_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 147 static void 148 out_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 155 static void 156 out_sleb128 (offsetT value) 157 { 158 output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1); 159 } 160 161 static offsetT 162 encoding_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 184 static void 185 emit_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 109 222 110 223 /* Build based on segment the derived .debug_... … … 129 242 130 243 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 } 132 251 else if (!dollar) 133 252 name = dot; … … 161 280 is_now_linkonce_segment (void) 162 281 { 282 if (compact_eh) 283 return now_seg; 284 163 285 if ((bfd_get_section_flags (stdoutput, now_seg) 164 286 & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD … … 273 395 { 274 396 struct cie_entry *next; 275 #if SUPPORT_FRAME_LINKONCE397 #if MULTIPLE_FRAME_SECTIONS 276 398 segT cur_seg; 277 399 #endif … … 279 401 unsigned int return_column; 280 402 unsigned int signal_frame; 403 unsigned char fde_encoding; 281 404 unsigned char per_encoding; 282 405 unsigned char lsda_encoding; … … 315 438 alloc_fde_entry (void) 316 439 { 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); 322 443 frchain_now->frch_cfi_data->cur_fde_data = fde; 323 444 *last_fde_data = fde; … … 329 450 fde->per_encoding = DW_EH_PE_omit; 330 451 fde->lsda_encoding = DW_EH_PE_omit; 452 fde->eh_header_type = EH_COMPACT_UNKNOWN; 331 453 332 454 return fde; … … 339 461 for the currently active FDE. */ 340 462 463 static bfd_boolean cfi_sections_set = FALSE; 464 static int cfi_sections = CFI_EMIT_eh_frame; 465 int all_cfi_sections = 0; 466 static struct fde_entry *last_fde; 467 341 468 static struct cfi_insn_data * 342 469 alloc_cfi_insn_data (void) 343 470 { 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); 346 472 struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data; 347 473 … … 380 506 } 381 507 508 void 509 cfi_set_sections (void) 510 { 511 frchain_now->frch_cfi_data->cur_fde_data->sections = all_cfi_sections; 512 cfi_sections_set = TRUE; 513 } 514 382 515 /* Universal functions to store new instructions. */ 383 516 … … 440 573 441 574 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 579 void 580 cfi_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 (¬es, name, len); 587 insn->u.sym_name = (char *) obstack_finish (¬es); 442 588 } 443 589 … … 517 663 cfi_add_CFA_insn (DW_CFA_remember_state); 518 664 519 p = (struct cfa_save_data *) xmalloc (sizeof (*p));665 p = XNEW (struct cfa_save_data); 520 666 p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset; 521 667 p->next = frchain_now->frch_cfi_data->cfa_save_stack; … … 550 696 static void dot_cfi_startproc (int); 551 697 static void dot_cfi_endproc (int); 698 static void dot_cfi_fde_data (int); 552 699 static void dot_cfi_personality (int); 700 static void dot_cfi_personality_id (int); 553 701 static void dot_cfi_lsda (int); 554 702 static void dot_cfi_val_encoded_addr (int); 703 static void dot_cfi_inline_lsda (int); 704 static void dot_cfi_label (int); 555 705 556 706 const pseudo_typeS cfi_pseudo_table[] = … … 559 709 { "cfi_startproc", dot_cfi_startproc, 0 }, 560 710 { "cfi_endproc", dot_cfi_endproc, 0 }, 711 { "cfi_fde_data", dot_cfi_fde_data, 0 }, 561 712 { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa }, 562 713 { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register }, … … 576 727 { "cfi_signal_frame", dot_cfi, CFI_signal_frame }, 577 728 { "cfi_personality", dot_cfi_personality, 0 }, 729 { "cfi_personality_id", dot_cfi_personality_id, 0 }, 578 730 { "cfi_lsda", dot_cfi_lsda, 0 }, 579 731 { "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 }, 580 734 { NULL, NULL, 0 } 581 735 }; … … 603 757 char *name, c; 604 758 605 name = input_line_pointer; 606 c = get_symbol_end (); 759 c = get_symbol_name (& name); 607 760 608 761 exp->X_op = O_constant; 609 762 exp->X_add_number = tc_regname_to_dw2regnum (name); 610 763 611 *input_line_pointer = c;764 restore_line_pointer (c); 612 765 } 613 766 else … … 796 949 do 797 950 { 798 e = (struct cfi_escape_data *) xmalloc (sizeof (*e));951 e = XNEW (struct cfi_escape_data); 799 952 do_parse_cons_expression (&e->exp, 1); 800 953 *tail = e; … … 835 988 836 989 if ((encoding & 0xff) != encoding 837 || (( encoding & 0x70) != 0990 || ((((encoding & 0x70) != 0 838 991 #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr 839 && (encoding & 0x70) != DW_EH_PE_pcrel992 && (encoding & 0x70) != DW_EH_PE_pcrel 840 993 #endif 841 994 ) 842 995 /* 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)) 845 999 { 846 1000 as_bad (_("invalid or unsupported encoding in .cfi_personality")); … … 905 1059 906 1060 if ((encoding & 0xff) != encoding 907 || (( encoding & 0x70) != 01061 || ((((encoding & 0x70) != 0 908 1062 #if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr 909 && (encoding & 0x70) != DW_EH_PE_pcrel910 #endif 911 )1063 && (encoding & 0x70) != DW_EH_PE_pcrel 1064 #endif 1065 ) 912 1066 /* 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)) 915 1070 { 916 1071 as_bad (_("invalid or unsupported encoding in .cfi_lsda")); … … 1019 1174 } 1020 1175 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; 1176 static void 1177 dot_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 } 1026 1195 1027 1196 static void … … 1031 1200 1032 1201 SKIP_WHITESPACE (); 1033 if (is_name_beginner (*input_line_pointer) )1202 if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"') 1034 1203 while (1) 1035 1204 { 1205 char * saved_ilp; 1036 1206 char *name, c; 1037 1207 1038 name= input_line_pointer;1039 c = get_symbol_ end ();1208 saved_ilp = input_line_pointer; 1209 c = get_symbol_name (& name); 1040 1210 1041 1211 if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0 … … 1044 1214 else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0) 1045 1215 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 1046 1223 #ifdef tc_cfi_section_name 1047 1224 else if (strcmp (name, tc_cfi_section_name) == 0) … … 1051 1228 { 1052 1229 *input_line_pointer = c; 1053 input_line_pointer = name;1230 input_line_pointer = saved_ilp; 1054 1231 break; 1055 1232 } 1056 1233 1057 1234 *input_line_pointer = c; 1058 SKIP_WHITESPACE ();1235 SKIP_WHITESPACE_AFTER_NAME (); 1059 1236 if (*input_line_pointer == ',') 1060 1237 { 1061 1238 name = input_line_pointer++; 1062 1239 SKIP_WHITESPACE (); 1063 if (!is_name_beginner (*input_line_pointer) )1240 if (!is_name_beginner (*input_line_pointer) && *input_line_pointer != '"') 1064 1241 { 1065 1242 input_line_pointer = name; … … 1067 1244 } 1068 1245 } 1069 else if (is_name_beginner (*input_line_pointer) )1246 else if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"') 1070 1247 break; 1071 1248 } 1072 1249 1073 1250 demand_empty_rest_of_line (); 1251 if (cfi_sections_set && cfi_sections != sections) 1252 as_bad (_("inconsistent uses of .cfi_sections")); 1074 1253 cfi_sections = sections; 1075 1254 } … … 1090 1269 1091 1270 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; 1094 1274 char *name, c; 1095 1275 1096 name = input_line_pointer; 1097 c = get_symbol_end (); 1276 c = get_symbol_name (& name); 1098 1277 1099 1278 if (strcmp (name, "simple") == 0) 1100 1279 { 1101 1280 simple = 1; 1102 *input_line_pointer = c;1281 restore_line_pointer (c); 1103 1282 } 1104 1283 else 1105 input_line_pointer = name;1284 input_line_pointer = saved_ilp; 1106 1285 } 1107 1286 demand_empty_rest_of_line (); 1108 1287 1288 cfi_sections_set = TRUE; 1289 all_cfi_sections |= cfi_sections; 1290 cfi_set_sections (); 1109 1291 frchain_now->frch_cfi_data->cur_cfa_offset = 0; 1110 1292 if (!simple) … … 1118 1300 dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED) 1119 1301 { 1120 struct fde_entry *fde;1121 1122 1302 if (frchain_now->frch_cfi_data == NULL) 1123 1303 { … … 1127 1307 } 1128 1308 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 1320 static segT 1321 get_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 1343 static void 1344 dot_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 1129 1355 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 (); 1133 1357 demand_empty_rest_of_line (); 1134 1358 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 1366 static void 1367 dot_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 1434 static void 1435 output_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. */ 1471 static void 1472 dot_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 */ 1535 static void 1536 dot_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 1542 static void 1543 dot_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 1549 static void 1550 dot_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 1180 1557 1181 1558 static void … … 1335 1712 { 1336 1713 unsigned encoding = insn->u.ea.encoding; 1337 offsetT enc oding_size;1714 offsetT enc_size; 1338 1715 1339 1716 if (encoding == DW_EH_PE_omit) … … 1345 1722 { 1346 1723 case DW_EH_PE_absptr: 1347 enc oding_size = DWARF2_ADDR_SIZE (stdoutput);1724 enc_size = DWARF2_ADDR_SIZE (stdoutput); 1348 1725 break; 1349 1726 case DW_EH_PE_udata2: 1350 enc oding_size = 2;1727 enc_size = 2; 1351 1728 break; 1352 1729 case DW_EH_PE_udata4: 1353 enc oding_size = 4;1730 enc_size = 4; 1354 1731 break; 1355 1732 case DW_EH_PE_udata8: 1356 enc oding_size = 8;1733 enc_size = 8; 1357 1734 break; 1358 1735 default: … … 1364 1741 if (insn->u.ea.encoding == DW_EH_PE_absptr) 1365 1742 { 1366 out_uleb128 (1 + enc oding_size);1743 out_uleb128 (1 + enc_size); 1367 1744 out_one (DW_OP_addr); 1368 1745 } 1369 1746 else 1370 1747 { 1371 out_uleb128 (1 + 1 + enc oding_size);1748 out_uleb128 (1 + 1 + enc_size); 1372 1749 out_one (DW_OP_GNU_encoded_addr); 1373 1750 out_one (encoding); … … 1379 1756 insn->u.ea.exp.X_op_symbol = symbol_temp_new_now (); 1380 1757 #elif defined (tc_cfi_emit_pcrel_expr) 1381 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc oding_size);1758 tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size); 1382 1759 break; 1383 1760 #else … … 1386 1763 } 1387 1764 } 1388 emit_expr (&insn->u.ea.exp, enc oding_size);1765 emit_expr (&insn->u.ea.exp, enc_size); 1389 1766 } 1390 1767 break; 1391 1768 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 1412 1773 default: 1413 1774 abort (); … … 1477 1838 out_uleb128 (augmentation_size); /* Augmentation size. */ 1478 1839 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); 1499 1841 1500 1842 if (cie->lsda_encoding != DW_EH_PE_omit) … … 1519 1861 enc |= DW_EH_PE_pcrel; 1520 1862 #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; 1521 1868 if (eh_frame) 1522 1869 out_one (enc); … … 1579 1926 } 1580 1927 1928 exp.X_op = O_symbol; 1581 1929 if (eh_frame) 1582 1930 { 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 { 1584 1964 exp.X_add_number = 0; 1585 #if CFI_DIFF_EXPR_OK1586 1965 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 #else1590 exp.X_op = O_symbol;1591 exp.X_add_symbol = fde->start_address;1592 #ifdef tc_cfi_emit_pcrel_expr1593 tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */1594 #else1595 emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */1596 #endif1597 #endif1598 addr_size = DWARF2_FDE_RELOC_SIZE;1599 }1600 else1601 {1602 exp.X_op = O_symbol;1603 exp.X_add_symbol = fde->start_address;1604 exp.X_add_number = 0;1605 1966 addr_size = DWARF2_ADDR_SIZE (stdoutput); 1606 1967 emit_expr (&exp, addr_size); … … 1617 1978 out_uleb128 (augmentation_size); /* Augmentation size. */ 1618 1979 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); 1637 1981 1638 1982 for (; first; first = first->next) … … 1725 2069 case CFI_escape: 1726 2070 case CFI_val_encoded_addr: 2071 case CFI_label: 1727 2072 /* Don't bother matching these for now. */ 1728 2073 goto fail; … … 1741 2086 || j->insn == DW_CFA_remember_state 1742 2087 || j->insn == CFI_escape 1743 || j->insn == CFI_val_encoded_addr)) 2088 || j->insn == CFI_val_encoded_addr 2089 || j->insn == CFI_label)) 1744 2090 { 1745 2091 *pfirst = j; … … 1750 2096 } 1751 2097 1752 cie = (struct cie_entry *) xmalloc (sizeof (struct cie_entry));2098 cie = XNEW (struct cie_entry); 1753 2099 cie->next = cie_root; 1754 2100 cie_root = cie; … … 1765 2111 || i->insn == DW_CFA_remember_state 1766 2112 || i->insn == CFI_escape 1767 || i->insn == CFI_val_encoded_addr) 2113 || i->insn == CFI_val_encoded_addr 2114 || i->insn == CFI_label) 1768 2115 break; 1769 2116 … … 1792 2139 case DW_CFA_GNU_window_save: 1793 2140 case CFI_escape: 2141 case CFI_label: 1794 2142 break; 1795 2143 … … 1824 2172 #endif 1825 2173 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 2175 static void 2176 cfi_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 2185 static void 2186 output_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; 1838 2193 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 1846 2218 1847 2219 void … … 1857 2229 return; 1858 2230 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) 1860 2234 { 1861 2235 /* Make sure check_eh_frame doesn't do anything with our output. */ … … 1863 2237 flag_traditional_format = 1; 1864 2238 1865 if (! SUPPORT_FRAME_LINKONCE)2239 if (!EH_FRAME_LINKONCE) 1866 2240 { 1867 2241 /* Open .eh_frame section. */ … … 1891 2265 for (fde = all_fde_data; fde ; fde = fde->next) 1892 2266 { 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) 1894 2283 { 1895 2284 if (HANDLED (fde)) … … 1925 2314 1926 2315 cie = select_cie_for_fde (fde, TRUE, &first, 2); 2316 fde->eh_loc = symbol_temp_new_now (); 1927 2317 output_fde (fde, cie, TRUE, first, 1928 2318 fde->next == NULL ? EH_FRAME_ALIGNMENT : 2); 1929 2319 } 1930 2320 } 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) 1934 2324 for (fde = all_fde_data; fde ; fde = fde->next) 1935 2325 SET_HANDLED (fde, 0); 1936 2326 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 1937 2414 flag_traditional_format = save_flag_traditional_format; 1938 2415 } 1939 2416 1940 if ((cfi_sections & CFI_EMIT_debug_frame) != 0) 2417 cfi_sections_set = TRUE; 2418 if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0) 1941 2419 { 1942 2420 int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1; … … 1961 2439 for (fde = all_fde_data; fde ; fde = fde->next) 1962 2440 { 2441 if ((fde->sections & CFI_EMIT_debug_frame) == 0) 2442 continue; 2443 1963 2444 if (SUPPORT_FRAME_LINKONCE) 1964 2445 { … … 2018 2499 { "cfi_startproc", dot_cfi_dummy, 0 }, 2019 2500 { "cfi_endproc", dot_cfi_dummy, 0 }, 2501 { "cfi_fde_data", dot_cfi_dummy, 0 }, 2020 2502 { "cfi_def_cfa", dot_cfi_dummy, 0 }, 2021 2503 { "cfi_def_cfa_register", dot_cfi_dummy, 0 }, … … 2035 2517 { "cfi_signal_frame", dot_cfi_dummy, 0 }, 2036 2518 { "cfi_personality", dot_cfi_dummy, 0 }, 2519 { "cfi_personality_id", dot_cfi_dummy, 0 }, 2037 2520 { "cfi_lsda", dot_cfi_dummy, 0 }, 2038 2521 { "cfi_val_encoded_addr", dot_cfi_dummy, 0 }, 2522 { "cfi_label", dot_cfi_dummy, 0 }, 2523 { "cfi_inline_lsda", dot_cfi_dummy, 0 }, 2039 2524 { NULL, NULL, 0 } 2040 2525 };
Note:
See TracChangeset
for help on using the changeset viewer.