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