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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define _SYSCALL32
00040 #include "bfd.h"
00041 #include "sysdep.h"
00042 #include "bfdlink.h"
00043 #include "libbfd.h"
00044 #define ARCH_SIZE 0
00045 #include "elf-bfd.h"
00046 #include "libiberty.h"
00047
00048 static int elf_sort_sections (const void *, const void *);
00049 static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
00050 static bfd_boolean prep_headers (bfd *);
00051 static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
00052 static bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ;
00053
00054
00055
00056
00057
00058
00059
00060 void
00061 _bfd_elf_swap_verdef_in (bfd *abfd,
00062 const Elf_External_Verdef *src,
00063 Elf_Internal_Verdef *dst)
00064 {
00065 dst->vd_version = H_GET_16 (abfd, src->vd_version);
00066 dst->vd_flags = H_GET_16 (abfd, src->vd_flags);
00067 dst->vd_ndx = H_GET_16 (abfd, src->vd_ndx);
00068 dst->vd_cnt = H_GET_16 (abfd, src->vd_cnt);
00069 dst->vd_hash = H_GET_32 (abfd, src->vd_hash);
00070 dst->vd_aux = H_GET_32 (abfd, src->vd_aux);
00071 dst->vd_next = H_GET_32 (abfd, src->vd_next);
00072 }
00073
00074
00075
00076 void
00077 _bfd_elf_swap_verdef_out (bfd *abfd,
00078 const Elf_Internal_Verdef *src,
00079 Elf_External_Verdef *dst)
00080 {
00081 H_PUT_16 (abfd, src->vd_version, dst->vd_version);
00082 H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
00083 H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
00084 H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
00085 H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
00086 H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
00087 H_PUT_32 (abfd, src->vd_next, dst->vd_next);
00088 }
00089
00090
00091
00092 void
00093 _bfd_elf_swap_verdaux_in (bfd *abfd,
00094 const Elf_External_Verdaux *src,
00095 Elf_Internal_Verdaux *dst)
00096 {
00097 dst->vda_name = H_GET_32 (abfd, src->vda_name);
00098 dst->vda_next = H_GET_32 (abfd, src->vda_next);
00099 }
00100
00101
00102
00103 void
00104 _bfd_elf_swap_verdaux_out (bfd *abfd,
00105 const Elf_Internal_Verdaux *src,
00106 Elf_External_Verdaux *dst)
00107 {
00108 H_PUT_32 (abfd, src->vda_name, dst->vda_name);
00109 H_PUT_32 (abfd, src->vda_next, dst->vda_next);
00110 }
00111
00112
00113
00114 void
00115 _bfd_elf_swap_verneed_in (bfd *abfd,
00116 const Elf_External_Verneed *src,
00117 Elf_Internal_Verneed *dst)
00118 {
00119 dst->vn_version = H_GET_16 (abfd, src->vn_version);
00120 dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt);
00121 dst->vn_file = H_GET_32 (abfd, src->vn_file);
00122 dst->vn_aux = H_GET_32 (abfd, src->vn_aux);
00123 dst->vn_next = H_GET_32 (abfd, src->vn_next);
00124 }
00125
00126
00127
00128 void
00129 _bfd_elf_swap_verneed_out (bfd *abfd,
00130 const Elf_Internal_Verneed *src,
00131 Elf_External_Verneed *dst)
00132 {
00133 H_PUT_16 (abfd, src->vn_version, dst->vn_version);
00134 H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
00135 H_PUT_32 (abfd, src->vn_file, dst->vn_file);
00136 H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
00137 H_PUT_32 (abfd, src->vn_next, dst->vn_next);
00138 }
00139
00140
00141
00142 void
00143 _bfd_elf_swap_vernaux_in (bfd *abfd,
00144 const Elf_External_Vernaux *src,
00145 Elf_Internal_Vernaux *dst)
00146 {
00147 dst->vna_hash = H_GET_32 (abfd, src->vna_hash);
00148 dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
00149 dst->vna_other = H_GET_16 (abfd, src->vna_other);
00150 dst->vna_name = H_GET_32 (abfd, src->vna_name);
00151 dst->vna_next = H_GET_32 (abfd, src->vna_next);
00152 }
00153
00154
00155
00156 void
00157 _bfd_elf_swap_vernaux_out (bfd *abfd,
00158 const Elf_Internal_Vernaux *src,
00159 Elf_External_Vernaux *dst)
00160 {
00161 H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
00162 H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
00163 H_PUT_16 (abfd, src->vna_other, dst->vna_other);
00164 H_PUT_32 (abfd, src->vna_name, dst->vna_name);
00165 H_PUT_32 (abfd, src->vna_next, dst->vna_next);
00166 }
00167
00168
00169
00170 void
00171 _bfd_elf_swap_versym_in (bfd *abfd,
00172 const Elf_External_Versym *src,
00173 Elf_Internal_Versym *dst)
00174 {
00175 dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
00176 }
00177
00178
00179
00180 void
00181 _bfd_elf_swap_versym_out (bfd *abfd,
00182 const Elf_Internal_Versym *src,
00183 Elf_External_Versym *dst)
00184 {
00185 H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
00186 }
00187
00188
00189
00190
00191 unsigned long
00192 bfd_elf_hash (const char *namearg)
00193 {
00194 const unsigned char *name = (const unsigned char *) namearg;
00195 unsigned long h = 0;
00196 unsigned long g;
00197 int ch;
00198
00199 while ((ch = *name++) != '\0')
00200 {
00201 h = (h << 4) + ch;
00202 if ((g = (h & 0xf0000000)) != 0)
00203 {
00204 h ^= g >> 24;
00205
00206
00207 h ^= g;
00208 }
00209 }
00210 return h & 0xffffffff;
00211 }
00212
00213
00214
00215
00216
00217 static bfd_byte *
00218 elf_read (bfd *abfd, file_ptr offset, bfd_size_type size)
00219 {
00220 bfd_byte *buf;
00221
00222 if ((buf = bfd_alloc (abfd, size)) == NULL)
00223 return NULL;
00224 if (bfd_seek (abfd, offset, SEEK_SET) != 0)
00225 return NULL;
00226 if (bfd_bread (buf, size, abfd) != size)
00227 {
00228 if (bfd_get_error () != bfd_error_system_call)
00229 bfd_set_error (bfd_error_file_truncated);
00230 return NULL;
00231 }
00232 return buf;
00233 }
00234
00235 bfd_boolean
00236 bfd_elf_mkobject (bfd *abfd)
00237 {
00238
00239
00240 elf_tdata (abfd) = bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
00241 if (elf_tdata (abfd) == 0)
00242 return FALSE;
00243
00244
00245
00246 return TRUE;
00247 }
00248
00249 bfd_boolean
00250 bfd_elf_mkcorefile (bfd *abfd)
00251 {
00252
00253 return bfd_elf_mkobject (abfd);
00254 }
00255
00256 char *
00257 bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
00258 {
00259 Elf_Internal_Shdr **i_shdrp;
00260 bfd_byte *shstrtab = NULL;
00261 file_ptr offset;
00262 bfd_size_type shstrtabsize;
00263
00264 i_shdrp = elf_elfsections (abfd);
00265 if (i_shdrp == 0 || i_shdrp[shindex] == 0)
00266 return NULL;
00267
00268 shstrtab = i_shdrp[shindex]->contents;
00269 if (shstrtab == NULL)
00270 {
00271
00272 offset = i_shdrp[shindex]->sh_offset;
00273 shstrtabsize = i_shdrp[shindex]->sh_size;
00274 shstrtab = elf_read (abfd, offset, shstrtabsize);
00275 i_shdrp[shindex]->contents = shstrtab;
00276 }
00277 return (char *) shstrtab;
00278 }
00279
00280 char *
00281 bfd_elf_string_from_elf_section (bfd *abfd,
00282 unsigned int shindex,
00283 unsigned int strindex)
00284 {
00285 Elf_Internal_Shdr *hdr;
00286
00287 if (strindex == 0)
00288 return "";
00289
00290 hdr = elf_elfsections (abfd)[shindex];
00291
00292 if (hdr->contents == NULL
00293 && bfd_elf_get_str_section (abfd, shindex) == NULL)
00294 return NULL;
00295
00296 if (strindex >= hdr->sh_size)
00297 {
00298 unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
00299 (*_bfd_error_handler)
00300 (_("%B: invalid string offset %u >= %lu for section `%s'"),
00301 abfd, strindex, (unsigned long) hdr->sh_size,
00302 (shindex == shstrndx && strindex == hdr->sh_name
00303 ? ".shstrtab"
00304 : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
00305 return "";
00306 }
00307
00308 return ((char *) hdr->contents) + strindex;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 Elf_Internal_Sym *
00318 bfd_elf_get_elf_syms (bfd *ibfd,
00319 Elf_Internal_Shdr *symtab_hdr,
00320 size_t symcount,
00321 size_t symoffset,
00322 Elf_Internal_Sym *intsym_buf,
00323 void *extsym_buf,
00324 Elf_External_Sym_Shndx *extshndx_buf)
00325 {
00326 Elf_Internal_Shdr *shndx_hdr;
00327 void *alloc_ext;
00328 const bfd_byte *esym;
00329 Elf_External_Sym_Shndx *alloc_extshndx;
00330 Elf_External_Sym_Shndx *shndx;
00331 Elf_Internal_Sym *isym;
00332 Elf_Internal_Sym *isymend;
00333 const struct elf_backend_data *bed;
00334 size_t extsym_size;
00335 bfd_size_type amt;
00336 file_ptr pos;
00337
00338 if (symcount == 0)
00339 return intsym_buf;
00340
00341
00342 shndx_hdr = NULL;
00343 if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
00344 shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
00345
00346
00347 alloc_ext = NULL;
00348 alloc_extshndx = NULL;
00349 bed = get_elf_backend_data (ibfd);
00350 extsym_size = bed->s->sizeof_sym;
00351 amt = symcount * extsym_size;
00352 pos = symtab_hdr->sh_offset + symoffset * extsym_size;
00353 if (extsym_buf == NULL)
00354 {
00355 alloc_ext = bfd_malloc (amt);
00356 extsym_buf = alloc_ext;
00357 }
00358 if (extsym_buf == NULL
00359 || bfd_seek (ibfd, pos, SEEK_SET) != 0
00360 || bfd_bread (extsym_buf, amt, ibfd) != amt)
00361 {
00362 intsym_buf = NULL;
00363 goto out;
00364 }
00365
00366 if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
00367 extshndx_buf = NULL;
00368 else
00369 {
00370 amt = symcount * sizeof (Elf_External_Sym_Shndx);
00371 pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
00372 if (extshndx_buf == NULL)
00373 {
00374 alloc_extshndx = bfd_malloc (amt);
00375 extshndx_buf = alloc_extshndx;
00376 }
00377 if (extshndx_buf == NULL
00378 || bfd_seek (ibfd, pos, SEEK_SET) != 0
00379 || bfd_bread (extshndx_buf, amt, ibfd) != amt)
00380 {
00381 intsym_buf = NULL;
00382 goto out;
00383 }
00384 }
00385
00386 if (intsym_buf == NULL)
00387 {
00388 bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym);
00389 intsym_buf = bfd_malloc (amt);
00390 if (intsym_buf == NULL)
00391 goto out;
00392 }
00393
00394
00395 isymend = intsym_buf + symcount;
00396 for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
00397 isym < isymend;
00398 esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
00399 (*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym);
00400
00401 out:
00402 if (alloc_ext != NULL)
00403 free (alloc_ext);
00404 if (alloc_extshndx != NULL)
00405 free (alloc_extshndx);
00406
00407 return intsym_buf;
00408 }
00409
00410
00411 const char *
00412 bfd_elf_sym_name (bfd *abfd,
00413 Elf_Internal_Shdr *symtab_hdr,
00414 Elf_Internal_Sym *isym)
00415 {
00416 unsigned int iname = isym->st_name;
00417 unsigned int shindex = symtab_hdr->sh_link;
00418 if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
00419
00420 && isym->st_shndx < elf_numsections (abfd)
00421 && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE))
00422 {
00423 iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
00424 shindex = elf_elfheader (abfd)->e_shstrndx;
00425 }
00426
00427 return bfd_elf_string_from_elf_section (abfd, shindex, iname);
00428 }
00429
00430
00431
00432
00433
00434 typedef union elf_internal_group {
00435 Elf_Internal_Shdr *shdr;
00436 unsigned int flags;
00437 } Elf_Internal_Group;
00438
00439
00440
00441
00442 static const char *
00443 group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
00444 {
00445 Elf_Internal_Shdr *hdr;
00446 unsigned char esym[sizeof (Elf64_External_Sym)];
00447 Elf_External_Sym_Shndx eshndx;
00448 Elf_Internal_Sym isym;
00449
00450
00451
00452 hdr = elf_elfsections (abfd) [ghdr->sh_link];
00453 if (hdr->sh_type != SHT_SYMTAB
00454 || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
00455 return NULL;
00456
00457
00458 hdr = &elf_tdata (abfd)->symtab_hdr;
00459 if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
00460 &isym, esym, &eshndx) == NULL)
00461 return NULL;
00462
00463 return bfd_elf_sym_name (abfd, hdr, &isym);
00464 }
00465
00466
00467
00468 static bfd_boolean
00469 setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
00470 {
00471 unsigned int num_group = elf_tdata (abfd)->num_group;
00472
00473
00474
00475 if (num_group == 0)
00476 {
00477 unsigned int i, shnum;
00478
00479
00480
00481 shnum = elf_numsections (abfd);
00482 num_group = 0;
00483 for (i = 0; i < shnum; i++)
00484 {
00485 Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
00486 if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
00487 num_group += 1;
00488 }
00489
00490 if (num_group == 0)
00491 num_group = (unsigned) -1;
00492 elf_tdata (abfd)->num_group = num_group;
00493
00494 if (num_group > 0)
00495 {
00496
00497
00498 bfd_size_type amt = num_group * sizeof (Elf_Internal_Shdr *);
00499 elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt);
00500 if (elf_tdata (abfd)->group_sect_ptr == NULL)
00501 return FALSE;
00502
00503 num_group = 0;
00504 for (i = 0; i < shnum; i++)
00505 {
00506 Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
00507 if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
00508 {
00509 unsigned char *src;
00510 Elf_Internal_Group *dest;
00511
00512
00513 elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
00514 num_group += 1;
00515
00516
00517 BFD_ASSERT (sizeof (*dest) >= 4);
00518 amt = shdr->sh_size * sizeof (*dest) / 4;
00519 shdr->contents = bfd_alloc (abfd, amt);
00520 if (shdr->contents == NULL
00521 || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
00522 || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
00523 != shdr->sh_size))
00524 return FALSE;
00525
00526
00527
00528
00529
00530 src = shdr->contents + shdr->sh_size;
00531 dest = (Elf_Internal_Group *) (shdr->contents + amt);
00532 while (1)
00533 {
00534 unsigned int idx;
00535
00536 src -= 4;
00537 --dest;
00538 idx = H_GET_32 (abfd, src);
00539 if (src == shdr->contents)
00540 {
00541 dest->flags = idx;
00542 if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
00543 shdr->bfd_section->flags
00544 |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
00545 break;
00546 }
00547 if (idx >= shnum)
00548 {
00549 ((*_bfd_error_handler)
00550 (_("%B: invalid SHT_GROUP entry"), abfd));
00551 idx = 0;
00552 }
00553 dest->shdr = elf_elfsections (abfd)[idx];
00554 }
00555 }
00556 }
00557 }
00558 }
00559
00560 if (num_group != (unsigned) -1)
00561 {
00562 unsigned int i;
00563
00564 for (i = 0; i < num_group; i++)
00565 {
00566 Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
00567 Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
00568 unsigned int n_elt = shdr->sh_size / 4;
00569
00570
00571
00572 while (--n_elt != 0)
00573 if ((++idx)->shdr == hdr)
00574 {
00575 asection *s = NULL;
00576
00577
00578
00579
00580 idx = (Elf_Internal_Group *) shdr->contents;
00581 n_elt = shdr->sh_size / 4;
00582 while (--n_elt != 0)
00583 if ((s = (++idx)->shdr->bfd_section) != NULL
00584 && elf_next_in_group (s) != NULL)
00585 break;
00586 if (n_elt != 0)
00587 {
00588
00589
00590 elf_group_name (newsect) = elf_group_name (s);
00591 elf_next_in_group (newsect) = elf_next_in_group (s);
00592 elf_next_in_group (s) = newsect;
00593 }
00594 else
00595 {
00596 const char *gname;
00597
00598 gname = group_signature (abfd, shdr);
00599 if (gname == NULL)
00600 return FALSE;
00601 elf_group_name (newsect) = gname;
00602
00603
00604 elf_next_in_group (newsect) = newsect;
00605 }
00606
00607
00608
00609 if (shdr->bfd_section != NULL)
00610 elf_next_in_group (shdr->bfd_section) = newsect;
00611
00612 i = num_group - 1;
00613 break;
00614 }
00615 }
00616 }
00617
00618 if (elf_group_name (newsect) == NULL)
00619 {
00620 (*_bfd_error_handler) (_("%B: no group info for section %A"),
00621 abfd, newsect);
00622 }
00623 return TRUE;
00624 }
00625
00626 bfd_boolean
00627 _bfd_elf_setup_group_pointers (bfd *abfd)
00628 {
00629 unsigned int i;
00630 unsigned int num_group = elf_tdata (abfd)->num_group;
00631 bfd_boolean result = TRUE;
00632
00633 if (num_group == (unsigned) -1)
00634 return result;
00635
00636 for (i = 0; i < num_group; i++)
00637 {
00638 Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
00639 Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
00640 unsigned int n_elt = shdr->sh_size / 4;
00641
00642 while (--n_elt != 0)
00643 if ((++idx)->shdr->bfd_section)
00644 elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
00645 else if (idx->shdr->sh_type == SHT_RELA
00646 || idx->shdr->sh_type == SHT_REL)
00647
00648
00649
00650
00651
00652 shdr->bfd_section->size -= 4;
00653 else
00654 {
00655
00656 (*_bfd_error_handler)
00657 (_("%B: unknown [%d] section `%s' in group [%s]"),
00658 abfd,
00659 (unsigned int) idx->shdr->sh_type,
00660 bfd_elf_string_from_elf_section (abfd,
00661 (elf_elfheader (abfd)
00662 ->e_shstrndx),
00663 idx->shdr->sh_name),
00664 shdr->bfd_section->name);
00665 result = FALSE;
00666 }
00667 }
00668 return result;
00669 }
00670
00671 bfd_boolean
00672 bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
00673 {
00674 return elf_next_in_group (sec) != NULL;
00675 }
00676
00677
00678
00679
00680 bfd_boolean
00681 _bfd_elf_make_section_from_shdr (bfd *abfd,
00682 Elf_Internal_Shdr *hdr,
00683 const char *name)
00684 {
00685 asection *newsect;
00686 flagword flags;
00687 const struct elf_backend_data *bed;
00688
00689 if (hdr->bfd_section != NULL)
00690 {
00691 BFD_ASSERT (strcmp (name,
00692 bfd_get_section_name (abfd, hdr->bfd_section)) == 0);
00693 return TRUE;
00694 }
00695
00696 newsect = bfd_make_section_anyway (abfd, name);
00697 if (newsect == NULL)
00698 return FALSE;
00699
00700 hdr->bfd_section = newsect;
00701 elf_section_data (newsect)->this_hdr = *hdr;
00702
00703
00704 elf_section_type (newsect) = hdr->sh_type;
00705 elf_section_flags (newsect) = hdr->sh_flags;
00706
00707 newsect->filepos = hdr->sh_offset;
00708
00709 if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
00710 || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
00711 || ! bfd_set_section_alignment (abfd, newsect,
00712 bfd_log2 ((bfd_vma) hdr->sh_addralign)))
00713 return FALSE;
00714
00715 flags = SEC_NO_FLAGS;
00716 if (hdr->sh_type != SHT_NOBITS)
00717 flags |= SEC_HAS_CONTENTS;
00718 if (hdr->sh_type == SHT_GROUP)
00719 flags |= SEC_GROUP | SEC_EXCLUDE;
00720 if ((hdr->sh_flags & SHF_ALLOC) != 0)
00721 {
00722 flags |= SEC_ALLOC;
00723 if (hdr->sh_type != SHT_NOBITS)
00724 flags |= SEC_LOAD;
00725 }
00726 if ((hdr->sh_flags & SHF_WRITE) == 0)
00727 flags |= SEC_READONLY;
00728 if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
00729 flags |= SEC_CODE;
00730 else if ((flags & SEC_LOAD) != 0)
00731 flags |= SEC_DATA;
00732 if ((hdr->sh_flags & SHF_MERGE) != 0)
00733 {
00734 flags |= SEC_MERGE;
00735 newsect->entsize = hdr->sh_entsize;
00736 if ((hdr->sh_flags & SHF_STRINGS) != 0)
00737 flags |= SEC_STRINGS;
00738 }
00739 if (hdr->sh_flags & SHF_GROUP)
00740 if (!setup_group (abfd, hdr, newsect))
00741 return FALSE;
00742 if ((hdr->sh_flags & SHF_TLS) != 0)
00743 flags |= SEC_THREAD_LOCAL;
00744
00745
00746
00747 {
00748 static const char *debug_sec_names [] =
00749 {
00750 ".debug",
00751 ".gnu.linkonce.wi.",
00752 ".line",
00753 ".stab"
00754 };
00755 int i;
00756
00757 for (i = ARRAY_SIZE (debug_sec_names); i--;)
00758 if (strncmp (name, debug_sec_names[i], strlen (debug_sec_names[i])) == 0)
00759 break;
00760
00761 if (i >= 0)
00762 flags |= SEC_DEBUGGING;
00763 }
00764
00765
00766
00767
00768
00769
00770
00771 if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0
00772 && elf_next_in_group (newsect) == NULL)
00773 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
00774
00775 bed = get_elf_backend_data (abfd);
00776 if (bed->elf_backend_section_flags)
00777 if (! bed->elf_backend_section_flags (&flags, hdr))
00778 return FALSE;
00779
00780 if (! bfd_set_section_flags (abfd, newsect, flags))
00781 return FALSE;
00782
00783 if ((flags & SEC_ALLOC) != 0)
00784 {
00785 Elf_Internal_Phdr *phdr;
00786 unsigned int i;
00787
00788
00789
00790
00791 phdr = elf_tdata (abfd)->phdr;
00792 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
00793 {
00794 if (phdr->p_paddr != 0)
00795 break;
00796 }
00797 if (i < elf_elfheader (abfd)->e_phnum)
00798 {
00799 phdr = elf_tdata (abfd)->phdr;
00800 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
00801 {
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814 if (phdr->p_type == PT_LOAD
00815 && (bfd_vma) hdr->sh_offset >= phdr->p_offset
00816 && (hdr->sh_offset + hdr->sh_size
00817 <= phdr->p_offset + phdr->p_memsz)
00818 && ((flags & SEC_LOAD) == 0
00819 || (hdr->sh_offset + hdr->sh_size
00820 <= phdr->p_offset + phdr->p_filesz)))
00821 {
00822 if ((flags & SEC_LOAD) == 0)
00823 newsect->lma = (phdr->p_paddr
00824 + hdr->sh_addr - phdr->p_vaddr);
00825 else
00826
00827
00828
00829
00830
00831
00832
00833 newsect->lma = (phdr->p_paddr
00834 + hdr->sh_offset - phdr->p_offset);
00835
00836
00837
00838
00839
00840 if (hdr->sh_addr >= phdr->p_vaddr
00841 && (hdr->sh_addr + hdr->sh_size
00842 <= phdr->p_vaddr + phdr->p_memsz))
00843 break;
00844 }
00845 }
00846 }
00847 }
00848
00849 return TRUE;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 struct elf_internal_shdr *
00868 bfd_elf_find_section (bfd *abfd, char *name)
00869 {
00870 Elf_Internal_Shdr **i_shdrp;
00871 char *shstrtab;
00872 unsigned int max;
00873 unsigned int i;
00874
00875 i_shdrp = elf_elfsections (abfd);
00876 if (i_shdrp != NULL)
00877 {
00878 shstrtab = bfd_elf_get_str_section (abfd,
00879 elf_elfheader (abfd)->e_shstrndx);
00880 if (shstrtab != NULL)
00881 {
00882 max = elf_numsections (abfd);
00883 for (i = 1; i < max; i++)
00884 if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
00885 return i_shdrp[i];
00886 }
00887 }
00888 return 0;
00889 }
00890
00891 const char *const bfd_elf_section_type_names[] = {
00892 "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
00893 "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
00894 "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
00895 };
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 bfd_reloc_status_type
00908 bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
00909 arelent *reloc_entry,
00910 asymbol *symbol,
00911 void *data ATTRIBUTE_UNUSED,
00912 asection *input_section,
00913 bfd *output_bfd,
00914 char **error_message ATTRIBUTE_UNUSED)
00915 {
00916 if (output_bfd != NULL
00917 && (symbol->flags & BSF_SECTION_SYM) == 0
00918 && (! reloc_entry->howto->partial_inplace
00919 || reloc_entry->addend == 0))
00920 {
00921 reloc_entry->address += input_section->output_offset;
00922 return bfd_reloc_ok;
00923 }
00924
00925 return bfd_reloc_continue;
00926 }
00927
00928
00929
00930 static void
00931 merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED,
00932 asection *sec)
00933 {
00934 BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE);
00935 sec->sec_info_type = ELF_INFO_TYPE_NONE;
00936 }
00937
00938
00939
00940 bfd_boolean
00941 _bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
00942 {
00943 bfd *ibfd;
00944 asection *sec;
00945
00946 if (!is_elf_hash_table (info->hash))
00947 return FALSE;
00948
00949 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
00950 if ((ibfd->flags & DYNAMIC) == 0)
00951 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
00952 if ((sec->flags & SEC_MERGE) != 0
00953 && !bfd_is_abs_section (sec->output_section))
00954 {
00955 struct bfd_elf_section_data *secdata;
00956
00957 secdata = elf_section_data (sec);
00958 if (! _bfd_add_merge_section (abfd,
00959 &elf_hash_table (info)->merge_info,
00960 sec, &secdata->sec_info))
00961 return FALSE;
00962 else if (secdata->sec_info)
00963 sec->sec_info_type = ELF_INFO_TYPE_MERGE;
00964 }
00965
00966 if (elf_hash_table (info)->merge_info != NULL)
00967 _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info,
00968 merge_sections_remove_hook);
00969 return TRUE;
00970 }
00971
00972 void
00973 _bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
00974 {
00975 sec->output_section = bfd_abs_section_ptr;
00976 sec->output_offset = sec->vma;
00977 if (!is_elf_hash_table (info->hash))
00978 return;
00979
00980 sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS;
00981 }
00982
00983
00984
00985
00986 bfd_boolean
00987 _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
00988 {
00989 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00990 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00991 return TRUE;
00992
00993 BFD_ASSERT (!elf_flags_init (obfd)
00994 || (elf_elfheader (obfd)->e_flags
00995 == elf_elfheader (ibfd)->e_flags));
00996
00997 elf_gp (obfd) = elf_gp (ibfd);
00998 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
00999 elf_flags_init (obfd) = TRUE;
01000 return TRUE;
01001 }
01002
01003
01004
01005 bfd_boolean
01006 _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
01007 {
01008 FILE *f = farg;
01009 Elf_Internal_Phdr *p;
01010 asection *s;
01011 bfd_byte *dynbuf = NULL;
01012
01013 p = elf_tdata (abfd)->phdr;
01014 if (p != NULL)
01015 {
01016 unsigned int i, c;
01017
01018 fprintf (f, _("\nProgram Header:\n"));
01019 c = elf_elfheader (abfd)->e_phnum;
01020 for (i = 0; i < c; i++, p++)
01021 {
01022 const char *pt;
01023 char buf[20];
01024
01025 switch (p->p_type)
01026 {
01027 case PT_NULL: pt = "NULL"; break;
01028 case PT_LOAD: pt = "LOAD"; break;
01029 case PT_DYNAMIC: pt = "DYNAMIC"; break;
01030 case PT_INTERP: pt = "INTERP"; break;
01031 case PT_NOTE: pt = "NOTE"; break;
01032 case PT_SHLIB: pt = "SHLIB"; break;
01033 case PT_PHDR: pt = "PHDR"; break;
01034 case PT_TLS: pt = "TLS"; break;
01035 case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
01036 case PT_GNU_STACK: pt = "STACK"; break;
01037 case PT_GNU_RELRO: pt = "RELRO"; break;
01038 default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
01039 }
01040 fprintf (f, "%8s off 0x", pt);
01041 bfd_fprintf_vma (abfd, f, p->p_offset);
01042 fprintf (f, " vaddr 0x");
01043 bfd_fprintf_vma (abfd, f, p->p_vaddr);
01044 fprintf (f, " paddr 0x");
01045 bfd_fprintf_vma (abfd, f, p->p_paddr);
01046 fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
01047 fprintf (f, " filesz 0x");
01048 bfd_fprintf_vma (abfd, f, p->p_filesz);
01049 fprintf (f, " memsz 0x");
01050 bfd_fprintf_vma (abfd, f, p->p_memsz);
01051 fprintf (f, " flags %c%c%c",
01052 (p->p_flags & PF_R) != 0 ? 'r' : '-',
01053 (p->p_flags & PF_W) != 0 ? 'w' : '-',
01054 (p->p_flags & PF_X) != 0 ? 'x' : '-');
01055 if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
01056 fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
01057 fprintf (f, "\n");
01058 }
01059 }
01060
01061 s = bfd_get_section_by_name (abfd, ".dynamic");
01062 if (s != NULL)
01063 {
01064 int elfsec;
01065 unsigned long shlink;
01066 bfd_byte *extdyn, *extdynend;
01067 size_t extdynsize;
01068 void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
01069
01070 fprintf (f, _("\nDynamic Section:\n"));
01071
01072 if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
01073 goto error_return;
01074
01075 elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
01076 if (elfsec == -1)
01077 goto error_return;
01078 shlink = elf_elfsections (abfd)[elfsec]->sh_link;
01079
01080 extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
01081 swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
01082
01083 extdyn = dynbuf;
01084 extdynend = extdyn + s->size;
01085 for (; extdyn < extdynend; extdyn += extdynsize)
01086 {
01087 Elf_Internal_Dyn dyn;
01088 const char *name;
01089 char ab[20];
01090 bfd_boolean stringp;
01091
01092 (*swap_dyn_in) (abfd, extdyn, &dyn);
01093
01094 if (dyn.d_tag == DT_NULL)
01095 break;
01096
01097 stringp = FALSE;
01098 switch (dyn.d_tag)
01099 {
01100 default:
01101 sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
01102 name = ab;
01103 break;
01104
01105 case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
01106 case DT_PLTRELSZ: name = "PLTRELSZ"; break;
01107 case DT_PLTGOT: name = "PLTGOT"; break;
01108 case DT_HASH: name = "HASH"; break;
01109 case DT_STRTAB: name = "STRTAB"; break;
01110 case DT_SYMTAB: name = "SYMTAB"; break;
01111 case DT_RELA: name = "RELA"; break;
01112 case DT_RELASZ: name = "RELASZ"; break;
01113 case DT_RELAENT: name = "RELAENT"; break;
01114 case DT_STRSZ: name = "STRSZ"; break;
01115 case DT_SYMENT: name = "SYMENT"; break;
01116 case DT_INIT: name = "INIT"; break;
01117 case DT_FINI: name = "FINI"; break;
01118 case DT_SONAME: name = "SONAME"; stringp = TRUE; break;
01119 case DT_RPATH: name = "RPATH"; stringp = TRUE; break;
01120 case DT_SYMBOLIC: name = "SYMBOLIC"; break;
01121 case DT_REL: name = "REL"; break;
01122 case DT_RELSZ: name = "RELSZ"; break;
01123 case DT_RELENT: name = "RELENT"; break;
01124 case DT_PLTREL: name = "PLTREL"; break;
01125 case DT_DEBUG: name = "DEBUG"; break;
01126 case DT_TEXTREL: name = "TEXTREL"; break;
01127 case DT_JMPREL: name = "JMPREL"; break;
01128 case DT_BIND_NOW: name = "BIND_NOW"; break;
01129 case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
01130 case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
01131 case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
01132 case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
01133 case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break;
01134 case DT_FLAGS: name = "FLAGS"; break;
01135 case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
01136 case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
01137 case DT_CHECKSUM: name = "CHECKSUM"; break;
01138 case DT_PLTPADSZ: name = "PLTPADSZ"; break;
01139 case DT_MOVEENT: name = "MOVEENT"; break;
01140 case DT_MOVESZ: name = "MOVESZ"; break;
01141 case DT_FEATURE: name = "FEATURE"; break;
01142 case DT_POSFLAG_1: name = "POSFLAG_1"; break;
01143 case DT_SYMINSZ: name = "SYMINSZ"; break;
01144 case DT_SYMINENT: name = "SYMINENT"; break;
01145 case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break;
01146 case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break;
01147 case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break;
01148 case DT_PLTPAD: name = "PLTPAD"; break;
01149 case DT_MOVETAB: name = "MOVETAB"; break;
01150 case DT_SYMINFO: name = "SYMINFO"; break;
01151 case DT_RELACOUNT: name = "RELACOUNT"; break;
01152 case DT_RELCOUNT: name = "RELCOUNT"; break;
01153 case DT_FLAGS_1: name = "FLAGS_1"; break;
01154 case DT_VERSYM: name = "VERSYM"; break;
01155 case DT_VERDEF: name = "VERDEF"; break;
01156 case DT_VERDEFNUM: name = "VERDEFNUM"; break;
01157 case DT_VERNEED: name = "VERNEED"; break;
01158 case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
01159 case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break;
01160 case DT_USED: name = "USED"; break;
01161 case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
01162 }
01163
01164 fprintf (f, " %-11s ", name);
01165 if (! stringp)
01166 fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
01167 else
01168 {
01169 const char *string;
01170 unsigned int tagv = dyn.d_un.d_val;
01171
01172 string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
01173 if (string == NULL)
01174 goto error_return;
01175 fprintf (f, "%s", string);
01176 }
01177 fprintf (f, "\n");
01178 }
01179
01180 free (dynbuf);
01181 dynbuf = NULL;
01182 }
01183
01184 if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
01185 || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
01186 {
01187 if (! _bfd_elf_slurp_version_tables (abfd, FALSE))
01188 return FALSE;
01189 }
01190
01191 if (elf_dynverdef (abfd) != 0)
01192 {
01193 Elf_Internal_Verdef *t;
01194
01195 fprintf (f, _("\nVersion definitions:\n"));
01196 for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
01197 {
01198 fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
01199 t->vd_flags, t->vd_hash, t->vd_nodename);
01200 if (t->vd_auxptr->vda_nextptr != NULL)
01201 {
01202 Elf_Internal_Verdaux *a;
01203
01204 fprintf (f, "\t");
01205 for (a = t->vd_auxptr->vda_nextptr;
01206 a != NULL;
01207 a = a->vda_nextptr)
01208 fprintf (f, "%s ", a->vda_nodename);
01209 fprintf (f, "\n");
01210 }
01211 }
01212 }
01213
01214 if (elf_dynverref (abfd) != 0)
01215 {
01216 Elf_Internal_Verneed *t;
01217
01218 fprintf (f, _("\nVersion References:\n"));
01219 for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
01220 {
01221 Elf_Internal_Vernaux *a;
01222
01223 fprintf (f, _(" required from %s:\n"), t->vn_filename);
01224 for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
01225 fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
01226 a->vna_flags, a->vna_other, a->vna_nodename);
01227 }
01228 }
01229
01230 return TRUE;
01231
01232 error_return:
01233 if (dynbuf != NULL)
01234 free (dynbuf);
01235 return FALSE;
01236 }
01237
01238
01239
01240 void
01241 bfd_elf_print_symbol (bfd *abfd,
01242 void *filep,
01243 asymbol *symbol,
01244 bfd_print_symbol_type how)
01245 {
01246 FILE *file = filep;
01247 switch (how)
01248 {
01249 case bfd_print_symbol_name:
01250 fprintf (file, "%s", symbol->name);
01251 break;
01252 case bfd_print_symbol_more:
01253 fprintf (file, "elf ");
01254 bfd_fprintf_vma (abfd, file, symbol->value);
01255 fprintf (file, " %lx", (long) symbol->flags);
01256 break;
01257 case bfd_print_symbol_all:
01258 {
01259 const char *section_name;
01260 const char *name = NULL;
01261 const struct elf_backend_data *bed;
01262 unsigned char st_other;
01263 bfd_vma val;
01264
01265 section_name = symbol->section ? symbol->section->name : "(*none*)";
01266
01267 bed = get_elf_backend_data (abfd);
01268 if (bed->elf_backend_print_symbol_all)
01269 name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
01270
01271 if (name == NULL)
01272 {
01273 name = symbol->name;
01274 bfd_print_symbol_vandf (abfd, file, symbol);
01275 }
01276
01277 fprintf (file, " %s\t", section_name);
01278
01279
01280
01281
01282 if (bfd_is_com_section (symbol->section))
01283 val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
01284 else
01285 val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
01286 bfd_fprintf_vma (abfd, file, val);
01287
01288
01289 if (elf_tdata (abfd)->dynversym_section != 0
01290 && (elf_tdata (abfd)->dynverdef_section != 0
01291 || elf_tdata (abfd)->dynverref_section != 0))
01292 {
01293 unsigned int vernum;
01294 const char *version_string;
01295
01296 vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION;
01297
01298 if (vernum == 0)
01299 version_string = "";
01300 else if (vernum == 1)
01301 version_string = "Base";
01302 else if (vernum <= elf_tdata (abfd)->cverdefs)
01303 version_string =
01304 elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
01305 else
01306 {
01307 Elf_Internal_Verneed *t;
01308
01309 version_string = "";
01310 for (t = elf_tdata (abfd)->verref;
01311 t != NULL;
01312 t = t->vn_nextref)
01313 {
01314 Elf_Internal_Vernaux *a;
01315
01316 for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
01317 {
01318 if (a->vna_other == vernum)
01319 {
01320 version_string = a->vna_nodename;
01321 break;
01322 }
01323 }
01324 }
01325 }
01326
01327 if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0)
01328 fprintf (file, " %-11s", version_string);
01329 else
01330 {
01331 int i;
01332
01333 fprintf (file, " (%s)", version_string);
01334 for (i = 10 - strlen (version_string); i > 0; --i)
01335 putc (' ', file);
01336 }
01337 }
01338
01339
01340 st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;
01341
01342 switch (st_other)
01343 {
01344 case 0: break;
01345 case STV_INTERNAL: fprintf (file, " .internal"); break;
01346 case STV_HIDDEN: fprintf (file, " .hidden"); break;
01347 case STV_PROTECTED: fprintf (file, " .protected"); break;
01348 default:
01349
01350
01351 fprintf (file, " 0x%02x", (unsigned int) st_other);
01352 }
01353
01354 fprintf (file, " %s", name);
01355 }
01356 break;
01357 }
01358 }
01359
01360
01361
01362 struct bfd_hash_entry *
01363 _bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
01364 struct bfd_hash_table *table,
01365 const char *string)
01366 {
01367
01368
01369 if (entry == NULL)
01370 {
01371 entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
01372 if (entry == NULL)
01373 return entry;
01374 }
01375
01376
01377 entry = _bfd_link_hash_newfunc (entry, table, string);
01378 if (entry != NULL)
01379 {
01380 struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
01381 struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;
01382
01383
01384 ret->indx = -1;
01385 ret->dynindx = -1;
01386 ret->got = ret->plt = htab->init_refcount;
01387 memset (&ret->size, 0, (sizeof (struct elf_link_hash_entry)
01388 - offsetof (struct elf_link_hash_entry, size)));
01389
01390
01391
01392
01393 ret->non_elf = 1;
01394
01395 #ifdef IPA_LINK
01396
01397 ret->ipa_indx = 0;
01398 #endif
01399 }
01400
01401 return entry;
01402 }
01403
01404
01405
01406
01407 void
01408 _bfd_elf_link_hash_copy_indirect (const struct elf_backend_data *bed,
01409 struct elf_link_hash_entry *dir,
01410 struct elf_link_hash_entry *ind)
01411 {
01412 bfd_signed_vma tmp;
01413 bfd_signed_vma lowest_valid = bed->can_refcount;
01414
01415
01416
01417
01418 dir->ref_dynamic |= ind->ref_dynamic;
01419 dir->ref_regular |= ind->ref_regular;
01420 dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
01421 dir->non_got_ref |= ind->non_got_ref;
01422 dir->needs_plt |= ind->needs_plt;
01423 dir->pointer_equality_needed |= ind->pointer_equality_needed;
01424
01425 if (ind->root.type != bfd_link_hash_indirect)
01426 return;
01427
01428
01429
01430 tmp = dir->got.refcount;
01431 if (tmp < lowest_valid)
01432 {
01433 dir->got.refcount = ind->got.refcount;
01434 ind->got.refcount = tmp;
01435 }
01436 else
01437 BFD_ASSERT (ind->got.refcount < lowest_valid);
01438
01439 tmp = dir->plt.refcount;
01440 if (tmp < lowest_valid)
01441 {
01442 dir->plt.refcount = ind->plt.refcount;
01443 ind->plt.refcount = tmp;
01444 }
01445 else
01446 BFD_ASSERT (ind->plt.refcount < lowest_valid);
01447
01448 if (dir->dynindx == -1)
01449 {
01450 dir->dynindx = ind->dynindx;
01451 dir->dynstr_index = ind->dynstr_index;
01452 ind->dynindx = -1;
01453 ind->dynstr_index = 0;
01454 }
01455 else
01456 BFD_ASSERT (ind->dynindx == -1);
01457 }
01458
01459 void
01460 _bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info,
01461 struct elf_link_hash_entry *h,
01462 bfd_boolean force_local)
01463 {
01464 h->plt = elf_hash_table (info)->init_offset;
01465 h->needs_plt = 0;
01466 if (force_local)
01467 {
01468 h->forced_local = 1;
01469 if (h->dynindx != -1)
01470 {
01471 h->dynindx = -1;
01472 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
01473 h->dynstr_index);
01474 }
01475 }
01476 }
01477
01478
01479
01480 bfd_boolean
01481 _bfd_elf_link_hash_table_init
01482 (struct elf_link_hash_table *table,
01483 bfd *abfd,
01484 struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
01485 struct bfd_hash_table *,
01486 const char *))
01487 {
01488 bfd_boolean ret;
01489
01490 table->dynamic_sections_created = FALSE;
01491 table->dynobj = NULL;
01492
01493
01494 table->init_refcount.refcount = get_elf_backend_data (abfd)->can_refcount;
01495 table->init_refcount.refcount -= 1;
01496 table->init_offset.offset = -(bfd_vma) 1;
01497
01498 table->dynsymcount = 1;
01499 table->dynstr = NULL;
01500 table->bucketcount = 0;
01501 table->needed = NULL;
01502 table->hgot = NULL;
01503 table->merge_info = NULL;
01504 memset (&table->stab_info, 0, sizeof (table->stab_info));
01505 memset (&table->eh_info, 0, sizeof (table->eh_info));
01506 table->dynlocal = NULL;
01507 table->runpath = NULL;
01508 table->tls_sec = NULL;
01509 table->tls_size = 0;
01510 table->loaded = NULL;
01511 table->is_relocatable_executable = FALSE;
01512
01513 ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc);
01514 table->root.type = bfd_link_elf_hash_table;
01515
01516 return ret;
01517 }
01518
01519
01520
01521 struct bfd_link_hash_table *
01522 _bfd_elf_link_hash_table_create (bfd *abfd)
01523 {
01524 struct elf_link_hash_table *ret;
01525 bfd_size_type amt = sizeof (struct elf_link_hash_table);
01526
01527 ret = bfd_malloc (amt);
01528 if (ret == NULL)
01529 return NULL;
01530
01531 if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc))
01532 {
01533 free (ret);
01534 return NULL;
01535 }
01536
01537 return &ret->root;
01538 }
01539
01540
01541
01542
01543
01544 void
01545 bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
01546 {
01547 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
01548 && bfd_get_format (abfd) == bfd_object)
01549 elf_dt_name (abfd) = name;
01550 }
01551
01552 int
01553 bfd_elf_get_dyn_lib_class (bfd *abfd)
01554 {
01555 int lib_class;
01556 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
01557 && bfd_get_format (abfd) == bfd_object)
01558 lib_class = elf_dyn_lib_class (abfd);
01559 else
01560 lib_class = 0;
01561 return lib_class;
01562 }
01563
01564 void
01565 bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class)
01566 {
01567 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
01568 && bfd_get_format (abfd) == bfd_object)
01569 elf_dyn_lib_class (abfd) = lib_class;
01570 }
01571
01572
01573
01574
01575 struct bfd_link_needed_list *
01576 bfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED,
01577 struct bfd_link_info *info)
01578 {
01579 if (! is_elf_hash_table (info->hash))
01580 return NULL;
01581 return elf_hash_table (info)->needed;
01582 }
01583
01584
01585
01586
01587 struct bfd_link_needed_list *
01588 bfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED,
01589 struct bfd_link_info *info)
01590 {
01591 if (! is_elf_hash_table (info->hash))
01592 return NULL;
01593 return elf_hash_table (info)->runpath;
01594 }
01595
01596
01597
01598
01599
01600 const char *
01601 bfd_elf_get_dt_soname (bfd *abfd)
01602 {
01603 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
01604 && bfd_get_format (abfd) == bfd_object)
01605 return elf_dt_name (abfd);
01606 return NULL;
01607 }
01608
01609
01610
01611
01612 bfd_boolean
01613 bfd_elf_get_bfd_needed_list (bfd *abfd,
01614 struct bfd_link_needed_list **pneeded)
01615 {
01616 asection *s;
01617 bfd_byte *dynbuf = NULL;
01618 int elfsec;
01619 unsigned long shlink;
01620 bfd_byte *extdyn, *extdynend;
01621 size_t extdynsize;
01622 void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
01623
01624 *pneeded = NULL;
01625
01626 if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
01627 || bfd_get_format (abfd) != bfd_object)
01628 return TRUE;
01629
01630 s = bfd_get_section_by_name (abfd, ".dynamic");
01631 if (s == NULL || s->size == 0)
01632 return TRUE;
01633
01634 if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
01635 goto error_return;
01636
01637 elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
01638 if (elfsec == -1)
01639 goto error_return;
01640
01641 shlink = elf_elfsections (abfd)[elfsec]->sh_link;
01642
01643 extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
01644 swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
01645
01646 extdyn = dynbuf;
01647 extdynend = extdyn + s->size;
01648 for (; extdyn < extdynend; extdyn += extdynsize)
01649 {
01650 Elf_Internal_Dyn dyn;
01651
01652 (*swap_dyn_in) (abfd, extdyn, &dyn);
01653
01654 if (dyn.d_tag == DT_NULL)
01655 break;
01656
01657 if (dyn.d_tag == DT_NEEDED)
01658 {
01659 const char *string;
01660 struct bfd_link_needed_list *l;
01661 unsigned int tagv = dyn.d_un.d_val;
01662 bfd_size_type amt;
01663
01664 string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
01665 if (string == NULL)
01666 goto error_return;
01667
01668 amt = sizeof *l;
01669 l = bfd_alloc (abfd, amt);
01670 if (l == NULL)
01671 goto error_return;
01672
01673 l->by = abfd;
01674 l->name = string;
01675 l->next = *pneeded;
01676 *pneeded = l;
01677 }
01678 }
01679
01680 free (dynbuf);
01681
01682 return TRUE;
01683
01684 error_return:
01685 if (dynbuf != NULL)
01686 free (dynbuf);
01687 return FALSE;
01688 }
01689
01690
01691
01692 struct bfd_strtab_hash *
01693 _bfd_elf_stringtab_init (void)
01694 {
01695 struct bfd_strtab_hash *ret;
01696
01697 ret = _bfd_stringtab_init ();
01698 if (ret != NULL)
01699 {
01700 bfd_size_type loc;
01701
01702 loc = _bfd_stringtab_add (ret, "", TRUE, FALSE);
01703 BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1);
01704 if (loc == (bfd_size_type) -1)
01705 {
01706 _bfd_stringtab_free (ret);
01707 ret = NULL;
01708 }
01709 }
01710 return ret;
01711 }
01712
01713
01714
01715
01716
01717 bfd_boolean
01718 bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
01719 {
01720 Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
01721 Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
01722 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
01723 const char *name;
01724
01725 name = bfd_elf_string_from_elf_section (abfd,
01726 elf_elfheader (abfd)->e_shstrndx,
01727 hdr->sh_name);
01728
01729 switch (hdr->sh_type)
01730 {
01731 case SHT_NULL:
01732
01733 return TRUE;
01734
01735 case SHT_PROGBITS:
01736 case SHT_NOBITS:
01737 case SHT_HASH:
01738 case SHT_NOTE:
01739 case SHT_INIT_ARRAY:
01740 case SHT_FINI_ARRAY:
01741 case SHT_PREINIT_ARRAY:
01742 case SHT_GNU_LIBLIST:
01743 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
01744
01745 case SHT_DYNAMIC:
01746 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
01747 return FALSE;
01748 if (hdr->sh_link > elf_numsections (abfd)
01749 || elf_elfsections (abfd)[hdr->sh_link] == NULL)
01750 return FALSE;
01751 if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
01752 {
01753 Elf_Internal_Shdr *dynsymhdr;
01754
01755
01756
01757
01758 if (elf_dynsymtab (abfd) != 0)
01759 {
01760 dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
01761 hdr->sh_link = dynsymhdr->sh_link;
01762 }
01763 else
01764 {
01765 unsigned int i, num_sec;
01766
01767 num_sec = elf_numsections (abfd);
01768 for (i = 1; i < num_sec; i++)
01769 {
01770 dynsymhdr = elf_elfsections (abfd)[i];
01771 if (dynsymhdr->sh_type == SHT_DYNSYM)
01772 {
01773 hdr->sh_link = dynsymhdr->sh_link;
01774 break;
01775 }
01776 }
01777 }
01778 }
01779 break;
01780
01781 case SHT_SYMTAB:
01782 if (elf_onesymtab (abfd) == shindex)
01783 return TRUE;
01784
01785 BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym);
01786 BFD_ASSERT (elf_onesymtab (abfd) == 0);
01787 elf_onesymtab (abfd) = shindex;
01788 elf_tdata (abfd)->symtab_hdr = *hdr;
01789 elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
01790 abfd->flags |= HAS_SYMS;
01791
01792
01793
01794
01795
01796
01797
01798 if ((hdr->sh_flags & SHF_ALLOC) != 0
01799 && (abfd->flags & DYNAMIC) != 0
01800 && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
01801 return FALSE;
01802
01803
01804
01805
01806 if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex)
01807 {
01808 unsigned int i, num_sec;
01809
01810 num_sec = elf_numsections (abfd);
01811 for (i = shindex + 1; i < num_sec; i++)
01812 {
01813 Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
01814 if (hdr2->sh_type == SHT_SYMTAB_SHNDX
01815 && hdr2->sh_link == shindex)
01816 break;
01817 }
01818 if (i == num_sec)
01819 for (i = 1; i < shindex; i++)
01820 {
01821 Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
01822 if (hdr2->sh_type == SHT_SYMTAB_SHNDX
01823 && hdr2->sh_link == shindex)
01824 break;
01825 }
01826 if (i != shindex)
01827 return bfd_section_from_shdr (abfd, i);
01828 }
01829 return TRUE;
01830
01831 case SHT_DYNSYM:
01832 if (elf_dynsymtab (abfd) == shindex)
01833 return TRUE;
01834
01835 BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym);
01836 BFD_ASSERT (elf_dynsymtab (abfd) == 0);
01837 elf_dynsymtab (abfd) = shindex;
01838 elf_tdata (abfd)->dynsymtab_hdr = *hdr;
01839 elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
01840 abfd->flags |= HAS_SYMS;
01841
01842
01843
01844 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
01845
01846 case SHT_SYMTAB_SHNDX:
01847 if (elf_symtab_shndx (abfd) == shindex)
01848 return TRUE;
01849
01850 BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
01851 elf_symtab_shndx (abfd) = shindex;
01852 elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
01853 elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
01854 return TRUE;
01855
01856 case SHT_STRTAB:
01857 if (hdr->bfd_section != NULL)
01858 return TRUE;
01859 if (ehdr->e_shstrndx == shindex)
01860 {
01861 elf_tdata (abfd)->shstrtab_hdr = *hdr;
01862 elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
01863 return TRUE;
01864 }
01865 if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
01866 {
01867 symtab_strtab:
01868 elf_tdata (abfd)->strtab_hdr = *hdr;
01869 elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
01870 return TRUE;
01871 }
01872 if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
01873 {
01874 dynsymtab_strtab:
01875 elf_tdata (abfd)->dynstrtab_hdr = *hdr;
01876 hdr = &elf_tdata (abfd)->dynstrtab_hdr;
01877 elf_elfsections (abfd)[shindex] = hdr;
01878
01879
01880 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
01881 }
01882
01883
01884
01885
01886 if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
01887 {
01888 unsigned int i, num_sec;
01889
01890 num_sec = elf_numsections (abfd);
01891 for (i = 1; i < num_sec; i++)
01892 {
01893 Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
01894 if (hdr2->sh_link == shindex)
01895 {
01896 if (! bfd_section_from_shdr (abfd, i))
01897 return FALSE;
01898 if (elf_onesymtab (abfd) == i)
01899 goto symtab_strtab;
01900 if (elf_dynsymtab (abfd) == i)
01901 goto dynsymtab_strtab;
01902 }
01903 }
01904 }
01905 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
01906
01907 case SHT_REL:
01908 case SHT_RELA:
01909
01910 {
01911 asection *target_sect;
01912 Elf_Internal_Shdr *hdr2;
01913 unsigned int num_sec = elf_numsections (abfd);
01914
01915
01916 if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
01917 || hdr->sh_link >= num_sec)
01918 {
01919 ((*_bfd_error_handler)
01920 (_("%B: invalid link %lu for reloc section %s (index %u)"),
01921 abfd, hdr->sh_link, name, shindex));
01922 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
01923 }
01924
01925
01926
01927
01928
01929
01930
01931
01932 if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
01933 && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
01934 {
01935 unsigned int scan;
01936 int found;
01937
01938 found = 0;
01939 for (scan = 1; scan < num_sec; scan++)
01940 {
01941 if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
01942 || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
01943 {
01944 if (found != 0)
01945 {
01946 found = 0;
01947 break;
01948 }
01949 found = scan;
01950 }
01951 }
01952 if (found != 0)
01953 hdr->sh_link = found;
01954 }
01955
01956
01957 if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
01958 || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
01959 && ! bfd_section_from_shdr (abfd, hdr->sh_link))
01960 return FALSE;
01961
01962
01963
01964
01965
01966
01967
01968 if (hdr->sh_link != elf_onesymtab (abfd) || hdr->sh_info == SHN_UNDEF)
01969 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
01970
01971 if (! bfd_section_from_shdr (abfd, hdr->sh_info))
01972 return FALSE;
01973 target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
01974 if (target_sect == NULL)
01975 return FALSE;
01976
01977 if ((target_sect->flags & SEC_RELOC) == 0
01978 || target_sect->reloc_count == 0)
01979 hdr2 = &elf_section_data (target_sect)->rel_hdr;
01980 else
01981 {
01982 bfd_size_type amt;
01983 BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
01984 amt = sizeof (*hdr2);
01985 hdr2 = bfd_alloc (abfd, amt);
01986 elf_section_data (target_sect)->rel_hdr2 = hdr2;
01987 }
01988 *hdr2 = *hdr;
01989 elf_elfsections (abfd)[shindex] = hdr2;
01990 target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
01991 target_sect->flags |= SEC_RELOC;
01992 target_sect->relocation = NULL;
01993 target_sect->rel_filepos = hdr->sh_offset;
01994
01995
01996 if (hdr->sh_size != 0)
01997 target_sect->use_rela_p = hdr->sh_type == SHT_RELA;
01998 abfd->flags |= HAS_RELOC;
01999 return TRUE;
02000 }
02001 break;
02002
02003 case SHT_GNU_verdef:
02004 elf_dynverdef (abfd) = shindex;
02005 elf_tdata (abfd)->dynverdef_hdr = *hdr;
02006 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
02007 break;
02008
02009 case SHT_GNU_versym:
02010 elf_dynversym (abfd) = shindex;
02011 elf_tdata (abfd)->dynversym_hdr = *hdr;
02012 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
02013 break;
02014
02015 case SHT_GNU_verneed:
02016 elf_dynverref (abfd) = shindex;
02017 elf_tdata (abfd)->dynverref_hdr = *hdr;
02018 return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
02019 break;
02020
02021 case SHT_SHLIB:
02022 return TRUE;
02023
02024 case SHT_GROUP:
02025
02026
02027
02028 name = group_signature (abfd, hdr);
02029 if (name == NULL)
02030 return FALSE;
02031 if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name))
02032 return FALSE;
02033 if (hdr->contents != NULL)
02034 {
02035 Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
02036 unsigned int n_elt = hdr->sh_size / 4;
02037 asection *s;
02038
02039 if (idx->flags & GRP_COMDAT)
02040 hdr->bfd_section->flags
02041 |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
02042
02043
02044 idx += n_elt;
02045 while (--n_elt != 0)
02046 if ((s = (--idx)->shdr->bfd_section) != NULL
02047 && elf_next_in_group (s) != NULL)
02048 {
02049 elf_next_in_group (hdr->bfd_section) = s;
02050 break;
02051 }
02052 }
02053 break;
02054
02055 default:
02056
02057
02058 {
02059 if (bed->elf_backend_section_from_shdr)
02060 (*bed->elf_backend_section_from_shdr) (abfd, hdr, name);
02061 }
02062 break;
02063 }
02064
02065 return TRUE;
02066 }
02067
02068
02069
02070
02071 asection *
02072 bfd_section_from_r_symndx (bfd *abfd,
02073 struct sym_sec_cache *cache,
02074 asection *sec,
02075 unsigned long r_symndx)
02076 {
02077 Elf_Internal_Shdr *symtab_hdr;
02078 unsigned char esym[sizeof (Elf64_External_Sym)];
02079 Elf_External_Sym_Shndx eshndx;
02080 Elf_Internal_Sym isym;
02081 unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
02082
02083 if (cache->abfd == abfd && cache->indx[ent] == r_symndx)
02084 return cache->sec[ent];
02085
02086 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
02087 if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
02088 &isym, esym, &eshndx) == NULL)
02089 return NULL;
02090
02091 if (cache->abfd != abfd)
02092 {
02093 memset (cache->indx, -1, sizeof (cache->indx));
02094 cache->abfd = abfd;
02095 }
02096 cache->indx[ent] = r_symndx;
02097 cache->sec[ent] = sec;
02098 if ((isym.st_shndx != SHN_UNDEF && isym.st_shndx < SHN_LORESERVE)
02099 || isym.st_shndx > SHN_HIRESERVE)
02100 {
02101 asection *s;
02102 s = bfd_section_from_elf_index (abfd, isym.st_shndx);
02103 if (s != NULL)
02104 cache->sec[ent] = s;
02105 }
02106 return cache->sec[ent];
02107 }
02108
02109
02110
02111
02112 asection *
02113 bfd_section_from_elf_index (bfd *abfd, unsigned int index)
02114 {
02115 if (index >= elf_numsections (abfd))
02116 return NULL;
02117 return elf_elfsections (abfd)[index]->bfd_section;
02118 }
02119
02120 static struct bfd_elf_special_section const special_sections[] =
02121 {
02122 { ".bss", 4, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
02123 { ".gnu.linkonce.b",15, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
02124 { ".comment", 8, 0, SHT_PROGBITS, 0 },
02125 { ".data", 5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
02126 { ".data1", 6, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
02127 { ".debug", 6, 0, SHT_PROGBITS, 0 },
02128 { ".fini", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
02129 { ".init", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
02130 { ".line", 5, 0, SHT_PROGBITS, 0 },
02131 { ".rodata", 7, -2, SHT_PROGBITS, SHF_ALLOC },
02132 { ".rodata1", 8, 0, SHT_PROGBITS, SHF_ALLOC },
02133 { ".tbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
02134 { ".tdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
02135 { ".text", 5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
02136 { ".init_array", 11, 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
02137 { ".fini_array", 11, 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
02138 { ".preinit_array", 14, 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
02139 { ".debug_line", 11, 0, SHT_PROGBITS, 0 },
02140 { ".debug_info", 11, 0, SHT_PROGBITS, 0 },
02141 { ".debug_abbrev", 13, 0, SHT_PROGBITS, 0 },
02142 { ".debug_aranges", 14, 0, SHT_PROGBITS, 0 },
02143 { ".dynamic", 8, 0, SHT_DYNAMIC, SHF_ALLOC },
02144 { ".dynstr", 7, 0, SHT_STRTAB, SHF_ALLOC },
02145 { ".dynsym", 7, 0, SHT_DYNSYM, SHF_ALLOC },
02146 { ".got", 4, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
02147 { ".hash", 5, 0, SHT_HASH, SHF_ALLOC },
02148 { ".interp", 7, 0, SHT_PROGBITS, 0 },
02149 { ".plt", 4, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
02150 { ".shstrtab", 9, 0, SHT_STRTAB, 0 },
02151 { ".strtab", 7, 0, SHT_STRTAB, 0 },
02152 { ".symtab", 7, 0, SHT_SYMTAB, 0 },
02153 { ".gnu.version", 12, 0, SHT_GNU_versym, 0 },
02154 { ".gnu.version_d", 14, 0, SHT_GNU_verdef, 0 },
02155 { ".gnu.version_r", 14, 0, SHT_GNU_verneed, 0 },
02156 { ".note.GNU-stack",15, 0, SHT_PROGBITS, 0 },
02157 { ".note", 5, -1, SHT_NOTE, 0 },
02158 { ".rela", 5, -1, SHT_RELA, 0 },
02159 { ".rel", 4, -1, SHT_REL, 0 },
02160 { ".stabstr", 5, 3, SHT_STRTAB, 0 },
02161 { ".gnu.liblist", 12, 0, SHT_GNU_LIBLIST, SHF_ALLOC },
02162 { ".gnu.conflict", 13, 0, SHT_RELA, SHF_ALLOC },
02163 { NULL, 0, 0, 0, 0 }
02164 };
02165
02166 static const struct bfd_elf_special_section *
02167 get_special_section (const char *name,
02168 const struct bfd_elf_special_section *special_sections,
02169 unsigned int rela)
02170 {
02171 int i;
02172 int len = strlen (name);
02173
02174 for (i = 0; special_sections[i].prefix != NULL; i++)
02175 {
02176 int suffix_len;
02177 int prefix_len = special_sections[i].prefix_length;
02178
02179 if (len < prefix_len)
02180 continue;
02181 if (memcmp (name, special_sections[i].prefix, prefix_len) != 0)
02182 continue;
02183
02184 suffix_len = special_sections[i].suffix_length;
02185 if (suffix_len <= 0)
02186 {
02187 if (name[prefix_len] != 0)
02188 {
02189 if (suffix_len == 0)
02190 continue;
02191 if (name[prefix_len] != '.'
02192 && (suffix_len == -2
02193 || (rela && special_sections[i].type == SHT_REL)))
02194 continue;
02195 }
02196 }
02197 else
02198 {
02199 if (len < prefix_len + suffix_len)
02200 continue;
02201 if (memcmp (name + len - suffix_len,
02202 special_sections[i].prefix + prefix_len,
02203 suffix_len) != 0)
02204 continue;
02205 }
02206 return &special_sections[i];
02207 }
02208
02209 return NULL;
02210 }
02211
02212 const struct bfd_elf_special_section *
02213 _bfd_elf_get_sec_type_attr (bfd *abfd, const char *name)
02214 {
02215 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02216 const struct bfd_elf_special_section *ssect = NULL;
02217
02218
02219 if (name)
02220 {
02221 unsigned int rela = bed->default_use_rela_p;
02222
02223 if (bed->special_sections)
02224 ssect = get_special_section (name, bed->special_sections, rela);
02225
02226 if (! ssect)
02227 ssect = get_special_section (name, special_sections, rela);
02228 }
02229
02230 return ssect;
02231 }
02232
02233 bfd_boolean
02234 _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
02235 {
02236 struct bfd_elf_section_data *sdata;
02237 const struct bfd_elf_special_section *ssect;
02238
02239 sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
02240 if (sdata == NULL)
02241 {
02242 sdata = bfd_zalloc (abfd, sizeof (*sdata));
02243 if (sdata == NULL)
02244 return FALSE;
02245 sec->used_by_bfd = sdata;
02246 }
02247
02248 elf_section_type (sec) = SHT_NULL;
02249 ssect = _bfd_elf_get_sec_type_attr (abfd, sec->name);
02250 if (ssect != NULL)
02251 {
02252 elf_section_type (sec) = ssect->type;
02253 elf_section_flags (sec) = ssect->attr;
02254 }
02255
02256
02257 sec->use_rela_p = get_elf_backend_data (abfd)->default_use_rela_p;
02258
02259 return TRUE;
02260 }
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284 bfd_boolean
02285 _bfd_elf_make_section_from_phdr (bfd *abfd,
02286 Elf_Internal_Phdr *hdr,
02287 int index,
02288 const char *typename)
02289 {
02290 asection *newsect;
02291 char *name;
02292 char namebuf[64];
02293 size_t len;
02294 int split;
02295
02296 split = ((hdr->p_memsz > 0)
02297 && (hdr->p_filesz > 0)
02298 && (hdr->p_memsz > hdr->p_filesz));
02299 sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
02300 len = strlen (namebuf) + 1;
02301 name = bfd_alloc (abfd, len);
02302 if (!name)
02303 return FALSE;
02304 memcpy (name, namebuf, len);
02305 newsect = bfd_make_section (abfd, name);
02306 if (newsect == NULL)
02307 return FALSE;
02308 newsect->vma = hdr->p_vaddr;
02309 newsect->lma = hdr->p_paddr;
02310 newsect->size = hdr->p_filesz;
02311 newsect->filepos = hdr->p_offset;
02312 newsect->flags |= SEC_HAS_CONTENTS;
02313 newsect->alignment_power = bfd_log2 (hdr->p_align);
02314 if (hdr->p_type == PT_LOAD)
02315 {
02316 newsect->flags |= SEC_ALLOC;
02317 newsect->flags |= SEC_LOAD;
02318 if (hdr->p_flags & PF_X)
02319 {
02320
02321
02322 newsect->flags |= SEC_CODE;
02323 }
02324 }
02325 if (!(hdr->p_flags & PF_W))
02326 {
02327 newsect->flags |= SEC_READONLY;
02328 }
02329
02330 if (split)
02331 {
02332 sprintf (namebuf, "%s%db", typename, index);
02333 len = strlen (namebuf) + 1;
02334 name = bfd_alloc (abfd, len);
02335 if (!name)
02336 return FALSE;
02337 memcpy (name, namebuf, len);
02338 newsect = bfd_make_section (abfd, name);
02339 if (newsect == NULL)
02340 return FALSE;
02341 newsect->vma = hdr->p_vaddr + hdr->p_filesz;
02342 newsect->lma = hdr->p_paddr + hdr->p_filesz;
02343 newsect->size = hdr->p_memsz - hdr->p_filesz;
02344 if (hdr->p_type == PT_LOAD)
02345 {
02346 newsect->flags |= SEC_ALLOC;
02347 if (hdr->p_flags & PF_X)
02348 newsect->flags |= SEC_CODE;
02349 }
02350 if (!(hdr->p_flags & PF_W))
02351 newsect->flags |= SEC_READONLY;
02352 }
02353
02354 return TRUE;
02355 }
02356
02357 bfd_boolean
02358 bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index)
02359 {
02360 const struct elf_backend_data *bed;
02361
02362 switch (hdr->p_type)
02363 {
02364 case PT_NULL:
02365 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "null");
02366
02367 case PT_LOAD:
02368 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "load");
02369
02370 case PT_DYNAMIC:
02371 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "dynamic");
02372
02373 case PT_INTERP:
02374 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "interp");
02375
02376 case PT_NOTE:
02377 if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note"))
02378 return FALSE;
02379 if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
02380 return FALSE;
02381 return TRUE;
02382
02383 case PT_SHLIB:
02384 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "shlib");
02385
02386 case PT_PHDR:
02387 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "phdr");
02388
02389 case PT_GNU_EH_FRAME:
02390 return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
02391 "eh_frame_hdr");
02392
02393 case PT_GNU_STACK:
02394 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack");
02395
02396 case PT_GNU_RELRO:
02397 return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro");
02398
02399 default:
02400
02401 bed = get_elf_backend_data (abfd);
02402 return bed->elf_backend_section_from_phdr (abfd, hdr, index, "proc");
02403 }
02404 }
02405
02406
02407
02408
02409
02410 bfd_boolean
02411 _bfd_elf_init_reloc_shdr (bfd *abfd,
02412 Elf_Internal_Shdr *rel_hdr,
02413 asection *asect,
02414 bfd_boolean use_rela_p)
02415 {
02416 char *name;
02417 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02418 bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
02419
02420 name = bfd_alloc (abfd, amt);
02421 if (name == NULL)
02422 return FALSE;
02423 sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
02424 rel_hdr->sh_name =
02425 (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
02426 FALSE);
02427 if (rel_hdr->sh_name == (unsigned int) -1)
02428 return FALSE;
02429 rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
02430 rel_hdr->sh_entsize = (use_rela_p
02431 ? bed->s->sizeof_rela
02432 : bed->s->sizeof_rel);
02433 rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
02434 rel_hdr->sh_flags = 0;
02435 rel_hdr->sh_addr = 0;
02436 rel_hdr->sh_size = 0;
02437 rel_hdr->sh_offset = 0;
02438
02439 return TRUE;
02440 }
02441
02442
02443
02444 static void
02445 elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
02446 {
02447 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02448 bfd_boolean *failedptr = failedptrarg;
02449 Elf_Internal_Shdr *this_hdr;
02450
02451 if (*failedptr)
02452 {
02453
02454
02455 return;
02456 }
02457
02458 this_hdr = &elf_section_data (asect)->this_hdr;
02459
02460 this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
02461 asect->name, FALSE);
02462 if (this_hdr->sh_name == (unsigned int) -1)
02463 {
02464 *failedptr = TRUE;
02465 return;
02466 }
02467
02468 this_hdr->sh_flags = 0;
02469
02470 if ((asect->flags & SEC_ALLOC) != 0
02471 || asect->user_set_vma)
02472 this_hdr->sh_addr = asect->vma;
02473 else
02474 this_hdr->sh_addr = 0;
02475
02476 this_hdr->sh_offset = 0;
02477 this_hdr->sh_size = asect->size;
02478 this_hdr->sh_link = 0;
02479 this_hdr->sh_addralign = 1 << asect->alignment_power;
02480
02481
02482
02483 this_hdr->bfd_section = asect;
02484 this_hdr->contents = NULL;
02485
02486
02487
02488 if (this_hdr->sh_type == SHT_NULL)
02489 {
02490 if ((asect->flags & SEC_GROUP) != 0)
02491 {
02492
02493
02494 struct bfd_link_order *l;
02495 asection *elt;
02496
02497 for (l = asect->link_order_head; l != NULL; l = l->next)
02498 if (l->type == bfd_indirect_link_order
02499 && (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
02500 do
02501 {
02502
02503 elf_group_name (elt->output_section) = "G";
02504 elf_section_flags (elt->output_section) |= SHF_GROUP;
02505
02506 elt = elf_next_in_group (elt);
02507
02508
02509 }
02510 while (elt != elf_next_in_group (l->u.indirect.section));
02511
02512 this_hdr->sh_type = SHT_GROUP;
02513 }
02514 else if ((asect->flags & SEC_ALLOC) != 0
02515 && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
02516 || (asect->flags & SEC_NEVER_LOAD) != 0))
02517 this_hdr->sh_type = SHT_NOBITS;
02518 else
02519 this_hdr->sh_type = SHT_PROGBITS;
02520 }
02521
02522 switch (this_hdr->sh_type)
02523 {
02524 default:
02525 break;
02526
02527 case SHT_STRTAB:
02528 case SHT_INIT_ARRAY:
02529 case SHT_FINI_ARRAY:
02530 case SHT_PREINIT_ARRAY:
02531 case SHT_NOTE:
02532 case SHT_NOBITS:
02533 case SHT_PROGBITS:
02534 break;
02535
02536 case SHT_HASH:
02537 this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
02538 break;
02539
02540 case SHT_DYNSYM:
02541 this_hdr->sh_entsize = bed->s->sizeof_sym;
02542 break;
02543
02544 case SHT_DYNAMIC:
02545 this_hdr->sh_entsize = bed->s->sizeof_dyn;
02546 break;
02547
02548 case SHT_RELA:
02549 if (get_elf_backend_data (abfd)->may_use_rela_p)
02550 this_hdr->sh_entsize = bed->s->sizeof_rela;
02551 break;
02552
02553 case SHT_REL:
02554 if (get_elf_backend_data (abfd)->may_use_rel_p)
02555 this_hdr->sh_entsize = bed->s->sizeof_rel;
02556 break;
02557
02558 case SHT_GNU_versym:
02559 this_hdr->sh_entsize = sizeof (Elf_External_Versym);
02560 break;
02561
02562 case SHT_GNU_verdef:
02563 this_hdr->sh_entsize = 0;
02564
02565
02566
02567 if (this_hdr->sh_info == 0)
02568 this_hdr->sh_info = elf_tdata (abfd)->cverdefs;
02569 else
02570 BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
02571 || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
02572 break;
02573
02574 case SHT_GNU_verneed:
02575 this_hdr->sh_entsize = 0;
02576
02577
02578
02579 if (this_hdr->sh_info == 0)
02580 this_hdr->sh_info = elf_tdata (abfd)->cverrefs;
02581 else
02582 BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
02583 || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
02584 break;
02585
02586 case SHT_GROUP:
02587 this_hdr->sh_entsize = 4;
02588 break;
02589 }
02590
02591 if ((asect->flags & SEC_ALLOC) != 0)
02592 this_hdr->sh_flags |= SHF_ALLOC;
02593 if ((asect->flags & SEC_READONLY) == 0)
02594 this_hdr->sh_flags |= SHF_WRITE;
02595 if ((asect->flags & SEC_CODE) != 0)
02596 this_hdr->sh_flags |= SHF_EXECINSTR;
02597 if ((asect->flags & SEC_MERGE) != 0)
02598 {
02599 this_hdr->sh_flags |= SHF_MERGE;
02600 this_hdr->sh_entsize = asect->entsize;
02601 if ((asect->flags & SEC_STRINGS) != 0)
02602 this_hdr->sh_flags |= SHF_STRINGS;
02603 }
02604 if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
02605 this_hdr->sh_flags |= SHF_GROUP;
02606 if ((asect->flags & SEC_THREAD_LOCAL) != 0)
02607 {
02608 this_hdr->sh_flags |= SHF_TLS;
02609 if (asect->size == 0 && (asect->flags & SEC_HAS_CONTENTS) == 0)
02610 {
02611 struct bfd_link_order *o;
02612
02613 this_hdr->sh_size = 0;
02614 for (o = asect->link_order_head; o != NULL; o = o->next)
02615 if (this_hdr->sh_size < o->offset + o->size)
02616 this_hdr->sh_size = o->offset + o->size;
02617 if (this_hdr->sh_size)
02618 this_hdr->sh_type = SHT_NOBITS;
02619 }
02620 }
02621
02622
02623 if (bed->elf_backend_fake_sections
02624 && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
02625 *failedptr = TRUE;
02626
02627
02628
02629
02630
02631 if ((asect->flags & SEC_RELOC) != 0
02632 && !_bfd_elf_init_reloc_shdr (abfd,
02633 &elf_section_data (asect)->rel_hdr,
02634 asect,
02635 asect->use_rela_p))
02636 *failedptr = TRUE;
02637 }
02638
02639
02640
02641 void
02642 bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
02643 {
02644 bfd_boolean *failedptr = failedptrarg;
02645 unsigned long symindx;
02646 asection *elt, *first;
02647 unsigned char *loc;
02648 struct bfd_link_order *l;
02649 bfd_boolean gas;
02650
02651 if (elf_section_data (sec)->this_hdr.sh_type != SHT_GROUP
02652 || *failedptr)
02653 return;
02654
02655 symindx = 0;
02656 if (elf_group_id (sec) != NULL)
02657 symindx = elf_group_id (sec)->udata.i;
02658
02659 if (symindx == 0)
02660 {
02661
02662
02663 if (elf_section_syms (abfd) != NULL)
02664 symindx = elf_section_syms (abfd)[sec->index]->udata.i;
02665 else
02666 symindx = sec->target_index;
02667 }
02668 elf_section_data (sec)->this_hdr.sh_info = symindx;
02669
02670
02671 gas = TRUE;
02672 if (sec->contents == NULL)
02673 {
02674 gas = FALSE;
02675 sec->contents = bfd_alloc (abfd, sec->size);
02676
02677
02678 elf_section_data (sec)->this_hdr.contents = sec->contents;
02679 if (sec->contents == NULL)
02680 {
02681 *failedptr = TRUE;
02682 return;
02683 }
02684 }
02685
02686 loc = sec->contents + sec->size;
02687
02688
02689
02690
02691 first = elt = elf_next_in_group (sec);
02692
02693
02694
02695
02696
02697 while (elt != NULL)
02698 {
02699 asection *s;
02700 unsigned int idx;
02701
02702 loc -= 4;
02703 s = elt;
02704 if (!gas)
02705 s = s->output_section;
02706 idx = 0;
02707 if (s != NULL)
02708 idx = elf_section_data (s)->this_idx;
02709 H_PUT_32 (abfd, idx, loc);
02710 elt = elf_next_in_group (elt);
02711 if (elt == first)
02712 break;
02713 }
02714
02715
02716
02717
02718 for (l = sec->link_order_head; l != NULL; l = l->next)
02719 if (l->type == bfd_indirect_link_order
02720 && (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
02721 do
02722 {
02723 loc -= 4;
02724 H_PUT_32 (abfd,
02725 elf_section_data (elt->output_section)->this_idx, loc);
02726 elt = elf_next_in_group (elt);
02727
02728 }
02729 while (elt != elf_next_in_group (l->u.indirect.section));
02730
02731 if ((loc -= 4) != sec->contents)
02732 abort ();
02733
02734 H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
02735 }
02736
02737
02738
02739
02740
02741 static bfd_boolean
02742 assign_section_numbers (bfd *abfd)
02743 {
02744 struct elf_obj_tdata *t = elf_tdata (abfd);
02745 asection *sec;
02746 unsigned int section_number, secn;
02747 Elf_Internal_Shdr **i_shdrp;
02748 bfd_size_type amt;
02749 struct bfd_elf_section_data *d;
02750
02751 section_number = 1;
02752
02753 _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
02754
02755
02756 for (sec = abfd->sections; sec; sec = sec->next)
02757 {
02758 d = elf_section_data (sec);
02759
02760 if (d->this_hdr.sh_type == SHT_GROUP)
02761 {
02762 if (section_number == SHN_LORESERVE)
02763 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02764 d->this_idx = section_number++;
02765 }
02766 }
02767
02768 for (sec = abfd->sections; sec; sec = sec->next)
02769 {
02770 d = elf_section_data (sec);
02771
02772 if (d->this_hdr.sh_type != SHT_GROUP)
02773 {
02774 if (section_number == SHN_LORESERVE)
02775 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02776 d->this_idx = section_number++;
02777 }
02778 _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
02779 if ((sec->flags & SEC_RELOC) == 0)
02780 d->rel_idx = 0;
02781 else
02782 {
02783 if (section_number == SHN_LORESERVE)
02784 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02785 d->rel_idx = section_number++;
02786 _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
02787 }
02788
02789 if (d->rel_hdr2)
02790 {
02791 if (section_number == SHN_LORESERVE)
02792 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02793 d->rel_idx2 = section_number++;
02794 _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
02795 }
02796 else
02797 d->rel_idx2 = 0;
02798 }
02799
02800 if (section_number == SHN_LORESERVE)
02801 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02802 t->shstrtab_section = section_number++;
02803 _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
02804 elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
02805
02806 if (bfd_get_symcount (abfd) > 0)
02807 {
02808 if (section_number == SHN_LORESERVE)
02809 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02810 t->symtab_section = section_number++;
02811 _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
02812 if (section_number > SHN_LORESERVE - 2)
02813 {
02814 if (section_number == SHN_LORESERVE)
02815 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02816 t->symtab_shndx_section = section_number++;
02817 t->symtab_shndx_hdr.sh_name
02818 = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
02819 ".symtab_shndx", FALSE);
02820 if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
02821 return FALSE;
02822 }
02823 if (section_number == SHN_LORESERVE)
02824 section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
02825 t->strtab_section = section_number++;
02826 _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
02827 }
02828
02829 _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
02830 t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
02831
02832 elf_numsections (abfd) = section_number;
02833 elf_elfheader (abfd)->e_shnum = section_number;
02834 if (section_number > SHN_LORESERVE)
02835 elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE;
02836
02837
02838
02839 amt = section_number * sizeof (Elf_Internal_Shdr *);
02840 i_shdrp = bfd_zalloc (abfd, amt);
02841 if (i_shdrp == NULL)
02842 return FALSE;
02843
02844 amt = sizeof (Elf_Internal_Shdr);
02845 i_shdrp[0] = bfd_zalloc (abfd, amt);
02846 if (i_shdrp[0] == NULL)
02847 {
02848 bfd_release (abfd, i_shdrp);
02849 return FALSE;
02850 }
02851
02852 elf_elfsections (abfd) = i_shdrp;
02853
02854 i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
02855 if (bfd_get_symcount (abfd) > 0)
02856 {
02857 i_shdrp[t->symtab_section] = &t->symtab_hdr;
02858 if (elf_numsections (abfd) > SHN_LORESERVE)
02859 {
02860 i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
02861 t->symtab_shndx_hdr.sh_link = t->symtab_section;
02862 }
02863 i_shdrp[t->strtab_section] = &t->strtab_hdr;
02864 t->symtab_hdr.sh_link = t->strtab_section;
02865 }
02866
02867 for (sec = abfd->sections; sec; sec = sec->next)
02868 {
02869 struct bfd_elf_section_data *d = elf_section_data (sec);
02870 asection *s;
02871 const char *name;
02872
02873 i_shdrp[d->this_idx] = &d->this_hdr;
02874 if (d->rel_idx != 0)
02875 i_shdrp[d->rel_idx] = &d->rel_hdr;
02876 if (d->rel_idx2 != 0)
02877 i_shdrp[d->rel_idx2] = d->rel_hdr2;
02878
02879
02880
02881
02882
02883
02884 if (d->rel_idx != 0)
02885 {
02886 d->rel_hdr.sh_link = t->symtab_section;
02887 d->rel_hdr.sh_info = d->this_idx;
02888 }
02889 if (d->rel_idx2 != 0)
02890 {
02891 d->rel_hdr2->sh_link = t->symtab_section;
02892 d->rel_hdr2->sh_info = d->this_idx;
02893 }
02894
02895
02896 if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
02897 {
02898 s = elf_linked_to_section (sec);
02899 if (s)
02900 d->this_hdr.sh_link = elf_section_data (s)->this_idx;
02901 else
02902 {
02903 struct bfd_link_order *p;
02904
02905
02906
02907 for (p = sec->link_order_head; p != NULL; p = p->next)
02908 {
02909 s = p->u.indirect.section;
02910 if (p->type == bfd_indirect_link_order
02911 && (bfd_get_flavour (s->owner)
02912 == bfd_target_elf_flavour))
02913 {
02914 Elf_Internal_Shdr ** const elf_shdrp
02915 = elf_elfsections (s->owner);
02916 int elfsec
02917 = _bfd_elf_section_from_bfd_section (s->owner, s);
02918 elfsec = elf_shdrp[elfsec]->sh_link;
02919
02920
02921
02922
02923
02924 if (elfsec == 0)
02925 {
02926 const struct elf_backend_data *bed
02927 = get_elf_backend_data (abfd);
02928 if (bed->link_order_error_handler)
02929 bed->link_order_error_handler
02930 (_("%B: warning: sh_link not set for section `%S'"),
02931 abfd, s);
02932 }
02933 else
02934 {
02935 s = elf_shdrp[elfsec]->bfd_section->output_section;
02936 BFD_ASSERT (s != NULL);
02937 d->this_hdr.sh_link = elf_section_data (s)->this_idx;
02938 }
02939 break;
02940 }
02941 }
02942 }
02943 }
02944
02945 switch (d->this_hdr.sh_type)
02946 {
02947 case SHT_REL:
02948 case SHT_RELA:
02949
02950
02951
02952
02953
02954
02955 s = bfd_get_section_by_name (abfd, ".dynsym");
02956 if (s != NULL)
02957 d->this_hdr.sh_link = elf_section_data (s)->this_idx;
02958
02959
02960 name = sec->name;
02961 if (d->this_hdr.sh_type == SHT_REL)
02962 name += 4;
02963 else
02964 name += 5;
02965 s = bfd_get_section_by_name (abfd, name);
02966 if (s != NULL)
02967 d->this_hdr.sh_info = elf_section_data (s)->this_idx;
02968 break;
02969
02970 case SHT_STRTAB:
02971
02972
02973
02974
02975 if (strncmp (sec->name, ".stab", sizeof ".stab" - 1) == 0
02976 && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
02977 {
02978 size_t len;
02979 char *alc;
02980
02981 len = strlen (sec->name);
02982 alc = bfd_malloc (len - 2);
02983 if (alc == NULL)
02984 return FALSE;
02985 memcpy (alc, sec->name, len - 3);
02986 alc[len - 3] = '\0';
02987 s = bfd_get_section_by_name (abfd, alc);
02988 free (alc);
02989 if (s != NULL)
02990 {
02991 elf_section_data (s)->this_hdr.sh_link = d->this_idx;
02992
02993
02994 if (elf_section_data (s)->this_hdr.sh_entsize == 0)
02995 elf_section_data (s)->this_hdr.sh_entsize
02996 = 4 + 2 * bfd_get_arch_size (abfd) / 8;
02997 }
02998 }
02999 break;
03000
03001 case SHT_DYNAMIC:
03002 case SHT_DYNSYM:
03003 case SHT_GNU_verneed:
03004 case SHT_GNU_verdef:
03005
03006
03007
03008 s = bfd_get_section_by_name (abfd, ".dynstr");
03009 if (s != NULL)
03010 d->this_hdr.sh_link = elf_section_data (s)->this_idx;
03011 break;
03012
03013 case SHT_GNU_LIBLIST:
03014
03015
03016
03017
03018 s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC)
03019 ? ".dynstr" : ".gnu.libstr");
03020 if (s != NULL)
03021 d->this_hdr.sh_link = elf_section_data (s)->this_idx;
03022 break;
03023
03024 case SHT_HASH:
03025 case SHT_GNU_versym:
03026
03027
03028 s = bfd_get_section_by_name (abfd, ".dynsym");
03029 if (s != NULL)
03030 d->this_hdr.sh_link = elf_section_data (s)->this_idx;
03031 break;
03032
03033 case SHT_GROUP:
03034 d->this_hdr.sh_link = t->symtab_section;
03035 }
03036 }
03037
03038 for (secn = 1; secn < section_number; ++secn)
03039 if (i_shdrp[secn] == NULL)
03040 i_shdrp[secn] = i_shdrp[0];
03041 else
03042 i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
03043 i_shdrp[secn]->sh_name);
03044 return TRUE;
03045 }
03046
03047
03048
03049
03050 static int
03051 sym_is_global (bfd *abfd, asymbol *sym)
03052 {
03053
03054 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
03055 if (bed->elf_backend_sym_is_global)
03056 return (*bed->elf_backend_sym_is_global) (abfd, sym);
03057
03058 return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
03059 || bfd_is_und_section (bfd_get_section (sym))
03060 || bfd_is_com_section (bfd_get_section (sym)));
03061 }
03062
03063 static bfd_boolean
03064 elf_map_symbols (bfd *abfd)
03065 {
03066 unsigned int symcount = bfd_get_symcount (abfd);
03067 asymbol **syms = bfd_get_outsymbols (abfd);
03068 asymbol **sect_syms;
03069 unsigned int num_locals = 0;
03070 unsigned int num_globals = 0;
03071 unsigned int num_locals2 = 0;
03072 unsigned int num_globals2 = 0;
03073 int max_index = 0;
03074 unsigned int idx;
03075 asection *asect;
03076 asymbol **new_syms;
03077 bfd_size_type amt;
03078
03079 #ifdef DEBUG
03080 fprintf (stderr, "elf_map_symbols\n");
03081 fflush (stderr);
03082 #endif
03083
03084 for (asect = abfd->sections; asect; asect = asect->next)
03085 {
03086 if (max_index < asect->index)
03087 max_index = asect->index;
03088 }
03089
03090 max_index++;
03091 amt = max_index * sizeof (asymbol *);
03092 sect_syms = bfd_zalloc (abfd, amt);
03093 if (sect_syms == NULL)
03094 return FALSE;
03095 elf_section_syms (abfd) = sect_syms;
03096 elf_num_section_syms (abfd) = max_index;
03097
03098
03099
03100 for (idx = 0; idx < symcount; idx++)
03101 {
03102 asymbol *sym = syms[idx];
03103
03104 if ((sym->flags & BSF_SECTION_SYM) != 0
03105 && sym->value == 0)
03106 {
03107 asection *sec;
03108
03109 sec = sym->section;
03110
03111 if (sec->owner != NULL)
03112 {
03113 if (sec->owner != abfd)
03114 {
03115 if (sec->output_offset != 0)
03116 continue;
03117
03118 sec = sec->output_section;
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130 if (sec->owner == NULL)
03131 continue;
03132
03133 BFD_ASSERT (sec->owner == abfd);
03134 }
03135 sect_syms[sec->index] = syms[idx];
03136 }
03137 }
03138 }
03139
03140
03141 for (idx = 0; idx < symcount; idx++)
03142 {
03143 if (!sym_is_global (abfd, syms[idx]))
03144 num_locals++;
03145 else
03146 num_globals++;
03147 }
03148
03149
03150
03151
03152
03153 for (asect = abfd->sections; asect; asect = asect->next)
03154 {
03155 if (sect_syms[asect->index] == NULL)
03156 {
03157 if (!sym_is_global (abfd, asect->symbol))
03158 num_locals++;
03159 else
03160 num_globals++;
03161 }
03162 }
03163
03164
03165 amt = (num_locals + num_globals) * sizeof (asymbol *);
03166 new_syms = bfd_alloc (abfd, amt);
03167
03168 if (new_syms == NULL)
03169 return FALSE;
03170
03171 for (idx = 0; idx < symcount; idx++)
03172 {
03173 asymbol *sym = syms[idx];
03174 unsigned int i;
03175
03176 if (!sym_is_global (abfd, sym))
03177 i = num_locals2++;
03178 else
03179 i = num_locals + num_globals2++;
03180 new_syms[i] = sym;
03181 sym->udata.i = i + 1;
03182 }
03183 for (asect = abfd->sections; asect; asect = asect->next)
03184 {
03185 if (sect_syms[asect->index] == NULL)
03186 {
03187 asymbol *sym = asect->symbol;
03188 unsigned int i;
03189
03190 sect_syms[asect->index] = sym;
03191 if (!sym_is_global (abfd, sym))
03192 i = num_locals2++;
03193 else
03194 i = num_locals + num_globals2++;
03195 new_syms[i] = sym;
03196 sym->udata.i = i + 1;
03197 }
03198 }
03199
03200 bfd_set_symtab (abfd, new_syms, num_locals + num_globals);
03201
03202 elf_num_locals (abfd) = num_locals;
03203 elf_num_globals (abfd) = num_globals;
03204 return TRUE;
03205 }
03206
03207
03208
03209
03210 static inline file_ptr
03211 align_file_position (file_ptr off, int align)
03212 {
03213 return (off + align - 1) & ~(align - 1);
03214 }
03215
03216
03217
03218
03219 file_ptr
03220 _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
03221 file_ptr offset,
03222 bfd_boolean align)
03223 {
03224 if (align)
03225 {
03226 unsigned int al;
03227
03228 al = i_shdrp->sh_addralign;
03229 if (al > 1)
03230 offset = BFD_ALIGN (offset, al);
03231 }
03232 i_shdrp->sh_offset = offset;
03233 if (i_shdrp->bfd_section != NULL)
03234 i_shdrp->bfd_section->filepos = offset;
03235 if (i_shdrp->sh_type != SHT_NOBITS)
03236 offset += i_shdrp->sh_size;
03237 return offset;
03238 }
03239
03240
03241
03242
03243
03244 bfd_boolean
03245 _bfd_elf_compute_section_file_positions (bfd *abfd,
03246 struct bfd_link_info *link_info)
03247 {
03248 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
03249 bfd_boolean failed;
03250 struct bfd_strtab_hash *strtab = NULL;
03251 Elf_Internal_Shdr *shstrtab_hdr;
03252
03253 if (abfd->output_has_begun)
03254 return TRUE;
03255
03256
03257 if (bed->elf_backend_begin_write_processing)
03258 (*bed->elf_backend_begin_write_processing) (abfd, link_info);
03259
03260 if (! prep_headers (abfd))
03261 return FALSE;
03262
03263
03264 if (bed->elf_backend_post_process_headers)
03265 (*bed->elf_backend_post_process_headers) (abfd, link_info);
03266
03267 failed = FALSE;
03268 bfd_map_over_sections (abfd, elf_fake_sections, &failed);
03269 if (failed)
03270 return FALSE;
03271
03272 if (!assign_section_numbers (abfd))
03273 return FALSE;
03274
03275
03276 if (link_info == NULL && bfd_get_symcount (abfd) > 0)
03277 {
03278
03279 int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
03280
03281 if (! swap_out_syms (abfd, &strtab, relocatable_p))
03282 return FALSE;
03283 }
03284
03285 if (link_info == NULL)
03286 {
03287 bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
03288 if (failed)
03289 return FALSE;
03290 }
03291
03292 shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
03293
03294 shstrtab_hdr->sh_type = SHT_STRTAB;
03295 shstrtab_hdr->sh_flags = 0;
03296 shstrtab_hdr->sh_addr = 0;
03297 shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
03298 shstrtab_hdr->sh_entsize = 0;
03299 shstrtab_hdr->sh_link = 0;
03300 shstrtab_hdr->sh_info = 0;
03301
03302 shstrtab_hdr->sh_addralign = 1;
03303
03304 if (!assign_file_positions_except_relocs (abfd, link_info))
03305 return FALSE;
03306
03307 if (link_info == NULL && bfd_get_symcount (abfd) > 0)
03308 {
03309 file_ptr off;
03310 Elf_Internal_Shdr *hdr;
03311
03312 off = elf_tdata (abfd)->next_file_pos;
03313
03314 hdr = &elf_tdata (abfd)->symtab_hdr;
03315 off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
03316
03317 hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
03318 if (hdr->sh_size != 0)
03319 off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
03320
03321 hdr = &elf_tdata (abfd)->strtab_hdr;
03322 off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
03323
03324 elf_tdata (abfd)->next_file_pos = off;
03325
03326
03327
03328 if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
03329 || ! _bfd_stringtab_emit (abfd, strtab))
03330 return FALSE;
03331 _bfd_stringtab_free (strtab);
03332 }
03333
03334 abfd->output_has_begun = TRUE;
03335
03336 return TRUE;
03337 }
03338
03339
03340
03341 static struct elf_segment_map *
03342 make_mapping (bfd *abfd,
03343 asection **sections,
03344 unsigned int from,
03345 unsigned int to,
03346 bfd_boolean phdr)
03347 {
03348 struct elf_segment_map *m;
03349 unsigned int i;
03350 asection **hdrpp;
03351 bfd_size_type amt;
03352
03353 amt = sizeof (struct elf_segment_map);
03354 amt += (to - from - 1) * sizeof (asection *);
03355 m = bfd_zalloc (abfd, amt);
03356 if (m == NULL)
03357 return NULL;
03358 m->next = NULL;
03359 m->p_type = PT_LOAD;
03360 for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
03361 m->sections[i - from] = *hdrpp;
03362 m->count = to - from;
03363
03364 if (from == 0 && phdr)
03365 {
03366
03367 m->includes_filehdr = 1;
03368 m->includes_phdrs = 1;
03369 }
03370
03371 return m;
03372 }
03373
03374
03375
03376
03377 struct elf_segment_map *
03378 _bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
03379 {
03380 struct elf_segment_map *m;
03381
03382 m = bfd_zalloc (abfd, sizeof (struct elf_segment_map));
03383 if (m == NULL)
03384 return NULL;
03385 m->next = NULL;
03386 m->p_type = PT_DYNAMIC;
03387 m->count = 1;
03388 m->sections[0] = dynsec;
03389
03390 return m;
03391 }
03392
03393
03394
03395 static bfd_boolean
03396 map_sections_to_segments (bfd *abfd)
03397 {
03398 asection **sections = NULL;
03399 asection *s;
03400 unsigned int i;
03401 unsigned int count;
03402 struct elf_segment_map *mfirst;
03403 struct elf_segment_map **pm;
03404 struct elf_segment_map *m;
03405 asection *last_hdr;
03406 bfd_vma last_size;
03407 unsigned int phdr_index;
03408 bfd_vma maxpagesize;
03409 asection **hdrpp;
03410 bfd_boolean phdr_in_segment = TRUE;
03411 bfd_boolean writable;
03412 int tls_count = 0;
03413 asection *first_tls = NULL;
03414 asection *dynsec, *eh_frame_hdr;
03415 bfd_size_type amt;
03416
03417 if (elf_tdata (abfd)->segment_map != NULL)
03418 return TRUE;
03419
03420 if (bfd_count_sections (abfd) == 0)
03421 return TRUE;
03422
03423
03424
03425 amt = bfd_count_sections (abfd) * sizeof (asection *);
03426 sections = bfd_malloc (amt);
03427 if (sections == NULL)
03428 goto error_return;
03429
03430 i = 0;
03431 for (s = abfd->sections; s != NULL; s = s->next)
03432 {
03433 if ((s->flags & SEC_ALLOC) != 0)
03434 {
03435 sections[i] = s;
03436 ++i;
03437 }
03438 }
03439 BFD_ASSERT (i <= bfd_count_sections (abfd));
03440 count = i;
03441
03442 qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);
03443
03444
03445
03446 mfirst = NULL;
03447 pm = &mfirst;
03448
03449
03450
03451
03452 s = bfd_get_section_by_name (abfd, ".interp");
03453 if (s != NULL && (s->flags & SEC_LOAD) != 0)
03454 {
03455 amt = sizeof (struct elf_segment_map);
03456 m = bfd_zalloc (abfd, amt);
03457 if (m == NULL)
03458 goto error_return;
03459 m->next = NULL;
03460 m->p_type = PT_PHDR;
03461
03462 m->p_flags = PF_R | PF_X;
03463 m->p_flags_valid = 1;
03464 m->includes_phdrs = 1;
03465
03466 *pm = m;
03467 pm = &m->next;
03468
03469 amt = sizeof (struct elf_segment_map);
03470 m = bfd_zalloc (abfd, amt);
03471 if (m == NULL)
03472 goto error_return;
03473 m->next = NULL;
03474 m->p_type = PT_INTERP;
03475 m->count = 1;
03476 m->sections[0] = s;
03477
03478 *pm = m;
03479 pm = &m->next;
03480 }
03481
03482
03483
03484
03485 last_hdr = NULL;
03486 last_size = 0;
03487 phdr_index = 0;
03488 maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
03489 writable = FALSE;
03490 dynsec = bfd_get_section_by_name (abfd, ".dynamic");
03491 if (dynsec != NULL
03492 && (dynsec->flags & SEC_LOAD) == 0)
03493 dynsec = NULL;
03494
03495
03496
03497
03498
03499 if (count > 0)
03500 {
03501 bfd_size_type phdr_size;
03502
03503 phdr_size = elf_tdata (abfd)->program_header_size;
03504 if (phdr_size == 0)
03505 phdr_size = get_elf_backend_data (abfd)->s->sizeof_phdr;
03506 if ((abfd->flags & D_PAGED) == 0
03507 || sections[0]->lma < phdr_size
03508 || sections[0]->lma % maxpagesize < phdr_size % maxpagesize)
03509 phdr_in_segment = FALSE;
03510 }
03511
03512 for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
03513 {
03514 asection *hdr;
03515 bfd_boolean new_segment;
03516
03517 hdr = *hdrpp;
03518
03519
03520
03521
03522 if (last_hdr == NULL)
03523 {
03524
03525
03526 new_segment = FALSE;
03527 }
03528 else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
03529 {
03530
03531
03532
03533 new_segment = TRUE;
03534 }
03535 else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
03536 < BFD_ALIGN (hdr->lma, maxpagesize))
03537 {
03538
03539
03540 new_segment = TRUE;
03541 }
03542 else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
03543 && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
03544 {
03545
03546
03547
03548 new_segment = TRUE;
03549 }
03550 else if ((abfd->flags & D_PAGED) == 0)
03551 {
03552
03553
03554
03555 new_segment = FALSE;
03556 }
03557 else if (! writable
03558 && (hdr->flags & SEC_READONLY) == 0
03559 && (((last_hdr->lma + last_size - 1)
03560 & ~(maxpagesize - 1))
03561 != (hdr->lma & ~(maxpagesize - 1))))
03562 {
03563
03564
03565
03566
03567
03568
03569
03570 new_segment = TRUE;
03571 }
03572 else
03573 {
03574
03575 new_segment = FALSE;
03576 }
03577
03578 if (! new_segment)
03579 {
03580 if ((hdr->flags & SEC_READONLY) == 0)
03581 writable = TRUE;
03582 last_hdr = hdr;
03583
03584 if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
03585 last_size = hdr->size;
03586 else
03587 last_size = 0;
03588 continue;
03589 }
03590
03591
03592
03593
03594 m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
03595 if (m == NULL)
03596 goto error_return;
03597
03598 *pm = m;
03599 pm = &m->next;
03600
03601 if ((hdr->flags & SEC_READONLY) == 0)
03602 writable = TRUE;
03603 else
03604 writable = FALSE;
03605
03606 last_hdr = hdr;
03607
03608 if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
03609 last_size = hdr->size;
03610 else
03611 last_size = 0;
03612 phdr_index = i;
03613 phdr_in_segment = FALSE;
03614 }
03615
03616
03617 if (last_hdr != NULL)
03618 {
03619 m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
03620 if (m == NULL)
03621 goto error_return;
03622
03623 *pm = m;
03624 pm = &m->next;
03625 }
03626
03627
03628 if (dynsec != NULL)
03629 {
03630 m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
03631 if (m == NULL)
03632 goto error_return;
03633 *pm = m;
03634 pm = &m->next;
03635 }
03636
03637
03638
03639
03640
03641
03642 for (s = abfd->sections; s != NULL; s = s->next)
03643 {
03644 if ((s->flags & SEC_LOAD) != 0
03645 && strncmp (s->name, ".note", 5) == 0)
03646 {
03647 amt = sizeof (struct elf_segment_map);
03648 m = bfd_zalloc (abfd, amt);
03649 if (m == NULL)
03650 goto error_return;
03651 m->next = NULL;
03652 m->p_type = PT_NOTE;
03653 m->count = 1;
03654 m->sections[0] = s;
03655
03656 *pm = m;
03657 pm = &m->next;
03658 }
03659 if (s->flags & SEC_THREAD_LOCAL)
03660 {
03661 if (! tls_count)
03662 first_tls = s;
03663 tls_count++;
03664 }
03665 }
03666
03667
03668 if (tls_count > 0)
03669 {
03670 int i;
03671
03672 amt = sizeof (struct elf_segment_map);
03673 amt += (tls_count - 1) * sizeof (asection *);
03674 m = bfd_zalloc (abfd, amt);
03675 if (m == NULL)
03676 goto error_return;
03677 m->next = NULL;
03678 m->p_type = PT_TLS;
03679 m->count = tls_count;
03680
03681 m->p_flags = PF_R;
03682 m->p_flags_valid = 1;
03683 for (i = 0; i < tls_count; ++i)
03684 {
03685 BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL);
03686 m->sections[i] = first_tls;
03687 first_tls = first_tls->next;
03688 }
03689
03690 *pm = m;
03691 pm = &m->next;
03692 }
03693
03694
03695
03696 eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
03697 if (eh_frame_hdr != NULL
03698 && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
03699 {
03700 amt = sizeof (struct elf_segment_map);
03701 m = bfd_zalloc (abfd, amt);
03702 if (m == NULL)
03703 goto error_return;
03704 m->next = NULL;
03705 m->p_type = PT_GNU_EH_FRAME;
03706 m->count = 1;
03707 m->sections[0] = eh_frame_hdr->output_section;
03708
03709 *pm = m;
03710 pm = &m->next;
03711 }
03712
03713 if (elf_tdata (abfd)->stack_flags)
03714 {
03715 amt = sizeof (struct elf_segment_map);
03716 m = bfd_zalloc (abfd, amt);
03717 if (m == NULL)
03718 goto error_return;
03719 m->next = NULL;
03720 m->p_type = PT_GNU_STACK;
03721 m->p_flags = elf_tdata (abfd)->stack_flags;
03722 m->p_flags_valid = 1;
03723
03724 *pm = m;
03725 pm = &m->next;
03726 }
03727
03728 if (elf_tdata (abfd)->relro)
03729 {
03730 amt = sizeof (struct elf_segment_map);
03731 m = bfd_zalloc (abfd, amt);
03732 if (m == NULL)
03733 goto error_return;
03734 m->next = NULL;
03735 m->p_type = PT_GNU_RELRO;
03736 m->p_flags = PF_R;
03737 m->p_flags_valid = 1;
03738
03739 *pm = m;
03740 pm = &m->next;
03741 }
03742
03743 free (sections);
03744 sections = NULL;
03745
03746 elf_tdata (abfd)->segment_map = mfirst;
03747 return TRUE;
03748
03749 error_return:
03750 if (sections != NULL)
03751 free (sections);
03752 return FALSE;
03753 }
03754
03755
03756
03757 static int
03758 elf_sort_sections (const void *arg1, const void *arg2)
03759 {
03760 const asection *sec1 = *(const asection **) arg1;
03761 const asection *sec2 = *(const asection **) arg2;
03762 bfd_size_type size1, size2;
03763
03764
03765
03766 if (sec1->lma < sec2->lma)
03767 return -1;
03768 else if (sec1->lma > sec2->lma)
03769 return 1;
03770
03771
03772
03773 if (sec1->vma < sec2->vma)
03774 return -1;
03775 else if (sec1->vma > sec2->vma)
03776 return 1;
03777
03778
03779
03780 #define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
03781
03782 if (TOEND (sec1))
03783 {
03784 if (TOEND (sec2))
03785 {
03786
03787
03788 if (sec1->target_index - sec2->target_index != 0)
03789 return sec1->target_index - sec2->target_index;
03790 }
03791 else
03792 return 1;
03793 }
03794 else if (TOEND (sec2))
03795 return -1;
03796
03797 #undef TOEND
03798
03799
03800
03801
03802 size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0;
03803 size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0;
03804
03805 if (size1 < size2)
03806 return -1;
03807 if (size1 > size2)
03808 return 1;
03809
03810 return sec1->target_index - sec2->target_index;
03811 }
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836 static file_ptr
03837 vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
03838 {
03839 return ((vma - off) % maxpagesize);
03840 }
03841
03842
03843
03844
03845
03846 static bfd_boolean
03847 assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
03848 {
03849 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
03850 unsigned int count;
03851 struct elf_segment_map *m;
03852 unsigned int alloc;
03853 Elf_Internal_Phdr *phdrs;
03854 file_ptr off, voff;
03855 bfd_vma filehdr_vaddr, filehdr_paddr;
03856 bfd_vma phdrs_vaddr, phdrs_paddr;
03857 Elf_Internal_Phdr *p;
03858 bfd_size_type amt;
03859
03860 if (elf_tdata (abfd)->segment_map == NULL)
03861 {
03862 if (! map_sections_to_segments (abfd))
03863 return FALSE;
03864 }
03865 else
03866 {
03867
03868
03869
03870 for (m = elf_tdata (abfd)->segment_map;
03871 m != NULL;
03872 m = m->next)
03873 {
03874 unsigned int new_count;
03875 unsigned int i;
03876
03877 if (m->p_type != PT_LOAD)
03878 continue;
03879
03880 new_count = 0;
03881 for (i = 0; i < m->count; i ++)
03882 {
03883 if ((m->sections[i]->flags & SEC_ALLOC) != 0)
03884 {
03885 if (i != new_count)
03886 m->sections[new_count] = m->sections[i];
03887
03888 new_count ++;
03889 }
03890 }
03891
03892 if (new_count != m->count)
03893 m->count = new_count;
03894 }
03895 }
03896
03897 if (bed->elf_backend_modify_segment_map)
03898 {
03899 if (! (*bed->elf_backend_modify_segment_map) (abfd, link_info))
03900 return FALSE;
03901 }
03902
03903 count = 0;
03904 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
03905 ++count;
03906
03907 elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
03908 elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
03909 elf_elfheader (abfd)->e_phnum = count;
03910
03911 if (count == 0)
03912 {
03913 elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr;
03914 return TRUE;
03915 }
03916
03917
03918
03919
03920 alloc = elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr;
03921 if (alloc != 0 && count > alloc)
03922 {
03923 ((*_bfd_error_handler)
03924 (_("%B: Not enough room for program headers (allocated %u, need %u)"),
03925 abfd, alloc, count));
03926 bfd_set_error (bfd_error_bad_value);
03927 return FALSE;
03928 }
03929
03930 if (alloc == 0)
03931 alloc = count;
03932
03933 amt = alloc * sizeof (Elf_Internal_Phdr);
03934 phdrs = bfd_alloc (abfd, amt);
03935 if (phdrs == NULL)
03936 return FALSE;
03937
03938 off = bed->s->sizeof_ehdr;
03939 off += alloc * bed->s->sizeof_phdr;
03940
03941 filehdr_vaddr = 0;
03942 filehdr_paddr = 0;
03943 phdrs_vaddr = 0;
03944 phdrs_paddr = 0;
03945
03946 for (m = elf_tdata (abfd)->segment_map, p = phdrs;
03947 m != NULL;
03948 m = m->next, p++)
03949 {
03950 unsigned int i;
03951 asection **secpp;
03952
03953
03954
03955
03956
03957
03958 if (m->count > 1
03959 && !(elf_elfheader (abfd)->e_type == ET_CORE
03960 && m->p_type == PT_NOTE))
03961 qsort (m->sections, (size_t) m->count, sizeof (asection *),
03962 elf_sort_sections);
03963
03964
03965
03966
03967
03968
03969
03970
03971 voff = 0;
03972 p->p_type = m->p_type;
03973 p->p_flags = m->p_flags;
03974
03975 if (p->p_type == PT_LOAD
03976 && m->count > 0)
03977 {
03978 bfd_size_type align;
03979 bfd_vma adjust;
03980
03981 if ((abfd->flags & D_PAGED) != 0)
03982 align = bed->maxpagesize;
03983 else
03984 {
03985 unsigned int align_power = 0;
03986 for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
03987 {
03988 unsigned int secalign;
03989
03990 secalign = bfd_get_section_alignment (abfd, *secpp);
03991 if (secalign > align_power)
03992 align_power = secalign;
03993 }
03994 align = (bfd_size_type) 1 << align_power;
03995 }
03996
03997 adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
03998 off += adjust;
03999 if (adjust != 0
04000 && !m->includes_filehdr
04001 && !m->includes_phdrs
04002 && (ufile_ptr) off >= align)
04003 {
04004
04005
04006
04007
04008
04009
04010 i = 0;
04011 while ((m->sections[i]->flags & SEC_LOAD) == 0)
04012 {
04013 if ((m->sections[i]->flags & SEC_THREAD_LOCAL) == 0
04014 || ++i >= m->count)
04015 {
04016 off -= adjust;
04017 voff = adjust - align;
04018 break;
04019 }
04020 }
04021 }
04022 }
04023
04024
04025 else if (p->p_type == PT_DYNAMIC
04026 && m->count > 1
04027 && strcmp (m->sections[0]->name, ".dynamic") != 0)
04028 {
04029 _bfd_error_handler
04030 (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
04031 abfd);
04032 bfd_set_error (bfd_error_bad_value);
04033 return FALSE;
04034 }
04035
04036 if (m->count == 0)
04037 p->p_vaddr = 0;
04038 else
04039 p->p_vaddr = m->sections[0]->vma;
04040
04041 if (m->p_paddr_valid)
04042 p->p_paddr = m->p_paddr;
04043 else if (m->count == 0)
04044 p->p_paddr = 0;
04045 else
04046 p->p_paddr = m->sections[0]->lma;
04047
04048 if (p->p_type == PT_LOAD
04049 && (abfd->flags & D_PAGED) != 0)
04050 p->p_align = bed->maxpagesize;
04051 else if (m->count == 0)
04052 p->p_align = 1 << bed->s->log_file_align;
04053 else
04054 p->p_align = 0;
04055
04056 p->p_offset = 0;
04057 p->p_filesz = 0;
04058 p->p_memsz = 0;
04059
04060 if (m->includes_filehdr)
04061 {
04062 if (! m->p_flags_valid)
04063 p->p_flags |= PF_R;
04064 p->p_offset = 0;
04065 p->p_filesz = bed->s->sizeof_ehdr;
04066 p->p_memsz = bed->s->sizeof_ehdr;
04067 if (m->count > 0)
04068 {
04069 BFD_ASSERT (p->p_type == PT_LOAD);
04070
04071 if (p->p_vaddr < (bfd_vma) off)
04072 {
04073 (*_bfd_error_handler)
04074 (_("%B: Not enough room for program headers, try linking with -N"),
04075 abfd);
04076 bfd_set_error (bfd_error_bad_value);
04077 return FALSE;
04078 }
04079
04080 p->p_vaddr -= off;
04081 if (! m->p_paddr_valid)
04082 p->p_paddr -= off;
04083 }
04084 if (p->p_type == PT_LOAD)
04085 {
04086 filehdr_vaddr = p->p_vaddr;
04087 filehdr_paddr = p->p_paddr;
04088 }
04089 }
04090
04091 if (m->includes_phdrs)
04092 {
04093 if (! m->p_flags_valid)
04094 p->p_flags |= PF_R;
04095
04096 if (m->includes_filehdr)
04097 {
04098 if (p->p_type == PT_LOAD)
04099 {
04100 phdrs_vaddr = p->p_vaddr + bed->s->sizeof_ehdr;
04101 phdrs_paddr = p->p_paddr + bed->s->sizeof_ehdr;
04102 }
04103 }
04104 else
04105 {
04106 p->p_offset = bed->s->sizeof_ehdr;
04107
04108 if (m->count > 0)
04109 {
04110 BFD_ASSERT (p->p_type == PT_LOAD);
04111 p->p_vaddr -= off - p->p_offset;
04112 if (! m->p_paddr_valid)
04113 p->p_paddr -= off - p->p_offset;
04114 }
04115
04116 if (p->p_type == PT_LOAD)
04117 {
04118 phdrs_vaddr = p->p_vaddr;
04119 phdrs_paddr = p->p_paddr;
04120 }
04121 else
04122 phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
04123 }
04124
04125 p->p_filesz += alloc * bed->s->sizeof_phdr;
04126 p->p_memsz += alloc * bed->s->sizeof_phdr;
04127 }
04128
04129 if (p->p_type == PT_LOAD
04130 || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
04131 {
04132 if (! m->includes_filehdr && ! m->includes_phdrs)
04133 p->p_offset = off + voff;
04134 else
04135 {
04136 file_ptr adjust;
04137
04138 adjust = off - (p->p_offset + p->p_filesz);
04139 p->p_filesz += adjust;
04140 p->p_memsz += adjust;
04141 }
04142 }
04143
04144 for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
04145 {
04146 asection *sec;
04147 flagword flags;
04148 bfd_size_type align;
04149
04150 sec = *secpp;
04151 flags = sec->flags;
04152 align = 1 << bfd_get_section_alignment (abfd, sec);
04153
04154 if (p->p_type == PT_LOAD
04155 || p->p_type == PT_TLS)
04156 {
04157 bfd_signed_vma adjust;
04158
04159 if ((flags & SEC_LOAD) != 0)
04160 {
04161 adjust = sec->lma - (p->p_paddr + p->p_filesz);
04162 if (adjust < 0)
04163 {
04164 (*_bfd_error_handler)
04165 (_("%B: section %A lma 0x%lx overlaps previous sections"),
04166 abfd, sec, (unsigned long) sec->lma);
04167 adjust = 0;
04168 }
04169 off += adjust;
04170 p->p_filesz += adjust;
04171 p->p_memsz += adjust;
04172 }
04173
04174
04175 else if ((flags & SEC_THREAD_LOCAL) == 0
04176 || p->p_type == PT_TLS)
04177 {
04178
04179
04180 bfd_size_type page = align;
04181 if ((abfd->flags & D_PAGED) != 0)
04182 page = bed->maxpagesize;
04183 adjust = vma_page_aligned_bias (sec->vma,
04184 p->p_vaddr + p->p_memsz,
04185 page);
04186 p->p_memsz += adjust;
04187 }
04188 }
04189
04190 if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
04191 {
04192
04193
04194 if (i == 0)
04195 {
04196 sec->filepos = off;
04197 off += sec->size;
04198 p->p_filesz = sec->size;
04199 p->p_memsz = 0;
04200 p->p_align = 1;
04201 }
04202 else
04203 {
04204
04205 sec->filepos = 0;
04206 sec->size = 0;
04207 sec->flags = 0;
04208 continue;
04209 }
04210 }
04211 else
04212 {
04213 if (p->p_type == PT_LOAD)
04214 {
04215 sec->filepos = off;
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230 if ((flags & SEC_LOAD) != 0
04231 || (flags & SEC_HAS_CONTENTS) != 0)
04232 off += sec->size;
04233 }
04234
04235 if ((flags & SEC_LOAD) != 0)
04236 {
04237 p->p_filesz += sec->size;
04238 p->p_memsz += sec->size;
04239 }
04240
04241
04242 else if (p->p_type == PT_NOTE
04243 && (flags & SEC_HAS_CONTENTS) != 0)
04244 p->p_filesz += sec->size;
04245
04246
04247
04248 else if ((flags & SEC_THREAD_LOCAL) == 0
04249 || p->p_type == PT_TLS)
04250 p->p_memsz += sec->size;
04251
04252 if (p->p_type == PT_TLS
04253 && sec->size == 0
04254 && (sec->flags & SEC_HAS_CONTENTS) == 0)
04255 {
04256 struct bfd_link_order *o;
04257 bfd_vma tbss_size = 0;
04258
04259 for (o = sec->link_order_head; o != NULL; o = o->next)
04260 if (tbss_size < o->offset + o->size)
04261 tbss_size = o->offset + o->size;
04262
04263 p->p_memsz += tbss_size;
04264 }
04265
04266 if (align > p->p_align
04267 && (p->p_type != PT_LOAD || (abfd->flags & D_PAGED) == 0))
04268 p->p_align = align;
04269 }
04270
04271 if (! m->p_flags_valid)
04272 {
04273 p->p_flags |= PF_R;
04274 if ((flags & SEC_CODE) != 0)
04275 p->p_flags |= PF_X;
04276 if ((flags & SEC_READONLY) == 0)
04277 p->p_flags |= PF_W;
04278 }
04279 }
04280 }
04281
04282
04283
04284 for (m = elf_tdata (abfd)->segment_map, p = phdrs;
04285 m != NULL;
04286 m = m->next, p++)
04287 {
04288 if (p->p_type != PT_LOAD && m->count > 0)
04289 {
04290 BFD_ASSERT (! m->includes_filehdr && ! m->includes_phdrs);
04291
04292
04293
04294
04295 if (p->p_type == PT_DYNAMIC && m->sections[0]->filepos == 0)
04296 {
04297 unsigned int i;
04298 Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
04299
04300 i = 1;
04301 while (i_shdrpp[i]->bfd_section != m->sections[0])
04302 ++i;
04303 off = (_bfd_elf_assign_file_position_for_section
04304 (i_shdrpp[i], off, TRUE));
04305 p->p_filesz = m->sections[0]->size;
04306 }
04307 p->p_offset = m->sections[0]->filepos;
04308 }
04309 if (m->count == 0)
04310 {
04311 if (m->includes_filehdr)
04312 {
04313 p->p_vaddr = filehdr_vaddr;
04314 if (! m->p_paddr_valid)
04315 p->p_paddr = filehdr_paddr;
04316 }
04317 else if (m->includes_phdrs)
04318 {
04319 p->p_vaddr = phdrs_vaddr;
04320 if (! m->p_paddr_valid)
04321 p->p_paddr = phdrs_paddr;
04322 }
04323 else if (p->p_type == PT_GNU_RELRO)
04324 {
04325 Elf_Internal_Phdr *lp;
04326
04327 for (lp = phdrs; lp < phdrs + count; ++lp)
04328 {
04329 if (lp->p_type == PT_LOAD
04330 && lp->p_vaddr <= link_info->relro_end
04331 && lp->p_vaddr >= link_info->relro_start
04332 && lp->p_vaddr + lp->p_filesz
04333 >= link_info->relro_end)
04334 break;
04335 }
04336
04337 if (lp < phdrs + count
04338 && link_info->relro_end > lp->p_vaddr)
04339 {
04340 p->p_vaddr = lp->p_vaddr;
04341 p->p_paddr = lp->p_paddr;
04342 p->p_offset = lp->p_offset;
04343 p->p_filesz = link_info->relro_end - lp->p_vaddr;
04344 p->p_memsz = p->p_filesz;
04345 p->p_align = 1;
04346 p->p_flags = (lp->p_flags & ~PF_W);
04347 }
04348 else
04349 {
04350 memset (p, 0, sizeof *p);
04351 p->p_type = PT_NULL;
04352 }
04353 }
04354 }
04355 }
04356
04357
04358 for (; count < alloc; count++, p++)
04359 {
04360 memset (p, 0, sizeof *p);
04361 p->p_type = PT_NULL;
04362 }
04363
04364 elf_tdata (abfd)->phdr = phdrs;
04365
04366 elf_tdata (abfd)->next_file_pos = off;
04367
04368
04369 if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
04370 || bed->s->write_out_phdrs (abfd, phdrs, alloc) != 0)
04371 return FALSE;
04372
04373 return TRUE;
04374 }
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387 static bfd_size_type
04388 get_program_header_size (bfd *abfd)
04389 {
04390 size_t segs;
04391 asection *s;
04392 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04393
04394
04395 if (elf_tdata (abfd)->program_header_size != 0)
04396 return elf_tdata (abfd)->program_header_size;
04397
04398 if (elf_tdata (abfd)->segment_map != NULL)
04399 {
04400 struct elf_segment_map *m;
04401
04402 segs = 0;
04403 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
04404 ++segs;
04405 elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
04406 return elf_tdata (abfd)->program_header_size;
04407 }
04408
04409
04410
04411 segs = 2;
04412
04413 s = bfd_get_section_by_name (abfd, ".interp");
04414 if (s != NULL && (s->flags & SEC_LOAD) != 0)
04415 {
04416
04417
04418
04419
04420 segs += 2;
04421 }
04422
04423 if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
04424 {
04425
04426 ++segs;
04427 }
04428
04429 if (elf_tdata (abfd)->eh_frame_hdr)
04430 {
04431
04432 ++segs;
04433 }
04434
04435 if (elf_tdata (abfd)->stack_flags)
04436 {
04437
04438 ++segs;
04439 }
04440
04441 if (elf_tdata (abfd)->relro)
04442 {
04443
04444 ++segs;
04445 }
04446
04447 for (s = abfd->sections; s != NULL; s = s->next)
04448 {
04449 if ((s->flags & SEC_LOAD) != 0
04450 && strncmp (s->name, ".note", 5) == 0)
04451 {
04452
04453 ++segs;
04454 }
04455 }
04456
04457 for (s = abfd->sections; s != NULL; s = s->next)
04458 {
04459 if (s->flags & SEC_THREAD_LOCAL)
04460 {
04461
04462 ++segs;
04463 break;
04464 }
04465 }
04466
04467
04468 if (bed->elf_backend_additional_program_headers)
04469 {
04470 int a;
04471
04472 a = (*bed->elf_backend_additional_program_headers) (abfd);
04473 if (a == -1)
04474 abort ();
04475 segs += a;
04476 }
04477
04478 elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
04479 return elf_tdata (abfd)->program_header_size;
04480 }
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496 static bfd_boolean
04497 assign_file_positions_except_relocs (bfd *abfd,
04498 struct bfd_link_info *link_info)
04499 {
04500 struct elf_obj_tdata * const tdata = elf_tdata (abfd);
04501 Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
04502 Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
04503 unsigned int num_sec = elf_numsections (abfd);
04504 file_ptr off;
04505 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04506
04507 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
04508 && bfd_get_format (abfd) != bfd_core)
04509 {
04510 Elf_Internal_Shdr **hdrpp;
04511 unsigned int i;
04512
04513
04514 off = i_ehdrp->e_ehsize;
04515
04516
04517
04518
04519 for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
04520 {
04521 Elf_Internal_Shdr *hdr;
04522
04523 hdr = *hdrpp;
04524 if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
04525 && hdr->bfd_section == NULL)
04526 || i == tdata->symtab_section
04527 || i == tdata->symtab_shndx_section
04528 || i == tdata->strtab_section)
04529 {
04530 hdr->sh_offset = -1;
04531 }
04532 else
04533 off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
04534
04535 if (i == SHN_LORESERVE - 1)
04536 {
04537 i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
04538 hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
04539 }
04540 }
04541 }
04542 else
04543 {
04544 unsigned int i;
04545 Elf_Internal_Shdr **hdrpp;
04546
04547
04548
04549 if (! assign_file_positions_for_segments (abfd, link_info))
04550 return FALSE;
04551
04552
04553
04554 off = elf_tdata (abfd)->next_file_pos;
04555 for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
04556 {
04557 Elf_Internal_Shdr *hdr;
04558
04559 hdr = *hdrpp;
04560 if (hdr->bfd_section != NULL
04561 && hdr->bfd_section->filepos != 0)
04562 hdr->sh_offset = hdr->bfd_section->filepos;
04563 else if ((hdr->sh_flags & SHF_ALLOC) != 0)
04564 {
04565 ((*_bfd_error_handler)
04566 (_("%B: warning: allocated section `%s' not in segment"),
04567 abfd,
04568 (hdr->bfd_section == NULL
04569 ? "*unknown*"
04570 : hdr->bfd_section->name)));
04571 if ((abfd->flags & D_PAGED) != 0)
04572 off += vma_page_aligned_bias (hdr->sh_addr, off,
04573 bed->maxpagesize);
04574 else
04575 off += vma_page_aligned_bias (hdr->sh_addr, off,
04576 hdr->sh_addralign);
04577 off = _bfd_elf_assign_file_position_for_section (hdr, off,
04578 FALSE);
04579 }
04580 else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
04581 && hdr->bfd_section == NULL)
04582 || hdr == i_shdrpp[tdata->symtab_section]
04583 || hdr == i_shdrpp[tdata->symtab_shndx_section]
04584 || hdr == i_shdrpp[tdata->strtab_section])
04585 hdr->sh_offset = -1;
04586 else
04587 off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
04588
04589 if (i == SHN_LORESERVE - 1)
04590 {
04591 i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
04592 hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
04593 }
04594 }
04595 }
04596
04597
04598 off = align_file_position (off, 1 << bed->s->log_file_align);
04599 i_ehdrp->e_shoff = off;
04600 off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
04601
04602 elf_tdata (abfd)->next_file_pos = off;
04603
04604 return TRUE;
04605 }
04606
04607 static bfd_boolean
04608 prep_headers (bfd *abfd)
04609 {
04610 Elf_Internal_Ehdr *i_ehdrp;
04611 Elf_Internal_Phdr *i_phdrp = 0;
04612 Elf_Internal_Shdr **i_shdrp;
04613 struct elf_strtab_hash *shstrtab;
04614 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04615
04616 i_ehdrp = elf_elfheader (abfd);
04617 i_shdrp = elf_elfsections (abfd);
04618
04619 shstrtab = _bfd_elf_strtab_init ();
04620 if (shstrtab == NULL)
04621 return FALSE;
04622
04623 elf_shstrtab (abfd) = shstrtab;
04624
04625 i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
04626 i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;
04627 i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;
04628 i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;
04629
04630 i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
04631 i_ehdrp->e_ident[EI_DATA] =
04632 bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
04633 i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
04634
04635 if ((abfd->flags & DYNAMIC) != 0)
04636 i_ehdrp->e_type = ET_DYN;
04637 else if ((abfd->flags & EXEC_P) != 0)
04638 i_ehdrp->e_type = ET_EXEC;
04639 else if (bfd_get_format (abfd) == bfd_core)
04640 i_ehdrp->e_type = ET_CORE;
04641 else
04642 i_ehdrp->e_type = ET_REL;
04643
04644 switch (bfd_get_arch (abfd))
04645 {
04646 case bfd_arch_unknown:
04647 i_ehdrp->e_machine = EM_NONE;
04648 break;
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658 default:
04659 i_ehdrp->e_machine = bed->elf_machine_code;
04660 }
04661
04662 i_ehdrp->e_version = bed->s->ev_current;
04663 i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
04664
04665
04666 i_ehdrp->e_phoff = 0;
04667 i_ehdrp->e_phentsize = 0;
04668 i_ehdrp->e_phnum = 0;
04669
04670
04671 i_ehdrp->e_entry = bfd_get_start_address (abfd);
04672 i_ehdrp->e_shentsize = bed->s->sizeof_shdr;
04673
04674
04675 if (abfd->flags & EXEC_P)
04676
04677 ;
04678 else
04679 {
04680 i_ehdrp->e_phentsize = 0;
04681 i_phdrp = 0;
04682 i_ehdrp->e_phoff = 0;
04683 }
04684
04685 elf_tdata (abfd)->symtab_hdr.sh_name =
04686 (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE);
04687 elf_tdata (abfd)->strtab_hdr.sh_name =
04688 (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE);
04689 elf_tdata (abfd)->shstrtab_hdr.sh_name =
04690 (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE);
04691 if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
04692 || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
04693 || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
04694 return FALSE;
04695
04696 return TRUE;
04697 }
04698
04699
04700
04701
04702 void
04703 _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
04704 {
04705 file_ptr off;
04706 unsigned int i, num_sec;
04707 Elf_Internal_Shdr **shdrpp;
04708
04709 off = elf_tdata (abfd)->next_file_pos;
04710
04711 num_sec = elf_numsections (abfd);
04712 for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
04713 {
04714 Elf_Internal_Shdr *shdrp;
04715
04716 shdrp = *shdrpp;
04717 if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
04718 && shdrp->sh_offset == -1)
04719 off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
04720 }
04721
04722 elf_tdata (abfd)->next_file_pos = off;
04723 }
04724
04725 bfd_boolean
04726 _bfd_elf_write_object_contents (bfd *abfd)
04727 {
04728 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04729 Elf_Internal_Ehdr *i_ehdrp;
04730 Elf_Internal_Shdr **i_shdrp;
04731 bfd_boolean failed;
04732 unsigned int count, num_sec;
04733
04734 if (! abfd->output_has_begun
04735 && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
04736 return FALSE;
04737
04738 i_shdrp = elf_elfsections (abfd);
04739 i_ehdrp = elf_elfheader (abfd);
04740
04741 failed = FALSE;
04742 bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
04743 if (failed)
04744 return FALSE;
04745
04746 _bfd_elf_assign_file_positions_for_relocs (abfd);
04747
04748
04749 num_sec = elf_numsections (abfd);
04750 for (count = 1; count < num_sec; count++)
04751 {
04752 if (bed->elf_backend_section_processing)
04753 (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
04754 if (i_shdrp[count]->contents)
04755 {
04756 bfd_size_type amt = i_shdrp[count]->sh_size;
04757
04758 if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
04759 || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
04760 return FALSE;
04761 }
04762 if (count == SHN_LORESERVE - 1)
04763 count += SHN_HIRESERVE + 1 - SHN_LORESERVE;
04764 }
04765
04766
04767 if (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
04768 || ! _bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd)))
04769 return FALSE;
04770
04771 if (bed->elf_backend_final_write_processing)
04772 (*bed->elf_backend_final_write_processing) (abfd,
04773 elf_tdata (abfd)->linker);
04774
04775 return bed->s->write_shdrs_and_ehdr (abfd);
04776 }
04777
04778 bfd_boolean
04779 _bfd_elf_write_corefile_contents (bfd *abfd)
04780 {
04781
04782 return _bfd_elf_write_object_contents (abfd);
04783 }
04784
04785
04786
04787 int
04788 _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
04789 {
04790 const struct elf_backend_data *bed;
04791 int index;
04792
04793 if (elf_section_data (asect) != NULL
04794 && elf_section_data (asect)->this_idx != 0)
04795 return elf_section_data (asect)->this_idx;
04796
04797 if (bfd_is_abs_section (asect))
04798 index = SHN_ABS;
04799 else if (bfd_is_com_section (asect))
04800 index = SHN_COMMON;
04801 else if (bfd_is_und_section (asect))
04802 index = SHN_UNDEF;
04803 else
04804 {
04805 Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd);
04806 int maxindex = elf_numsections (abfd);
04807
04808 for (index = 1; index < maxindex; index++)
04809 {
04810 Elf_Internal_Shdr *hdr = i_shdrp[index];
04811
04812 if (hdr != NULL && hdr->bfd_section == asect)
04813 return index;
04814 }
04815 index = -1;
04816 }
04817
04818 bed = get_elf_backend_data (abfd);
04819 if (bed->elf_backend_section_from_bfd_section)
04820 {
04821 int retval = index;
04822
04823 if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
04824 return retval;
04825 }
04826
04827 if (index == -1)
04828 bfd_set_error (bfd_error_nonrepresentable_section);
04829
04830 return index;
04831 }
04832
04833
04834
04835
04836 int
04837 _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
04838 {
04839 asymbol *asym_ptr = *asym_ptr_ptr;
04840 int idx;
04841 flagword flags = asym_ptr->flags;
04842
04843
04844
04845
04846
04847
04848 if (asym_ptr->udata.i == 0
04849 && (flags & BSF_SECTION_SYM)
04850 && asym_ptr->section)
04851 {
04852 int indx;
04853
04854 if (asym_ptr->section->output_section != NULL)
04855 indx = asym_ptr->section->output_section->index;
04856 else
04857 indx = asym_ptr->section->index;
04858 if (indx < elf_num_section_syms (abfd)
04859 && elf_section_syms (abfd)[indx] != NULL)
04860 asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
04861 }
04862
04863 idx = asym_ptr->udata.i;
04864
04865 if (idx == 0)
04866 {
04867
04868
04869 (*_bfd_error_handler)
04870 (_("%B: symbol `%s' required but not present"),
04871 abfd, bfd_asymbol_name (asym_ptr));
04872 bfd_set_error (bfd_error_no_symbols);
04873 return -1;
04874 }
04875
04876 #if DEBUG & 4
04877 {
04878 fprintf (stderr,
04879 "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n",
04880 (long) asym_ptr, asym_ptr->name, idx, flags,
04881 elf_symbol_flags (flags));
04882 fflush (stderr);
04883 }
04884 #endif
04885
04886 return idx;
04887 }
04888
04889
04890
04891 static bfd_boolean
04892 copy_private_bfd_data (bfd *ibfd, bfd *obfd)
04893 {
04894 Elf_Internal_Ehdr *iehdr;
04895 struct elf_segment_map *map;
04896 struct elf_segment_map *map_first;
04897 struct elf_segment_map **pointer_to_map;
04898 Elf_Internal_Phdr *segment;
04899 asection *section;
04900 unsigned int i;
04901 unsigned int num_segments;
04902 bfd_boolean phdr_included = FALSE;
04903 bfd_vma maxpagesize;
04904 struct elf_segment_map *phdr_adjust_seg = NULL;
04905 unsigned int phdr_adjust_num = 0;
04906 const struct elf_backend_data *bed;
04907
04908 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
04909 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
04910 return TRUE;
04911
04912 if (elf_tdata (ibfd)->phdr == NULL)
04913 return TRUE;
04914
04915 bed = get_elf_backend_data (ibfd);
04916 iehdr = elf_elfheader (ibfd);
04917
04918 map_first = NULL;
04919 pointer_to_map = &map_first;
04920
04921 num_segments = elf_elfheader (ibfd)->e_phnum;
04922 maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
04923
04924
04925 #define SEGMENT_END(segment, start) \
04926 (start + (segment->p_memsz > segment->p_filesz \
04927 ? segment->p_memsz : segment->p_filesz))
04928
04929 #define SECTION_SIZE(section, segment) \
04930 (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \
04931 != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \
04932 ? section->size : 0)
04933
04934
04935
04936 #define IS_CONTAINED_BY_VMA(section, segment) \
04937 (section->vma >= segment->p_vaddr \
04938 && (section->vma + SECTION_SIZE (section, segment) \
04939 <= (SEGMENT_END (segment, segment->p_vaddr))))
04940
04941
04942
04943 #define IS_CONTAINED_BY_LMA(section, segment, base) \
04944 (section->lma >= base \
04945 && (section->lma + SECTION_SIZE (section, segment) \
04946 <= SEGMENT_END (segment, base)))
04947
04948
04949 #define IS_COREFILE_NOTE(p, s) \
04950 (p->p_type == PT_NOTE \
04951 && bfd_get_format (ibfd) == bfd_core \
04952 && s->vma == 0 && s->lma == 0 \
04953 && (bfd_vma) s->filepos >= p->p_offset \
04954 && ((bfd_vma) s->filepos + s->size \
04955 <= p->p_offset + p->p_filesz))
04956
04957
04958
04959
04960 #define IS_SOLARIS_PT_INTERP(p, s) \
04961 (p->p_vaddr == 0 \
04962 && p->p_paddr == 0 \
04963 && p->p_memsz == 0 \
04964 && p->p_filesz > 0 \
04965 && (s->flags & SEC_HAS_CONTENTS) != 0 \
04966 && s->size > 0 \
04967 && (bfd_vma) s->filepos >= p->p_offset \
04968 && ((bfd_vma) s->filepos + s->size \
04969 <= p->p_offset + p->p_filesz))
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983 #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
04984 ((((segment->p_paddr \
04985 ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \
04986 : IS_CONTAINED_BY_VMA (section, segment)) \
04987 && (section->flags & SEC_ALLOC) != 0) \
04988 || IS_COREFILE_NOTE (segment, section)) \
04989 && section->output_section != NULL \
04990 && segment->p_type != PT_GNU_STACK \
04991 && (segment->p_type != PT_TLS \
04992 || (section->flags & SEC_THREAD_LOCAL)) \
04993 && (segment->p_type == PT_LOAD \
04994 || segment->p_type == PT_TLS \
04995 || (section->flags & SEC_THREAD_LOCAL) == 0) \
04996 && (segment->p_type != PT_DYNAMIC \
04997 || SECTION_SIZE (section, segment) > 0 \
04998 || (segment->p_paddr \
04999 ? segment->p_paddr != section->lma \
05000 : segment->p_vaddr != section->vma) \
05001 || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \
05002 == 0)) \
05003 && ! section->segment_mark)
05004
05005
05006 #define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \
05007 (seg1->field >= SEGMENT_END (seg2, seg2->field))
05008
05009
05010
05011
05012
05013
05014
05015 #define SEGMENT_OVERLAPS(seg1, seg2) \
05016 ( !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr) \
05017 || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr)) \
05018 && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr) \
05019 || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
05020
05021
05022 for (section = ibfd->sections; section != NULL; section = section->next)
05023 section->segment_mark = FALSE;
05024
05025
05026
05027
05028
05029 for (i = 0, segment = elf_tdata (ibfd)->phdr;
05030 i < num_segments;
05031 i++, segment++)
05032 {
05033 unsigned int j;
05034 Elf_Internal_Phdr *segment2;
05035
05036 if (segment->p_type == PT_INTERP)
05037 for (section = ibfd->sections; section; section = section->next)
05038 if (IS_SOLARIS_PT_INTERP (segment, section))
05039 {
05040
05041
05042 segment->p_vaddr = section->vma;
05043 break;
05044 }
05045
05046 if (segment->p_type != PT_LOAD)
05047 continue;
05048
05049
05050 for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2 ++)
05051 {
05052 bfd_signed_vma extra_length;
05053
05054 if (segment2->p_type != PT_LOAD
05055 || ! SEGMENT_OVERLAPS (segment, segment2))
05056 continue;
05057
05058
05059 if (segment2->p_vaddr < segment->p_vaddr)
05060 {
05061
05062
05063 extra_length =
05064 SEGMENT_END (segment, segment->p_vaddr)
05065 - SEGMENT_END (segment2, segment2->p_vaddr);
05066
05067 if (extra_length > 0)
05068 {
05069 segment2->p_memsz += extra_length;
05070 segment2->p_filesz += extra_length;
05071 }
05072
05073 segment->p_type = PT_NULL;
05074
05075
05076 i = 0;
05077 segment = elf_tdata (ibfd)->phdr;
05078 break;
05079 }
05080 else
05081 {
05082
05083
05084 extra_length =
05085 SEGMENT_END (segment2, segment2->p_vaddr)
05086 - SEGMENT_END (segment, segment->p_vaddr);
05087
05088 if (extra_length > 0)
05089 {
05090 segment->p_memsz += extra_length;
05091 segment->p_filesz += extra_length;
05092 }
05093
05094 segment2->p_type = PT_NULL;
05095 }
05096 }
05097 }
05098
05099
05100 for (i = 0, segment = elf_tdata (ibfd)->phdr;
05101 i < num_segments;
05102 i ++, segment ++)
05103 {
05104 unsigned int section_count;
05105 asection ** sections;
05106 asection * output_section;
05107 unsigned int isec;
05108 bfd_vma matching_lma;
05109 bfd_vma suggested_lma;
05110 unsigned int j;
05111 bfd_size_type amt;
05112
05113 if (segment->p_type == PT_NULL)
05114 continue;
05115
05116
05117 for (section = ibfd->sections, section_count = 0;
05118 section != NULL;
05119 section = section->next)
05120 if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
05121 ++section_count;
05122
05123
05124
05125 amt = sizeof (struct elf_segment_map);
05126 amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
05127 map = bfd_alloc (obfd, amt);
05128 if (map == NULL)
05129 return FALSE;
05130
05131
05132
05133 map->next = NULL;
05134 map->p_type = segment->p_type;
05135 map->p_flags = segment->p_flags;
05136 map->p_flags_valid = 1;
05137 map->p_paddr = segment->p_paddr;
05138 map->p_paddr_valid = 1;
05139
05140
05141
05142 map->includes_filehdr = (segment->p_offset == 0
05143 && segment->p_filesz >= iehdr->e_ehsize);
05144
05145 map->includes_phdrs = 0;
05146
05147 if (! phdr_included || segment->p_type != PT_LOAD)
05148 {
05149 map->includes_phdrs =
05150 (segment->p_offset <= (bfd_vma) iehdr->e_phoff
05151 && (segment->p_offset + segment->p_filesz
05152 >= ((bfd_vma) iehdr->e_phoff
05153 + iehdr->e_phnum * iehdr->e_phentsize)));
05154
05155 if (segment->p_type == PT_LOAD && map->includes_phdrs)
05156 phdr_included = TRUE;
05157 }
05158
05159 if (section_count == 0)
05160 {
05161
05162
05163
05164
05165 if (segment->p_type == PT_LOAD)
05166 (*_bfd_error_handler)
05167 (_("%B: warning: Empty loadable segment detected, is this intentional ?\n"),
05168 ibfd);
05169
05170 map->count = 0;
05171 *pointer_to_map = map;
05172 pointer_to_map = &map->next;
05173
05174 continue;
05175 }
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207 amt = section_count * sizeof (asection *);
05208 sections = bfd_malloc (amt);
05209 if (sections == NULL)
05210 return FALSE;
05211
05212
05213
05214
05215
05216
05217
05218 isec = 0;
05219 matching_lma = 0;
05220 suggested_lma = 0;
05221
05222 for (j = 0, section = ibfd->sections;
05223 section != NULL;
05224 section = section->next)
05225 {
05226 if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
05227 {
05228 output_section = section->output_section;
05229
05230 sections[j ++] = section;
05231
05232
05233
05234
05235
05236 if (segment->p_paddr == 0
05237 && segment->p_vaddr != 0
05238 && (! bed->want_p_paddr_set_to_zero)
05239 && isec == 0
05240 && output_section->lma != 0
05241 && (output_section->vma == (segment->p_vaddr
05242 + (map->includes_filehdr
05243 ? iehdr->e_ehsize
05244 : 0)
05245 + (map->includes_phdrs
05246 ? (iehdr->e_phnum
05247 * iehdr->e_phentsize)
05248 : 0))))
05249 map->p_paddr = segment->p_vaddr;
05250
05251
05252
05253 if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
05254 || IS_COREFILE_NOTE (segment, section)
05255 || (bed->want_p_paddr_set_to_zero &&
05256 IS_CONTAINED_BY_VMA (output_section, segment))
05257 )
05258 {
05259 if (matching_lma == 0)
05260 matching_lma = output_section->lma;
05261
05262
05263
05264
05265 map->sections[isec ++] = output_section;
05266 }
05267 else if (suggested_lma == 0)
05268 suggested_lma = output_section->lma;
05269 }
05270 }
05271
05272 BFD_ASSERT (j == section_count);
05273
05274
05275
05276 if (isec == section_count)
05277 {
05278
05279
05280
05281
05282 map->count = section_count;
05283 *pointer_to_map = map;
05284 pointer_to_map = &map->next;
05285
05286 free (sections);
05287 continue;
05288 }
05289 else
05290 {
05291 if (matching_lma != 0)
05292 {
05293
05294
05295
05296 map->p_paddr = matching_lma;
05297 }
05298 else
05299 {
05300
05301
05302
05303 map->p_paddr = suggested_lma;
05304 }
05305
05306
05307
05308 if (map->includes_filehdr)
05309 map->p_paddr -= iehdr->e_ehsize;
05310
05311 if (map->includes_phdrs)
05312 {
05313 map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
05314
05315
05316
05317
05318
05319
05320 phdr_adjust_num = iehdr->e_phnum;
05321 phdr_adjust_seg = map;
05322 }
05323 }
05324
05325
05326
05327
05328
05329
05330
05331
05332 isec = 0;
05333 do
05334 {
05335 map->count = 0;
05336 suggested_lma = 0;
05337
05338
05339 for (j = 0; j < section_count; j++)
05340 {
05341 section = sections[j];
05342
05343 if (section == NULL)
05344 continue;
05345
05346 output_section = section->output_section;
05347
05348 BFD_ASSERT (output_section != NULL);
05349
05350 if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
05351 || IS_COREFILE_NOTE (segment, section))
05352 {
05353 if (map->count == 0)
05354 {
05355
05356
05357
05358 if (output_section->lma !=
05359 (map->p_paddr
05360 + (map->includes_filehdr ? iehdr->e_ehsize : 0)
05361 + (map->includes_phdrs
05362 ? iehdr->e_phnum * iehdr->e_phentsize
05363 : 0)))
05364 abort ();
05365 }
05366 else
05367 {
05368 asection * prev_sec;
05369
05370 prev_sec = map->sections[map->count - 1];
05371
05372
05373
05374
05375 if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
05376 maxpagesize)
05377 < BFD_ALIGN (output_section->lma, maxpagesize))
05378 || ((prev_sec->lma + prev_sec->size)
05379 > output_section->lma))
05380 {
05381 if (suggested_lma == 0)
05382 suggested_lma = output_section->lma;
05383
05384 continue;
05385 }
05386 }
05387
05388 map->sections[map->count++] = output_section;
05389 ++isec;
05390 sections[j] = NULL;
05391 section->segment_mark = TRUE;
05392 }
05393 else if (suggested_lma == 0)
05394 suggested_lma = output_section->lma;
05395 }
05396
05397 BFD_ASSERT (map->count > 0);
05398
05399
05400 *pointer_to_map = map;
05401 pointer_to_map = &map->next;
05402
05403 if (isec < section_count)
05404 {
05405
05406
05407
05408 amt = sizeof (struct elf_segment_map);
05409 amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
05410 map = bfd_alloc (obfd, amt);
05411 if (map == NULL)
05412 {
05413 free (sections);
05414 return FALSE;
05415 }
05416
05417
05418
05419
05420 map->next = NULL;
05421 map->p_type = segment->p_type;
05422 map->p_flags = segment->p_flags;
05423 map->p_flags_valid = 1;
05424 map->p_paddr = suggested_lma;
05425 map->p_paddr_valid = 1;
05426 map->includes_filehdr = 0;
05427 map->includes_phdrs = 0;
05428 }
05429 }
05430 while (isec < section_count);
05431
05432 free (sections);
05433 }
05434
05435
05436
05437
05438
05439 for (map = map_first; map != NULL; map = map->next)
05440 if (map->p_paddr != 0)
05441 break;
05442 if (map == NULL)
05443 for (map = map_first; map != NULL; map = map->next)
05444 map->p_paddr_valid = 0;
05445
05446 elf_tdata (obfd)->segment_map = map_first;
05447
05448
05449
05450
05451 if (phdr_adjust_seg != NULL)
05452 {
05453 unsigned int count;
05454
05455 for (count = 0, map = map_first; map != NULL; map = map->next)
05456 count++;
05457
05458 if (count > phdr_adjust_num)
05459 phdr_adjust_seg->p_paddr
05460 -= (count - phdr_adjust_num) * iehdr->e_phentsize;
05461 }
05462
05463 #undef SEGMENT_END
05464 #undef SECTION_SIZE
05465 #undef IS_CONTAINED_BY_VMA
05466 #undef IS_CONTAINED_BY_LMA
05467 #undef IS_COREFILE_NOTE
05468 #undef IS_SOLARIS_PT_INTERP
05469 #undef INCLUDE_SECTION_IN_SEGMENT
05470 #undef SEGMENT_AFTER_SEGMENT
05471 #undef SEGMENT_OVERLAPS
05472 return TRUE;
05473 }
05474
05475
05476
05477
05478 bfd_boolean
05479 _bfd_elf_copy_private_section_data (bfd *ibfd,
05480 asection *isec,
05481 bfd *obfd,
05482 asection *osec)
05483 {
05484 Elf_Internal_Shdr *ihdr, *ohdr;
05485
05486 if (ibfd->xvec->flavour != bfd_target_elf_flavour
05487 || obfd->xvec->flavour != bfd_target_elf_flavour)
05488 return TRUE;
05489
05490 ihdr = &elf_section_data (isec)->this_hdr;
05491 ohdr = &elf_section_data (osec)->this_hdr;
05492
05493 ohdr->sh_entsize = ihdr->sh_entsize;
05494
05495 if (ihdr->sh_type == SHT_SYMTAB
05496 || ihdr->sh_type == SHT_DYNSYM
05497 || ihdr->sh_type == SHT_GNU_verneed
05498 || ihdr->sh_type == SHT_GNU_verdef)
05499 ohdr->sh_info = ihdr->sh_info;
05500
05501
05502
05503
05504 elf_next_in_group (osec) = elf_next_in_group (isec);
05505 elf_group_name (osec) = elf_group_name (isec);
05506
05507 osec->use_rela_p = isec->use_rela_p;
05508
05509 return TRUE;
05510 }
05511
05512
05513
05514 bfd_boolean
05515 _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
05516 {
05517 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
05518 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
05519 return TRUE;
05520
05521
05522
05523
05524
05525
05526 if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL)
05527 {
05528 if (! copy_private_bfd_data (ibfd, obfd))
05529 return FALSE;
05530 }
05531
05532 return TRUE;
05533 }
05534
05535
05536
05537
05538
05539
05540
05541 #define MAP_ONESYMTAB (SHN_HIOS + 1)
05542 #define MAP_DYNSYMTAB (SHN_HIOS + 2)
05543 #define MAP_STRTAB (SHN_HIOS + 3)
05544 #define MAP_SHSTRTAB (SHN_HIOS + 4)
05545 #define MAP_SYM_SHNDX (SHN_HIOS + 5)
05546
05547 bfd_boolean
05548 _bfd_elf_copy_private_symbol_data (bfd *ibfd,
05549 asymbol *isymarg,
05550 bfd *obfd,
05551 asymbol *osymarg)
05552 {
05553 elf_symbol_type *isym, *osym;
05554
05555 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
05556 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
05557 return TRUE;
05558
05559 isym = elf_symbol_from (ibfd, isymarg);
05560 osym = elf_symbol_from (obfd, osymarg);
05561
05562 if (isym != NULL
05563 && osym != NULL
05564 && bfd_is_abs_section (isym->symbol.section))
05565 {
05566 unsigned int shndx;
05567
05568 shndx = isym->internal_elf_sym.st_shndx;
05569 if (shndx == elf_onesymtab (ibfd))
05570 shndx = MAP_ONESYMTAB;
05571 else if (shndx == elf_dynsymtab (ibfd))
05572 shndx = MAP_DYNSYMTAB;
05573 else if (shndx == elf_tdata (ibfd)->strtab_section)
05574 shndx = MAP_STRTAB;
05575 else if (shndx == elf_tdata (ibfd)->shstrtab_section)
05576 shndx = MAP_SHSTRTAB;
05577 else if (shndx == elf_tdata (ibfd)->symtab_shndx_section)
05578 shndx = MAP_SYM_SHNDX;
05579 osym->internal_elf_sym.st_shndx = shndx;
05580 }
05581
05582 return TRUE;
05583 }
05584
05585
05586
05587 static bfd_boolean
05588 swap_out_syms (bfd *abfd,
05589 struct bfd_strtab_hash **sttp,
05590 int relocatable_p)
05591 {
05592 const struct elf_backend_data *bed;
05593 int symcount;
05594 asymbol **syms;
05595 struct bfd_strtab_hash *stt;
05596 Elf_Internal_Shdr *symtab_hdr;
05597 Elf_Internal_Shdr *symtab_shndx_hdr;
05598 Elf_Internal_Shdr *symstrtab_hdr;
05599 bfd_byte *outbound_syms;
05600 bfd_byte *outbound_shndx;
05601 int idx;
05602 bfd_size_type amt;
05603 bfd_boolean name_local_sections;
05604
05605 if (!elf_map_symbols (abfd))
05606 return FALSE;
05607
05608
05609 stt = _bfd_elf_stringtab_init ();
05610 if (stt == NULL)
05611 return FALSE;
05612
05613 bed = get_elf_backend_data (abfd);
05614 symcount = bfd_get_symcount (abfd);
05615 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
05616 symtab_hdr->sh_type = SHT_SYMTAB;
05617 symtab_hdr->sh_entsize = bed->s->sizeof_sym;
05618 symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
05619 symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
05620 symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
05621
05622 symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
05623 symstrtab_hdr->sh_type = SHT_STRTAB;
05624
05625 amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
05626 outbound_syms = bfd_alloc (abfd, amt);
05627 if (outbound_syms == NULL)
05628 {
05629 _bfd_stringtab_free (stt);
05630 return FALSE;
05631 }
05632 symtab_hdr->contents = outbound_syms;
05633
05634 outbound_shndx = NULL;
05635 symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
05636 if (symtab_shndx_hdr->sh_name != 0)
05637 {
05638 amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
05639 outbound_shndx = bfd_zalloc (abfd, amt);
05640 if (outbound_shndx == NULL)
05641 {
05642 _bfd_stringtab_free (stt);
05643 return FALSE;
05644 }
05645
05646 symtab_shndx_hdr->contents = outbound_shndx;
05647 symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
05648 symtab_shndx_hdr->sh_size = amt;
05649 symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
05650 symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
05651 }
05652
05653
05654 {
05655
05656 Elf_Internal_Sym sym;
05657 sym.st_name = 0;
05658 sym.st_value = 0;
05659 sym.st_size = 0;
05660 sym.st_info = 0;
05661 sym.st_other = 0;
05662 sym.st_shndx = SHN_UNDEF;
05663 bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
05664 outbound_syms += bed->s->sizeof_sym;
05665 if (outbound_shndx != NULL)
05666 outbound_shndx += sizeof (Elf_External_Sym_Shndx);
05667 }
05668
05669 name_local_sections
05670 = (bed->elf_backend_name_local_section_symbols
05671 && bed->elf_backend_name_local_section_symbols (abfd));
05672
05673 syms = bfd_get_outsymbols (abfd);
05674 for (idx = 0; idx < symcount; idx++)
05675 {
05676 Elf_Internal_Sym sym;
05677 bfd_vma value = syms[idx]->value;
05678 elf_symbol_type *type_ptr;
05679 flagword flags = syms[idx]->flags;
05680 int type;
05681
05682 if (!name_local_sections
05683 && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
05684 {
05685
05686 sym.st_name = 0;
05687 }
05688 else
05689 {
05690 sym.st_name = (unsigned long) _bfd_stringtab_add (stt,
05691 syms[idx]->name,
05692 TRUE, FALSE);
05693 if (sym.st_name == (unsigned long) -1)
05694 {
05695 _bfd_stringtab_free (stt);
05696 return FALSE;
05697 }
05698 }
05699
05700 type_ptr = elf_symbol_from (abfd, syms[idx]);
05701
05702 if ((flags & BSF_SECTION_SYM) == 0
05703 && bfd_is_com_section (syms[idx]->section))
05704 {
05705
05706
05707
05708 sym.st_size = value;
05709 if (type_ptr == NULL
05710 || type_ptr->internal_elf_sym.st_value == 0)
05711 sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value));
05712 else
05713 sym.st_value = type_ptr->internal_elf_sym.st_value;
05714 sym.st_shndx = _bfd_elf_section_from_bfd_section
05715 (abfd, syms[idx]->section);
05716 }
05717 else
05718 {
05719 asection *sec = syms[idx]->section;
05720 int shndx;
05721
05722 if (sec->output_section)
05723 {
05724 value += sec->output_offset;
05725 sec = sec->output_section;
05726 }
05727
05728
05729 if (! relocatable_p)
05730 value += sec->vma;
05731 sym.st_value = value;
05732 sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0;
05733
05734 if (bfd_is_abs_section (sec)
05735 && type_ptr != NULL
05736 && type_ptr->internal_elf_sym.st_shndx != 0)
05737 {
05738
05739
05740
05741 shndx = type_ptr->internal_elf_sym.st_shndx;
05742 switch (shndx)
05743 {
05744 case MAP_ONESYMTAB:
05745 shndx = elf_onesymtab (abfd);
05746 break;
05747 case MAP_DYNSYMTAB:
05748 shndx = elf_dynsymtab (abfd);
05749 break;
05750 case MAP_STRTAB:
05751 shndx = elf_tdata (abfd)->strtab_section;
05752 break;
05753 case MAP_SHSTRTAB:
05754 shndx = elf_tdata (abfd)->shstrtab_section;
05755 break;
05756 case MAP_SYM_SHNDX:
05757 shndx = elf_tdata (abfd)->symtab_shndx_section;
05758 break;
05759 default:
05760 break;
05761 }
05762 }
05763 else
05764 {
05765 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
05766
05767 if (shndx == -1)
05768 {
05769 asection *sec2;
05770
05771
05772
05773
05774
05775
05776
05777
05778 sec2 = bfd_get_section_by_name (abfd, sec->name);
05779 if (sec2 == NULL)
05780 {
05781 _bfd_error_handler (_("\
05782 Unable to find equivalent output section for symbol '%s' from section '%s'"),
05783 syms[idx]->name ? syms[idx]->name : "<Local sym>",
05784 sec->name);
05785 bfd_set_error (bfd_error_invalid_operation);
05786 _bfd_stringtab_free (stt);
05787 return FALSE;
05788 }
05789
05790 shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
05791 BFD_ASSERT (shndx != -1);
05792 }
05793 }
05794
05795 sym.st_shndx = shndx;
05796 }
05797
05798 if ((flags & BSF_THREAD_LOCAL) != 0)
05799 type = STT_TLS;
05800 else if ((flags & BSF_FUNCTION) != 0)
05801 type = STT_FUNC;
05802 else if ((flags & BSF_OBJECT) != 0)
05803 type = STT_OBJECT;
05804 else
05805 type = STT_NOTYPE;
05806
05807 if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
05808 type = STT_TLS;
05809
05810
05811 if (type_ptr != NULL
05812 && bed->elf_backend_get_symbol_type)
05813 type = ((*bed->elf_backend_get_symbol_type)
05814 (&type_ptr->internal_elf_sym, type));
05815
05816 if (flags & BSF_SECTION_SYM)
05817 {
05818 if (flags & BSF_GLOBAL)
05819 sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
05820 else
05821 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
05822 }
05823 else if (bfd_is_com_section (syms[idx]->section))
05824 sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
05825 else if (bfd_is_und_section (syms[idx]->section))
05826 sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
05827 ? STB_WEAK
05828 : STB_GLOBAL),
05829 type);
05830 else if (flags & BSF_FILE)
05831 sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
05832 else
05833 {
05834 int bind = STB_LOCAL;
05835
05836 if (flags & BSF_LOCAL)
05837 bind = STB_LOCAL;
05838 else if (flags & BSF_WEAK)
05839 bind = STB_WEAK;
05840 else if (flags & BSF_GLOBAL)
05841 bind = STB_GLOBAL;
05842
05843 sym.st_info = ELF_ST_INFO (bind, type);
05844 }
05845
05846 if (type_ptr != NULL)
05847 sym.st_other = type_ptr->internal_elf_sym.st_other;
05848 else
05849 sym.st_other = 0;
05850
05851 bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
05852 outbound_syms += bed->s->sizeof_sym;
05853 if (outbound_shndx != NULL)
05854 outbound_shndx += sizeof (Elf_External_Sym_Shndx);
05855 }
05856
05857 *sttp = stt;
05858 symstrtab_hdr->sh_size = _bfd_stringtab_size (stt);
05859 symstrtab_hdr->sh_type = SHT_STRTAB;
05860
05861 symstrtab_hdr->sh_flags = 0;
05862 symstrtab_hdr->sh_addr = 0;
05863 symstrtab_hdr->sh_entsize = 0;
05864 symstrtab_hdr->sh_link = 0;
05865 symstrtab_hdr->sh_info = 0;
05866 symstrtab_hdr->sh_addralign = 1;
05867
05868 return TRUE;
05869 }
05870
05871
05872
05873
05874
05875
05876
05877 long
05878 _bfd_elf_get_symtab_upper_bound (bfd *abfd)
05879 {
05880 long symcount;
05881 long symtab_size;
05882 Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
05883
05884 symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
05885 symtab_size = (symcount + 1) * (sizeof (asymbol *));
05886 if (symcount > 0)
05887 symtab_size -= sizeof (asymbol *);
05888
05889 return symtab_size;
05890 }
05891
05892 long
05893 _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
05894 {
05895 long symcount;
05896 long symtab_size;
05897 Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;
05898
05899 if (elf_dynsymtab (abfd) == 0)
05900 {
05901 bfd_set_error (bfd_error_invalid_operation);
05902 return -1;
05903 }
05904
05905 symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
05906 symtab_size = (symcount + 1) * (sizeof (asymbol *));
05907 if (symcount > 0)
05908 symtab_size -= sizeof (asymbol *);
05909
05910 return symtab_size;
05911 }
05912
05913 long
05914 _bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
05915 sec_ptr asect)
05916 {
05917 return (asect->reloc_count + 1) * sizeof (arelent *);
05918 }
05919
05920
05921
05922 long
05923 _bfd_elf_canonicalize_reloc (bfd *abfd,
05924 sec_ptr section,
05925 arelent **relptr,
05926 asymbol **symbols)
05927 {
05928 arelent *tblptr;
05929 unsigned int i;
05930 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
05931
05932 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
05933 return -1;
05934
05935 tblptr = section->relocation;
05936 for (i = 0; i < section->reloc_count; i++)
05937 *relptr++ = tblptr++;
05938
05939 *relptr = NULL;
05940
05941 return section->reloc_count;
05942 }
05943
05944 long
05945 _bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
05946 {
05947 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
05948 long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE);
05949
05950 if (symcount >= 0)
05951 bfd_get_symcount (abfd) = symcount;
05952 return symcount;
05953 }
05954
05955 long
05956 _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
05957 asymbol **allocation)
05958 {
05959 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
05960 long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE);
05961
05962 if (symcount >= 0)
05963 bfd_get_dynamic_symcount (abfd) = symcount;
05964 return symcount;
05965 }
05966
05967
05968
05969
05970
05971
05972 long
05973 _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
05974 {
05975 long ret;
05976 asection *s;
05977
05978 if (elf_dynsymtab (abfd) == 0)
05979 {
05980 bfd_set_error (bfd_error_invalid_operation);
05981 return -1;
05982 }
05983
05984 ret = sizeof (arelent *);
05985 for (s = abfd->sections; s != NULL; s = s->next)
05986 if ((s->flags & SEC_LOAD) != 0
05987 && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
05988 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
05989 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
05990 ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
05991 * sizeof (arelent *));
05992
05993 return ret;
05994 }
05995
05996
05997
05998
05999
06000
06001
06002
06003
06004 long
06005 _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
06006 arelent **storage,
06007 asymbol **syms)
06008 {
06009 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
06010 asection *s;
06011 long ret;
06012
06013 if (elf_dynsymtab (abfd) == 0)
06014 {
06015 bfd_set_error (bfd_error_invalid_operation);
06016 return -1;
06017 }
06018
06019 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
06020 ret = 0;
06021 for (s = abfd->sections; s != NULL; s = s->next)
06022 {
06023 if ((s->flags & SEC_LOAD) != 0
06024 && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
06025 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
06026 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
06027 {
06028 arelent *p;
06029 long count, i;
06030
06031 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
06032 return -1;
06033 count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
06034 p = s->relocation;
06035 for (i = 0; i < count; i++)
06036 *storage++ = p++;
06037 ret += count;
06038 }
06039 }
06040
06041 *storage = NULL;
06042
06043 return ret;
06044 }
06045
06046
06047
06048 bfd_boolean
06049 _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
06050 {
06051 bfd_byte *contents = NULL;
06052 bfd_size_type amt;
06053 unsigned int freeidx = 0;
06054
06055 if (elf_dynverref (abfd) != 0)
06056 {
06057 Elf_Internal_Shdr *hdr;
06058 Elf_External_Verneed *everneed;
06059 Elf_Internal_Verneed *iverneed;
06060 unsigned int i;
06061
06062 hdr = &elf_tdata (abfd)->dynverref_hdr;
06063
06064 amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed);
06065 elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt);
06066 if (elf_tdata (abfd)->verref == NULL)
06067 goto error_return;
06068
06069 elf_tdata (abfd)->cverrefs = hdr->sh_info;
06070
06071 contents = bfd_malloc (hdr->sh_size);
06072 if (contents == NULL)
06073 goto error_return;
06074 if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
06075 || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
06076 goto error_return;
06077
06078 everneed = (Elf_External_Verneed *) contents;
06079 iverneed = elf_tdata (abfd)->verref;
06080 for (i = 0; i < hdr->sh_info; i++, iverneed++)
06081 {
06082 Elf_External_Vernaux *evernaux;
06083 Elf_Internal_Vernaux *ivernaux;
06084 unsigned int j;
06085
06086 _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
06087
06088 iverneed->vn_bfd = abfd;
06089
06090 iverneed->vn_filename =
06091 bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
06092 iverneed->vn_file);
06093 if (iverneed->vn_filename == NULL)
06094 goto error_return;
06095
06096 amt = iverneed->vn_cnt;
06097 amt *= sizeof (Elf_Internal_Vernaux);
06098 iverneed->vn_auxptr = bfd_alloc (abfd, amt);
06099
06100 evernaux = ((Elf_External_Vernaux *)
06101 ((bfd_byte *) everneed + iverneed->vn_aux));
06102 ivernaux = iverneed->vn_auxptr;
06103 for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
06104 {
06105 _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
06106
06107 ivernaux->vna_nodename =
06108 bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
06109 ivernaux->vna_name);
06110 if (ivernaux->vna_nodename == NULL)
06111 goto error_return;
06112
06113 if (j + 1 < iverneed->vn_cnt)
06114 ivernaux->vna_nextptr = ivernaux + 1;
06115 else
06116 ivernaux->vna_nextptr = NULL;
06117
06118 evernaux = ((Elf_External_Vernaux *)
06119 ((bfd_byte *) evernaux + ivernaux->vna_next));
06120
06121 if (ivernaux->vna_other > freeidx)
06122 freeidx = ivernaux->vna_other;
06123 }
06124
06125 if (i + 1 < hdr->sh_info)
06126 iverneed->vn_nextref = iverneed + 1;
06127 else
06128 iverneed->vn_nextref = NULL;
06129
06130 everneed = ((Elf_External_Verneed *)
06131 ((bfd_byte *) everneed + iverneed->vn_next));
06132 }
06133
06134 free (contents);
06135 contents = NULL;
06136 }
06137
06138 if (elf_dynverdef (abfd) != 0)
06139 {
06140 Elf_Internal_Shdr *hdr;
06141 Elf_External_Verdef *everdef;
06142 Elf_Internal_Verdef *iverdef;
06143 Elf_Internal_Verdef *iverdefarr;
06144 Elf_Internal_Verdef iverdefmem;
06145 unsigned int i;
06146 unsigned int maxidx;
06147
06148 hdr = &elf_tdata (abfd)->dynverdef_hdr;
06149
06150 contents = bfd_malloc (hdr->sh_size);
06151 if (contents == NULL)
06152 goto error_return;
06153 if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
06154 || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
06155 goto error_return;
06156
06157
06158
06159
06160 everdef = (Elf_External_Verdef *) contents;
06161 maxidx = 0;
06162 for (i = 0; i < hdr->sh_info; ++i)
06163 {
06164 _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
06165
06166 if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
06167 maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
06168
06169 everdef = ((Elf_External_Verdef *)
06170 ((bfd_byte *) everdef + iverdefmem.vd_next));
06171 }
06172
06173 if (default_imported_symver)
06174 {
06175 if (freeidx > maxidx)
06176 maxidx = ++freeidx;
06177 else
06178 freeidx = ++maxidx;
06179 }
06180 amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef);
06181 elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
06182 if (elf_tdata (abfd)->verdef == NULL)
06183 goto error_return;
06184
06185 elf_tdata (abfd)->cverdefs = maxidx;
06186
06187 everdef = (Elf_External_Verdef *) contents;
06188 iverdefarr = elf_tdata (abfd)->verdef;
06189 for (i = 0; i < hdr->sh_info; i++)
06190 {
06191 Elf_External_Verdaux *everdaux;
06192 Elf_Internal_Verdaux *iverdaux;
06193 unsigned int j;
06194
06195 _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
06196
06197 iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
06198 memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
06199
06200 iverdef->vd_bfd = abfd;
06201
06202 amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux);
06203 iverdef->vd_auxptr = bfd_alloc (abfd, amt);
06204 if (iverdef->vd_auxptr == NULL)
06205 goto error_return;
06206
06207 everdaux = ((Elf_External_Verdaux *)
06208 ((bfd_byte *) everdef + iverdef->vd_aux));
06209 iverdaux = iverdef->vd_auxptr;
06210 for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
06211 {
06212 _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);
06213
06214 iverdaux->vda_nodename =
06215 bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
06216 iverdaux->vda_name);
06217 if (iverdaux->vda_nodename == NULL)
06218 goto error_return;
06219
06220 if (j + 1 < iverdef->vd_cnt)
06221 iverdaux->vda_nextptr = iverdaux + 1;
06222 else
06223 iverdaux->vda_nextptr = NULL;
06224
06225 everdaux = ((Elf_External_Verdaux *)
06226 ((bfd_byte *) everdaux + iverdaux->vda_next));
06227 }
06228
06229 iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
06230
06231 if (i + 1 < hdr->sh_info)
06232 iverdef->vd_nextdef = iverdef + 1;
06233 else
06234 iverdef->vd_nextdef = NULL;
06235
06236 everdef = ((Elf_External_Verdef *)
06237 ((bfd_byte *) everdef + iverdef->vd_next));
06238 }
06239
06240 free (contents);
06241 contents = NULL;
06242 }
06243 else if (default_imported_symver)
06244 {
06245 if (freeidx < 3)
06246 freeidx = 3;
06247 else
06248 freeidx++;
06249
06250 amt = (bfd_size_type) freeidx * sizeof (Elf_Internal_Verdef);
06251 elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
06252 if (elf_tdata (abfd)->verdef == NULL)
06253 goto error_return;
06254
06255 elf_tdata (abfd)->cverdefs = freeidx;
06256 }
06257
06258
06259 if (default_imported_symver)
06260 {
06261 Elf_Internal_Verdef *iverdef;
06262 Elf_Internal_Verdaux *iverdaux;
06263
06264 iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];;
06265
06266 iverdef->vd_version = VER_DEF_CURRENT;
06267 iverdef->vd_flags = 0;
06268 iverdef->vd_ndx = freeidx;
06269 iverdef->vd_cnt = 1;
06270
06271 iverdef->vd_bfd = abfd;
06272
06273 iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
06274 if (iverdef->vd_nodename == NULL)
06275 goto error_return;
06276 iverdef->vd_nextdef = NULL;
06277 amt = (bfd_size_type) sizeof (Elf_Internal_Verdaux);
06278 iverdef->vd_auxptr = bfd_alloc (abfd, amt);
06279
06280 iverdaux = iverdef->vd_auxptr;
06281 iverdaux->vda_nodename = iverdef->vd_nodename;
06282 iverdaux->vda_nextptr = NULL;
06283 }
06284
06285 return TRUE;
06286
06287 error_return:
06288 if (contents != NULL)
06289 free (contents);
06290 return FALSE;
06291 }
06292
06293 asymbol *
06294 _bfd_elf_make_empty_symbol (bfd *abfd)
06295 {
06296 elf_symbol_type *newsym;
06297 bfd_size_type amt = sizeof (elf_symbol_type);
06298
06299 newsym = bfd_zalloc (abfd, amt);
06300 if (!newsym)
06301 return NULL;
06302 else
06303 {
06304 newsym->symbol.the_bfd = abfd;
06305 return &newsym->symbol;
06306 }
06307 }
06308
06309 void
06310 _bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
06311 asymbol *symbol,
06312 symbol_info *ret)
06313 {
06314 bfd_symbol_info (symbol, ret);
06315 }
06316
06317
06318
06319
06320
06321 bfd_boolean
06322 _bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
06323 const char *name)
06324 {
06325
06326 if (name[0] == '.' && name[1] == 'L')
06327 return TRUE;
06328
06329
06330
06331 if (name[0] == '.' && name[1] == '.')
06332 return TRUE;
06333
06334
06335
06336
06337
06338
06339
06340 if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
06341 return TRUE;
06342
06343 return FALSE;
06344 }
06345
06346 alent *
06347 _bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED,
06348 asymbol *symbol ATTRIBUTE_UNUSED)
06349 {
06350 abort ();
06351 return NULL;
06352 }
06353
06354 bfd_boolean
06355 _bfd_elf_set_arch_mach (bfd *abfd,
06356 enum bfd_architecture arch,
06357 unsigned long machine)
06358 {
06359
06360
06361 if (arch != get_elf_backend_data (abfd)->arch
06362 && arch != bfd_arch_unknown
06363 && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
06364 return FALSE;
06365
06366 return bfd_default_set_arch_mach (abfd, arch, machine);
06367 }
06368
06369
06370
06371
06372 static bfd_boolean
06373 elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
06374 asection *section,
06375 asymbol **symbols,
06376 bfd_vma offset,
06377 const char **filename_ptr,
06378 const char **functionname_ptr)
06379 {
06380 const char *filename;
06381 asymbol *func, *file;
06382 bfd_vma low_func;
06383 asymbol **p;
06384
06385
06386
06387
06388
06389
06390
06391
06392 enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
06393
06394 filename = NULL;
06395 func = NULL;
06396 file = NULL;
06397 low_func = 0;
06398 state = nothing_seen;
06399
06400 for (p = symbols; *p != NULL; p++)
06401 {
06402 elf_symbol_type *q;
06403
06404 q = (elf_symbol_type *) *p;
06405
06406 switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
06407 {
06408 default:
06409 break;
06410 case STT_FILE:
06411 file = &q->symbol;
06412 if (state == symbol_seen)
06413 state = file_after_symbol_seen;
06414 continue;
06415 case STT_SECTION:
06416 continue;
06417 case STT_NOTYPE:
06418 case STT_FUNC:
06419 if (bfd_get_section (&q->symbol) == section
06420 && q->symbol.value >= low_func
06421 && q->symbol.value <= offset)
06422 {
06423 func = (asymbol *) q;
06424 low_func = q->symbol.value;
06425 if (file == NULL)
06426 filename = NULL;
06427 else if (ELF_ST_BIND (q->internal_elf_sym.st_info) != STB_LOCAL
06428 && state == file_after_symbol_seen)
06429 filename = NULL;
06430 else
06431 filename = bfd_asymbol_name (file);
06432 }
06433 break;
06434 }
06435 if (state == nothing_seen)
06436 state = symbol_seen;
06437 }
06438
06439 if (func == NULL)
06440 return FALSE;
06441
06442 if (filename_ptr)
06443 *filename_ptr = filename;
06444 if (functionname_ptr)
06445 *functionname_ptr = bfd_asymbol_name (func);
06446
06447 return TRUE;
06448 }
06449
06450
06451
06452
06453 bfd_boolean
06454 _bfd_elf_find_nearest_line (bfd *abfd,
06455 asection *section,
06456 asymbol **symbols,
06457 bfd_vma offset,
06458 const char **filename_ptr,
06459 const char **functionname_ptr,
06460 unsigned int *line_ptr)
06461 {
06462 bfd_boolean found;
06463
06464 if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
06465 filename_ptr, functionname_ptr,
06466 line_ptr))
06467 {
06468 if (!*functionname_ptr)
06469 elf_find_function (abfd, section, symbols, offset,
06470 *filename_ptr ? NULL : filename_ptr,
06471 functionname_ptr);
06472
06473 return TRUE;
06474 }
06475
06476 if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
06477 filename_ptr, functionname_ptr,
06478 line_ptr, 0,
06479 &elf_tdata (abfd)->dwarf2_find_line_info))
06480 {
06481 if (!*functionname_ptr)
06482 elf_find_function (abfd, section, symbols, offset,
06483 *filename_ptr ? NULL : filename_ptr,
06484 functionname_ptr);
06485
06486 return TRUE;
06487 }
06488
06489 if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
06490 &found, filename_ptr,
06491 functionname_ptr, line_ptr,
06492 &elf_tdata (abfd)->line_info))
06493 return FALSE;
06494 if (found && (*functionname_ptr || *line_ptr))
06495 return TRUE;
06496
06497 if (symbols == NULL)
06498 return FALSE;
06499
06500 if (! elf_find_function (abfd, section, symbols, offset,
06501 filename_ptr, functionname_ptr))
06502 return FALSE;
06503
06504 *line_ptr = 0;
06505 return TRUE;
06506 }
06507
06508 int
06509 _bfd_elf_sizeof_headers (bfd *abfd, bfd_boolean reloc)
06510 {
06511 int ret;
06512
06513 ret = get_elf_backend_data (abfd)->s->sizeof_ehdr;
06514 if (! reloc)
06515 ret += get_program_header_size (abfd);
06516 return ret;
06517 }
06518
06519 bfd_boolean
06520 _bfd_elf_set_section_contents (bfd *abfd,
06521 sec_ptr section,
06522 const void *location,
06523 file_ptr offset,
06524 bfd_size_type count)
06525 {
06526 Elf_Internal_Shdr *hdr;
06527 bfd_signed_vma pos;
06528
06529 if (! abfd->output_has_begun
06530 && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
06531 return FALSE;
06532
06533 hdr = &elf_section_data (section)->this_hdr;
06534 pos = hdr->sh_offset + offset;
06535 if (bfd_seek (abfd, pos, SEEK_SET) != 0
06536 || bfd_bwrite (location, count, abfd) != count)
06537 return FALSE;
06538
06539 return TRUE;
06540 }
06541
06542 void
06543 _bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
06544 arelent *cache_ptr ATTRIBUTE_UNUSED,
06545 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
06546 {
06547 abort ();
06548 }
06549
06550
06551
06552 bfd_boolean
06553 _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
06554 {
06555
06556
06557 if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
06558 {
06559 bfd_reloc_code_real_type code;
06560 reloc_howto_type *howto;
06561
06562
06563
06564
06565 if (areloc->howto->pc_relative)
06566 {
06567 switch (areloc->howto->bitsize)
06568 {
06569 case 8:
06570 code = BFD_RELOC_8_PCREL;
06571 break;
06572 case 12:
06573 code = BFD_RELOC_12_PCREL;
06574 break;
06575 case 16:
06576 code = BFD_RELOC_16_PCREL;
06577 break;
06578 case 24:
06579 code = BFD_RELOC_24_PCREL;
06580 break;
06581 case 32:
06582 code = BFD_RELOC_32_PCREL;
06583 break;
06584 case 64:
06585 code = BFD_RELOC_64_PCREL;
06586 break;
06587 default:
06588 goto fail;
06589 }
06590
06591 howto = bfd_reloc_type_lookup (abfd, code);
06592
06593 if (areloc->howto->pcrel_offset != howto->pcrel_offset)
06594 {
06595 if (howto->pcrel_offset)
06596 areloc->addend += areloc->address;
06597 else
06598 areloc->addend -= areloc->address;
06599 }
06600 }
06601 else
06602 {
06603 switch (areloc->howto->bitsize)
06604 {
06605 case 8:
06606 code = BFD_RELOC_8;
06607 break;
06608 case 14:
06609 code = BFD_RELOC_14;
06610 break;
06611 case 16:
06612 code = BFD_RELOC_16;
06613 break;
06614 case 26:
06615 code = BFD_RELOC_26;
06616 break;
06617 case 32:
06618 code = BFD_RELOC_32;
06619 break;
06620 case 64:
06621 code = BFD_RELOC_64;
06622 break;
06623 default:
06624 goto fail;
06625 }
06626
06627 howto = bfd_reloc_type_lookup (abfd, code);
06628 }
06629
06630 if (howto)
06631 areloc->howto = howto;
06632 else
06633 goto fail;
06634 }
06635
06636 return TRUE;
06637
06638 fail:
06639 (*_bfd_error_handler)
06640 (_("%B: unsupported relocation type %s"),
06641 abfd, areloc->howto->name);
06642 bfd_set_error (bfd_error_bad_value);
06643 return FALSE;
06644 }
06645
06646 bfd_boolean
06647 _bfd_elf_close_and_cleanup (bfd *abfd)
06648 {
06649 if (bfd_get_format (abfd) == bfd_object)
06650 {
06651 if (elf_shstrtab (abfd) != NULL)
06652 _bfd_elf_strtab_free (elf_shstrtab (abfd));
06653 }
06654
06655 return _bfd_generic_close_and_cleanup (abfd);
06656 }
06657
06658
06659
06660
06661
06662
06663 bfd_reloc_status_type
06664 _bfd_elf_rel_vtable_reloc_fn
06665 (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
06666 struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
06667 void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
06668 bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
06669 {
06670 return bfd_reloc_ok;
06671 }
06672
06673
06674
06675
06676
06677
06678 #ifdef HAVE_SYS_PROCFS_H
06679 # include <sys/procfs.h>
06680 #endif
06681
06682
06683
06684 static int
06685 elfcore_make_pid (bfd *abfd)
06686 {
06687 return ((elf_tdata (abfd)->core_lwpid << 16)
06688 + (elf_tdata (abfd)->core_pid));
06689 }
06690
06691
06692
06693
06694
06695
06696 static bfd_boolean
06697 elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
06698 {
06699 asection *sect2;
06700
06701 if (bfd_get_section_by_name (abfd, name) != NULL)
06702 return TRUE;
06703
06704 sect2 = bfd_make_section (abfd, name);
06705 if (sect2 == NULL)
06706 return FALSE;
06707
06708 sect2->size = sect->size;
06709 sect2->filepos = sect->filepos;
06710 sect2->flags = sect->flags;
06711 sect2->alignment_power = sect->alignment_power;
06712 return TRUE;
06713 }
06714
06715
06716
06717
06718
06719
06720
06721
06722 bfd_boolean
06723 _bfd_elfcore_make_pseudosection (bfd *abfd,
06724 char *name,
06725 size_t size,
06726 ufile_ptr filepos)
06727 {
06728 char buf[100];
06729 char *threaded_name;
06730 size_t len;
06731 asection *sect;
06732
06733
06734
06735 sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
06736 len = strlen (buf) + 1;
06737 threaded_name = bfd_alloc (abfd, len);
06738 if (threaded_name == NULL)
06739 return FALSE;
06740 memcpy (threaded_name, buf, len);
06741
06742 sect = bfd_make_section_anyway (abfd, threaded_name);
06743 if (sect == NULL)
06744 return FALSE;
06745 sect->size = size;
06746 sect->filepos = filepos;
06747 sect->flags = SEC_HAS_CONTENTS;
06748 sect->alignment_power = 2;
06749
06750 return elfcore_maybe_make_sect (abfd, name, sect);
06751 }
06752
06753
06754
06755
06756
06757
06758
06759 #if defined (HAVE_PRSTATUS_T)
06760
06761 static bfd_boolean
06762 elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
06763 {
06764 size_t size;
06765 int offset;
06766
06767 if (note->descsz == sizeof (prstatus_t))
06768 {
06769 prstatus_t prstat;
06770
06771 size = sizeof (prstat.pr_reg);
06772 offset = offsetof (prstatus_t, pr_reg);
06773 memcpy (&prstat, note->descdata, sizeof (prstat));
06774
06775
06776
06777 if (elf_tdata (abfd)->core_signal == 0)
06778 elf_tdata (abfd)->core_signal = prstat.pr_cursig;
06779 elf_tdata (abfd)->core_pid = prstat.pr_pid;
06780
06781
06782
06783
06784
06785
06786
06787 #if defined (HAVE_PRSTATUS_T_PR_WHO)
06788 elf_tdata (abfd)->core_lwpid = prstat.pr_who;
06789 #endif
06790 }
06791 #if defined (HAVE_PRSTATUS32_T)
06792 else if (note->descsz == sizeof (prstatus32_t))
06793 {
06794
06795 prstatus32_t prstat;
06796
06797 size = sizeof (prstat.pr_reg);
06798 offset = offsetof (prstatus32_t, pr_reg);
06799 memcpy (&prstat, note->descdata, sizeof (prstat));
06800
06801
06802
06803 if (elf_tdata (abfd)->core_signal == 0)
06804 elf_tdata (abfd)->core_signal = prstat.pr_cursig;
06805 elf_tdata (abfd)->core_pid = prstat.pr_pid;
06806
06807
06808
06809
06810
06811
06812
06813 #if defined (HAVE_PRSTATUS32_T_PR_WHO)
06814 elf_tdata (abfd)->core_lwpid = prstat.pr_who;
06815 #endif
06816 }
06817 #endif
06818 else
06819 {
06820
06821
06822 return TRUE;
06823 }
06824
06825
06826 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
06827 size, note->descpos + offset);
06828 }
06829 #endif
06830
06831
06832 static bfd_boolean
06833 elfcore_make_note_pseudosection (bfd *abfd,
06834 char *name,
06835 Elf_Internal_Note *note)
06836 {
06837 return _bfd_elfcore_make_pseudosection (abfd, name,
06838 note->descsz, note->descpos);
06839 }
06840
06841
06842
06843
06844
06845 static bfd_boolean
06846 elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
06847 {
06848 return elfcore_make_note_pseudosection (abfd, ".reg2", note);
06849 }
06850
06851
06852
06853
06854
06855 static bfd_boolean
06856 elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
06857 {
06858 return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
06859 }
06860
06861 #if defined (HAVE_PRPSINFO_T)
06862 typedef prpsinfo_t elfcore_psinfo_t;
06863 #if defined (HAVE_PRPSINFO32_T)
06864 typedef prpsinfo32_t elfcore_psinfo32_t;
06865 #endif
06866 #endif
06867
06868 #if defined (HAVE_PSINFO_T)
06869 typedef psinfo_t elfcore_psinfo_t;
06870 #if defined (HAVE_PSINFO32_T)
06871 typedef psinfo32_t elfcore_psinfo32_t;
06872 #endif
06873 #endif
06874
06875
06876
06877
06878
06879 char *
06880 _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
06881 {
06882 char *dups;
06883 char *end = memchr (start, '\0', max);
06884 size_t len;
06885
06886 if (end == NULL)
06887 len = max;
06888 else
06889 len = end - start;
06890
06891 dups = bfd_alloc (abfd, len + 1);
06892 if (dups == NULL)
06893 return NULL;
06894
06895 memcpy (dups, start, len);
06896 dups[len] = '\0';
06897
06898 return dups;
06899 }
06900
06901 #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
06902 static bfd_boolean
06903 elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
06904 {
06905 if (note->descsz == sizeof (elfcore_psinfo_t))
06906 {
06907 elfcore_psinfo_t psinfo;
06908
06909 memcpy (&psinfo, note->descdata, sizeof (psinfo));
06910
06911 elf_tdata (abfd)->core_program
06912 = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
06913 sizeof (psinfo.pr_fname));
06914
06915 elf_tdata (abfd)->core_command
06916 = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
06917 sizeof (psinfo.pr_psargs));
06918 }
06919 #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
06920 else if (note->descsz == sizeof (elfcore_psinfo32_t))
06921 {
06922
06923 elfcore_psinfo32_t psinfo;
06924
06925 memcpy (&psinfo, note->descdata, sizeof (psinfo));
06926
06927 elf_tdata (abfd)->core_program
06928 = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
06929 sizeof (psinfo.pr_fname));
06930
06931 elf_tdata (abfd)->core_command
06932 = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
06933 sizeof (psinfo.pr_psargs));
06934 }
06935 #endif
06936
06937 else
06938 {
06939
06940
06941 return TRUE;
06942 }
06943
06944
06945
06946
06947
06948 {
06949 char *command = elf_tdata (abfd)->core_command;
06950 int n = strlen (command);
06951
06952 if (0 < n && command[n - 1] == ' ')
06953 command[n - 1] = '\0';
06954 }
06955
06956 return TRUE;
06957 }
06958 #endif
06959
06960 #if defined (HAVE_PSTATUS_T)
06961 static bfd_boolean
06962 elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
06963 {
06964 if (note->descsz == sizeof (pstatus_t)
06965 #if defined (HAVE_PXSTATUS_T)
06966 || note->descsz == sizeof (pxstatus_t)
06967 #endif
06968 )
06969 {
06970 pstatus_t pstat;
06971
06972 memcpy (&pstat, note->descdata, sizeof (pstat));
06973
06974 elf_tdata (abfd)->core_pid = pstat.pr_pid;
06975 }
06976 #if defined (HAVE_PSTATUS32_T)
06977 else if (note->descsz == sizeof (pstatus32_t))
06978 {
06979
06980 pstatus32_t pstat;
06981
06982 memcpy (&pstat, note->descdata, sizeof (pstat));
06983
06984 elf_tdata (abfd)->core_pid = pstat.pr_pid;
06985 }
06986 #endif
06987
06988
06989
06990
06991 return TRUE;
06992 }
06993 #endif
06994
06995 #if defined (HAVE_LWPSTATUS_T)
06996 static bfd_boolean
06997 elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
06998 {
06999 lwpstatus_t lwpstat;
07000 char buf[100];
07001 char *name;
07002 size_t len;
07003 asection *sect;
07004
07005 if (note->descsz != sizeof (lwpstat)
07006 #if defined (HAVE_LWPXSTATUS_T)
07007 && note->descsz != sizeof (lwpxstatus_t)
07008 #endif
07009 )
07010 return TRUE;
07011
07012 memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
07013
07014 elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid;
07015 elf_tdata (abfd)->core_signal = lwpstat.pr_cursig;
07016
07017
07018
07019 sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
07020 len = strlen (buf) + 1;
07021 name = bfd_alloc (abfd, len);
07022 if (name == NULL)
07023 return FALSE;
07024 memcpy (name, buf, len);
07025
07026 sect = bfd_make_section_anyway (abfd, name);
07027 if (sect == NULL)
07028 return FALSE;
07029
07030 #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
07031 sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
07032 sect->filepos = note->descpos
07033 + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
07034 #endif
07035
07036 #if defined (HAVE_LWPSTATUS_T_PR_REG)
07037 sect->size = sizeof (lwpstat.pr_reg);
07038 sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
07039 #endif
07040
07041 sect->flags = SEC_HAS_CONTENTS;
07042 sect->alignment_power = 2;
07043
07044 if (!elfcore_maybe_make_sect (abfd, ".reg", sect))
07045 return FALSE;
07046
07047
07048
07049 sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
07050 len = strlen (buf) + 1;
07051 name = bfd_alloc (abfd, len);
07052 if (name == NULL)
07053 return FALSE;
07054 memcpy (name, buf, len);
07055
07056 sect = bfd_make_section_anyway (abfd, name);
07057 if (sect == NULL)
07058 return FALSE;
07059
07060 #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
07061 sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
07062 sect->filepos = note->descpos
07063 + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
07064 #endif
07065
07066 #if defined (HAVE_LWPSTATUS_T_PR_FPREG)
07067 sect->size = sizeof (lwpstat.pr_fpreg);
07068 sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
07069 #endif
07070
07071 sect->flags = SEC_HAS_CONTENTS;
07072 sect->alignment_power = 2;
07073
07074 return elfcore_maybe_make_sect (abfd, ".reg2", sect);
07075 }
07076 #endif
07077
07078 #if defined (HAVE_WIN32_PSTATUS_T)
07079 static bfd_boolean
07080 elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
07081 {
07082 char buf[30];
07083 char *name;
07084 size_t len;
07085 asection *sect;
07086 win32_pstatus_t pstatus;
07087
07088 if (note->descsz < sizeof (pstatus))
07089 return TRUE;
07090
07091 memcpy (&pstatus, note->descdata, sizeof (pstatus));
07092
07093 switch (pstatus.data_type)
07094 {
07095 case NOTE_INFO_PROCESS:
07096
07097 elf_tdata (abfd)->core_signal = pstatus.data.process_info.signal;
07098 elf_tdata (abfd)->core_pid = pstatus.data.process_info.pid;
07099 break;
07100
07101 case NOTE_INFO_THREAD:
07102
07103 sprintf (buf, ".reg/%ld", (long) pstatus.data.thread_info.tid);
07104
07105 len = strlen (buf) + 1;
07106 name = bfd_alloc (abfd, len);
07107 if (name == NULL)
07108 return FALSE;
07109
07110 memcpy (name, buf, len);
07111
07112 sect = bfd_make_section_anyway (abfd, name);
07113 if (sect == NULL)
07114 return FALSE;
07115
07116 sect->size = sizeof (pstatus.data.thread_info.thread_context);
07117 sect->filepos = (note->descpos
07118 + offsetof (struct win32_pstatus,
07119 data.thread_info.thread_context));
07120 sect->flags = SEC_HAS_CONTENTS;
07121 sect->alignment_power = 2;
07122
07123 if (pstatus.data.thread_info.is_active_thread)
07124 if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
07125 return FALSE;
07126 break;
07127
07128 case NOTE_INFO_MODULE:
07129
07130 sprintf (buf, ".module/%08lx",
07131 (long) pstatus.data.module_info.base_address);
07132
07133 len = strlen (buf) + 1;
07134 name = bfd_alloc (abfd, len);
07135 if (name == NULL)
07136 return FALSE;
07137
07138 memcpy (name, buf, len);
07139
07140 sect = bfd_make_section_anyway (abfd, name);
07141
07142 if (sect == NULL)
07143 return FALSE;
07144
07145 sect->size = note->descsz;
07146 sect->filepos = note->descpos;
07147 sect->flags = SEC_HAS_CONTENTS;
07148 sect->alignment_power = 2;
07149 break;
07150
07151 default:
07152 return TRUE;
07153 }
07154
07155 return TRUE;
07156 }
07157 #endif
07158
07159 static bfd_boolean
07160 elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
07161 {
07162 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
07163
07164 switch (note->type)
07165 {
07166 default:
07167 return TRUE;
07168
07169 case NT_PRSTATUS:
07170 if (bed->elf_backend_grok_prstatus)
07171 if ((*bed->elf_backend_grok_prstatus) (abfd, note))
07172 return TRUE;
07173 #if defined (HAVE_PRSTATUS_T)
07174 return elfcore_grok_prstatus (abfd, note);
07175 #else
07176 return TRUE;
07177 #endif
07178
07179 #if defined (HAVE_PSTATUS_T)
07180 case NT_PSTATUS:
07181 return elfcore_grok_pstatus (abfd, note);
07182 #endif
07183
07184 #if defined (HAVE_LWPSTATUS_T)
07185 case NT_LWPSTATUS:
07186 return elfcore_grok_lwpstatus (abfd, note);
07187 #endif
07188
07189 case NT_FPREGSET:
07190 return elfcore_grok_prfpreg (abfd, note);
07191
07192 #if defined (HAVE_WIN32_PSTATUS_T)
07193 case NT_WIN32PSTATUS:
07194 return elfcore_grok_win32pstatus (abfd, note);
07195 #endif
07196
07197 case NT_PRXFPREG:
07198 if (note->namesz == 6
07199 && strcmp (note->namedata, "LINUX") == 0)
07200 return elfcore_grok_prxfpreg (abfd, note);
07201 else
07202 return TRUE;
07203
07204 case NT_PRPSINFO:
07205 case NT_PSINFO:
07206 if (bed->elf_backend_grok_psinfo)
07207 if ((*bed->elf_backend_grok_psinfo) (abfd, note))
07208 return TRUE;
07209 #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
07210 return elfcore_grok_psinfo (abfd, note);
07211 #else
07212 return TRUE;
07213 #endif
07214
07215 case NT_AUXV:
07216 {
07217 asection *sect = bfd_make_section_anyway (abfd, ".auxv");
07218
07219 if (sect == NULL)
07220 return FALSE;
07221 sect->size = note->descsz;
07222 sect->filepos = note->descpos;
07223 sect->flags = SEC_HAS_CONTENTS;
07224 sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
07225
07226 return TRUE;
07227 }
07228 }
07229 }
07230
07231 static bfd_boolean
07232 elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
07233 {
07234 char *cp;
07235
07236 cp = strchr (note->namedata, '@');
07237 if (cp != NULL)
07238 {
07239 *lwpidp = atoi(cp + 1);
07240 return TRUE;
07241 }
07242 return FALSE;
07243 }
07244
07245 static bfd_boolean
07246 elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
07247 {
07248
07249
07250 elf_tdata (abfd)->core_signal
07251 = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
07252
07253
07254 elf_tdata (abfd)->core_pid
07255 = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
07256
07257
07258 elf_tdata (abfd)->core_command
07259 = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
07260
07261 return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
07262 note);
07263 }
07264
07265 static bfd_boolean
07266 elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
07267 {
07268 int lwp;
07269
07270 if (elfcore_netbsd_get_lwpid (note, &lwp))
07271 elf_tdata (abfd)->core_lwpid = lwp;
07272
07273 if (note->type == NT_NETBSDCORE_PROCINFO)
07274 {
07275
07276
07277
07278
07279
07280 return elfcore_grok_netbsd_procinfo (abfd, note);
07281 }
07282
07283
07284
07285
07286
07287
07288 if (note->type < NT_NETBSDCORE_FIRSTMACH)
07289 return TRUE;
07290
07291
07292 switch (bfd_get_arch (abfd))
07293 {
07294
07295
07296
07297 case bfd_arch_alpha:
07298 case bfd_arch_sparc:
07299 switch (note->type)
07300 {
07301 case NT_NETBSDCORE_FIRSTMACH+0:
07302 return elfcore_make_note_pseudosection (abfd, ".reg", note);
07303
07304 case NT_NETBSDCORE_FIRSTMACH+2:
07305 return elfcore_make_note_pseudosection (abfd, ".reg2", note);
07306
07307 default:
07308 return TRUE;
07309 }
07310
07311
07312
07313
07314 default:
07315 switch (note->type)
07316 {
07317 case NT_NETBSDCORE_FIRSTMACH+1:
07318 return elfcore_make_note_pseudosection (abfd, ".reg", note);
07319
07320 case NT_NETBSDCORE_FIRSTMACH+3:
07321 return elfcore_make_note_pseudosection (abfd, ".reg2", note);
07322
07323 default:
07324 return TRUE;
07325 }
07326 }
07327
07328 }
07329
07330 static bfd_boolean
07331 elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, pid_t *tid)
07332 {
07333 void *ddata = note->descdata;
07334 char buf[100];
07335 char *name;
07336 asection *sect;
07337 short sig;
07338 unsigned flags;
07339
07340
07341 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
07342
07343
07344 *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
07345
07346
07347 flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
07348
07349
07350 if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
07351 {
07352 elf_tdata (abfd)->core_signal = sig;
07353 elf_tdata (abfd)->core_lwpid = *tid;
07354 }
07355
07356
07357
07358
07359 if (flags & 0x00000080)
07360 elf_tdata (abfd)->core_lwpid = *tid;
07361
07362
07363 sprintf (buf, ".qnx_core_status/%d", *tid);
07364
07365 name = bfd_alloc (abfd, strlen (buf) + 1);
07366 if (name == NULL)
07367 return FALSE;
07368 strcpy (name, buf);
07369
07370 sect = bfd_make_section_anyway (abfd, name);
07371 if (sect == NULL)
07372 return FALSE;
07373
07374 sect->size = note->descsz;
07375 sect->filepos = note->descpos;
07376 sect->flags = SEC_HAS_CONTENTS;
07377 sect->alignment_power = 2;
07378
07379 return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
07380 }
07381
07382 static bfd_boolean
07383 elfcore_grok_nto_regs (bfd *abfd,
07384 Elf_Internal_Note *note,
07385 pid_t tid,
07386 char *base)
07387 {
07388 char buf[100];
07389 char *name;
07390 asection *sect;
07391
07392
07393 sprintf (buf, "%s/%d", base, tid);
07394
07395 name = bfd_alloc (abfd, strlen (buf) + 1);
07396 if (name == NULL)
07397 return FALSE;
07398 strcpy (name, buf);
07399
07400 sect = bfd_make_section_anyway (abfd, name);
07401 if (sect == NULL)
07402 return FALSE;
07403
07404 sect->size = note->descsz;
07405 sect->filepos = note->descpos;
07406 sect->flags = SEC_HAS_CONTENTS;
07407 sect->alignment_power = 2;
07408
07409
07410 if (elf_tdata (abfd)->core_lwpid == tid)
07411 return elfcore_maybe_make_sect (abfd, base, sect);
07412
07413 return TRUE;
07414 }
07415
07416 #define BFD_QNT_CORE_INFO 7
07417 #define BFD_QNT_CORE_STATUS 8
07418 #define BFD_QNT_CORE_GREG 9
07419 #define BFD_QNT_CORE_FPREG 10
07420
07421 static bfd_boolean
07422 elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
07423 {
07424
07425
07426
07427 static pid_t tid = 1;
07428
07429