X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcofflink.c;h=1eac3c58ce800b28c8fb21f5e62f5c8724609480;hb=86fb1dece37497b267579ed4f062d280cd5760cd;hp=b648fa19eea1665eae450fae91012a59d0617e1d;hpb=9bd09e220fef247580c9736ab0d680c875c11f93;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/cofflink.c b/bfd/cofflink.c index b648fa19ee..1eac3c58ce 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -1,5 +1,6 @@ /* COFF specific linker code. - Copyright 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -40,6 +41,15 @@ static int process_embedded_commands PARAMS ((bfd *, struct bfd_link_info *, bfd *)); static void mark_relocs PARAMS ((struct coff_final_link_info *, bfd *)); +/* Return true if SYM is a weak, external symbol. */ +#define IS_WEAK_EXTERNAL(abfd, sym) \ + ((sym).n_sclass == C_WEAKEXT \ + || (obj_pe (abfd) && (sym).n_sclass == C_NT_WEAK)) + +/* Return true if SYM is an external symbol. */ +#define IS_EXTERNAL(abfd, sym) \ + ((sym).n_sclass == C_EXT || IS_WEAK_EXTERNAL (abfd, sym)) + /* Define macros so that the ISFCN, et. al., macros work correctly. These macros are defined in include/coff/internal.h in terms of N_TMASK, etc. These definitions require a user to define local @@ -107,15 +117,15 @@ _bfd_coff_link_hash_table_create (abfd) bfd *abfd; { struct coff_link_hash_table *ret; + bfd_size_type amt = sizeof (struct coff_link_hash_table); - ret = ((struct coff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct coff_link_hash_table))); + ret = (struct coff_link_hash_table *) bfd_malloc (amt); if (ret == NULL) return NULL; if (! _bfd_coff_link_hash_table_init (ret, abfd, _bfd_coff_link_hash_newfunc)) { - bfd_release (abfd, ret); + free (ret); return (struct bfd_link_hash_table *) NULL; } return &ret->root; @@ -267,6 +277,16 @@ coff_link_check_ar_symbols (abfd, info, pneeded) return false; h = bfd_link_hash_lookup (info->hash, name, false, false, true); + /* auto import */ + if (!h && info->pei386_auto_import) + { + if (!strncmp (name,"__imp_", 6)) + { + h = + bfd_link_hash_lookup (info->hash, name + 6, false, false, + true); + } + } /* We are only interested in symbols that are currently undefined. If a symbol is currently known to be common, COFF linkers do not bring in an object file which defines @@ -305,6 +325,7 @@ coff_link_add_symbols (abfd, info) bfd_size_type symesz; bfd_byte *esym; bfd_byte *esym_end; + bfd_size_type amt; /* Keep the symbols during this function, in case the linker needs to read the generic symbols in order to report an error message. */ @@ -320,10 +341,8 @@ coff_link_add_symbols (abfd, info) /* We keep a list of the linker hash table entries that correspond to particular symbols. */ - sym_hash = ((struct coff_link_hash_entry **) - bfd_alloc (abfd, - ((size_t) symcount - * sizeof (struct coff_link_hash_entry *)))); + amt = symcount * sizeof (struct coff_link_hash_entry *); + sym_hash = (struct coff_link_hash_entry **) bfd_alloc (abfd, amt); if (sym_hash == NULL && symcount != 0) goto error_return; obj_coff_sym_hashes (abfd) = sym_hash; @@ -395,8 +414,7 @@ coff_link_add_symbols (abfd, info) break; } - if (sym.n_sclass == C_WEAKEXT - || (obj_pe (abfd) && sym.n_sclass == C_NT_WEAK)) + if (IS_WEAK_EXTERNAL (abfd, sym)) flags = BSF_WEAK; addit = true; @@ -424,7 +442,7 @@ coff_link_add_symbols (abfd, info) /* The Microsoft Visual C compiler does string pooling by hashing the constants to an internal symbol name, and - relying on the the linker comdat support to discard + relying on the linker comdat support to discard duplicate names. However, if one string is a literal and one is a data initializer, one will end up in the .data section and one will end up in the .rdata section. The @@ -517,7 +535,7 @@ coff_link_add_symbols (abfd, info) (*_bfd_error_handler) (_("Warning: type of symbol `%s' changed from %d to %d in %s"), name, (*sym_hash)->type, sym.n_type, - bfd_get_filename (abfd)); + bfd_archive_filename (abfd)); /* We don't want to change from a meaningful base type to a null one, but if we know @@ -545,8 +563,8 @@ coff_link_add_symbols (abfd, info) i < sym.n_numaux; i++, eaux += symesz, iaux++) bfd_coff_swap_aux_in (abfd, (PTR) eaux, sym.n_type, - sym.n_sclass, i, sym.n_numaux, - (PTR) iaux); + sym.n_sclass, (int) i, + sym.n_numaux, (PTR) iaux); (*sym_hash)->aux = alloc; } } @@ -599,9 +617,8 @@ coff_link_add_symbols (abfd, info) secdata = coff_section_data (abfd, stab); if (secdata == NULL) { - stab->used_by_bfd = - (PTR) bfd_zalloc (abfd, - sizeof (struct coff_section_tdata)); + amt = sizeof (struct coff_section_tdata); + stab->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); if (stab->used_by_bfd == NULL) goto error_return; secdata = coff_section_data (abfd, stab); @@ -639,11 +656,11 @@ _bfd_coff_final_link (abfd, info) boolean long_section_names; asection *o; struct bfd_link_order *p; - size_t max_sym_count; - size_t max_lineno_count; - size_t max_reloc_count; - size_t max_output_reloc_count; - size_t max_contents_size; + bfd_size_type max_sym_count; + bfd_size_type max_lineno_count; + bfd_size_type max_reloc_count; + bfd_size_type max_output_reloc_count; + bfd_size_type max_contents_size; file_ptr rel_filepos; unsigned int relsz; file_ptr line_filepos; @@ -651,6 +668,7 @@ _bfd_coff_final_link (abfd, info) bfd *sub; bfd_byte *external_relocs = NULL; char strbuf[STRING_SIZE_SIZE]; + bfd_size_type amt; symesz = bfd_coff_symesz (abfd); @@ -766,10 +784,9 @@ _bfd_coff_final_link (abfd, info) /* We use section_count + 1, rather than section_count, because the target_index fields are 1 based. */ - finfo.section_info = - ((struct coff_link_section_info *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct coff_link_section_info))); + amt = abfd->section_count + 1; + amt *= sizeof (struct coff_link_section_info); + finfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt); if (finfo.section_info == NULL) goto error_return; for (i = 0; i <= abfd->section_count; i++) @@ -810,13 +827,14 @@ _bfd_coff_final_link (abfd, info) but only when doing a relocateable link, which is not the common case. */ BFD_ASSERT (info->relocateable); + amt = o->reloc_count; + amt *= sizeof (struct internal_reloc); finfo.section_info[o->target_index].relocs = - ((struct internal_reloc *) - bfd_malloc (o->reloc_count * sizeof (struct internal_reloc))); + (struct internal_reloc *) bfd_malloc (amt); + amt = o->reloc_count; + amt *= sizeof (struct coff_link_hash_entry *); finfo.section_info[o->target_index].rel_hashes = - ((struct coff_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct coff_link_hash_entry *))); + (struct coff_link_hash_entry **) bfd_malloc (amt); if (finfo.section_info[o->target_index].relocs == NULL || finfo.section_info[o->target_index].rel_hashes == NULL) goto error_return; @@ -848,22 +866,23 @@ _bfd_coff_final_link (abfd, info) } /* Allocate some buffers used while linking. */ - finfo.internal_syms = ((struct internal_syment *) - bfd_malloc (max_sym_count - * sizeof (struct internal_syment))); - finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count - * sizeof (asection *)); - finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.outsyms = ((bfd_byte *) - bfd_malloc ((size_t) ((max_sym_count + 1) * symesz))); - finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count - * bfd_coff_linesz (abfd)); + amt = max_sym_count * sizeof (struct internal_syment); + finfo.internal_syms = (struct internal_syment *) bfd_malloc (amt); + amt = max_sym_count * sizeof (asection *); + finfo.sec_ptrs = (asection **) bfd_malloc (amt); + amt = max_sym_count * sizeof (long); + finfo.sym_indices = (long *) bfd_malloc (amt); + finfo.outsyms = (bfd_byte *) bfd_malloc ((max_sym_count + 1) * symesz); + amt = max_lineno_count * bfd_coff_linesz (abfd); + finfo.linenos = (bfd_byte *) bfd_malloc (amt); finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz); + amt = max_reloc_count * relsz; + finfo.external_relocs = (bfd_byte *) bfd_malloc (amt); if (! info->relocateable) - finfo.internal_relocs = ((struct internal_reloc *) - bfd_malloc (max_reloc_count - * sizeof (struct internal_reloc))); + { + amt = max_reloc_count * sizeof (struct internal_reloc); + finfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt); + } if ((finfo.internal_syms == NULL && max_sym_count > 0) || (finfo.sec_ptrs == NULL && max_sym_count > 0) || (finfo.sym_indices == NULL && max_sym_count > 0) @@ -920,7 +939,7 @@ _bfd_coff_final_link (abfd, info) if (! bfd_coff_final_link_postscript (abfd, & finfo)) goto error_return; - + /* Free up the buffers used by _bfd_coff_link_input_bfd. */ coff_debug_merge_hash_table_free (&finfo.debug_merge); @@ -968,24 +987,26 @@ _bfd_coff_final_link (abfd, info) if (finfo.last_file_index != -1 && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd)) { + file_ptr pos; + finfo.last_file.n_value = obj_raw_syment_count (abfd); bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, (PTR) finfo.outsyms); - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + finfo.last_file_index * symesz), - SEEK_SET) != 0 - || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz) + + pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz; + if (bfd_seek (abfd, pos, SEEK_SET) != 0 + || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz) return false; } /* If doing task linking (ld --task-link) then make a pass through the global symbols, writing out any that are defined, and making them - static. */ + static. */ if (info->task_link) { finfo.failed = false; - coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_task_globals, + coff_link_hash_traverse (coff_hash_table (info), + _bfd_coff_write_task_globals, (PTR) &finfo); if (finfo.failed) goto error_return; @@ -993,7 +1014,8 @@ _bfd_coff_final_link (abfd, info) /* Write out the global symbols. */ finfo.failed = false; - coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym, + coff_link_hash_traverse (coff_hash_table (info), + _bfd_coff_write_global_sym, (PTR) &finfo); if (finfo.failed) goto error_return; @@ -1010,8 +1032,8 @@ _bfd_coff_final_link (abfd, info) /* Now that we have written out all the global symbols, we know the symbol indices to use for relocs against them, and we can finally write out the relocs. */ - external_relocs = ((bfd_byte *) - bfd_malloc (max_output_reloc_count * relsz)); + amt = max_output_reloc_count * relsz; + external_relocs = (bfd_byte *) bfd_malloc (amt); if (external_relocs == NULL) goto error_return; @@ -1040,8 +1062,9 @@ _bfd_coff_final_link (abfd, info) } if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || bfd_write ((PTR) external_relocs, relsz, o->reloc_count, - abfd) != relsz * o->reloc_count) + || (bfd_bwrite ((PTR) external_relocs, + (bfd_size_type) relsz * o->reloc_count, abfd) + != (bfd_size_type) relsz * o->reloc_count)) goto error_return; } @@ -1075,25 +1098,28 @@ _bfd_coff_final_link (abfd, info) /* Write out the string table. */ if (obj_raw_syment_count (abfd) != 0 || long_section_names) { - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * symesz), - SEEK_SET) != 0) + file_ptr pos; + + pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz; + if (bfd_seek (abfd, pos, SEEK_SET) != 0) return false; #if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, - _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, - (bfd_byte *) strbuf); + H_PUT_32 (abfd, + _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, + strbuf); #else - #error Change bfd_h_put_32 + #error Change H_PUT_32 above #endif - if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) + if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd) + != STRING_SIZE_SIZE) return false; if (! _bfd_stringtab_emit (abfd, finfo.strtab)) return false; + + obj_coff_strings_written (abfd) = true; } _bfd_stringtab_free (finfo.strtab); @@ -1151,21 +1177,21 @@ dores_com (ptr, output_bfd, heap) bfd *output_bfd; int heap; { - if (coff_data(output_bfd)->pe) + if (coff_data(output_bfd)->pe) { int val = strtoul (ptr, &ptr, 0); if (heap) - pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve =val; + pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve = val; else - pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve =val; + pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve = val; - if (ptr[0] == ',') + if (ptr[0] == ',') { - int val = strtoul (ptr+1, &ptr, 0); + val = strtoul (ptr+1, &ptr, 0); if (heap) - pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit =val; + pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit = val; else - pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit =val; + pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit = val; } } return ptr; @@ -1185,7 +1211,7 @@ char **dst; } /* Process any magic embedded commands in a section called .drectve */ - + static int process_embedded_commands (output_bfd, info, abfd) bfd *output_bfd; @@ -1196,19 +1222,19 @@ process_embedded_commands (output_bfd, info, abfd) char *s; char *e; char *copy; - if (!sec) + if (!sec) return 1; - - copy = bfd_malloc ((size_t) sec->_raw_size); - if (!copy) + + copy = bfd_malloc (sec->_raw_size); + if (!copy) return 0; - if (! bfd_get_section_contents(abfd, sec, copy, 0, sec->_raw_size)) + if (! bfd_get_section_contents(abfd, sec, copy, (bfd_vma) 0, sec->_raw_size)) { free (copy); return 0; } e = copy + sec->_raw_size; - for (s = copy; s < e ; ) + for (s = copy; s < e ; ) { if (s[0]!= '-') { s++; @@ -1229,7 +1255,7 @@ process_embedded_commands (output_bfd, info, abfd) s = get_name(s, &name); s = get_name(s, &attribs); while (loop) { - switch (*attribs++) + switch (*attribs++) { case 'W': had_write = 1; @@ -1263,7 +1289,7 @@ process_embedded_commands (output_bfd, info, abfd) { s = dores_com (s+6, output_bfd, 0); } - else + else s++; } free (copy); @@ -1273,7 +1299,7 @@ process_embedded_commands (output_bfd, info, abfd) /* Place a marker against all symbols which are used by relocations. This marker can be picked up by the 'do we skip this symbol ?' loop in _bfd_coff_link_input_bfd() and used to prevent skipping - that symbol. + that symbol. */ static void @@ -1285,14 +1311,13 @@ mark_relocs (finfo, input_bfd) if ((bfd_get_file_flags (input_bfd) & HAS_SYMS) == 0) return; - + for (a = input_bfd->sections; a != (asection *) NULL; a = a->next) { struct internal_reloc * internal_relocs; struct internal_reloc * irel; struct internal_reloc * irelend; - if ((a->flags & SEC_RELOC) == 0 || a->reloc_count < 1) continue; @@ -1305,7 +1330,7 @@ mark_relocs (finfo, input_bfd) ? (finfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count) : finfo->internal_relocs) ); - + if (internal_relocs == NULL) continue; @@ -1316,7 +1341,7 @@ mark_relocs (finfo, input_bfd) been initialised to 0) for all of the symbols that are used in the relocation table. This will then be picked up in the skip/don't pass */ - + for (; irel < irelend; irel++) { finfo->sym_indices[ irel->r_symndx ] = -1; @@ -1399,8 +1424,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) && finfo->info->relocateable) { /* mark the symbol array as 'not-used' */ - memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp); - + memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp); + mark_relocs (finfo, input_bfd); } @@ -1447,7 +1472,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) dont_skip_symbol = *indexp; else dont_skip_symbol = false; - + *indexp = -1; skip = false; @@ -1491,6 +1516,19 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) } } +#ifndef COFF_WITH_PE + /* Skip section symbols for sections which are not going to be + emitted. */ + if (!skip + && isym.n_sclass == C_STAT + && isym.n_type == T_NULL + && isym.n_numaux > 0) + { + if ((*secpp)->output_section == bfd_abs_section_ptr) + skip = true; + } +#endif + /* If we stripping debugging symbols, and this is a debugging symbol, then skip it. FIXME: gas sets the section to N_ABS for some types of debugging symbols; I don't know if this is @@ -1551,6 +1589,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) struct coff_debug_merge_element **epp; bfd_byte *esl, *eslend; struct internal_syment *islp; + bfd_size_type amt; name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); if (name == NULL) @@ -1571,9 +1610,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) /* Allocate memory to hold type information. If this turns out to be a duplicate, we pass this address to bfd_release. */ - mt = ((struct coff_debug_merge_type *) - bfd_alloc (input_bfd, - sizeof (struct coff_debug_merge_type))); + amt = sizeof (struct coff_debug_merge_type); + mt = (struct coff_debug_merge_type *) bfd_alloc (input_bfd, amt); if (mt == NULL) return false; mt->class = isym.n_sclass; @@ -1599,9 +1637,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) bfd_coff_swap_sym_in (input_bfd, (PTR) esl, (PTR) islp); + amt = sizeof (struct coff_debug_merge_element); *epp = ((struct coff_debug_merge_element *) - bfd_alloc (input_bfd, - sizeof (struct coff_debug_merge_element))); + bfd_alloc (input_bfd, amt)); if (*epp == NULL) return false; @@ -1610,8 +1648,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) if (elename == NULL) return false; - name_copy = (char *) bfd_alloc (input_bfd, - strlen (elename) + 1); + amt = strlen (elename) + 1; + name_copy = (char *) bfd_alloc (input_bfd, amt); if (name_copy == NULL) return false; strcpy (name_copy, elename); @@ -1794,7 +1832,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) have to write the symbol out twice. */ if (finfo->last_file_index != -1 - && finfo->last_file.n_value != (long) output_index) + && finfo->last_file.n_value != (bfd_vma) output_index) { /* We must correct the value of the last C_FILE entry. */ @@ -1811,18 +1849,18 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) } else { + file_ptr pos; + /* We have already written out the last C_FILE symbol. We need to write it out again. We borrow *outsym temporarily. */ bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file, (PTR) outsym); - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + finfo->last_file_index * osymesz), - SEEK_SET) != 0 - || (bfd_write (outsym, osymesz, 1, output_bfd) - != osymesz)) + pos = obj_sym_filepos (output_bfd); + pos += finfo->last_file_index * osymesz; + if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 + || bfd_bwrite (outsym, osymesz, output_bfd) != osymesz) return false; } } @@ -1833,12 +1871,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) } /* If doing task linking, convert normal global function symbols to - static functions. */ - - if (finfo->info->task_link - && (isym.n_sclass == C_EXT - || isym.n_sclass == C_WEAKEXT - || (obj_pe (input_bfd) && isym.n_sclass == C_NT_WEAK))) + static functions. */ + if (finfo->info->task_link && IS_EXTERNAL (input_bfd, isym)) isym.n_sclass = C_STAT; /* Output the symbol. */ @@ -2048,6 +2082,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) } else { + file_ptr pos; + /* We have already written out the last .bf aux entry. We need to write it out again. We borrow *outsym @@ -2059,12 +2095,11 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) isymp->n_sclass, 0, isymp->n_numaux, (PTR) outsym); - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + finfo->last_bf_index * osymesz), - SEEK_SET) != 0 - || bfd_write (outsym, osymesz, 1, - output_bfd) != osymesz) + pos = obj_sym_filepos (output_bfd); + pos += finfo->last_bf_index * osymesz; + if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 + || (bfd_bwrite (outsym, osymesz, output_bfd) + != osymesz)) return false; } } @@ -2112,6 +2147,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) bfd_byte *elineend; bfd_byte *oeline; boolean skipping; + file_ptr pos; + bfd_size_type amt; /* FIXME: If SEC_HAS_CONTENTS is not for the section, then build_link_order in ldwrite.c will not have created a @@ -2127,7 +2164,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) continue; if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0 - || bfd_read (finfo->linenos, linesz, o->lineno_count, + || bfd_bread (finfo->linenos, linesz * o->lineno_count, input_bfd) != linesz * o->lineno_count) return false; @@ -2201,7 +2238,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) is.n_numaux, auxptr); } - skipping = false; + skipping = false; } iline.l_addr.l_symndx = indx; @@ -2215,17 +2252,14 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) } } - if (bfd_seek (output_bfd, - (o->output_section->line_filepos - + o->output_section->lineno_count * linesz), - SEEK_SET) != 0 - || (bfd_write (finfo->linenos, 1, oeline - finfo->linenos, - output_bfd) - != (bfd_size_type) (oeline - finfo->linenos))) + pos = o->output_section->line_filepos; + pos += o->output_section->lineno_count * linesz; + amt = oeline - finfo->linenos; + if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 + || bfd_bwrite (finfo->linenos, amt, output_bfd) != amt) return false; - o->output_section->lineno_count += - (oeline - finfo->linenos) / linesz; + o->output_section->lineno_count += amt / linesz; } } @@ -2246,12 +2280,13 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) /* Write the modified symbols to the output file. */ if (outsym > finfo->outsyms) { - if (bfd_seek (output_bfd, - obj_sym_filepos (output_bfd) + syment_base * osymesz, - SEEK_SET) != 0 - || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, - output_bfd) - != (bfd_size_type) (outsym - finfo->outsyms))) + file_ptr pos; + bfd_size_type amt; + + pos = obj_sym_filepos (output_bfd) + syment_base * osymesz; + amt = outsym - finfo->outsyms; + if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 + || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt) return false; BFD_ASSERT ((obj_raw_syment_count (output_bfd) @@ -2282,7 +2317,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) { ((*_bfd_error_handler) (_("%s: relocs in section `%s', but it has no contents"), - bfd_get_filename (input_bfd), + bfd_archive_filename (input_bfd), bfd_get_section_name (input_bfd, o))); bfd_set_error (bfd_error_no_contents); return false; @@ -2399,8 +2434,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) /* This reloc is against a symbol we are stripping. This should have been handled by the 'dont_skip_symbol' code in the while - loop at the top of this function. */ - + loop at the top of this function. */ + is = finfo->internal_syms + irel->r_symndx; name = (_bfd_coff_internal_syment_name @@ -2423,14 +2458,11 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) /* Write out the modified section contents. */ if (secdata == NULL || secdata->stab_info == NULL) { + file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd); + bfd_size_type amt = (o->_cooked_size != 0 + ? o->_cooked_size : o->_raw_size); if (! bfd_set_section_contents (output_bfd, o->output_section, - contents, - (file_ptr) - (o->output_offset * - bfd_octets_per_byte (output_bfd)), - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) + contents, loc, amt)) return false; } else @@ -2463,9 +2495,17 @@ _bfd_coff_write_global_sym (h, data) struct internal_syment isym; bfd_size_type symesz; unsigned int i; + file_ptr pos; output_bfd = finfo->output_bfd; + if (h->root.type == bfd_link_hash_warning) + { + h = (struct coff_link_hash_entry *) h->root.u.i.link; + if (h->root.type == bfd_link_hash_new) + return true; + } + if (h->indx >= 0) return true; @@ -2481,6 +2521,7 @@ _bfd_coff_write_global_sym (h, data) { default: case bfd_link_hash_new: + case bfd_link_hash_warning: abort (); return false; @@ -2513,7 +2554,6 @@ _bfd_coff_write_global_sym (h, data) break; case bfd_link_hash_indirect: - case bfd_link_hash_warning: /* Just ignore these. They can't be handled anyhow. */ return true; } @@ -2548,29 +2588,33 @@ _bfd_coff_write_global_sym (h, data) /* If doing task linking and this is the pass where we convert defined globals to statics, then do that conversion now. If the symbol is not being converted, just ignore it and it will be - output during a later pass. */ + output during a later pass. */ if (finfo->global_to_static) { - if (isym.n_sclass != C_EXT - && isym.n_sclass != C_WEAKEXT - && (! obj_pe (output_bfd) || isym.n_sclass != C_NT_WEAK)) - { - return true; - } + if (! IS_EXTERNAL (output_bfd, isym)) + return true; + isym.n_sclass = C_STAT; } + /* When a weak symbol is not overriden by a strong one, + turn it into an external symbol when not building a + shared or relocateable object. */ + if (! finfo->info->shared + && ! finfo->info->relocateable + && IS_WEAK_EXTERNAL (finfo->output_bfd, isym)) + isym.n_sclass = C_EXT; + isym.n_numaux = h->numaux; - + bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms); symesz = bfd_coff_symesz (output_bfd); - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + obj_raw_syment_count (output_bfd) * symesz), - SEEK_SET) != 0 - || bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz) + pos = obj_sym_filepos (output_bfd); + pos += obj_raw_syment_count (output_bfd) * symesz; + if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 + || bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz) { finfo->failed = true; return false; @@ -2638,9 +2682,9 @@ _bfd_coff_write_global_sym (h, data) } bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isym.n_type, - isym.n_sclass, i, isym.n_numaux, + isym.n_sclass, (int) i, isym.n_numaux, (PTR) finfo->outsyms); - if (bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz) + if (bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz) { finfo->failed = true; return false; @@ -2653,7 +2697,7 @@ _bfd_coff_write_global_sym (h, data) /* Write out task global symbols, converting them to statics. Called via coff_link_hash_traverse. Calls bfd_coff_write_global_sym to do - the dirty work, if the symbol we are processing needs conversion. */ + the dirty work, if the symbol we are processing needs conversion. */ boolean _bfd_coff_write_task_globals (h, data) @@ -2664,6 +2708,9 @@ _bfd_coff_write_task_globals (h, data) boolean rtnval = true; boolean save_global_to_static; + if (h->root.type == bfd_link_hash_warning) + h = (struct coff_link_hash_entry *) h->root.u.i.link; + if (h->indx < 0) { switch (h->root.type) @@ -2708,6 +2755,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) bfd_byte *buf; bfd_reloc_status_type rstat; boolean ok; + file_ptr loc; size = bfd_get_reloc_size (howto); buf = (bfd_byte *) bfd_zmalloc (size); @@ -2715,7 +2763,8 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) return false; rstat = _bfd_relocate_contents (howto, output_bfd, - link_order->u.reloc.p->addend, buf); + (bfd_vma) link_order->u.reloc.p->addend,\ + buf); switch (rstat) { case bfd_reloc_ok: @@ -2738,10 +2787,9 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) } break; } + loc = link_order->offset * bfd_octets_per_byte (output_bfd); ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) - (link_order->offset * - bfd_octets_per_byte (output_bfd)), size); + loc, size); free (buf); if (! ok) return false; @@ -2857,11 +2905,11 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, { (*_bfd_error_handler) ("%s: illegal symbol index %ld in relocs", - bfd_get_filename (input_bfd), symndx); + bfd_archive_filename (input_bfd), symndx); return false; } else - { + { h = obj_coff_sym_hashes (input_bfd)[symndx]; sym = syms + symndx; } @@ -2876,7 +2924,6 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, else addend = 0; - howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, sym, &addend); if (howto == NULL) @@ -2928,6 +2975,9 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, + sec->output_offset); } + else if (h->root.type == bfd_link_hash_undefweak) + val = 0; + else if (! info->relocateable) { if (! ((*info->callbacks->undefined_symbol) @@ -2939,7 +2989,7 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, if (info->base_file) { - /* Emit a reloc if the backend thinks it needs it. */ + /* Emit a reloc if the backend thinks it needs it. */ if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto)) { /* Relocation to a symbol in a section which isn't @@ -2948,9 +2998,9 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, reloc section. Note that the base file is not portable between systems. We write out a long here, and dlltool reads in a long. */ - long addr = (rel->r_vaddr - - input_section->vma - + input_section->output_offset + long addr = (rel->r_vaddr + - input_section->vma + + input_section->output_offset + input_section->output_section->vma); if (coff_data (output_bfd)->pe) addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; @@ -2962,7 +3012,7 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, } } } - + rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_vaddr - input_section->vma, @@ -2977,7 +3027,7 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, case bfd_reloc_outofrange: (*_bfd_error_handler) (_("%s: bad reloc address 0x%lx in section `%s'"), - bfd_get_filename (input_bfd), + bfd_archive_filename (input_bfd), (unsigned long) rel->r_vaddr, bfd_get_section_name (input_bfd, input_section)); return false; @@ -3006,4 +3056,3 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, } return true; } -