?? symbol.c.svn-base
字號:
/*
* 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, 1998 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.1.1.1 2006/09/08 09:21:43 cvsuser Exp $
*
* $Log: symbol.c,v $
* Revision 1.1.1.1 2006/09/08 09:21:43 cvsuser
* Godson-3 simulator
*
* Revision 1.1 2005/01/27 03:18:24 fxzhang
* create godson2 cvs
*
* Revision 1.1.1.1 2004/12/05 14:36:32 fxzhang
* initial import of ss-mips
*
* Revision 1.2 2004/08/03 09:50:06 fxzhang
* merge back changes on AMD64
*
* Revision 1.2 2004/07/30 02:48:22 fxzhang
* fix stat64/lstat64
*
* Revision 1.2 2004/07/15 07:31:03 fxzhang
* fix syscall on x86-64
*
* Revision 1.1.1.1 2004/07/15 01:26:34 fxzhang
* import
*
* Revision 1.1.1.1 2004/07/10 16:46:50 fxzhang
* initial
*
* Revision 1.1.1.1 2000/05/26 15:21:54 taustin
* SimpleScalar Tool Set
*
*
* Revision 1.3 1998/08/27 17:06:45 taustin
* implemented host interface description in host.h
* added target interface support
* added support for MS VC++ and CYGWIN32 hosts
*
* 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>
#include "host.h"
#include "misc.h"
#ifdef BFD_LOADER
#include <bfd.h>
#else /* !BFD_LOADER */
#include "target-mips/ecoff.h"
#endif /* BFD_LOADER */
#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 int
acmp(struct sym_sym_t **sym1, struct sym_sym_t **sym2)
{
return (int)((*sym1)->addr - (*sym2)->addr);
}
/* qsort helper function */
static int
ncmp(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 */
void
sym_loadsyms(char *fname, /* file name containing symbols */
int load_locals) /* load local symbols */
{
#if 0
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 */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -