00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "bfd.h"
00029 #include "sysdep.h"
00030 #include "bfdlink.h"
00031 #include "libbfd.h"
00032 #include "coff/internal.h"
00033 #include "libcoff.h"
00034 #include "safe-ctype.h"
00035
00036 static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info);
00037 static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded);
00038 static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info);
00039
00040
00041 #define IS_WEAK_EXTERNAL(abfd, sym) \
00042 ((sym).n_sclass == C_WEAKEXT \
00043 || (obj_pe (abfd) && (sym).n_sclass == C_NT_WEAK))
00044
00045
00046 #define IS_EXTERNAL(abfd, sym) \
00047 ((sym).n_sclass == C_EXT || IS_WEAK_EXTERNAL (abfd, sym))
00048
00049
00050
00051
00052
00053
00054
00055 #define N_TMASK n_tmask
00056 #define N_BTSHFT n_btshft
00057 #define N_BTMASK n_btmask
00058
00059
00060
00061 struct bfd_hash_entry *
00062 _bfd_coff_link_hash_newfunc (struct bfd_hash_entry *entry,
00063 struct bfd_hash_table *table,
00064 const char *string)
00065 {
00066 struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry;
00067
00068
00069
00070 if (ret == (struct coff_link_hash_entry *) NULL)
00071 ret = ((struct coff_link_hash_entry *)
00072 bfd_hash_allocate (table, sizeof (struct coff_link_hash_entry)));
00073 if (ret == (struct coff_link_hash_entry *) NULL)
00074 return (struct bfd_hash_entry *) ret;
00075
00076
00077 ret = ((struct coff_link_hash_entry *)
00078 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
00079 table, string));
00080 if (ret != (struct coff_link_hash_entry *) NULL)
00081 {
00082
00083 ret->indx = -1;
00084 ret->type = T_NULL;
00085 ret->class = C_NULL;
00086 ret->numaux = 0;
00087 ret->auxbfd = NULL;
00088 ret->aux = NULL;
00089 }
00090
00091 return (struct bfd_hash_entry *) ret;
00092 }
00093
00094
00095
00096 bfd_boolean
00097 _bfd_coff_link_hash_table_init (struct coff_link_hash_table *table,
00098 bfd *abfd,
00099 struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
00100 struct bfd_hash_table *,
00101 const char *))
00102 {
00103 memset (&table->stab_info, 0, sizeof (table->stab_info));
00104 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
00105 }
00106
00107
00108
00109 struct bfd_link_hash_table *
00110 _bfd_coff_link_hash_table_create (bfd *abfd)
00111 {
00112 struct coff_link_hash_table *ret;
00113 bfd_size_type amt = sizeof (struct coff_link_hash_table);
00114
00115 ret = bfd_malloc (amt);
00116 if (ret == NULL)
00117 return NULL;
00118
00119 if (! _bfd_coff_link_hash_table_init (ret, abfd,
00120 _bfd_coff_link_hash_newfunc))
00121 {
00122 free (ret);
00123 return (struct bfd_link_hash_table *) NULL;
00124 }
00125 return &ret->root;
00126 }
00127
00128
00129
00130 struct bfd_hash_entry *
00131 _bfd_coff_debug_merge_hash_newfunc (struct bfd_hash_entry *entry,
00132 struct bfd_hash_table *table,
00133 const char *string)
00134 {
00135 struct coff_debug_merge_hash_entry *ret =
00136 (struct coff_debug_merge_hash_entry *) entry;
00137
00138
00139
00140 if (ret == (struct coff_debug_merge_hash_entry *) NULL)
00141 ret = ((struct coff_debug_merge_hash_entry *)
00142 bfd_hash_allocate (table,
00143 sizeof (struct coff_debug_merge_hash_entry)));
00144 if (ret == (struct coff_debug_merge_hash_entry *) NULL)
00145 return (struct bfd_hash_entry *) ret;
00146
00147
00148 ret = ((struct coff_debug_merge_hash_entry *)
00149 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
00150 if (ret != (struct coff_debug_merge_hash_entry *) NULL)
00151 {
00152
00153 ret->types = NULL;
00154 }
00155
00156 return (struct bfd_hash_entry *) ret;
00157 }
00158
00159
00160
00161
00162 bfd_boolean
00163 _bfd_coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
00164 {
00165 switch (bfd_get_format (abfd))
00166 {
00167 case bfd_object:
00168 return coff_link_add_object_symbols (abfd, info);
00169 case bfd_archive:
00170 return _bfd_generic_link_add_archive_symbols
00171 (abfd, info, coff_link_check_archive_element);
00172 default:
00173 bfd_set_error (bfd_error_wrong_format);
00174 return FALSE;
00175 }
00176 }
00177
00178
00179
00180 static bfd_boolean
00181 coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
00182 {
00183 if (! _bfd_coff_get_external_symbols (abfd))
00184 return FALSE;
00185 if (! coff_link_add_symbols (abfd, info))
00186 return FALSE;
00187
00188 if (! info->keep_memory
00189 && ! _bfd_coff_free_symbols (abfd))
00190 return FALSE;
00191
00192 return TRUE;
00193 }
00194
00195
00196
00197
00198 static bfd_boolean
00199 coff_link_check_ar_symbols (bfd *abfd,
00200 struct bfd_link_info *info,
00201 bfd_boolean *pneeded)
00202 {
00203 bfd_size_type symesz;
00204 bfd_byte *esym;
00205 bfd_byte *esym_end;
00206
00207 *pneeded = FALSE;
00208
00209 symesz = bfd_coff_symesz (abfd);
00210 esym = (bfd_byte *) obj_coff_external_syms (abfd);
00211 esym_end = esym + obj_raw_syment_count (abfd) * symesz;
00212 while (esym < esym_end)
00213 {
00214 struct internal_syment sym;
00215 enum coff_symbol_classification classification;
00216
00217 bfd_coff_swap_sym_in (abfd, esym, &sym);
00218
00219 classification = bfd_coff_classify_symbol (abfd, &sym);
00220 if (classification == COFF_SYMBOL_GLOBAL
00221 || classification == COFF_SYMBOL_COMMON)
00222 {
00223 const char *name;
00224 char buf[SYMNMLEN + 1];
00225 struct bfd_link_hash_entry *h;
00226
00227
00228
00229 name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
00230 if (name == NULL)
00231 return FALSE;
00232 h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
00233
00234
00235 if (!h
00236 && info->pei386_auto_import
00237 && !strncmp (name,"__imp_", 6))
00238 h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE);
00239
00240
00241
00242
00243
00244 if (h != (struct bfd_link_hash_entry *) NULL
00245 && h->type == bfd_link_hash_undefined)
00246 {
00247 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
00248 return FALSE;
00249 *pneeded = TRUE;
00250 return TRUE;
00251 }
00252 }
00253
00254 esym += (sym.n_numaux + 1) * symesz;
00255 }
00256
00257
00258 return TRUE;
00259 }
00260
00261
00262
00263
00264
00265
00266 static bfd_boolean
00267 coff_link_check_archive_element (bfd *abfd,
00268 struct bfd_link_info *info,
00269 bfd_boolean *pneeded)
00270 {
00271 if (! _bfd_coff_get_external_symbols (abfd))
00272 return FALSE;
00273
00274 if (! coff_link_check_ar_symbols (abfd, info, pneeded))
00275 return FALSE;
00276
00277 if (*pneeded
00278 && ! coff_link_add_symbols (abfd, info))
00279 return FALSE;
00280
00281 if ((! info->keep_memory || ! *pneeded)
00282 && ! _bfd_coff_free_symbols (abfd))
00283 return FALSE;
00284
00285 return TRUE;
00286 }
00287
00288
00289
00290 static bfd_boolean
00291 coff_link_add_symbols (bfd *abfd,
00292 struct bfd_link_info *info)
00293 {
00294 unsigned int n_tmask = coff_data (abfd)->local_n_tmask;
00295 unsigned int n_btshft = coff_data (abfd)->local_n_btshft;
00296 unsigned int n_btmask = coff_data (abfd)->local_n_btmask;
00297 bfd_boolean keep_syms;
00298 bfd_boolean default_copy;
00299 bfd_size_type symcount;
00300 struct coff_link_hash_entry **sym_hash;
00301 bfd_size_type symesz;
00302 bfd_byte *esym;
00303 bfd_byte *esym_end;
00304 bfd_size_type amt;
00305
00306
00307
00308 keep_syms = obj_coff_keep_syms (abfd);
00309 obj_coff_keep_syms (abfd) = TRUE;
00310
00311 if (info->keep_memory)
00312 default_copy = FALSE;
00313 else
00314 default_copy = TRUE;
00315
00316 symcount = obj_raw_syment_count (abfd);
00317
00318
00319
00320 amt = symcount * sizeof (struct coff_link_hash_entry *);
00321 sym_hash = bfd_zalloc (abfd, amt);
00322 if (sym_hash == NULL && symcount != 0)
00323 goto error_return;
00324 obj_coff_sym_hashes (abfd) = sym_hash;
00325
00326 symesz = bfd_coff_symesz (abfd);
00327 BFD_ASSERT (symesz == bfd_coff_auxesz (abfd));
00328 esym = (bfd_byte *) obj_coff_external_syms (abfd);
00329 esym_end = esym + symcount * symesz;
00330 while (esym < esym_end)
00331 {
00332 struct internal_syment sym;
00333 enum coff_symbol_classification classification;
00334 bfd_boolean copy;
00335
00336 bfd_coff_swap_sym_in (abfd, esym, &sym);
00337
00338 classification = bfd_coff_classify_symbol (abfd, &sym);
00339 if (classification != COFF_SYMBOL_LOCAL)
00340 {
00341 const char *name;
00342 char buf[SYMNMLEN + 1];
00343 flagword flags;
00344 asection *section;
00345 bfd_vma value;
00346 bfd_boolean addit;
00347
00348
00349
00350 name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
00351 if (name == NULL)
00352 goto error_return;
00353
00354
00355
00356 copy = default_copy;
00357 if (sym._n._n_n._n_zeroes != 0
00358 || sym._n._n_n._n_offset == 0)
00359 copy = TRUE;
00360
00361 value = sym.n_value;
00362
00363 switch (classification)
00364 {
00365 default:
00366 abort ();
00367
00368 case COFF_SYMBOL_GLOBAL:
00369 flags = BSF_EXPORT | BSF_GLOBAL;
00370 section = coff_section_from_bfd_index (abfd, sym.n_scnum);
00371 if (! obj_pe (abfd))
00372 value -= section->vma;
00373 break;
00374
00375 case COFF_SYMBOL_UNDEFINED:
00376 flags = 0;
00377 section = bfd_und_section_ptr;
00378 break;
00379
00380 case COFF_SYMBOL_COMMON:
00381 flags = BSF_GLOBAL;
00382 section = bfd_com_section_ptr;
00383 break;
00384
00385 case COFF_SYMBOL_PE_SECTION:
00386 flags = BSF_SECTION_SYM | BSF_GLOBAL;
00387 section = coff_section_from_bfd_index (abfd, sym.n_scnum);
00388 break;
00389 }
00390
00391 if (IS_WEAK_EXTERNAL (abfd, sym))
00392 flags = BSF_WEAK;
00393
00394 addit = TRUE;
00395
00396
00397
00398
00399 if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
00400 {
00401 *sym_hash = coff_link_hash_lookup (coff_hash_table (info),
00402 name, FALSE, copy, FALSE);
00403 if (*sym_hash != NULL)
00404 {
00405 if (((*sym_hash)->coff_link_hash_flags
00406 & COFF_LINK_HASH_PE_SECTION_SYMBOL) == 0
00407 && (*sym_hash)->root.type != bfd_link_hash_undefined
00408 && (*sym_hash)->root.type != bfd_link_hash_undefweak)
00409 (*_bfd_error_handler)
00410 ("Warning: symbol `%s' is both section and non-section",
00411 name);
00412
00413 addit = FALSE;
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 if (obj_pe (abfd)
00440 && (classification == COFF_SYMBOL_GLOBAL
00441 || classification == COFF_SYMBOL_PE_SECTION)
00442 && coff_section_data (abfd, section) != NULL
00443 && coff_section_data (abfd, section)->comdat != NULL
00444 && strncmp (name, "??_", 3) == 0
00445 && strcmp (name, coff_section_data (abfd, section)->comdat->name) == 0)
00446 {
00447 if (*sym_hash == NULL)
00448 *sym_hash = coff_link_hash_lookup (coff_hash_table (info),
00449 name, FALSE, copy, FALSE);
00450 if (*sym_hash != NULL
00451 && (*sym_hash)->root.type == bfd_link_hash_defined
00452 && coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat != NULL
00453 && strcmp (coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat->name,
00454 coff_section_data (abfd, section)->comdat->name) == 0)
00455 addit = FALSE;
00456 }
00457
00458 if (addit)
00459 {
00460 if (! (bfd_coff_link_add_one_symbol
00461 (info, abfd, name, flags, section, value,
00462 (const char *) NULL, copy, FALSE,
00463 (struct bfd_link_hash_entry **) sym_hash)))
00464 goto error_return;
00465 }
00466
00467 if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
00468 (*sym_hash)->coff_link_hash_flags |=
00469 COFF_LINK_HASH_PE_SECTION_SYMBOL;
00470
00471
00472
00473
00474
00475
00476 if (section == bfd_com_section_ptr
00477 && (*sym_hash)->root.type == bfd_link_hash_common
00478 && ((*sym_hash)->root.u.c.p->alignment_power
00479 > bfd_coff_default_section_alignment_power (abfd)))
00480 (*sym_hash)->root.u.c.p->alignment_power
00481 = bfd_coff_default_section_alignment_power (abfd);
00482
00483 if (info->hash->creator->flavour == bfd_get_flavour (abfd))
00484 {
00485
00486
00487
00488
00489 if (((*sym_hash)->class == C_NULL
00490 && (*sym_hash)->type == T_NULL)
00491 || sym.n_scnum != 0
00492 || (sym.n_value != 0
00493 && (*sym_hash)->root.type != bfd_link_hash_defined
00494 && (*sym_hash)->root.type != bfd_link_hash_defweak))
00495 {
00496 (*sym_hash)->class = sym.n_sclass;
00497 if (sym.n_type != T_NULL)
00498 {
00499
00500
00501
00502
00503
00504
00505 if ((*sym_hash)->type != T_NULL
00506 && (*sym_hash)->type != sym.n_type
00507 && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type)
00508 && (BTYPE ((*sym_hash)->type) == T_NULL
00509 || BTYPE (sym.n_type) == T_NULL)))
00510 (*_bfd_error_handler)
00511 (_("Warning: type of symbol `%s' changed from %d to %d in %B"),
00512 abfd, name, (*sym_hash)->type, sym.n_type);
00513
00514
00515
00516
00517 if (BTYPE (sym.n_type) != T_NULL
00518 || (*sym_hash)->type == T_NULL)
00519 (*sym_hash)->type = sym.n_type;
00520 }
00521 (*sym_hash)->auxbfd = abfd;
00522 if (sym.n_numaux != 0)
00523 {
00524 union internal_auxent *alloc;
00525 unsigned int i;
00526 bfd_byte *eaux;
00527 union internal_auxent *iaux;
00528
00529 (*sym_hash)->numaux = sym.n_numaux;
00530 alloc = ((union internal_auxent *)
00531 bfd_hash_allocate (&info->hash->table,
00532 (sym.n_numaux
00533 * sizeof (*alloc))));
00534 if (alloc == NULL)
00535 goto error_return;
00536 for (i = 0, eaux = esym + symesz, iaux = alloc;
00537 i < sym.n_numaux;
00538 i++, eaux += symesz, iaux++)
00539 bfd_coff_swap_aux_in (abfd, eaux, sym.n_type,
00540 sym.n_sclass, (int) i,
00541 sym.n_numaux, iaux);
00542 (*sym_hash)->aux = alloc;
00543 }
00544 }
00545 }
00546
00547 if (classification == COFF_SYMBOL_PE_SECTION
00548 && (*sym_hash)->numaux != 0)
00549 {
00550
00551
00552
00553
00554
00555
00556
00557 BFD_ASSERT ((*sym_hash)->numaux == 1);
00558 if (section->size == 0)
00559 section->size = (*sym_hash)->aux[0].x_scn.x_scnlen;
00560
00561
00562
00563
00564 }
00565 }
00566
00567 esym += (sym.n_numaux + 1) * symesz;
00568 sym_hash += sym.n_numaux + 1;
00569 }
00570
00571
00572
00573 if (! info->relocatable
00574 && ! info->traditional_format
00575 && info->hash->creator->flavour == bfd_get_flavour (abfd)
00576 && (info->strip != strip_all && info->strip != strip_debugger))
00577 {
00578 asection *stabstr;
00579
00580 stabstr = bfd_get_section_by_name (abfd, ".stabstr");
00581
00582 if (stabstr != NULL)
00583 {
00584 bfd_size_type string_offset = 0;
00585 asection *stab;
00586
00587 for (stab = abfd->sections; stab; stab = stab->next)
00588 if (strncmp (".stab", stab->name, 5) == 0
00589 && (!stab->name[5]
00590 || (stab->name[5] == '.' && ISDIGIT (stab->name[6]))))
00591 {
00592 struct coff_link_hash_table *table;
00593 struct coff_section_tdata *secdata
00594 = coff_section_data (abfd, stab);
00595
00596 if (secdata == NULL)
00597 {
00598 amt = sizeof (struct coff_section_tdata);
00599 stab->used_by_bfd = bfd_zalloc (abfd, amt);
00600 if (stab->used_by_bfd == NULL)
00601 goto error_return;
00602 secdata = coff_section_data (abfd, stab);
00603 }
00604
00605 table = coff_hash_table (info);
00606
00607 if (! _bfd_link_section_stabs (abfd, &table->stab_info,
00608 stab, stabstr,
00609 &secdata->stab_info,
00610 &string_offset))
00611 goto error_return;
00612 }
00613 }
00614 }
00615
00616 obj_coff_keep_syms (abfd) = keep_syms;
00617
00618 return TRUE;
00619
00620 error_return:
00621 obj_coff_keep_syms (abfd) = keep_syms;
00622 return FALSE;
00623 }
00624
00625
00626
00627 bfd_boolean
00628 _bfd_coff_final_link (bfd *abfd,
00629 struct bfd_link_info *info)
00630 {
00631 bfd_size_type symesz;
00632 struct coff_final_link_info finfo;
00633 bfd_boolean debug_merge_allocated;
00634 bfd_boolean long_section_names;
00635 asection *o;
00636 struct bfd_link_order *p;
00637 bfd_size_type max_sym_count;
00638 bfd_size_type max_lineno_count;
00639 bfd_size_type max_reloc_count;
00640 bfd_size_type max_output_reloc_count;
00641 bfd_size_type max_contents_size;
00642 file_ptr rel_filepos;
00643 unsigned int relsz;
00644 file_ptr line_filepos;
00645 unsigned int linesz;
00646 bfd *sub;
00647 bfd_byte *external_relocs = NULL;
00648 char strbuf[STRING_SIZE_SIZE];
00649 bfd_size_type amt;
00650
00651 symesz = bfd_coff_symesz (abfd);
00652
00653 finfo.info = info;
00654 finfo.output_bfd = abfd;
00655 finfo.strtab = NULL;
00656 finfo.section_info = NULL;
00657 finfo.last_file_index = -1;
00658 finfo.last_bf_index = -1;
00659 finfo.internal_syms = NULL;
00660 finfo.sec_ptrs = NULL;
00661 finfo.sym_indices = NULL;
00662 finfo.outsyms = NULL;
00663 finfo.linenos = NULL;
00664 finfo.contents = NULL;
00665 finfo.external_relocs = NULL;
00666 finfo.internal_relocs = NULL;
00667 finfo.global_to_static = FALSE;
00668 debug_merge_allocated = FALSE;
00669
00670 coff_data (abfd)->link_info = info;
00671
00672 finfo.strtab = _bfd_stringtab_init ();
00673 if (finfo.strtab == NULL)
00674 goto error_return;
00675
00676 if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
00677 goto error_return;
00678 debug_merge_allocated = TRUE;
00679
00680
00681 if (! abfd->output_has_begun)
00682 {
00683 if (! bfd_coff_compute_section_file_positions (abfd))
00684 goto error_return;
00685 }
00686
00687
00688
00689 rel_filepos = obj_relocbase (abfd);
00690 relsz = bfd_coff_relsz (abfd);
00691 max_contents_size = 0;
00692 max_lineno_count = 0;
00693 max_reloc_count = 0;
00694
00695 long_section_names = FALSE;
00696 for (o = abfd->sections; o != NULL; o = o->next)
00697 {
00698 o->reloc_count = 0;
00699 o->lineno_count = 0;
00700 for (p = o->link_order_head; p != NULL; p = p->next)
00701 {
00702 if (p->type == bfd_indirect_link_order)
00703 {
00704 asection *sec;
00705
00706 sec = p->u.indirect.section;
00707
00708
00709
00710
00711
00712 sec->linker_mark = TRUE;
00713
00714 if (info->strip == strip_none
00715 || info->strip == strip_some)
00716 o->lineno_count += sec->lineno_count;
00717
00718 if (info->relocatable)
00719 o->reloc_count += sec->reloc_count;
00720
00721 if (sec->rawsize > max_contents_size)
00722 max_contents_size = sec->rawsize;
00723 if (sec->size > max_contents_size)
00724 max_contents_size = sec->size;
00725 if (sec->lineno_count > max_lineno_count)
00726 max_lineno_count = sec->lineno_count;
00727 if (sec->reloc_count > max_reloc_count)
00728 max_reloc_count = sec->reloc_count;
00729 }
00730 else if (info->relocatable
00731 && (p->type == bfd_section_reloc_link_order
00732 || p->type == bfd_symbol_reloc_link_order))
00733 ++o->reloc_count;
00734 }
00735 if (o->reloc_count == 0)
00736 o->rel_filepos = 0;
00737 else
00738 {
00739 o->flags |= SEC_RELOC;
00740 o->rel_filepos = rel_filepos;
00741 rel_filepos += o->reloc_count * relsz;
00742
00743
00744 if (obj_pe (abfd) && o->reloc_count >= 0xffff)
00745 rel_filepos += relsz;
00746 }
00747
00748 if (bfd_coff_long_section_names (abfd)
00749 && strlen (o->name) > SCNNMLEN)
00750 {
00751
00752
00753
00754
00755
00756 if (_bfd_stringtab_add (finfo.strtab, o->name, FALSE, FALSE)
00757 == (bfd_size_type) -1)
00758 goto error_return;
00759 long_section_names = TRUE;
00760 }
00761 }
00762
00763
00764
00765 if (info->relocatable)
00766 {
00767 unsigned int i;
00768
00769
00770
00771 amt = abfd->section_count + 1;
00772 amt *= sizeof (struct coff_link_section_info);
00773 finfo.section_info = bfd_malloc (amt);
00774 if (finfo.section_info == NULL)
00775 goto error_return;
00776 for (i = 0; i <= abfd->section_count; i++)
00777 {
00778 finfo.section_info[i].relocs = NULL;
00779 finfo.section_info[i].rel_hashes = NULL;
00780 }
00781 }
00782
00783
00784
00785 line_filepos = rel_filepos;
00786 linesz = bfd_coff_linesz (abfd);
00787 max_output_reloc_count = 0;
00788 for (o = abfd->sections; o != NULL; o = o->next)
00789 {
00790 if (o->lineno_count == 0)
00791 o->line_filepos = 0;
00792 else
00793 {
00794 o->line_filepos = line_filepos;
00795 line_filepos += o->lineno_count * linesz;
00796 }
00797
00798 if (o->reloc_count != 0)
00799 {
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 BFD_ASSERT (info->relocatable);
00814 amt = o->reloc_count;
00815 amt *= sizeof (struct internal_reloc);
00816 finfo.section_info[o->target_index].relocs = bfd_malloc (amt);
00817 amt = o->reloc_count;
00818 amt *= sizeof (struct coff_link_hash_entry *);
00819 finfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt);
00820 if (finfo.section_info[o->target_index].relocs == NULL
00821 || finfo.section_info[o->target_index].rel_hashes == NULL)
00822 goto error_return;
00823
00824 if (o->reloc_count > max_output_reloc_count)
00825 max_output_reloc_count = o->reloc_count;
00826 }
00827
00828
00829
00830 o->reloc_count = 0;
00831 o->lineno_count = 0;
00832 }
00833
00834 obj_sym_filepos (abfd) = line_filepos;
00835
00836
00837
00838
00839 max_sym_count = 0;
00840 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
00841 {
00842 size_t sz;
00843
00844 sub->output_has_begun = FALSE;
00845 sz = obj_raw_syment_count (sub);
00846 if (sz > max_sym_count)
00847 max_sym_count = sz;
00848 }
00849
00850
00851 amt = max_sym_count * sizeof (struct internal_syment);
00852 finfo.internal_syms = bfd_malloc (amt);
00853 amt = max_sym_count * sizeof (asection *);
00854 finfo.sec_ptrs = bfd_malloc (amt);
00855 amt = max_sym_count * sizeof (long);
00856 finfo.sym_indices = bfd_malloc (amt);
00857 finfo.outsyms = bfd_malloc ((max_sym_count + 1) * symesz);
00858 amt = max_lineno_count * bfd_coff_linesz (abfd);
00859 finfo.linenos = bfd_malloc (amt);
00860 finfo.contents = bfd_malloc (max_contents_size);
00861 amt = max_reloc_count * relsz;
00862 finfo.external_relocs = bfd_malloc (amt);
00863 if (! info->relocatable)
00864 {
00865 amt = max_reloc_count * sizeof (struct internal_reloc);
00866 finfo.internal_relocs = bfd_malloc (amt);
00867 }
00868 if ((finfo.internal_syms == NULL && max_sym_count > 0)
00869 || (finfo.sec_ptrs == NULL && max_sym_count > 0)
00870 || (finfo.sym_indices == NULL && max_sym_count > 0)
00871 || finfo.outsyms == NULL
00872 || (finfo.linenos == NULL && max_lineno_count > 0)
00873 || (finfo.contents == NULL && max_contents_size > 0)
00874 || (finfo.external_relocs == NULL && max_reloc_count > 0)
00875 || (! info->relocatable
00876 && finfo.internal_relocs == NULL
00877 && max_reloc_count > 0))
00878 goto error_return;
00879
00880
00881
00882
00883
00884
00885 obj_raw_syment_count (abfd) = 0;
00886
00887 if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
00888 {
00889 if (! bfd_coff_start_final_link (abfd, info))
00890 goto error_return;
00891 }
00892
00893 for (o = abfd->sections; o != NULL; o = o->next)
00894 {
00895 for (p = o->link_order_head; p != NULL; p = p->next)
00896 {
00897 if (p->type == bfd_indirect_link_order
00898 && bfd_family_coff (p->u.indirect.section->owner))
00899 {
00900 sub = p->u.indirect.section->owner;
00901 if (! bfd_coff_link_output_has_begun (sub, & finfo))
00902 {
00903 if (! _bfd_coff_link_input_bfd (&finfo, sub))
00904 goto error_return;
00905 sub->output_has_begun = TRUE;
00906 }
00907 }
00908 else if (p->type == bfd_section_reloc_link_order
00909 || p->type == bfd_symbol_reloc_link_order)
00910 {
00911 if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
00912 goto error_return;
00913 }
00914 else
00915 {
00916 if (! _bfd_default_link_order (abfd, info, o, p))
00917 goto error_return;
00918 }
00919 }
00920 }
00921
00922 if (! bfd_coff_final_link_postscript (abfd, & finfo))
00923 goto error_return;
00924
00925
00926
00927 coff_debug_merge_hash_table_free (&finfo.debug_merge);
00928 debug_merge_allocated = FALSE;
00929
00930 if (finfo.internal_syms != NULL)
00931 {
00932 free (finfo.internal_syms);
00933 finfo.internal_syms = NULL;
00934 }
00935 if (finfo.sec_ptrs != NULL)
00936 {
00937 free (finfo.sec_ptrs);
00938 finfo.sec_ptrs = NULL;
00939 }
00940 if (finfo.sym_indices != NULL)
00941 {
00942 free (finfo.sym_indices);
00943 finfo.sym_indices = NULL;
00944 }
00945 if (finfo.linenos != NULL)
00946 {
00947 free (finfo.linenos);
00948 finfo.linenos = NULL;
00949 }
00950 if (finfo.contents != NULL)
00951 {
00952 free (finfo.contents);
00953 finfo.contents = NULL;
00954 }
00955 if (finfo.external_relocs != NULL)
00956 {
00957 free (finfo.external_relocs);
00958 finfo.external_relocs = NULL;
00959 }
00960 if (finfo.internal_relocs != NULL)
00961 {
00962 free (finfo.internal_relocs);
00963 finfo.internal_relocs = NULL;
00964 }
00965
00966
00967
00968
00969 if (finfo.last_file_index != -1
00970 && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
00971 {
00972 file_ptr pos;
00973
00974 finfo.last_file.n_value = obj_raw_syment_count (abfd);
00975 bfd_coff_swap_sym_out (abfd, &finfo.last_file,
00976 finfo.outsyms);
00977
00978 pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz;
00979 if (bfd_seek (abfd, pos, SEEK_SET) != 0
00980 || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz)
00981 return FALSE;
00982 }
00983
00984
00985
00986
00987 if (info->task_link)
00988 {
00989 finfo.failed = FALSE;
00990 coff_link_hash_traverse (coff_hash_table (info),
00991 _bfd_coff_write_task_globals, &finfo);
00992 if (finfo.failed)
00993 goto error_return;
00994 }
00995
00996
00997 finfo.failed = FALSE;
00998 coff_link_hash_traverse (coff_hash_table (info),
00999 _bfd_coff_write_global_sym, &finfo);
01000 if (finfo.failed)
01001 goto error_return;
01002
01003
01004 if (finfo.outsyms != NULL)
01005 {
01006 free (finfo.outsyms);
01007 finfo.outsyms = NULL;
01008 }
01009
01010 if (info->relocatable && max_output_reloc_count > 0)
01011 {
01012
01013
01014
01015 amt = max_output_reloc_count * relsz;
01016 external_relocs = bfd_malloc (amt);
01017 if (external_relocs == NULL)
01018 goto error_return;
01019
01020 for (o = abfd->sections; o != NULL; o = o->next)
01021 {
01022 struct internal_reloc *irel;
01023 struct internal_reloc *irelend;
01024 struct coff_link_hash_entry **rel_hash;
01025 bfd_byte *erel;
01026
01027 if (o->reloc_count == 0)
01028 continue;
01029
01030 irel = finfo.section_info[o->target_index].relocs;
01031 irelend = irel + o->reloc_count;
01032 rel_hash = finfo.section_info[o->target_index].rel_hashes;
01033 erel = external_relocs;
01034 for (; irel < irelend; irel++, rel_hash++, erel += relsz)
01035 {
01036 if (*rel_hash != NULL)
01037 {
01038 BFD_ASSERT ((*rel_hash)->indx >= 0);
01039 irel->r_symndx = (*rel_hash)->indx;
01040 }
01041 bfd_coff_swap_reloc_out (abfd, irel, erel);
01042 }
01043
01044 if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
01045 goto error_return;
01046 if (obj_pe (abfd) && o->reloc_count >= 0xffff)
01047 {
01048
01049
01050
01051 struct internal_reloc incount;
01052 bfd_byte *excount = (bfd_byte *)bfd_malloc (relsz);
01053
01054 memset (&incount, 0, sizeof (incount));
01055 incount.r_vaddr = o->reloc_count + 1;
01056 bfd_coff_swap_reloc_out (abfd, (PTR) &incount, (PTR) excount);
01057 if (bfd_bwrite (excount, relsz, abfd) != relsz)
01058
01059 goto error_return;
01060 free (excount);
01061 }
01062 if (bfd_bwrite (external_relocs,
01063 (bfd_size_type) relsz * o->reloc_count, abfd)
01064 != (bfd_size_type) relsz * o->reloc_count)
01065 goto error_return;
01066 }
01067
01068 free (external_relocs);
01069 external_relocs = NULL;
01070 }
01071
01072
01073 if (finfo.section_info != NULL)
01074 {
01075 unsigned int i;
01076
01077 for (i = 0; i < abfd->section_count; i++)
01078 {
01079 if (finfo.section_info[i].relocs != NULL)
01080 free (finfo.section_info[i].relocs);
01081 if (finfo.section_info[i].rel_hashes != NULL)
01082 free (finfo.section_info[i].rel_hashes);
01083 }
01084 free (finfo.section_info);
01085 finfo.section_info = NULL;
01086 }
01087
01088
01089 if (coff_hash_table (info)->stab_info.stabstr != NULL)
01090 {
01091 if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
01092 return FALSE;
01093 }
01094
01095
01096 if (obj_raw_syment_count (abfd) != 0 || long_section_names)
01097 {
01098 file_ptr pos;
01099
01100 pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz;
01101 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
01102 return FALSE;
01103
01104 #if STRING_SIZE_SIZE == 4
01105 H_PUT_32 (abfd,
01106 _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
01107 strbuf);
01108 #else
01109 #error Change H_PUT_32 above
01110 #endif
01111
01112 if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd)
01113 != STRING_SIZE_SIZE)
01114 return FALSE;
01115
01116 if (! _bfd_stringtab_emit (abfd, finfo.strtab))
01117 return FALSE;
01118
01119 obj_coff_strings_written (abfd) = TRUE;
01120 }
01121
01122 _bfd_stringtab_free (finfo.strtab);
01123
01124
01125
01126 bfd_get_symcount (abfd) = 0;
01127
01128 return TRUE;
01129
01130 error_return:
01131 if (debug_merge_allocated)
01132 coff_debug_merge_hash_table_free (&finfo.debug_merge);
01133 if (finfo.strtab != NULL)
01134 _bfd_stringtab_free (finfo.strtab);
01135 if (finfo.section_info != NULL)
01136 {
01137 unsigned int i;
01138
01139 for (i = 0; i < abfd->section_count; i++)
01140 {
01141 if (finfo.section_info[i].relocs != NULL)
01142 free (finfo.section_info[i].relocs);
01143 if (finfo.section_info[i].rel_hashes != NULL)
01144 free (finfo.section_info[i].rel_hashes);
01145 }
01146 free (finfo.section_info);
01147 }
01148 if (finfo.internal_syms != NULL)
01149 free (finfo.internal_syms);
01150 if (finfo.sec_ptrs != NULL)
01151 free (finfo.sec_ptrs);
01152 if (finfo.sym_indices != NULL)
01153 free (finfo.sym_indices);
01154 if (finfo.outsyms != NULL)
01155 free (finfo.outsyms);
01156 if (finfo.linenos != NULL)
01157 free (finfo.linenos);
01158 if (finfo.contents != NULL)
01159 free (finfo.contents);
01160 if (finfo.external_relocs != NULL)
01161 free (finfo.external_relocs);
01162 if (finfo.internal_relocs != NULL)
01163 free (finfo.internal_relocs);
01164 if (external_relocs != NULL)
01165 free (external_relocs);
01166 return FALSE;
01167 }
01168
01169
01170
01171 static char *
01172 dores_com (char *ptr, bfd *output_bfd, int heap)
01173 {
01174 if (coff_data(output_bfd)->pe)
01175 {
01176 int val = strtoul (ptr, &ptr, 0);
01177
01178 if (heap)
01179 pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve = val;
01180 else
01181 pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve = val;
01182
01183 if (ptr[0] == ',')
01184 {
01185 val = strtoul (ptr+1, &ptr, 0);
01186 if (heap)
01187 pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit = val;
01188 else
01189 pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit = val;
01190 }
01191 }
01192 return ptr;
01193 }
01194
01195 static char *
01196 get_name (char *ptr, char **dst)
01197 {
01198 while (*ptr == ' ')
01199 ptr++;
01200 *dst = ptr;
01201 while (*ptr && *ptr != ' ')
01202 ptr++;
01203 *ptr = 0;
01204 return ptr+1;
01205 }
01206
01207
01208
01209 static int
01210 process_embedded_commands (bfd *output_bfd,
01211 struct bfd_link_info *info ATTRIBUTE_UNUSED,
01212 bfd *abfd)
01213 {
01214 asection *sec = bfd_get_section_by_name (abfd, ".drectve");
01215 char *s;
01216 char *e;
01217 bfd_byte *copy;
01218
01219 if (!sec)
01220 return 1;
01221
01222 if (!bfd_malloc_and_get_section (abfd, sec, ©))
01223 {
01224 if (copy != NULL)
01225 free (copy);
01226 return 0;
01227 }
01228 e = (char *) copy + sec->size;
01229
01230 for (s = (char *) copy; s < e ; )
01231 {
01232 if (s[0] != '-')
01233 {
01234 s++;
01235 continue;
01236 }
01237 if (strncmp (s, "-attr", 5) == 0)
01238 {
01239 char *name;
01240 char *attribs;
01241 asection *asec;
01242 int loop = 1;
01243 int had_write = 0;
01244 int had_read = 0;
01245 int had_exec= 0;
01246 int had_shared= 0;
01247
01248 s += 5;
01249 s = get_name (s, &name);
01250 s = get_name (s, &attribs);
01251
01252 while (loop)
01253 {
01254 switch (*attribs++)
01255 {
01256 case 'W':
01257 had_write = 1;
01258 break;
01259 case 'R':
01260 had_read = 1;
01261 break;
01262 case 'S':
01263 had_shared = 1;
01264 break;
01265 case 'X':
01266 had_exec = 1;
01267 break;
01268 default:
01269 loop = 0;
01270 }
01271 }
01272 asec = bfd_get_section_by_name (abfd, name);
01273 if (asec)
01274 {
01275 if (had_exec)
01276 asec->flags |= SEC_CODE;
01277 if (!had_write)
01278 asec->flags |= SEC_READONLY;
01279 }
01280 }
01281 else if (strncmp (s,"-heap", 5) == 0)
01282 s = dores_com (s+5, output_bfd, 1);
01283
01284 else if (strncmp (s,"-stack", 6) == 0)
01285 s = dores_com (s+6, output_bfd, 0);
01286
01287 else
01288 s++;
01289 }
01290 free (copy);
01291 return 1;
01292 }
01293
01294
01295
01296
01297
01298
01299 static void
01300 mark_relocs (struct coff_final_link_info *finfo, bfd *input_bfd)
01301 {
01302 asection * a;
01303
01304 if ((bfd_get_file_flags (input_bfd) & HAS_SYMS) == 0)
01305 return;
01306
01307 for (a = input_bfd->sections; a != (asection *) NULL; a = a->next)
01308 {
01309 struct internal_reloc * internal_relocs;
01310 struct internal_reloc * irel;
01311 struct internal_reloc * irelend;
01312
01313 if ((a->flags & SEC_RELOC) == 0 || a->reloc_count < 1)
01314 continue;
01315
01316 if (a->output_section == bfd_abs_section_ptr)
01317 continue;
01318
01319
01320 internal_relocs = _bfd_coff_read_internal_relocs
01321 (input_bfd, a, FALSE,
01322 finfo->external_relocs,
01323 finfo->info->relocatable,
01324 (finfo->info->relocatable
01325 ? (finfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
01326 : finfo->internal_relocs)
01327 );
01328
01329 if (internal_relocs == NULL)
01330 continue;
01331
01332 irel = internal_relocs;
01333 irelend = irel + a->reloc_count;
01334
01335
01336
01337
01338
01339 for (; irel < irelend; irel++)
01340 finfo->sym_indices[ irel->r_symndx ] = -1;
01341 }
01342 }
01343
01344
01345
01346
01347 bfd_boolean
01348 _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd)
01349 {
01350 unsigned int n_tmask = coff_data (input_bfd)->local_n_tmask;
01351 unsigned int n_btshft = coff_data (input_bfd)->local_n_btshft;
01352 bfd_boolean (*adjust_symndx)
01353 (bfd *, struct bfd_link_info *, bfd *, asection *,
01354 struct internal_reloc *, bfd_boolean *);
01355 bfd *output_bfd;
01356 const char *strings;
01357 bfd_size_type syment_base;
01358 bfd_boolean copy, hash;
01359 bfd_size_type isymesz;
01360 bfd_size_type osymesz;
01361 bfd_size_type linesz;
01362 bfd_byte *esym;
01363 bfd_byte *esym_end;
01364 struct internal_syment *isymp;
01365 asection **secpp;
01366 long *indexp;
01367 unsigned long output_index;
01368 bfd_byte *outsym;
01369 struct coff_link_hash_entry **sym_hash;
01370 asection *o;
01371
01372
01373
01374 output_bfd = finfo->output_bfd;
01375 strings = NULL;
01376 syment_base = obj_raw_syment_count (output_bfd);
01377 isymesz = bfd_coff_symesz (input_bfd);
01378 osymesz = bfd_coff_symesz (output_bfd);
01379 linesz = bfd_coff_linesz (input_bfd);
01380 BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd));
01381
01382 copy = FALSE;
01383 if (! finfo->info->keep_memory)
01384 copy = TRUE;
01385 hash = TRUE;
01386 if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
01387 hash = FALSE;
01388
01389 if (! _bfd_coff_get_external_symbols (input_bfd))
01390 return FALSE;
01391
01392 esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
01393 esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
01394 isymp = finfo->internal_syms;
01395 secpp = finfo->sec_ptrs;
01396 indexp = finfo->sym_indices;
01397 output_index = syment_base;
01398 outsym = finfo->outsyms;
01399
01400 if (coff_data (output_bfd)->pe
01401 && ! process_embedded_commands (output_bfd, finfo->info, input_bfd))
01402 return FALSE;
01403
01404
01405
01406
01407 if (( finfo->info->strip != strip_none
01408 || finfo->info->discard != discard_none)
01409 && finfo->info->relocatable)
01410 {
01411
01412 memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
01413
01414 mark_relocs (finfo, input_bfd);
01415 }
01416
01417 while (esym < esym_end)
01418 {
01419 struct internal_syment isym;
01420 enum coff_symbol_classification classification;
01421 bfd_boolean skip;
01422 bfd_boolean global;
01423 bfd_boolean dont_skip_symbol;
01424 int add;
01425
01426 bfd_coff_swap_sym_in (input_bfd, esym, isymp);
01427
01428
01429
01430
01431
01432 isym = *isymp;
01433
01434 classification = bfd_coff_classify_symbol (input_bfd, &isym);
01435 switch (classification)
01436 {
01437 default:
01438 abort ();
01439 case COFF_SYMBOL_GLOBAL:
01440 case COFF_SYMBOL_PE_SECTION:
01441 case COFF_SYMBOL_LOCAL:
01442 *secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
01443 break;
01444 case COFF_SYMBOL_COMMON:
01445 *secpp = bfd_com_section_ptr;
01446 break;
01447 case COFF_SYMBOL_UNDEFINED:
01448 *secpp = bfd_und_section_ptr;
01449 break;
01450 }
01451
01452
01453
01454 if ((finfo->info->strip != strip_none
01455 || finfo->info->discard != discard_none)
01456 && finfo->info->relocatable)
01457 dont_skip_symbol = *indexp;
01458 else
01459 dont_skip_symbol = FALSE;
01460
01461 *indexp = -1;
01462
01463 skip = FALSE;
01464 global = FALSE;
01465 add = 1 + isym.n_numaux;
01466
01467
01468 if (finfo->info->strip == strip_all && ! dont_skip_symbol)
01469 skip = TRUE;
01470
01471 if (! skip)
01472 {
01473 switch (classification)
01474 {
01475 default:
01476 abort ();
01477 case COFF_SYMBOL_GLOBAL:
01478 case COFF_SYMBOL_COMMON:
01479 case COFF_SYMBOL_PE_SECTION:
01480
01481
01482
01483
01484 global = TRUE;
01485 if (! ISFCN (isym.n_type))
01486 skip = TRUE;
01487 break;
01488
01489 case COFF_SYMBOL_UNDEFINED:
01490
01491 global = TRUE;
01492 skip = TRUE;
01493 break;
01494
01495 case COFF_SYMBOL_LOCAL:
01496
01497
01498 if (finfo->info->discard == discard_all && ! dont_skip_symbol)
01499 skip = TRUE;
01500 break;
01501 }
01502 }
01503
01504 #ifndef COFF_WITH_PE
01505
01506
01507 if (!skip
01508 && dont_skip_symbol == 0
01509 && isym.n_sclass == C_STAT
01510 && isym.n_type == T_NULL
01511 && isym.n_numaux > 0
01512 && (*secpp)->output_section == bfd_abs_section_ptr)
01513 skip = TRUE;
01514 #endif
01515
01516
01517
01518
01519
01520 if (! skip
01521 && finfo->info->strip == strip_debugger
01522 && ! dont_skip_symbol
01523 && (isym.n_scnum == N_DEBUG
01524 || (isym.n_scnum == N_ABS
01525 && (isym.n_sclass == C_AUTO
01526 || isym.n_sclass == C_REG
01527 || isym.n_sclass == C_MOS
01528 || isym.n_sclass == C_MOE
01529 || isym.n_sclass == C_MOU
01530 || isym.n_sclass == C_ARG
01531 || isym.n_sclass == C_REGPARM
01532 || isym.n_sclass == C_FIELD
01533 || isym.n_sclass == C_EOS))))
01534 skip = TRUE;
01535
01536
01537
01538 if (! skip
01539 && (finfo->info->strip == strip_some
01540 || finfo->info->discard == discard_l))
01541 {
01542 const char *name;
01543 char buf[SYMNMLEN + 1];
01544
01545 name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
01546 if (name == NULL)
01547 return FALSE;
01548
01549 if (! dont_skip_symbol
01550 && ((finfo->info->strip == strip_some
01551 && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE,
01552 FALSE) == NULL))
01553 || (! global
01554 && finfo->info->discard == discard_l
01555 && bfd_is_local_label_name (input_bfd, name))))
01556 skip = TRUE;
01557 }
01558
01559
01560
01561 if (! skip
01562 && (finfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0
01563 && (isym.n_sclass == C_ENTAG
01564 || isym.n_sclass == C_STRTAG
01565 || isym.n_sclass == C_UNTAG)
01566 && isym.n_numaux == 1)
01567 {
01568 const char *name;
01569 char buf[SYMNMLEN + 1];
01570 struct coff_debug_merge_hash_entry *mh;
01571 struct coff_debug_merge_type *mt;
01572 union internal_auxent aux;
01573 struct coff_debug_merge_element **epp;
01574 bfd_byte *esl, *eslend;
01575 struct internal_syment *islp;
01576 bfd_size_type amt;
01577
01578 name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
01579 if (name == NULL)
01580 return FALSE;
01581
01582
01583
01584 if (*name == '~' || *name == '.' || *name == '$'
01585 || (*name == bfd_get_symbol_leading_char (input_bfd)
01586 && (name[1] == '~' || name[1] == '.' || name[1] == '$')))
01587 name = "";
01588
01589 mh = coff_debug_merge_hash_lookup (&finfo->debug_merge, name,
01590 TRUE, TRUE);
01591 if (mh == NULL)
01592 return FALSE;
01593
01594
01595
01596
01597 amt = sizeof (struct coff_debug_merge_type);
01598 mt = bfd_alloc (input_bfd, amt);
01599 if (mt == NULL)
01600 return FALSE;
01601 mt->class = isym.n_sclass;
01602
01603
01604
01605 bfd_coff_swap_aux_in (input_bfd, (esym + isymesz),
01606 isym.n_type, isym.n_sclass, 0, isym.n_numaux,
01607 &aux);
01608
01609
01610 epp = &mt->elements;
01611 mt->elements = NULL;
01612 islp = isymp + 2;
01613 esl = esym + 2 * isymesz;
01614 eslend = ((bfd_byte *) obj_coff_external_syms (input_bfd)
01615 + aux.x_sym.x_fcnary.x_fcn.x_endndx.l * isymesz);
01616 while (esl < eslend)
01617 {
01618 const char *elename;
01619 char elebuf[SYMNMLEN + 1];
01620 char *name_copy;
01621
01622 bfd_coff_swap_sym_in (input_bfd, esl, islp);
01623
01624 amt = sizeof (struct coff_debug_merge_element);
01625 *epp = bfd_alloc (input_bfd, amt);
01626 if (*epp == NULL)
01627 return FALSE;
01628
01629 elename = _bfd_coff_internal_syment_name (input_bfd, islp,
01630 elebuf);
01631 if (elename == NULL)
01632 return FALSE;
01633
01634 amt = strlen (elename) + 1;
01635 name_copy = bfd_alloc (input_bfd, amt);
01636 if (name_copy == NULL)
01637 return FALSE;
01638 strcpy (name_copy, elename);
01639
01640 (*epp)->name = name_copy;
01641 (*epp)->type = islp->n_type;
01642 (*epp)->tagndx = 0;
01643 if (islp->n_numaux >= 1
01644 && islp->n_type != T_NULL
01645 && islp->n_sclass != C_EOS)
01646 {
01647 union internal_auxent eleaux;
01648 long indx;
01649
01650 bfd_coff_swap_aux_in (input_bfd, (esl + isymesz),
01651 islp->n_type, islp->n_sclass, 0,
01652 islp->n_numaux, &eleaux);
01653 indx = eleaux.x_sym.x_tagndx.l;
01654
01655
01656
01657
01658
01659 if (indx > 0
01660 && (indx
01661 < ((esym -
01662 (bfd_byte *) obj_coff_external_syms (input_bfd))
01663 / (long) isymesz)))
01664 {
01665 (*epp)->tagndx = finfo->sym_indices[indx];
01666 if ((*epp)->tagndx < 0)
01667 (*epp)->tagndx = 0;
01668 }
01669 }
01670 epp = &(*epp)->next;
01671 *epp = NULL;
01672
01673 esl += (islp->n_numaux + 1) * isymesz;
01674 islp += islp->n_numaux + 1;
01675 }
01676
01677
01678
01679
01680 if (mt->elements == NULL)
01681 bfd_release (input_bfd, mt);
01682 else
01683 {
01684 struct coff_debug_merge_type *mtl;
01685
01686 for (mtl = mh->types; mtl != NULL; mtl = mtl->next)
01687 {
01688 struct coff_debug_merge_element *me, *mel;
01689
01690 if (mtl->class != mt->class)
01691 continue;
01692
01693 for (me = mt->elements, mel = mtl->elements;
01694 me != NULL && mel != NULL;
01695 me = me->next, mel = mel->next)
01696 {
01697 if (strcmp (me->name, mel->name) != 0
01698 || me->type != mel->type
01699 || me->tagndx != mel->tagndx)
01700 break;
01701 }
01702
01703 if (me == NULL && mel == NULL)
01704 break;
01705 }
01706
01707 if (mtl == NULL || (bfd_size_type) mtl->indx >= syment_base)
01708 {
01709
01710 mt->indx = output_index;
01711 mt->next = mh->types;
01712 mh->types = mt;
01713 }
01714 else
01715 {
01716
01717 bfd_release (input_bfd, mt);
01718 *indexp = mtl->indx;
01719 add = (eslend - esym) / isymesz;
01720 skip = TRUE;
01721 }
01722 }
01723 }
01724
01725
01726 if (! skip)
01727 {
01728
01729
01730 if (isym._n._n_n._n_zeroes == 0
01731 && isym._n._n_n._n_offset != 0)
01732 {
01733 const char *name;
01734 bfd_size_type indx;
01735
01736
01737
01738
01739
01740
01741 name = _bfd_coff_internal_syment_name (input_bfd, &isym, NULL);
01742 if (name == NULL)
01743 return FALSE;
01744 indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy);
01745 if (indx == (bfd_size_type) -1)
01746 return FALSE;
01747 isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
01748 }
01749
01750 switch (isym.n_sclass)
01751 {
01752 case C_AUTO:
01753 case C_MOS:
01754 case C_EOS:
01755 case C_MOE:
01756 case C_MOU:
01757 case C_UNTAG:
01758 case C_STRTAG:
01759 case C_ENTAG:
01760 case C_TPDEF:
01761 case C_ARG:
01762 case C_USTATIC:
01763 case C_REG:
01764 case C_REGPARM:
01765 case C_FIELD:
01766
01767 break;
01768
01769 case C_FCN:
01770 if (obj_pe (input_bfd)
01771 && strcmp (isym.n_name, ".bf") != 0
01772 && isym.n_scnum > 0)
01773 {
01774
01775
01776
01777
01778 isym.n_scnum = (*secpp)->output_section->target_index;
01779 break;
01780 }
01781
01782 default:
01783 case C_LABEL:
01784 case C_EXTDEF:
01785 case C_BLOCK:
01786 case C_EFCN:
01787 case C_NULL:
01788 case C_EXT:
01789 case C_STAT:
01790 case C_SECTION:
01791 case C_NT_WEAK:
01792
01793 if (isym.n_scnum > 0)
01794 {
01795 isym.n_scnum = (*secpp)->output_section->target_index;
01796 isym.n_value += (*secpp)->output_offset;
01797 if (! obj_pe (input_bfd))
01798 isym.n_value -= (*secpp)->vma;
01799 if (! obj_pe (finfo->output_bfd))
01800 isym.n_value += (*secpp)->output_section->vma;
01801 }
01802 break;
01803
01804 case C_FILE:
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814 if (finfo->last_file_index != -1
01815 && finfo->last_file.n_value != (bfd_vma) output_index)
01816 {
01817
01818
01819 finfo->last_file.n_value = output_index;
01820 if ((bfd_size_type) finfo->last_file_index >= syment_base)
01821 {
01822
01823 bfd_coff_swap_sym_out (output_bfd,
01824 &finfo->last_file,
01825 (finfo->outsyms
01826 + ((finfo->last_file_index
01827 - syment_base)
01828 * osymesz)));
01829 }
01830 else
01831 {
01832 file_ptr pos;
01833
01834
01835
01836
01837 bfd_coff_swap_sym_out (output_bfd,
01838 &finfo->last_file, outsym);
01839 pos = obj_sym_filepos (output_bfd);
01840 pos += finfo->last_file_index * osymesz;
01841 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
01842 || bfd_bwrite (outsym, osymesz, output_bfd) != osymesz)
01843 return FALSE;
01844 }
01845 }
01846
01847 finfo->last_file_index = output_index;
01848 finfo->last_file = isym;
01849 break;
01850 }
01851
01852
01853
01854 if (finfo->info->task_link && IS_EXTERNAL (input_bfd, isym))
01855 isym.n_sclass = C_STAT;
01856
01857
01858 bfd_coff_swap_sym_out (output_bfd, &isym, outsym);
01859
01860 *indexp = output_index;
01861
01862 if (global)
01863 {
01864 long indx;
01865 struct coff_link_hash_entry *h;
01866
01867 indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd))
01868 / isymesz);
01869 h = obj_coff_sym_hashes (input_bfd)[indx];
01870 if (h == NULL)
01871 {
01872
01873
01874 bfd_set_error (bfd_error_bad_value);
01875 return FALSE;
01876 }
01877 h->indx = output_index;
01878 }
01879
01880 output_index += add;
01881 outsym += add * osymesz;
01882 }
01883
01884 esym += add * isymesz;
01885 isymp += add;
01886 ++secpp;
01887 ++indexp;
01888 for (--add; add > 0; --add)
01889 {
01890 *secpp++ = NULL;
01891 *indexp++ = -1;
01892 }
01893 }
01894
01895
01896
01897
01898 esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
01899 esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
01900 isymp = finfo->internal_syms;
01901 indexp = finfo->sym_indices;
01902 sym_hash = obj_coff_sym_hashes (input_bfd);
01903 outsym = finfo->outsyms;
01904
01905 while (esym < esym_end)
01906 {
01907 int add;
01908
01909 add = 1 + isymp->n_numaux;
01910
01911 if ((*indexp < 0
01912 || (bfd_size_type) *indexp < syment_base)
01913 && (*sym_hash == NULL
01914 || (*sym_hash)->auxbfd != input_bfd))
01915 esym += add * isymesz;
01916 else
01917 {
01918 struct coff_link_hash_entry *h;
01919 int i;
01920
01921 h = NULL;
01922 if (*indexp < 0)
01923 {
01924 h = *sym_hash;
01925
01926
01927
01928
01929 BFD_ASSERT (isymp->n_numaux == 0
01930 || h->numaux == isymp->n_numaux);
01931 }
01932
01933 esym += isymesz;
01934
01935 if (h == NULL)
01936 outsym += osymesz;
01937
01938
01939
01940 for (i = 0; i < isymp->n_numaux && esym < esym_end; i++)
01941 {
01942 union internal_auxent aux;
01943 union internal_auxent *auxp;
01944
01945 if (h != NULL)
01946 auxp = h->aux + i;
01947 else
01948 {
01949 bfd_coff_swap_aux_in (input_bfd, esym, isymp->n_type,
01950 isymp->n_sclass, i, isymp->n_numaux, &aux);
01951 auxp = &aux;
01952 }
01953
01954 if (isymp->n_sclass == C_FILE)
01955 {
01956
01957
01958 if (auxp->x_file.x_n.x_zeroes == 0
01959 && auxp->x_file.x_n.x_offset != 0)
01960 {
01961 const char *filename;
01962 bfd_size_type indx;
01963
01964 BFD_ASSERT (auxp->x_file.x_n.x_offset
01965 >= STRING_SIZE_SIZE);
01966 if (strings == NULL)
01967 {
01968 strings = _bfd_coff_read_string_table (input_bfd);
01969 if (strings == NULL)
01970 return FALSE;
01971 }
01972 filename = strings + auxp->x_file.x_n.x_offset;
01973 indx = _bfd_stringtab_add (finfo->strtab, filename,
01974 hash, copy);
01975 if (indx == (bfd_size_type) -1)
01976 return FALSE;
01977 auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
01978 }
01979 }
01980 else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
01981 && isymp->n_sclass != C_NT_WEAK)
01982 {
01983 unsigned long indx;
01984
01985 if (ISFCN (isymp->n_type)
01986 || ISTAG (isymp->n_sclass)
01987 || isymp->n_sclass == C_BLOCK
01988 || isymp->n_sclass == C_FCN)
01989 {
01990 indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l;
01991 if (indx > 0
01992 && indx < obj_raw_syment_count (input_bfd))
01993 {
01994
01995
01996
01997
01998 while ((finfo->sym_indices[indx] < 0
01999 || ((bfd_size_type) finfo->sym_indices[indx]
02000 < syment_base))
02001 && indx < obj_raw_syment_count (input_bfd))
02002 ++indx;
02003 if (indx >= obj_raw_syment_count (input_bfd))
02004 indx = output_index;
02005 else
02006 indx = finfo->sym_indices[indx];
02007 auxp->x_sym.x_fcnary.x_fcn.x_endndx.l = indx;
02008 }
02009 }
02010
02011 indx = auxp->x_sym.x_tagndx.l;
02012 if (indx > 0 && indx < obj_raw_syment_count (input_bfd))
02013 {
02014 long symindx;
02015
02016 symindx = finfo->sym_indices[indx];
02017 if (symindx < 0)
02018 auxp->x_sym.x_tagndx.l = 0;
02019 else
02020 auxp->x_sym.x_tagndx.l = symindx;
02021 }
02022
02023
02024
02025
02026 if (i == 0
02027 && h == NULL
02028 && isymp->n_sclass == C_FCN
02029 && (isymp->_n._n_n._n_zeroes != 0
02030 || isymp->_n._n_n._n_offset == 0)
02031 && isymp->_n._n_name[0] == '.'
02032 && isymp->_n._n_name[1] == 'b'
02033 && isymp->_n._n_name[2] == 'f'
02034 && isymp->_n._n_name[3] == '\0')
02035 {
02036 if (finfo->last_bf_index != -1)
02037 {
02038 finfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.l =
02039 *indexp;
02040
02041 if ((bfd_size_type) finfo->last_bf_index
02042 >= syment_base)
02043 {
02044 void *auxout;
02045
02046
02047
02048
02049
02050 auxout = (finfo->outsyms
02051 + ((finfo->last_bf_index
02052 - syment_base)
02053 * osymesz));
02054
02055 bfd_coff_swap_aux_out (output_bfd,
02056 &finfo->last_bf,
02057 isymp->n_type,
02058 isymp->n_sclass,
02059 0, isymp->n_numaux,
02060 auxout);
02061 }
02062 else
02063 {
02064 file_ptr pos;
02065
02066
02067
02068
02069
02070
02071 bfd_coff_swap_aux_out (output_bfd,
02072 &finfo->last_bf,
02073 isymp->n_type,
02074 isymp->n_sclass,
02075 0, isymp->n_numaux,
02076 outsym);
02077 pos = obj_sym_filepos (output_bfd);
02078 pos += finfo->last_bf_index * osymesz;
02079 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
02080 || (bfd_bwrite (outsym, osymesz, output_bfd)
02081 != osymesz))
02082 return FALSE;
02083 }
02084 }
02085
02086 if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.l != 0)
02087 finfo->last_bf_index = -1;
02088 else
02089 {
02090
02091
02092
02093 finfo->last_bf = *auxp;
02094 finfo->last_bf_index = (((outsym - finfo->outsyms)
02095 / osymesz)
02096 + syment_base);
02097 }
02098 }
02099 }
02100
02101 if (h == NULL)
02102 {
02103 bfd_coff_swap_aux_out (output_bfd, auxp, isymp->n_type,
02104 isymp->n_sclass, i, isymp->n_numaux,
02105 outsym);
02106 outsym += osymesz;
02107 }
02108
02109 esym += isymesz;
02110 }
02111 }
02112
02113 indexp += add;
02114 isymp += add;
02115 sym_hash += add;
02116 }
02117
02118
02119 if (finfo->info->strip == strip_none
02120 || finfo->info->strip == strip_some)
02121 {
02122 for (o = input_bfd->sections; o != NULL; o = o->next)
02123 {
02124 bfd_vma offset;
02125 bfd_byte *eline;
02126 bfd_byte *elineend;
02127 bfd_byte *oeline;
02128 bfd_boolean skipping;
02129 file_ptr pos;
02130 bfd_size_type amt;
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141 if (o->lineno_count == 0
02142 || (o->output_section->flags & SEC_HAS_CONTENTS) == 0)
02143 continue;
02144
02145 if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0
02146 || bfd_bread (finfo->linenos, linesz * o->lineno_count,
02147 input_bfd) != linesz * o->lineno_count)
02148 return FALSE;
02149
02150 offset = o->output_section->vma + o->output_offset - o->vma;
02151 eline = finfo->linenos;
02152 oeline = finfo->linenos;
02153 elineend = eline + linesz * o->lineno_count;
02154 skipping = FALSE;
02155 for (; eline < elineend; eline += linesz)
02156 {
02157 struct internal_lineno iline;
02158
02159 bfd_coff_swap_lineno_in (input_bfd, eline, &iline);
02160
02161 if (iline.l_lnno != 0)
02162 iline.l_addr.l_paddr += offset;
02163 else if (iline.l_addr.l_symndx >= 0
02164 && ((unsigned long) iline.l_addr.l_symndx
02165 < obj_raw_syment_count (input_bfd)))
02166 {
02167 long indx;
02168
02169 indx = finfo->sym_indices[iline.l_addr.l_symndx];
02170
02171 if (indx < 0)
02172 {
02173
02174
02175
02176
02177
02178
02179
02180 skipping = TRUE;
02181 }
02182 else
02183 {
02184 struct internal_syment is;
02185 union internal_auxent ia;
02186
02187
02188
02189
02190
02191
02192
02193
02194 bfd_coff_swap_sym_in (output_bfd,
02195 (finfo->outsyms
02196 + ((indx - syment_base)
02197 * osymesz)), &is);
02198 if ((ISFCN (is.n_type)
02199 || is.n_sclass == C_BLOCK)
02200 && is.n_numaux >= 1)
02201 {
02202 void *auxptr;
02203
02204 auxptr = (finfo->outsyms
02205 + ((indx - syment_base + 1)
02206 * osymesz));
02207 bfd_coff_swap_aux_in (output_bfd, auxptr,
02208 is.n_type, is.n_sclass,
02209 0, is.n_numaux, &ia);
02210 ia.x_sym.x_fcnary.x_fcn.x_lnnoptr =
02211 (o->output_section->line_filepos
02212 + o->output_section->lineno_count * linesz
02213 + eline - finfo->linenos);
02214 bfd_coff_swap_aux_out (output_bfd, &ia,
02215 is.n_type, is.n_sclass, 0,
02216 is.n_numaux, auxptr);
02217 }
02218
02219 skipping = FALSE;
02220 }
02221
02222 iline.l_addr.l_symndx = indx;
02223 }
02224
02225 if (!skipping)
02226 {
02227 bfd_coff_swap_lineno_out (output_bfd, &iline, oeline);
02228 oeline += linesz;
02229 }
02230 }
02231
02232 pos = o->output_section->line_filepos;
02233 pos += o->output_section->lineno_count * linesz;
02234 amt = oeline - finfo->linenos;
02235 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
02236 || bfd_bwrite (finfo->linenos, amt, output_bfd) != amt)
02237 return FALSE;
02238
02239 o->output_section->lineno_count += amt / linesz;
02240 }
02241 }
02242
02243
02244
02245
02246
02247 if (finfo->last_file_index != -1
02248 && (bfd_size_type) finfo->last_file_index >= syment_base)
02249 {
02250 finfo->last_file.n_value = output_index;
02251 bfd_coff_swap_sym_out (output_bfd, &finfo->last_file,
02252 (finfo->outsyms
02253 + ((finfo->last_file_index - syment_base)
02254 * osymesz)));
02255 }
02256
02257
02258 if (outsym > finfo->outsyms)
02259 {
02260 file_ptr pos;
02261 bfd_size_type amt;
02262
02263 pos = obj_sym_filepos (output_bfd) + syment_base * osymesz;
02264 amt = outsym - finfo->outsyms;
02265 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
02266 || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt)
02267 return FALSE;
02268
02269 BFD_ASSERT ((obj_raw_syment_count (output_bfd)
02270 + (outsym - finfo->outsyms) / osymesz)
02271 == output_index);
02272
02273 obj_raw_syment_count (output_bfd) = output_index;
02274 }
02275
02276
02277 adjust_symndx = coff_backend_info (input_bfd)->_bfd_coff_adjust_symndx;
02278 for (o = input_bfd->sections; o != NULL; o = o->next)
02279 {
02280 bfd_byte *contents;
02281 struct coff_section_tdata *secdata;
02282
02283 if (! o->linker_mark)
02284
02285 continue;
02286
02287 if ((o->flags & SEC_LINKER_CREATED) != 0)
02288 continue;
02289
02290 if ((o->flags & SEC_HAS_CONTENTS) == 0
02291 || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
02292 {
02293 if ((o->flags & SEC_RELOC) != 0
02294 && o->reloc_count != 0)
02295 {
02296 (*_bfd_error_handler)
02297 (_("%B: relocs in section `%A', but it has no contents"),
02298 input_bfd, o);
02299 bfd_set_error (bfd_error_no_contents);
02300 return FALSE;
02301 }
02302
02303 continue;
02304 }
02305
02306 secdata = coff_section_data (input_bfd, o);
02307 if (secdata != NULL && secdata->contents != NULL)
02308 contents = secdata->contents;
02309 else
02310 {
02311 bfd_size_type x = o->rawsize ? o->rawsize : o->size;
02312 if (! bfd_get_section_contents (input_bfd, o, finfo->contents, 0, x))
02313 return FALSE;
02314 contents = finfo->contents;
02315 }
02316
02317 if ((o->flags & SEC_RELOC) != 0)
02318 {
02319 int target_index;
02320 struct internal_reloc *internal_relocs;
02321 struct internal_reloc *irel;
02322
02323
02324 target_index = o->output_section->target_index;
02325 internal_relocs = (_bfd_coff_read_internal_relocs
02326 (input_bfd, o, FALSE, finfo->external_relocs,
02327 finfo->info->relocatable,
02328 (finfo->info->relocatable
02329 ? (finfo->section_info[target_index].relocs
02330 + o->output_section->reloc_count)
02331 : finfo->internal_relocs)));
02332 if (internal_relocs == NULL)
02333 return FALSE;
02334
02335
02336
02337 if (! bfd_coff_relocate_section (output_bfd, finfo->info,
02338 input_bfd, o,
02339 contents,
02340 internal_relocs,
02341 finfo->internal_syms,
02342 finfo->sec_ptrs))
02343 return FALSE;
02344
02345 if (finfo->info->relocatable)
02346 {
02347 bfd_vma offset;
02348 struct internal_reloc *irelend;
02349 struct coff_link_hash_entry **rel_hash;
02350
02351 offset = o->output_section->vma + o->output_offset - o->vma;
02352 irel = internal_relocs;
02353 irelend = irel + o->reloc_count;
02354 rel_hash = (finfo->section_info[target_index].rel_hashes
02355 + o->output_section->reloc_count);
02356 for (; irel < irelend; irel++, rel_hash++)
02357 {
02358 struct coff_link_hash_entry *h;
02359 bfd_boolean adjusted;
02360
02361 *rel_hash = NULL;
02362
02363
02364 irel->r_vaddr += offset;
02365
02366 if (irel->r_symndx == -1)
02367 continue;
02368
02369 if (adjust_symndx)
02370 {
02371 if (! (*adjust_symndx) (output_bfd, finfo->info,
02372 input_bfd, o, irel,
02373 &adjusted))
02374 return FALSE;
02375 if (adjusted)
02376 continue;
02377 }
02378
02379 h = obj_coff_sym_hashes (input_bfd)[irel->r_symndx];
02380 if (h != NULL)
02381 {
02382
02383 if (h->indx >= 0)
02384 irel->r_symndx = h->indx;
02385 else
02386 {
02387
02388
02389
02390
02391
02392
02393 *rel_hash = h;
02394 h->indx = -2;
02395 }
02396 }
02397 else
02398 {
02399 long indx;
02400
02401 indx = finfo->sym_indices[irel->r_symndx];
02402 if (indx != -1)
02403 irel->r_symndx = indx;
02404 else
02405 {
02406 struct internal_syment *is;
02407 const char *name;
02408 char buf[SYMNMLEN + 1];
02409
02410
02411
02412
02413
02414 is = finfo->internal_syms + irel->r_symndx;
02415
02416 name = (_bfd_coff_internal_syment_name
02417 (input_bfd, is, buf));
02418 if (name == NULL)
02419 return FALSE;
02420
02421 if (! ((*finfo->info->callbacks->unattached_reloc)
02422 (finfo->info, name, input_bfd, o,
02423 irel->r_vaddr)))
02424 return FALSE;
02425 }
02426 }
02427 }
02428
02429 o->output_section->reloc_count += o->reloc_count;
02430 }
02431 }
02432
02433
02434 if (secdata == NULL || secdata->stab_info == NULL)
02435 {
02436 file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd);
02437 if (! bfd_set_section_contents (output_bfd, o->output_section,
02438 contents, loc, o->size))
02439 return FALSE;
02440 }
02441 else
02442 {
02443 if (! (_bfd_write_section_stabs
02444 (output_bfd, &coff_hash_table (finfo->info)->stab_info,
02445 o, &secdata->stab_info, contents)))
02446 return FALSE;
02447 }
02448 }
02449
02450 if (! finfo->info->keep_memory
02451 && ! _bfd_coff_free_symbols (input_bfd))
02452 return FALSE;
02453
02454 return TRUE;
02455 }
02456
02457
02458
02459 bfd_boolean
02460 _bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data)
02461 {
02462 struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
02463 bfd *output_bfd;
02464 struct internal_syment isym;
02465 bfd_size_type symesz;
02466 unsigned int i;
02467 file_ptr pos;
02468
02469 output_bfd = finfo->output_bfd;
02470
02471 if (h->root.type == bfd_link_hash_warning)
02472 {
02473 h = (struct coff_link_hash_entry *) h->root.u.i.link;
02474 if (h->root.type == bfd_link_hash_new)
02475 return TRUE;
02476 }
02477
02478 if (h->indx >= 0)
02479 return TRUE;
02480
02481 if (h->indx != -2
02482 && (finfo->info->strip == strip_all
02483 || (finfo->info->strip == strip_some
02484 && (bfd_hash_lookup (finfo->info->keep_hash,
02485 h->root.root.string, FALSE, FALSE)
02486 == NULL))))
02487 return TRUE;
02488
02489 switch (h->root.type)
02490 {
02491 default:
02492 case bfd_link_hash_new:
02493 case bfd_link_hash_warning:
02494 abort ();
02495 return FALSE;
02496
02497 case bfd_link_hash_undefined:
02498 case bfd_link_hash_undefweak:
02499 isym.n_scnum = N_UNDEF;
02500 isym.n_value = 0;
02501 break;
02502
02503 case bfd_link_hash_defined:
02504 case bfd_link_hash_defweak:
02505 {
02506 asection *sec;
02507
02508 sec = h->root.u.def.section->output_section;
02509 if (bfd_is_abs_section (sec))
02510 isym.n_scnum = N_ABS;
02511 else
02512 isym.n_scnum = sec->target_index;
02513 isym.n_value = (h->root.u.def.value
02514 + h->root.u.def.section->output_offset);
02515 if (! obj_pe (finfo->output_bfd))
02516 isym.n_value += sec->vma;
02517 }
02518 break;
02519
02520 case bfd_link_hash_common:
02521 isym.n_scnum = N_UNDEF;
02522 isym.n_value = h->root.u.c.size;
02523 break;
02524
02525 case bfd_link_hash_indirect:
02526
02527 return TRUE;
02528 }
02529
02530 if (strlen (h->root.root.string) <= SYMNMLEN)
02531 strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN);
02532 else
02533 {
02534 bfd_boolean hash;
02535 bfd_size_type indx;
02536
02537 hash = TRUE;
02538 if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
02539 hash = FALSE;
02540 indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash,
02541 FALSE);
02542 if (indx == (bfd_size_type) -1)
02543 {
02544 finfo->failed = TRUE;
02545 return FALSE;
02546 }
02547 isym._n._n_n._n_zeroes = 0;
02548 isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
02549 }
02550
02551 isym.n_sclass = h->class;
02552 isym.n_type = h->type;
02553
02554 if (isym.n_sclass == C_NULL)
02555 isym.n_sclass = C_EXT;
02556
02557
02558
02559
02560
02561 if (finfo->global_to_static)
02562 {
02563 if (! IS_EXTERNAL (output_bfd, isym))
02564 return TRUE;
02565
02566 isym.n_sclass = C_STAT;
02567 }
02568
02569
02570
02571
02572 if (! finfo->info->shared
02573 && ! finfo->info->relocatable
02574 && IS_WEAK_EXTERNAL (finfo->output_bfd, isym))
02575 isym.n_sclass = C_EXT;
02576
02577 isym.n_numaux = h->numaux;
02578
02579 bfd_coff_swap_sym_out (output_bfd, &isym, finfo->outsyms);
02580
02581 symesz = bfd_coff_symesz (output_bfd);
02582
02583 pos = obj_sym_filepos (output_bfd);
02584 pos += obj_raw_syment_count (output_bfd) * symesz;
02585 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
02586 || bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz)
02587 {
02588 finfo->failed = TRUE;
02589 return FALSE;
02590 }
02591
02592 h->indx = obj_raw_syment_count (output_bfd);
02593
02594 ++obj_raw_syment_count (output_bfd);
02595
02596
02597
02598
02599
02600 for (i = 0; i < isym.n_numaux; i++)
02601 {
02602 union internal_auxent *auxp;
02603
02604 auxp = h->aux + i;
02605
02606
02607
02608 if (i == 0
02609 && (isym.n_sclass == C_STAT
02610 || isym.n_sclass == C_HIDDEN)
02611 && isym.n_type == T_NULL
02612 && (h->root.type == bfd_link_hash_defined
02613 || h->root.type == bfd_link_hash_defweak))
02614 {
02615 asection *sec;
02616
02617 sec = h->root.u.def.section->output_section;
02618 if (sec != NULL)
02619 {
02620 auxp->x_scn.x_scnlen = sec->size;
02621
02622
02623
02624 if (sec->reloc_count > 0xffff
02625 && (! obj_pe (output_bfd)
02626 || finfo->info->relocatable))
02627 (*_bfd_error_handler)
02628 (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
02629 bfd_get_filename (output_bfd),
02630 bfd_get_section_name (output_bfd, sec),
02631 sec->reloc_count);
02632
02633 if (sec->lineno_count > 0xffff
02634 && (! obj_pe (output_bfd)
02635 || finfo->info->relocatable))
02636 (*_bfd_error_handler)
02637 (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
02638 bfd_get_filename (output_bfd),
02639 bfd_get_section_name (output_bfd, sec),
02640 sec->lineno_count);
02641
02642 auxp->x_scn.x_nreloc = sec->reloc_count;
02643 auxp->x_scn.x_nlinno = sec->lineno_count;
02644 auxp->x_scn.x_checksum = 0;
02645 auxp->x_scn.x_associated = 0;
02646 auxp->x_scn.x_comdat = 0;
02647 }
02648 }
02649
02650 bfd_coff_swap_aux_out (output_bfd, auxp, isym.n_type,
02651 isym.n_sclass, (int) i, isym.n_numaux,
02652 finfo->outsyms);
02653 if (bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz)
02654 {
02655 finfo->failed = TRUE;
02656 return FALSE;
02657 }
02658 ++obj_raw_syment_count (output_bfd);
02659 }
02660
02661 return TRUE;
02662 }
02663
02664
02665
02666
02667
02668 bfd_boolean
02669 _bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data)
02670 {
02671 struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
02672 bfd_boolean rtnval = TRUE;
02673 bfd_boolean save_global_to_static;
02674
02675 if (h->root.type == bfd_link_hash_warning)
02676 h = (struct coff_link_hash_entry *) h->root.u.i.link;
02677
02678 if (h->indx < 0)
02679 {
02680 switch (h->root.type)
02681 {
02682 case bfd_link_hash_defined:
02683 case bfd_link_hash_defweak:
02684 save_global_to_static = finfo->global_to_static;
02685 finfo->global_to_static = TRUE;
02686 rtnval = _bfd_coff_write_global_sym (h, data);
02687 finfo->global_to_static = save_global_to_static;
02688 break;
02689 default:
02690 break;
02691 }
02692 }
02693 return (rtnval);
02694 }
02695
02696
02697
02698 bfd_boolean
02699 _bfd_coff_reloc_link_order (bfd *output_bfd,
02700 struct coff_final_link_info *finfo,
02701 asection *output_section,
02702 struct bfd_link_order *link_order)
02703 {
02704 reloc_howto_type *howto;
02705 struct internal_reloc *irel;
02706 struct coff_link_hash_entry **rel_hash_ptr;
02707
02708 howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
02709 if (howto == NULL)
02710 {
02711 bfd_set_error (bfd_error_bad_value);
02712 return FALSE;
02713 }
02714
02715 if (link_order->u.reloc.p->addend != 0)
02716 {
02717 bfd_size_type size;
02718 bfd_byte *buf;
02719 bfd_reloc_status_type rstat;
02720 bfd_boolean ok;
02721 file_ptr loc;
02722
02723 size = bfd_get_reloc_size (howto);
02724 buf = bfd_zmalloc (size);
02725 if (buf == NULL)
02726 return FALSE;
02727
02728 rstat = _bfd_relocate_contents (howto, output_bfd,
02729 (bfd_vma) link_order->u.reloc.p->addend,\
02730 buf);
02731 switch (rstat)
02732 {
02733 case bfd_reloc_ok:
02734 break;
02735 default:
02736 case bfd_reloc_outofrange:
02737 abort ();
02738 case bfd_reloc_overflow:
02739 if (! ((*finfo->info->callbacks->reloc_overflow)
02740 (finfo->info, NULL,
02741 (link_order->type == bfd_section_reloc_link_order
02742 ? bfd_section_name (output_bfd,
02743 link_order->u.reloc.p->u.section)
02744 : link_order->u.reloc.p->u.name),
02745 howto->name, link_order->u.reloc.p->addend,
02746 (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
02747 {
02748 free (buf);
02749 return FALSE;
02750 }
02751 break;
02752 }
02753 loc = link_order->offset * bfd_octets_per_byte (output_bfd);
02754 ok = bfd_set_section_contents (output_bfd, output_section, buf,
02755 loc, size);
02756 free (buf);
02757 if (! ok)
02758 return FALSE;
02759 }
02760
02761
02762
02763 irel = (finfo->section_info[output_section->target_index].relocs
02764 + output_section->reloc_count);
02765 rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes
02766 + output_section->reloc_count);
02767
02768 memset (irel, 0, sizeof (struct internal_reloc));
02769 *rel_hash_ptr = NULL;
02770
02771 irel->r_vaddr = output_section->vma + link_order->offset;
02772
02773 if (link_order->type == bfd_section_reloc_link_order)
02774 {
02775
02776
02777
02778
02779 abort ();
02780 *rel_hash_ptr = NULL;
02781 irel->r_symndx = 0;
02782 }
02783 else
02784 {
02785 struct coff_link_hash_entry *h;
02786
02787 h = ((struct coff_link_hash_entry *)
02788 bfd_wrapped_link_hash_lookup (output_bfd, finfo->info,
02789 link_order->u.reloc.p->u.name,
02790 FALSE, FALSE, TRUE));
02791 if (h != NULL)
02792 {
02793 if (h->indx >= 0)
02794 irel->r_symndx = h->indx;
02795 else
02796 {
02797
02798
02799 h->indx = -2;
02800 *rel_hash_ptr = h;
02801 irel->r_symndx = 0;
02802 }
02803 }
02804 else
02805 {
02806 if (! ((*finfo->info->callbacks->unattached_reloc)
02807 (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL,
02808 (asection *) NULL, (bfd_vma) 0)))
02809 return FALSE;
02810 irel->r_symndx = 0;
02811 }
02812 }
02813
02814
02815 irel->r_type = howto->type;
02816
02817
02818
02819
02820
02821 ++output_section->reloc_count;
02822
02823 return TRUE;
02824 }
02825
02826
02827
02828
02829 bfd_boolean
02830 _bfd_coff_generic_relocate_section (bfd *output_bfd,
02831 struct bfd_link_info *info,
02832 bfd *input_bfd,
02833 asection *input_section,
02834 bfd_byte *contents,
02835 struct internal_reloc *relocs,
02836 struct internal_syment *syms,
02837 asection **sections)
02838 {
02839 struct internal_reloc *rel;
02840 struct internal_reloc *relend;
02841
02842 rel = relocs;
02843 relend = rel + input_section->reloc_count;
02844 for (; rel < relend; rel++)
02845 {
02846 long symndx;
02847 struct coff_link_hash_entry *h;
02848 struct internal_syment *sym;
02849 bfd_vma addend;
02850 bfd_vma val;
02851 reloc_howto_type *howto;
02852 bfd_reloc_status_type rstat;
02853
02854 symndx = rel->r_symndx;
02855
02856 if (symndx == -1)
02857 {
02858 h = NULL;
02859 sym = NULL;
02860 }
02861 else if (symndx < 0
02862 || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
02863 {
02864 (*_bfd_error_handler)
02865 ("%B: illegal symbol index %ld in relocs", input_bfd, symndx);
02866 return FALSE;
02867 }
02868 else
02869 {
02870 h = obj_coff_sym_hashes (input_bfd)[symndx];
02871 sym = syms + symndx;
02872 }
02873
02874
02875
02876
02877
02878 if (sym != NULL && sym->n_scnum != 0)
02879 addend = - sym->n_value;
02880 else
02881 addend = 0;
02882
02883 howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
02884 sym, &addend);
02885 if (howto == NULL)
02886 return FALSE;
02887
02888
02889
02890
02891
02892 if (howto->pc_relative && howto->pcrel_offset)
02893 {
02894 if (info->relocatable)
02895 continue;
02896 if (sym != NULL && sym->n_scnum != 0)
02897 addend += sym->n_value;
02898 }
02899
02900 val = 0;
02901
02902 if (h == NULL)
02903 {
02904 asection *sec;
02905
02906 if (symndx == -1)
02907 {
02908 sec = bfd_abs_section_ptr;
02909 val = 0;
02910 }
02911 else
02912 {
02913 sec = sections[symndx];
02914 val = (sec->output_section->vma
02915 + sec->output_offset
02916 + sym->n_value);
02917 if (! obj_pe (input_bfd))
02918 val -= sec->vma;
02919 }
02920 }
02921 else
02922 {
02923 if (h->root.type == bfd_link_hash_defined
02924 || h->root.type == bfd_link_hash_defweak)
02925 {
02926
02927 asection *sec;
02928
02929 sec = h->root.u.def.section;
02930 val = (h->root.u.def.value
02931 + sec->output_section->vma
02932 + sec->output_offset);
02933 }
02934
02935 else if (h->root.type == bfd_link_hash_undefweak)
02936 {
02937 if (h->class == C_NT_WEAK && h->numaux == 1)
02938 {
02939
02940
02941
02942
02943
02944
02945
02946
02947 asection *sec;
02948 struct coff_link_hash_entry *h2 =
02949 input_bfd->tdata.coff_obj_data->sym_hashes[
02950 h->aux->x_sym.x_tagndx.l];
02951
02952 if (!h2 || h2->root.type == bfd_link_hash_undefined)
02953 {
02954 sec = bfd_abs_section_ptr;
02955 val = 0;
02956 }
02957 else
02958 {
02959 sec = h2->root.u.def.section;
02960 val = h2->root.u.def.value
02961 + sec->output_section->vma + sec->output_offset;
02962 }
02963 }
02964 else
02965
02966 val = 0;
02967 }
02968
02969 else if (! info->relocatable)
02970 {
02971 if (! ((*info->callbacks->undefined_symbol)
02972 (info, h->root.root.string, input_bfd, input_section,
02973 rel->r_vaddr - input_section->vma, TRUE)))
02974 return FALSE;
02975 }
02976 }
02977
02978 if (info->base_file)
02979 {
02980
02981 if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto))
02982 {
02983
02984
02985
02986
02987
02988
02989 long addr = (rel->r_vaddr
02990 - input_section->vma
02991 + input_section->output_offset
02992 + input_section->output_section->vma);
02993 if (coff_data (output_bfd)->pe)
02994 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
02995 if (fwrite (&addr, 1, sizeof (long), (FILE *) info->base_file)
02996 != sizeof (long))
02997 {
02998 bfd_set_error (bfd_error_system_call);
02999 return FALSE;
03000 }
03001 }
03002 }
03003
03004 rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
03005 contents,
03006 rel->r_vaddr - input_section->vma,
03007 val, addend);
03008
03009 switch (rstat)
03010 {
03011 default:
03012 abort ();
03013 case bfd_reloc_ok:
03014 break;
03015 case bfd_reloc_outofrange:
03016 (*_bfd_error_handler)
03017 (_("%B: bad reloc address 0x%lx in section `%A'"),
03018 input_bfd, input_section, (unsigned long) rel->r_vaddr);
03019 return FALSE;
03020 case bfd_reloc_overflow:
03021 {
03022 const char *name;
03023 char buf[SYMNMLEN + 1];
03024
03025 if (symndx == -1)
03026 name = "*ABS*";
03027 else if (h != NULL)
03028 name = NULL;
03029 else
03030 {
03031 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
03032 if (name == NULL)
03033 return FALSE;
03034 }
03035
03036 if (! ((*info->callbacks->reloc_overflow)
03037 (info, (h ? &h->root : NULL), name, howto->name,
03038 (bfd_vma) 0, input_bfd, input_section,
03039 rel->r_vaddr - input_section->vma)))
03040 return FALSE;
03041 }
03042 }
03043 }
03044 return TRUE;
03045 }