stabs.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 654 行 · 第 1/2 页
C
654 行
struct stab_link_includes_entry *incl_entry; struct stab_link_includes_totals *t; struct stab_excl_list *ne; val = 0; nest = 0; for (incl_sym = sym + STABSIZE; incl_sym < symend; incl_sym += STABSIZE) { int incl_type; incl_type = incl_sym[TYPEOFF]; if (incl_type == 0) break; else if (incl_type == N_EINCL) { if (nest == 0) break; --nest; } else if (incl_type == N_BINCL) ++nest; else if (nest == 0) { const char *str; str = ((char *) stabstrbuf + stroff + bfd_get_32 (abfd, incl_sym + STRDXOFF)); for (; *str != '\0'; str++) { val += *str; if (*str == '(') { /* Skip the file number. */ ++str; while (isdigit ((unsigned char) *str)) ++str; --str; } } } } /* 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, true, true); if (incl_entry == NULL) goto error_return; for (t = incl_entry->totals; t != NULL; t = t->next) if (t->total == val) break; /* Record this symbol, so that we can set the value correctly. */ ne = (struct stab_excl_list *) bfd_alloc (abfd, sizeof *ne); if (ne == NULL) goto error_return; ne->offset = sym - stabbuf; ne->val = val; ne->type = N_BINCL; ne->next = secinfo->excls; secinfo->excls = ne; if (t == NULL) { /* This is the first time we have seen this header file with this set of stabs strings. */ t = ((struct stab_link_includes_totals *) bfd_hash_allocate (&sinfo->includes.root, sizeof *t)); if (t == NULL) goto error_return; t->total = val; t->next = incl_entry->totals; incl_entry->totals = t; } else { bfd_size_type *incl_pstridx; /* We have seen this header file before. Tell the final pass to change the type to N_EXCL. */ ne->type = N_EXCL; /* Mark the skipped symbols. */ nest = 0; for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1; incl_sym < symend; incl_sym += STABSIZE, ++incl_pstridx) { int incl_type; incl_type = incl_sym[TYPEOFF]; if (incl_type == N_EINCL) { if (nest == 0) { *incl_pstridx = (bfd_size_type) -1; ++skip; break; } --nest; } else if (incl_type == N_BINCL) ++nest; else if (nest == 0) { *incl_pstridx = (bfd_size_type) -1; ++skip; } } } } } free (stabbuf); stabbuf = NULL; free (stabstrbuf); stabstrbuf = NULL; /* We need to set the section sizes such that the linker will compute the output section sizes correctly. We set the .stab size to not include the entries we don't want. We set SEC_EXCLUDE for the .stabstr section, so that it will be dropped from the link. We record the size of the strtab in the first .stabstr section we saw, and make sure we don't set SEC_EXCLUDE for that section. */ stabsec->_cooked_size = (count - skip) * STABSIZE; if (stabsec->_cooked_size == 0) stabsec->flags |= SEC_EXCLUDE; stabstrsec->flags |= SEC_EXCLUDE; sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings); /* Calculate the `cumulative_skips' array now that stabs have been deleted for this section. */ if (skip != 0) { bfd_size_type i, offset; bfd_size_type *pskips; secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, count * sizeof (bfd_size_type)); if (secinfo->cumulative_skips == NULL) goto error_return; pskips = secinfo->cumulative_skips; pstridx = secinfo->stridxs; offset = 0; for (i = 0; i < count; i++, pskips++, pstridx++) { *pskips = offset; if (*pstridx == (bfd_size_type) -1) offset += STABSIZE; } BFD_ASSERT (offset != 0); } return true; error_return: if (stabbuf != NULL) free (stabbuf); if (stabstrbuf != NULL) free (stabstrbuf); return false;}/* Write out the stab section. This is called with the relocated contents. */boolean_bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents) bfd *output_bfd; PTR *psinfo; asection *stabsec; PTR *psecinfo; bfd_byte *contents;{ struct stab_info *sinfo; struct stab_section_info *secinfo; struct stab_excl_list *e; bfd_byte *sym, *tosym, *symend; bfd_size_type *pstridx; sinfo = (struct stab_info *) *psinfo; secinfo = (struct stab_section_info *) *psecinfo; if (secinfo == NULL) return bfd_set_section_contents (output_bfd, stabsec->output_section, contents, stabsec->output_offset, stabsec->_raw_size); /* Handle each N_BINCL entry. */ for (e = secinfo->excls; e != NULL; e = e->next) { bfd_byte *excl_sym; BFD_ASSERT (e->offset < stabsec->_raw_size); excl_sym = contents + e->offset; bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF); excl_sym[TYPEOFF] = e->type; } /* Copy over all the stabs symbols, omitting the ones we don't want, and correcting the string indices for those we do want. */ tosym = contents; symend = contents + stabsec->_raw_size; for (sym = contents, pstridx = secinfo->stridxs; sym < symend; sym += STABSIZE, ++pstridx) { if (*pstridx != (bfd_size_type) -1) { if (tosym != sym) memcpy (tosym, sym, STABSIZE); bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF); if (sym[TYPEOFF] == 0) { /* This is the header symbol for the stabs section. We don't really need one, since we have merged all the input stabs sections into one, but we generate one for the benefit of readers which expect to see one. */ BFD_ASSERT (sym == contents); bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings), tosym + VALOFF); bfd_put_16 (output_bfd, stabsec->output_section->_raw_size / STABSIZE - 1, tosym + DESCOFF); } tosym += STABSIZE; } } BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size); return bfd_set_section_contents (output_bfd, stabsec->output_section, contents, stabsec->output_offset, stabsec->_cooked_size);}/* Write out the .stabstr section. */boolean_bfd_write_stab_strings (output_bfd, psinfo) bfd *output_bfd; PTR *psinfo;{ struct stab_info *sinfo; sinfo = (struct stab_info *) *psinfo; if (sinfo == NULL) return true; if (bfd_is_abs_section (sinfo->stabstr->output_section)) { /* The section was discarded from the link. */ return true; } BFD_ASSERT ((sinfo->stabstr->output_offset + _bfd_stringtab_size (sinfo->strings)) <= sinfo->stabstr->output_section->_raw_size); if (bfd_seek (output_bfd, (sinfo->stabstr->output_section->filepos + sinfo->stabstr->output_offset), SEEK_SET) != 0) return false; if (! _bfd_stringtab_emit (output_bfd, sinfo->strings)) return false; /* We no longer need the stabs information. */ _bfd_stringtab_free (sinfo->strings); bfd_hash_table_free (&sinfo->includes.root); return true;}/* Adjust an address in the .stab section. Given OFFSET within STABSEC, this returns the new offset in the adjusted stab section, or -1 if the address refers to a stab which has been removed. */bfd_vma_bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset) bfd *output_bfd ATTRIBUTE_UNUSED; PTR *psinfo ATTRIBUTE_UNUSED; asection *stabsec; PTR *psecinfo; bfd_vma offset;{ struct stab_section_info *secinfo; secinfo = (struct stab_section_info *) *psecinfo; if (secinfo == NULL) return offset; if (offset >= stabsec->_raw_size) return offset - (stabsec->_cooked_size - stabsec->_raw_size); if (secinfo->cumulative_skips) { bfd_vma i; i = offset / STABSIZE; if (secinfo->stridxs [i] == (bfd_size_type) -1) return (bfd_vma) -1; return offset - secinfo->cumulative_skips [i]; } return offset;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?