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

📄 mipsread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	   we mark it explicitly */	int             pend = (sh->reserved == 1);	enum address_class class;	TIR		tir;	switch (sh->st) {	    case stNil:		break;	    case stGlobal:	/* external symbol, goes into global block */		class = LOC_STATIC;		b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(top_stack->cur_st),				      GLOBAL_BLOCK);		s = new_symbol((char *)sh->iss);		SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;		goto data;	    case stStatic:	/* static data, goes into current block. */		class = LOC_STATIC;		b = top_stack->cur_block;		s = new_symbol((char *)sh->iss);		SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;		goto data;	    case stLocal:	/* local variable, goes into current block */		if (sh->sc == scRegister) {			class = LOC_REGISTER;			if (sh->value > 31)				sh->value += FP0_REGNUM-32;		} else			class = LOC_LOCAL;		b = top_stack->cur_block;		s = new_symbol((char *)sh->iss);		SYMBOL_VALUE(s) = sh->value;data:		/* Common code for symbols describing data */		SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;		SYMBOL_CLASS(s) = class;		add_symbol(s, b);		/* Type could be missing in a number of cases */		if (sh->sc == scUndefined || sh->sc == scNil ||		    sh->index == 0xfffff)			SYMBOL_TYPE(s) = builtin_type_int;	/* undefined? */		else			SYMBOL_TYPE(s) = parse_type(ax + sh->index, 0, bigend);		/* Value of a data symbol is its memory address */		break;	    case stParam:	/* arg to procedure, goes into current block */		max_gdbinfo++;		top_stack->numargs++;		name = (char*)sh->iss;		/* Special GNU C++ name.  */		if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0)		    name = "this";	/* FIXME, not alloc'd in obstack */		s = new_symbol(name);		SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;		if (sh->sc == scRegister) {			SYMBOL_CLASS(s) = LOC_REGPARM;			if (sh->value > 31)				sh->value += FP0_REGNUM-32;		} else			SYMBOL_CLASS(s) = LOC_ARG;		SYMBOL_VALUE(s) = sh->value;		SYMBOL_TYPE(s) = parse_type(ax + sh->index, 0, bigend);		add_symbol(s, top_stack->cur_block);#if 0		/* FIXME:  This has not been tested.  See dbxread.c */		/* Add the type of this parameter to the function/procedure		   type of this block. */		add_param_to_type(&top_stack->cur_block->function->type,s);#endif		break;	    case stLabel:	/* label, goes into current block */		s = new_symbol((char *)sh->iss);		SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;	/* so that it can be used */		SYMBOL_CLASS(s) = LOC_LABEL;		/* but not misused */		SYMBOL_VALUE_ADDRESS(s) = (CORE_ADDR)sh->value;		SYMBOL_TYPE(s) = builtin_type_int;		add_symbol(s, top_stack->cur_block);		break;	    case stProc:	/* Procedure, usually goes into global block */	    case stStaticProc:	/* Static procedure, goes into current block */		s = new_symbol((char *)sh->iss);		SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;		SYMBOL_CLASS(s) = LOC_BLOCK;		/* Type of the return value */		if (sh->sc == scUndefined || sh->sc == scNil)			t = builtin_type_int;		else			t = parse_type(ax + sh->index + 1, 0, bigend);		b = top_stack->cur_block;		if (sh->st == stProc) {		    struct blockvector *bv = BLOCKVECTOR(top_stack->cur_st);		    /* The next test should normally be true,		       but provides a hook for nested functions		       (which we don't want to make global). */		    if (b == BLOCKVECTOR_BLOCK(bv, STATIC_BLOCK))			b = BLOCKVECTOR_BLOCK(bv, GLOBAL_BLOCK);		}		add_symbol(s, b);		/* Make a type for the procedure itself */#if 0		/* FIXME:  This has not been tested yet!  See dbxread.c */		/* Generate a template for the type of this function.  The		   types of the arguments will be added as we read the symbol		   table. */		bcopy(SYMBOL_TYPE(s),lookup_function_type(t),sizeof(struct type));#else		SYMBOL_TYPE(s) = lookup_function_type (t);#endif		/* Create and enter a new lexical context */		b = new_block(top_stack->maxsyms);		SYMBOL_BLOCK_VALUE(s) = b;		BLOCK_FUNCTION(b) = s;		BLOCK_START(b) = BLOCK_END(b) = sh->value;		BLOCK_SUPERBLOCK(b) = top_stack->cur_block;		add_block(b, top_stack->cur_st);		/* Not if we only have partial info */		if (sh->sc == scUndefined || sh->sc == scNil)			break;		push_parse_stack();		top_stack->cur_block = b;		top_stack->blocktype = sh->st;		top_stack->cur_type = SYMBOL_TYPE(s);		top_stack->cur_field = -1;		top_stack->procadr = sh->value;		top_stack->numargs = 0;		sh->value = (long) SYMBOL_TYPE(s);		break;	    /* Beginning of code for structure, union, and enum definitions.	       They all share a common set of local variables, defined here.  */	    {		enum type_code type_code;		SYMR *tsym;		int nfields;		long max_value;		struct field *f;	    case stStruct:	/* Start a block defining a struct type */		type_code = TYPE_CODE_STRUCT;		goto structured_common;	    case stUnion:	/* Start a block defining a union type */		type_code = TYPE_CODE_UNION;		goto structured_common;	    case stEnum:	/* Start a block defining an enum type */		type_code = TYPE_CODE_ENUM;		goto structured_common;	    case stBlock:	/* Either a lexical block, or some type */		if (sh->sc != scInfo)		  goto case_stBlock_code;	/* Lexical block */		type_code = TYPE_CODE_UNDEF;	/* We have a type.  */	    /* Common code for handling struct, union, enum, and/or as-yet-	       unknown-type blocks of info about structured data.  `type_code'	       has been set to the proper TYPE_CODE, if we know it.  */	    structured_common:		push_parse_stack();		top_stack->blocktype = stBlock;		s = new_symbol((char *)sh->iss);		SYMBOL_NAMESPACE(s) = STRUCT_NAMESPACE;		SYMBOL_CLASS(s) = LOC_TYPEDEF;		SYMBOL_VALUE(s) = 0;		add_symbol(s, top_stack->cur_block);		/* First count the number of fields and the highest value. */		nfields = 0;		max_value = 0;		for (tsym = sh+1; tsym->st != stEnd; tsym++)		  {		    if (tsym->st == stMember) {			if (nfields == 0 && type_code == TYPE_CODE_UNDEF)			    /* If the type of the member is Nil (or Void),			       assume the tag is an enumeration. */			    if (tsym->index == indexNil)				type_code = TYPE_CODE_ENUM;			    else {				ecoff_swap_tir_in (bigend,						   &ax[tsym->index].a_ti,						   &tir);				if (tir.bt == btNil || tir.bt == btVoid)				    type_code = TYPE_CODE_ENUM;			    }			nfields++;			if (tsym->value > max_value)			    max_value = tsym->value;		    }		    else if (tsym->st == stBlock			     || tsym->st == stUnion			     || tsym->st == stEnum			     || tsym->st == stStruct			     || tsym->st == stParsed) {			if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/			if (tsym->index != 0)			    tsym = ((SYMR*)cur_fdr->isymBase)				+ tsym->index-1;		    }		    else complain (&block_member_complaint, (char *)tsym->st);		  }		/* In an stBlock, there is no way to distinguish structs,		   unions, and enums at this point.  This is a bug in the		   original design (that has been fixed with the		   recent addition of the stStruct, stUnion, and stEnum		   symbol types.)  The way you can tell is if/when you		   see a variable or field of that type.  In that case		   the variable's type (in the AUX table) says if the		   type is struct, union, or enum,		   and points back to the stBlock here.		   So you can patch the tag kind up later - but only		   if there actually is a variable or field of that type.		   So until we know for sure, we will guess at this point.		   The heuristic is:		   If the first member has index==indexNil or a void type,		   assume we have an enumeration.		   Otherwise, if there is more than one member, and all		   the members have offset 0, assume we have a union.		   Otherwise, assume we have a struct.		   The heuristic could guess wrong in the case of		   of an enumeration with no members or a union		   with one (or zero) members, or when all except the		   last field of a struct have width zero.		   These are uncommon and/or illegal situations, and		   in any case guessing wrong probably doesn't matter much.		   But if we later do find out we were wrong,		   we fixup the tag kind.  Members of an enumeration		   must be handled differently from struct/union fields,		   and that is harder to patch up, but luckily we		   shouldn't need to.  (If there are any enumeration		   members, we can tell for sure it's an enum here.) */		if (type_code == TYPE_CODE_UNDEF)		    if (nfields > 1 && max_value == 0)		      type_code = TYPE_CODE_UNION;		    else		      type_code = TYPE_CODE_STRUCT;		/* If this type was expected, use its partial definition */		if (pend)		    t = is_pending_symbol(cur_fdr, sh)->t;		else		    t = new_type(prepend_tag_kind((char *)sh->iss,						  type_code));		TYPE_CODE(t) = type_code;		TYPE_LENGTH(t) = sh->value;		TYPE_NFIELDS(t) = nfields;		TYPE_FIELDS(t) = f = (struct field*)		  TYPE_ALLOC (t, nfields * sizeof (struct field));		if (type_code == TYPE_CODE_ENUM) {		    /* This is a non-empty enum. */		    for (tsym = sh + 1; tsym->st == stMember; tsym++) {			struct symbol *enum_sym;			f->bitpos = tsym->value;			f->type = t;			f->name = (char*)tsym->iss;			f->bitsize = 0;			enum_sym = (struct symbol *)			    obstack_alloc (&current_objfile->symbol_obstack,					   sizeof (struct symbol));			memset ((PTR)enum_sym, 0, sizeof (struct symbol));			SYMBOL_NAME (enum_sym) = f->name;			SYMBOL_CLASS (enum_sym) = LOC_CONST;			SYMBOL_TYPE (enum_sym) = t;			SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE;			SYMBOL_VALUE (enum_sym) = tsym->value;			add_symbol(enum_sym, top_stack->cur_block);			/* Skip the stMembers that we've handled. */			count++;			f++;		    }		}		SYMBOL_TYPE(s) = t;		/* make this the current type */		top_stack->cur_type = t;		top_stack->cur_field = 0;		/* Mark that symbol has a type, and say which one */		sh->value = (long) t;		break;	    /* End of local variables shared by struct, union, enum, and	       block (as yet unknown struct/union/enum) processing.  */	    }	    case_stBlock_code:		/* beginnning of (code) block. Value of symbol		   is the displacement from procedure start */		push_parse_stack();		top_stack->blocktype = stBlock;		b = new_block(top_stack->maxsyms);		BLOCK_START(b) = sh->value + top_stack->procadr;		BLOCK_SUPERBLOCK(b) = top_stack->cur_block;		top_stack->cur_block = b;		add_block(b, top_stack->cur_st);		break;	    case stEnd:		/* end (of anything) */		if (sh->sc == scInfo) {			/* Finished with type */			top_stack->cur_type = 0;		} else if (sh->sc == scText &&			   (top_stack->blocktype == stProc ||			    top_stack->blocktype == stStaticProc)) {		    /* Finished with procedure */		    struct blockvector *bv = BLOCKVECTOR(top_stack->cur_st);		    struct mips_extra_func_info *e;		    struct block *b;		    int i;		    BLOCK_END(top_stack->cur_block) += sh->value; /* size */		    /* Make up special symbol to contain procedure specific		       info */		    s = new_symbol(MIPS_EFI_SYMBOL_NAME);		    SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;		    SYMBOL_CLASS(s) = LOC_CONST;		    SYMBOL_TYPE(s) = builtin_type_void;		    e = (struct mips_extra_func_info *)		      obstack_alloc (&current_objfile->symbol_obstack,				     sizeof (struct mips_extra_func_info));		    SYMBOL_VALUE(s) = (int)e;		    e->numargs = top_stack->numargs;		    add_symbol(s, top_stack->cur_block);		    /* Reallocate symbols, saving memory */		    b = shrink_block(top_stack->cur_block, top_stack->cur_st);		    /* f77 emits proc-level with address bounds==[0,0],		       So look for such child blocks, and patch them.  */		    for (i = 0; i < BLOCKVECTOR_NBLOCKS(bv); i++) {			struct block *b_bad = BLOCKVECTOR_BLOCK(bv,i);			if (BLOCK_SUPERBLOCK(b_bad) == b			 && BLOCK_START(b_bad) == top_stack->procadr			 && BLOCK_END(b_bad) == top_stack->procadr) {			    BLOCK_START(b_bad) = BLOCK_START(b);			    BLOCK_END(b_bad) = BLOCK_END(b);			}		    }		} else if (sh->sc == scText && top_stack->blocktype == stBlock) {			/* End of (code) block. The value of the symbol			   is the displacement from the procedure`s start			   address of the end of this block. */			BLOCK_END(top_stack->cur_block) = sh->value + top_stack->procadr;			shrink_block(top_stack->cur_block, top_stack->cur_st);		} else if (sh->sc == scText && top_stack->blocktype == stFile) {			/* End of file.  Pop parse stack and ignore.  Higher			   level code deals with this.  */			;		} else complain (&stEnd_complaint, (char *)sh->sc);		pop_parse_stack();	/* restore previous lexical context */		break;	    case stMember:	/* member of struct or union */		f = &TYPE_FIELDS(top_stack->cur_type)[top_stack->cur_field++];		f->name = (char*)sh->iss;		f->bitpos = sh->value;		f->bitsize = 0;		f->type = parse_type(ax + sh->index, &f->bitsize, bigend);		break;	    case stTypedef:	/* type definition */		s = new_symbol((char *)sh->iss);		SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;		SYMBOL_CLASS(s) = LOC_TYPEDEF;		SYMBOL_BLOCK_VALUE(s) = top_stack->cur_block;		add_symbol(s, top_stack->cur_block);		SYMBOL_TYPE(s) = parse_type(ax + sh->index, 0, bigend);		sh->value = (long) SYMBOL_TYPE(s);		break;	    case stFile:	/* file name */		push_parse_stack();		top_stack->blocktype = sh->st;		break;		/* I`ve never seen these for C */	    case stRegReloc:		break;		/* register relocation */	    case stForward:		break;		/* forwarding address */	    case stConstant:		break;		/* constant */	    default:		complain(&unknown_mips_symtype_complaint, (char *)sh->st);		break;	}	sh->st = stParsed;	return count;}/* Parse the type information provided in the raw AX entries for   the symbol SH. Return the bitfield size in BS, in case.   We must byte-swap the AX entries before we use them; BIGEND says whether   they are big-endian or little-endian (from fh->fBigendian).  */static struct type *parse_type(ax, bs, bigend)	union aux_ext	*ax;	int	*bs;	int	bigend;{	/* Null entries in this map are treated specially */	static struct type **map_bt[] =	{		 &builtin_type_void,		/* btNil */		 0,				/* btAdr */		 &builtin_type_char,		/* btChar */		 &builtin_type_unsigned_char,	/* btUChar */		 &builtin_type_short,		/* btShort */		 &builtin_type_unsigned_short,	/* btUShort */		 &builtin_type_int,		/* btInt */		 &builtin_type_unsigned_int,	/* btUInt */		 &builtin_type_long,		/* btLong */		 &builtin_type_unsigned_long,	/* btULong */		 &builtin_type_float,		/* btFloat */		 &builtin_type_double,		/* btDouble */		 0,				/* btStruct */		 0,				/* btUnion */		 0,				/* btEnum */		 0,				/* btTypedef */		 0,				/* btRange */		 0,				/* btSet */		 &builtin_type_complex,		/* btComplex */		 &builtin_type_double_complex,	/* btDComplex */		 0,				/* btIndirect */		 &builtin_type_fixed_dec,	/* btFixedDec */		 &builtin_type_float_dec,	/* btFloatDec */		 &builtin_type_string,		/* btString */		 0,				/* btBit */		 0,				/* btPicture */		 &builtin_type_void,		/* btVoid */		 &builtin_type_long_long,	/* btLongLong */		 &builtin_type_unsigned_long_long,/* btULongLong */	};

⌨️ 快捷键说明

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