X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fcofflink.c;h=b2b64db95002451e9582ba09174fbfd36412f4d2;hb=7ef412cf72a197d68e532604cc1fa21351adc858;hp=c1541d1bd8510a4f675d90ca0c1a3d308db388fa;hpb=3a062fa1eeee8296dece36a9bb7ecc8d4500de18;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/cofflink.c b/bfd/cofflink.c index c1541d1bd8..b2b64db950 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -1,5 +1,5 @@ /* COFF specific linker code. - Copyright (C) 1994-2015 Free Software Foundation, Inc. + Copyright (C) 1994-2020 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -212,11 +212,16 @@ coff_link_check_archive_element (bfd *abfd, if (h->type != bfd_link_hash_undefined) return TRUE; + /* PR 22369 - Skip non COFF objects in the archive. */ + if (! bfd_family_coff (abfd)) + return TRUE; + + /* Include this element? */ if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd)) - return FALSE; + return TRUE; *pneeded = TRUE; - return coff_link_add_object_symbols (abfd, info); + return bfd_link_add_symbols (abfd, info); } /* Add all the symbols from an object file to the hash table. */ @@ -289,7 +294,7 @@ coff_link_add_symbols (bfd *abfd, goto error_return; /* We must copy the name into memory if we got it from the - syment itself, rather than the string table. */ + syment itself, rather than the string table. */ copy = default_copy; if (sym._n._n_n._n_zeroes != 0 || sym._n._n_n._n_offset == 0) @@ -305,7 +310,9 @@ coff_link_add_symbols (bfd *abfd, case COFF_SYMBOL_GLOBAL: flags = BSF_EXPORT | BSF_GLOBAL; section = coff_section_from_bfd_index (abfd, sym.n_scnum); - if (! obj_pe (abfd)) + if (discarded_section (section)) + section = bfd_und_section_ptr; + else if (! obj_pe (abfd)) value -= section->vma; break; @@ -322,6 +329,8 @@ coff_link_add_symbols (bfd *abfd, case COFF_SYMBOL_PE_SECTION: flags = BSF_SECTION_SYM | BSF_GLOBAL; section = coff_section_from_bfd_index (abfd, sym.n_scnum); + if (discarded_section (section)) + section = bfd_und_section_ptr; break; } @@ -331,8 +340,8 @@ coff_link_add_symbols (bfd *abfd, addit = TRUE; /* In the PE format, section symbols actually refer to the - start of the output section. We handle them specially - here. */ + start of the output section. We handle them specially + here. */ if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0) { *sym_hash = coff_link_hash_lookup (coff_hash_table (info), @@ -343,8 +352,8 @@ coff_link_add_symbols (bfd *abfd, & COFF_LINK_HASH_PE_SECTION_SYMBOL) == 0 && (*sym_hash)->root.type != bfd_link_hash_undefined && (*sym_hash)->root.type != bfd_link_hash_undefweak) - (*_bfd_error_handler) - ("Warning: symbol `%s' is both section and non-section", + _bfd_error_handler + (_("warning: symbol `%s' is both section and non-section"), name); addit = FALSE; @@ -406,10 +415,10 @@ coff_link_add_symbols (bfd *abfd, COFF_LINK_HASH_PE_SECTION_SYMBOL; /* Limit the alignment of a common symbol to the possible - alignment of a section. There is no point to permitting - a higher alignment for a common symbol: we can not - guarantee it, and it may cause us to allocate extra space - in the common section. */ + alignment of a section. There is no point to permitting + a higher alignment for a common symbol: we can not + guarantee it, and it may cause us to allocate extra space + in the common section. */ if (section == bfd_com_section_ptr && (*sym_hash)->root.type == bfd_link_hash_common && ((*sym_hash)->root.u.c.p->alignment_power @@ -420,42 +429,44 @@ coff_link_add_symbols (bfd *abfd, if (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd)) { /* If we don't have any symbol information currently in - the hash table, or if we are looking at a symbol - definition, then update the symbol class and type in - the hash table. */ - if (((*sym_hash)->symbol_class == C_NULL - && (*sym_hash)->type == T_NULL) - || sym.n_scnum != 0 - || (sym.n_value != 0 - && (*sym_hash)->root.type != bfd_link_hash_defined - && (*sym_hash)->root.type != bfd_link_hash_defweak)) - { - (*sym_hash)->symbol_class = sym.n_sclass; - if (sym.n_type != T_NULL) - { - /* We want to warn if the type changed, but not - if it changed from an unspecified type. - Testing the whole type byte may work, but the - change from (e.g.) a function of unspecified - type to function of known type also wants to - skip the warning. */ - if ((*sym_hash)->type != T_NULL - && (*sym_hash)->type != sym.n_type - && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type) - && (BTYPE ((*sym_hash)->type) == T_NULL - || BTYPE (sym.n_type) == T_NULL))) - (*_bfd_error_handler) - (_("Warning: type of symbol `%s' changed from %d to %d in %B"), - abfd, name, (*sym_hash)->type, sym.n_type); - - /* We don't want to change from a meaningful - base type to a null one, but if we know - nothing, take what little we might now know. */ - if (BTYPE (sym.n_type) != T_NULL - || (*sym_hash)->type == T_NULL) + the hash table, or if we are looking at a symbol + definition, then update the symbol class and type in + the hash table. */ + if (((*sym_hash)->symbol_class == C_NULL + && (*sym_hash)->type == T_NULL) + || sym.n_scnum != 0 + || (sym.n_value != 0 + && (*sym_hash)->root.type != bfd_link_hash_defined + && (*sym_hash)->root.type != bfd_link_hash_defweak)) + { + (*sym_hash)->symbol_class = sym.n_sclass; + if (sym.n_type != T_NULL) + { + /* We want to warn if the type changed, but not + if it changed from an unspecified type. + Testing the whole type byte may work, but the + change from (e.g.) a function of unspecified + type to function of known type also wants to + skip the warning. */ + if ((*sym_hash)->type != T_NULL + && (*sym_hash)->type != sym.n_type + && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type) + && (BTYPE ((*sym_hash)->type) == T_NULL + || BTYPE (sym.n_type) == T_NULL))) + _bfd_error_handler + /* xgettext: c-format */ + (_("warning: type of symbol `%s' changed" + " from %d to %d in %pB"), + name, (*sym_hash)->type, sym.n_type, abfd); + + /* We don't want to change from a meaningful + base type to a null one, but if we know + nothing, take what little we might now know. */ + if (BTYPE (sym.n_type) != T_NULL + || (*sym_hash)->type == T_NULL) (*sym_hash)->type = sym.n_type; - } - (*sym_hash)->auxbfd = abfd; + } + (*sym_hash)->auxbfd = abfd; if (sym.n_numaux != 0) { union internal_auxent *alloc; @@ -485,8 +496,8 @@ coff_link_add_symbols (bfd *abfd, && (*sym_hash)->numaux != 0) { /* Some PE sections (such as .bss) have a zero size in - the section header, but a non-zero size in the AUX - record. Correct that here. + the section header, but a non-zero size in the AUX + record. Correct that here. FIXME: This is not at all the right place to do this. For example, it won't help objdump. This needs to be @@ -496,8 +507,8 @@ coff_link_add_symbols (bfd *abfd, section->size = (*sym_hash)->aux[0].x_scn.x_scnlen; /* FIXME: We could test whether the section sizes - matches the size in the aux entry, but apparently - that sometimes fails unexpectedly. */ + matches the size in the aux entry, but apparently + that sometimes fails unexpectedly. */ } } @@ -507,7 +518,7 @@ coff_link_add_symbols (bfd *abfd, /* If this is a non-traditional, non-relocatable link, try to optimize the handling of any .stab/.stabstr sections. */ - if (! info->relocatable + if (! bfd_link_relocatable (info) && ! info->traditional_format && bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd) && (info->strip != strip_all && info->strip != strip_debugger)) @@ -652,7 +663,7 @@ _bfd_coff_final_link (bfd *abfd, || info->strip == strip_some) o->lineno_count += sec->lineno_count; - if (info->relocatable) + if (bfd_link_relocatable (info)) o->reloc_count += sec->reloc_count; if (sec->rawsize > max_contents_size) @@ -664,7 +675,7 @@ _bfd_coff_final_link (bfd *abfd, if (sec->reloc_count > max_reloc_count) max_reloc_count = sec->reloc_count; } - else if (info->relocatable + else if (bfd_link_relocatable (info) && (p->type == bfd_section_reloc_link_order || p->type == bfd_symbol_reloc_link_order)) ++o->reloc_count; @@ -686,10 +697,10 @@ _bfd_coff_final_link (bfd *abfd, && strlen (o->name) > SCNNMLEN) { /* This section has a long name which must go in the string - table. This must correspond to the code in - coff_write_object_contents which puts the string index - into the s_name field of the section header. That is why - we pass hash as FALSE. */ + table. This must correspond to the code in + coff_write_object_contents which puts the string index + into the s_name field of the section header. That is why + we pass hash as FALSE. */ if (_bfd_stringtab_add (flaginfo.strtab, o->name, FALSE, FALSE) == (bfd_size_type) -1) goto error_return; @@ -699,12 +710,12 @@ _bfd_coff_final_link (bfd *abfd, /* If doing a relocatable link, allocate space for the pointers we need to keep. */ - if (info->relocatable) + if (bfd_link_relocatable (info)) { unsigned int i; /* We use section_count + 1, rather than section_count, because - the target_index fields are 1 based. */ + the target_index fields are 1 based. */ amt = abfd->section_count + 1; amt *= sizeof (struct coff_link_section_info); flaginfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt); @@ -735,27 +746,27 @@ _bfd_coff_final_link (bfd *abfd, if (o->reloc_count != 0) { /* We don't know the indices of global symbols until we have - written out all the local symbols. For each section in - the output file, we keep an array of pointers to hash - table entries. Each entry in the array corresponds to a - reloc. When we find a reloc against a global symbol, we - set the corresponding entry in this array so that we can - fix up the symbol index after we have written out all the - local symbols. + written out all the local symbols. For each section in + the output file, we keep an array of pointers to hash + table entries. Each entry in the array corresponds to a + reloc. When we find a reloc against a global symbol, we + set the corresponding entry in this array so that we can + fix up the symbol index after we have written out all the + local symbols. Because of this problem, we also keep the relocs in memory until the end of the link. This wastes memory, but only when doing a relocatable link, which is not the common case. */ - BFD_ASSERT (info->relocatable); + BFD_ASSERT (bfd_link_relocatable (info)); amt = o->reloc_count; amt *= sizeof (struct internal_reloc); flaginfo.section_info[o->target_index].relocs = - (struct internal_reloc *) bfd_malloc (amt); + (struct internal_reloc *) bfd_malloc (amt); amt = o->reloc_count; amt *= sizeof (struct coff_link_hash_entry *); flaginfo.section_info[o->target_index].rel_hashes = - (struct coff_link_hash_entry **) bfd_malloc (amt); + (struct coff_link_hash_entry **) bfd_malloc (amt); if (flaginfo.section_info[o->target_index].relocs == NULL || flaginfo.section_info[o->target_index].rel_hashes == NULL) goto error_return; @@ -799,7 +810,7 @@ _bfd_coff_final_link (bfd *abfd, flaginfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); amt = max_reloc_count * relsz; flaginfo.external_relocs = (bfd_byte *) bfd_malloc (amt); - if (! info->relocatable) + if (! bfd_link_relocatable (info)) { amt = max_reloc_count * sizeof (struct internal_reloc); flaginfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt); @@ -811,7 +822,7 @@ _bfd_coff_final_link (bfd *abfd, || (flaginfo.linenos == NULL && max_lineno_count > 0) || (flaginfo.contents == NULL && max_contents_size > 0) || (flaginfo.external_relocs == NULL && max_reloc_count > 0) - || (! info->relocatable + || (! bfd_link_relocatable (info) && flaginfo.internal_relocs == NULL && max_reloc_count > 0)) goto error_return; @@ -872,9 +883,10 @@ _bfd_coff_final_link (bfd *abfd, asymbol *sym = bfd_get_outsymbols (sub) [i]; file_ptr pos; struct internal_syment isym; - bfd_size_type string_size = 0; + union internal_auxent iaux; + bfd_size_type string_size = 0, indx; bfd_vma written = 0; - bfd_boolean rewrite = FALSE; + bfd_boolean rewrite = FALSE, hash; if (! (sym->flags & BSF_LOCAL) || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC @@ -890,8 +902,8 @@ _bfd_coff_final_link (bfd *abfd, bfd_asymbol_name(sym), FALSE, FALSE) == NULL)) || (((flaginfo.info->discard == discard_sec_merge - && (bfd_get_section (sym)->flags & SEC_MERGE) - && ! flaginfo.info->relocatable) + && (bfd_asymbol_section (sym)->flags & SEC_MERGE) + && ! bfd_link_relocatable (flaginfo.info)) || flaginfo.info->discard == discard_l) && bfd_is_local_label_name (sub, bfd_asymbol_name(sym)))) continue; @@ -900,23 +912,52 @@ _bfd_coff_final_link (bfd *abfd, * symesz; if (bfd_seek (abfd, pos, SEEK_SET) != 0) goto error_return; - if (! coff_write_alien_symbol(abfd, sym, &isym, &written, + if (! coff_write_alien_symbol(abfd, sym, &isym, &iaux, &written, &string_size, NULL, NULL)) goto error_return; - if (string_size) + hash = !flaginfo.info->traditional_format; + + if (string_size >= 6 && isym.n_sclass == C_FILE + && ! isym._n._n_n._n_zeroes && isym.n_numaux) { - bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT); - bfd_size_type indx; + indx = _bfd_stringtab_add (flaginfo.strtab, ".file", hash, + FALSE); + if (indx == (bfd_size_type) -1) + goto error_return; + isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; + bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms); + if (bfd_seek (abfd, pos, SEEK_SET) != 0 + || bfd_bwrite (flaginfo.outsyms, symesz, + abfd) != symesz) + goto error_return; + string_size -= 6; + } + if (string_size) + { indx = _bfd_stringtab_add (flaginfo.strtab, bfd_asymbol_name (sym), hash, FALSE); if (indx == (bfd_size_type) -1) goto error_return; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms); - rewrite = TRUE; + if (isym.n_sclass != C_FILE) + { + isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; + bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms); + rewrite = TRUE; + } + else + { + BFD_ASSERT (isym.n_numaux == 1); + iaux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; + bfd_coff_swap_aux_out (abfd, &iaux, isym.n_type, C_FILE, + 0, 1, flaginfo.outsyms + symesz); + if (bfd_seek (abfd, pos + symesz, SEEK_SET) != 0 + || bfd_bwrite (flaginfo.outsyms + symesz, symesz, + abfd) != symesz) + goto error_return; + } } if (isym.n_sclass == C_FILE) @@ -1031,7 +1072,7 @@ _bfd_coff_final_link (bfd *abfd, flaginfo.outsyms = NULL; } - if (info->relocatable && max_output_reloc_count > 0) + if (bfd_link_relocatable (info) && max_output_reloc_count > 0) { /* Now that we have written out all the global symbols, we know the symbol indices to use for relocs against them, and we can @@ -1145,9 +1186,9 @@ _bfd_coff_final_link (bfd *abfd, _bfd_stringtab_free (flaginfo.strtab); - /* Setting bfd_get_symcount to 0 will cause write_object_contents to + /* Setting symcount to 0 will cause write_object_contents to not try to write out the symbols. */ - bfd_get_symcount (abfd) = 0; + abfd->symcount = 0; return TRUE; @@ -1350,8 +1391,8 @@ mark_relocs (struct coff_final_link_info *flaginfo, bfd *input_bfd) internal_relocs = _bfd_coff_read_internal_relocs (input_bfd, a, FALSE, flaginfo->external_relocs, - flaginfo->info->relocatable, - (flaginfo->info->relocatable + bfd_link_relocatable (flaginfo->info), + (bfd_link_relocatable (flaginfo->info) ? (flaginfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count) : flaginfo->internal_relocs) ); @@ -1367,7 +1408,8 @@ mark_relocs (struct coff_final_link_info *flaginfo, bfd *input_bfd) in the relocation table. This will then be picked up in the skip/don't-skip pass. */ for (; irel < irelend; irel++) - flaginfo->sym_indices[ irel->r_symndx ] = -1; + if ((unsigned long) irel->r_symndx < obj_raw_syment_count (input_bfd)) + flaginfo->sym_indices[irel->r_symndx] = -1; } } @@ -1413,7 +1455,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) if (! flaginfo->info->keep_memory) copy = TRUE; hash = TRUE; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) + if (flaginfo->info->traditional_format) hash = FALSE; if (! _bfd_coff_get_external_symbols (input_bfd)) @@ -1436,7 +1478,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) symbols that are going to be involved in the relocations. */ if (( flaginfo->info->strip != strip_none || flaginfo->info->discard != discard_none) - && flaginfo->info->relocatable) + && bfd_link_relocatable (flaginfo->info)) { /* Mark the symbol array as 'not-used'. */ memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp); @@ -1480,10 +1522,10 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) } /* Extract the flag indicating if this symbol is used by a - relocation. */ + relocation. */ if ((flaginfo->info->strip != strip_none || flaginfo->info->discard != discard_none) - && flaginfo->info->relocatable) + && bfd_link_relocatable (flaginfo->info)) dont_skip_symbol = *indexp; else dont_skip_symbol = FALSE; @@ -1524,7 +1566,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) case COFF_SYMBOL_LOCAL: /* This is a local symbol. Skip it if we are discarding - local symbols. */ + local symbols. */ if (flaginfo->info->discard == discard_all && ! dont_skip_symbol) skip = TRUE; break; @@ -1546,9 +1588,9 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) #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 - a bug or not. In any case, we handle it here. */ + 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 + a bug or not. In any case, we handle it here. */ if (! skip && flaginfo->info->strip == strip_debugger && ! dont_skip_symbol @@ -1589,9 +1631,9 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) } /* If this is an enum, struct, or union tag, see if we have - already output an identical type. */ + already output an identical type. */ if (! skip - && (flaginfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0 + && !flaginfo->info->traditional_format && (isym.n_sclass == C_ENTAG || isym.n_sclass == C_STRTAG || isym.n_sclass == C_UNTAG) @@ -1612,7 +1654,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) return FALSE; /* Ignore fake names invented by compiler; treat them all as - the same name. */ + the same name. */ if (*name == '~' || *name == '.' || *name == '$' || (*name == bfd_get_symbol_leading_char (input_bfd) && (name[1] == '~' || name[1] == '.' || name[1] == '$'))) @@ -1624,8 +1666,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) return FALSE; /* Allocate memory to hold type information. If this turns - out to be a duplicate, we pass this address to - bfd_release. */ + out to be a duplicate, we pass this address to + bfd_release. */ amt = sizeof (struct coff_debug_merge_type); mt = (struct coff_debug_merge_type *) bfd_alloc (input_bfd, amt); if (mt == NULL) @@ -1633,7 +1675,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) mt->type_class = isym.n_sclass; /* Pick up the aux entry, which points to the end of the tag - entries. */ + entries. */ bfd_coff_swap_aux_in (input_bfd, (esym + isymesz), isym.n_type, isym.n_sclass, 0, isym.n_numaux, &aux); @@ -1655,7 +1697,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) amt = sizeof (struct coff_debug_merge_element); *epp = (struct coff_debug_merge_element *) - bfd_alloc (input_bfd, amt); + bfd_alloc (input_bfd, amt); if (*epp == NULL) return FALSE; @@ -1708,8 +1750,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) } /* See if we already have a definition which matches this - type. We always output the type if it has no elements, - for simplicity. */ + type. We always output the type if it has no elements, + for simplicity. */ if (mt->elements == NULL) bfd_release (input_bfd, mt); else @@ -1801,7 +1843,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) case C_FCN: if (obj_pe (input_bfd) - && strcmp (isym.n_name, ".bf") != 0 + && memcmp (isym.n_name, ".bf", sizeof ".bf") != 0 && isym.n_scnum > 0) { /* For PE, .lf and .ef get their value left alone, @@ -1848,7 +1890,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) && flaginfo->last_file.n_value != (bfd_vma) output_index) { /* We must correct the value of the last C_FILE - entry. */ + entry. */ flaginfo->last_file.n_value = output_index; if ((bfd_size_type) flaginfo->last_file_index >= syment_base) { @@ -1903,7 +1945,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) if (h == NULL) { /* This can happen if there were errors earlier in - the link. */ + the link. */ bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1957,8 +1999,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) h = *sym_hash; /* The m68k-motorola-sysv assembler will sometimes - generate two symbols with the same name, but only one - will have aux entries. */ + generate two symbols with the same name, but only one + will have aux entries. */ BFD_ASSERT (isymp->n_numaux == 0 || h->numaux == 0 || h->numaux == isymp->n_numaux); @@ -2029,9 +2071,9 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) && indx < obj_raw_syment_count (input_bfd)) { /* We look forward through the symbol for - the index of the next symbol we are going - to include. I don't know if this is - entirely right. */ + the index of the next symbol we are going + to include. I don't know if this is + entirely right. */ while ((flaginfo->sym_indices[indx] < 0 || ((bfd_size_type) flaginfo->sym_indices[indx] < syment_base)) @@ -2101,10 +2143,10 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) file_ptr pos; /* We have already written out the last - .bf aux entry. We need to write it - out again. We borrow *outsym - temporarily. FIXME: This case should - be made faster. */ + .bf aux entry. We need to write it + out again. We borrow *outsym + temporarily. FIXME: This case should + be made faster. */ bfd_coff_swap_aux_out (output_bfd, &flaginfo->last_bf, isymp->n_type, @@ -2125,8 +2167,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) else { /* The endndx field of this aux entry must - be updated with the symbol number of the - next .bf symbol. */ + be updated with the symbol number of the + next .bf symbol. */ flaginfo->last_bf = *auxp; flaginfo->last_bf_index = (((outsym - flaginfo->outsyms) / osymesz) @@ -2260,7 +2302,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) } if (!skipping) - { + { bfd_coff_swap_lineno_out (output_bfd, &iline, oeline); oeline += linesz; } @@ -2330,8 +2372,9 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) if ((o->flags & SEC_RELOC) != 0 && o->reloc_count != 0) { - (*_bfd_error_handler) - (_("%B: relocs in section `%A', but it has no contents"), + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: relocs in section `%pA', but it has no contents"), input_bfd, o); bfd_set_error (bfd_error_no_contents); return FALSE; @@ -2360,8 +2403,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) target_index = o->output_section->target_index; internal_relocs = (_bfd_coff_read_internal_relocs (input_bfd, o, FALSE, flaginfo->external_relocs, - flaginfo->info->relocatable, - (flaginfo->info->relocatable + bfd_link_relocatable (flaginfo->info), + (bfd_link_relocatable (flaginfo->info) ? (flaginfo->section_info[target_index].relocs + o->output_section->reloc_count) : flaginfo->internal_relocs))); @@ -2393,13 +2436,14 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) /* Complain if definition comes from an excluded section. */ if (ps->flags & SEC_EXCLUDE) (*flaginfo->info->callbacks->einfo) - (_("%X`%s' referenced in section `%A' of %B: " - "defined in discarded section `%A' of %B\n"), + /* xgettext: c-format */ + (_("%X`%s' referenced in section `%pA' of %pB: " + "defined in discarded section `%pA' of %pB\n"), h->root.root.string, o, input_bfd, ps, ps->owner); } /* Call processor specific code to relocate the section - contents. */ + contents. */ if (! bfd_coff_relocate_section (output_bfd, flaginfo->info, input_bfd, o, contents, @@ -2408,7 +2452,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) flaginfo->sec_ptrs)) return FALSE; - if (flaginfo->info->relocatable) + if (bfd_link_relocatable (flaginfo->info)) { bfd_vma offset; struct internal_reloc *irelend; @@ -2474,7 +2518,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) char buf[SYMNMLEN + 1]; /* This reloc is against a symbol we are - stripping. This should have been handled + stripping. This should have been handled by the 'dont_skip_symbol' code in the while loop at the top of this function. */ is = flaginfo->internal_syms + irel->r_symndx; @@ -2484,10 +2528,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) if (name == NULL) return FALSE; - if (! ((*flaginfo->info->callbacks->unattached_reloc) - (flaginfo->info, name, input_bfd, o, - irel->r_vaddr))) - return FALSE; + (*flaginfo->info->callbacks->unattached_reloc) + (flaginfo->info, name, input_bfd, o, irel->r_vaddr); } } } @@ -2499,7 +2541,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *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); + file_ptr loc = (o->output_offset + * bfd_octets_per_byte (output_bfd, o)); if (! bfd_set_section_contents (output_bfd, o->output_section, contents, loc, o->size)) return FALSE; @@ -2602,7 +2645,7 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) bfd_size_type indx; hash = TRUE; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) + if (flaginfo->info->traditional_format) hash = FALSE; indx = _bfd_stringtab_add (flaginfo->strtab, h->root.root.string, hash, FALSE); @@ -2636,8 +2679,8 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) /* When a weak symbol is not overridden by a strong one, turn it into an external symbol when not building a shared or relocatable object. */ - if (! flaginfo->info->shared - && ! flaginfo->info->relocatable + if (! bfd_link_pic (flaginfo->info) + && ! bfd_link_relocatable (flaginfo->info) && IS_WEAK_EXTERNAL (flaginfo->output_bfd, isym)) isym.n_sclass = C_EXT; @@ -2671,7 +2714,7 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) auxp = h->aux + i; /* Look for a section aux entry here using the same tests that - coff_swap_aux_out uses. */ + coff_swap_aux_out uses. */ if (i == 0 && (isym.n_sclass == C_STAT || isym.n_sclass == C_HIDDEN) @@ -2687,24 +2730,22 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) auxp->x_scn.x_scnlen = sec->size; /* For PE, an overflow on the final link reportedly does - not matter. FIXME: Why not? */ + not matter. FIXME: Why not? */ if (sec->reloc_count > 0xffff && (! obj_pe (output_bfd) - || flaginfo->info->relocatable)) - (*_bfd_error_handler) - (_("%s: %s: reloc overflow: 0x%lx > 0xffff"), - bfd_get_filename (output_bfd), - bfd_get_section_name (output_bfd, sec), - sec->reloc_count); + || bfd_link_relocatable (flaginfo->info))) + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: %pA: reloc overflow: %#x > 0xffff"), + output_bfd, sec, sec->reloc_count); if (sec->lineno_count > 0xffff && (! obj_pe (output_bfd) - || flaginfo->info->relocatable)) - (*_bfd_error_handler) - (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"), - bfd_get_filename (output_bfd), - bfd_get_section_name (output_bfd, sec), - sec->lineno_count); + || bfd_link_relocatable (flaginfo->info))) + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: warning: %pA: line number overflow: %#x > 0xffff"), + output_bfd, sec, sec->lineno_count); auxp->x_scn.x_nreloc = sec->reloc_count; auxp->x_scn.x_nlinno = sec->lineno_count; @@ -2793,7 +2834,7 @@ _bfd_coff_reloc_link_order (bfd *output_bfd, return FALSE; rstat = _bfd_relocate_contents (howto, output_bfd, - (bfd_vma) link_order->u.reloc.p->addend,\ + (bfd_vma) link_order->u.reloc.p->addend, buf); switch (rstat) { @@ -2803,23 +2844,19 @@ _bfd_coff_reloc_link_order (bfd *output_bfd, case bfd_reloc_outofrange: abort (); case bfd_reloc_overflow: - if (! ((*flaginfo->info->callbacks->reloc_overflow) - (flaginfo->info, NULL, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - howto->name, link_order->u.reloc.p->addend, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return FALSE; - } + (*flaginfo->info->callbacks->reloc_overflow) + (flaginfo->info, NULL, + (link_order->type == bfd_section_reloc_link_order + ? bfd_section_name (link_order->u.reloc.p->u.section) + : link_order->u.reloc.p->u.name), + howto->name, link_order->u.reloc.p->addend, + (bfd *) NULL, (asection *) NULL, (bfd_vma) 0); break; } - loc = link_order->offset * bfd_octets_per_byte (output_bfd); + loc = link_order->offset * bfd_octets_per_byte (output_bfd, + output_section); ok = bfd_set_section_contents (output_bfd, output_section, buf, - loc, size); + loc, size); free (buf); if (! ok) return FALSE; @@ -2840,9 +2877,9 @@ _bfd_coff_reloc_link_order (bfd *output_bfd, if (link_order->type == bfd_section_reloc_link_order) { /* We need to somehow locate a symbol in the right section. The - symbol must either have a value of zero, or we must adjust - the addend by the value of the symbol. FIXME: Write this - when we need it. The old linker couldn't handle this anyhow. */ + symbol must either have a value of zero, or we must adjust + the addend by the value of the symbol. FIXME: Write this + when we need it. The old linker couldn't handle this anyhow. */ abort (); *rel_hash_ptr = NULL; irel->r_symndx = 0; @@ -2870,10 +2907,9 @@ _bfd_coff_reloc_link_order (bfd *output_bfd, } else { - if (! ((*flaginfo->info->callbacks->unattached_reloc) - (flaginfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return FALSE; + (*flaginfo->info->callbacks->unattached_reloc) + (flaginfo->info, link_order->u.reloc.p->u.name, + (bfd *) NULL, (asection *) NULL, (bfd_vma) 0); irel->r_symndx = 0; } } @@ -2929,8 +2965,9 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, else if (symndx < 0 || (unsigned long) symndx >= obj_raw_syment_count (input_bfd)) { - (*_bfd_error_handler) - ("%B: illegal symbol index %ld in relocs", input_bfd, symndx); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: illegal symbol index %ld in relocs"), input_bfd, symndx); return FALSE; } else @@ -2940,9 +2977,9 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, } /* COFF treats common symbols in one of two ways. Either the - size of the symbol is included in the section contents, or it - is not. We assume that the size is not included, and force - the rtype_to_howto function to adjust the addend as needed. */ + size of the symbol is included in the section contents, or it + is not. We assume that the size is not included, and force + the rtype_to_howto function to adjust the addend as needed. */ if (sym != NULL && sym->n_scnum != 0) addend = - sym->n_value; else @@ -2954,12 +2991,12 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, return FALSE; /* If we are doing a relocatable link, then we can just ignore - a PC relative reloc that is pcrel_offset. It will already - have the correct value. If this is not a relocatable link, - then we should ignore the symbol value. */ + a PC relative reloc that is pcrel_offset. It will already + have the correct value. If this is not a relocatable link, + then we should ignore the symbol value. */ if (howto->pc_relative && howto->pcrel_offset) { - if (info->relocatable) + if (bfd_link_relocatable (info)) continue; if (sym != NULL && sym->n_scnum != 0) addend += sym->n_value; @@ -2977,7 +3014,13 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, else { sec = sections[symndx]; - val = (sec->output_section->vma + + /* PR 19623: Relocations against symbols in + the absolute sections should ignored. */ + if (bfd_is_abs_section (sec)) + continue; + + val = (sec->output_section->vma + sec->output_offset + sym->n_value); if (! obj_pe (input_bfd)) @@ -2998,10 +3041,10 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, else if (h->root.type == bfd_link_hash_undefweak) { - if (h->symbol_class == C_NT_WEAK && h->numaux == 1) + if (h->symbol_class == C_NT_WEAK && h->numaux == 1) { /* See _Microsoft Portable Executable and Common Object - File Format Specification_, section 5.5.3. + File Format Specification_, section 5.5.3. Note that weak symbols without aux records are a GNU extension. FIXME: All weak externals are treated as having @@ -3027,17 +3070,14 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, } } else - /* This is a GNU extension. */ + /* This is a GNU extension. */ val = 0; } - else if (! info->relocatable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma, TRUE))) - return FALSE; - } + else if (! bfd_link_relocatable (info)) + (*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, input_section, + rel->r_vaddr - input_section->vma, TRUE); } /* If the input section defining the symbol has been discarded @@ -3045,7 +3085,7 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, if (sec != NULL && discarded_section (sec)) { _bfd_clear_contents (howto, input_bfd, input_section, - contents + (rel->r_vaddr - input_section->vma)); + contents, rel->r_vaddr - input_section->vma); continue; } @@ -3087,9 +3127,10 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, case bfd_reloc_ok: break; case bfd_reloc_outofrange: - (*_bfd_error_handler) - (_("%B: bad reloc address 0x%lx in section `%A'"), - input_bfd, input_section, (unsigned long) rel->r_vaddr); + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: bad reloc address %#" PRIx64 " in section `%pA'"), + input_bfd, (uint64_t) rel->r_vaddr, input_section); return FALSE; case bfd_reloc_overflow: { @@ -3107,11 +3148,10 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, return FALSE; } - if (! ((*info->callbacks->reloc_overflow) - (info, (h ? &h->root : NULL), name, howto->name, - (bfd_vma) 0, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return FALSE; + (*info->callbacks->reloc_overflow) + (info, (h ? &h->root : NULL), name, howto->name, + (bfd_vma) 0, input_bfd, input_section, + rel->r_vaddr - input_section->vma); } } }