diff options
Diffstat (limited to 'bfd/elflink.h')
-rw-r--r-- | bfd/elflink.h | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/bfd/elflink.h b/bfd/elflink.h index 76dbb19..7fd8b53 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -3029,7 +3029,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, struct bfd_elf_version_tree *verdefs; { bfd_size_type soname_indx; - bfd *dynobj; + bfd *dynobj, *sub; + asection *o; + int need_preinit_array = 0, need_init_array = 0, need_fini_array = 0; struct elf_backend_data *bed; struct elf_assign_sym_version_info asvinfo; @@ -3200,6 +3202,43 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, return false; } + for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (o = sub->sections; o != NULL; o = o->next) + { + /* yuck, more matching by name... */ + + if (strcmp (bfd_section_name (sub, o), ".preinit_array") == 0) + need_preinit_array = 1; + if (strcmp (bfd_section_name (sub, o), ".init_array") == 0) + need_init_array = 1; + if (strcmp (bfd_section_name (sub, o), ".fini_array") == 0) + need_fini_array = 1; + } + if (need_preinit_array) + { + if (!elf_add_dynamic_entry (info, (bfd_vma) DT_PREINIT_ARRAY, + (bfd_vma) 0) + || !elf_add_dynamic_entry (info, (bfd_vma) DT_PREINIT_ARRAYSZ, + (bfd_vma) 0)) + return false; + } + if (need_init_array) + { + if (!elf_add_dynamic_entry (info, (bfd_vma) DT_INIT_ARRAY, + (bfd_vma) 0) + || !elf_add_dynamic_entry (info, (bfd_vma) DT_INIT_ARRAYSZ, + (bfd_vma) 0)) + return false; + } + if (need_fini_array) + { + if (!elf_add_dynamic_entry (info, (bfd_vma) DT_FINI_ARRAY, + (bfd_vma) 0) + || !elf_add_dynamic_entry (info, (bfd_vma) DT_FINI_ARRAYSZ, + (bfd_vma) 0)) + return false; + } + dynstr = bfd_get_section_by_name (dynobj, ".dynstr"); /* If .dynstr is excluded from the link, we don't want any of these tags. Strictly, we should be checking each section @@ -5550,6 +5589,31 @@ elf_bfd_final_link (abfd, info) } break; + case DT_PREINIT_ARRAYSZ: + name = ".preinit_array"; + goto get_size; + case DT_INIT_ARRAYSZ: + name = ".init_array"; + goto get_size; + case DT_FINI_ARRAYSZ: + name = ".fini_array"; + get_size: + o = bfd_get_section_by_name (abfd, name); + BFD_ASSERT (o != NULL); + dyn.d_un.d_val = o->_raw_size; + elf_swap_dyn_out (dynobj, &dyn, dyncon); + break; + + case DT_PREINIT_ARRAY: + name = ".preinit_array"; + goto get_vma; + case DT_INIT_ARRAY: + name = ".init_array"; + goto get_vma; + case DT_FINI_ARRAY: + name = ".fini_array"; + goto get_vma; + case DT_HASH: name = ".hash"; goto get_vma; |