X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcofflink.c;h=63bdcde115deae70f52d4eb543ab1170d2c49d81;hb=8df017996f662ce6ab23aea4abeb8f7ac1f62651;hp=b2b64db95002451e9582ba09174fbfd36412f4d2;hpb=b3adc24a0713411ab38a21dc894dd40dbc5c8f4f;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/cofflink.c b/bfd/cofflink.c index b2b64db950..63bdcde115 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -109,7 +109,7 @@ struct bfd_link_hash_table * _bfd_coff_link_hash_table_create (bfd *abfd) { struct coff_link_hash_table *ret; - bfd_size_type amt = sizeof (struct coff_link_hash_table); + size_t amt = sizeof (struct coff_link_hash_table); ret = (struct coff_link_hash_table *) bfd_malloc (amt); if (ret == NULL) @@ -212,6 +212,12 @@ coff_link_check_archive_element (bfd *abfd, if (h->type != bfd_link_hash_undefined) return TRUE; + /* If the archive element has already been loaded then one + of the symbols defined by that element might have been + made undefined due to being in a discarded section. */ + if (((struct coff_link_hash_entry *) h)->indx == -3) + return TRUE; + /* PR 22369 - Skip non COFF objects in the archive. */ if (! bfd_family_coff (abfd)) return TRUE; @@ -286,6 +292,7 @@ coff_link_add_symbols (bfd *abfd, asection *section; bfd_vma value; bfd_boolean addit; + bfd_boolean discarded = FALSE; /* This symbol is externally visible. */ @@ -311,7 +318,10 @@ coff_link_add_symbols (bfd *abfd, flags = BSF_EXPORT | BSF_GLOBAL; section = coff_section_from_bfd_index (abfd, sym.n_scnum); if (discarded_section (section)) - section = bfd_und_section_ptr; + { + discarded = TRUE; + section = bfd_und_section_ptr; + } else if (! obj_pe (abfd)) value -= section->vma; break; @@ -408,6 +418,9 @@ coff_link_add_symbols (bfd *abfd, (const char *) NULL, copy, FALSE, (struct bfd_link_hash_entry **) sym_hash))) goto error_return; + + if (discarded) + (*sym_hash)->indx = -3; } if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0) @@ -689,7 +702,7 @@ _bfd_coff_final_link (bfd *abfd, rel_filepos += o->reloc_count * relsz; /* In PE COFF, if there are at least 0xffff relocations an extra relocation will be written out to encode the count. */ - if (obj_pe (abfd) && o->reloc_count >= 0xffff) + if ((obj_pe (abfd) || obj_go32 (abfd)) && o->reloc_count >= 0xffff) rel_filepos += relsz; } @@ -993,41 +1006,20 @@ _bfd_coff_final_link (bfd *abfd, coff_debug_merge_hash_table_free (&flaginfo.debug_merge); debug_merge_allocated = FALSE; - if (flaginfo.internal_syms != NULL) - { - free (flaginfo.internal_syms); - flaginfo.internal_syms = NULL; - } - if (flaginfo.sec_ptrs != NULL) - { - free (flaginfo.sec_ptrs); - flaginfo.sec_ptrs = NULL; - } - if (flaginfo.sym_indices != NULL) - { - free (flaginfo.sym_indices); - flaginfo.sym_indices = NULL; - } - if (flaginfo.linenos != NULL) - { - free (flaginfo.linenos); - flaginfo.linenos = NULL; - } - if (flaginfo.contents != NULL) - { - free (flaginfo.contents); - flaginfo.contents = NULL; - } - if (flaginfo.external_relocs != NULL) - { - free (flaginfo.external_relocs); - flaginfo.external_relocs = NULL; - } - if (flaginfo.internal_relocs != NULL) - { - free (flaginfo.internal_relocs); - flaginfo.internal_relocs = NULL; - } + free (flaginfo.internal_syms); + flaginfo.internal_syms = NULL; + free (flaginfo.sec_ptrs); + flaginfo.sec_ptrs = NULL; + free (flaginfo.sym_indices); + flaginfo.sym_indices = NULL; + free (flaginfo.linenos); + flaginfo.linenos = NULL; + free (flaginfo.contents); + flaginfo.contents = NULL; + free (flaginfo.external_relocs); + flaginfo.external_relocs = NULL; + free (flaginfo.internal_relocs); + flaginfo.internal_relocs = NULL; /* The value of the last C_FILE symbol is supposed to be the symbol index of the first external symbol. Write it out again if @@ -1066,11 +1058,8 @@ _bfd_coff_final_link (bfd *abfd, goto error_return; /* The outsyms buffer is used by _bfd_coff_write_global_sym. */ - if (flaginfo.outsyms != NULL) - { - free (flaginfo.outsyms); - flaginfo.outsyms = NULL; - } + free (flaginfo.outsyms); + flaginfo.outsyms = NULL; if (bfd_link_relocatable (info) && max_output_reloc_count > 0) { @@ -1108,7 +1097,7 @@ _bfd_coff_final_link (bfd *abfd, if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0) goto error_return; - if (obj_pe (abfd) && o->reloc_count >= 0xffff) + if ((obj_pe (abfd) || obj_go32 (abfd)) && o->reloc_count >= 0xffff) { /* In PE COFF, write the count of relocs as the first reloc. The header overflow bit will be set @@ -1141,10 +1130,8 @@ _bfd_coff_final_link (bfd *abfd, for (i = 0; i < abfd->section_count; i++) { - if (flaginfo.section_info[i].relocs != NULL) - free (flaginfo.section_info[i].relocs); - if (flaginfo.section_info[i].rel_hashes != NULL) - free (flaginfo.section_info[i].rel_hashes); + free (flaginfo.section_info[i].relocs); + free (flaginfo.section_info[i].rel_hashes); } free (flaginfo.section_info); flaginfo.section_info = NULL; @@ -1203,31 +1190,20 @@ _bfd_coff_final_link (bfd *abfd, for (i = 0; i < abfd->section_count; i++) { - if (flaginfo.section_info[i].relocs != NULL) - free (flaginfo.section_info[i].relocs); - if (flaginfo.section_info[i].rel_hashes != NULL) - free (flaginfo.section_info[i].rel_hashes); + free (flaginfo.section_info[i].relocs); + free (flaginfo.section_info[i].rel_hashes); } free (flaginfo.section_info); } - if (flaginfo.internal_syms != NULL) - free (flaginfo.internal_syms); - if (flaginfo.sec_ptrs != NULL) - free (flaginfo.sec_ptrs); - if (flaginfo.sym_indices != NULL) - free (flaginfo.sym_indices); - if (flaginfo.outsyms != NULL) - free (flaginfo.outsyms); - if (flaginfo.linenos != NULL) - free (flaginfo.linenos); - if (flaginfo.contents != NULL) - free (flaginfo.contents); - if (flaginfo.external_relocs != NULL) - free (flaginfo.external_relocs); - if (flaginfo.internal_relocs != NULL) - free (flaginfo.internal_relocs); - if (external_relocs != NULL) - free (external_relocs); + free (flaginfo.internal_syms); + free (flaginfo.sec_ptrs); + free (flaginfo.sym_indices); + free (flaginfo.outsyms); + free (flaginfo.linenos); + free (flaginfo.contents); + free (flaginfo.external_relocs); + free (flaginfo.internal_relocs); + free (external_relocs); return FALSE; } @@ -1286,8 +1262,7 @@ process_embedded_commands (bfd *output_bfd, if (!bfd_malloc_and_get_section (abfd, sec, ©)) { - if (copy != NULL) - free (copy); + free (copy); return 0; } e = (char *) copy + sec->size; @@ -1647,7 +1622,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd) struct coff_debug_merge_element **epp; bfd_byte *esl, *eslend; struct internal_syment *islp; - bfd_size_type amt; + size_t amt; name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); if (name == NULL) @@ -2605,6 +2580,9 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) return FALSE; case bfd_link_hash_undefined: + if (h->indx == -3) + return TRUE; + /* Fall through. */ case bfd_link_hash_undefweak: isym.n_scnum = N_UNDEF; isym.n_value = 0;