ecofflink.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,153 行 · 第 1/5 页
C
2,153 行
const struct ecoff_debug_swap *swap; boolean relocateable; boolean (*get_extr) PARAMS ((asymbol *, EXTR *)); void (*set_index) PARAMS ((asymbol *, bfd_size_type));{ HDRR * const symhdr = &debug->symbolic_header; asymbol **sym_ptr_ptr; size_t c; sym_ptr_ptr = bfd_get_outsymbols (abfd); if (sym_ptr_ptr == NULL) return true; for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++) { asymbol *sym_ptr; EXTR esym; sym_ptr = *sym_ptr_ptr; /* Get the external symbol information. */ if ((*get_extr) (sym_ptr, &esym) == false) continue; /* If we're producing an executable, move common symbols into bss. */ if (relocateable == false) { if (esym.asym.sc == scCommon) esym.asym.sc = scBss; else if (esym.asym.sc == scSCommon) esym.asym.sc = scSBss; } if (bfd_is_com_section (sym_ptr->section) || bfd_is_und_section (sym_ptr->section) || sym_ptr->section->output_section == (asection *) NULL) { /* FIXME: gas does not keep the value of a small undefined symbol in the symbol itself, because of relocation problems. */ if (esym.asym.sc != scSUndefined || esym.asym.value == 0 || sym_ptr->value != 0) esym.asym.value = sym_ptr->value; } else esym.asym.value = (sym_ptr->value + sym_ptr->section->output_offset + sym_ptr->section->output_section->vma); if (set_index) (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax); if (! bfd_ecoff_debug_one_external (abfd, debug, swap, sym_ptr->name, &esym)) return false; } return true;}/* Add a single external symbol to the debugging information. */booleanbfd_ecoff_debug_one_external (abfd, debug, swap, name, esym) bfd *abfd; struct ecoff_debug_info *debug; const struct ecoff_debug_swap *swap; const char *name; EXTR *esym;{ const bfd_size_type external_ext_size = swap->external_ext_size; void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR)) = swap->swap_ext_out; HDRR * const symhdr = &debug->symbolic_header; size_t namelen; namelen = strlen (name); if ((size_t) (debug->ssext_end - debug->ssext) < symhdr->issExtMax + namelen + 1) { if (ecoff_add_bytes ((char **) &debug->ssext, (char **) &debug->ssext_end, symhdr->issExtMax + namelen + 1) == false) return false; } if ((size_t) ((char *) debug->external_ext_end - (char *) debug->external_ext) < (symhdr->iextMax + 1) * external_ext_size) { if (ecoff_add_bytes ((char **) &debug->external_ext, (char **) &debug->external_ext_end, (symhdr->iextMax + 1) * external_ext_size) == false) return false; } esym->asym.iss = symhdr->issExtMax; (*swap_ext_out) (abfd, esym, ((char *) debug->external_ext + symhdr->iextMax * swap->external_ext_size)); ++symhdr->iextMax; strcpy (debug->ssext + symhdr->issExtMax, name); symhdr->issExtMax += namelen + 1; return true;}/* Align the ECOFF debugging information. */static voidecoff_align_debug (abfd, debug, swap) bfd *abfd ATTRIBUTE_UNUSED; struct ecoff_debug_info *debug; const struct ecoff_debug_swap *swap;{ HDRR * const symhdr = &debug->symbolic_header; bfd_size_type debug_align, aux_align, rfd_align; size_t add; /* Adjust the counts so that structures are aligned. */ debug_align = swap->debug_align; aux_align = debug_align / sizeof (union aux_ext); rfd_align = debug_align / swap->external_rfd_size; add = debug_align - (symhdr->cbLine & (debug_align - 1)); if (add != debug_align) { if (debug->line != (unsigned char *) NULL) memset ((PTR) (debug->line + symhdr->cbLine), 0, add); symhdr->cbLine += add; } add = debug_align - (symhdr->issMax & (debug_align - 1)); if (add != debug_align) { if (debug->ss != (char *) NULL) memset ((PTR) (debug->ss + symhdr->issMax), 0, add); symhdr->issMax += add; } add = debug_align - (symhdr->issExtMax & (debug_align - 1)); if (add != debug_align) { if (debug->ssext != (char *) NULL) memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add); symhdr->issExtMax += add; } add = aux_align - (symhdr->iauxMax & (aux_align - 1)); if (add != aux_align) { if (debug->external_aux != (union aux_ext *) NULL) memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0, add * sizeof (union aux_ext)); symhdr->iauxMax += add; } add = rfd_align - (symhdr->crfd & (rfd_align - 1)); if (add != rfd_align) { if (debug->external_rfd != (PTR) NULL) memset ((PTR) ((char *) debug->external_rfd + symhdr->crfd * swap->external_rfd_size), 0, (size_t) (add * swap->external_rfd_size)); symhdr->crfd += add; }}/* Return the size required by the ECOFF debugging information. */bfd_size_typebfd_ecoff_debug_size (abfd, debug, swap) bfd *abfd; struct ecoff_debug_info *debug; const struct ecoff_debug_swap *swap;{ bfd_size_type tot; ecoff_align_debug (abfd, debug, swap); tot = swap->external_hdr_size;#define ADD(count, size) \ tot += debug->symbolic_header.count * size ADD (cbLine, sizeof (unsigned char)); ADD (idnMax, swap->external_dnr_size); ADD (ipdMax, swap->external_pdr_size); ADD (isymMax, swap->external_sym_size); ADD (ioptMax, swap->external_opt_size); ADD (iauxMax, sizeof (union aux_ext)); ADD (issMax, sizeof (char)); ADD (issExtMax, sizeof (char)); ADD (ifdMax, swap->external_fdr_size); ADD (crfd, swap->external_rfd_size); ADD (iextMax, swap->external_ext_size);#undef ADD return tot;}/* Write out the ECOFF symbolic header, given the file position it is going to be placed at. This assumes that the counts are set correctly. */static booleanecoff_write_symhdr (abfd, debug, swap, where) bfd *abfd; struct ecoff_debug_info *debug; const struct ecoff_debug_swap *swap; file_ptr where;{ HDRR * const symhdr = &debug->symbolic_header; char *buff = NULL; ecoff_align_debug (abfd, debug, swap); /* Go to the right location in the file. */ if (bfd_seek (abfd, where, SEEK_SET) != 0) return false; where += swap->external_hdr_size; symhdr->magic = swap->sym_magic; /* Fill in the file offsets. */#define SET(offset, count, size) \ if (symhdr->count == 0) \ symhdr->offset = 0; \ else \ { \ symhdr->offset = where; \ where += symhdr->count * size; \ } SET (cbLineOffset, cbLine, sizeof (unsigned char)); SET (cbDnOffset, idnMax, swap->external_dnr_size); SET (cbPdOffset, ipdMax, swap->external_pdr_size); SET (cbSymOffset, isymMax, swap->external_sym_size); SET (cbOptOffset, ioptMax, swap->external_opt_size); SET (cbAuxOffset, iauxMax, sizeof (union aux_ext)); SET (cbSsOffset, issMax, sizeof (char)); SET (cbSsExtOffset, issExtMax, sizeof (char)); SET (cbFdOffset, ifdMax, swap->external_fdr_size); SET (cbRfdOffset, crfd, swap->external_rfd_size); SET (cbExtOffset, iextMax, swap->external_ext_size);#undef SET buff = (PTR) bfd_malloc ((size_t) swap->external_hdr_size); if (buff == NULL && swap->external_hdr_size != 0) goto error_return; (*swap->swap_hdr_out) (abfd, symhdr, buff); if (bfd_write (buff, 1, swap->external_hdr_size, abfd) != swap->external_hdr_size) goto error_return; if (buff != NULL) free (buff); return true; error_return: if (buff != NULL) free (buff); return false;}/* Write out the ECOFF debugging information. This function assumes that the information (the pointers and counts) in *DEBUG have been set correctly. WHERE is the position in the file to write the information to. This function fills in the file offsets in the symbolic header. */booleanbfd_ecoff_write_debug (abfd, debug, swap, where) bfd *abfd; struct ecoff_debug_info *debug; const struct ecoff_debug_swap *swap; file_ptr where;{ HDRR * const symhdr = &debug->symbolic_header; if (! ecoff_write_symhdr (abfd, debug, swap, where)) return false;#define WRITE(ptr, count, size, offset) \ BFD_ASSERT (symhdr->offset == 0 \ || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \ if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \ != size * symhdr->count) \ return false; WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset); WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset); WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset); WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset); WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset); WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset); WRITE (ss, issMax, sizeof (char), cbSsOffset); WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset); WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset); WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset); WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);#undef WRITE return true;}/* Write out a shuffle list. */static boolean ecoff_write_shuffle PARAMS ((bfd *, const struct ecoff_debug_swap *, struct shuffle *, PTR space));static booleanecoff_write_shuffle (abfd, swap, shuffle, space) bfd *abfd; const struct ecoff_debug_swap *swap; struct shuffle *shuffle; PTR space;{ register struct shuffle *l; unsigned long total; total = 0; for (l = shuffle; l != (struct shuffle *) NULL; l = l->next) { if (! l->filep) { if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size) return false; } else { if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0 || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size || bfd_write (space, 1, l->size, abfd) != l->size) return false; } total += l->size; } if ((total & (swap->debug_align - 1)) != 0) { unsigned int i; bfd_byte *s; i = swap->debug_align - (total & (swap->debug_align - 1)); s = (bfd_byte *) bfd_malloc (i); if (s == NULL && i != 0) return false; memset ((PTR) s, 0, i); if (bfd_write ((PTR) s, 1, i, abfd) != i) { free (s); return false; } free (s); } return true;}/* Write out debugging information using accumulated linker information. */booleanbfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) PTR handle; bfd *abfd; struct ecoff_debug_info *debug; const struct ecoff_debug_swap *swap; struct bfd_link_info *info; file_ptr where;{ struct accumulate *ainfo = (struct accumulate *) handle; PTR space = NULL; if (! ecoff_write_symhdr (abfd, debug, swap, where)) goto error_return; space = (PTR) bfd_malloc (ainfo->largest_file_shuffle); if (space == NULL && ainfo->largest_file_shuffle != 0) goto error_return; if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space) || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space)) goto error_return; /* The string table is written out from the hash table if this is a final link. */ if (info->relocateable) { BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL); if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space)) goto error_return; } else { unsigned long total; bfd_byte null; struct string_hash_entry *sh; BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL); null = 0; if (bfd_write ((PTR) &null, 1, 1, abfd) != 1) goto error_return; total = 1; BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1); for (sh = ainfo->ss_hash; sh != (struct string_hash_entry *) NULL; sh = sh->next) { size_t len; len = strlen (sh->root.string); if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1) goto error_return; total += len + 1; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?