X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcoffgen.c;h=53aaf4fbc510f956fe877ac93e17e8b77f82db81;hb=1865dcb816777a2805861caebdb8439db213789d;hp=8724715116fb489fba3b45ae45d4bb3a4e06487e;hpb=f5d3fb7587e9edae76435e029b7325eb8adee465;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 8724715116..53aaf4fbc5 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1,5 +1,6 @@ /* Support for the generic parts of COFF, for BFD. - Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -283,18 +284,14 @@ coff_object_p (abfd) opthdr = bfd_alloc (abfd, aoutsz); if (opthdr == NULL) return 0;; - if (bfd_read (opthdr, 1, aoutsz, abfd) != aoutsz) + if (bfd_read (opthdr, 1, internal_f.f_opthdr, abfd) + != internal_f.f_opthdr) { return 0; } - bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) & internal_a); + bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a); } - /* Seek past the opt hdr stuff */ - if (bfd_seek (abfd, (file_ptr) (internal_f.f_opthdr + filhsz), SEEK_SET) - != 0) - return NULL; - return coff_real_object_p (abfd, nscns, &internal_f, (internal_f.f_opthdr != 0 ? &internal_a @@ -562,7 +559,7 @@ coff_count_linenumbers (abfd) /*ARGSUSED*/ coff_symbol_type * coff_symbol_from (ignore_abfd, symbol) - bfd *ignore_abfd; + bfd *ignore_abfd ATTRIBUTE_UNUSED; asymbol *symbol; { if (bfd_asymbol_flavour (symbol) != bfd_target_coff_flavour) @@ -597,6 +594,7 @@ fixup_symbol_value (abfd, coff_symbol_ptr, syment) syment->n_scnum = N_UNDEF; syment->n_value = 0; } + /* FIXME: Do we need to handle the absolute section here? */ else { if (coff_symbol_ptr->symbol.section) @@ -661,16 +659,18 @@ coff_renumber_symbols (bfd_ptr, first_undef) if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 || (!bfd_is_und_section (symbol_ptr_ptr[i]->section) && !bfd_is_com_section (symbol_ptr_ptr[i]->section) - && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_FUNCTION)) - != BSF_GLOBAL))) + && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0 + || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) + == 0)))) *newsyms++ = symbol_ptr_ptr[i]; for (i = 0; i < symbol_count; i++) if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 && !bfd_is_und_section (symbol_ptr_ptr[i]->section) && (bfd_is_com_section (symbol_ptr_ptr[i]->section) - || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_FUNCTION)) - == BSF_GLOBAL))) + || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0 + && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) + != 0)))) *newsyms++ = symbol_ptr_ptr[i]; *first_undef = newsyms - bfd_ptr->outsymbols; @@ -1035,6 +1035,8 @@ coff_write_alien_symbol (abfd, symbol, written, string_size_p, native->u.syment.n_type = 0; if (symbol->flags & BSF_LOCAL) native->u.syment.n_sclass = C_STAT; + else if (symbol->flags & BSF_WEAK) + native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT; else native->u.syment.n_sclass = C_EXT; native->u.syment.n_numaux = 0; @@ -1350,7 +1352,7 @@ coff_write_linenumbers (abfd) /*ARGSUSED */ alent * coff_get_lineno (ignore_abfd, symbol) - bfd *ignore_abfd; + bfd *ignore_abfd ATTRIBUTE_UNUSED; asymbol *symbol; { return coffsymbol (symbol)->lineno; @@ -1420,8 +1422,8 @@ coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent) unsigned int indaux; combined_entry_type *auxent; { - int type = symbol->u.syment.n_type; - int class = symbol->u.syment.n_sclass; + unsigned int type = symbol->u.syment.n_type; + unsigned int class = symbol->u.syment.n_sclass; if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) { @@ -1603,7 +1605,7 @@ _bfd_coff_read_string_table (abfd) if (strsize < STRING_SIZE_SIZE) { (*_bfd_error_handler) - ("%s: bad string table size %lu", bfd_get_filename (abfd), + (_("%s: bad string table size %lu"), bfd_get_filename (abfd), (unsigned long) strsize); bfd_set_error (bfd_error_bad_value); return NULL; @@ -1745,10 +1747,26 @@ coff_get_normalized_symtab (abfd) } else { - /* ordinary short filename, put into memory anyway */ - internal_ptr->u.syment._n._n_n._n_offset = (long) - copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname, - FILNMLEN); + /* Ordinary short filename, put into memory anyway. The + Microsoft PE tools sometimes store a filename in + multiple AUX entries. */ + if (internal_ptr->u.syment.n_numaux > 1 + && coff_data (abfd)->pe) + { + internal_ptr->u.syment._n._n_n._n_offset = + ((long) + copy_name (abfd, + (internal_ptr + 1)->u.auxent.x_file.x_fname, + internal_ptr->u.syment.n_numaux * symesz)); + } + else + { + internal_ptr->u.syment._n._n_n._n_offset = + ((long) + copy_name (abfd, + (internal_ptr + 1)->u.auxent.x_file.x_fname, + FILNMLEN)); + } } } else @@ -1846,8 +1864,8 @@ coff_make_empty_symbol (abfd) asymbol * coff_bfd_make_debug_symbol (abfd, ptr, sz) bfd *abfd; - PTR ptr; - unsigned long sz; + PTR ptr ATTRIBUTE_UNUSED; + unsigned long sz ATTRIBUTE_UNUSED; { coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type)); if (new == NULL) @@ -2094,10 +2112,10 @@ coff_print_symbol (abfd, filep, symbol, how) boolean _bfd_coff_is_local_label_name (abfd, name) - bfd *abfd; + bfd *abfd ATTRIBUTE_UNUSED; const char *name; { - return ((name[0] == '.' && name[1] == 'L') ? true : false); + return name[0] == '.' && name[1] == 'L'; } /* Provided a BFD, a section and an offset into the section, calculate @@ -2162,9 +2180,11 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, if (p < pend) { + bfd_vma sec_vma; bfd_vma maxdiff; /* Look through the C_FILE symbols to find the best one. */ + sec_vma = bfd_get_section_vma (abfd, section); *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; maxdiff = (bfd_vma) 0 - (bfd_vma) 1; while (1) @@ -2187,12 +2207,14 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, } } + /* We use <= MAXDIFF here so that if we get a zero length + file, we actually use the next file entry. */ if (p2 < pend - && offset >= (bfd_vma) p2->u.syment.n_value - && offset - (bfd_vma) p2->u.syment.n_value < maxdiff) + && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value + && offset + sec_vma - (bfd_vma) p2->u.syment.n_value <= maxdiff) { *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; - maxdiff = offset - p2->u.syment.n_value; + maxdiff = offset + sec_vma - p2->u.syment.n_value; } /* Avoid endless loops on erroneous files by ensuring that @@ -2226,6 +2248,8 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, if (section->lineno != NULL) { + bfd_vma last_value = 0; + l = §ion->lineno[i]; for (; i < section->lineno_count; i++) @@ -2237,6 +2261,7 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, if (coff->symbol.value > offset) break; *functionname_ptr = coff->symbol.name; + last_value = coff->symbol.value; if (coff->native) { combined_entry_type *s = coff->native; @@ -2259,12 +2284,26 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, } else { - if (l->u.offset + bfd_get_section_vma (abfd, section) > offset) + if (l->u.offset > offset) break; *line_ptr = l->line_number + line_base - 1; } l++; } + + /* If we fell off the end of the loop, then assume that this + symbol has no line number info. Otherwise, symbols with no + line number info get reported with the line number of the + last line of the last symbol which does have line number + info. We use 0x100 as a slop to account for cases where the + last line has executable code. */ + if (i >= section->lineno_count + && last_value != 0 + && offset - last_value > 0x100) + { + *functionname_ptr = NULL; + *line_ptr = 0; + } } /* Cache the results for the next call. */ @@ -2305,3 +2344,71 @@ coff_sizeof_headers (abfd, reloc) size += abfd->section_count * bfd_coff_scnhsz (abfd); return size; } + +/* Change the class of a coff symbol held by BFD. */ +boolean +bfd_coff_set_symbol_class (abfd, symbol, class) + bfd * abfd; + asymbol * symbol; + unsigned int class; +{ + coff_symbol_type * csym; + + csym = coff_symbol_from (abfd, symbol); + if (csym == NULL) + { + bfd_set_error (bfd_error_invalid_operation); + return false; + } + else if (csym->native == NULL) + { + /* This is an alien symbol which no native coff backend data. + We cheat here by creating a fake native entry for it and + then filling in the class. This code is based on that in + coff_write_alien_symbol(). */ + + combined_entry_type * native; + + native = (combined_entry_type *) bfd_alloc (abfd, sizeof (* native)); + if (native == NULL) + return false; + + memset (native, 0, sizeof (* native)); + + native->u.syment.n_type = T_NULL; + native->u.syment.n_sclass = class; + + if (bfd_is_und_section (symbol->section)) + { + native->u.syment.n_scnum = N_UNDEF; + native->u.syment.n_value = symbol->value; + } + else if (bfd_is_com_section (symbol->section)) + { + native->u.syment.n_scnum = N_UNDEF; + native->u.syment.n_value = symbol->value; + } + else + { + native->u.syment.n_scnum = + symbol->section->output_section->target_index; + native->u.syment.n_value = (symbol->value + + symbol->section->output_offset); + if (! obj_pe (abfd)) + native->u.syment.n_value += symbol->section->output_section->vma; + + /* Copy the any flags from the the file header into the symbol. + FIXME: Why? */ + native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags; + } + + csym->native = native; + } + else + { + csym->native->u.syment.n_sclass = class; + } + + return true; +} +