📄 coffread.c
字号:
This puts the block in the list after all its subblocks. */ pblock = (struct pending_block *) xmalloc (sizeof (struct pending_block)); pblock->block = block; if (opblock) { pblock->next = opblock->next; opblock->next = pblock; } else { pblock->next = pending_blocks; pending_blocks = pblock; }}static struct blockvector *make_blockvector (objfile) struct objfile *objfile;{ register struct pending_block *next, *next1; register struct blockvector *blockvector; register int i; /* Count the length of the list of blocks. */ for (next = pending_blocks, i = 0; next; next = next->next, i++); blockvector = (struct blockvector *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector) + (i - 1) * sizeof (struct block *)); /* Copy the blocks into the blockvector. This is done in reverse order, which happens to put the blocks into the proper order (ascending starting address). coff_finish_block has hair to insert each block into the list after its subblocks in order to make sure this is true. */ BLOCKVECTOR_NBLOCKS (blockvector) = i; for (next = pending_blocks; next; next = next->next) BLOCKVECTOR_BLOCK (blockvector, --i) = next->block; /* Now free the links of the list, and empty the list. */ for (next = pending_blocks; next; next = next1) { next1 = next->next; free ((PTR)next); } pending_blocks = 0; return blockvector;}/* Manage the vector of line numbers. */static voidcoff_record_line (line, pc) int line; CORE_ADDR pc;{ struct linetable_entry *e; /* Make sure line vector is big enough. */ if (line_vector_index + 2 >= line_vector_length) { line_vector_length *= 2; line_vector = (struct linetable *) xrealloc ((char *) line_vector, sizeof (struct linetable) + (line_vector_length * sizeof (struct linetable_entry))); } e = line_vector->item + line_vector_index++; e->line = line; e->pc = pc;}/* Start a new symtab for a new source file. This is called when a COFF ".file" symbol is seen; it indicates the start of data for one original source file. */static voidcoff_start_symtab (){ coff_file_symbols = 0; coff_global_symbols = 0; coff_context_stack = 0; within_function = 0; last_source_file = NULL; /* Initialize the source file line number information for this file. */ if (line_vector) /* Unlikely, but maybe possible? */ free ((PTR)line_vector); line_vector_index = 0; line_vector_length = 1000; prev_line_number = -2; /* Force first line number to be explicit */ line_vector = (struct linetable *) xmalloc (sizeof (struct linetable) + line_vector_length * sizeof (struct linetable_entry));}/* Save the vital information from when starting to read a file, for use when closing off the current file. NAME is the file name the symbols came from, START_ADDR is the first text address for the file, and SIZE is the number of bytes of text. */static voidcomplete_symtab (name, start_addr, size) char *name; CORE_ADDR start_addr; unsigned int size;{ last_source_file = savestring (name, strlen (name)); cur_src_start_addr = start_addr; cur_src_end_addr = start_addr + size; if (current_objfile -> ei.entry_point >= cur_src_start_addr && current_objfile -> ei.entry_point < cur_src_end_addr) { current_objfile -> ei.entry_file_lowpc = cur_src_start_addr; current_objfile -> ei.entry_file_highpc = cur_src_end_addr; }}/* Finish the symbol definitions for one main source file, close off all the lexical contexts for that file (creating struct block's for them), then make the struct symtab for that file and put it in the list of all such. */static voidcoff_end_symtab (objfile) struct objfile *objfile;{ register struct symtab *symtab; register struct coff_context_stack *cstk; register struct blockvector *blockvector; register struct linetable *lv; /* Finish the lexical context of the last function in the file. */ if (coff_context_stack) { cstk = coff_context_stack; coff_context_stack = 0; /* Make a block for the local symbols within. */ coff_finish_block (cstk->name, &coff_local_symbols, cstk->old_blocks, cstk->start_addr, cur_src_end_addr, objfile); free ((PTR)cstk); } /* Ignore a file that has no functions with real debugging info. */ if (pending_blocks == 0 && coff_file_symbols == 0 && coff_global_symbols == 0) { free ((PTR)line_vector); line_vector = 0; line_vector_length = -1; last_source_file = NULL; return; } /* It is unfortunate that in amdcoff, pending blocks might not be ordered in this stage. Especially, blocks for static functions will show up at the end. We need to sort them, so tools like `find_pc_function' and `find_pc_block' can work reliably. */ if (pending_blocks) { /* FIXME! Remove this horrid bubble sort and use qsort!!! */ int swapped; do { struct pending_block *pb, *pbnext; pb = pending_blocks, pbnext = pb->next; swapped = 0; while ( pbnext ) { /* swap blocks if unordered! */ if (BLOCK_START(pb->block) < BLOCK_START(pbnext->block)) { struct block *tmp = pb->block; complain (&misordered_blocks_complaint, (char *) BLOCK_START (pb->block)); pb->block = pbnext->block; pbnext->block = tmp; swapped = 1; } pb = pbnext; pbnext = pbnext->next; } } while (swapped); } /* Create the two top-level blocks for this file (STATIC_BLOCK and GLOBAL_BLOCK). */ coff_finish_block (0, &coff_file_symbols, 0, cur_src_start_addr, cur_src_end_addr, objfile); coff_finish_block (0, &coff_global_symbols, 0, cur_src_start_addr, cur_src_end_addr, objfile); /* Create the blockvector that points to all the file's blocks. */ blockvector = make_blockvector (objfile); /* Now create the symtab object for this source file. */ symtab = allocate_symtab (last_source_file, objfile); /* Fill in its components. */ symtab->blockvector = blockvector; symtab->free_code = free_linetable; symtab->free_ptr = 0; symtab->filename = last_source_file; symtab->dirname = NULL; lv = line_vector; lv->nitems = line_vector_index; symtab->linetable = (struct linetable *) xrealloc ((char *) lv, (sizeof (struct linetable) + lv->nitems * sizeof (struct linetable_entry))); free_named_symtabs (symtab->filename); /* Reinitialize for beginning of new file. */ line_vector = 0; line_vector_length = -1; last_source_file = NULL;}static voidrecord_minimal_symbol (name, address, type) char *name; CORE_ADDR address; enum minimal_symbol_type type;{ /* We don't want TDESC entry points in the minimal symbol table */ if (name[0] == '@') return; /* mst_text isn't true, but apparently COFF doesn't tell us what it really is, so this guess is more useful than mst_unknown. */ prim_record_minimal_symbol (savestring (name, strlen (name)), address, type);}/* coff_symfile_init () is the coff-specific initialization routine for reading symbols. It is passed a struct objfile which contains, among other things, the BFD for the file whose symbols are being read, and a slot for a pointer to "private data" which we fill with cookies and other treats for coff_symfile_read (). We will only be called if this is a COFF or COFF-like file. BFD handles figuring out the format of the file, and code in symtab.c uses BFD's determination to vector to us. The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */struct coff_symfile_info { file_ptr min_lineno_offset; /* Where in file lowest line#s are */ file_ptr max_lineno_offset; /* 1+last byte of line#s in file */};static int text_bfd_scnum;static voidcoff_symfile_init (objfile) struct objfile *objfile;{ asection *section; bfd *abfd = objfile->obfd; /* Allocate struct to keep track of the symfile */ objfile -> sym_private = xmmalloc (objfile -> md, sizeof (struct coff_symfile_info)); init_entry_point_info (objfile); /* Save the section number for the text section */ section = bfd_get_section_by_name(abfd,".text"); if (section) text_bfd_scnum = section->index; else text_bfd_scnum = -1; }/* This function is called for every section; it finds the outer limits of the line table (minimum and maximum file offset) so that the mainline code can read the whole thing for efficiency. *//* ARGSUSED */static voidfind_linenos (abfd, asect, vpinfo) bfd *abfd; sec_ptr asect; PTR vpinfo;{ struct coff_symfile_info *info; int size, count; file_ptr offset, maxoff;/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ count = asect->lineno_count;/* End of warning */ if (count == 0) return; size = count * local_linesz; info = (struct coff_symfile_info *)vpinfo;/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ offset = asect->line_filepos;/* End of warning */ if (offset < info->min_lineno_offset || info->min_lineno_offset == 0) info->min_lineno_offset = offset; maxoff = offset + size; if (maxoff > info->max_lineno_offset) info->max_lineno_offset = maxoff;}/* The BFD for this file -- only good while we're actively reading symbols into a psymtab or a symtab. */static bfd *symfile_bfd;/* Read a symbol file, after initialization by coff_symfile_init. *//* FIXME! Addr and Mainline are not used yet -- this will not work for shared libraries or add_file! *//* ARGSUSED */static voidcoff_symfile_read (objfile, section_offsets, mainline) struct objfile *objfile; struct section_offsets *section_offsets; int mainline;{ struct coff_symfile_info *info; bfd *abfd = objfile->obfd; coff_data_type *cdata = coff_data (abfd); char *name = bfd_get_filename (abfd); int desc; register int val; int num_symbols; int symtab_offset; int stringtab_offset; info = (struct coff_symfile_info *) objfile -> sym_private; symfile_bfd = abfd; /* Kludge for swap routines *//* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ desc = fileno ((FILE *)(abfd->iostream)); /* File descriptor */ num_symbols = bfd_get_symcount (abfd); /* How many syms */ symtab_offset = cdata->sym_filepos; /* Symbol table file offset */ stringtab_offset = symtab_offset + /* String table file offset */ num_symbols * cdata->local_symesz; /* Set a few file-statics that give us specific information about the particular COFF file format we're reading. */ local_linesz = cdata->local_linesz; local_n_btmask = cdata->local_n_btmask; local_n_btshft = cdata->local_n_btshft; local_n_tmask = cdata->local_n_tmask; local_n_tshift = cdata->local_n_tshift; local_linesz = cdata->local_linesz; local_symesz = cdata->local_symesz; local_auxesz = cdata->local_auxesz; /* Allocate space for raw symbol and aux entries, based on their space requirements as reported by BFD. */ temp_sym = (char *) xmalloc (cdata->local_symesz + cdata->local_auxesz); temp_aux = temp_sym + cdata->local_symesz; make_cleanup (free_current_contents, &temp_sym);/* End of warning */ /* Read the line number table, all at once. */ info->min_lineno_offset = 0; info->max_lineno_offset = 0; bfd_map_over_sections (abfd, find_linenos, (PTR)info); val = init_lineno (desc, info->min_lineno_offset, info->max_lineno_offset - info->min_lineno_offset); if (val < 0) error ("\"%s\": error reading line numbers\n", name); /* Now read the string table, all at once. */ val = init_stringtab (desc, stringtab_offset); if (val < 0) error ("\"%s\": can't get string table", name); make_cleanup (free_stringtab, 0); init_minimal_symbol_collection (); make_cleanup (discard_minimal_symbols, 0); /* Now that the executable file is positioned at symbol table, process it and define symbols accordingly. */ read_coff_symtab ((long)symtab_offset, num_symbols, objfile); /* Sort symbols alphabetically within each block. */ sort_all_symtab_syms (); /* Install any minimal symbols that have been collected as the current minimal symbols for this objfile. */ install_minimal_symbols (objfile);}static voidcoff_new_init (ignore) struct objfile *ignore;{ /* Nothin' to do */}/* Perform any local cleanups required when we are done with a particular objfile. I.E, we are in the process of discarding all symbol information for an objfile, freeing up all memory held for it, and unlinking the objfile struct from the global list of known objfiles. */static voidcoff_symfile_finish (objfile) struct objfile *objfile;{ if (objfile -> sym_private != NULL) { mfree (objfile -> md, objfile -> sym_private); }}/* Given pointers to a symbol table in coff style exec file, analyze them and create struct symtab's describing the symbols. NSYMS is the number of symbols in the symbol table. We read them one at a time using read_one_sym (). */static voidread_coff_symtab (symtab_offset, nsyms, objfile) long symtab_offset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -