⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbol.c

📁 体系机构仿真
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * symbol.c - program symbol and line data routines * * This file is a part of the SimpleScalar tool suite written by * Todd M. Austin as a part of the Multiscalar Research Project. *   * The tool suite is currently maintained by Doug Burger and Todd M. Austin. *  * Copyright (C) 1994, 1995, 1996, 1997 by Todd M. Austin * * This source file is distributed "as is" in the hope that it will be * useful.  The tool set comes with no warranty, and no author or * distributor accepts any responsibility for the consequences of its * use.  *  * Everyone is granted permission to copy, modify and redistribute * this tool set under the following conditions: *  *    This source code is distributed for non-commercial use only.  *    Please contact the maintainer for restrictions applying to  *    commercial use. * *    Permission is granted to anyone to make or distribute copies *    of this source code, either as received or modified, in any *    medium, provided that all copyright notices, permission and *    nonwarranty notices are preserved, and that the distributor *    grants the recipient permission for further redistribution as *    permitted by this document. * *    Permission is granted to distribute this file in compiled *    or executable form under the same conditions that apply for *    source code, provided that either: * *    A. it is accompanied by the corresponding machine-readable *       source code, *    B. it is accompanied by a written offer, with no time limit, *       to give anyone a machine-readable copy of the corresponding *       source code in return for reimbursement of the cost of *       distribution.  This written offer must permit verbatim *       duplication by anyone, or *    C. it is distributed by someone who received only the *       executable form, and is accompanied by a copy of the *       written offer of source code that they received concurrently. * * In other words, you are welcome to use, share and improve this * source file.  You are forbidden to forbid anyone else to use, share * and improve what you give them. * * INTERNET: dburger@cs.wisc.edu * US Mail:  1210 W. Dayton Street, Madison, WI 53706 * * $Id: symbol.c,v 1.2 1997/04/16 22:11:50 taustin Exp taustin $ * * $Log: symbol.c,v $ * Revision 1.2  1997/04/16  22:11:50  taustin * added standalone loader support * * Revision 1.1  1997/03/11  01:34:45  taustin * Initial revision * * */#include <stdio.h>#include <stdlib.h>#ifdef BFD_LOADER#include <bfd.h>#else /* !BFD_LOADER */#include "ecoff.h"#endif /* BFD_LOADER */#include "misc.h"#include "loader.h"#include "symbol.h"/* #define PRINT_SYMS *//* symbol database in no particular order */struct sym_sym_t *sym_db = NULL;/* all symbol sorted by address */int sym_nsyms = 0;struct sym_sym_t **sym_syms = NULL;/* all symbols sorted by name */struct sym_sym_t **sym_syms_by_name = NULL;/* text symbols sorted by address */int sym_ntextsyms = 0;struct sym_sym_t **sym_textsyms = NULL;/* text symbols sorted by name */struct sym_sym_t **sym_textsyms_by_name = NULL;/* data symbols sorted by address */int sym_ndatasyms = 0;struct sym_sym_t **sym_datasyms = NULL;/* data symbols sorted by name */struct sym_sym_t **sym_datasyms_by_name = NULL;/* symbols loaded? */static int syms_loaded = FALSE;#ifdef PRINT_SYMS/* convert BFD symbols flags to a printable string */static char *			/* symbol flags string */flags2str(unsigned int flags)	/* bfd symbol flags */{  static char buf[256];  char *p;  if (!flags)    return "";  p = buf;  *p = '\0';  if (flags & BSF_LOCAL)    {      *p++ = 'L';      *p++ = '|';    }  if (flags & BSF_GLOBAL)    {      *p++ = 'G';      *p++ = '|';    }  if (flags & BSF_DEBUGGING)    {      *p++ = 'D';      *p++ = '|';    }  if (flags & BSF_FUNCTION)    {      *p++ = 'F';      *p++ = '|';    }  if (flags & BSF_KEEP)    {      *p++ = 'K';      *p++ = '|';    }  if (flags & BSF_KEEP_G)    {      *p++ = 'k'; *p++ = '|';    }  if (flags & BSF_WEAK)    {      *p++ = 'W';      *p++ = '|';    }  if (flags & BSF_SECTION_SYM)    {      *p++ = 'S'; *p++ = '|';    }  if (flags & BSF_OLD_COMMON)    {      *p++ = 'O';      *p++ = '|';    }  if (flags & BSF_NOT_AT_END)    {      *p++ = 'N';      *p++ = '|';    }  if (flags & BSF_CONSTRUCTOR)    {      *p++ = 'C';      *p++ = '|';    }  if (flags & BSF_WARNING)    {      *p++ = 'w';      *p++ = '|';    }  if (flags & BSF_INDIRECT)    {      *p++ = 'I';      *p++ = '|';    }  if (flags & BSF_FILE)    {      *p++ = 'f';      *p++ = '|';    }  if (p == buf)    panic("no flags detected");  *--p = '\0';  return buf;}#endif /* PRINT_SYMS *//* qsort helper function */static intacmp(struct sym_sym_t **sym1, struct sym_sym_t **sym2){  return (int)((*sym1)->addr - (*sym2)->addr);}/* qsort helper function */static intncmp(struct sym_sym_t **sym1, struct sym_sym_t **sym2){  return strcmp((*sym1)->name, (*sym2)->name);}#define RELEVANT_SCOPE(SYM)						\(/* global symbol */							\ ((SYM)->flags & BSF_GLOBAL)						\ || (/* local symbol */							\     (((SYM)->flags & (BSF_LOCAL|BSF_DEBUGGING)) == BSF_LOCAL)		\     && (SYM)->name[0] != '$')						\ || (/* compiler local */						\     load_locals							\     && ((/* basic block idents */					\	  ((SYM)->flags&(BSF_LOCAL|BSF_DEBUGGING))==(BSF_LOCAL|BSF_DEBUGGING)\	  && (SYM)->name[0] == '$')					\	 || (/* local constant idents */				\	     ((SYM)->flags & (BSF_LOCAL|BSF_DEBUGGING)) == (BSF_LOCAL)	\	     && (SYM)->name[0] == '$'))))     /* load symbols out of FNAME */voidsym_loadsyms(char *fname,	/* file name containing symbols */	     int load_locals)	/* load local symbols */{  int i, debug_cnt;#ifdef BFD_LOADER  bfd *abfd;  asymbol **syms;  int storage, i, nsyms, debug_cnt;#else /* !BFD_LOADER */  int len;  FILE *fobj;  struct ecoff_filehdr fhdr;  struct ecoff_aouthdr ahdr;  struct ecoff_symhdr_t symhdr;  char *strtab = NULL;  struct ecoff_EXTR *extr;#endif /* BFD_LOADER */  if (syms_loaded)    {      /* symbols are already loaded */      /* FIXME: can't handle symbols from multiple files */      return;    }#ifdef BFD_LOADER  /* load the program into memory, try both endians */  if (!(abfd = bfd_openr(fname, "ss-coff-big")))    if (!(abfd = bfd_openr(fname, "ss-coff-little")))      fatal("cannot open executable `%s'", fname);  /* this call is mainly for its side effect of reading in the sections.     we follow the traditional behavior of `strings' in that we don't     complain if we don't recognize a file to be an object file.  */  if (!bfd_check_format(abfd, bfd_object))    {      bfd_close(abfd);      fatal("cannot open executable `%s'", fname);    }  /* sanity check, endian should be the same as loader.c encountered */  if (abfd->xvec->byteorder_big_p != (unsigned)ld_target_big_endian)    panic("binary endian changed");  if ((bfd_get_file_flags(abfd) & (HAS_SYMS|HAS_LOCALS)))    {      /* file has locals, read them in */      storage = bfd_get_symtab_upper_bound(abfd);      if (storage <= 0)	fatal("HAS_SYMS is set, but `%s' still lacks symbols", fname);      syms = (asymbol **)calloc(storage, 1);      if (!syms)	fatal("out of virtual memory");      nsyms = bfd_canonicalize_symtab (abfd, syms);      if (nsyms <= 0)	fatal("HAS_SYMS is set, but `%s' still lacks symbols", fname);      /*       * convert symbols to local format       */      /* first count symbols */      sym_ndatasyms = 0; sym_ntextsyms = 0;      for (i=0; i < nsyms; i++)	{	  asymbol *sym = syms[i];	  /* decode symbol type */	  if (/* from the data section */	      (!strcmp(sym->section->name, ".rdata")	       || !strcmp(sym->section->name, ".data")	       || !strcmp(sym->section->name, ".sdata")	       || !strcmp(sym->section->name, ".bss")	       || !strcmp(sym->section->name, ".sbss"))	      /* from a scope we are interested in */	      && RELEVANT_SCOPE(sym))	    {	      /* data segment symbol */	      sym_ndatasyms++;#ifdef PRINT_SYMS	      fprintf(stderr,		      "+sym: %s  sect: %s  flags: %s  value: 0x%08lx\n",		      sym->name, sym->section->name, flags2str(sym->flags),		      sym->value + sym->section->vma);#endif /* PRINT_SYMS */	    }	  else if (/* from the text section */		   !strcmp(sym->section->name, ".text")		   /* from a scope we are interested in */		   && RELEVANT_SCOPE(sym))	    {	      /* text segment symbol */	      sym_ntextsyms++;#ifdef PRINT_SYMS	      fprintf(stderr,		      "+sym: %s  sect: %s  flags: %s  value: 0x%08lx\n",		      sym->name, sym->section->name, flags2str(sym->flags),		      sym->value + sym->section->vma);#endif /* PRINT_SYMS */	    }	  else	    {	      /* non-segment sections */#ifdef PRINT_SYMS	      fprintf(stderr,		      "-sym: %s  sect: %s  flags: %s  value: 0x%08lx\n",		      sym->name, sym->section->name, flags2str(sym->flags),		      sym->value + sym->section->vma);#endif /* PRINT_SYMS */	    }	}      sym_nsyms = sym_ntextsyms + sym_ndatasyms;      if (sym_nsyms <= 0)	fatal("`%s' has no text or data symbols", fname);      /* allocate symbol space */      sym_db = (struct sym_sym_t *)calloc(sym_nsyms, sizeof(struct sym_sym_t));      if (!sym_db)	fatal("out of virtual memory");      /* convert symbols to internal format */      for (debug_cnt=0, i=0; i < nsyms; i++)	{	  asymbol *sym = syms[i];	  /* decode symbol type */	  if (/* from the data section */	      (!strcmp(sym->section->name, ".rdata")	       || !strcmp(sym->section->name, ".data")	       || !strcmp(sym->section->name, ".sdata")	       || !strcmp(sym->section->name, ".bss")	       || !strcmp(sym->section->name, ".sbss"))	      /* from a scope we are interested in */	      && RELEVANT_SCOPE(sym))	    {	      /* data segment symbol, insert into symbol database */	      sym_db[debug_cnt].name = mystrdup((char *)sym->name);	      sym_db[debug_cnt].seg = ss_data;	      sym_db[debug_cnt].initialized =		(!strcmp(sym->section->name, ".rdata")		 || !strcmp(sym->section->name, ".data")		 || !strcmp(sym->section->name, ".sdata"));	      sym_db[debug_cnt].pub = (sym->flags & BSF_GLOBAL);	      sym_db[debug_cnt].local = (sym->name[0] == '$');	      sym_db[debug_cnt].addr = sym->value + sym->section->vma;	      debug_cnt++;	    }	  else if (/* from the text section */		   !strcmp(sym->section->name, ".text")		   /* from a scope we are interested in */		   && RELEVANT_SCOPE(sym))	    {	      /* text segment symbol, insert into symbol database */	      sym_db[debug_cnt].name = mystrdup((char *)sym->name);	      sym_db[debug_cnt].seg = ss_text;	      sym_db[debug_cnt].initialized = /* seems reasonable */TRUE;	      sym_db[debug_cnt].pub = (sym->flags & BSF_GLOBAL);	      sym_db[debug_cnt].local = (sym->name[0] == '$');	      sym_db[debug_cnt].addr = sym->value + sym->section->vma;	      debug_cnt++;	    }	  else	    {	      /* non-segment sections */	    }	}      /* sanity check */      if (debug_cnt != sym_nsyms)	panic("could not locate all counted symbols");      /* release bfd symbol storage */      free(syms);    }  /* done with file, close if */  if (!bfd_close(abfd))    fatal("could not close executable `%s'", fname);#else /* !BFD_LOADER */  /* load the program into memory, try both endians */#ifdef __CYGWIN32__  fobj = fopen(fname, "rb");#else  fobj = fopen(fname, "r");#endif  if (!fobj)    fatal("cannot open executable `%s'", fname);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -