📄 minsyms.c
字号:
msym_bunch -> contents[msym_bunch_index].name = (char *) name; msym_bunch -> contents[msym_bunch_index].address = address; msym_bunch -> contents[msym_bunch_index].info = NULL; msym_bunch -> contents[msym_bunch_index].type = ms_type; msym_bunch_index++; msym_count++;}voidprim_record_minimal_symbol_and_info (name, address, ms_type, info) const char *name; CORE_ADDR address; enum minimal_symbol_type ms_type; char *info;{ register struct msym_bunch *new; if (msym_bunch_index == BUNCH_SIZE) { new = (struct msym_bunch *) xmalloc (sizeof (struct msym_bunch)); msym_bunch_index = 0; new -> next = msym_bunch; msym_bunch = new; } msym_bunch -> contents[msym_bunch_index].name = (char *) name; msym_bunch -> contents[msym_bunch_index].address = address; msym_bunch -> contents[msym_bunch_index].info = NULL; msym_bunch -> contents[msym_bunch_index].type = ms_type; /* FIXME: This info, if it remains, needs its own field. */ msym_bunch -> contents[msym_bunch_index].info = info; /* FIXME! */ msym_bunch_index++; msym_count++;}/* Compare two minimal symbols by address and return a signed result based on unsigned comparisons, so that we sort into unsigned numeric order. */static intcompare_minimal_symbols (fn1p, fn2p) const PTR fn1p; const PTR fn2p;{ register const struct minimal_symbol *fn1; register const struct minimal_symbol *fn2; fn1 = (const struct minimal_symbol *) fn1p; fn2 = (const struct minimal_symbol *) fn2p; if (fn1 -> address < fn2 -> address) { return (-1); } else if (fn1 -> address > fn2 -> address) { return (1); } else { return (0); }}/* Discard the currently collected minimal symbols, if any. If we wish to save them for later use, we must have already copied them somewhere else before calling this function. FIXME: We could allocate the minimal symbol bunches on their own obstack and then simply blow the obstack away when we are done with it. Is it worth the extra trouble though? *//* ARGSUSED */voiddiscard_minimal_symbols (foo) int foo;{ register struct msym_bunch *next; while (msym_bunch != NULL) { next = msym_bunch -> next; free ((PTR)msym_bunch); msym_bunch = next; }}/* Compact duplicate entries out of a minimal symbol table by walking through the table and compacting out entries with duplicate addresses and matching names. Return the number of entries remaining. On entry, the table resides between msymbol[0] and msymbol[mcount]. On exit, it resides between msymbol[0] and msymbol[result_count]. When files contain multiple sources of symbol information, it is possible for the minimal symbol table to contain many duplicate entries. As an example, SVR4 systems use ELF formatted object files, which usually contain at least two different types of symbol tables (a standard ELF one and a smaller dynamic linking table), as well as DWARF debugging information for files compiled with -g. Without compacting, the minimal symbol table for gdb itself contains over a 1000 duplicates, about a third of the total table size. Aside from the potential trap of not noticing that two successive entries identify the same location, this duplication impacts the time required to linearly scan the table, which is done in a number of places. So we just do one linear scan here and toss out the duplicates. Note that we are not concerned here about recovering the space that is potentially freed up, because the strings themselves are allocated on the symbol_obstack, and will get automatically freed when the symbol table is freed. The caller can free up the unused minimal symbols at the end of the compacted region if their allocation strategy allows it. Also note we only go up to the next to last entry within the loop and then copy the last entry explicitly after the loop terminates. Since the different sources of information for each symbol may have different levels of "completeness", we may have duplicates that have one entry with type "mst_unknown" and the other with a known type. So if the one we are leaving alone has type mst_unknown, overwrite its type with the type from the one we are compacting out. */static intcompact_minimal_symbols (msymbol, mcount) struct minimal_symbol *msymbol; int mcount;{ struct minimal_symbol *copyfrom; struct minimal_symbol *copyto; if (mcount > 0) { copyfrom = copyto = msymbol; while (copyfrom < msymbol + mcount - 1) { if (copyfrom -> address == (copyfrom + 1) -> address && (strcmp (copyfrom -> name, (copyfrom + 1) -> name) == 0)) { if ((copyfrom + 1) -> type == mst_unknown) { (copyfrom + 1) -> type = copyfrom -> type; } copyfrom++; } else { *copyto++ = *copyfrom++; } } *copyto++ = *copyfrom++; mcount = copyto - msymbol; } return (mcount);}/* Add the minimal symbols in the existing bunches to the objfile's official minimal symbol table. 99% of the time, this adds the bunches to NO existing symbols. Once in a while for shared libraries, we add symbols (e.g. common symbols) to an existing objfile. */voidinstall_minimal_symbols (objfile) struct objfile *objfile;{ register int bindex; register int mcount; register struct msym_bunch *bunch; register struct minimal_symbol *msymbols; int alloc_count; if (msym_count > 0) { /* Allocate enough space in the obstack, into which we will gather the bunches of new and existing minimal symbols, sort them, and then compact out the duplicate entries. Once we have a final table, we will give back the excess space. */ alloc_count = msym_count + objfile->minimal_symbol_count + 1; obstack_blank (&objfile->symbol_obstack, alloc_count * sizeof (struct minimal_symbol)); msymbols = (struct minimal_symbol *) obstack_base (&objfile->symbol_obstack); /* Copy in the existing minimal symbols, if there are any. */ if (objfile->minimal_symbol_count) memcpy ((char *)msymbols, (char *)objfile->msymbols, objfile->minimal_symbol_count * sizeof (struct minimal_symbol)); /* Walk through the list of minimal symbol bunches, adding each symbol to the new contiguous array of symbols. Note that we start with the current, possibly partially filled bunch (thus we use the current msym_bunch_index for the first bunch we copy over), and thereafter each bunch is full. */ mcount = objfile->minimal_symbol_count; for (bunch = msym_bunch; bunch != NULL; bunch = bunch -> next) { for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++) { msymbols[mcount] = bunch -> contents[bindex];#ifdef NAMES_HAVE_UNDERSCORE if (msymbols[mcount].name[0] == '_') { msymbols[mcount].name++; }#endif#ifdef SOME_NAMES_HAVE_DOT if (msymbols[mcount].name[0] == '.') { msymbols[mcount].name++; }#endif } msym_bunch_index = BUNCH_SIZE; } /* Sort the minimal symbols by address. */ qsort (msymbols, mcount, sizeof (struct minimal_symbol), compare_minimal_symbols); /* Compact out any duplicates, and free up whatever space we are no longer using. */ mcount = compact_minimal_symbols (msymbols, mcount); obstack_blank (&objfile->symbol_obstack, (mcount + 1 - alloc_count) * sizeof (struct minimal_symbol)); msymbols = (struct minimal_symbol *) obstack_finish (&objfile->symbol_obstack); /* We also terminate the minimal symbol table with a "null symbol", which is *not* included in the size of the table. This makes it easier to find the end of the table when we are handed a pointer to some symbol in the middle of it. Zero out the fields in the "null symbol" allocated at the end of the array. Note that the symbol count does *not* include this null symbol, which is why it is indexed by mcount and not mcount-1. */ msymbols[mcount].name = NULL; msymbols[mcount].address = 0; msymbols[mcount].info = NULL; msymbols[mcount].type = mst_unknown; /* Attach the minimal symbol table to the specified objfile. The strings themselves are also located in the symbol_obstack of this objfile. */ objfile -> minimal_symbol_count = mcount; objfile -> msymbols = msymbols; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -