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

📄 mipsread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	val = bfd_read((PTR)&filhdr, sizeof filhdr, 1, abfd);	if (end_of_text_segp)		*end_of_text_segp =			bfd_h_get_32 (abfd, filhdr.a.text_start) +			bfd_h_get_32 (abfd, filhdr.a.tsize);	/* Find and read the symbol table header */	st_hdrsize = bfd_h_get_32 (abfd, filhdr.f.f_nsyms);	st_filptr  = bfd_h_get_32 (abfd, filhdr.f.f_symptr);	if (st_filptr == 0)		return;	bfd_seek (abfd, st_filptr, L_SET);	if (st_hdrsize != sizeof (hdr_ext)) {	/* Profanity check */		error ("Wrong header size: %d, not %d", st_hdrsize,			sizeof (hdr_ext));	}	if (bfd_read((PTR)&hdr_ext, st_hdrsize, 1, abfd) != st_hdrsize)		goto readerr;	ecoff_swap_hdr_in (abfd, &hdr_ext, &st_hdr);	/* Find out how large the symbol table is */	stsize = (st_hdr.cbExtOffset - (st_filptr + st_hdrsize))		+ st_hdr.iextMax * cbEXTR;	/* Allocate space for the symbol table.  Read it in.  */	cur_hdr = (HDRR *) xmalloc(stsize + st_hdrsize);	memcpy((PTR)cur_hdr, (PTR)&hdr_ext, st_hdrsize);	if (bfd_read((char *)cur_hdr + st_hdrsize, stsize, 1, abfd) != stsize)		goto readerr;	/* Fixup file_pointers in it */	fixup_symtab(cur_hdr, (char *) cur_hdr + st_hdrsize,		     st_filptr + st_hdrsize, abfd);	return;readerr:	error("Short read on %s", bfd_get_filename (abfd));}/* Turn all file-relative pointers in the symtab described by HDR   into memory pointers, given that the symtab itself is located   at DATA in memory and F_PTR in the file.   Byte-swap all the data structures, in place, while we are at it --   except AUX entries, which we leave in their original byte order.   They will be swapped as they are used instead.  (FIXME:  we ought to   do all the data structures that way.)  */static voidfixup_symtab (hdr, data, f_ptr, abfd)	HDRR *hdr;	char *data;	file_ptr f_ptr;	bfd *abfd;{	int             f_idx, s_idx, i;	FDR            *fh;	SYMR	       *sh;	PDR	       *pr;	EXTR	       *esh;	struct rfd_ext *rbase;	/* This function depends on the external and internal forms	   of the MIPS symbol table taking identical space.  Check this	   assumption at compile-time.  	   DO NOT DELETE THESE ENTRIES, OR COMMENT THEM OUT, JUST BECAUSE SOME	   "LINT" OR COMPILER THINKS THEY ARE UNUSED!  Thank you.  */	static check_hdr1[1 + sizeof (struct hdr_ext) - sizeof (HDRR)] = {0};	static check_hdr2[1 + sizeof (HDRR) - sizeof (struct hdr_ext)] = {0};	static check_fdr1[1 + sizeof (struct fdr_ext) - sizeof (FDR)] = {0};	static check_fdr2[1 + sizeof (FDR) - sizeof (struct fdr_ext)] = {0};	static check_pdr1[1 + sizeof (struct pdr_ext) - sizeof (PDR)] = {0};	static check_pdr2[1 + sizeof (PDR) - sizeof (struct pdr_ext)] = {0};	static check_sym1[1 + sizeof (struct sym_ext) - sizeof (SYMR)] = {0};	static check_sym2[1 + sizeof (SYMR) - sizeof (struct sym_ext)] = {0};	static check_ext1[1 + sizeof (struct ext_ext) - sizeof (EXTR)] = {0};	static check_ext2[1 + sizeof (EXTR) - sizeof (struct ext_ext)] = {0};	static check_rfd1[1 + sizeof (struct rfd_ext) - sizeof (RFDT)] = {0};	static check_rfd2[1 + sizeof (RFDT) - sizeof (struct rfd_ext)] = {0};	/* Swap in the header record.  */	ecoff_swap_hdr_in (abfd, hdr, hdr);	/*	 * These fields are useless (and empty) by now:	 *	hdr->cbDnOffset, hdr->cbOptOffset	 * We use them for other internal purposes.	 */	hdr->cbDnOffset = 0;	hdr->cbOptOffset = 0;#define FIX(off) \	if (hdr->off) hdr->off = (unsigned int)data + (hdr->off - f_ptr);	FIX(cbLineOffset);	FIX(cbPdOffset);	FIX(cbSymOffset);	FIX(cbOptOffset);	FIX(cbAuxOffset);	FIX(cbSsOffset);	FIX(cbSsExtOffset);	FIX(cbFdOffset);	FIX(cbRfdOffset);	FIX(cbExtOffset);#undef	FIX	/* Fix all the RFD's.  */	rbase = (struct rfd_ext *)(hdr->cbRfdOffset);	for (i = 0; i < hdr->crfd; i++) {	  ecoff_swap_rfd_in (abfd, rbase+i, (pRFDT) rbase+i);	}	/* Fix all string pointers inside the symtab, and	   the FDR records.  Also fix other miscellany.  */	for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) {		register unsigned code_offset;		/* Header itself, and strings */		fh = (FDR *) (hdr->cbFdOffset) + f_idx;		/* Swap in the FDR */		ecoff_swap_fdr_in (abfd, fh, fh);		fh->issBase += hdr->cbSsOffset;		if (fh->rss != -1)			fh->rss = (long)fh->rss + fh->issBase;		/* Local symbols */		fh->isymBase = (int)((SYMR*)(hdr->cbSymOffset)+fh->isymBase);		/* FIXME! Probably don't want to do this here! */		for (s_idx = 0; s_idx < fh->csym; s_idx++) {			sh = (SYMR*)fh->isymBase + s_idx;			ecoff_swap_sym_in (abfd, sh, sh);			sh->iss = (long) sh->iss + fh->issBase;			sh->reserved = 0;		}		cur_fd = f_idx;		/* cannot fix fh->ipdFirst because it is a short */#define IPDFIRST(h,fh) \		((long)h->cbPdOffset + fh->ipdFirst * sizeof(PDR))		/* Optional symbols (actually used for partial_symtabs) */		fh->ioptBase = 0;		fh->copt = 0;		/* Aux symbols */		if (fh->caux)			fh->iauxBase = hdr->cbAuxOffset + fh->iauxBase * sizeof(union aux_ext);		/* Relative file descriptor table */		fh->rfdBase = hdr->cbRfdOffset + fh->rfdBase * sizeof(RFDT);		/* Line numbers */		if (fh->cbLine)			fh->cbLineOffset += hdr->cbLineOffset;		/* Procedure symbols.  (XXX This should be done later) */		code_offset = fh->adr;		for (s_idx = 0; s_idx < fh->cpd; s_idx++) {			unsigned name, only_ext;			pr = (PDR*)(IPDFIRST(hdr,fh)) + s_idx;			ecoff_swap_pdr_in (abfd, pr, pr);			/* Simple rule to find files linked "-x" */			only_ext = fh->rss == -1;			if (only_ext) {				if (pr->isym == -1) {					/* static function */					sh = (SYMR*)-1;				} else {					/* external */					name = hdr->cbExtOffset + pr->isym * sizeof(EXTR);					sh = &((EXTR*)name)->asym;				}			} else {				/* Full symbols */				sh = (SYMR*)fh->isymBase + pr->isym;				/* Included code ? */				if (s_idx == 0 && pr->adr != 0)					code_offset -= pr->adr;			}			/* Turn index into a pointer */			pr->isym = (long)sh;			/* Fix line numbers */			pr->cbLineOffset += fh->cbLineOffset;			/* Relocate address */			if (!only_ext)				pr->adr += code_offset;		}	}	/* External symbols: swap in, and fix string */	for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) {		esh = (EXTR*)(hdr->cbExtOffset) + s_idx;		ecoff_swap_ext_in (abfd, esh, esh);		esh->asym.iss = esh->asym.iss + hdr->cbSsExtOffset;	}}/* Find a file descriptor given its index RF relative to a file CF */static FDR *get_rfd (cf, rf)	int cf, rf;{	register FDR   *f;	f = (FDR *) (cur_hdr->cbFdOffset) + cf;	/* Object files do not have the RFD table, all refs are absolute */	if (f->rfdBase == 0)		return (FDR *) (cur_hdr->cbFdOffset) + rf;	cf = *((pRFDT) f->rfdBase + rf);	return (FDR *) (cur_hdr->cbFdOffset) + cf;}/* Return a safer print NAME for a file descriptor */static char *fdr_name(name)	char *name;{	if (name == (char *) -1)		return "<stripped file>";	if (UNSAFE_DATA_ADDR(name))		return "<NFY>";	return name;}/* Read in and parse the symtab of the file OBJFILE.  Symbols from   different sections are relocated via the SECTION_OFFSETS.  */static voidread_mips_symtab (objfile, section_offsets)	struct objfile *objfile;	struct section_offsets *section_offsets;{	CORE_ADDR end_of_text_seg;	read_the_mips_symtab(objfile->obfd, &end_of_text_seg);	parse_partial_symbols(end_of_text_seg, objfile, section_offsets);#if 0	/*	 * Check to make sure file was compiled with -g.	 * If not, warn the user of this limitation.	 */	if (compare_glevel(max_glevel, GLEVEL_2) < 0) {		if (max_gdbinfo == 0)			printf ("\n%s not compiled with -g, debugging support is limited.\n",				objfile->name);		printf("You should compile with -g2 or -g3 for best debugging support.\n");		fflush(stdout);	}#endif}/* Local utilities *//* Map of FDR indexes to partial symtabs */struct pst_map {    struct partial_symtab *pst;	/* the psymtab proper */    int n_globals; /* exported globals (external symbols) */    int globals_offset;  /* cumulative */};/* Utility stack, used to nest procedures and blocks properly.   It is a doubly linked list, to avoid too many alloc/free.   Since we might need it quite a few times it is NOT deallocated   after use. */static struct parse_stack {    struct parse_stack	*next, *prev;    struct symtab	*cur_st;	/* Current symtab. */    struct block	*cur_block;	/* Block in it. */    int			 blocktype;	/* What are we parsing. */    int			 maxsyms;	/* Max symbols in this block. */    struct type		*cur_type;	/* Type we parse fields for. */    int			 cur_field;	/* Field number in cur_type. */    int			 procadr;	/* Start addres of this procedure */    int			 numargs;	/* Its argument count */} *top_stack;	/* Top stack ptr *//* Enter a new lexical context */static voidpush_parse_stack(){	struct parse_stack *new;	/* Reuse frames if possible */	if (top_stack && top_stack->prev)		new = top_stack->prev;	else		new = (struct parse_stack *) xzalloc(sizeof(struct parse_stack));	/* Initialize new frame with previous content */	if (top_stack) {		register struct parse_stack *prev = new->prev;		*new = *top_stack;		top_stack->prev = new;		new->prev = prev;		new->next = top_stack;	}	top_stack = new;}/* Exit a lexical context */static voidpop_parse_stack(){	if (!top_stack)		return;	if (top_stack->next)		top_stack = top_stack->next;}/* Cross-references might be to things we haven't looked at   yet, e.g. type references.  To avoid too many type   duplications we keep a quick fixup table, an array   of lists of references indexed by file descriptor */static struct mips_pending {	struct mips_pending	*next;		/* link */	SYMR		*s;		/* the symbol */	struct type	*t;		/* its partial type descriptor */} **pending_list;/* Check whether we already saw symbol SH in file FH as undefined */static struct mips_pending *is_pending_symbol(fh, sh)	FDR *fh;	SYMR *sh;{	int             f_idx = fh - (FDR *) cur_hdr->cbFdOffset;	register struct mips_pending *p;	/* Linear search is ok, list is typically no more than 10 deep */	for (p = pending_list[f_idx]; p; p = p->next)		if (p->s == sh)			break;	return p;}/* Add a new undef symbol SH of type T */static voidadd_pending(fh, sh, t)	FDR *fh;	SYMR *sh;	struct type *t;{	int             f_idx = fh - (FDR *) cur_hdr->cbFdOffset;	struct mips_pending *p = is_pending_symbol(fh, sh);	/* Make sure we do not make duplicates */	if (!p) {		p = (struct mips_pending *) xmalloc(sizeof(*p));		p->s = sh;		p->t = t;		p->next = pending_list[f_idx];		pending_list[f_idx] = p;	}	sh->reserved = 1;	/* for quick check */}/* Throw away undef entries when done with file index F_IDX *//* FIXME -- storage leak.  This is never called!!!   --gnu */#if 0static voidfree_pending(f_idx)	int f_idx;{	register struct mips_pending *p, *q;	for (p = pending_list[f_idx]; p; p = q) {		q = p->next;		free((PTR)p);	}	pending_list[f_idx] = 0;}#endifstatic char *prepend_tag_kind(tag_name, type_code)     char *tag_name;     enum type_code type_code;{    char *prefix;    char *result;    switch (type_code) {      case TYPE_CODE_ENUM:	prefix = "enum ";	break;      case TYPE_CODE_STRUCT:	prefix = "struct ";	break;      case TYPE_CODE_UNION:	prefix = "union ";	break;      default:	prefix = "";    }    result = (char*)obstack_alloc (&current_objfile->symbol_obstack,				   strlen(prefix) + strlen(tag_name) + 1);    sprintf(result, "%s%s", prefix, tag_name);    return result;}/* Parsing Routines proper. *//* Parse a single symbol. Mostly just make up a GDB symbol for it.   For blocks, procedures and types we open a new lexical context.   This is basically just a big switch on the symbol's type.   Argument AX is the base pointer of aux symbols for this file (fh->iauxBase).   BIGEND says whether aux symbols are big-endian or little-endian.   Return count of SYMR's handled (normally one). */static intparse_symbol(sh, ax, bigend)	SYMR *sh;	union aux_ext *ax;	int bigend;{	char *name;	struct symbol  *s;	struct block   *b;	struct type    *t;	struct field   *f;	int count = 1;	/* When a symbol is cross-referenced from other files/symbols

⌨️ 快捷键说明

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