| OLD | NEW |
| 1 /* .eh_frame section optimization. | 1 /* .eh_frame section optimization. |
| 2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, |
| 3 Free Software Foundation, Inc. | 3 2012 Free Software Foundation, Inc. |
| 4 Written by Jakub Jelinek <jakub@redhat.com>. | 4 Written by Jakub Jelinek <jakub@redhat.com>. |
| 5 | 5 |
| 6 This file is part of BFD, the Binary File Descriptor library. | 6 This file is part of BFD, the Binary File Descriptor library. |
| 7 | 7 |
| 8 This program is free software; you can redistribute it and/or modify | 8 This program is free software; you can redistribute it and/or modify |
| 9 it under the terms of the GNU General Public License as published by | 9 it under the terms of the GNU General Public License as published by |
| 10 the Free Software Foundation; either version 3 of the License, or | 10 the Free Software Foundation; either version 3 of the License, or |
| 11 (at your option) any later version. | 11 (at your option) any later version. |
| 12 | 12 |
| 13 This program is distributed in the hope that it will be useful, | 13 This program is distributed in the hope that it will be useful, |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 unsigned int num_cies; | 484 unsigned int num_cies; |
| 485 unsigned int num_entries; | 485 unsigned int num_entries; |
| 486 elf_gc_mark_hook_fn gc_mark_hook; | 486 elf_gc_mark_hook_fn gc_mark_hook; |
| 487 | 487 |
| 488 htab = elf_hash_table (info); | 488 htab = elf_hash_table (info); |
| 489 hdr_info = &htab->eh_info; | 489 hdr_info = &htab->eh_info; |
| 490 if (hdr_info->parsed_eh_frames) | 490 if (hdr_info->parsed_eh_frames) |
| 491 return; | 491 return; |
| 492 | 492 |
| 493 if (sec->size == 0 | 493 if (sec->size == 0 |
| 494 || sec->sec_info_type != ELF_INFO_TYPE_NONE) | 494 || sec->sec_info_type != SEC_INFO_TYPE_NONE) |
| 495 { | 495 { |
| 496 /* This file does not contain .eh_frame information. */ | 496 /* This file does not contain .eh_frame information. */ |
| 497 return; | 497 return; |
| 498 } | 498 } |
| 499 | 499 |
| 500 if (bfd_is_abs_section (sec->output_section)) | 500 if (bfd_is_abs_section (sec->output_section)) |
| 501 { | 501 { |
| 502 /* At least one of the sections is being discarded from the | 502 /* At least one of the sections is being discarded from the |
| 503 link, so we should just ignore them. */ | 503 link, so we should just ignore them. */ |
| 504 return; | 504 return; |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 | 897 |
| 898 this_inf->removed = 1; | 898 this_inf->removed = 1; |
| 899 this_inf->fde_encoding = cie->fde_encoding; | 899 this_inf->fde_encoding = cie->fde_encoding; |
| 900 this_inf->lsda_encoding = cie->lsda_encoding; | 900 this_inf->lsda_encoding = cie->lsda_encoding; |
| 901 sec_info->count++; | 901 sec_info->count++; |
| 902 } | 902 } |
| 903 BFD_ASSERT (sec_info->count == num_entries); | 903 BFD_ASSERT (sec_info->count == num_entries); |
| 904 BFD_ASSERT (cie_count == num_cies); | 904 BFD_ASSERT (cie_count == num_cies); |
| 905 | 905 |
| 906 elf_section_data (sec)->sec_info = sec_info; | 906 elf_section_data (sec)->sec_info = sec_info; |
| 907 sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME; | 907 sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME; |
| 908 if (hdr_info->merge_cies) | 908 if (hdr_info->merge_cies) |
| 909 { | 909 { |
| 910 sec_info->cies = local_cies; | 910 sec_info->cies = local_cies; |
| 911 local_cies = NULL; | 911 local_cies = NULL; |
| 912 } | 912 } |
| 913 goto success; | 913 goto success; |
| 914 | 914 |
| 915 free_no_table: | 915 free_no_table: |
| 916 (*info->callbacks->einfo) | 916 (*info->callbacks->einfo) |
| 917 (_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"), | 917 (_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"), |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 _bfd_elf_discard_section_eh_frame | 1130 _bfd_elf_discard_section_eh_frame |
| 1131 (bfd *abfd, struct bfd_link_info *info, asection *sec, | 1131 (bfd *abfd, struct bfd_link_info *info, asection *sec, |
| 1132 bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *), | 1132 bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *), |
| 1133 struct elf_reloc_cookie *cookie) | 1133 struct elf_reloc_cookie *cookie) |
| 1134 { | 1134 { |
| 1135 struct eh_cie_fde *ent; | 1135 struct eh_cie_fde *ent; |
| 1136 struct eh_frame_sec_info *sec_info; | 1136 struct eh_frame_sec_info *sec_info; |
| 1137 struct eh_frame_hdr_info *hdr_info; | 1137 struct eh_frame_hdr_info *hdr_info; |
| 1138 unsigned int ptr_size, offset; | 1138 unsigned int ptr_size, offset; |
| 1139 | 1139 |
| 1140 if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) | 1140 if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME) |
| 1141 return FALSE; | 1141 return FALSE; |
| 1142 | 1142 |
| 1143 sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; | 1143 sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; |
| 1144 if (sec_info == NULL) | 1144 if (sec_info == NULL) |
| 1145 return FALSE; | 1145 return FALSE; |
| 1146 | 1146 |
| 1147 ptr_size = (get_elf_backend_data (sec->owner) | 1147 ptr_size = (get_elf_backend_data (sec->owner) |
| 1148 ->elf_backend_eh_frame_address_size (sec->owner, sec)); | 1148 ->elf_backend_eh_frame_address_size (sec->owner, sec)); |
| 1149 | 1149 |
| 1150 hdr_info = &elf_hash_table (info)->eh_info; | 1150 hdr_info = &elf_hash_table (info)->eh_info; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 return FALSE; | 1240 return FALSE; |
| 1241 | 1241 |
| 1242 sec->size = EH_FRAME_HDR_SIZE; | 1242 sec->size = EH_FRAME_HDR_SIZE; |
| 1243 if (hdr_info->table) | 1243 if (hdr_info->table) |
| 1244 sec->size += 4 + hdr_info->fde_count * 8; | 1244 sec->size += 4 + hdr_info->fde_count * 8; |
| 1245 | 1245 |
| 1246 elf_tdata (abfd)->eh_frame_hdr = sec; | 1246 elf_tdata (abfd)->eh_frame_hdr = sec; |
| 1247 return TRUE; | 1247 return TRUE; |
| 1248 } | 1248 } |
| 1249 | 1249 |
| 1250 /* Return true if there is at least one non-empty .eh_frame section in |
| 1251 input files. Can only be called after ld has mapped input to |
| 1252 output sections, and before sections are stripped. */ |
| 1253 bfd_boolean |
| 1254 _bfd_elf_eh_frame_present (struct bfd_link_info *info) |
| 1255 { |
| 1256 asection *eh = bfd_get_section_by_name (info->output_bfd, ".eh_frame"); |
| 1257 |
| 1258 if (eh == NULL) |
| 1259 return FALSE; |
| 1260 |
| 1261 /* Count only sections which have at least a single CIE or FDE. |
| 1262 There cannot be any CIE or FDE <= 8 bytes. */ |
| 1263 for (eh = eh->map_head.s; eh != NULL; eh = eh->map_head.s) |
| 1264 if (eh->size > 8) |
| 1265 return TRUE; |
| 1266 |
| 1267 return FALSE; |
| 1268 } |
| 1269 |
| 1250 /* This function is called from size_dynamic_sections. | 1270 /* This function is called from size_dynamic_sections. |
| 1251 It needs to decide whether .eh_frame_hdr should be output or not, | 1271 It needs to decide whether .eh_frame_hdr should be output or not, |
| 1252 because when the dynamic symbol table has been sized it is too late | 1272 because when the dynamic symbol table has been sized it is too late |
| 1253 to strip sections. */ | 1273 to strip sections. */ |
| 1254 | 1274 |
| 1255 bfd_boolean | 1275 bfd_boolean |
| 1256 _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) | 1276 _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) |
| 1257 { | 1277 { |
| 1258 asection *o; | |
| 1259 bfd *abfd; | |
| 1260 struct elf_link_hash_table *htab; | 1278 struct elf_link_hash_table *htab; |
| 1261 struct eh_frame_hdr_info *hdr_info; | 1279 struct eh_frame_hdr_info *hdr_info; |
| 1262 | 1280 |
| 1263 htab = elf_hash_table (info); | 1281 htab = elf_hash_table (info); |
| 1264 hdr_info = &htab->eh_info; | 1282 hdr_info = &htab->eh_info; |
| 1265 if (hdr_info->hdr_sec == NULL) | 1283 if (hdr_info->hdr_sec == NULL) |
| 1266 return TRUE; | 1284 return TRUE; |
| 1267 | 1285 |
| 1268 if (bfd_is_abs_section (hdr_info->hdr_sec->output_section)) | 1286 if (bfd_is_abs_section (hdr_info->hdr_sec->output_section) |
| 1269 { | 1287 || !info->eh_frame_hdr |
| 1270 hdr_info->hdr_sec = NULL; | 1288 || !_bfd_elf_eh_frame_present (info)) |
| 1271 return TRUE; | |
| 1272 } | |
| 1273 | |
| 1274 abfd = NULL; | |
| 1275 if (info->eh_frame_hdr) | |
| 1276 for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) | |
| 1277 { | |
| 1278 » /* Count only sections which have at least a single CIE or FDE. | |
| 1279 » There cannot be any CIE or FDE <= 8 bytes. */ | |
| 1280 » o = bfd_get_section_by_name (abfd, ".eh_frame"); | |
| 1281 » if (o && o->size > 8 && !bfd_is_abs_section (o->output_section)) | |
| 1282 » break; | |
| 1283 } | |
| 1284 | |
| 1285 if (abfd == NULL) | |
| 1286 { | 1289 { |
| 1287 hdr_info->hdr_sec->flags |= SEC_EXCLUDE; | 1290 hdr_info->hdr_sec->flags |= SEC_EXCLUDE; |
| 1288 hdr_info->hdr_sec = NULL; | 1291 hdr_info->hdr_sec = NULL; |
| 1289 return TRUE; | 1292 return TRUE; |
| 1290 } | 1293 } |
| 1291 | 1294 |
| 1292 hdr_info->table = TRUE; | 1295 hdr_info->table = TRUE; |
| 1293 return TRUE; | 1296 return TRUE; |
| 1294 } | 1297 } |
| 1295 | 1298 |
| 1296 /* Adjust an address in the .eh_frame section. Given OFFSET within | 1299 /* Adjust an address in the .eh_frame section. Given OFFSET within |
| 1297 SEC, this returns the new offset in the adjusted .eh_frame section, | 1300 SEC, this returns the new offset in the adjusted .eh_frame section, |
| 1298 or -1 if the address refers to a CIE/FDE which has been removed | 1301 or -1 if the address refers to a CIE/FDE which has been removed |
| 1299 or to offset with dynamic relocation which is no longer needed. */ | 1302 or to offset with dynamic relocation which is no longer needed. */ |
| 1300 | 1303 |
| 1301 bfd_vma | 1304 bfd_vma |
| 1302 _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, | 1305 _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, |
| 1303 struct bfd_link_info *info ATTRIBUTE_UNUSED, | 1306 struct bfd_link_info *info ATTRIBUTE_UNUSED, |
| 1304 asection *sec, | 1307 asection *sec, |
| 1305 bfd_vma offset) | 1308 bfd_vma offset) |
| 1306 { | 1309 { |
| 1307 struct eh_frame_sec_info *sec_info; | 1310 struct eh_frame_sec_info *sec_info; |
| 1308 unsigned int lo, hi, mid; | 1311 unsigned int lo, hi, mid; |
| 1309 | 1312 |
| 1310 if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) | 1313 if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME) |
| 1311 return offset; | 1314 return offset; |
| 1312 sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; | 1315 sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; |
| 1313 | 1316 |
| 1314 if (offset >= sec->rawsize) | 1317 if (offset >= sec->rawsize) |
| 1315 return offset - sec->rawsize + sec->size; | 1318 return offset - sec->rawsize + sec->size; |
| 1316 | 1319 |
| 1317 lo = 0; | 1320 lo = 0; |
| 1318 hi = sec_info->count; | 1321 hi = sec_info->count; |
| 1319 mid = 0; | 1322 mid = 0; |
| 1320 while (lo < hi) | 1323 while (lo < hi) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1388 struct bfd_link_info *info, | 1391 struct bfd_link_info *info, |
| 1389 asection *sec, | 1392 asection *sec, |
| 1390 bfd_byte *contents) | 1393 bfd_byte *contents) |
| 1391 { | 1394 { |
| 1392 struct eh_frame_sec_info *sec_info; | 1395 struct eh_frame_sec_info *sec_info; |
| 1393 struct elf_link_hash_table *htab; | 1396 struct elf_link_hash_table *htab; |
| 1394 struct eh_frame_hdr_info *hdr_info; | 1397 struct eh_frame_hdr_info *hdr_info; |
| 1395 unsigned int ptr_size; | 1398 unsigned int ptr_size; |
| 1396 struct eh_cie_fde *ent; | 1399 struct eh_cie_fde *ent; |
| 1397 | 1400 |
| 1398 if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) | 1401 if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME) |
| 1399 /* FIXME: octets_per_byte. */ | 1402 /* FIXME: octets_per_byte. */ |
| 1400 return bfd_set_section_contents (abfd, sec->output_section, contents, | 1403 return bfd_set_section_contents (abfd, sec->output_section, contents, |
| 1401 sec->output_offset, sec->size); | 1404 sec->output_offset, sec->size); |
| 1402 | 1405 |
| 1403 ptr_size = (get_elf_backend_data (abfd) | 1406 ptr_size = (get_elf_backend_data (abfd) |
| 1404 ->elf_backend_eh_frame_address_size (abfd, sec)); | 1407 ->elf_backend_eh_frame_address_size (abfd, sec)); |
| 1405 BFD_ASSERT (ptr_size != 0); | 1408 BFD_ASSERT (ptr_size != 0); |
| 1406 | 1409 |
| 1407 sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; | 1410 sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; |
| 1408 htab = elf_hash_table (info); | 1411 htab = elf_hash_table (info); |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1864 _bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED, | 1867 _bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED, |
| 1865 struct bfd_link_info *info ATTRIBUTE_UNUSED, | 1868 struct bfd_link_info *info ATTRIBUTE_UNUSED, |
| 1866 asection *osec, bfd_vma offset, | 1869 asection *osec, bfd_vma offset, |
| 1867 asection *loc_sec, bfd_vma loc_offset, | 1870 asection *loc_sec, bfd_vma loc_offset, |
| 1868 bfd_vma *encoded) | 1871 bfd_vma *encoded) |
| 1869 { | 1872 { |
| 1870 *encoded = osec->vma + offset - | 1873 *encoded = osec->vma + offset - |
| 1871 (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset); | 1874 (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset); |
| 1872 return DW_EH_PE_pcrel | DW_EH_PE_sdata4; | 1875 return DW_EH_PE_pcrel | DW_EH_PE_sdata4; |
| 1873 } | 1876 } |
| OLD | NEW |