X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Fcoffgen.c;h=5474f6c24d8d35d513ebb0fe36912aae236d649a;hb=784712bf4fed9507cb807277ac64d07686bab2c1;hp=b13e7732962bcdc52b6e66d1291b5da46d11a5e1;hpb=97834047e13bb9f30430331c27b11412a5ed6950;p=binutils-gdb.git diff --git a/bfd/coffgen.c b/bfd/coffgen.c index b13e7732962..5474f6c24d8 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -847,6 +847,34 @@ coff_mangle_symbols (bfd *bfd_ptr) } } +static void +coff_write_auxent_fname (bfd *abfd, + char *str, + union internal_auxent *auxent, + bfd_size_type *string_size_p) +{ + unsigned int str_length = strlen (str); + unsigned int filnmlen = bfd_coff_filnmlen (abfd); + + if (bfd_coff_long_filenames (abfd)) + { + if (str_length <= filnmlen) + strncpy (auxent->x_file.x_n.x_fname, str, filnmlen); + else + { + auxent->x_file.x_n.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; + auxent->x_file.x_n.x_n.x_zeroes = 0; + *string_size_p += str_length + 1; + } + } + else + { + strncpy (auxent->x_file.x_n.x_fname, str, filnmlen); + if (str_length > filnmlen) + str[filnmlen] = '\0'; + } +} + static void coff_fix_symbol_name (bfd *abfd, asymbol *symbol, @@ -856,7 +884,6 @@ coff_fix_symbol_name (bfd *abfd, bfd_size_type *debug_string_size_p) { unsigned int name_length; - union internal_auxent *auxent; char *name = (char *) (symbol->name); if (name == NULL) @@ -871,8 +898,6 @@ coff_fix_symbol_name (bfd *abfd, if (native->u.syment.n_sclass == C_FILE && native->u.syment.n_numaux > 0) { - unsigned int filnmlen; - if (bfd_coff_force_symnames_in_strings (abfd)) { native->u.syment._n._n_n._n_offset = @@ -884,27 +909,8 @@ coff_fix_symbol_name (bfd *abfd, strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); BFD_ASSERT (! (native + 1)->is_sym); - auxent = &(native + 1)->u.auxent; - - filnmlen = bfd_coff_filnmlen (abfd); - - if (bfd_coff_long_filenames (abfd)) - { - if (name_length <= filnmlen) - strncpy (auxent->x_file.x_fname, name, filnmlen); - else - { - auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; - auxent->x_file.x_n.x_zeroes = 0; - *string_size_p += name_length + 1; - } - } - else - { - strncpy (auxent->x_file.x_fname, name, filnmlen); - if (name_length > filnmlen) - name[filnmlen] = '\0'; - } + coff_write_auxent_fname (abfd, name, &(native + 1)->u.auxent, + string_size_p); } else { @@ -1029,6 +1035,14 @@ coff_write_symbol (bfd *abfd, for (j = 0; j < native->u.syment.n_numaux; j++) { BFD_ASSERT (! (native + j + 1)->is_sym); + + /* Adjust auxent only if this isn't the filename + auxiliary entry. */ + if (native->u.syment.n_sclass == C_FILE + && (native + j + 1)->u.auxent.x_file.x_ftype) + coff_write_auxent_fname (abfd, (char *) (native + j + 1)->extrap, + &(native + j + 1)->u.auxent, string_size_p); + bfd_coff_swap_aux_out (abfd, &((native + j + 1)->u.auxent), type, n_sclass, (int) j, @@ -1358,6 +1372,7 @@ coff_write_symbols (bfd *abfd) size_t name_length = strlen (q->name); coff_symbol_type *c_symbol = coff_symbol_from (q); size_t maxlen; + bool is_c_file = false; /* Figure out whether the symbol name should go in the string table. Symbol names that are short enough are stored @@ -1384,6 +1399,7 @@ coff_write_symbols (bfd *abfd) else if (c_symbol->native->u.syment.n_sclass == C_FILE && c_symbol->native->u.syment.n_numaux > 0) { + is_c_file=true; if (bfd_coff_force_symnames_in_strings (abfd)) { if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) @@ -1400,6 +1416,35 @@ coff_write_symbols (bfd *abfd) abfd) != name_length + 1) return false; } + + /* Add strings for C_FILE aux entries. */ + if (is_c_file + && c_symbol->native->u.syment.n_numaux > 1) + { + for (int j = 1; j < c_symbol->native->u.syment.n_numaux; j++) + { + char *str; + size_t str_length; + + /* Add strings from aux entries only if this isn't the + filename auxiliary entry. */ + if (!c_symbol->native[j + 1].u.auxent.x_file.x_ftype) + continue; + + if (c_symbol->native[j + 1].u.auxent.x_file.x_n.x_fname[0] != 0) + continue; + + str = (char *) c_symbol->native[j + 1].extrap; + str_length = strlen (str); + if (str_length > maxlen) + { + if (bfd_bwrite ((void *) (str), (bfd_size_type) str_length + 1, + abfd) != str_length + 1) + return false; + } + + } + } } } else @@ -1662,8 +1707,10 @@ _bfd_coff_read_string_table (bfd *abfd) char extstrsize[STRING_SIZE_SIZE]; bfd_size_type strsize; char *strings; - file_ptr pos; + ufile_ptr pos; ufile_ptr filesize; + size_t symesz; + size_t size; if (obj_coff_strings (abfd) != NULL) return obj_coff_strings (abfd); @@ -1674,9 +1721,16 @@ _bfd_coff_read_string_table (bfd *abfd) return NULL; } + symesz = bfd_coff_symesz (abfd); pos = obj_sym_filepos (abfd); - pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd); - if (bfd_seek (abfd, pos, SEEK_SET) != 0) + if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size) + || pos + size < pos) + { + bfd_set_error (bfd_error_file_truncated); + return NULL; + } + + if (bfd_seek (abfd, pos + size, SEEK_SET) != 0) return NULL; if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd) @@ -1798,7 +1852,7 @@ coff_get_normalized_symtab (bfd *abfd) /* Mark the end of the symbols. */ symesz = bfd_coff_symesz (abfd); - raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz; + raw_end = PTR_ADD (raw_src, obj_raw_syment_count (abfd) * symesz); /* FIXME SOMEDAY. A string table size of zero is very weird, but probably possible. If one shows up, it will probably kill us. */ @@ -1863,7 +1917,7 @@ coff_get_normalized_symtab (bfd *abfd) the text ".file" is redundant. */ BFD_ASSERT (! aux->is_sym); - if (aux->u.auxent.x_file.x_n.x_zeroes == 0) + if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0) { /* The filename is a long one, point into the string table. */ if (string_table == NULL) @@ -1873,12 +1927,12 @@ coff_get_normalized_symtab (bfd *abfd) return NULL; } - if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_offset) + if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset) >= obj_coff_strings_len (abfd)) internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _(""); else internal_ptr->u.syment._n._n_n._n_offset = - (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_offset)); + (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_n.x_offset)); } else { @@ -1890,15 +1944,48 @@ coff_get_normalized_symtab (bfd *abfd) internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) copy_name (abfd, - aux->u.auxent.x_file.x_fname, + aux->u.auxent.x_file.x_n.x_fname, internal_ptr->u.syment.n_numaux * symesz); else internal_ptr->u.syment._n._n_n._n_offset = ((bfd_hostptr_t) copy_name (abfd, - aux->u.auxent.x_file.x_fname, + aux->u.auxent.x_file.x_n.x_fname, (size_t) bfd_coff_filnmlen (abfd))); } + + /* Normalize other strings available in C_FILE aux entries. */ + if (!coff_data (abfd)->pe) + for (int numaux = 1; numaux < internal_ptr->u.syment.n_numaux; numaux++) + { + aux = internal_ptr + numaux + 1; + BFD_ASSERT (! aux->is_sym); + + if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0) + { + /* The string information is a long one, point into the string table. */ + if (string_table == NULL) + { + string_table = _bfd_coff_read_string_table (abfd); + if (string_table == NULL) + return NULL; + } + + if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset) + >= obj_coff_strings_len (abfd)) + aux->u.auxent.x_file.x_n.x_n.x_offset = (bfd_hostptr_t) _(""); + else + aux->u.auxent.x_file.x_n.x_n.x_offset = + (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_n.x_offset)); + } + else + aux->u.auxent.x_file.x_n.x_n.x_offset = + ((bfd_hostptr_t) + copy_name (abfd, + aux->u.auxent.x_file.x_n.x_fname, + (size_t) bfd_coff_filnmlen (abfd))); + } + } else { @@ -1987,7 +2074,7 @@ coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) return -1; } #endif - return (asect->reloc_count + 1) * sizeof (arelent *); + return (asect->reloc_count + 1L) * sizeof (arelent *); } asymbol * @@ -2043,8 +2130,10 @@ coff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret) if (coffsymbol (symbol)->native != NULL && coffsymbol (symbol)->native->fix_value && coffsymbol (symbol)->native->is_sym) - ret->value = coffsymbol (symbol)->native->u.syment.n_value - - (bfd_hostptr_t) obj_raw_syments (abfd); + ret->value = + ((coffsymbol (symbol)->native->u.syment.n_value - + (bfd_hostptr_t) obj_raw_syments (abfd)) + / sizeof (combined_entry_type)); } /* Print out information about COFF symbol. */ @@ -2092,7 +2181,8 @@ coff_print_symbol (bfd *abfd, if (! combined->fix_value) val = (bfd_vma) combined->u.syment.n_value; else - val = combined->u.syment.n_value - (bfd_hostptr_t) root; + val = ((combined->u.syment.n_value - (bfd_hostptr_t) root) + / sizeof (combined_entry_type)); fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x", combined->u.syment.n_scnum, @@ -2123,6 +2213,12 @@ coff_print_symbol (bfd *abfd, { case C_FILE: fprintf (file, "File "); + /* Add additional information if this isn't the filename + auxiliary entry. */ + if (auxp->u.auxent.x_file.x_ftype) + fprintf (file, "ftype %d fname \"%s\"", + auxp->u.auxent.x_file.x_ftype, + (char *) auxp->u.auxent.x_file.x_n.x_n.x_offset); break; case C_DWARF: