00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "safe-ctype.h"
00028
00029 static bfd_boolean elf_link_add_object_symbols (bfd *, struct bfd_link_info *);
00030 static bfd_boolean elf_finalize_dynstr (bfd *, struct bfd_link_info *);
00031 static bfd_boolean elf_collect_hash_codes (struct elf_link_hash_entry *,
00032 void *);
00033 static bfd_boolean elf_section_ignore_discarded_relocs (asection *);
00034
00035 #define SHN_IPA_TEXT 0xff01
00036 #define SHN_IPA_DATA 0xff02
00037
00038 int ld_set_ndx (bfd *abfd) __attribute__((weak));
00039
00040 int
00041 ld_set_ndx (bfd *abfd)
00042 {
00043 (void) abfd;
00044 return 0;
00045 }
00046
00047
00048
00049
00050 bfd_boolean
00051 elf_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
00052 {
00053 switch (bfd_get_format (abfd))
00054 {
00055 case bfd_object:
00056 return elf_link_add_object_symbols (abfd, info);
00057 case bfd_archive:
00058 return _bfd_elf_link_add_archive_symbols (abfd, info);
00059 default:
00060 bfd_set_error (bfd_error_wrong_format);
00061 return FALSE;
00062 }
00063 }
00064
00065
00066 static int
00067 sort_symbol (const void *arg1, const void *arg2)
00068 {
00069 const struct elf_link_hash_entry *h1
00070 = *(const struct elf_link_hash_entry **) arg1;
00071 const struct elf_link_hash_entry *h2
00072 = *(const struct elf_link_hash_entry **) arg2;
00073 bfd_signed_vma vdiff = h1->root.u.def.value - h2->root.u.def.value;
00074
00075 if (vdiff)
00076 return vdiff > 0 ? 1 : -1;
00077 else
00078 {
00079 long sdiff = h1->root.u.def.section - h2->root.u.def.section;
00080 if (sdiff)
00081 return sdiff > 0 ? 1 : -1;
00082 else
00083 return 0;
00084 }
00085 }
00086
00087
00088
00089 static bfd_boolean
00090 elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
00091 {
00092 bfd_boolean (*add_symbol_hook)
00093 (bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
00094 const char **, flagword *, asection **, bfd_vma *);
00095 bfd_boolean (*check_relocs)
00096 (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
00097 bfd_boolean collect;
00098 Elf_Internal_Shdr *hdr;
00099 bfd_size_type symcount;
00100 bfd_size_type extsymcount;
00101 bfd_size_type extsymoff;
00102 struct elf_link_hash_entry **sym_hash;
00103 bfd_boolean dynamic;
00104 Elf_External_Versym *extversym = NULL;
00105 Elf_External_Versym *ever;
00106 struct elf_link_hash_entry *weaks;
00107 struct elf_link_hash_entry **nondeflt_vers = NULL;
00108 bfd_size_type nondeflt_vers_cnt = 0;
00109 Elf_Internal_Sym *isymbuf = NULL;
00110 Elf_Internal_Sym *isym;
00111 Elf_Internal_Sym *isymend;
00112 const struct elf_backend_data *bed;
00113 bfd_boolean dt_needed;
00114 struct elf_link_hash_table * hash_table;
00115 bfd_size_type amt;
00116
00117 hash_table = elf_hash_table (info);
00118
00119 bed = get_elf_backend_data (abfd);
00120 add_symbol_hook = bed->elf_add_symbol_hook;
00121 collect = bed->collect;
00122
00123 if ((abfd->flags & DYNAMIC) == 0)
00124 dynamic = FALSE;
00125 else
00126 {
00127 dynamic = TRUE;
00128
00129
00130
00131
00132 if (info->relocatable
00133 || !is_elf_hash_table (hash_table)
00134 || hash_table->root.creator != abfd->xvec)
00135 {
00136 bfd_set_error (bfd_error_invalid_operation);
00137 goto error_return;
00138 }
00139 }
00140
00141
00142
00143
00144
00145 if (info->executable)
00146 {
00147 asection *s;
00148
00149 for (s = abfd->sections; s != NULL; s = s->next)
00150 {
00151 const char *name;
00152
00153 name = bfd_get_section_name (abfd, s);
00154 if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0)
00155 {
00156 char *msg;
00157 bfd_size_type sz;
00158 bfd_size_type prefix_len;
00159 const char * gnu_warning_prefix = _("warning: ");
00160
00161 name += sizeof ".gnu.warning." - 1;
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 if (dynamic)
00173 {
00174 struct elf_link_hash_entry *h;
00175
00176 h = elf_link_hash_lookup (hash_table, name,
00177 FALSE, FALSE, TRUE);
00178
00179
00180 if (h != NULL
00181 && (h->root.type == bfd_link_hash_defined
00182 || h->root.type == bfd_link_hash_defweak))
00183 {
00184
00185
00186
00187 s->_raw_size = 0;
00188 continue;
00189 }
00190 }
00191
00192 sz = bfd_section_size (abfd, s);
00193 prefix_len = strlen (gnu_warning_prefix);
00194 msg = bfd_alloc (abfd, prefix_len + sz + 1);
00195 if (msg == NULL)
00196 goto error_return;
00197
00198 strcpy (msg, gnu_warning_prefix);
00199 if (! bfd_get_section_contents (abfd, s, msg + prefix_len, 0, sz))
00200 goto error_return;
00201
00202 msg[prefix_len + sz] = '\0';
00203
00204 if (! (_bfd_generic_link_add_one_symbol
00205 (info, abfd, name, BSF_WARNING, s, 0, msg,
00206 FALSE, collect, NULL)))
00207 goto error_return;
00208
00209 if (! info->relocatable)
00210 {
00211
00212
00213 s->_raw_size = 0;
00214 }
00215 }
00216 }
00217 }
00218
00219 dt_needed = FALSE;
00220 if (! dynamic)
00221 {
00222
00223
00224
00225
00226
00227 if (info->shared
00228 && is_elf_hash_table (hash_table)
00229 && hash_table->root.creator == abfd->xvec
00230 && ! hash_table->dynamic_sections_created)
00231 {
00232 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
00233 goto error_return;
00234 }
00235 }
00236 else if (!is_elf_hash_table (hash_table))
00237 goto error_return;
00238 else
00239 {
00240 asection *s;
00241 bfd_boolean add_needed;
00242 const char *name;
00243 bfd_size_type oldsize;
00244 bfd_size_type strindex;
00245 struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
00246
00247
00248
00249
00250 if ((s = abfd->sections) != NULL
00251 && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
00252 goto error_return;
00253
00254
00255
00256
00257
00258
00259
00260
00261 add_needed = TRUE;
00262 name = bfd_get_filename (abfd);
00263 if (elf_dt_name (abfd) != NULL)
00264 {
00265 name = elf_dt_name (abfd);
00266 if (*name == '\0')
00267 {
00268 if (elf_dt_soname (abfd) != NULL)
00269 dt_needed = TRUE;
00270
00271 add_needed = FALSE;
00272 }
00273 }
00274 s = bfd_get_section_by_name (abfd, ".dynamic");
00275 if (s != NULL)
00276 {
00277 Elf_External_Dyn *dynbuf = NULL;
00278 Elf_External_Dyn *extdyn;
00279 Elf_External_Dyn *extdynend;
00280 int elfsec;
00281 unsigned long shlink;
00282
00283 dynbuf = bfd_malloc (s->_raw_size);
00284 if (dynbuf == NULL)
00285 goto error_return;
00286
00287 if (! bfd_get_section_contents (abfd, s, dynbuf, 0, s->_raw_size))
00288 goto error_free_dyn;
00289
00290 elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
00291 if (elfsec == -1)
00292 goto error_free_dyn;
00293 shlink = elf_elfsections (abfd)[elfsec]->sh_link;
00294
00295 extdyn = dynbuf;
00296 extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn);
00297 for (; extdyn < extdynend; extdyn++)
00298 {
00299 Elf_Internal_Dyn dyn;
00300
00301 elf_swap_dyn_in (abfd, extdyn, &dyn);
00302 if (dyn.d_tag == DT_SONAME)
00303 {
00304 unsigned int tagv = dyn.d_un.d_val;
00305 name = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
00306 if (name == NULL)
00307 goto error_free_dyn;
00308 }
00309 if (dyn.d_tag == DT_NEEDED)
00310 {
00311 struct bfd_link_needed_list *n, **pn;
00312 char *fnm, *anm;
00313 unsigned int tagv = dyn.d_un.d_val;
00314
00315 amt = sizeof (struct bfd_link_needed_list);
00316 n = bfd_alloc (abfd, amt);
00317 fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
00318 if (n == NULL || fnm == NULL)
00319 goto error_free_dyn;
00320 amt = strlen (fnm) + 1;
00321 anm = bfd_alloc (abfd, amt);
00322 if (anm == NULL)
00323 goto error_free_dyn;
00324 memcpy (anm, fnm, amt);
00325 n->name = anm;
00326 n->by = abfd;
00327 n->next = NULL;
00328 for (pn = & hash_table->needed;
00329 *pn != NULL;
00330 pn = &(*pn)->next)
00331 ;
00332 *pn = n;
00333 }
00334 if (dyn.d_tag == DT_RUNPATH)
00335 {
00336 struct bfd_link_needed_list *n, **pn;
00337 char *fnm, *anm;
00338 unsigned int tagv = dyn.d_un.d_val;
00339
00340 amt = sizeof (struct bfd_link_needed_list);
00341 n = bfd_alloc (abfd, amt);
00342 fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
00343 if (n == NULL || fnm == NULL)
00344 goto error_free_dyn;
00345 amt = strlen (fnm) + 1;
00346 anm = bfd_alloc (abfd, amt);
00347 if (anm == NULL)
00348 goto error_free_dyn;
00349 memcpy (anm, fnm, amt);
00350 n->name = anm;
00351 n->by = abfd;
00352 n->next = NULL;
00353 for (pn = & runpath;
00354 *pn != NULL;
00355 pn = &(*pn)->next)
00356 ;
00357 *pn = n;
00358 }
00359
00360 if (!runpath && dyn.d_tag == DT_RPATH)
00361 {
00362 struct bfd_link_needed_list *n, **pn;
00363 char *fnm, *anm;
00364 unsigned int tagv = dyn.d_un.d_val;
00365
00366 amt = sizeof (struct bfd_link_needed_list);
00367 n = bfd_alloc (abfd, amt);
00368 fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
00369 if (n == NULL || fnm == NULL)
00370 goto error_free_dyn;
00371 amt = strlen (fnm) + 1;
00372 anm = bfd_alloc (abfd, amt);
00373 if (anm == NULL)
00374 {
00375 error_free_dyn:
00376 free (dynbuf);
00377 goto error_return;
00378 }
00379 memcpy (anm, fnm, amt);
00380 n->name = anm;
00381 n->by = abfd;
00382 n->next = NULL;
00383 for (pn = & rpath;
00384 *pn != NULL;
00385 pn = &(*pn)->next)
00386 ;
00387 *pn = n;
00388 }
00389 }
00390
00391 free (dynbuf);
00392 }
00393
00394
00395
00396 if (runpath)
00397 rpath = runpath;
00398
00399 if (rpath)
00400 {
00401 struct bfd_link_needed_list **pn;
00402 for (pn = & hash_table->runpath;
00403 *pn != NULL;
00404 pn = &(*pn)->next)
00405 ;
00406 *pn = rpath;
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416 bfd_section_list_clear (abfd);
00417
00418
00419
00420 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
00421 goto error_return;
00422
00423 if (add_needed)
00424 {
00425
00426 oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
00427 strindex = _bfd_elf_strtab_add (hash_table->dynstr, name, FALSE);
00428 if (strindex == (bfd_size_type) -1)
00429 goto error_return;
00430
00431 if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
00432 {
00433 asection *sdyn;
00434 Elf_External_Dyn *dyncon, *dynconend;
00435
00436
00437
00438
00439
00440
00441 sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
00442 BFD_ASSERT (sdyn != NULL);
00443
00444 dyncon = (Elf_External_Dyn *) sdyn->contents;
00445 dynconend = (Elf_External_Dyn *) (sdyn->contents +
00446 sdyn->_raw_size);
00447 for (; dyncon < dynconend; dyncon++)
00448 {
00449 Elf_Internal_Dyn dyn;
00450
00451 elf_swap_dyn_in (hash_table->dynobj, dyncon, & dyn);
00452 if (dyn.d_tag == DT_NEEDED
00453 && dyn.d_un.d_val == strindex)
00454 {
00455 _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
00456 return TRUE;
00457 }
00458 }
00459 }
00460
00461 if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
00462 goto error_return;
00463 }
00464
00465
00466
00467 if (*name == '\0')
00468 name = basename (bfd_get_filename (abfd));
00469 elf_dt_name (abfd) = name;
00470 }
00471
00472
00473
00474
00475
00476
00477 if (! dynamic || elf_dynsymtab (abfd) == 0)
00478 hdr = &elf_tdata (abfd)->symtab_hdr;
00479 else
00480 hdr = &elf_tdata (abfd)->dynsymtab_hdr;
00481
00482 symcount = hdr->sh_size / sizeof (Elf_External_Sym);
00483
00484
00485
00486
00487 if (elf_bad_symtab (abfd))
00488 {
00489 extsymcount = symcount;
00490 extsymoff = 0;
00491 }
00492 else
00493 {
00494 extsymcount = symcount - hdr->sh_info;
00495 extsymoff = hdr->sh_info;
00496 }
00497
00498 sym_hash = NULL;
00499 if (extsymcount != 0)
00500 {
00501 isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
00502 NULL, NULL, NULL);
00503 if (isymbuf == NULL)
00504 goto error_return;
00505
00506
00507
00508 amt = extsymcount * sizeof (struct elf_link_hash_entry *);
00509 sym_hash = bfd_alloc (abfd, amt);
00510 if (sym_hash == NULL)
00511 goto error_free_sym;
00512 elf_sym_hashes (abfd) = sym_hash;
00513 }
00514
00515 if (dynamic)
00516 {
00517
00518 if (! _bfd_elf_slurp_version_tables (abfd))
00519 goto error_free_sym;
00520
00521
00522
00523 if (elf_dynversym (abfd) != 0)
00524 {
00525 Elf_Internal_Shdr *versymhdr;
00526
00527 versymhdr = &elf_tdata (abfd)->dynversym_hdr;
00528 extversym = bfd_malloc (versymhdr->sh_size);
00529 if (extversym == NULL)
00530 goto error_free_sym;
00531 amt = versymhdr->sh_size;
00532 if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
00533 || bfd_bread (extversym, amt, abfd) != amt)
00534 goto error_free_vers;
00535 }
00536 }
00537
00538 weaks = NULL;
00539
00540 ever = extversym != NULL ? extversym + extsymoff : NULL;
00541 for (isym = isymbuf, isymend = isymbuf + extsymcount;
00542 isym < isymend;
00543 isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
00544 {
00545 int bind;
00546 bfd_vma value;
00547 asection *sec;
00548 flagword flags;
00549 const char *name;
00550 struct elf_link_hash_entry *h;
00551 bfd_boolean definition;
00552 bfd_boolean size_change_ok;
00553 bfd_boolean type_change_ok;
00554 bfd_boolean new_weakdef;
00555 bfd_boolean override;
00556 unsigned int old_alignment;
00557 bfd *old_bfd;
00558
00559 override = FALSE;
00560
00561 flags = BSF_NO_FLAGS;
00562 sec = NULL;
00563 value = isym->st_value;
00564 *sym_hash = NULL;
00565
00566 bind = ELF_ST_BIND (isym->st_info);
00567 if (bind == STB_LOCAL)
00568 {
00569
00570
00571
00572
00573 continue;
00574 }
00575 else if (bind == STB_GLOBAL)
00576 {
00577 if (isym->st_shndx != SHN_UNDEF
00578 && isym->st_shndx != SHN_COMMON)
00579 flags = BSF_GLOBAL;
00580 }
00581 else if (bind == STB_WEAK)
00582 flags = BSF_WEAK;
00583 else
00584 {
00585
00586 }
00587
00588 if (isym->st_shndx == SHN_UNDEF)
00589 sec = bfd_und_section_ptr;
00590 else if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
00591 {
00592 sec = section_from_elf_index (abfd, isym->st_shndx);
00593 if (sec == NULL)
00594 sec = bfd_abs_section_ptr;
00595 else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
00596 value -= sec->vma;
00597 }
00598 else if (isym->st_shndx == SHN_ABS)
00599 sec = bfd_abs_section_ptr;
00600 else if (isym->st_shndx == SHN_COMMON)
00601 {
00602 sec = bfd_com_section_ptr;
00603
00604
00605 value = isym->st_size;
00606 }
00607 else if (isym->st_shndx == SHN_IPA_TEXT)
00608 sec = bfd_whirl_text_section_ptr;
00609 else if (isym->st_shndx == SHN_IPA_DATA)
00610 sec = bfd_whirl_data_section_ptr;
00611 else
00612 {
00613
00614 }
00615
00616 name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
00617 isym->st_name);
00618 if (name == NULL)
00619 goto error_free_vers;
00620
00621 if (isym->st_shndx == SHN_COMMON
00622 && ELF_ST_TYPE (isym->st_info) == STT_TLS)
00623 {
00624 asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
00625
00626 if (tcomm == NULL)
00627 {
00628 tcomm = bfd_make_section (abfd, ".tcommon");
00629 if (tcomm == NULL
00630 || !bfd_set_section_flags (abfd, tcomm, (SEC_ALLOC
00631 | SEC_IS_COMMON
00632 | SEC_LINKER_CREATED
00633 | SEC_THREAD_LOCAL)))
00634 goto error_free_vers;
00635 }
00636 sec = tcomm;
00637 }
00638 else if (add_symbol_hook)
00639 {
00640 if (! (*add_symbol_hook) (abfd, info, isym, &name, &flags, &sec,
00641 &value))
00642 goto error_free_vers;
00643
00644
00645
00646 if (name == NULL)
00647 continue;
00648 }
00649
00650
00651 if (sec == NULL)
00652 {
00653 bfd_set_error (bfd_error_bad_value);
00654 goto error_free_vers;
00655 }
00656
00657 if (bfd_is_und_section (sec)
00658 || bfd_is_com_section (sec))
00659 definition = FALSE;
00660 else
00661 definition = TRUE;
00662
00663 size_change_ok = FALSE;
00664 type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
00665 old_alignment = 0;
00666 old_bfd = NULL;
00667
00668 if (is_elf_hash_table (hash_table))
00669 {
00670 Elf_Internal_Versym iver;
00671 unsigned int vernum = 0;
00672 bfd_boolean skip;
00673
00674 if (ever != NULL)
00675 {
00676 _bfd_elf_swap_versym_in (abfd, ever, &iver);
00677 vernum = iver.vs_vers & VERSYM_VERSION;
00678
00679
00680
00681
00682
00683
00684 if ((iver.vs_vers & VERSYM_HIDDEN) != 0
00685 || (vernum > 1 && ! bfd_is_abs_section (sec)))
00686 {
00687 const char *verstr;
00688 size_t namelen, verlen, newlen;
00689 char *newname, *p;
00690
00691 if (isym->st_shndx != SHN_UNDEF)
00692 {
00693 if (vernum > elf_tdata (abfd)->dynverdef_hdr.sh_info)
00694 {
00695 (*_bfd_error_handler)
00696 (_("%s: %s: invalid version %u (max %d)"),
00697 bfd_archive_filename (abfd), name, vernum,
00698 elf_tdata (abfd)->dynverdef_hdr.sh_info);
00699 bfd_set_error (bfd_error_bad_value);
00700 goto error_free_vers;
00701 }
00702 else if (vernum > 1)
00703 verstr =
00704 elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
00705 else
00706 verstr = "";
00707 }
00708 else
00709 {
00710
00711
00712
00713
00714 Elf_Internal_Verneed *t;
00715
00716 verstr = NULL;
00717 for (t = elf_tdata (abfd)->verref;
00718 t != NULL;
00719 t = t->vn_nextref)
00720 {
00721 Elf_Internal_Vernaux *a;
00722
00723 for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
00724 {
00725 if (a->vna_other == vernum)
00726 {
00727 verstr = a->vna_nodename;
00728 break;
00729 }
00730 }
00731 if (a != NULL)
00732 break;
00733 }
00734 if (verstr == NULL)
00735 {
00736 (*_bfd_error_handler)
00737 (_("%s: %s: invalid needed version %d"),
00738 bfd_archive_filename (abfd), name, vernum);
00739 bfd_set_error (bfd_error_bad_value);
00740 goto error_free_vers;
00741 }
00742 }
00743
00744 namelen = strlen (name);
00745 verlen = strlen (verstr);
00746 newlen = namelen + verlen + 2;
00747 if ((iver.vs_vers & VERSYM_HIDDEN) == 0
00748 && isym->st_shndx != SHN_UNDEF)
00749 ++newlen;
00750
00751 newname = bfd_alloc (abfd, newlen);
00752 if (newname == NULL)
00753 goto error_free_vers;
00754 memcpy (newname, name, namelen);
00755 p = newname + namelen;
00756 *p++ = ELF_VER_CHR;
00757
00758
00759
00760 if ((iver.vs_vers & VERSYM_HIDDEN) == 0
00761 && isym->st_shndx != SHN_UNDEF)
00762 *p++ = ELF_VER_CHR;
00763 memcpy (p, verstr, verlen + 1);
00764
00765 name = newname;
00766 }
00767 }
00768
00769 if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
00770 sym_hash, &skip, &override,
00771 &type_change_ok, &size_change_ok,
00772 dt_needed))
00773 goto error_free_vers;
00774
00775 if (skip)
00776 continue;
00777
00778 if (override)
00779 definition = FALSE;
00780
00781 h = *sym_hash;
00782 while (h->root.type == bfd_link_hash_indirect
00783 || h->root.type == bfd_link_hash_warning)
00784 h = (struct elf_link_hash_entry *) h->root.u.i.link;
00785
00786
00787
00788
00789
00790
00791
00792 switch (h->root.type)
00793 {
00794 default:
00795 break;
00796
00797 case bfd_link_hash_defined:
00798 case bfd_link_hash_defweak:
00799 old_bfd = h->root.u.def.section->owner;
00800 break;
00801
00802 case bfd_link_hash_common:
00803 old_bfd = h->root.u.c.p->section->owner;
00804 old_alignment = h->root.u.c.p->alignment_power;
00805 break;
00806 }
00807
00808 if (elf_tdata (abfd)->verdef != NULL
00809 && ! override
00810 && vernum > 1
00811 && definition)
00812 h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1];
00813 }
00814
00815 if (! (_bfd_generic_link_add_one_symbol
00816 (info, abfd, name, flags, sec, value, NULL, FALSE, collect,
00817 (struct bfd_link_hash_entry **) sym_hash)))
00818 goto error_free_vers;
00819
00820 h = *sym_hash;
00821 while (h->root.type == bfd_link_hash_indirect
00822 || h->root.type == bfd_link_hash_warning)
00823 h = (struct elf_link_hash_entry *) h->root.u.i.link;
00824 *sym_hash = h;
00825
00826 new_weakdef = FALSE;
00827 if (dynamic
00828 && definition
00829 && (flags & BSF_WEAK) != 0
00830 && ELF_ST_TYPE (isym->st_info) != STT_FUNC
00831 && is_elf_hash_table (hash_table)
00832 && h->weakdef == NULL)
00833 {
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 h->weakdef = weaks;
00847 weaks = h;
00848 new_weakdef = TRUE;
00849 }
00850
00851
00852 if (isym->st_shndx == SHN_COMMON
00853 && h->root.type == bfd_link_hash_common)
00854 {
00855 unsigned int align;
00856
00857 align = bfd_log2 (isym->st_value);
00858 if (align > old_alignment
00859
00860
00861 || (isym->st_value == 1 && old_alignment == 0))
00862 h->root.u.c.p->alignment_power = align;
00863 else
00864 h->root.u.c.p->alignment_power = old_alignment;
00865 }
00866
00867 if (is_elf_hash_table (hash_table))
00868 {
00869 int old_flags;
00870 bfd_boolean dynsym;
00871 int new_flag;
00872
00873
00874
00875
00876
00877
00878 if ((old_alignment || isym->st_shndx == SHN_COMMON)
00879 && h->root.type != bfd_link_hash_common)
00880 {
00881 unsigned int common_align;
00882 unsigned int normal_align;
00883 unsigned int symbol_align;
00884 bfd *normal_bfd;
00885 bfd *common_bfd;
00886
00887 symbol_align = ffs (h->root.u.def.value) - 1;
00888 if (h->root.u.def.section->owner != NULL
00889 && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
00890 {
00891 normal_align = h->root.u.def.section->alignment_power;
00892 if (normal_align > symbol_align)
00893 normal_align = symbol_align;
00894 }
00895 else
00896 normal_align = symbol_align;
00897
00898 if (old_alignment)
00899 {
00900 common_align = old_alignment;
00901 common_bfd = old_bfd;
00902 normal_bfd = abfd;
00903 }
00904 else
00905 {
00906 common_align = bfd_log2 (isym->st_value);
00907 common_bfd = abfd;
00908 normal_bfd = old_bfd;
00909 }
00910
00911 if (normal_align < common_align)
00912 (*_bfd_error_handler)
00913 (_("Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"),
00914 1 << normal_align,
00915 name,
00916 bfd_archive_filename (normal_bfd),
00917 1 << common_align,
00918 bfd_archive_filename (common_bfd));
00919 }
00920
00921
00922 if (isym->st_size != 0
00923 && (definition || h->size == 0))
00924 {
00925
00926
00927
00928 if (h->size != 0 && h->size != isym->st_size && ! size_change_ok
00929 && ipa_is_whirl(abfd))
00930
00931
00932
00933
00934
00935
00936 if( old_bfd == NULL ){
00937 char* old_src =
00938 h->root.u.def.invalid_section_owner
00939 ? bfd_archive_filename((bfd*)(h->root.u.def.section))
00940 : "previous object";
00941
00942 (*_bfd_error_handler)
00943 (_("Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"),
00944 name, (unsigned long) h->size,
00945 old_src,
00946 (unsigned long) isym->st_size,
00947 bfd_archive_filename (abfd));
00948 } else {
00949 (*_bfd_error_handler)
00950 (_("Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"),
00951 name, (unsigned long) h->size,
00952 bfd_archive_filename (old_bfd),
00953 (unsigned long) isym->st_size,
00954 bfd_archive_filename (abfd));
00955 }
00956
00957 h->size = isym->st_size;
00958 }
00959
00960
00961
00962
00963
00964
00965 if (h->root.type == bfd_link_hash_common)
00966 h->size = h->root.u.c.size;
00967
00968 if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
00969 && (definition || h->type == STT_NOTYPE))
00970 {
00971 if (h->type != STT_NOTYPE
00972 && h->type != ELF_ST_TYPE (isym->st_info)
00973 && ! type_change_ok)
00974 (*_bfd_error_handler)
00975 (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
00976 name, h->type, ELF_ST_TYPE (isym->st_info),
00977 bfd_archive_filename (abfd));
00978
00979 h->type = ELF_ST_TYPE (isym->st_info);
00980 }
00981
00982
00983
00984
00985 if (bed->elf_backend_merge_symbol_attribute)
00986 (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition,
00987 dynamic);
00988
00989 if (isym->st_other != 0 && !dynamic)
00990 {
00991 unsigned char hvis, symvis, other, nvis;
00992
00993
00994 other = (definition ? isym->st_other : h->other);
00995 other &= ~ ELF_ST_VISIBILITY (-1);
00996
00997
00998 hvis = ELF_ST_VISIBILITY (h->other);
00999 symvis = ELF_ST_VISIBILITY (isym->st_other);
01000 if (! hvis)
01001 nvis = symvis;
01002 else if (! symvis)
01003 nvis = hvis;
01004 else
01005 nvis = hvis < symvis ? hvis : symvis;
01006
01007 h->other = other | nvis;
01008 }
01009
01010
01011
01012
01013
01014
01015 old_flags = h->elf_link_hash_flags;
01016 dynsym = FALSE;
01017 if (! dynamic)
01018 {
01019 if (! definition)
01020 {
01021 new_flag = 0;
01022 if (!ipa_is_whirl(abfd))
01023 new_flag = ELF_LINK_HASH_REF_REGULAR;
01024 if (bind != STB_WEAK)
01025 new_flag |= ELF_LINK_HASH_REF_REGULAR_NONWEAK;
01026 }
01027 else
01028 {
01029 new_flag = 0;
01030 if (!ipa_is_whirl(abfd))
01031 new_flag = ELF_LINK_HASH_DEF_REGULAR;
01032 }
01033 if (! info->executable
01034 || (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC
01035 | ELF_LINK_HASH_REF_DYNAMIC)) != 0)
01036 dynsym = TRUE;
01037 }
01038 else
01039 {
01040 if (! definition)
01041 new_flag = ELF_LINK_HASH_REF_DYNAMIC;
01042 else
01043 new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
01044 if ((old_flags & (ELF_LINK_HASH_DEF_REGULAR
01045 | ELF_LINK_HASH_REF_REGULAR)) != 0
01046 || (h->weakdef != NULL
01047 && ! new_weakdef
01048 && h->weakdef->dynindx != -1))
01049 dynsym = TRUE;
01050 }
01051
01052 h->elf_link_hash_flags |= new_flag;
01053
01054
01055
01056 if (definition || h->root.type == bfd_link_hash_common)
01057 if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym,
01058 &sec, &value, &dynsym,
01059 override, dt_needed,
01060 flags, &weaks))
01061 goto error_free_vers;
01062
01063 if (definition && !dynamic)
01064 {
01065 char *p = strchr (name, ELF_VER_CHR);
01066 if (p != NULL && p[1] != ELF_VER_CHR)
01067 {
01068
01069
01070 if (! nondeflt_vers)
01071 {
01072 amt = (isymend - isym + 1)
01073 * sizeof (struct elf_link_hash_entry *);
01074 nondeflt_vers = bfd_malloc (amt);
01075 }
01076 nondeflt_vers [nondeflt_vers_cnt++] = h;
01077 }
01078 }
01079
01080 if (dynsym && h->dynindx == -1)
01081 {
01082 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
01083 goto error_free_vers;
01084 if (h->weakdef != NULL
01085 && ! new_weakdef
01086 && h->weakdef->dynindx == -1)
01087 {
01088 if (! _bfd_elf_link_record_dynamic_symbol (info, h->weakdef))
01089 goto error_free_vers;
01090 }
01091 }
01092 else if (dynsym && h->dynindx != -1)
01093
01094
01095
01096 switch (ELF_ST_VISIBILITY (h->other))
01097 {
01098 case STV_INTERNAL:
01099 case STV_HIDDEN:
01100 (*bed->elf_backend_hide_symbol) (info, h, TRUE);
01101 break;
01102 }
01103
01104 if (dt_needed && definition
01105 && (h->elf_link_hash_flags
01106 & ELF_LINK_HASH_REF_REGULAR) != 0)
01107 {
01108 bfd_size_type oldsize;
01109 bfd_size_type strindex;
01110
01111
01112
01113
01114
01115 dt_needed = FALSE;
01116 oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
01117 strindex = _bfd_elf_strtab_add (hash_table->dynstr,
01118 elf_dt_soname (abfd), FALSE);
01119 if (strindex == (bfd_size_type) -1)
01120 goto error_free_vers;
01121
01122 if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
01123 {
01124 asection *sdyn;
01125 Elf_External_Dyn *dyncon, *dynconend;
01126
01127 sdyn = bfd_get_section_by_name (hash_table->dynobj,
01128 ".dynamic");
01129 BFD_ASSERT (sdyn != NULL);
01130
01131 dyncon = (Elf_External_Dyn *) sdyn->contents;
01132 dynconend = (Elf_External_Dyn *) (sdyn->contents +
01133 sdyn->_raw_size);
01134 for (; dyncon < dynconend; dyncon++)
01135 {
01136 Elf_Internal_Dyn dyn;
01137
01138 elf_swap_dyn_in (hash_table->dynobj,
01139 dyncon, &dyn);
01140 BFD_ASSERT (dyn.d_tag != DT_NEEDED ||
01141 dyn.d_un.d_val != strindex);
01142 }
01143 }
01144
01145 if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
01146 goto error_free_vers;
01147 }
01148 }
01149 }
01150
01151
01152
01153 if (nondeflt_vers != NULL)
01154 {
01155 bfd_size_type cnt, symidx;
01156
01157 for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt)
01158 {
01159 struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi;
01160 char *shortname, *p;
01161
01162 p = strchr (h->root.root.string, ELF_VER_CHR);
01163 if (p == NULL
01164 || (h->root.type != bfd_link_hash_defined
01165 && h->root.type != bfd_link_hash_defweak))
01166 continue;
01167
01168 amt = p - h->root.root.string;
01169 shortname = bfd_malloc (amt + 1);
01170 memcpy (shortname, h->root.root.string, amt);
01171 shortname[amt] = '\0';
01172
01173 hi = (struct elf_link_hash_entry *)
01174 bfd_link_hash_lookup (&hash_table->root, shortname,
01175 FALSE, FALSE, FALSE);
01176 if (hi != NULL
01177 && hi->root.type == h->root.type
01178 && hi->root.u.def.value == h->root.u.def.value
01179 && hi->root.u.def.section == h->root.u.def.section)
01180 {
01181 (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
01182 hi->root.type = bfd_link_hash_indirect;
01183 hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
01184 (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
01185 sym_hash = elf_sym_hashes (abfd);
01186 if (sym_hash)
01187 for (symidx = 0; symidx < extsymcount; ++symidx)
01188 if (sym_hash[symidx] == hi)
01189 {
01190 sym_hash[symidx] = h;
01191 break;
01192 }
01193 }
01194 free (shortname);
01195 }
01196 free (nondeflt_vers);
01197 nondeflt_vers = NULL;
01198 }
01199
01200 if (extversym != NULL)
01201 {
01202 free (extversym);
01203 extversym = NULL;
01204 }
01205
01206 if (isymbuf != NULL)
01207 free (isymbuf);
01208 isymbuf = NULL;
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223 if (weaks != NULL)
01224 {
01225 struct elf_link_hash_entry **hpp;
01226 struct elf_link_hash_entry **hppend;
01227 struct elf_link_hash_entry **sorted_sym_hash;
01228 struct elf_link_hash_entry *h;
01229 size_t sym_count;
01230
01231
01232
01233
01234 amt = extsymcount * sizeof (struct elf_link_hash_entry *);
01235 sorted_sym_hash = bfd_malloc (amt);
01236 if (sorted_sym_hash == NULL)
01237 goto error_return;
01238 sym_hash = sorted_sym_hash;
01239 hpp = elf_sym_hashes (abfd);
01240 hppend = hpp + extsymcount;
01241 sym_count = 0;
01242 for (; hpp < hppend; hpp++)
01243 {
01244 h = *hpp;
01245 if (h != NULL
01246 && h->root.type == bfd_link_hash_defined
01247 && h->type != STT_FUNC)
01248 {
01249 *sym_hash = h;
01250 sym_hash++;
01251 sym_count++;
01252 }
01253 }
01254
01255 qsort (sorted_sym_hash, sym_count,
01256 sizeof (struct elf_link_hash_entry *),
01257 sort_symbol);
01258
01259 while (weaks != NULL)
01260 {
01261 struct elf_link_hash_entry *hlook;
01262 asection *slook;
01263 bfd_vma vlook;
01264 long ilook;
01265 size_t i, j, idx;
01266
01267 hlook = weaks;
01268 weaks = hlook->weakdef;
01269 hlook->weakdef = NULL;
01270 #ifndef KEY
01271 BFD_ASSERT (hlook->root.type == bfd_link_hash_defined
01272 || hlook->root.type == bfd_link_hash_defweak
01273 || hlook->root.type == bfd_link_hash_common
01274 || hlook->root.type == bfd_link_hash_indirect);
01275 #endif
01276 slook = hlook->root.u.def.section;
01277 vlook = hlook->root.u.def.value;
01278
01279 ilook = -1;
01280 i = 0;
01281 j = sym_count;
01282 while (i < j)
01283 {
01284 bfd_signed_vma vdiff;
01285 idx = (i + j) / 2;
01286 h = sorted_sym_hash [idx];
01287 vdiff = vlook - h->root.u.def.value;
01288 if (vdiff < 0)
01289 j = idx;
01290 else if (vdiff > 0)
01291 i = idx + 1;
01292 else
01293 {
01294 long sdiff = slook - h->root.u.def.section;
01295 if (sdiff < 0)
01296 j = idx;
01297 else if (sdiff > 0)
01298 i = idx + 1;
01299 else
01300 {
01301 ilook = idx;
01302 break;
01303 }
01304 }
01305 }
01306
01307
01308 if (ilook == -1)
01309 continue;
01310
01311 for (i = ilook; i < sym_count; i++)
01312 {
01313 h = sorted_sym_hash [i];
01314
01315
01316 if (h->root.u.def.value != vlook
01317 || h->root.u.def.section != slook)
01318 break;
01319 else if (h != hlook)
01320 {
01321 hlook->weakdef = h;
01322
01323
01324
01325
01326 if (hlook->dynindx != -1 && h->dynindx == -1)
01327 {
01328 if (! _bfd_elf_link_record_dynamic_symbol (info,
01329 h))
01330 goto error_return;
01331 }
01332
01333
01334
01335
01336
01337
01338 if (h->dynindx != -1 && hlook->dynindx == -1)
01339 {
01340 if (! _bfd_elf_link_record_dynamic_symbol (info,
01341 hlook))
01342 goto error_return;
01343 }
01344 break;
01345 }
01346 }
01347 }
01348
01349 free (sorted_sym_hash);
01350 }
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369 check_relocs = get_elf_backend_data (abfd)->check_relocs;
01370 if (! dynamic
01371 && is_elf_hash_table (hash_table)
01372 && hash_table->root.creator == abfd->xvec
01373 && check_relocs != NULL)
01374 {
01375 asection *o;
01376
01377 for (o = abfd->sections; o != NULL; o = o->next)
01378 {
01379 Elf_Internal_Rela *internal_relocs;
01380 bfd_boolean ok;
01381
01382 if ((o->flags & SEC_RELOC) == 0
01383 || o->reloc_count == 0
01384 || ((info->strip == strip_all || info->strip == strip_debugger)
01385 && (o->flags & SEC_DEBUGGING) != 0)
01386 || bfd_is_abs_section (o->output_section))
01387 continue;
01388
01389 internal_relocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
01390 info->keep_memory);
01391 if (internal_relocs == NULL)
01392 goto error_return;
01393
01394 ok = (*check_relocs) (abfd, info, o, internal_relocs);
01395
01396 if (elf_section_data (o)->relocs != internal_relocs)
01397 free (internal_relocs);
01398
01399 if (! ok)
01400 goto error_return;
01401 }
01402 }
01403
01404
01405
01406 if (! dynamic
01407 && ! info->traditional_format
01408 && is_elf_hash_table (hash_table)
01409 && (info->strip != strip_all && info->strip != strip_debugger))
01410 {
01411 asection *stabstr;
01412
01413 stabstr = bfd_get_section_by_name (abfd, ".stabstr");
01414 if (stabstr != NULL)
01415 {
01416 bfd_size_type string_offset = 0;
01417 asection *stab;
01418
01419 for (stab = abfd->sections; stab; stab = stab->next)
01420 if (strncmp (".stab", stab->name, 5) == 0
01421 && (!stab->name[5] ||
01422 (stab->name[5] == '.' && ISDIGIT (stab->name[6])))
01423 && (stab->flags & SEC_MERGE) == 0
01424 && !bfd_is_abs_section (stab->output_section))
01425 {
01426 struct bfd_elf_section_data *secdata;
01427
01428 secdata = elf_section_data (stab);
01429 if (! _bfd_link_section_stabs (abfd,
01430 & hash_table->stab_info,
01431 stab, stabstr,
01432 &secdata->sec_info,
01433 &string_offset))
01434 goto error_return;
01435 if (secdata->sec_info)
01436 stab->sec_info_type = ELF_INFO_TYPE_STABS;
01437 }
01438 }
01439 }
01440
01441 if (! info->relocatable
01442 && ! dynamic
01443 && is_elf_hash_table (hash_table))
01444 {
01445 asection *s;
01446
01447 for (s = abfd->sections; s != NULL; s = s->next)
01448 if ((s->flags & SEC_MERGE) != 0
01449 && !bfd_is_abs_section (s->output_section))
01450 {
01451 struct bfd_elf_section_data *secdata;
01452
01453 secdata = elf_section_data (s);
01454 if (! _bfd_merge_section (abfd,
01455 & hash_table->merge_info,
01456 s, &secdata->sec_info))
01457 goto error_return;
01458 else if (secdata->sec_info)
01459 s->sec_info_type = ELF_INFO_TYPE_MERGE;
01460 }
01461 }
01462
01463 if (is_elf_hash_table (hash_table))
01464 {
01465
01466 struct elf_link_loaded_list *n;
01467
01468 n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
01469 if (n == NULL)
01470 goto error_return;
01471 n->abfd = abfd;
01472 n->next = hash_table->loaded;
01473 hash_table->loaded = n;
01474 }
01475
01476 return TRUE;
01477
01478 error_free_vers:
01479 if (nondeflt_vers != NULL)
01480 free (nondeflt_vers);
01481 if (extversym != NULL)
01482 free (extversym);
01483 error_free_sym:
01484 if (isymbuf != NULL)
01485 free (isymbuf);
01486 error_return:
01487 return FALSE;
01488 }
01489
01490
01491
01492 bfd_boolean
01493 elf_add_dynamic_entry (struct bfd_link_info *info, bfd_vma tag, bfd_vma val)
01494 {
01495 Elf_Internal_Dyn dyn;
01496 bfd *dynobj;
01497 asection *s;
01498 bfd_size_type newsize;
01499 bfd_byte *newcontents;
01500
01501 if (! is_elf_hash_table (info->hash))
01502 return FALSE;
01503
01504 dynobj = elf_hash_table (info)->dynobj;
01505
01506 s = bfd_get_section_by_name (dynobj, ".dynamic");
01507 BFD_ASSERT (s != NULL);
01508
01509 newsize = s->_raw_size + sizeof (Elf_External_Dyn);
01510 newcontents = bfd_realloc (s->contents, newsize);
01511 if (newcontents == NULL)
01512 return FALSE;
01513
01514 dyn.d_tag = tag;
01515 dyn.d_un.d_val = val;
01516 elf_swap_dyn_out (dynobj, &dyn,
01517 (Elf_External_Dyn *) (newcontents + s->_raw_size));
01518
01519 s->_raw_size = newsize;
01520 s->contents = newcontents;
01521
01522 return TRUE;
01523 }
01524
01525
01526
01527
01528
01529
01530
01531 static const size_t elf_buckets[] =
01532 {
01533 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
01534 16411, 32771, 0
01535 };
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545 static size_t
01546 compute_bucket_count (struct bfd_link_info *info)
01547 {
01548 size_t dynsymcount = elf_hash_table (info)->dynsymcount;
01549 size_t best_size = 0;
01550 unsigned long int *hashcodes;
01551 unsigned long int *hashcodesp;
01552 unsigned long int i;
01553 bfd_size_type amt;
01554
01555
01556
01557
01558 amt = dynsymcount;
01559 amt *= sizeof (unsigned long int);
01560 hashcodes = bfd_malloc (amt);
01561 if (hashcodes == NULL)
01562 return 0;
01563 hashcodesp = hashcodes;
01564
01565
01566 elf_link_hash_traverse (elf_hash_table (info),
01567 elf_collect_hash_codes, &hashcodesp);
01568
01569
01570
01571
01572 #ifdef BFD_HOST_U_64_BIT
01573 if (info->optimize)
01574 {
01575 unsigned long int nsyms = hashcodesp - hashcodes;
01576 size_t minsize;
01577 size_t maxsize;
01578 BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0);
01579 unsigned long int *counts ;
01580
01581
01582
01583
01584 minsize = nsyms / 4;
01585 if (minsize == 0)
01586 minsize = 1;
01587 best_size = maxsize = nsyms * 2;
01588
01589
01590
01591 amt = maxsize;
01592 amt *= sizeof (unsigned long int);
01593 counts = bfd_malloc (amt);
01594 if (counts == NULL)
01595 {
01596 free (hashcodes);
01597 return 0;
01598 }
01599
01600
01601
01602
01603 for (i = minsize; i < maxsize; ++i)
01604 {
01605
01606 BFD_HOST_U_64_BIT max;
01607 unsigned long int j;
01608 unsigned long int fact;
01609
01610 memset (counts, '\0', i * sizeof (unsigned long int));
01611
01612
01613 for (j = 0; j < nsyms; ++j)
01614 ++counts[hashcodes[j] % i];
01615
01616
01617
01618
01619
01620
01621 # ifndef BFD_TARGET_PAGESIZE
01622 # define BFD_TARGET_PAGESIZE (4096)
01623 # endif
01624
01625
01626
01627 max = (2 + nsyms) * (ARCH_SIZE / 8);
01628
01629 # if 1
01630
01631
01632
01633 for (j = 0; j < i; ++j)
01634 max += counts[j] * counts[j];
01635
01636
01637 fact = i / (BFD_TARGET_PAGESIZE / (ARCH_SIZE / 8)) + 1;
01638 max *= fact * fact;
01639 # else
01640
01641
01642
01643 for (j = 0; j < i; ++j)
01644 max += (1 + counts[j]) * (1 + counts[j]);
01645
01646
01647
01648 fact = i / (BFD_TARGET_PAGESIZE / (ARCH_SIZE / 8)) + 1;
01649 max *= fact;
01650 # endif
01651
01652
01653 if (max < best_chlen)
01654 {
01655 best_chlen = max;
01656 best_size = i;
01657 }
01658 }
01659
01660 free (counts);
01661 }
01662 else
01663 #endif
01664 {
01665
01666
01667
01668 for (i = 0; elf_buckets[i] != 0; i++)
01669 {
01670 best_size = elf_buckets[i];
01671 if (dynsymcount < elf_buckets[i + 1])
01672 break;
01673 }
01674 }
01675
01676
01677 free (hashcodes);
01678
01679 return best_size;
01680 }
01681
01682
01683
01684
01685
01686
01687 bfd_boolean
01688 NAME(bfd_elf,size_dynamic_sections) (bfd *output_bfd,
01689 const char *soname,
01690 const char *rpath,
01691 const char *filter_shlib,
01692 const char * const *auxiliary_filters,
01693 struct bfd_link_info *info,
01694 asection **sinterpptr,
01695 struct bfd_elf_version_tree *verdefs)
01696 {
01697 bfd_size_type soname_indx;
01698 bfd *dynobj;
01699 const struct elf_backend_data *bed;
01700 struct elf_assign_sym_version_info asvinfo;
01701
01702 *sinterpptr = NULL;
01703
01704 soname_indx = (bfd_size_type) -1;
01705
01706 if (!is_elf_hash_table (info->hash))
01707 return TRUE;
01708
01709 if (info->execstack)
01710 elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
01711 else if (info->noexecstack)
01712 elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
01713 else
01714 {
01715 bfd *inputobj;
01716 asection *notesec = NULL;
01717 int exec = 0;
01718
01719 for (inputobj = info->input_bfds;
01720 inputobj;
01721 inputobj = inputobj->link_next)
01722 {
01723 asection *s;
01724
01725 if (inputobj->flags & DYNAMIC)
01726 continue;
01727 s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
01728 if (s)
01729 {
01730 if (s->flags & SEC_CODE)
01731 exec = PF_X;
01732 notesec = s;
01733 }
01734 else
01735 exec = PF_X;
01736 }
01737 if (notesec)
01738 {
01739 elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec;
01740 if (exec && info->relocatable
01741 && notesec->output_section != bfd_abs_section_ptr)
01742 notesec->output_section->flags |= SEC_CODE;
01743 }
01744 }
01745
01746
01747
01748 elf_hash_table (info)->init_refcount = elf_hash_table (info)->init_offset;
01749
01750
01751
01752 bed = get_elf_backend_data (output_bfd);
01753 if (bed->elf_backend_always_size_sections
01754 && ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
01755 return FALSE;
01756
01757 dynobj = elf_hash_table (info)->dynobj;
01758
01759
01760
01761 if (dynobj == NULL)
01762 return TRUE;
01763
01764 if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
01765 return FALSE;
01766
01767 if (elf_hash_table (info)->dynamic_sections_created)
01768 {
01769 struct elf_info_failed eif;
01770 struct elf_link_hash_entry *h;
01771 asection *dynstr;
01772 struct bfd_elf_version_tree *t;
01773 struct bfd_elf_version_expr *d;
01774 bfd_boolean all_defined;
01775
01776 *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
01777 BFD_ASSERT (*sinterpptr != NULL || !info->executable);
01778
01779 if (soname != NULL)
01780 {
01781 soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
01782 soname, TRUE);
01783 if (soname_indx == (bfd_size_type) -1
01784 || ! elf_add_dynamic_entry (info, DT_SONAME, soname_indx))
01785 return FALSE;
01786 }
01787
01788 if (info->symbolic)
01789 {
01790 if (! elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
01791 return FALSE;
01792 info->flags |= DF_SYMBOLIC;
01793 }
01794
01795 if (rpath != NULL)
01796 {
01797 bfd_size_type indx;
01798
01799 indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath,
01800 TRUE);
01801 if (info->new_dtags)
01802 _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx);
01803 if (indx == (bfd_size_type) -1
01804 || ! elf_add_dynamic_entry (info, DT_RPATH, indx)
01805 || (info->new_dtags
01806 && ! elf_add_dynamic_entry (info, DT_RUNPATH, indx)))
01807 return FALSE;
01808 }
01809
01810 if (filter_shlib != NULL)
01811 {
01812 bfd_size_type indx;
01813
01814 indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
01815 filter_shlib, TRUE);
01816 if (indx == (bfd_size_type) -1
01817 || ! elf_add_dynamic_entry (info, DT_FILTER, indx))
01818 return FALSE;
01819 }
01820
01821 if (auxiliary_filters != NULL)
01822 {
01823 const char * const *p;
01824
01825 for (p = auxiliary_filters; *p != NULL; p++)
01826 {
01827 bfd_size_type indx;
01828
01829 indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
01830 *p, TRUE);
01831 if (indx == (bfd_size_type) -1
01832 || ! elf_add_dynamic_entry (info, DT_AUXILIARY, indx))
01833 return FALSE;
01834 }
01835 }
01836
01837 eif.info = info;
01838 eif.verdefs = verdefs;
01839 eif.failed = FALSE;
01840
01841
01842
01843 if (info->export_dynamic)
01844 {
01845 elf_link_hash_traverse (elf_hash_table (info),
01846 _bfd_elf_export_symbol,
01847 &eif);
01848 if (eif.failed)
01849 return FALSE;
01850 }
01851
01852
01853 for (t = verdefs; t != NULL; t = t->next)
01854 for (d = t->globals.list; d != NULL; d = d->next)
01855 if (!d->symver && d->symbol)
01856 {
01857 const char *verstr, *name;
01858 size_t namelen, verlen, newlen;
01859 char *newname, *p;
01860 struct elf_link_hash_entry *newh;
01861
01862 name = d->symbol;
01863 namelen = strlen (name);
01864 verstr = t->name;
01865 verlen = strlen (verstr);
01866 newlen = namelen + verlen + 3;
01867
01868 newname = bfd_malloc (newlen);
01869 if (newname == NULL)
01870 return FALSE;
01871 memcpy (newname, name, namelen);
01872
01873
01874 p = newname + namelen;
01875 *p++ = ELF_VER_CHR;
01876 memcpy (p, verstr, verlen + 1);
01877 newh = elf_link_hash_lookup (elf_hash_table (info),
01878 newname, FALSE, FALSE,
01879 FALSE);
01880 if (newh == NULL
01881 || (newh->root.type != bfd_link_hash_defined
01882 && newh->root.type != bfd_link_hash_defweak))
01883 {
01884
01885 *p++ = ELF_VER_CHR;
01886 memcpy (p, verstr, verlen + 1);
01887 newh = elf_link_hash_lookup (elf_hash_table (info),
01888 newname, FALSE, FALSE,
01889 FALSE);
01890 }
01891 free (newname);
01892
01893
01894
01895 if (newh != NULL
01896 && ((newh->elf_link_hash_flags
01897 & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
01898 && (newh->root.type == bfd_link_hash_defined
01899 || newh->root.type == bfd_link_hash_defweak))
01900 d->symver = 1;
01901 }
01902
01903
01904 asvinfo.output_bfd = output_bfd;
01905 asvinfo.info = info;
01906 asvinfo.verdefs = verdefs;
01907 asvinfo.failed = FALSE;
01908
01909 elf_link_hash_traverse (elf_hash_table (info),
01910 _bfd_elf_link_assign_sym_version,
01911 &asvinfo);
01912 if (asvinfo.failed)
01913 return FALSE;
01914
01915 if (!info->allow_undefined_version)
01916 {
01917
01918 all_defined = TRUE;
01919 for (t = verdefs; t != NULL; t = t->next)
01920 for (d = t->globals.list; d != NULL; d = d->next)
01921 if (!d->symver && !d->script)
01922 {
01923 (*_bfd_error_handler)
01924 (_("%s: undefined version: %s"),
01925 d->pattern, t->name);
01926 all_defined = FALSE;
01927 }
01928
01929 if (!all_defined)
01930 {
01931 bfd_set_error (bfd_error_bad_value);
01932 return FALSE;
01933 }
01934 }
01935
01936
01937
01938 elf_link_hash_traverse (elf_hash_table (info),
01939 _bfd_elf_adjust_dynamic_symbol,
01940 &eif);
01941 if (eif.failed)
01942 return FALSE;
01943
01944
01945
01946
01947
01948
01949
01950 h = (info->init_function
01951 ? elf_link_hash_lookup (elf_hash_table (info),
01952 info->init_function, FALSE,
01953 FALSE, FALSE)
01954 : NULL);
01955 if (h != NULL
01956 && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
01957 | ELF_LINK_HASH_DEF_REGULAR)) != 0)
01958 {
01959 if (! elf_add_dynamic_entry (info, DT_INIT, 0))
01960 return FALSE;
01961 }
01962 h = (info->fini_function
01963 ? elf_link_hash_lookup (elf_hash_table (info),
01964 info->fini_function, FALSE,
01965 FALSE, FALSE)
01966 : NULL);
01967 if (h != NULL
01968 && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
01969 | ELF_LINK_HASH_DEF_REGULAR)) != 0)
01970 {
01971 if (! elf_add_dynamic_entry (info, DT_FINI, 0))
01972 return FALSE;
01973 }
01974
01975 if (bfd_get_section_by_name (output_bfd, ".preinit_array") != NULL)
01976 {
01977
01978 if (! info->executable)
01979 {
01980 bfd *sub;
01981 asection *o;
01982
01983 for (sub = info->input_bfds; sub != NULL;
01984 sub = sub->link_next)
01985 for (o = sub->sections; o != NULL; o = o->next)
01986 if (elf_section_data (o)->this_hdr.sh_type
01987 == SHT_PREINIT_ARRAY)
01988 {
01989 (*_bfd_error_handler)
01990 (_("%s: .preinit_array section is not allowed in DSO"),
01991 bfd_archive_filename (sub));
01992 break;
01993 }
01994
01995 bfd_set_error (bfd_error_nonrepresentable_section);
01996 return FALSE;
01997 }
01998
01999 if (!elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0)
02000 || !elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0))
02001 return FALSE;
02002 }
02003 if (bfd_get_section_by_name (output_bfd, ".init_array") != NULL)
02004 {
02005 if (!elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0)
02006 || !elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0))
02007 return FALSE;
02008 }
02009 if (bfd_get_section_by_name (output_bfd, ".fini_array") != NULL)
02010 {
02011 if (!elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0)
02012 || !elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0))
02013 return FALSE;
02014 }
02015
02016 dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
02017
02018
02019
02020
02021 if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr)
02022 {
02023 bfd_size_type strsize;
02024
02025 strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
02026 if (! elf_add_dynamic_entry (info, DT_HASH, 0)
02027 || ! elf_add_dynamic_entry (info, DT_STRTAB, 0)
02028 || ! elf_add_dynamic_entry (info, DT_SYMTAB, 0)
02029 || ! elf_add_dynamic_entry (info, DT_STRSZ, strsize)
02030 || ! elf_add_dynamic_entry (info, DT_SYMENT,
02031 sizeof (Elf_External_Sym)))
02032 return FALSE;
02033 }
02034 }
02035
02036
02037
02038 if (bed->elf_backend_size_dynamic_sections
02039 && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
02040 return FALSE;
02041
02042 if (elf_hash_table (info)->dynamic_sections_created)
02043 {
02044 bfd_size_type dynsymcount;
02045 asection *s;
02046 size_t bucketcount = 0;
02047 size_t hash_entry_size;
02048 unsigned int dtagcount;
02049
02050
02051 s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
02052 BFD_ASSERT (s != NULL);
02053
02054
02055
02056 verdefs = asvinfo.verdefs;
02057
02058
02059 if (verdefs != NULL && verdefs->vernum == 0)
02060 verdefs = verdefs->next;
02061
02062 if (verdefs == NULL)
02063 _bfd_strip_section_from_output (info, s);
02064 else
02065 {
02066 unsigned int cdefs;
02067 bfd_size_type size;
02068 struct bfd_elf_version_tree *t;
02069 bfd_byte *p;
02070 Elf_Internal_Verdef def;
02071 Elf_Internal_Verdaux defaux;
02072
02073 cdefs = 0;
02074 size = 0;
02075
02076
02077 size += sizeof (Elf_External_Verdef);
02078 size += sizeof (Elf_External_Verdaux);
02079 ++cdefs;
02080
02081 for (t = verdefs; t != NULL; t = t->next)
02082 {
02083 struct bfd_elf_version_deps *n;
02084
02085 size += sizeof (Elf_External_Verdef);
02086 size += sizeof (Elf_External_Verdaux);
02087 ++cdefs;
02088
02089 for (n = t->deps; n != NULL; n = n->next)
02090 size += sizeof (Elf_External_Verdaux);
02091 }
02092
02093 s->_raw_size = size;
02094 s->contents = bfd_alloc (output_bfd, s->_raw_size);
02095 if (s->contents == NULL && s->_raw_size != 0)
02096 return FALSE;
02097
02098
02099
02100 p = s->contents;
02101
02102 def.vd_version = VER_DEF_CURRENT;
02103 def.vd_flags = VER_FLG_BASE;
02104 def.vd_ndx = 1;
02105 def.vd_cnt = 1;
02106 def.vd_aux = sizeof (Elf_External_Verdef);
02107 def.vd_next = (sizeof (Elf_External_Verdef)
02108 + sizeof (Elf_External_Verdaux));
02109
02110 if (soname_indx != (bfd_size_type) -1)
02111 {
02112 _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
02113 soname_indx);
02114 def.vd_hash = bfd_elf_hash (soname);
02115 defaux.vda_name = soname_indx;
02116 }
02117 else
02118 {
02119 const char *name;
02120 bfd_size_type indx;
02121
02122 name = basename (output_bfd->filename);
02123 def.vd_hash = bfd_elf_hash (name);
02124 indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
02125 name, FALSE);
02126 if (indx == (bfd_size_type) -1)
02127 return FALSE;
02128 defaux.vda_name = indx;
02129 }
02130 defaux.vda_next = 0;
02131
02132 _bfd_elf_swap_verdef_out (output_bfd, &def,
02133 (Elf_External_Verdef *) p);
02134 p += sizeof (Elf_External_Verdef);
02135 _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
02136 (Elf_External_Verdaux *) p);
02137 p += sizeof (Elf_External_Verdaux);
02138
02139 for (t = verdefs; t != NULL; t = t->next)
02140 {
02141 unsigned int cdeps;
02142 struct bfd_elf_version_deps *n;
02143 struct elf_link_hash_entry *h;
02144 struct bfd_link_hash_entry *bh;
02145
02146 cdeps = 0;
02147 for (n = t->deps; n != NULL; n = n->next)
02148 ++cdeps;
02149
02150
02151 bh = NULL;
02152 if (! (_bfd_generic_link_add_one_symbol
02153 (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr,
02154 0, NULL, FALSE,
02155 get_elf_backend_data (dynobj)->collect, &bh)))
02156 return FALSE;
02157 h = (struct elf_link_hash_entry *) bh;
02158 h->elf_link_hash_flags &= ~ ELF_LINK_NON_ELF;
02159 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
02160 h->type = STT_OBJECT;
02161 h->verinfo.vertree = t;
02162
02163 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
02164 return FALSE;
02165
02166 def.vd_version = VER_DEF_CURRENT;
02167 def.vd_flags = 0;
02168 if (t->globals.list == NULL && t->locals.list == NULL && ! t->used)
02169 def.vd_flags |= VER_FLG_WEAK;
02170 def.vd_ndx = t->vernum + 1;
02171 def.vd_cnt = cdeps + 1;
02172 def.vd_hash = bfd_elf_hash (t->name);
02173 def.vd_aux = sizeof (Elf_External_Verdef);
02174 if (t->next != NULL)
02175 def.vd_next = (sizeof (Elf_External_Verdef)
02176 + (cdeps + 1) * sizeof (Elf_External_Verdaux));
02177 else
02178 def.vd_next = 0;
02179
02180 _bfd_elf_swap_verdef_out (output_bfd, &def,
02181 (Elf_External_Verdef *) p);
02182 p += sizeof (Elf_External_Verdef);
02183
02184 defaux.vda_name = h->dynstr_index;
02185 _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
02186 h->dynstr_index);
02187 if (t->deps == NULL)
02188 defaux.vda_next = 0;
02189 else
02190 defaux.vda_next = sizeof (Elf_External_Verdaux);
02191 t->name_indx = defaux.vda_name;
02192
02193 _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
02194 (Elf_External_Verdaux *) p);
02195 p += sizeof (Elf_External_Verdaux);
02196
02197 for (n = t->deps; n != NULL; n = n->next)
02198 {
02199 if (n->version_needed == NULL)
02200 {
02201
02202
02203 defaux.vda_name = 0;
02204 }
02205 else
02206 {
02207 defaux.vda_name = n->version_needed->name_indx;
02208 _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
02209 defaux.vda_name);
02210 }
02211 if (n->next == NULL)
02212 defaux.vda_next = 0;
02213 else
02214 defaux.vda_next = sizeof (Elf_External_Verdaux);
02215
02216 _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
02217 (Elf_External_Verdaux *) p);
02218 p += sizeof (Elf_External_Verdaux);
02219 }
02220 }
02221
02222 if (! elf_add_dynamic_entry (info, DT_VERDEF, 0)
02223 || ! elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs))
02224 return FALSE;
02225
02226 elf_tdata (output_bfd)->cverdefs = cdefs;
02227 }
02228
02229 if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS))
02230 {
02231 if (! elf_add_dynamic_entry (info, DT_FLAGS, info->flags))
02232 return FALSE;
02233 }
02234 else if (info->flags & DF_BIND_NOW)
02235 {
02236 if (! elf_add_dynamic_entry (info, DT_BIND_NOW, 0))
02237 return FALSE;
02238 }
02239
02240 if (info->flags_1)
02241 {
02242 if (info->executable)
02243 info->flags_1 &= ~ (DF_1_INITFIRST
02244 | DF_1_NODELETE
02245 | DF_1_NOOPEN);
02246 if (! elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1))
02247 return FALSE;
02248 }
02249
02250
02251
02252 s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
02253 BFD_ASSERT (s != NULL);
02254 {
02255 struct elf_find_verdep_info sinfo;
02256
02257 sinfo.output_bfd = output_bfd;
02258 sinfo.info = info;
02259 sinfo.vers = elf_tdata (output_bfd)->cverdefs;
02260 if (sinfo.vers == 0)
02261 sinfo.vers = 1;
02262 sinfo.failed = FALSE;
02263
02264 elf_link_hash_traverse (elf_hash_table (info),
02265 _bfd_elf_link_find_version_dependencies,
02266 &sinfo);
02267
02268 if (elf_tdata (output_bfd)->verref == NULL)
02269 _bfd_strip_section_from_output (info, s);
02270 else
02271 {
02272 Elf_Internal_Verneed *t;
02273 unsigned int size;
02274 unsigned int crefs;
02275 bfd_byte *p;
02276
02277
02278 size = 0;
02279 crefs = 0;
02280 for (t = elf_tdata (output_bfd)->verref;
02281 t != NULL;
02282 t = t->vn_nextref)
02283 {
02284 Elf_Internal_Vernaux *a;
02285
02286 size += sizeof (Elf_External_Verneed);
02287 ++crefs;
02288 for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
02289 size += sizeof (Elf_External_Vernaux);
02290 }
02291
02292 s->_raw_size = size;
02293 s->contents = bfd_alloc (output_bfd, s->_raw_size);
02294 if (s->contents == NULL)
02295 return FALSE;
02296
02297 p = s->contents;
02298 for (t = elf_tdata (output_bfd)->verref;
02299 t != NULL;
02300 t = t->vn_nextref)
02301 {
02302 unsigned int caux;
02303 Elf_Internal_Vernaux *a;
02304 bfd_size_type indx;
02305
02306 caux = 0;
02307 for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
02308 ++caux;
02309
02310 t->vn_version = VER_NEED_CURRENT;
02311 t->vn_cnt = caux;
02312 indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
02313 elf_dt_name (t->vn_bfd) != NULL
02314 ? elf_dt_name (t->vn_bfd)
02315 : basename (t->vn_bfd->filename),
02316 FALSE);
02317 if (indx == (bfd_size_type) -1)
02318 return FALSE;
02319 t->vn_file = indx;
02320 t->vn_aux = sizeof (Elf_External_Verneed);
02321 if (t->vn_nextref == NULL)
02322 t->vn_next = 0;
02323 else
02324 t->vn_next = (sizeof (Elf_External_Verneed)
02325 + caux * sizeof (Elf_External_Vernaux));
02326
02327 _bfd_elf_swap_verneed_out (output_bfd, t,
02328 (Elf_External_Verneed *) p);
02329 p += sizeof (Elf_External_Verneed);
02330
02331 for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
02332 {
02333 a->vna_hash = bfd_elf_hash (a->vna_nodename);
02334 indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
02335 a->vna_nodename, FALSE);
02336 if (indx == (bfd_size_type) -1)
02337 return FALSE;
02338 a->vna_name = indx;
02339 if (a->vna_nextptr == NULL)
02340 a->vna_next = 0;
02341 else
02342 a->vna_next = sizeof (Elf_External_Vernaux);
02343
02344 _bfd_elf_swap_vernaux_out (output_bfd, a,
02345 (Elf_External_Vernaux *) p);
02346 p += sizeof (Elf_External_Vernaux);
02347 }
02348 }
02349
02350 if (! elf_add_dynamic_entry (info, DT_VERNEED, 0)
02351 || ! elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs))
02352 return FALSE;
02353
02354 elf_tdata (output_bfd)->cverrefs = crefs;
02355 }
02356 }
02357
02358
02359
02360
02361
02362
02363 dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
02364
02365
02366 s = bfd_get_section_by_name (dynobj, ".gnu.version");
02367 BFD_ASSERT (s != NULL);
02368 if (dynsymcount == 0
02369 || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
02370 {
02371 _bfd_strip_section_from_output (info, s);
02372
02373
02374 dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
02375 }
02376 else
02377 {
02378 s->_raw_size = dynsymcount * sizeof (Elf_External_Versym);
02379 s->contents = bfd_zalloc (output_bfd, s->_raw_size);
02380 if (s->contents == NULL)
02381 return FALSE;
02382
02383 if (! elf_add_dynamic_entry (info, DT_VERSYM, 0))
02384 return FALSE;
02385 }
02386
02387
02388
02389
02390
02391
02392
02393 s = bfd_get_section_by_name (dynobj, ".dynsym");
02394 BFD_ASSERT (s != NULL);
02395 s->_raw_size = dynsymcount * sizeof (Elf_External_Sym);
02396 s->contents = bfd_alloc (output_bfd, s->_raw_size);
02397 if (s->contents == NULL && s->_raw_size != 0)
02398 return FALSE;
02399
02400 if (dynsymcount != 0)
02401 {
02402 Elf_Internal_Sym isym;
02403
02404
02405 isym.st_value = 0;
02406 isym.st_size = 0;
02407 isym.st_name = 0;
02408 isym.st_info = 0;
02409 isym.st_other = 0;
02410 isym.st_shndx = 0;
02411 elf_swap_symbol_out (output_bfd, &isym, s->contents, 0);
02412 }
02413
02414
02415
02416 bucketcount = compute_bucket_count (info);
02417
02418 s = bfd_get_section_by_name (dynobj, ".hash");
02419 BFD_ASSERT (s != NULL);
02420 hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
02421 s->_raw_size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
02422 s->contents = bfd_zalloc (output_bfd, s->_raw_size);
02423 if (s->contents == NULL)
02424 return FALSE;
02425
02426 bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
02427 bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
02428 s->contents + hash_entry_size);
02429
02430 elf_hash_table (info)->bucketcount = bucketcount;
02431
02432 s = bfd_get_section_by_name (dynobj, ".dynstr");
02433 BFD_ASSERT (s != NULL);
02434
02435 elf_finalize_dynstr (output_bfd, info);
02436
02437 s->_raw_size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
02438
02439 for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount)
02440 if (! elf_add_dynamic_entry (info, DT_NULL, 0))
02441 return FALSE;
02442 }
02443
02444 return TRUE;
02445 }
02446
02447
02448
02449
02450 static bfd_boolean
02451 elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data)
02452 {
02453 struct elf_strtab_hash *dynstr = data;
02454
02455 if (h->root.type == bfd_link_hash_warning)
02456 h = (struct elf_link_hash_entry *) h->root.u.i.link;
02457
02458 if (h->dynindx != -1)
02459 h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index);
02460 return TRUE;
02461 }
02462
02463
02464
02465
02466 static bfd_boolean
02467 elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
02468 {
02469 struct elf_link_local_dynamic_entry *entry;
02470 struct elf_strtab_hash *dynstr = elf_hash_table (info)->dynstr;
02471 bfd *dynobj = elf_hash_table (info)->dynobj;
02472 asection *sdyn;
02473 bfd_size_type size;
02474 Elf_External_Dyn *dyncon, *dynconend;
02475
02476 _bfd_elf_strtab_finalize (dynstr);
02477 size = _bfd_elf_strtab_size (dynstr);
02478
02479
02480 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
02481 BFD_ASSERT (sdyn != NULL);
02482
02483 dyncon = (Elf_External_Dyn *) sdyn->contents;
02484 dynconend = (Elf_External_Dyn *) (sdyn->contents +
02485 sdyn->_raw_size);
02486 for (; dyncon < dynconend; dyncon++)
02487 {
02488 Elf_Internal_Dyn dyn;
02489
02490 elf_swap_dyn_in (dynobj, dyncon, & dyn);
02491 switch (dyn.d_tag)
02492 {
02493 case DT_STRSZ:
02494 dyn.d_un.d_val = size;
02495 elf_swap_dyn_out (dynobj, & dyn, dyncon);
02496 break;
02497 case DT_NEEDED:
02498 case DT_SONAME:
02499 case DT_RPATH:
02500 case DT_RUNPATH:
02501 case DT_FILTER:
02502 case DT_AUXILIARY:
02503 dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
02504 elf_swap_dyn_out (dynobj, & dyn, dyncon);
02505 break;
02506 default:
02507 break;
02508 }
02509 }
02510
02511
02512 for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next)
02513 entry->isym.st_name = _bfd_elf_strtab_offset (dynstr,
02514 entry->isym.st_name);
02515
02516
02517 elf_link_hash_traverse (elf_hash_table (info),
02518 elf_adjust_dynstr_offsets, dynstr);
02519
02520
02521 if (elf_tdata (output_bfd)->cverdefs)
02522 {
02523 asection *s;
02524 bfd_byte *p;
02525 bfd_size_type i;
02526 Elf_Internal_Verdef def;
02527 Elf_Internal_Verdaux defaux;
02528
02529 s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
02530 p = (bfd_byte *) s->contents;
02531 do
02532 {
02533 _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p,
02534 &def);
02535 p += sizeof (Elf_External_Verdef);
02536 for (i = 0; i < def.vd_cnt; ++i)
02537 {
02538 _bfd_elf_swap_verdaux_in (output_bfd,
02539 (Elf_External_Verdaux *) p, &defaux);
02540 defaux.vda_name = _bfd_elf_strtab_offset (dynstr,
02541 defaux.vda_name);
02542 _bfd_elf_swap_verdaux_out (output_bfd,
02543 &defaux, (Elf_External_Verdaux *) p);
02544 p += sizeof (Elf_External_Verdaux);
02545 }
02546 }
02547 while (def.vd_next);
02548 }
02549
02550
02551 if (elf_tdata (output_bfd)->verref)
02552 {
02553 asection *s;
02554 bfd_byte *p;
02555 bfd_size_type i;
02556 Elf_Internal_Verneed need;
02557 Elf_Internal_Vernaux needaux;
02558
02559 s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
02560 p = (bfd_byte *) s->contents;
02561 do
02562 {
02563 _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p,
02564 &need);
02565 need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file);
02566 _bfd_elf_swap_verneed_out (output_bfd, &need,
02567 (Elf_External_Verneed *) p);
02568 p += sizeof (Elf_External_Verneed);
02569 for (i = 0; i < need.vn_cnt; ++i)
02570 {
02571 _bfd_elf_swap_vernaux_in (output_bfd,
02572 (Elf_External_Vernaux *) p, &needaux);
02573 needaux.vna_name = _bfd_elf_strtab_offset (dynstr,
02574 needaux.vna_name);
02575 _bfd_elf_swap_vernaux_out (output_bfd,
02576 &needaux,
02577 (Elf_External_Vernaux *) p);
02578 p += sizeof (Elf_External_Vernaux);
02579 }
02580 }
02581 while (need.vn_next);
02582 }
02583
02584 return TRUE;
02585 }
02586
02587
02588
02589
02590
02591 struct elf_final_link_info
02592 {
02593
02594 struct bfd_link_info *info;
02595
02596 bfd *output_bfd;
02597
02598 struct bfd_strtab_hash *symstrtab;
02599
02600 asection *dynsym_sec;
02601
02602 asection *hash_sec;
02603
02604 asection *symver_sec;
02605
02606 bfd_byte *contents;
02607
02608 void *external_relocs;
02609
02610 Elf_Internal_Rela *internal_relocs;
02611
02612
02613 Elf_External_Sym *external_syms;
02614
02615 Elf_External_Sym_Shndx *locsym_shndx;
02616
02617
02618 Elf_Internal_Sym *internal_syms;
02619
02620
02621 long *indices;
02622
02623
02624 asection **sections;
02625
02626 Elf_External_Sym *symbuf;
02627
02628 Elf_External_Sym_Shndx *symshndxbuf;
02629
02630 size_t symbuf_count;
02631
02632 size_t symbuf_size;
02633
02634 size_t shndxbuf_size;
02635 };
02636
02637 static bfd_boolean elf_link_output_sym
02638 (struct elf_final_link_info *, const char *, Elf_Internal_Sym *, asection *,
02639 struct elf_link_hash_entry *);
02640 static bfd_boolean elf_link_flush_output_syms
02641 (struct elf_final_link_info *);
02642 static bfd_boolean elf_link_output_extsym
02643 (struct elf_link_hash_entry *, void *);
02644 static bfd_boolean elf_link_input_bfd
02645 (struct elf_final_link_info *, bfd *);
02646 static bfd_boolean elf_reloc_link_order
02647 (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *);
02648
02649
02650
02651 struct elf_outext_info
02652 {
02653 bfd_boolean failed;
02654 bfd_boolean localsyms;
02655 struct elf_final_link_info *finfo;
02656 };
02657
02658
02659
02660
02661
02662
02663 static void
02664 elf_link_adjust_relocs (bfd *abfd,
02665 Elf_Internal_Shdr *rel_hdr,
02666 unsigned int count,
02667 struct elf_link_hash_entry **rel_hash)
02668 {
02669 unsigned int i;
02670 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02671 bfd_byte *erela;
02672 void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
02673 void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
02674
02675 if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel))
02676 {
02677 swap_in = bed->s->swap_reloc_in;
02678 swap_out = bed->s->swap_reloc_out;
02679 }
02680 else if (rel_hdr->sh_entsize == sizeof (Elf_External_Rela))
02681 {
02682 swap_in = bed->s->swap_reloca_in;
02683 swap_out = bed->s->swap_reloca_out;
02684 }
02685 else
02686 abort ();
02687
02688 if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL)
02689 abort ();
02690
02691 erela = rel_hdr->contents;
02692 for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize)
02693 {
02694 Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL];
02695 unsigned int j;
02696
02697 if (*rel_hash == NULL)
02698 continue;
02699
02700 BFD_ASSERT ((*rel_hash)->indx >= 0);
02701
02702 (*swap_in) (abfd, erela, irela);
02703 for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
02704 irela[j].r_info = ELF_R_INFO ((*rel_hash)->indx,
02705 ELF_R_TYPE (irela[j].r_info));
02706 (*swap_out) (abfd, irela, erela);
02707 }
02708 }
02709
02710 struct elf_link_sort_rela
02711 {
02712 bfd_vma offset;
02713 enum elf_reloc_type_class type;
02714
02715 Elf_Internal_Rela rela[1];
02716 };
02717
02718 static int
02719 elf_link_sort_cmp1 (const void *A, const void *B)
02720 {
02721 const struct elf_link_sort_rela *a = A;
02722 const struct elf_link_sort_rela *b = B;
02723 int relativea, relativeb;
02724
02725 relativea = a->type == reloc_class_relative;
02726 relativeb = b->type == reloc_class_relative;
02727
02728 if (relativea < relativeb)
02729 return 1;
02730 if (relativea > relativeb)
02731 return -1;
02732 if (ELF_R_SYM (a->rela->r_info) < ELF_R_SYM (b->rela->r_info))
02733 return -1;
02734 if (ELF_R_SYM (a->rela->r_info) > ELF_R_SYM (b->rela->r_info))
02735 return 1;
02736 if (a->rela->r_offset < b->rela->r_offset)
02737 return -1;
02738 if (a->rela->r_offset > b->rela->r_offset)
02739 return 1;
02740 return 0;
02741 }
02742
02743 static int
02744 elf_link_sort_cmp2 (const void *A, const void *B)
02745 {
02746 const struct elf_link_sort_rela *a = A;
02747 const struct elf_link_sort_rela *b = B;
02748 int copya, copyb;
02749
02750 if (a->offset < b->offset)
02751 return -1;
02752 if (a->offset > b->offset)
02753 return 1;
02754 copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt);
02755 copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt);
02756 if (copya < copyb)
02757 return -1;
02758 if (copya > copyb)
02759 return 1;
02760 if (a->rela->r_offset < b->rela->r_offset)
02761 return -1;
02762 if (a->rela->r_offset > b->rela->r_offset)
02763 return 1;
02764 return 0;
02765 }
02766
02767 static size_t
02768 elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
02769 {
02770 asection *reldyn;
02771 bfd_size_type count, size;
02772 size_t i, ret, sort_elt, ext_size;
02773 bfd_byte *sort, *s_non_relative, *p;
02774 struct elf_link_sort_rela *sq;
02775 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02776 int i2e = bed->s->int_rels_per_ext_rel;
02777 void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
02778 void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
02779 struct bfd_link_order *lo;
02780
02781 reldyn = bfd_get_section_by_name (abfd, ".rela.dyn");
02782 if (reldyn == NULL || reldyn->_raw_size == 0)
02783 {
02784 reldyn = bfd_get_section_by_name (abfd, ".rel.dyn");
02785 if (reldyn == NULL || reldyn->_raw_size == 0)
02786 return 0;
02787 ext_size = sizeof (Elf_External_Rel);
02788 swap_in = bed->s->swap_reloc_in;
02789 swap_out = bed->s->swap_reloc_out;
02790 }
02791 else
02792 {
02793 ext_size = sizeof (Elf_External_Rela);
02794 swap_in = bed->s->swap_reloca_in;
02795 swap_out = bed->s->swap_reloca_out;
02796 }
02797 count = reldyn->_raw_size / ext_size;
02798
02799 size = 0;
02800 for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
02801 if (lo->type == bfd_indirect_link_order)
02802 {
02803 asection *o = lo->u.indirect.section;
02804 size += o->_raw_size;
02805 }
02806
02807 if (size != reldyn->_raw_size)
02808 return 0;
02809
02810 sort_elt = (sizeof (struct elf_link_sort_rela)
02811 + (i2e - 1) * sizeof (Elf_Internal_Rela));
02812 sort = bfd_zmalloc (sort_elt * count);
02813 if (sort == NULL)
02814 {
02815 (*info->callbacks->warning)
02816 (info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0);
02817 return 0;
02818 }
02819
02820 for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
02821 if (lo->type == bfd_indirect_link_order)
02822 {
02823 bfd_byte *erel, *erelend;
02824 asection *o = lo->u.indirect.section;
02825
02826 erel = o->contents;
02827 erelend = o->contents + o->_raw_size;
02828 p = sort + o->output_offset / ext_size * sort_elt;
02829 while (erel < erelend)
02830 {
02831 struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
02832 (*swap_in) (abfd, erel, s->rela);
02833 s->type = (*bed->elf_backend_reloc_type_class) (s->rela);
02834 p += sort_elt;
02835 erel += ext_size;
02836 }
02837 }
02838
02839 qsort (sort, count, sort_elt, elf_link_sort_cmp1);
02840
02841 for (i = 0, p = sort; i < count; i++, p += sort_elt)
02842 {
02843 struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
02844 if (s->type != reloc_class_relative)
02845 break;
02846 }
02847 ret = i;
02848 s_non_relative = p;
02849
02850 sq = (struct elf_link_sort_rela *) s_non_relative;
02851 for (; i < count; i++, p += sort_elt)
02852 {
02853 struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p;
02854 if (ELF_R_SYM (sp->rela->r_info) != ELF_R_SYM (sq->rela->r_info))
02855 sq = sp;
02856 sp->offset = sq->rela->r_offset;
02857 }
02858
02859 qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
02860
02861 for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
02862 if (lo->type == bfd_indirect_link_order)
02863 {
02864 bfd_byte *erel, *erelend;
02865 asection *o = lo->u.indirect.section;
02866
02867 erel = o->contents;
02868 erelend = o->contents + o->_raw_size;
02869 p = sort + o->output_offset / ext_size * sort_elt;
02870 while (erel < erelend)
02871 {
02872 struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
02873 (*swap_out) (abfd, s->rela, erel);
02874 p += sort_elt;
02875 erel += ext_size;
02876 }
02877 }
02878
02879 free (sort);
02880 *psec = reldyn;
02881 return ret;
02882 }
02883
02884
02885
02886 bfd_boolean
02887 elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
02888 {
02889 bfd_boolean dynamic;
02890 bfd_boolean emit_relocs;
02891 bfd *dynobj;
02892 struct elf_final_link_info finfo;
02893 register asection *o;
02894 register struct bfd_link_order *p;
02895 register bfd *sub;
02896 bfd_size_type max_contents_size;
02897 bfd_size_type max_external_reloc_size;
02898 bfd_size_type max_internal_reloc_count;
02899 bfd_size_type max_sym_count;
02900 bfd_size_type max_sym_shndx_count;
02901 file_ptr off;
02902 Elf_Internal_Sym elfsym;
02903 unsigned int i;
02904 Elf_Internal_Shdr *symtab_hdr;
02905 Elf_Internal_Shdr *symtab_shndx_hdr;
02906 Elf_Internal_Shdr *symstrtab_hdr;
02907 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02908 struct elf_outext_info eoinfo;
02909 bfd_boolean merged;
02910 size_t relativecount = 0;
02911 asection *reldyn = 0;
02912 bfd_size_type amt;
02913
02914 if (! is_elf_hash_table (info->hash))
02915 return FALSE;
02916
02917 if (info->shared)
02918 abfd->flags |= DYNAMIC;
02919
02920 dynamic = elf_hash_table (info)->dynamic_sections_created;
02921 dynobj = elf_hash_table (info)->dynobj;
02922
02923 emit_relocs = (info->relocatable
02924 || info->emitrelocations
02925 || bed->elf_backend_emit_relocs);
02926
02927 finfo.info = info;
02928 finfo.output_bfd = abfd;
02929 finfo.symstrtab = elf_stringtab_init ();
02930 if (finfo.symstrtab == NULL)
02931 return FALSE;
02932
02933 if (! dynamic)
02934 {
02935 finfo.dynsym_sec = NULL;
02936 finfo.hash_sec = NULL;
02937 finfo.symver_sec = NULL;
02938 }
02939 else
02940 {
02941 finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym");
02942 finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash");
02943 BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL);
02944 finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version");
02945
02946 }
02947
02948 finfo.contents = NULL;
02949 finfo.external_relocs = NULL;
02950 finfo.internal_relocs = NULL;
02951 finfo.external_syms = NULL;
02952 finfo.locsym_shndx = NULL;
02953 finfo.internal_syms = NULL;
02954 finfo.indices = NULL;
02955 finfo.sections = NULL;
02956 finfo.symbuf = NULL;
02957 finfo.symshndxbuf = NULL;
02958 finfo.symbuf_count = 0;
02959 finfo.shndxbuf_size = 0;
02960
02961
02962
02963
02964 max_contents_size = 0;
02965 max_external_reloc_size = 0;
02966 max_internal_reloc_count = 0;
02967 max_sym_count = 0;
02968 max_sym_shndx_count = 0;
02969 merged = FALSE;
02970 for (o = abfd->sections; o != NULL; o = o->next)
02971 {
02972 struct bfd_elf_section_data *esdo = elf_section_data (o);
02973 o->reloc_count = 0;
02974
02975 for (p = o->link_order_head; p != NULL; p = p->next)
02976 {
02977 unsigned int reloc_count = 0;
02978 struct bfd_elf_section_data *esdi = NULL;
02979 unsigned int *rel_count1;
02980
02981 if (p->type == bfd_section_reloc_link_order
02982 || p->type == bfd_symbol_reloc_link_order)
02983 reloc_count = 1;
02984 else if (p->type == bfd_indirect_link_order)
02985 {
02986 asection *sec;
02987
02988 sec = p->u.indirect.section;
02989 esdi = elf_section_data (sec);
02990
02991
02992
02993
02994
02995 sec->linker_mark = TRUE;
02996
02997 if (sec->flags & SEC_MERGE)
02998 merged = TRUE;
02999
03000 if (info->relocatable || info->emitrelocations)
03001 reloc_count = sec->reloc_count;
03002 else if (bed->elf_backend_count_relocs)
03003 {
03004 Elf_Internal_Rela * relocs;
03005
03006 relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
03007 info->keep_memory);
03008
03009 reloc_count = (*bed->elf_backend_count_relocs) (sec, relocs);
03010
03011 if (elf_section_data (o)->relocs != relocs)
03012 free (relocs);
03013 }
03014
03015 if (sec->_raw_size > max_contents_size)
03016 max_contents_size = sec->_raw_size;
03017 if (sec->_cooked_size > max_contents_size)
03018 max_contents_size = sec->_cooked_size;
03019
03020
03021
03022 if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
03023 && (sec->owner->flags & DYNAMIC) == 0)
03024 {
03025 size_t sym_count;
03026
03027 if (elf_bad_symtab (sec->owner))
03028 sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size
03029 / sizeof (Elf_External_Sym));
03030 else
03031 sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info;
03032
03033 if (sym_count > max_sym_count)
03034 max_sym_count = sym_count;
03035
03036 if (sym_count > max_sym_shndx_count
03037 && elf_symtab_shndx (sec->owner) != 0)
03038 max_sym_shndx_count = sym_count;
03039
03040 if ((sec->flags & SEC_RELOC) != 0)
03041 {
03042 size_t ext_size;
03043
03044 ext_size = elf_section_data (sec)->rel_hdr.sh_size;
03045 if (ext_size > max_external_reloc_size)
03046 max_external_reloc_size = ext_size;
03047 if (sec->reloc_count > max_internal_reloc_count)
03048 max_internal_reloc_count = sec->reloc_count;
03049 }
03050 }
03051 }
03052
03053 if (reloc_count == 0)
03054 continue;
03055
03056 o->reloc_count += reloc_count;
03057
03058
03059
03060
03061
03062
03063
03064 rel_count1 = &esdo->rel_count;
03065 if (esdi != NULL)
03066 {
03067 bfd_boolean same_size;
03068 bfd_size_type entsize1;
03069
03070 entsize1 = esdi->rel_hdr.sh_entsize;
03071 BFD_ASSERT (entsize1 == sizeof (Elf_External_Rel)
03072 || entsize1 == sizeof (Elf_External_Rela));
03073 same_size = (!o->use_rela_p
03074 == (entsize1 == sizeof (Elf_External_Rel)));
03075
03076 if (!same_size)
03077 rel_count1 = &esdo->rel_count2;
03078
03079 if (esdi->rel_hdr2 != NULL)
03080 {
03081 bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize;
03082 unsigned int alt_count;
03083 unsigned int *rel_count2;
03084
03085 BFD_ASSERT (entsize2 != entsize1
03086 && (entsize2 == sizeof (Elf_External_Rel)
03087 || entsize2 == sizeof (Elf_External_Rela)));
03088
03089 rel_count2 = &esdo->rel_count2;
03090 if (!same_size)
03091 rel_count2 = &esdo->rel_count;
03092
03093
03094
03095 BFD_ASSERT (bed->elf_backend_count_relocs == NULL);
03096 alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2);
03097 *rel_count2 += alt_count;
03098 reloc_count -= alt_count;
03099 }
03100 }
03101 *rel_count1 += reloc_count;
03102 }
03103
03104 if (o->reloc_count > 0)
03105 o->flags |= SEC_RELOC;
03106 else
03107 {
03108
03109
03110
03111 o->flags &=~ SEC_RELOC;
03112 }
03113
03114
03115
03116
03117
03118 if ((o->flags & SEC_ALLOC) == 0
03119 && ! o->user_set_vma)
03120 o->vma = 0;
03121 }
03122
03123 if (! info->relocatable && merged)
03124 elf_link_hash_traverse (elf_hash_table (info),
03125 _bfd_elf_link_sec_merge_syms, abfd);
03126
03127
03128
03129
03130 bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1;
03131 BFD_ASSERT (! abfd->output_has_begun);
03132 if (! _bfd_elf_compute_section_file_positions (abfd, info))
03133 goto error_return;
03134
03135
03136
03137 for (o = abfd->sections; o != NULL; o = o->next)
03138 {
03139 if ((o->flags & SEC_RELOC) != 0)
03140 {
03141 if (!(_bfd_elf_link_size_reloc_section
03142 (abfd, &elf_section_data (o)->rel_hdr, o)))
03143 goto error_return;
03144
03145 if (elf_section_data (o)->rel_hdr2
03146 && !(_bfd_elf_link_size_reloc_section
03147 (abfd, elf_section_data (o)->rel_hdr2, o)))
03148 goto error_return;
03149 }
03150
03151
03152
03153 elf_section_data (o)->rel_count = 0;
03154 elf_section_data (o)->rel_count2 = 0;
03155 }
03156
03157 _bfd_elf_assign_file_positions_for_relocs (abfd);
03158
03159
03160
03161
03162
03163 bfd_get_symcount (abfd) = 0;
03164 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
03165
03166 symtab_hdr->sh_type = SHT_SYMTAB;
03167
03168 symtab_hdr->sh_entsize = sizeof (Elf_External_Sym);
03169
03170
03171
03172 symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
03173
03174 off = elf_tdata (abfd)->next_file_pos;
03175 off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
03176
03177
03178
03179
03180
03181
03182
03183 if (! info->keep_memory || max_sym_count < 20)
03184 finfo.symbuf_size = 20;
03185 else
03186 finfo.symbuf_size = max_sym_count;
03187 amt = finfo.symbuf_size;
03188 amt *= sizeof (Elf_External_Sym);
03189 finfo.symbuf = bfd_malloc (amt);
03190 if (finfo.symbuf == NULL)
03191 goto error_return;
03192 if (elf_numsections (abfd) > SHN_LORESERVE)
03193 {
03194
03195 amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
03196 finfo.shndxbuf_size = amt;
03197 amt *= sizeof (Elf_External_Sym_Shndx);
03198 finfo.symshndxbuf = bfd_zmalloc (amt);
03199 if (finfo.symshndxbuf == NULL)
03200 goto error_return;
03201 }
03202
03203
03204
03205 if (info->strip != strip_all
03206 || emit_relocs)
03207 {
03208 elfsym.st_value = 0;
03209 elfsym.st_size = 0;
03210 elfsym.st_info = 0;
03211 elfsym.st_other = 0;
03212 elfsym.st_shndx = SHN_UNDEF;
03213 if (! elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr,
03214 NULL))
03215 goto error_return;
03216 }
03217
03218 #if 0
03219
03220
03221
03222
03223
03224 elfsym.st_value = 0;
03225 elfsym.st_size = 0;
03226 elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
03227 elfsym.st_other = 0;
03228 elfsym.st_shndx = SHN_ABS;
03229 if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd),
03230 &elfsym, bfd_abs_section_ptr, NULL))
03231 goto error_return;
03232 #endif
03233
03234
03235
03236
03237
03238
03239 if (info->strip != strip_all
03240 || emit_relocs)
03241 {
03242 elfsym.st_size = 0;
03243 elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
03244 elfsym.st_other = 0;
03245 for (i = 1; i < elf_numsections (abfd); i++)
03246 {
03247 o = section_from_elf_index (abfd, i);
03248 if (o != NULL)
03249 o->target_index = bfd_get_symcount (abfd);
03250 elfsym.st_shndx = i;
03251 if (info->relocatable || o == NULL)
03252 elfsym.st_value = 0;
03253 else
03254 elfsym.st_value = o->vma;
03255 if (! elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL))
03256 goto error_return;
03257 if (i == SHN_LORESERVE - 1)
03258 i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
03259 }
03260 }
03261
03262
03263
03264 if (max_contents_size != 0)
03265 {
03266 finfo.contents = bfd_malloc (max_contents_size);
03267 if (finfo.contents == NULL)
03268 goto error_return;
03269 }
03270
03271 if (max_external_reloc_size != 0)
03272 {
03273 finfo.external_relocs = bfd_malloc (max_external_reloc_size);
03274 if (finfo.external_relocs == NULL)
03275 goto error_return;
03276 }
03277
03278 if (max_internal_reloc_count != 0)
03279 {
03280 amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel;
03281 amt *= sizeof (Elf_Internal_Rela);
03282 finfo.internal_relocs = bfd_malloc (amt);
03283 if (finfo.internal_relocs == NULL)
03284 goto error_return;
03285 }
03286
03287 if (max_sym_count != 0)
03288 {
03289 amt = max_sym_count * sizeof (Elf_External_Sym);
03290 finfo.external_syms = bfd_malloc (amt);
03291 if (finfo.external_syms == NULL)
03292 goto error_return;
03293
03294 amt = max_sym_count * sizeof (Elf_Internal_Sym);
03295 finfo.internal_syms = bfd_malloc (amt);
03296 if (finfo.internal_syms == NULL)
03297 goto error_return;
03298
03299 amt = max_sym_count * sizeof (long);
03300 finfo.indices = bfd_malloc (amt);
03301 if (finfo.indices == NULL)
03302 goto error_return;
03303
03304 amt = max_sym_count * sizeof (asection *);
03305 finfo.sections = bfd_malloc (amt);
03306 if (finfo.sections == NULL)
03307 goto error_return;
03308 }
03309
03310 if (max_sym_shndx_count != 0)
03311 {
03312 amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx);
03313 finfo.locsym_shndx = bfd_malloc (amt);
03314 if (finfo.locsym_shndx == NULL)
03315 goto error_return;
03316 }
03317
03318 if (elf_hash_table (info)->tls_sec)
03319 {
03320 bfd_vma base, end = 0;
03321 asection *sec;
03322
03323 for (sec = elf_hash_table (info)->tls_sec;
03324 sec && (sec->flags & SEC_THREAD_LOCAL);
03325 sec = sec->next)
03326 {
03327 bfd_vma size = sec->_raw_size;
03328
03329 if (size == 0 && (sec->flags & SEC_HAS_CONTENTS) == 0)
03330 {
03331 struct bfd_link_order *o;
03332
03333 for (o = sec->link_order_head; o != NULL; o = o->next)
03334 if (size < o->offset + o->size)
03335 size = o->offset + o->size;
03336 }
03337 end = sec->vma + size;
03338 }
03339 base = elf_hash_table (info)->tls_sec->vma;
03340 end = align_power (end, elf_hash_table (info)->tls_sec->alignment_power);
03341 elf_hash_table (info)->tls_size = end - base;
03342 }
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
03365 sub->output_has_begun = FALSE;
03366 for (o = abfd->sections; o != NULL; o = o->next)
03367 {
03368 for (p = o->link_order_head; p != NULL; p = p->next)
03369 {
03370 if (p->type == bfd_indirect_link_order
03371 && (bfd_get_flavour ((sub = p->u.indirect.section->owner))
03372 == bfd_target_elf_flavour)
03373 && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass)
03374 {
03375 if (! sub->output_has_begun)
03376 {
03377 if (! elf_link_input_bfd (&finfo, sub))
03378 goto error_return;
03379 sub->output_has_begun = TRUE;
03380 }
03381 }
03382 else if (p->type == bfd_section_reloc_link_order
03383 || p->type == bfd_symbol_reloc_link_order)
03384 {
03385 if (! elf_reloc_link_order (abfd, info, o, p))
03386 goto error_return;
03387 }
03388 else
03389 {
03390 if (! _bfd_default_link_order (abfd, info, o, p))
03391 goto error_return;
03392 }
03393 }
03394 }
03395
03396
03397
03398
03399
03400
03401
03402 eoinfo.failed = FALSE;
03403 eoinfo.finfo = &finfo;
03404 eoinfo.localsyms = TRUE;
03405 elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym,
03406 &eoinfo);
03407 if (eoinfo.failed)
03408 return FALSE;
03409
03410
03411
03412
03413
03414
03415
03416 symtab_hdr->sh_info = bfd_get_symcount (abfd);
03417
03418 if (dynamic
03419 && finfo.dynsym_sec->output_section != bfd_abs_section_ptr)
03420 {
03421 Elf_Internal_Sym sym;
03422 Elf_External_Sym *dynsym =
03423 (Elf_External_Sym *) finfo.dynsym_sec->contents;
03424 long last_local = 0;
03425
03426
03427 if (info->shared)
03428 {
03429 asection *s;
03430
03431 sym.st_size = 0;
03432 sym.st_name = 0;
03433 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
03434 sym.st_other = 0;
03435
03436 for (s = abfd->sections; s != NULL; s = s->next)
03437 {
03438 int indx;
03439 Elf_External_Sym *dest;
03440
03441 indx = elf_section_data (s)->this_idx;
03442 BFD_ASSERT (indx > 0);
03443 sym.st_shndx = indx;
03444 sym.st_value = s->vma;
03445 dest = dynsym + elf_section_data (s)->dynindx;
03446 elf_swap_symbol_out (abfd, &sym, dest, 0);
03447 }
03448
03449 last_local = bfd_count_sections (abfd);
03450 }
03451
03452
03453 if (elf_hash_table (info)->dynlocal)
03454 {
03455 struct elf_link_local_dynamic_entry *e;
03456 for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
03457 {
03458 asection *s;
03459 Elf_External_Sym *dest;
03460
03461 sym.st_size = e->isym.st_size;
03462 sym.st_other = e->isym.st_other;
03463
03464
03465
03466
03467 sym = e->isym;
03468
03469 if (e->isym.st_shndx != SHN_UNDEF
03470 && (e->isym.st_shndx < SHN_LORESERVE
03471 || e->isym.st_shndx > SHN_HIRESERVE))
03472 {
03473 s = bfd_section_from_elf_index (e->input_bfd,
03474 e->isym.st_shndx);
03475
03476 sym.st_shndx =
03477 elf_section_data (s->output_section)->this_idx;
03478 sym.st_value = (s->output_section->vma
03479 + s->output_offset
03480 + e->isym.st_value);
03481 }
03482
03483 if (last_local < e->dynindx)
03484 last_local = e->dynindx;
03485
03486 dest = dynsym + e->dynindx;
03487 elf_swap_symbol_out (abfd, &sym, dest, 0);
03488 }
03489 }
03490
03491 elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info =
03492 last_local + 1;
03493 }
03494
03495
03496 eoinfo.failed = FALSE;
03497 eoinfo.localsyms = FALSE;
03498 eoinfo.finfo = &finfo;
03499 elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym,
03500 &eoinfo);
03501 if (eoinfo.failed)
03502 return FALSE;
03503
03504
03505
03506 if (bed->elf_backend_output_arch_syms)
03507 {
03508 typedef bfd_boolean (*out_sym_func)
03509 (void *, const char *, Elf_Internal_Sym *, asection *,
03510 struct elf_link_hash_entry *);
03511
03512 if (! ((*bed->elf_backend_output_arch_syms)
03513 (abfd, info, &finfo, (out_sym_func) elf_link_output_sym)))
03514 return FALSE;
03515 }
03516
03517
03518 if (! elf_link_flush_output_syms (&finfo))
03519 return FALSE;
03520
03521
03522 off += symtab_hdr->sh_size;
03523
03524 symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
03525 if (symtab_shndx_hdr->sh_name != 0)
03526 {
03527 symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
03528 symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
03529 symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
03530 amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx);
03531 symtab_shndx_hdr->sh_size = amt;
03532
03533 off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr,
03534 off, TRUE);
03535
03536 if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0
03537 || (bfd_bwrite (finfo.symshndxbuf, amt, abfd) != amt))
03538 return FALSE;
03539 }
03540
03541
03542
03543
03544 symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
03545
03546 symstrtab_hdr->sh_type = SHT_STRTAB;
03547 symstrtab_hdr->sh_flags = 0;
03548 symstrtab_hdr->sh_addr = 0;
03549 symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab);
03550 symstrtab_hdr->sh_entsize = 0;
03551 symstrtab_hdr->sh_link = 0;
03552 symstrtab_hdr->sh_info = 0;
03553
03554 symstrtab_hdr->sh_addralign = 1;
03555
03556 off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE);
03557 elf_tdata (abfd)->next_file_pos = off;
03558
03559 if (bfd_get_symcount (abfd) > 0)
03560 {
03561 if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0
03562 || ! _bfd_stringtab_emit (abfd, finfo.symstrtab))
03563 return FALSE;
03564 }
03565
03566
03567 for (o = abfd->sections; o != NULL; o = o->next)
03568 {
03569 if ((o->flags & SEC_RELOC) == 0)
03570 continue;
03571
03572 elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr,
03573 elf_section_data (o)->rel_count,
03574 elf_section_data (o)->rel_hashes);
03575 if (elf_section_data (o)->rel_hdr2 != NULL)
03576 elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2,
03577 elf_section_data (o)->rel_count2,
03578 (elf_section_data (o)->rel_hashes
03579 + elf_section_data (o)->rel_count));
03580
03581
03582
03583 o->reloc_count = 0;
03584 }
03585
03586 if (dynamic && info->combreloc && dynobj != NULL)
03587 relativecount = elf_link_sort_relocs (abfd, info, &reldyn);
03588
03589
03590
03591 if (dynamic)
03592 {
03593 Elf_External_Dyn *dyncon, *dynconend;
03594
03595
03596 o = bfd_get_section_by_name (dynobj, ".dynamic");
03597 BFD_ASSERT (o != NULL);
03598
03599 dyncon = (Elf_External_Dyn *) o->contents;
03600 dynconend = (Elf_External_Dyn *) (o->contents + o->_raw_size);
03601 for (; dyncon < dynconend; dyncon++)
03602 {
03603 Elf_Internal_Dyn dyn;
03604 const char *name;
03605 unsigned int type;
03606
03607 elf_swap_dyn_in (dynobj, dyncon, &dyn);
03608
03609 switch (dyn.d_tag)
03610 {
03611 default:
03612 break;
03613 case DT_NULL:
03614 if (relativecount > 0 && dyncon + 1 < dynconend)
03615 {
03616 switch (elf_section_data (reldyn)->this_hdr.sh_type)
03617 {
03618 case SHT_REL: dyn.d_tag = DT_RELCOUNT; break;
03619 case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break;
03620 default: break;
03621 }
03622 if (dyn.d_tag != DT_NULL)
03623 {
03624 dyn.d_un.d_val = relativecount;
03625 elf_swap_dyn_out (dynobj, &dyn, dyncon);
03626 relativecount = 0;
03627 }
03628 }
03629 break;
03630 case DT_INIT:
03631 name = info->init_function;
03632 goto get_sym;
03633 case DT_FINI:
03634 name = info->fini_function;
03635 get_sym:
03636 {
03637 struct elf_link_hash_entry *h;
03638
03639 h = elf_link_hash_lookup (elf_hash_table (info), name,
03640 FALSE, FALSE, TRUE);
03641 if (h != NULL
03642 && (h->root.type == bfd_link_hash_defined
03643 || h->root.type == bfd_link_hash_defweak))
03644 {
03645 dyn.d_un.d_val = h->root.u.def.value;
03646 o = h->root.u.def.section;
03647 if (o->output_section != NULL)
03648 dyn.d_un.d_val += (o->output_section->vma
03649 + o->output_offset);
03650 else
03651 {
03652
03653
03654 dyn.d_un.d_val = 0;
03655 }
03656
03657 elf_swap_dyn_out (dynobj, &dyn, dyncon);
03658 }
03659 }
03660 break;
03661
03662 case DT_PREINIT_ARRAYSZ:
03663 name = ".preinit_array";
03664 goto get_size;
03665 case DT_INIT_ARRAYSZ:
03666 name = ".init_array";
03667 goto get_size;
03668 case DT_FINI_ARRAYSZ:
03669 name = ".fini_array";
03670 get_size:
03671 o = bfd_get_section_by_name (abfd, name);
03672 if (o == NULL)
03673 {
03674 (*_bfd_error_handler)
03675 (_("%s: could not find output section %s"),
03676 bfd_get_filename (abfd), name);
03677 goto error_return;
03678 }
03679 if (o->_raw_size == 0)
03680 (*_bfd_error_handler)
03681 (_("warning: %s section has zero size"), name);
03682 dyn.d_un.d_val = o->_raw_size;
03683 elf_swap_dyn_out (dynobj, &dyn, dyncon);
03684 break;
03685
03686 case DT_PREINIT_ARRAY:
03687 name = ".preinit_array";
03688 goto get_vma;
03689 case DT_INIT_ARRAY:
03690 name = ".init_array";
03691 goto get_vma;
03692 case DT_FINI_ARRAY:
03693 name = ".fini_array";
03694 goto get_vma;
03695
03696 case DT_HASH:
03697 name = ".hash";
03698 goto get_vma;
03699 case DT_STRTAB:
03700 name = ".dynstr";
03701 goto get_vma;
03702 case DT_SYMTAB:
03703 name = ".dynsym";
03704 goto get_vma;
03705 case DT_VERDEF:
03706 name = ".gnu.version_d";
03707 goto get_vma;
03708 case DT_VERNEED:
03709 name = ".gnu.version_r";
03710 goto get_vma;
03711 case DT_VERSYM:
03712 name = ".gnu.version";
03713 get_vma:
03714 o = bfd_get_section_by_name (abfd, name);
03715 if (o == NULL)
03716 {
03717 (*_bfd_error_handler)
03718 (_("%s: could not find output section %s"),
03719 bfd_get_filename (abfd), name);
03720 goto error_return;
03721 }
03722 dyn.d_un.d_ptr = o->vma;
03723 elf_swap_dyn_out (dynobj, &dyn, dyncon);
03724 break;
03725
03726 case DT_REL:
03727 case DT_RELA:
03728 case DT_RELSZ:
03729 case DT_RELASZ:
03730 if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ)
03731 type = SHT_REL;
03732 else
03733 type = SHT_RELA;
03734 dyn.d_un.d_val = 0;
03735 for (i = 1; i < elf_numsections (abfd); i++)
03736 {
03737 Elf_Internal_Shdr *hdr;
03738
03739 hdr = elf_elfsections (abfd)[i];
03740 if (hdr->sh_type == type
03741 && (hdr->sh_flags & SHF_ALLOC) != 0)
03742 {
03743 if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ)
03744 dyn.d_un.d_val += hdr->sh_size;
03745 else
03746 {
03747 if (dyn.d_un.d_val == 0
03748 || hdr->sh_addr < dyn.d_un.d_val)
03749 dyn.d_un.d_val = hdr->sh_addr;
03750 }
03751 }
03752 }
03753 elf_swap_dyn_out (dynobj, &dyn, dyncon);
03754 break;
03755 }
03756 }
03757 }
03758
03759
03760 if (dynobj != NULL)
03761 {
03762 if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info))
03763 goto error_return;
03764
03765 for (o = dynobj->sections; o != NULL; o = o->next)
03766 {
03767 if ((o->flags & SEC_HAS_CONTENTS) == 0
03768 || o->_raw_size == 0
03769 || o->output_section == bfd_abs_section_ptr)
03770 continue;
03771 if ((o->flags & SEC_LINKER_CREATED) == 0)
03772 {
03773
03774
03775 continue;
03776 }
03777 if ((elf_section_data (o->output_section)->this_hdr.sh_type
03778 != SHT_STRTAB)
03779 || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
03780 {
03781 if (! bfd_set_section_contents (abfd, o->output_section,
03782 o->contents,
03783 (file_ptr) o->output_offset,
03784 o->_raw_size))
03785 goto error_return;
03786 }
03787 else
03788 {
03789
03790
03791 off = elf_section_data (o->output_section)->this_hdr.sh_offset;
03792 if (bfd_seek (abfd, off, SEEK_SET) != 0
03793 || ! _bfd_elf_strtab_emit (abfd,
03794 elf_hash_table (info)->dynstr))
03795 goto error_return;
03796 }
03797 }
03798 }
03799
03800 if (info->relocatable)
03801 {
03802 bfd_boolean failed = FALSE;
03803
03804 bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
03805 if (failed)
03806 goto error_return;
03807 }
03808
03809
03810 if (elf_hash_table (info)->stab_info != NULL)
03811 {
03812 if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info))
03813 goto error_return;
03814 }
03815
03816 if (info->eh_frame_hdr)
03817 {
03818 if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info))
03819 goto error_return;
03820 }
03821
03822 if (finfo.symstrtab != NULL)
03823 _bfd_stringtab_free (finfo.symstrtab);
03824 if (finfo.contents != NULL)
03825 free (finfo.contents);
03826 if (finfo.external_relocs != NULL)
03827 free (finfo.external_relocs);
03828 if (finfo.internal_relocs != NULL)
03829 free (finfo.internal_relocs);
03830 if (finfo.external_syms != NULL)
03831 free (finfo.external_syms);
03832 if (finfo.locsym_shndx != NULL)
03833 free (finfo.locsym_shndx);
03834 if (finfo.internal_syms != NULL)
03835 free (finfo.internal_syms);
03836 if (finfo.indices != NULL)
03837 free (finfo.indices);
03838 if (finfo.sections != NULL)
03839 free (finfo.sections);
03840 if (finfo.symbuf != NULL)
03841 free (finfo.symbuf);
03842 if (finfo.symshndxbuf != NULL)
03843 free (finfo.symshndxbuf);
03844 for (o = abfd->sections; o != NULL; o = o->next)
03845 {
03846 if ((o->flags & SEC_RELOC) != 0
03847 && elf_section_data (o)->rel_hashes != NULL)
03848 free (elf_section_data (o)->rel_hashes);
03849 }
03850
03851 elf_tdata (abfd)->linker = TRUE;
03852
03853 return TRUE;
03854
03855 error_return:
03856 if (finfo.symstrtab != NULL)
03857 _bfd_stringtab_free (finfo.symstrtab);
03858 if (finfo.contents != NULL)
03859 free (finfo.contents);
03860 if (finfo.external_relocs != NULL)
03861 free (finfo.external_relocs);
03862 if (finfo.internal_relocs != NULL)
03863 free (finfo.internal_relocs);
03864 if (finfo.external_syms != NULL)
03865 free (finfo.external_syms);
03866 if (finfo.locsym_shndx != NULL)
03867 free (finfo.locsym_shndx);
03868 if (finfo.internal_syms != NULL)
03869 free (finfo.internal_syms);
03870 if (finfo.indices != NULL)
03871 free (finfo.indices);
03872 if (finfo.sections != NULL)
03873 free (finfo.sections);
03874 if (finfo.symbuf != NULL)
03875 free (finfo.symbuf);
03876 if (finfo.symshndxbuf != NULL)
03877 free (finfo.symshndxbuf);
03878 for (o = abfd->sections; o != NULL; o = o->next)
03879 {
03880 if ((o->flags & SEC_RELOC) != 0
03881 && elf_section_data (o)->rel_hashes != NULL)
03882 free (elf_section_data (o)->rel_hashes);
03883 }
03884
03885 return FALSE;
03886 }
03887
03888
03889
03890 static bfd_boolean
03891 elf_link_output_sym (struct elf_final_link_info *finfo,
03892 const char *name,
03893 Elf_Internal_Sym *elfsym,
03894 asection *input_sec,
03895 struct elf_link_hash_entry *h)
03896 {
03897 Elf_External_Sym *dest;
03898 Elf_External_Sym_Shndx *destshndx;
03899 bfd_boolean (*output_symbol_hook)
03900 (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
03901 struct elf_link_hash_entry *);
03902
03903 output_symbol_hook = get_elf_backend_data (finfo->output_bfd)->
03904 elf_backend_link_output_symbol_hook;
03905 if (output_symbol_hook != NULL)
03906 {
03907 if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h))
03908 return FALSE;
03909 }
03910
03911 if (name == NULL || *name == '\0')
03912 elfsym->st_name = 0;
03913 else if (input_sec->flags & SEC_EXCLUDE)
03914 elfsym->st_name = 0;
03915 else
03916 {
03917 elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab,
03918 name, TRUE, FALSE);
03919 if (elfsym->st_name == (unsigned long) -1)
03920 return FALSE;
03921 }
03922
03923 if (finfo->symbuf_count >= finfo->symbuf_size)
03924 {
03925 if (! elf_link_flush_output_syms (finfo))
03926 return FALSE;
03927 }
03928
03929 dest = finfo->symbuf + finfo->symbuf_count;
03930 destshndx = finfo->symshndxbuf;
03931 if (destshndx != NULL)
03932 {
03933 if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size)
03934 {
03935 bfd_size_type amt;
03936
03937 amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
03938 finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2);
03939 if (destshndx == NULL)
03940 return FALSE;
03941 memset ((char *) destshndx + amt, 0, amt);
03942 finfo->shndxbuf_size *= 2;
03943 }
03944 destshndx += bfd_get_symcount (finfo->output_bfd);
03945 }
03946
03947 elf_swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx);
03948 finfo->symbuf_count += 1;
03949 bfd_get_symcount (finfo->output_bfd) += 1;
03950
03951 return TRUE;
03952 }
03953
03954
03955
03956 static bfd_boolean
03957 elf_link_flush_output_syms (struct elf_final_link_info *finfo)
03958 {
03959 if (finfo->symbuf_count > 0)
03960 {
03961 Elf_Internal_Shdr *hdr;
03962 file_ptr pos;
03963 bfd_size_type amt;
03964
03965 hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr;
03966 pos = hdr->sh_offset + hdr->sh_size;
03967 amt = finfo->symbuf_count * sizeof (Elf_External_Sym);
03968 if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0
03969 || bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt)
03970 return FALSE;
03971
03972 hdr->sh_size += amt;
03973 finfo->symbuf_count = 0;
03974 }
03975
03976 return TRUE;
03977 }
03978
03979
03980
03981
03982
03983
03984
03985 static bfd_boolean
03986 elf_link_check_versioned_symbol (struct bfd_link_info *info,
03987 struct elf_link_hash_entry *h)
03988 {
03989 bfd *abfd;
03990 struct elf_link_loaded_list *loaded;
03991
03992 if (!is_elf_hash_table (info->hash))
03993 return FALSE;
03994
03995 switch (h->root.type)
03996 {
03997 default:
03998 abfd = NULL;
03999 break;
04000
04001 case bfd_link_hash_undefined:
04002 case bfd_link_hash_undefweak:
04003 abfd = h->root.u.undef.abfd;
04004 if ((abfd->flags & DYNAMIC) == 0 || elf_dt_soname (abfd) == NULL)
04005 return FALSE;
04006 break;
04007
04008 case bfd_link_hash_defined:
04009 case bfd_link_hash_defweak:
04010 abfd = h->root.u.def.section->owner;
04011 break;
04012
04013 case bfd_link_hash_common:
04014 abfd = h->root.u.c.p->section->owner;
04015 break;
04016 }
04017 BFD_ASSERT (abfd != NULL);
04018
04019 for (loaded = elf_hash_table (info)->loaded;
04020 loaded != NULL;
04021 loaded = loaded->next)
04022 {
04023 bfd *input;
04024 Elf_Internal_Shdr *hdr;
04025 bfd_size_type symcount;
04026 bfd_size_type extsymcount;
04027 bfd_size_type extsymoff;
04028 Elf_Internal_Shdr *versymhdr;
04029 Elf_Internal_Sym *isym;
04030 Elf_Internal_Sym *isymend;
04031 Elf_Internal_Sym *isymbuf;
04032 Elf_External_Versym *ever;
04033 Elf_External_Versym *extversym;
04034
04035 input = loaded->abfd;
04036
04037
04038 if (input == abfd
04039 || (input->flags & DYNAMIC) == 0
04040 || elf_dynversym (input) == 0)
04041 continue;
04042
04043 hdr = &elf_tdata (input)->dynsymtab_hdr;
04044
04045 symcount = hdr->sh_size / sizeof (Elf_External_Sym);
04046 if (elf_bad_symtab (input))
04047 {
04048 extsymcount = symcount;
04049 extsymoff = 0;
04050 }
04051 else
04052 {
04053 extsymcount = symcount - hdr->sh_info;
04054 extsymoff = hdr->sh_info;
04055 }
04056
04057 if (extsymcount == 0)
04058 continue;
04059
04060 isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff,
04061 NULL, NULL, NULL);
04062 if (isymbuf == NULL)
04063 return FALSE;
04064
04065
04066 versymhdr = &elf_tdata (input)->dynversym_hdr;
04067 extversym = bfd_malloc (versymhdr->sh_size);
04068 if (extversym == NULL)
04069 goto error_ret;
04070
04071 if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0
04072 || (bfd_bread (extversym, versymhdr->sh_size, input)
04073 != versymhdr->sh_size))
04074 {
04075 free (extversym);
04076 error_ret:
04077 free (isymbuf);
04078 return FALSE;
04079 }
04080
04081 ever = extversym + extsymoff;
04082 isymend = isymbuf + extsymcount;
04083 for (isym = isymbuf; isym < isymend; isym++, ever++)
04084 {
04085 const char *name;
04086 Elf_Internal_Versym iver;
04087 unsigned short version_index;
04088
04089 if (ELF_ST_BIND (isym->st_info) == STB_LOCAL
04090 || isym->st_shndx == SHN_UNDEF)
04091 continue;
04092
04093 name = bfd_elf_string_from_elf_section (input,
04094 hdr->sh_link,
04095 isym->st_name);
04096 if (strcmp (name, h->root.root.string) != 0)
04097 continue;
04098
04099 _bfd_elf_swap_versym_in (input, ever, &iver);
04100
04101 if ((iver.vs_vers & VERSYM_HIDDEN) == 0)
04102 {
04103
04104
04105 abort ();
04106 }
04107
04108 version_index = iver.vs_vers & VERSYM_VERSION;
04109 if (version_index == 1 || version_index == 2)
04110 {
04111
04112 free (extversym);
04113 free (isymbuf);
04114 return TRUE;
04115 }
04116 }
04117
04118 free (extversym);
04119 free (isymbuf);
04120 }
04121
04122 return FALSE;
04123 }
04124
04125
04126
04127
04128
04129
04130
04131
04132 static bfd_boolean
04133 elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
04134 {
04135 struct elf_outext_info *eoinfo = data;
04136 struct elf_final_link_info *finfo = eoinfo->finfo;
04137 bfd_boolean strip;
04138 Elf_Internal_Sym sym;
04139 asection *input_sec;
04140
04141 if (h->root.type == bfd_link_hash_warning)
04142 {
04143 h = (struct elf_link_hash_entry *) h->root.u.i.link;
04144 if (h->root.type == bfd_link_hash_new)
04145 return TRUE;
04146 }
04147
04148
04149 if (eoinfo->localsyms)
04150 {
04151 if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
04152 return TRUE;
04153 }
04154 else
04155 {
04156 if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
04157 return TRUE;
04158 }
04159
04160
04161
04162
04163
04164 if (h->root.type == bfd_link_hash_undefined
04165 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
04166 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
04167 && ! elf_link_check_versioned_symbol (finfo->info, h)
04168 && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
04169 {
04170 if (! ((*finfo->info->callbacks->undefined_symbol)
04171 (finfo->info, h->root.root.string, h->root.u.undef.abfd,
04172 NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)))
04173 {
04174 eoinfo->failed = TRUE;
04175 return FALSE;
04176 }
04177 }
04178
04179
04180
04181 if (! finfo->info->relocatable
04182 && (! finfo->info->shared)
04183 && (h->elf_link_hash_flags
04184 & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
04185 == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC)
04186 && ! elf_link_check_versioned_symbol (finfo->info, h))
04187 {
04188 (*_bfd_error_handler)
04189 (_("%s: %s symbol `%s' in %s is referenced by DSO"),
04190 bfd_get_filename (finfo->output_bfd),
04191 ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
04192 ? "internal"
04193 : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
04194 ? "hidden" : "local",
04195 h->root.root.string,
04196 bfd_archive_filename (h->root.u.def.section->owner));
04197 eoinfo->failed = TRUE;
04198 return FALSE;
04199 }
04200
04201
04202
04203
04204
04205 if (h->indx == -2)
04206 strip = FALSE;
04207 else if (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
04208 || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
04209 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
04210 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
04211 strip = TRUE;
04212 else if (finfo->info->strip == strip_all)
04213 strip = TRUE;
04214 else if (finfo->info->strip == strip_some
04215 && bfd_hash_lookup (finfo->info->keep_hash,
04216 h->root.root.string, FALSE, FALSE) == NULL)
04217 strip = TRUE;
04218 else if (finfo->info->strip_discarded
04219 && (h->root.type == bfd_link_hash_defined
04220 || h->root.type == bfd_link_hash_defweak)
04221 && elf_discarded_section (h->root.u.def.section))
04222 strip = TRUE;
04223 else
04224 strip = FALSE;
04225
04226
04227
04228 if (strip
04229 && h->dynindx == -1
04230 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
04231 return TRUE;
04232
04233 sym.st_value = 0;
04234 sym.st_size = h->size;
04235 sym.st_other = h->other;
04236 if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
04237 sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
04238 else if (h->root.type == bfd_link_hash_undefweak
04239 || h->root.type == bfd_link_hash_defweak)
04240 sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
04241 else
04242 sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type);
04243
04244 switch (h->root.type)
04245 {
04246 default:
04247 case bfd_link_hash_new:
04248 case bfd_link_hash_warning:
04249 abort ();
04250 return FALSE;
04251
04252 case bfd_link_hash_undefined:
04253 case bfd_link_hash_undefweak:
04254 input_sec = bfd_und_section_ptr;
04255 sym.st_shndx = SHN_UNDEF;
04256 break;
04257
04258 case bfd_link_hash_defined:
04259 case bfd_link_hash_defweak:
04260 {
04261 input_sec = h->root.u.def.section;
04262 if (input_sec->output_section != NULL)
04263 {
04264 sym.st_shndx =
04265 _bfd_elf_section_from_bfd_section (finfo->output_bfd,
04266 input_sec->output_section);
04267 if (sym.st_shndx == SHN_BAD)
04268 {
04269 (*_bfd_error_handler)
04270 (_("%s: could not find output section %s for input section %s"),
04271 bfd_get_filename (finfo->output_bfd),
04272 input_sec->output_section->name,
04273 input_sec->name);
04274 eoinfo->failed = TRUE;
04275 return FALSE;
04276 }
04277
04278
04279
04280
04281 sym.st_value = h->root.u.def.value + input_sec->output_offset;
04282 if (! finfo->info->relocatable)
04283 {
04284 sym.st_value += input_sec->output_section->vma;
04285 if (h->type == STT_TLS)
04286 {
04287
04288
04289 BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL);
04290 sym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma;
04291 }
04292 }
04293 }
04294 else
04295 {
04296 BFD_ASSERT (input_sec->owner == NULL
04297 || (input_sec->owner->flags & DYNAMIC) != 0);
04298 sym.st_shndx = SHN_UNDEF;
04299 input_sec = bfd_und_section_ptr;
04300 }
04301 }
04302 break;
04303
04304 case bfd_link_hash_common:
04305 input_sec = h->root.u.c.p->section;
04306 sym.st_shndx = SHN_COMMON;
04307 sym.st_value = 1 << h->root.u.c.p->alignment_power;
04308 break;
04309
04310 case bfd_link_hash_indirect:
04311
04312
04313
04314
04315
04316
04317 return TRUE;
04318 }
04319
04320
04321
04322
04323
04324 if ((h->dynindx != -1
04325 || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
04326 && ((finfo->info->shared
04327 && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
04328 || h->root.type != bfd_link_hash_undefweak))
04329 || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
04330 && elf_hash_table (finfo->info)->dynamic_sections_created)
04331 {
04332 const struct elf_backend_data *bed;
04333
04334 bed = get_elf_backend_data (finfo->output_bfd);
04335 if (! ((*bed->elf_backend_finish_dynamic_symbol)
04336 (finfo->output_bfd, finfo->info, h, &sym)))
04337 {
04338 eoinfo->failed = TRUE;
04339 return FALSE;
04340 }
04341 }
04342
04343
04344
04345
04346
04347
04348
04349 if (sym.st_shndx == SHN_UNDEF
04350 && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) != 0
04351 && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL
04352 || ELF_ST_BIND (sym.st_info) == STB_WEAK))
04353 {
04354 int bindtype;
04355
04356 if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK) != 0)
04357 bindtype = STB_GLOBAL;
04358 else
04359 bindtype = STB_WEAK;
04360 sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
04361 }
04362
04363
04364
04365 if (! finfo->info->relocatable
04366 && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
04367 && ELF_ST_BIND (sym.st_info) != STB_WEAK
04368 && h->root.type == bfd_link_hash_undefined
04369 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
04370 {
04371 (*_bfd_error_handler)
04372 (_("%s: %s symbol `%s' isn't defined"),
04373 bfd_get_filename (finfo->output_bfd),
04374 ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED
04375 ? "protected"
04376 : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL
04377 ? "internal" : "hidden",
04378 h->root.root.string);
04379 eoinfo->failed = TRUE;
04380 return FALSE;
04381 }
04382
04383
04384
04385
04386 if (h->dynindx != -1
04387 && elf_hash_table (finfo->info)->dynamic_sections_created)
04388 {
04389 size_t bucketcount;
04390 size_t bucket;
04391 size_t hash_entry_size;
04392 bfd_byte *bucketpos;
04393 bfd_vma chain;
04394 Elf_External_Sym *esym;
04395
04396 sym.st_name = h->dynstr_index;
04397 esym = (Elf_External_Sym *) finfo->dynsym_sec->contents + h->dynindx;
04398 elf_swap_symbol_out (finfo->output_bfd, &sym, esym, 0);
04399
04400 bucketcount = elf_hash_table (finfo->info)->bucketcount;
04401 bucket = h->elf_hash_value % bucketcount;
04402 hash_entry_size
04403 = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize;
04404 bucketpos = ((bfd_byte *) finfo->hash_sec->contents
04405 + (bucket + 2) * hash_entry_size);
04406 chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos);
04407 bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos);
04408 bfd_put (8 * hash_entry_size, finfo->output_bfd, chain,
04409 ((bfd_byte *) finfo->hash_sec->contents
04410 + (bucketcount + 2 + h->dynindx) * hash_entry_size));
04411
04412 if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL)
04413 {
04414 Elf_Internal_Versym iversym;
04415 Elf_External_Versym *eversym;
04416
04417 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
04418 {
04419 if (h->verinfo.verdef == NULL)
04420 iversym.vs_vers = 0;
04421 else
04422 iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1;
04423 }
04424 else
04425 {
04426 if (h->verinfo.vertree == NULL)
04427 iversym.vs_vers = 1;
04428 else
04429 iversym.vs_vers = h->verinfo.vertree->vernum + 1;
04430 }
04431
04432 if ((h->elf_link_hash_flags & ELF_LINK_HIDDEN) != 0)
04433 iversym.vs_vers |= VERSYM_HIDDEN;
04434
04435 eversym = (Elf_External_Versym *) finfo->symver_sec->contents;
04436 eversym += h->dynindx;
04437 _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym);
04438 }
04439 }
04440
04441
04442
04443 if (strip || (input_sec->flags & SEC_EXCLUDE) != 0)
04444 return TRUE;
04445
04446 h->indx = bfd_get_symcount (finfo->output_bfd);
04447
04448 if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec, h))
04449 {
04450 eoinfo->failed = TRUE;
04451 return FALSE;
04452 }
04453
04454 return TRUE;
04455 }
04456
04457
04458
04459
04460
04461
04462 static bfd_boolean
04463 elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
04464 {
04465 bfd_boolean (*relocate_section)
04466 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
04467 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
04468 bfd *output_bfd;
04469 Elf_Internal_Shdr *symtab_hdr;
04470 size_t locsymcount;
04471 size_t extsymoff;
04472 Elf_Internal_Sym *isymbuf;
04473 Elf_Internal_Sym *isym;
04474 Elf_Internal_Sym *isymend;
04475 long *pindex;
04476 asection **ppsection;
04477 asection *o;
04478 const struct elf_backend_data *bed;
04479 bfd_boolean emit_relocs;
04480 struct elf_link_hash_entry **sym_hashes;
04481
04482 output_bfd = finfo->output_bfd;
04483 bed = get_elf_backend_data (output_bfd);
04484 relocate_section = bed->elf_backend_relocate_section;
04485
04486
04487
04488
04489 if ((input_bfd->flags & DYNAMIC) != 0)
04490 return TRUE;
04491
04492 emit_relocs = (finfo->info->relocatable
04493 || finfo->info->emitrelocations
04494 || bed->elf_backend_emit_relocs);
04495
04496 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
04497 if (elf_bad_symtab (input_bfd))
04498 {
04499 locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
04500 extsymoff = 0;
04501 }
04502 else
04503 {
04504 locsymcount = symtab_hdr->sh_info;
04505 extsymoff = symtab_hdr->sh_info;
04506 }
04507
04508
04509 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
04510 if (isymbuf == NULL && locsymcount != 0)
04511 {
04512 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
04513 finfo->internal_syms,
04514 finfo->external_syms,
04515 finfo->locsym_shndx);
04516 if (isymbuf == NULL)
04517 return FALSE;
04518 }
04519
04520
04521
04522
04523 isymend = isymbuf + locsymcount;
04524 for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections;
04525 isym < isymend;
04526 isym++, pindex++, ppsection++)
04527 {
04528 asection *isec;
04529 const char *name;
04530 Elf_Internal_Sym osym;
04531
04532 *pindex = -1;
04533
04534 if (elf_bad_symtab (input_bfd))
04535 {
04536 if (ELF_ST_BIND (isym->st_info) != STB_LOCAL)
04537 {
04538 *ppsection = NULL;
04539 continue;
04540 }
04541 }
04542
04543 if (isym->st_shndx == SHN_UNDEF)
04544 isec = bfd_und_section_ptr;
04545 else if (isym->st_shndx < SHN_LORESERVE
04546 || isym->st_shndx > SHN_HIRESERVE)
04547 {
04548 isec = section_from_elf_index (input_bfd, isym->st_shndx);
04549 if (isec
04550 && isec->sec_info_type == ELF_INFO_TYPE_MERGE
04551 && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
04552 isym->st_value =
04553 _bfd_merged_section_offset (output_bfd, &isec,
04554 elf_section_data (isec)->sec_info,
04555 isym->st_value, 0);
04556 }
04557 else if (isym->st_shndx == SHN_ABS)
04558 isec = bfd_abs_section_ptr;
04559 else if (isym->st_shndx == SHN_COMMON)
04560 isec = bfd_com_section_ptr;
04561 else
04562 {
04563
04564 isec = NULL;
04565 }
04566
04567 *ppsection = isec;
04568
04569
04570 if (ppsection == finfo->sections)
04571 continue;
04572
04573 if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
04574 {
04575
04576
04577
04578 continue;
04579 }
04580
04581
04582
04583 if (finfo->info->strip == strip_all)
04584 continue;
04585
04586
04587
04588
04589
04590
04591 if (finfo->info->discard == discard_all)
04592 continue;
04593
04594
04595
04596
04597
04598
04599 if ((isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
04600 && isec != NULL
04601 && ((! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
04602 || (! finfo->info->relocatable
04603 && (isec->flags & SEC_EXCLUDE) != 0)))
04604 continue;
04605
04606
04607 name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link,
04608 isym->st_name);
04609 if (name == NULL)
04610 return FALSE;
04611
04612
04613 if ((finfo->info->strip == strip_some
04614 && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
04615 == NULL))
04616 || (((finfo->info->discard == discard_sec_merge
04617 && (isec->flags & SEC_MERGE) && ! finfo->info->relocatable)
04618 || finfo->info->discard == discard_l)
04619 && bfd_is_local_label_name (input_bfd, name)))
04620 continue;
04621
04622
04623
04624 osym = *isym;
04625
04626
04627 osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
04628 isec->output_section);
04629 if (osym.st_shndx == SHN_BAD)
04630 return FALSE;
04631
04632 *pindex = bfd_get_symcount (output_bfd);
04633
04634
04635
04636
04637
04638
04639
04640
04641 osym.st_value += isec->output_offset;
04642 if (! finfo->info->relocatable)
04643 {
04644 osym.st_value += isec->output_section->vma;
04645 if (ELF_ST_TYPE (osym.st_info) == STT_TLS)
04646 {
04647
04648 BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL);
04649 osym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma;
04650 }
04651 }
04652
04653 if (! elf_link_output_sym (finfo, name, &osym, isec, NULL))
04654 return FALSE;
04655 }
04656
04657
04658 sym_hashes = elf_sym_hashes (input_bfd);
04659 for (o = input_bfd->sections; o != NULL; o = o->next)
04660 {
04661 bfd_byte *contents;
04662
04663 if (! o->linker_mark)
04664 {
04665
04666 continue;
04667 }
04668
04669 if ((o->flags & SEC_HAS_CONTENTS) == 0
04670 || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
04671 continue;
04672
04673 if ((o->flags & SEC_LINKER_CREATED) != 0)
04674 {
04675
04676
04677 continue;
04678 }
04679
04680
04681
04682
04683
04684 if (elf_section_data (o)->this_hdr.contents != NULL)
04685 contents = elf_section_data (o)->this_hdr.contents;
04686 else
04687 {
04688 contents = finfo->contents;
04689 if (! bfd_get_section_contents (input_bfd, o, contents, 0,
04690 o->_raw_size))
04691 return FALSE;
04692 }
04693
04694 if ((o->flags & SEC_RELOC) != 0)
04695 {
04696 Elf_Internal_Rela *internal_relocs;
04697
04698
04699 internal_relocs
04700 = _bfd_elf_link_read_relocs (input_bfd, o, finfo->external_relocs,
04701 finfo->internal_relocs, FALSE);
04702 if (internal_relocs == NULL
04703 && o->reloc_count > 0)
04704 return FALSE;
04705
04706
04707
04708
04709
04710
04711
04712 if (!elf_section_ignore_discarded_relocs (o))
04713 {
04714 Elf_Internal_Rela *rel, *relend;
04715
04716 rel = internal_relocs;
04717 relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
04718 for ( ; rel < relend; rel++)
04719 {
04720 unsigned long r_symndx = ELF_R_SYM (rel->r_info);
04721 asection *sec;
04722
04723 if (r_symndx >= locsymcount
04724 || (elf_bad_symtab (input_bfd)
04725 && finfo->sections[r_symndx] == NULL))
04726 {
04727 struct elf_link_hash_entry *h;
04728
04729 h = sym_hashes[r_symndx - extsymoff];
04730 while (h->root.type == bfd_link_hash_indirect
04731 || h->root.type == bfd_link_hash_warning)
04732 h = (struct elf_link_hash_entry *) h->root.u.i.link;
04733
04734
04735
04736 sec = h->root.u.def.section;
04737 if ((h->root.type == bfd_link_hash_defined
04738 || h->root.type == bfd_link_hash_defweak)
04739 && elf_discarded_section (sec))
04740 {
04741 if ((o->flags & SEC_DEBUGGING) != 0)
04742 {
04743 BFD_ASSERT (r_symndx != 0);
04744
04745 if ((o->flags & SEC_DEBUGGING) != 0
04746 && sec->kept_section != NULL
04747 && sec->_raw_size == sec->kept_section->_raw_size)
04748 h->root.u.def.section
04749 = sec->kept_section;
04750 else
04751 memset (rel, 0, sizeof (*rel));
04752 }
04753 else
04754 finfo->info->callbacks->error_handler
04755 (LD_DEFINITION_IN_DISCARDED_SECTION,
04756 _("%T: discarded in section `%s' from %s\n"),
04757 h->root.root.string,
04758 h->root.root.string,
04759 h->root.u.def.section->name,
04760 bfd_archive_filename (h->root.u.def.section->owner));
04761 }
04762 }
04763 else
04764 {
04765 sec = finfo->sections[r_symndx];
04766
04767 if (sec != NULL && elf_discarded_section (sec))
04768 {
04769 if ((o->flags & SEC_DEBUGGING) != 0
04770 || (sec->flags & SEC_LINK_ONCE) != 0)
04771 {
04772 BFD_ASSERT (r_symndx != 0);
04773
04774 if ((o->flags & SEC_DEBUGGING) != 0
04775 && sec->kept_section != NULL
04776 && sec->_raw_size == sec->kept_section->_raw_size)
04777 finfo->sections[r_symndx]
04778 = sec->kept_section;
04779 else
04780 {
04781 rel->r_info
04782 = ELF_R_INFO (0, ELF_R_TYPE (rel->r_info));
04783 rel->r_addend = 0;
04784 }
04785 }
04786 else
04787 {
04788 static int count;
04789 int ok;
04790 char *buf;
04791
04792 ok = asprintf (&buf, "local symbol %d",
04793 count++);
04794 if (ok <= 0)
04795 buf = (char *) "local symbol";
04796 finfo->info->callbacks->error_handler
04797 (LD_DEFINITION_IN_DISCARDED_SECTION,
04798 _("%T: discarded in section `%s' from %s\n"),
04799 buf, buf, sec->name,
04800 bfd_archive_filename (input_bfd));
04801 if (ok != -1)
04802 free (buf);
04803 }
04804 }
04805 }
04806 }
04807 }
04808
04809
04810
04811
04812
04813
04814
04815
04816
04817
04818
04819
04820
04821
04822
04823
04824
04825
04826
04827
04828
04829 if (! (*relocate_section) (output_bfd, finfo->info,
04830 input_bfd, o, contents,
04831 internal_relocs,
04832 isymbuf,
04833 finfo->sections))
04834 return FALSE;
04835
04836 if (emit_relocs)
04837 {
04838 Elf_Internal_Rela *irela;
04839 Elf_Internal_Rela *irelaend;
04840 bfd_vma last_offset;
04841 struct elf_link_hash_entry **rel_hash;
04842 Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
04843 unsigned int next_erel;
04844 bfd_boolean (*reloc_emitter)
04845 (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *);
04846 bfd_boolean rela_normal;
04847
04848 input_rel_hdr = &elf_section_data (o)->rel_hdr;
04849 rela_normal = (bed->rela_normal
04850 && (input_rel_hdr->sh_entsize
04851 == sizeof (Elf_External_Rela)));
04852
04853
04854
04855 irela = internal_relocs;
04856 irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
04857 rel_hash = (elf_section_data (o->output_section)->rel_hashes
04858 + elf_section_data (o->output_section)->rel_count
04859 + elf_section_data (o->output_section)->rel_count2);
04860 last_offset = o->output_offset;
04861 if (!finfo->info->relocatable)
04862 last_offset += o->output_section->vma;
04863 for (next_erel = 0; irela < irelaend; irela++, next_erel++)
04864 {
04865 unsigned long r_symndx;
04866 asection *sec;
04867 Elf_Internal_Sym sym;
04868
04869 if (next_erel == bed->s->int_rels_per_ext_rel)
04870 {
04871 rel_hash++;
04872 next_erel = 0;
04873 }
04874
04875 irela->r_offset = _bfd_elf_section_offset (output_bfd,
04876 finfo->info, o,
04877 irela->r_offset);
04878 if (irela->r_offset >= (bfd_vma) -2)
04879 {
04880
04881
04882
04883
04884
04885 irela->r_offset = last_offset;
04886 irela->r_info = 0;
04887 irela->r_addend = 0;
04888 continue;
04889 }
04890
04891 irela->r_offset += o->output_offset;
04892
04893
04894 if (!finfo->info->relocatable)
04895 irela->r_offset += o->output_section->vma;
04896
04897 last_offset = irela->r_offset;
04898
04899 r_symndx = ELF_R_SYM (irela->r_info);
04900 if (r_symndx == STN_UNDEF)
04901 continue;
04902
04903 if (r_symndx >= locsymcount
04904 || (elf_bad_symtab (input_bfd)
04905 && finfo->sections[r_symndx] == NULL))
04906 {
04907 struct elf_link_hash_entry *rh;
04908 unsigned long indx;
04909
04910
04911
04912
04913
04914
04915
04916
04917 indx = r_symndx - extsymoff;
04918 rh = elf_sym_hashes (input_bfd)[indx];
04919 while (rh->root.type == bfd_link_hash_indirect
04920 || rh->root.type == bfd_link_hash_warning)
04921 rh = (struct elf_link_hash_entry *) rh->root.u.i.link;
04922
04923
04924
04925
04926 BFD_ASSERT (rh->indx < 0);
04927 rh->indx = -2;
04928
04929 *rel_hash = rh;
04930
04931 continue;
04932 }
04933
04934
04935
04936 *rel_hash = NULL;
04937 sym = isymbuf[r_symndx];
04938 sec = finfo->sections[r_symndx];
04939 if (ELF_ST_TYPE (sym.st_info) == STT_SECTION)
04940 {
04941
04942
04943
04944
04945
04946 if (bfd_is_abs_section (sec)
04947 || (sec != NULL
04948 && bfd_is_abs_section (sec->output_section)))
04949 r_symndx = 0;
04950 else if (sec == NULL || sec->owner == NULL)
04951 {
04952 bfd_set_error (bfd_error_bad_value);
04953 return FALSE;
04954 }
04955 else
04956 {
04957 r_symndx = sec->output_section->target_index;
04958 BFD_ASSERT (r_symndx != 0);
04959 }
04960
04961
04962
04963 if (rela_normal)
04964 irela->r_addend += sec->output_offset;
04965 }
04966 else
04967 {
04968 if (finfo->indices[r_symndx] == -1)
04969 {
04970 unsigned long shlink;
04971 const char *name;
04972 asection *osec;
04973
04974 if (finfo->info->strip == strip_all)
04975 {
04976
04977 bfd_set_error (bfd_error_invalid_operation);
04978 return FALSE;
04979 }
04980
04981
04982
04983
04984 shlink = symtab_hdr->sh_link;
04985 name = (bfd_elf_string_from_elf_section
04986 (input_bfd, shlink, sym.st_name));
04987 if (name == NULL)
04988 return FALSE;
04989
04990 osec = sec->output_section;
04991 sym.st_shndx =
04992 _bfd_elf_section_from_bfd_section (output_bfd,
04993 osec);
04994 if (sym.st_shndx == SHN_BAD)
04995 return FALSE;
04996
04997 sym.st_value += sec->output_offset;
04998 if (! finfo->info->relocatable)
04999 {
05000 sym.st_value += osec->vma;
05001 if (ELF_ST_TYPE (sym.st_info) == STT_TLS)
05002 {
05003
05004
05005 BFD_ASSERT (elf_hash_table (finfo->info)
05006 ->tls_sec != NULL);
05007 sym.st_value -= (elf_hash_table (finfo->info)
05008 ->tls_sec->vma);
05009 }
05010 }
05011
05012 finfo->indices[r_symndx]
05013 = bfd_get_symcount (output_bfd);
05014
05015 if (! elf_link_output_sym (finfo, name, &sym, sec,
05016 NULL))
05017 return FALSE;
05018 }
05019
05020 r_symndx = finfo->indices[r_symndx];
05021 }
05022
05023 irela->r_info = ELF_R_INFO (r_symndx,
05024 ELF_R_TYPE (irela->r_info));
05025 }
05026
05027
05028 if (bed->elf_backend_emit_relocs
05029 && !(finfo->info->relocatable
05030 || finfo->info->emitrelocations))
05031 reloc_emitter = bed->elf_backend_emit_relocs;
05032 else
05033 reloc_emitter = _bfd_elf_link_output_relocs;
05034
05035 if (input_rel_hdr->sh_size != 0
05036 && ! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
05037 internal_relocs))
05038 return FALSE;
05039
05040 input_rel_hdr2 = elf_section_data (o)->rel_hdr2;
05041 if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0)
05042 {
05043 internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
05044 * bed->s->int_rels_per_ext_rel);
05045 if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr2,
05046 internal_relocs))
05047 return FALSE;
05048 }
05049 }
05050 }
05051
05052
05053 if (bed->elf_backend_write_section
05054 && (*bed->elf_backend_write_section) (output_bfd, o, contents))
05055 {
05056
05057 }
05058 else switch (o->sec_info_type)
05059 {
05060 case ELF_INFO_TYPE_STABS:
05061 if (! (_bfd_write_section_stabs
05062 (output_bfd,
05063 &elf_hash_table (finfo->info)->stab_info,
05064 o, &elf_section_data (o)->sec_info, contents)))
05065 return FALSE;
05066 break;
05067 case ELF_INFO_TYPE_MERGE:
05068 if (! _bfd_write_merged_section (output_bfd, o,
05069 elf_section_data (o)->sec_info))
05070 return FALSE;
05071 break;
05072 case ELF_INFO_TYPE_EH_FRAME:
05073 {
05074 if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info,
05075 o, contents))
05076 return FALSE;
05077 }
05078 break;
05079 default:
05080 {
05081 bfd_size_type sec_size;
05082
05083 sec_size = (o->_cooked_size != 0 ? o->_cooked_size : o->_raw_size);
05084 if (! (o->flags & SEC_EXCLUDE)
05085 && ! bfd_set_section_contents (output_bfd, o->output_section,
05086 contents,
05087 (file_ptr) o->output_offset,
05088 sec_size))
05089 return FALSE;
05090 }
05091 break;
05092 }
05093 }
05094
05095 return TRUE;
05096 }
05097
05098
05099
05100
05101
05102
05103 static bfd_boolean
05104 elf_reloc_link_order (bfd *output_bfd,
05105 struct bfd_link_info *info,
05106 asection *output_section,
05107 struct bfd_link_order *link_order)
05108 {
05109 reloc_howto_type *howto;
05110 long indx;
05111 bfd_vma offset;
05112 bfd_vma addend;
05113 struct elf_link_hash_entry **rel_hash_ptr;
05114 Elf_Internal_Shdr *rel_hdr;
05115 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
05116 Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL];
05117 bfd_byte *erel;
05118 unsigned int i;
05119
05120 howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
05121 if (howto == NULL)
05122 {
05123 bfd_set_error (bfd_error_bad_value);
05124 return FALSE;
05125 }
05126
05127 addend = link_order->u.reloc.p->addend;
05128
05129
05130 rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
05131 + elf_section_data (output_section)->rel_count
05132 + elf_section_data (output_section)->rel_count2);
05133 if (link_order->type == bfd_section_reloc_link_order)
05134 {
05135 indx = link_order->u.reloc.p->u.section->target_index;
05136 BFD_ASSERT (indx != 0);
05137 *rel_hash_ptr = NULL;
05138 }
05139 else
05140 {
05141 struct elf_link_hash_entry *h;
05142
05143
05144
05145 h = ((struct elf_link_hash_entry *)
05146 bfd_wrapped_link_hash_lookup (output_bfd, info,
05147 link_order->u.reloc.p->u.name,
05148 FALSE, FALSE, TRUE));
05149 if (h != NULL
05150 && (h->root.type == bfd_link_hash_defined
05151 || h->root.type == bfd_link_hash_defweak))
05152 {
05153 asection *section;
05154
05155 section = h->root.u.def.section;
05156 indx = section->output_section->target_index;
05157 *rel_hash_ptr = NULL;
05158
05159
05160
05161 addend += section->output_section->vma + section->output_offset;
05162 }
05163 else if (h != NULL)
05164 {
05165
05166
05167 h->indx = -2;
05168 *rel_hash_ptr = h;
05169 indx = 0;
05170 }
05171 else
05172 {
05173 if (! ((*info->callbacks->unattached_reloc)
05174 (info, link_order->u.reloc.p->u.name, NULL, NULL, 0)))
05175 return FALSE;
05176 indx = 0;
05177 }
05178 }
05179
05180
05181
05182 if (howto->partial_inplace && addend != 0)
05183 {
05184 bfd_size_type size;
05185 bfd_reloc_status_type rstat;
05186 bfd_byte *buf;
05187 bfd_boolean ok;
05188 const char *sym_name;
05189
05190 size = bfd_get_reloc_size (howto);
05191 buf = bfd_zmalloc (size);
05192 if (buf == NULL)
05193 return FALSE;
05194 rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
05195 switch (rstat)
05196 {
05197 case bfd_reloc_ok:
05198 break;
05199
05200 default:
05201 case bfd_reloc_outofrange:
05202 abort ();
05203
05204 case bfd_reloc_overflow:
05205 if (link_order->type == bfd_section_reloc_link_order)
05206 sym_name = bfd_section_name (output_bfd,
05207 link_order->u.reloc.p->u.section);
05208 else
05209 sym_name = link_order->u.reloc.p->u.name;
05210 if (! ((*info->callbacks->reloc_overflow)
05211 (info, sym_name, howto->name, addend, NULL, NULL, 0)))
05212 {
05213 free (buf);
05214 return FALSE;
05215 }
05216 break;
05217 }
05218 ok = bfd_set_section_contents (output_bfd, output_section, buf,
05219 link_order->offset, size);
05220 free (buf);
05221 if (! ok)
05222 return FALSE;
05223 }
05224
05225
05226
05227
05228 offset = link_order->offset;
05229 if (! info->relocatable)
05230 offset += output_section->vma;
05231
05232 for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
05233 {
05234 irel[i].r_offset = offset;
05235 irel[i].r_info = 0;
05236 irel[i].r_addend = 0;
05237 }
05238 irel[0].r_info = ELF_R_INFO (indx, howto->type);
05239
05240 rel_hdr = &elf_section_data (output_section)->rel_hdr;
05241 erel = rel_hdr->contents;
05242 if (rel_hdr->sh_type == SHT_REL)
05243 {
05244 erel += (elf_section_data (output_section)->rel_count
05245 * sizeof (Elf_External_Rel));
05246 (*bed->s->swap_reloc_out) (output_bfd, irel, erel);
05247 }
05248 else
05249 {
05250 irel[0].r_addend = addend;
05251 erel += (elf_section_data (output_section)->rel_count
05252 * sizeof (Elf_External_Rela));
05253 (*bed->s->swap_reloca_out) (output_bfd, irel, erel);
05254 }
05255
05256 ++elf_section_data (output_section)->rel_count;
05257
05258 return TRUE;
05259 }
05260
05261
05262
05263 static bfd_boolean elf_gc_sweep_symbol
05264 (struct elf_link_hash_entry *, void *);
05265
05266 static bfd_boolean elf_gc_allocate_got_offsets
05267 (struct elf_link_hash_entry *, void *);
05268
05269
05270
05271
05272
05273 typedef asection * (*gc_mark_hook_fn)
05274 (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
05275 struct elf_link_hash_entry *, Elf_Internal_Sym *);
05276
05277 static bfd_boolean
05278 elf_gc_mark (struct bfd_link_info *info,
05279 asection *sec,
05280 gc_mark_hook_fn gc_mark_hook)
05281 {
05282 bfd_boolean ret;
05283 asection *group_sec;
05284
05285 sec->gc_mark = 1;
05286
05287
05288 group_sec = elf_section_data (sec)->next_in_group;
05289 if (group_sec && !group_sec->gc_mark)
05290 if (!elf_gc_mark (info, group_sec, gc_mark_hook))
05291 return FALSE;
05292
05293
05294 ret = TRUE;
05295 if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
05296 {
05297 Elf_Internal_Rela *relstart, *rel, *relend;
05298 Elf_Internal_Shdr *symtab_hdr;
05299 struct elf_link_hash_entry **sym_hashes;
05300 size_t nlocsyms;
05301 size_t extsymoff;
05302 bfd *input_bfd = sec->owner;
05303 const struct elf_backend_data *bed = get_elf_backend_data (input_bfd);
05304 Elf_Internal_Sym *isym = NULL;
05305
05306 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
05307 sym_hashes = elf_sym_hashes (input_bfd);
05308
05309
05310 if (elf_bad_symtab (input_bfd))
05311 {
05312 nlocsyms = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
05313 extsymoff = 0;
05314 }
05315 else
05316 extsymoff = nlocsyms = symtab_hdr->sh_info;
05317
05318 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
05319 if (isym == NULL && nlocsyms != 0)
05320 {
05321 isym = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, nlocsyms, 0,
05322 NULL, NULL, NULL);
05323 if (isym == NULL)
05324 return FALSE;
05325 }
05326
05327
05328 relstart = _bfd_elf_link_read_relocs (input_bfd, sec, NULL, NULL,
05329 info->keep_memory);
05330 if (relstart == NULL)
05331 {
05332 ret = FALSE;
05333 goto out1;
05334 }
05335 relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
05336
05337 for (rel = relstart; rel < relend; rel++)
05338 {
05339 unsigned long r_symndx;
05340 asection *rsec;
05341 struct elf_link_hash_entry *h;
05342
05343 r_symndx = ELF_R_SYM (rel->r_info);
05344 if (r_symndx == 0)
05345 continue;
05346
05347 if (r_symndx >= nlocsyms
05348 || ELF_ST_BIND (isym[r_symndx].st_info) != STB_LOCAL)
05349 {
05350 h = sym_hashes[r_symndx - extsymoff];
05351 rsec = (*gc_mark_hook) (sec, info, rel, h, NULL);
05352 }
05353 else
05354 {
05355 rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]);
05356 }
05357
05358 if (rsec && !rsec->gc_mark)
05359 {
05360 if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
05361 rsec->gc_mark = 1;
05362 else if (!elf_gc_mark (info, rsec, gc_mark_hook))
05363 {
05364 ret = FALSE;
05365 goto out2;
05366 }
05367 }
05368 }
05369
05370 out2:
05371 if (elf_section_data (sec)->relocs != relstart)
05372 free (relstart);
05373 out1:
05374 if (isym != NULL && symtab_hdr->contents != (unsigned char *) isym)
05375 {
05376 if (! info->keep_memory)
05377 free (isym);
05378 else
05379 symtab_hdr->contents = (unsigned char *) isym;
05380 }
05381 }
05382
05383 return ret;
05384 }
05385
05386
05387
05388 typedef bfd_boolean (*gc_sweep_hook_fn)
05389 (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
05390
05391 static bfd_boolean
05392 elf_gc_sweep (struct bfd_link_info *info, gc_sweep_hook_fn gc_sweep_hook)
05393 {
05394 bfd *sub;
05395
05396 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
05397 {
05398 asection *o;
05399
05400 if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
05401 continue;
05402
05403 for (o = sub->sections; o != NULL; o = o->next)
05404 {
05405
05406 if ((o->flags & SEC_LINKER_CREATED)
05407 || (o->flags & SEC_DEBUGGING))
05408 o->gc_mark = 1;
05409
05410 if (o->gc_mark)
05411 continue;
05412
05413
05414 if (o->flags & SEC_EXCLUDE)
05415 continue;
05416
05417
05418
05419 o->flags |= SEC_EXCLUDE;
05420
05421
05422
05423 if (gc_sweep_hook
05424 && (o->flags & SEC_RELOC) && o->reloc_count > 0)
05425 {
05426 Elf_Internal_Rela *internal_relocs;
05427 bfd_boolean r;
05428
05429 internal_relocs
05430 = _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL,
05431 info->keep_memory);
05432 if (internal_relocs == NULL)
05433 return FALSE;
05434
05435 r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs);
05436
05437 if (elf_section_data (o)->relocs != internal_relocs)
05438 free (internal_relocs);
05439
05440 if (!r)
05441 return FALSE;
05442 }
05443 }
05444 }
05445
05446
05447
05448
05449 {
05450 int i = 0;
05451
05452 elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, &i);
05453
05454 elf_hash_table (info)->dynsymcount = i;
05455 }
05456
05457 return TRUE;
05458 }
05459
05460
05461
05462 static bfd_boolean
05463 elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *idxptr)
05464 {
05465 int *idx = idxptr;
05466
05467 if (h->root.type == bfd_link_hash_warning)
05468 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05469
05470 if (h->dynindx != -1
05471 && ((h->root.type != bfd_link_hash_defined
05472 && h->root.type != bfd_link_hash_defweak)
05473 || h->root.u.def.section->gc_mark))
05474 h->dynindx = (*idx)++;
05475
05476 return TRUE;
05477 }
05478
05479
05480
05481
05482 static bfd_boolean
05483 elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
05484 {
05485 if (h->root.type == bfd_link_hash_warning)
05486 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05487
05488
05489 if (h->vtable_parent == NULL)
05490 return TRUE;
05491
05492
05493 if (h->vtable_parent == (struct elf_link_hash_entry *) -1)
05494 return TRUE;
05495
05496
05497 if (h->vtable_entries_used && h->vtable_entries_used[-1])
05498 return TRUE;
05499
05500
05501 elf_gc_propagate_vtable_entries_used (h->vtable_parent, okp);
05502
05503 if (h->vtable_entries_used == NULL)
05504 {
05505
05506
05507 h->vtable_entries_used = h->vtable_parent->vtable_entries_used;
05508 h->vtable_entries_size = h->vtable_parent->vtable_entries_size;
05509 }
05510 else
05511 {
05512 size_t n;
05513 bfd_boolean *cu, *pu;
05514
05515
05516 cu = h->vtable_entries_used;
05517 cu[-1] = TRUE;
05518 pu = h->vtable_parent->vtable_entries_used;
05519 if (pu != NULL)
05520 {
05521 const struct elf_backend_data *bed;
05522 unsigned int log_file_align;
05523
05524 bed = get_elf_backend_data (h->root.u.def.section->owner);
05525 log_file_align = bed->s->log_file_align;
05526 n = h->vtable_parent->vtable_entries_size >> log_file_align;
05527 while (n--)
05528 {
05529 if (*pu)
05530 *cu = TRUE;
05531 pu++;
05532 cu++;
05533 }
05534 }
05535 }
05536
05537 return TRUE;
05538 }
05539
05540 static bfd_boolean
05541 elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp)
05542 {
05543 asection *sec;
05544 bfd_vma hstart, hend;
05545 Elf_Internal_Rela *relstart, *relend, *rel;
05546 const struct elf_backend_data *bed;
05547 unsigned int log_file_align;
05548
05549 if (h->root.type == bfd_link_hash_warning)
05550 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05551
05552
05553
05554 if (h->vtable_parent == NULL)
05555 return TRUE;
05556
05557 BFD_ASSERT (h->root.type == bfd_link_hash_defined
05558 || h->root.type == bfd_link_hash_defweak);
05559
05560 sec = h->root.u.def.section;
05561 hstart = h->root.u.def.value;
05562 hend = hstart + h->size;
05563
05564 relstart = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE);
05565 if (!relstart)
05566 return *(bfd_boolean *) okp = FALSE;
05567 bed = get_elf_backend_data (sec->owner);
05568 log_file_align = bed->s->log_file_align;
05569
05570 relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
05571
05572 for (rel = relstart; rel < relend; ++rel)
05573 if (rel->r_offset >= hstart && rel->r_offset < hend)
05574 {
05575
05576 if (h->vtable_entries_used
05577 && (rel->r_offset - hstart) < h->vtable_entries_size)
05578 {
05579 bfd_vma entry = (rel->r_offset - hstart) >> log_file_align;
05580 if (h->vtable_entries_used[entry])
05581 continue;
05582 }
05583
05584 rel->r_offset = rel->r_info = rel->r_addend = 0;
05585 }
05586
05587 return TRUE;
05588 }
05589
05590
05591
05592 bfd_boolean
05593 elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
05594 {
05595 bfd_boolean ok = TRUE;
05596 bfd *sub;
05597 asection * (*gc_mark_hook)
05598 (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
05599 struct elf_link_hash_entry *h, Elf_Internal_Sym *);
05600
05601 if (!get_elf_backend_data (abfd)->can_gc_sections
05602 || info->relocatable
05603 || info->emitrelocations
05604 || !is_elf_hash_table (info->hash)
05605 || elf_hash_table (info)->dynamic_sections_created)
05606 {
05607 (*_bfd_error_handler)(_("Warning: gc-sections option ignored"));
05608 return TRUE;
05609 }
05610
05611
05612 elf_link_hash_traverse (elf_hash_table (info),
05613 elf_gc_propagate_vtable_entries_used,
05614 &ok);
05615 if (!ok)
05616 return FALSE;
05617
05618
05619 elf_link_hash_traverse (elf_hash_table (info),
05620 elf_gc_smash_unused_vtentry_relocs,
05621 &ok);
05622 if (!ok)
05623 return FALSE;
05624
05625
05626
05627 gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
05628 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
05629 {
05630 asection *o;
05631
05632 if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
05633 continue;
05634
05635 for (o = sub->sections; o != NULL; o = o->next)
05636 {
05637 if (o->flags & SEC_KEEP)
05638 if (!elf_gc_mark (info, o, gc_mark_hook))
05639 return FALSE;
05640 }
05641 }
05642
05643
05644 if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook))
05645 return FALSE;
05646
05647 return TRUE;
05648 }
05649
05650
05651
05652 bfd_boolean
05653 elf_gc_record_vtinherit (bfd *abfd,
05654 asection *sec,
05655 struct elf_link_hash_entry *h,
05656 bfd_vma offset)
05657 {
05658 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
05659 struct elf_link_hash_entry **search, *child;
05660 bfd_size_type extsymcount;
05661
05662
05663
05664
05665 extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size/sizeof (Elf_External_Sym);
05666 if (!elf_bad_symtab (abfd))
05667 extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info;
05668
05669 sym_hashes = elf_sym_hashes (abfd);
05670 sym_hashes_end = sym_hashes + extsymcount;
05671
05672
05673
05674 for (search = sym_hashes; search != sym_hashes_end; ++search)
05675 {
05676 if ((child = *search) != NULL
05677 && (child->root.type == bfd_link_hash_defined
05678 || child->root.type == bfd_link_hash_defweak)
05679 && child->root.u.def.section == sec
05680 && child->root.u.def.value == offset)
05681 goto win;
05682 }
05683
05684 (*_bfd_error_handler) ("%s: %s+%lu: No symbol found for INHERIT",
05685 bfd_archive_filename (abfd), sec->name,
05686 (unsigned long) offset);
05687 bfd_set_error (bfd_error_invalid_operation);
05688 return FALSE;
05689
05690 win:
05691 if (!h)
05692 {
05693
05694
05695
05696
05697
05698 child->vtable_parent = (struct elf_link_hash_entry *) -1;
05699 }
05700 else
05701 child->vtable_parent = h;
05702
05703 return TRUE;
05704 }
05705
05706
05707
05708 bfd_boolean
05709 elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
05710 asection *sec ATTRIBUTE_UNUSED,
05711 struct elf_link_hash_entry *h,
05712 bfd_vma addend)
05713 {
05714 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
05715 unsigned int log_file_align = bed->s->log_file_align;
05716
05717 if (addend >= h->vtable_entries_size)
05718 {
05719 size_t size, bytes, file_align;
05720 bfd_boolean *ptr = h->vtable_entries_used;
05721
05722
05723
05724 file_align = 1 << log_file_align;
05725 if (h->root.type == bfd_link_hash_undefined)
05726 size = addend + file_align;
05727 else
05728 {
05729 size = h->size;
05730 if (addend >= size)
05731 {
05732
05733
05734 size = addend + file_align;
05735 }
05736 }
05737 size = (size + file_align - 1) & -file_align;
05738
05739
05740
05741 bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean);
05742
05743 if (ptr)
05744 {
05745 ptr = bfd_realloc (ptr - 1, bytes);
05746
05747 if (ptr != NULL)
05748 {
05749 size_t oldbytes;
05750
05751 oldbytes = (((h->vtable_entries_size >> log_file_align) + 1)
05752 * sizeof (bfd_boolean));
05753 memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes);
05754 }
05755 }
05756 else
05757 ptr = bfd_zmalloc (bytes);
05758
05759 if (ptr == NULL)
05760 return FALSE;
05761
05762
05763 h->vtable_entries_used = ptr + 1;
05764 h->vtable_entries_size = size;
05765 }
05766
05767 h->vtable_entries_used[addend >> log_file_align] = TRUE;
05768
05769 return TRUE;
05770 }
05771
05772
05773
05774
05775 bfd_boolean
05776 elf_gc_common_finalize_got_offsets (bfd *abfd,
05777 struct bfd_link_info *info)
05778 {
05779 bfd *i;
05780 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
05781 bfd_vma gotoff;
05782
05783 if (! is_elf_hash_table (info->hash))
05784 return FALSE;
05785
05786
05787
05788 if (bed->want_got_plt)
05789 gotoff = 0;
05790 else
05791 gotoff = bed->got_header_size;
05792
05793
05794 for (i = info->input_bfds; i; i = i->link_next)
05795 {
05796 bfd_signed_vma *local_got;
05797 bfd_size_type j, locsymcount;
05798 Elf_Internal_Shdr *symtab_hdr;
05799
05800 if (bfd_get_flavour (i) != bfd_target_elf_flavour)
05801 continue;
05802
05803 local_got = elf_local_got_refcounts (i);
05804 if (!local_got)
05805 continue;
05806
05807 symtab_hdr = &elf_tdata (i)->symtab_hdr;
05808 if (elf_bad_symtab (i))
05809 locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
05810 else
05811 locsymcount = symtab_hdr->sh_info;
05812
05813 for (j = 0; j < locsymcount; ++j)
05814 {
05815 if (local_got[j] > 0)
05816 {
05817 local_got[j] = gotoff;
05818 gotoff += ARCH_SIZE / 8;
05819 }
05820 else
05821 local_got[j] = (bfd_vma) -1;
05822 }
05823 }
05824
05825
05826
05827 elf_link_hash_traverse (elf_hash_table (info),
05828 elf_gc_allocate_got_offsets,
05829 &gotoff);
05830 return TRUE;
05831 }
05832
05833
05834
05835
05836 static bfd_boolean
05837 elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *offarg)
05838 {
05839 bfd_vma *off = offarg;
05840
05841 if (h->root.type == bfd_link_hash_warning)
05842 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05843
05844 if (h->got.refcount > 0)
05845 {
05846 h->got.offset = off[0];
05847 off[0] += ARCH_SIZE / 8;
05848 }
05849 else
05850 h->got.offset = (bfd_vma) -1;
05851
05852 return TRUE;
05853 }
05854
05855
05856
05857
05858 bfd_boolean
05859 elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info)
05860 {
05861 if (!elf_gc_common_finalize_got_offsets (abfd, info))
05862 return FALSE;
05863
05864
05865 return elf_bfd_final_link (abfd, info);
05866 }
05867
05868
05869
05870
05871 static bfd_boolean
05872 elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
05873 {
05874 unsigned long **valuep = data;
05875 const char *name;
05876 char *p;
05877 unsigned long ha;
05878 char *alc = NULL;
05879
05880 if (h->root.type == bfd_link_hash_warning)
05881 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05882
05883
05884 if (h->dynindx == -1)
05885 return TRUE;
05886
05887 name = h->root.root.string;
05888 p = strchr (name, ELF_VER_CHR);
05889 if (p != NULL)
05890 {
05891 alc = bfd_malloc (p - name + 1);
05892 memcpy (alc, name, p - name);
05893 alc[p - name] = '\0';
05894 name = alc;
05895 }
05896
05897
05898 ha = bfd_elf_hash (name);
05899
05900
05901 *(*valuep)++ = ha;
05902
05903
05904
05905 h->elf_hash_value = ha;
05906
05907 if (alc != NULL)
05908 free (alc);
05909
05910 return TRUE;
05911 }
05912
05913 bfd_boolean
05914 elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
05915 {
05916 struct elf_reloc_cookie *rcookie = cookie;
05917
05918 if (rcookie->bad_symtab)
05919 rcookie->rel = rcookie->rels;
05920
05921 for (; rcookie->rel < rcookie->relend; rcookie->rel++)
05922 {
05923 unsigned long r_symndx;
05924
05925 if (! rcookie->bad_symtab)
05926 if (rcookie->rel->r_offset > offset)
05927 return FALSE;
05928 if (rcookie->rel->r_offset != offset)
05929 continue;
05930
05931 r_symndx = ELF_R_SYM (rcookie->rel->r_info);
05932 if (r_symndx == SHN_UNDEF)
05933 return TRUE;
05934
05935 if (r_symndx >= rcookie->locsymcount
05936 || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
05937 {
05938 struct elf_link_hash_entry *h;
05939
05940 h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff];
05941
05942 while (h->root.type == bfd_link_hash_indirect
05943 || h->root.type == bfd_link_hash_warning)
05944 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05945
05946 if ((h->root.type == bfd_link_hash_defined
05947 || h->root.type == bfd_link_hash_defweak)
05948 && elf_discarded_section (h->root.u.def.section))
05949 return TRUE;
05950 else
05951 return FALSE;
05952 }
05953 else
05954 {
05955
05956
05957
05958 asection *isec;
05959 Elf_Internal_Sym *isym;
05960
05961
05962 isym = &rcookie->locsyms[r_symndx];
05963 if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
05964 {
05965 isec = section_from_elf_index (rcookie->abfd, isym->st_shndx);
05966 if (isec != NULL && elf_discarded_section (isec))
05967 return TRUE;
05968 }
05969 }
05970 return FALSE;
05971 }
05972 return FALSE;
05973 }
05974
05975
05976
05977
05978
05979
05980 bfd_boolean
05981 elf_bfd_discard_info (bfd *output_bfd, struct bfd_link_info *info)
05982 {
05983 struct elf_reloc_cookie cookie;
05984 asection *stab, *eh;
05985 Elf_Internal_Shdr *symtab_hdr;
05986 const struct elf_backend_data *bed;
05987 bfd *abfd;
05988 unsigned int count;
05989 bfd_boolean ret = FALSE;
05990
05991 if (info->traditional_format
05992 || !is_elf_hash_table (info->hash))
05993 return FALSE;
05994
05995 for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
05996 {
05997 if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
05998 continue;
05999
06000 bed = get_elf_backend_data (abfd);
06001
06002 if ((abfd->flags & DYNAMIC) != 0)
06003 continue;
06004
06005 eh = bfd_get_section_by_name (abfd, ".eh_frame");
06006 if (info->relocatable
06007 || (eh != NULL
06008 && (eh->_raw_size == 0
06009 || bfd_is_abs_section (eh->output_section))))
06010 eh = NULL;
06011
06012 stab = bfd_get_section_by_name (abfd, ".stab");
06013 if (stab != NULL
06014 && (stab->_raw_size == 0
06015 || bfd_is_abs_section (stab->output_section)
06016 || stab->sec_info_type != ELF_INFO_TYPE_STABS))
06017 stab = NULL;
06018
06019 if (stab == NULL
06020 && eh == NULL
06021 && bed->elf_backend_discard_info == NULL)
06022 continue;
06023
06024 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
06025 cookie.abfd = abfd;
06026 cookie.sym_hashes = elf_sym_hashes (abfd);
06027 cookie.bad_symtab = elf_bad_symtab (abfd);
06028 if (cookie.bad_symtab)
06029 {
06030 cookie.locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
06031 cookie.extsymoff = 0;
06032 }
06033 else
06034 {
06035 cookie.locsymcount = symtab_hdr->sh_info;
06036 cookie.extsymoff = symtab_hdr->sh_info;
06037 }
06038
06039 cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
06040 if (cookie.locsyms == NULL && cookie.locsymcount != 0)
06041 {
06042 cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
06043 cookie.locsymcount, 0,
06044 NULL, NULL, NULL);
06045 if (cookie.locsyms == NULL)
06046 return FALSE;
06047 }
06048
06049 if (stab != NULL)
06050 {
06051 cookie.rels = NULL;
06052 count = stab->reloc_count;
06053 if (count != 0)
06054 cookie.rels = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL,
06055 info->keep_memory);
06056 if (cookie.rels != NULL)
06057 {
06058 cookie.rel = cookie.rels;
06059 cookie.relend = cookie.rels;
06060 cookie.relend += count * bed->s->int_rels_per_ext_rel;
06061 if (_bfd_discard_section_stabs (abfd, stab,
06062 elf_section_data (stab)->sec_info,
06063 elf_reloc_symbol_deleted_p,
06064 &cookie))
06065 ret = TRUE;
06066 if (elf_section_data (stab)->relocs != cookie.rels)
06067 free (cookie.rels);
06068 }
06069 }
06070
06071 if (eh != NULL)
06072 {
06073 cookie.rels = NULL;
06074 count = eh->reloc_count;
06075 if (count != 0)
06076 cookie.rels = _bfd_elf_link_read_relocs (abfd, eh, NULL, NULL,
06077 info->keep_memory);
06078 cookie.rel = cookie.rels;
06079 cookie.relend = cookie.rels;
06080 if (cookie.rels != NULL)
06081 cookie.relend += count * bed->s->int_rels_per_ext_rel;
06082
06083 if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
06084 elf_reloc_symbol_deleted_p,
06085 &cookie))
06086 ret = TRUE;
06087
06088 if (cookie.rels != NULL
06089 && elf_section_data (eh)->relocs != cookie.rels)
06090 free (cookie.rels);
06091 }
06092
06093 if (bed->elf_backend_discard_info != NULL
06094 && (*bed->elf_backend_discard_info) (abfd, &cookie, info))
06095 ret = TRUE;
06096
06097 if (cookie.locsyms != NULL
06098 && symtab_hdr->contents != (unsigned char *) cookie.locsyms)
06099 {
06100 if (! info->keep_memory)
06101 free (cookie.locsyms);
06102 else
06103 symtab_hdr->contents = (unsigned char *) cookie.locsyms;
06104 }
06105 }
06106
06107 if (info->eh_frame_hdr
06108 && !info->relocatable
06109 && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
06110 ret = TRUE;
06111
06112 return ret;
06113 }
06114
06115 static bfd_boolean
06116 elf_section_ignore_discarded_relocs (asection *sec)
06117 {
06118 const struct elf_backend_data *bed;
06119
06120 switch (sec->sec_info_type)
06121 {
06122 case ELF_INFO_TYPE_STABS:
06123 case ELF_INFO_TYPE_EH_FRAME:
06124 return TRUE;
06125 default:
06126 break;
06127 }
06128
06129 bed = get_elf_backend_data (sec->owner);
06130 if (bed->elf_backend_ignore_discarded_relocs != NULL
06131 && (*bed->elf_backend_ignore_discarded_relocs) (sec))
06132 return TRUE;
06133
06134 return FALSE;
06135 }