📄 symbol.c
字号:
if (fread(&fhdr, sizeof(struct ecoff_filehdr), 1, fobj) < 1) fatal("cannot read header from executable `%s'", fname); /* record endian of target */ if (fhdr.f_magic != ECOFF_EB_MAGIC && fhdr.f_magic != ECOFF_EL_MAGIC) fatal("bad magic number in executable `%s'", fname); if (fread(&ahdr, sizeof(struct ecoff_aouthdr), 1, fobj) < 1) fatal("cannot read AOUT header from executable `%s'", fname); /* seek to the beginning of the symbolic header */ fseek(fobj, fhdr.f_symptr, 0); if (fread(&symhdr, sizeof(struct ecoff_symhdr_t), 1, fobj) < 1) fatal("could not read symbolic header from executable `%s'", fname); if (symhdr.magic != ECOFF_magicSym) fatal("bad magic number (0x%x) in symbolic header", symhdr.magic); /* allocate space for the string table */ len = symhdr.issMax + symhdr.issExtMax; strtab = (char *)calloc(len, sizeof(char)); if (!strtab) fatal("out of virtual memory"); /* read all the symbol names into memory */ fseek(fobj, symhdr.cbSsOffset, 0); if (fread(strtab, len, 1, fobj) < 0) fatal("error while reading symbol table names"); /* allocate symbol space */ len = symhdr.isymMax + symhdr.iextMax; if (len <= 0) fatal("`%s' has no text or data symbols", fname); sym_db = (struct sym_sym_t *)calloc(len, sizeof(struct sym_sym_t)); if (!sym_db) fatal("out of virtual memory"); /* allocate space for the external symbol entries */ extr = (struct ecoff_EXTR *)calloc(symhdr.iextMax, sizeof(struct ecoff_EXTR)); if (!extr) fatal("out of virtual memory"); fseek(fobj, symhdr.cbExtOffset, 0); if (fread(extr, sizeof(struct ecoff_EXTR), symhdr.iextMax, fobj) < 0) fatal("error reading external symbol entries"); sym_nsyms = 0; sym_ndatasyms = 0; sym_ntextsyms = 0; /* convert symbols to internal format */ for (i=0; i < symhdr.iextMax; i++) { int str_offset; str_offset = symhdr.issMax + extr[i].asym.iss;#if 0 printf("ext %2d: ifd = %2d, iss = %3d, value = %8x, st = %3x, " "sc = %3x, index = %3x\n", i, extr[i].ifd, extr[i].asym.iss, extr[i].asym.value, extr[i].asym.st, extr[i].asym.sc, extr[i].asym.index); printf(" %08x %2d %2d %s\n", extr[i].asym.value, extr[i].asym.st, extr[i].asym.sc, &strtab[str_offset]);#endif switch (extr[i].asym.st) { case ECOFF_stGlobal: case ECOFF_stStatic: /* from data segment */ sym_db[sym_nsyms].name = mystrdup(&strtab[str_offset]); sym_db[sym_nsyms].seg = ss_data; sym_db[sym_nsyms].initialized = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].pub = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].local = /* FIXME: ??? */FALSE; sym_db[sym_nsyms].addr = extr[i].asym.value; sym_nsyms++; sym_ndatasyms++; break; case ECOFF_stProc: case ECOFF_stStaticProc: case ECOFF_stLabel: /* from text segment */ sym_db[sym_nsyms].name = mystrdup(&strtab[str_offset]); sym_db[sym_nsyms].seg = ss_text; sym_db[sym_nsyms].initialized = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].pub = /* FIXME: ??? */TRUE; sym_db[sym_nsyms].local = /* FIXME: ??? */FALSE; sym_db[sym_nsyms].addr = extr[i].asym.value; sym_nsyms++; sym_ntextsyms++; break; default: /* FIXME: ignored... */; } } free(extr); /* done with the executable, close it */ if (fclose(fobj)) fatal("could not close executable `%s'", fname);#endif /* BFD_LOADER */ /* * generate various sortings */ /* all symbols sorted by address and name */ sym_syms = (struct sym_sym_t **)calloc(sym_nsyms, sizeof(struct sym_sym_t *)); if (!sym_syms) fatal("out of virtual memory"); sym_syms_by_name = (struct sym_sym_t **)calloc(sym_nsyms, sizeof(struct sym_sym_t *)); if (!sym_syms_by_name) fatal("out of virtual memory"); for (debug_cnt=0, i=0; i<sym_nsyms; i++) { sym_syms[debug_cnt] = &sym_db[i]; sym_syms_by_name[debug_cnt] = &sym_db[i]; debug_cnt++; } /* sanity check */ if (debug_cnt != sym_nsyms) panic("could not locate all symbols"); /* sort by address */ qsort(sym_syms, sym_nsyms, sizeof(struct sym_sym_t *), (void *)acmp); /* sort by name */ qsort(sym_syms_by_name, sym_nsyms, sizeof(struct sym_sym_t *), (void *)ncmp); /* text segment sorted by address and name */ sym_textsyms = (struct sym_sym_t **)calloc(sym_ntextsyms, sizeof(struct sym_sym_t *)); if (!sym_textsyms) fatal("out of virtual memory"); sym_textsyms_by_name = (struct sym_sym_t **)calloc(sym_ntextsyms, sizeof(struct sym_sym_t *)); if (!sym_textsyms_by_name) fatal("out of virtual memory"); for (debug_cnt=0, i=0; i<sym_nsyms; i++) { if (sym_db[i].seg == ss_text) { sym_textsyms[debug_cnt] = &sym_db[i]; sym_textsyms_by_name[debug_cnt] = &sym_db[i]; debug_cnt++; } } /* sanity check */ if (debug_cnt != sym_ntextsyms) panic("could not locate all text symbols"); /* sort by address */ qsort(sym_textsyms, sym_ntextsyms, sizeof(struct sym_sym_t *), (void *)acmp); /* sort by name */ qsort(sym_textsyms_by_name, sym_ntextsyms, sizeof(struct sym_sym_t *), (void *)ncmp); /* data segment sorted by address and name */ sym_datasyms = (struct sym_sym_t **)calloc(sym_ndatasyms, sizeof(struct sym_sym_t *)); if (!sym_datasyms) fatal("out of virtual memory"); sym_datasyms_by_name = (struct sym_sym_t **)calloc(sym_ndatasyms, sizeof(struct sym_sym_t *)); if (!sym_datasyms_by_name) fatal("out of virtual memory"); for (debug_cnt=0, i=0; i<sym_nsyms; i++) { if (sym_db[i].seg == ss_data) { sym_datasyms[debug_cnt] = &sym_db[i]; sym_datasyms_by_name[debug_cnt] = &sym_db[i]; debug_cnt++; } } /* sanity check */ if (debug_cnt != sym_ndatasyms) panic("could not locate all data symbols"); /* sort by address */ qsort(sym_datasyms, sym_ndatasyms, sizeof(struct sym_sym_t *), (void *)acmp); /* sort by name */ qsort(sym_datasyms_by_name, sym_ndatasyms, sizeof(struct sym_sym_t *), (void *)ncmp); /* compute symbol sizes */ for (i=0; i<sym_ntextsyms; i++) { sym_textsyms[i]->size = (i != (sym_ntextsyms - 1) ? (sym_textsyms[i+1]->addr - sym_textsyms[i]->addr) : ((ld_text_base + ld_text_size) - sym_textsyms[i]->addr)); } for (i=0; i<sym_ndatasyms; i++) { sym_datasyms[i]->size = (i != (sym_ndatasyms - 1) ? (sym_datasyms[i+1]->addr - sym_datasyms[i]->addr) : ((ld_data_base + ld_data_size) - sym_datasyms[i]->addr)); } /* symbols are now available for use */ syms_loaded = TRUE;}/* dump symbol SYM to output stream FD */voidsym_dumpsym(struct sym_sym_t *sym, /* symbol to display */ FILE *fd) /* output stream */{ fprintf(fd, "sym `%s': %s seg, init-%s, pub-%s, local-%s, addr=0x%08x, size=%d\n", sym->name, sym->seg == ss_data ? "data" : "text", sym->initialized ? "y" : "n", sym->pub ? "y" : "n", sym->local ? "y" : "n", sym->addr, sym->size);}/* dump all symbols to output stream FD */voidsym_dumpsyms(FILE *fd) /* output stream */{ int i; for (i=0; i < sym_nsyms; i++) sym_dumpsym(sym_syms[i], fd);}/* dump all symbol state to output stream FD */voidsym_dumpstate(FILE *fd) /* output stream */{ int i; if (fd == NULL) fd = stderr; fprintf(fd, "** All symbols sorted by address:\n"); for (i=0; i < sym_nsyms; i++) sym_dumpsym(sym_syms[i], fd); fprintf(fd, "\n** All symbols sorted by name:\n"); for (i=0; i < sym_nsyms; i++) sym_dumpsym(sym_syms_by_name[i], fd); fprintf(fd, "** Text symbols sorted by address:\n"); for (i=0; i < sym_ntextsyms; i++) sym_dumpsym(sym_textsyms[i], fd); fprintf(fd, "\n** Text symbols sorted by name:\n"); for (i=0; i < sym_ntextsyms; i++) sym_dumpsym(sym_textsyms_by_name[i], fd); fprintf(fd, "** Data symbols sorted by address:\n"); for (i=0; i < sym_ndatasyms; i++) sym_dumpsym(sym_datasyms[i], fd); fprintf(fd, "\n** Data symbols sorted by name:\n"); for (i=0; i < sym_ndatasyms; i++) sym_dumpsym(sym_datasyms_by_name[i], fd);}/* bind address ADDR to a symbol in symbol database DB, the address must match exactly if EXACT is non-zero, the index of the symbol in the requested symbol database is returned in *PINDEX if the pointer is non-NULL */struct sym_sym_t * /* symbol found, or NULL */sym_bind_addr(SS_ADDR_TYPE addr, /* address of symbol to locate */ int *pindex, /* ptr to index result var */ int exact, /* require exact address match? */ enum sym_db_t db) /* symbol database to search */{ int nsyms, low, high, pos; struct sym_sym_t **syms; switch (db) { case sdb_any: syms = sym_syms; nsyms = sym_nsyms; break; case sdb_text: syms = sym_textsyms; nsyms = sym_ntextsyms; break; case sdb_data: syms = sym_datasyms; nsyms = sym_ndatasyms; break; default: panic("bogus symbol database"); } /* any symbols to search? */ if (!nsyms) { if (pindex) *pindex = -1; return NULL; } /* binary search symbol database (sorted by address) */ low = 0; high = nsyms-1; pos = (low + high) >> 1; while (!(/* exact match */ (exact && syms[pos]->addr == addr) /* in bounds match */ || (!exact && syms[pos]->addr <= addr && addr < (syms[pos]->addr + MAX(1, syms[pos]->size))))) { if (addr < syms[pos]->addr) high = pos - 1; else low = pos + 1; if (high >= low) pos = (low + high) >> 1; else { if (pindex) *pindex = -1; return NULL; } } /* bound! */ if (pindex) *pindex = pos; return syms[pos];}/* bind name NAME to a symbol in symbol database DB, the index of the symbol in the requested symbol database is returned in *PINDEX if the pointer is non-NULL */struct sym_sym_t * /* symbol found, or NULL */sym_bind_name(char *name, /* symbol name to locate */ int *pindex, /* ptr to index result var */ enum sym_db_t db) /* symbol database to search */{ int nsyms, low, high, pos, cmp; struct sym_sym_t **syms; switch (db) { case sdb_any: syms = sym_syms_by_name; nsyms = sym_nsyms; break; case sdb_text: syms = sym_textsyms_by_name; nsyms = sym_ntextsyms; break; case sdb_data: syms = sym_datasyms_by_name; nsyms = sym_ndatasyms; break; default: panic("bogus symbol database"); } /* any symbols to search? */ if (!nsyms) { if (pindex) *pindex = -1; return NULL; } /* binary search symbol database (sorted by name) */ low = 0; high = nsyms-1; pos = (low + high) >> 1; while (!(/* exact string match */!(cmp = strcmp(syms[pos]->name, name)))) { if (cmp > 0) high = pos - 1; else low = pos + 1; if (high >= low) pos = (low + high) >> 1; else { if (pindex) *pindex = -1; return NULL; } } /* bound! */ if (pindex) *pindex = pos; return syms[pos];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -