diff options
Diffstat (limited to 'bfd/stabs.c')
-rw-r--r-- | bfd/stabs.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/bfd/stabs.c b/bfd/stabs.c index 23cb24a..04b91f6 100644 --- a/bfd/stabs.c +++ b/bfd/stabs.c @@ -56,17 +56,19 @@ struct stab_link_includes_table }; /* A linked list of totals that we have found for a particular header - file. A total is the sum of all the STABS characters for a particular - file and the number of these charactes. It is used to identify - duplicate files which can be excluded. XXX: A better method would be to - compute an MD5 checksum, but that is coding left for another day. - The bfd_vma type is used because it is a very large unsigned type. */ + file. A total is a unique identifier for a particular BINCL...EINCL + sequence of STABs that can be used to identify duplicate sequences. + It consists of three fields, 'sum_chars' which is the sum of all the + STABS characters; 'num_chars' which is the number of these charactes + and 'symb' which is a buffer of all the symbols in the sequence. This + buffer is only checked as a last resort. */ struct stab_link_includes_totals { struct stab_link_includes_totals *next; bfd_vma sum_chars; /* Accumulated sum of STABS characters. */ bfd_vma num_chars; /* Number of STABS characters. */ + const char* symb; /* The STABS characters themselves. */ }; /* An entry in the header file hash table. */ @@ -347,14 +349,19 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of { bfd_vma sum_chars; bfd_vma num_chars; + bfd_vma buf_len = 0; + char * symb; + char * symb_rover; int nest; - bfd_byte *incl_sym; - struct stab_link_includes_entry *incl_entry; - struct stab_link_includes_totals *t; - struct stab_excl_list *ne; + bfd_byte * incl_sym; + struct stab_link_includes_entry * incl_entry; + struct stab_link_includes_totals * t; + struct stab_excl_list * ne; + symb = symb_rover = NULL; sum_chars = num_chars = 0; nest = 0; + for (incl_sym = sym + STABSIZE; incl_sym < symend; incl_sym += STABSIZE) @@ -383,6 +390,15 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of + bfd_get_32 (abfd, incl_sym + STRDXOFF)); for (; *str != '\0'; str++) { + if (num_chars >= buf_len) + { + buf_len += 32 * 1024; + symb = bfd_realloc (symb, buf_len); + if (symb == NULL) + goto error_return; + symb_rover = symb + num_chars; + } + * symb_rover ++ = * str; sum_chars += *str; num_chars ++; if (*str == '(') @@ -397,6 +413,8 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of } } + BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb)); + /* If we have already included a header file with the same value, then replaced this one with an N_EXCL symbol. */ incl_entry = stab_link_includes_lookup (&sinfo->includes, string, @@ -405,7 +423,9 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of goto error_return; for (t = incl_entry->totals; t != NULL; t = t->next) - if (t->sum_chars == sum_chars && t->num_chars == num_chars) + if (t->sum_chars == sum_chars + && t->num_chars == num_chars + && memcmp (t->symb, symb, num_chars) == 0) break; /* Record this symbol, so that we can set the value @@ -430,6 +450,7 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of goto error_return; t->sum_chars = sum_chars; t->num_chars = num_chars; + t->symb = bfd_realloc (symb, num_chars); /* Trim data down. */ t->next = incl_entry->totals; incl_entry->totals = t; } @@ -441,6 +462,9 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of pass to change the type to N_EXCL. */ ne->type = (int) N_EXCL; + /* Free off superfluous symbols. */ + free (symb); + /* Mark the skipped symbols. */ nest = 0; |