ecoff.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,282 行 · 第 1/5 页
C
2,282 行
const struct ecoff_debug_swap * const debug_swap = &ecoff_backend (abfd)->debug_swap; struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info; struct ecoff_find_line *line_info; /* Make sure we have the FDR's. */ if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, debug_info) || bfd_get_symcount (abfd) == 0) return false; if (ecoff_data (abfd)->find_line_info == NULL) { ecoff_data (abfd)->find_line_info = ((struct ecoff_find_line *) bfd_zalloc (abfd, sizeof (struct ecoff_find_line))); if (ecoff_data (abfd)->find_line_info == NULL) return false; } line_info = ecoff_data (abfd)->find_line_info; return _bfd_ecoff_locate_line (abfd, section, offset, debug_info, debug_swap, line_info, filename_ptr, functionname_ptr, retline_ptr);}/* Copy private BFD data. This is called by objcopy and strip. We use it to copy the ECOFF debugging information from one BFD to the other. It would be theoretically possible to represent the ECOFF debugging information in the symbol table. However, it would be a lot of work, and there would be little gain (gas, gdb, and ld already access the ECOFF debugging information via the ecoff_debug_info structure, and that structure would have to be retained in order to support ECOFF debugging in MIPS ELF). The debugging information for the ECOFF external symbols comes from the symbol table, so this function only handles the other debugging information. */boolean_bfd_ecoff_bfd_copy_private_bfd_data (ibfd, obfd) bfd *ibfd; bfd *obfd;{ struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info; struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info; register int i; asymbol **sym_ptr_ptr; size_t c; boolean local; /* We only want to copy information over if both BFD's use ECOFF format. */ if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour || bfd_get_flavour (obfd) != bfd_target_ecoff_flavour) return true; /* Copy the GP value and the register masks. */ ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp; ecoff_data (obfd)->gprmask = ecoff_data (ibfd)->gprmask; ecoff_data (obfd)->fprmask = ecoff_data (ibfd)->fprmask; for (i = 0; i < 3; i++) ecoff_data (obfd)->cprmask[i] = ecoff_data (ibfd)->cprmask[i]; /* Copy the version stamp. */ oinfo->symbolic_header.vstamp = iinfo->symbolic_header.vstamp; /* If there are no symbols, don't copy any debugging information. */ c = bfd_get_symcount (obfd); sym_ptr_ptr = bfd_get_outsymbols (obfd); if (c == 0 || sym_ptr_ptr == (asymbol **) NULL) return true; /* See if there are any local symbols. */ local = false; for (; c > 0; c--, sym_ptr_ptr++) { if (ecoffsymbol (*sym_ptr_ptr)->local) { local = true; break; } } if (local) { /* There are some local symbols. We just bring over all the debugging information. FIXME: This is not quite the right thing to do. If the user has asked us to discard all debugging information, then we are probably going to wind up keeping it because there will probably be some local symbol which objcopy did not discard. We should actually break apart the debugging information and only keep that which applies to the symbols we want to keep. */ oinfo->symbolic_header.ilineMax = iinfo->symbolic_header.ilineMax; oinfo->symbolic_header.cbLine = iinfo->symbolic_header.cbLine; oinfo->line = iinfo->line; oinfo->symbolic_header.idnMax = iinfo->symbolic_header.idnMax; oinfo->external_dnr = iinfo->external_dnr; oinfo->symbolic_header.ipdMax = iinfo->symbolic_header.ipdMax; oinfo->external_pdr = iinfo->external_pdr; oinfo->symbolic_header.isymMax = iinfo->symbolic_header.isymMax; oinfo->external_sym = iinfo->external_sym; oinfo->symbolic_header.ioptMax = iinfo->symbolic_header.ioptMax; oinfo->external_opt = iinfo->external_opt; oinfo->symbolic_header.iauxMax = iinfo->symbolic_header.iauxMax; oinfo->external_aux = iinfo->external_aux; oinfo->symbolic_header.issMax = iinfo->symbolic_header.issMax; oinfo->ss = iinfo->ss; oinfo->symbolic_header.ifdMax = iinfo->symbolic_header.ifdMax; oinfo->external_fdr = iinfo->external_fdr; oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd; oinfo->external_rfd = iinfo->external_rfd; } else { /* We are discarding all the local symbol information. Look through the external symbols and remove all references to FDR or aux information. */ c = bfd_get_symcount (obfd); sym_ptr_ptr = bfd_get_outsymbols (obfd); for (; c > 0; c--, sym_ptr_ptr++) { EXTR esym; (*(ecoff_backend (obfd)->debug_swap.swap_ext_in)) (obfd, ecoffsymbol (*sym_ptr_ptr)->native, &esym); esym.ifd = ifdNil; esym.asym.index = indexNil; (*(ecoff_backend (obfd)->debug_swap.swap_ext_out)) (obfd, &esym, ecoffsymbol (*sym_ptr_ptr)->native); } } return true;}/* Set the architecture. The supported architecture is stored in the backend pointer. We always set the architecture anyhow, since many callers ignore the return value. */boolean_bfd_ecoff_set_arch_mach (abfd, arch, machine) bfd *abfd; enum bfd_architecture arch; unsigned long machine;{ bfd_default_set_arch_mach (abfd, arch, machine); return arch == ecoff_backend (abfd)->arch;}/* Get the size of the section headers. */int_bfd_ecoff_sizeof_headers (abfd, reloc) bfd *abfd; boolean reloc ATTRIBUTE_UNUSED;{ asection *current; int c; int ret; c = 0; for (current = abfd->sections; current != (asection *)NULL; current = current->next) ++c; ret = (bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd) + c * bfd_coff_scnhsz (abfd)); return BFD_ALIGN (ret, 16);}/* Get the contents of a section. */boolean_bfd_ecoff_get_section_contents (abfd, section, location, offset, count) bfd *abfd; asection *section; PTR location; file_ptr offset; bfd_size_type count;{ return _bfd_generic_get_section_contents (abfd, section, location, offset, count);}/* Sort sections by VMA, but put SEC_ALLOC sections first. This is called via qsort. */static intecoff_sort_hdrs (arg1, arg2) const PTR arg1; const PTR arg2;{ const asection *hdr1 = *(const asection **) arg1; const asection *hdr2 = *(const asection **) arg2; if ((hdr1->flags & SEC_ALLOC) != 0) { if ((hdr2->flags & SEC_ALLOC) == 0) return -1; } else { if ((hdr2->flags & SEC_ALLOC) != 0) return 1; } if (hdr1->vma < hdr2->vma) return -1; else if (hdr1->vma > hdr2->vma) return 1; else return 0;}/* Calculate the file position for each section, and set reloc_filepos. */static booleanecoff_compute_section_file_positions (abfd) bfd *abfd;{ file_ptr sofar, file_sofar; asection **sorted_hdrs; asection *current; unsigned int i; file_ptr old_sofar; boolean rdata_in_text; boolean first_data, first_nonalloc; const bfd_vma round = ecoff_backend (abfd)->round; sofar = _bfd_ecoff_sizeof_headers (abfd, false); file_sofar = sofar; /* Sort the sections by VMA. */ sorted_hdrs = (asection **) bfd_malloc (abfd->section_count * sizeof (asection *)); if (sorted_hdrs == NULL) return false; for (current = abfd->sections, i = 0; current != NULL; current = current->next, i++) sorted_hdrs[i] = current; BFD_ASSERT (i == abfd->section_count); qsort (sorted_hdrs, abfd->section_count, sizeof (asection *), ecoff_sort_hdrs); /* Some versions of the OSF linker put the .rdata section in the text segment, and some do not. */ rdata_in_text = ecoff_backend (abfd)->rdata_in_text; if (rdata_in_text) { for (i = 0; i < abfd->section_count; i++) { current = sorted_hdrs[i]; if (strcmp (current->name, _RDATA) == 0) break; if ((current->flags & SEC_CODE) == 0 && strcmp (current->name, _PDATA) != 0 && strcmp (current->name, _RCONST) != 0) { rdata_in_text = false; break; } } } ecoff_data (abfd)->rdata_in_text = rdata_in_text; first_data = true; first_nonalloc = true; for (i = 0; i < abfd->section_count; i++) { unsigned int alignment_power; current = sorted_hdrs[i]; /* For the Alpha ECOFF .pdata section the lnnoptr field is supposed to indicate the number of .pdata entries that are really in the section. Each entry is 8 bytes. We store this away in line_filepos before increasing the section size. */ if (strcmp (current->name, _PDATA) == 0) current->line_filepos = current->_raw_size / 8; alignment_power = current->alignment_power; /* On Ultrix, the data sections in an executable file must be aligned to a page boundary within the file. This does not affect the section size, though. FIXME: Does this work for other platforms? It requires some modification for the Alpha, because .rdata on the Alpha goes with the text, not the data. */ if ((abfd->flags & EXEC_P) != 0 && (abfd->flags & D_PAGED) != 0 && ! first_data && (current->flags & SEC_CODE) == 0 && (! rdata_in_text || strcmp (current->name, _RDATA) != 0) && strcmp (current->name, _PDATA) != 0 && strcmp (current->name, _RCONST) != 0) { sofar = (sofar + round - 1) &~ (round - 1); file_sofar = (file_sofar + round - 1) &~ (round - 1); first_data = false; } else if (strcmp (current->name, _LIB) == 0) { /* On Irix 4, the location of contents of the .lib section from a shared library section is also rounded up to a page boundary. */ sofar = (sofar + round - 1) &~ (round - 1); file_sofar = (file_sofar + round - 1) &~ (round - 1); } else if (first_nonalloc && (current->flags & SEC_ALLOC) == 0 && (abfd->flags & D_PAGED) != 0) { /* Skip up to the next page for an unallocated section, such as the .comment section on the Alpha. This leaves room for the .bss section. */ first_nonalloc = false; sofar = (sofar + round - 1) &~ (round - 1); file_sofar = (file_sofar + round - 1) &~ (round - 1); } /* Align the sections in the file to the same boundary on which they are aligned in virtual memory. */ sofar = BFD_ALIGN (sofar, 1 << alignment_power); if ((current->flags & SEC_HAS_CONTENTS) != 0) file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power); if ((abfd->flags & D_PAGED) != 0 && (current->flags & SEC_ALLOC) != 0) { sofar += (current->vma - sofar) % round; if ((current->flags & SEC_HAS_CONTENTS) != 0) file_sofar += (current->vma - file_sofar) % round; } if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) != 0) current->filepos = file_sofar; sofar += current->_raw_size; if ((current->flags & SEC_HAS_CONTENTS) != 0) file_sofar += current->_raw_size; /* make sure that this section is of the right size too */ old_sofar = sofar; sofar = BFD_ALIGN (sofar, 1 << alignment_power); if ((current->flags & SEC_HAS_CONTENTS) != 0) file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power); current->_raw_size += sofar - old_sofar; } free (sorted_hdrs); sorted_hdrs = NULL; ecoff_data (abfd)->reloc_filepos = file_sofar; return true;}/* Determine the location of the relocs for all the sections in the output file, as well as the location of the symbolic debugging information. */static bfd_size_typeecoff_compute_reloc_file_positions (abfd) bfd *abfd;{ const bfd_size_type external_reloc_size = ecoff_backend (abfd)->external_reloc_size; file_ptr reloc_base; bfd_size_type reloc_size; asection *current; file_ptr sym_base; if (! abfd->output_has_begun) { if (! ecoff_compute_section_file_positions (abfd)) abort (); abfd->output_has_begun = true; } reloc_base = ecoff_data (abfd)->reloc_filepos; reloc_size = 0; for (current = abfd->sections; current != (asection *)NULL; current = current->next) { if (current->reloc_count == 0) current->rel_filepos = 0; else { bfd_size_type relsize; current->rel_filepos = reloc_base; relsize = current->reloc_count * external_reloc_size; reloc_size += relsize; reloc_base += relsize; } } sym_base = ecoff_data (abfd)->reloc_filepos + reloc_size; /* At least on Ultrix, the symbol table of an executable file must be aligned to a page boundary. FIXME: Is this true on other platforms? */ if ((abfd->flags & EXEC_P) != 0 && (abfd->flags & D_PAGED) != 0) sym_base = ((sym_base + ecoff_backend (abfd)->round - 1) &~ (ecoff_backend (abfd)->round - 1)); ecoff_data (abfd)->sym_filepos = sym_base; return reloc_size;}/* Set the contents of a section. */boolean_bfd_ecoff_set_section_contents (abfd, section, location, offset, count) bfd *abfd; asection *section; PTR location; file_ptr offset; bfd_size_type count;{ /* This must be done first, because bfd_set_section_contents is going to set output_has_begun to true. */ if (abfd->output_has_begun == false) { if (! ecoff_compute_section_file_positions (abfd)) return false; } /* Handle the .lib section specially so that Irix 4 shared libraries work out. See coff_set_section_contents in coffcode.h. */ if (strcmp (section->name, _LIB) == 0) { bfd_byte *rec, *recend; rec
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?