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

📄 mipsread.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	TIR            t[1];	struct type    *tp = 0;	char           *fmt;	union aux_ext *tax;	enum type_code type_code;	/* Use aux as a type information record, map its basic type.  */	tax = ax;	ecoff_swap_tir_in (bigend, &tax->a_ti, t);	if (t->bt > (sizeof (map_bt)/sizeof (*map_bt))) {		complain (&basic_type_complaint, (char *)t->bt);		return builtin_type_int;	}	if (map_bt[t->bt]) {		tp = *map_bt[t->bt];		fmt = "%s";	} else {		tp = NULL;		/* Cannot use builtin types -- build our own */		switch (t->bt) {		    case btAdr:			tp = lookup_pointer_type (builtin_type_void);			fmt = "%s";			break;		    case btStruct:			type_code = TYPE_CODE_STRUCT;			fmt = "struct %s";			break;		    case btUnion:			type_code = TYPE_CODE_UNION;			fmt = "union %s";			break;		    case btEnum:			type_code = TYPE_CODE_ENUM;			fmt = "enum %s";			break;		    case btRange:			type_code = TYPE_CODE_RANGE;			fmt = "%s";			break;		    case btSet:			type_code = TYPE_CODE_SET;			fmt = "set %s";			break;		    case btTypedef:		    default:			complain (&basic_type_complaint, (char *)t->bt);			return builtin_type_int;		}	}	/* Skip over any further type qualifiers (FIXME).  */	if (t->continued) {		/* This is the way it would work if the compiler worked */		TIR t1[1];		do {			ax++;			ecoff_swap_tir_in (bigend, ax, t1);		} while (t1->continued);	}	/* Move on to next aux */	ax++;	if (t->fBitfield) {		if (bs != 0)			*bs = AUX_GET_WIDTH (bigend, ax);		ax++;	}	/* All these types really point to some (common) MIPS type	   definition, and only the type-qualifiers fully identify	   them.  We'll make the same effort at sharing. */	if (t->bt == btIndirect ||	    t->bt == btStruct ||	    t->bt == btUnion ||	    t->bt == btEnum ||	    t->bt == btTypedef ||	    t->bt == btRange ||	    t->bt == btSet) {		char            name[256], *pn;		/* Try to cross reference this type */		ax += cross_ref(ax, &tp, type_code, &pn, bigend);		/* reading .o file ? */		if (UNSAFE_DATA_ADDR(tp))		    tp = init_type(type_code, 0, 0, (char *) NULL,				   (struct objfile *) NULL);		/* SOMEONE OUGHT TO FIX DBXREAD TO DROP "STRUCT" */		sprintf(name, fmt, pn);		/* Usually, TYPE_CODE(tp) is already type_code.  The main		   exception is if we guessed wrong re struct/union/enum. */		if (TYPE_CODE(tp) != type_code) {		    complain (&bad_tag_guess_complaint, name);		    TYPE_CODE(tp) = type_code;		}		if (TYPE_NAME(tp) == NULL || strcmp(TYPE_NAME(tp), name) != 0)		    TYPE_NAME(tp) = obsavestring(name, strlen(name),						 &current_objfile -> type_obstack);	}	/* Deal with range types */	if (t->bt == btRange) {		TYPE_NFIELDS (tp) = 2;		TYPE_FIELDS (tp) = (struct field *)		  TYPE_ALLOC (tp, 2 * sizeof (struct field));		TYPE_FIELD_NAME (tp, 0) = obsavestring ("Low", strlen ("Low"),							&current_objfile -> type_obstack);		TYPE_FIELD_BITPOS (tp, 0) = AUX_GET_DNLOW (bigend, ax);		ax++;		TYPE_FIELD_NAME (tp, 1) = obsavestring ("High", strlen ("High"),							&current_objfile -> type_obstack);		TYPE_FIELD_BITPOS (tp, 1) = AUX_GET_DNHIGH (bigend, ax);		ax++;	}	/* Parse all the type qualifiers now. If there are more	   than 6 the game will continue in the next aux */#define PARSE_TQ(tq) \	if (t->tq != tqNil) ax += upgrade_type(&tp, t->tq, ax, bigend);again:	PARSE_TQ(tq0);	PARSE_TQ(tq1);	PARSE_TQ(tq2);	PARSE_TQ(tq3);	PARSE_TQ(tq4);	PARSE_TQ(tq5);#undef	PARSE_TQ	if (t->continued) {		tax++;		ecoff_swap_tir_in (bigend, &tax->a_ti, t);		goto again;	}	return tp;}/* Make up a complex type from a basic one.  Type is passed by   reference in TPP and side-effected as necessary. The type   qualifier TQ says how to handle the aux symbols at AX for   the symbol SX we are currently analyzing.  BIGEND says whether   aux symbols are big-endian or little-endian.   Returns the number of aux symbols we parsed. */static intupgrade_type(tpp, tq, ax, bigend)	struct type  **tpp;	int	       tq;	union aux_ext *ax;	int	       bigend;{	int            off;	struct type   *t;	/* Used in array processing */	int             rf, id;	FDR            *fh;	struct field   *f;	int		lower, upper;	RNDXR		rndx;	switch (tq) {	case tqPtr:		t = lookup_pointer_type (*tpp);		*tpp = t;		return 0;	case tqProc:		t = lookup_function_type (*tpp);		*tpp = t;		return 0;	case tqArray:		off = 0;		t = init_type(TYPE_CODE_ARRAY, 0, 0, (char *) NULL,			      (struct objfile *) NULL);		TYPE_TARGET_TYPE(t) = *tpp;		/* Determine and record the domain type (type of index) */		ecoff_swap_rndx_in (bigend, ax, &rndx);		id = rndx.index;		rf = rndx.rfd;		if (rf == 0xfff) {			ax++;			rf = AUX_GET_ISYM (bigend, ax);			off++;		}		fh = get_rfd(cur_fd, rf);		/* Fields are kept in an array */		/* FIXME - Memory leak! */		if (TYPE_NFIELDS(t))		    TYPE_FIELDS(t) = (struct field*)			xrealloc((PTR) TYPE_FIELDS(t),				 (TYPE_NFIELDS(t)+1) * sizeof(struct field));		else		    TYPE_FIELDS(t) = (struct field*)			xzalloc(sizeof(struct field));		f = &(TYPE_FIELD(t,TYPE_NFIELDS(t)));		TYPE_NFIELDS(t)++;		memset((PTR)f, 0, sizeof(struct field));/* XXX */	f->type = parse_type(id + (union aux_ext *)fh->iauxBase,				     &f->bitsize, bigend);		ax++;		lower = AUX_GET_DNLOW (bigend, ax);		ax++;		upper = AUX_GET_DNHIGH (bigend, ax);		ax++;		rf = AUX_GET_WIDTH (bigend, ax);	/* bit size of array element */		/* Check whether supplied array element bit size matches		   the known size of the element type.  If this complaint		   ends up not happening, we can remove this code.  It's		   here because we aren't sure we understand this *&%&$		   symbol format.  */		id = TYPE_LENGTH(TYPE_TARGET_TYPE(t)) << 3; /* bitsize */		if (id == 0) {			/* Most likely an undefined type */			id = rf;			TYPE_LENGTH(TYPE_TARGET_TYPE(t)) = id >> 3;		}		if (id != rf)			complain (&array_bitsize_complaint, (char *)rf);		TYPE_LENGTH(t) = (upper < 0) ? 0 :			(upper - lower + 1) * (rf >> 3);		*tpp = t;		return 4 + off;	case tqVol:		/* Volatile -- currently ignored */		return 0;	case tqConst:		/* Const -- currently ignored */		return 0;	default:		complain (&unknown_type_qual_complaint, (char *)tq);		return 0;	}}/* Parse a procedure descriptor record PR.  Note that the procedure   is parsed _after_ the local symbols, now we just insert the extra   information we need into a MIPS_EFI_SYMBOL_NAME symbol that has already   been placed in the procedure's main block.  Note also that images that   have been partially stripped (ld -x) have been deprived   of local symbols, and we have to cope with them here.   The procedure's code ends at BOUND */static voidparse_procedure (pr, bound, have_stabs)	PDR *pr;	int bound;	int have_stabs;{    struct symbol *s, *i;    SYMR *sh = (SYMR*)pr->isym;    struct block *b;    struct mips_extra_func_info *e;    char *sh_name;    /* Static procedure at address pr->adr.  Sigh. */    if (sh == (SYMR*)-1) {	complain (&pdr_static_symbol_complaint, (char *)pr->adr);	return;    }    sh_name = (char*)sh->iss;    if (have_stabs)	s = lookup_symbol(sh_name, NULL, VAR_NAMESPACE, 0, NULL);    else	s = mylookup_symbol(sh_name, top_stack->cur_block,			    VAR_NAMESPACE, LOC_BLOCK);    if (s != 0) {	    b = SYMBOL_BLOCK_VALUE(s);    } else {	    complain (&pdr_for_nonsymbol_complaint, sh_name);#if 1	return;#else/* FIXME -- delete.  We can't do symbol allocation now; it's all done.  */	    s = new_symbol(sh_name);	    SYMBOL_NAMESPACE(s) = VAR_NAMESPACE;	    SYMBOL_CLASS(s) = LOC_BLOCK;	    /* Donno its type, hope int is ok */	    SYMBOL_TYPE(s) = lookup_function_type (builtin_type_int);	    add_symbol(s, top_stack->cur_block);	    /* Wont have symbols for this one */	    b = new_block(2);	    SYMBOL_BLOCK_VALUE(s) = b;	    BLOCK_FUNCTION(b) = s;	    BLOCK_START(b) = pr->adr;	    BLOCK_END(b) = bound;	    BLOCK_SUPERBLOCK(b) = top_stack->cur_block;	    add_block(b, top_stack->cur_st);#endif    }    i = mylookup_symbol(MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, LOC_CONST);    if (i)      {	e = (struct mips_extra_func_info *)SYMBOL_VALUE(i);	e->pdr = *pr;	e->pdr.isym = (long)s;      }}/* Parse the external symbol ES. Just call parse_symbol() after   making sure we know where the aux are for it. For procedures,   parsing of the PDRs has already provided all the needed   information, we only parse them if SKIP_PROCEDURES is false,   and only if this causes no symbol duplication.   BIGEND says whether aux entries are big-endian or little-endian.   This routine clobbers top_stack->cur_block and ->cur_st. */static voidparse_external(es, skip_procedures, bigend)	EXTR *es;	int skip_procedures;	int bigend;{	union aux_ext *ax;	if (es->ifd != ifdNil) {		cur_fd = es->ifd;		cur_fdr = (FDR*)(cur_hdr->cbFdOffset) + cur_fd;		ax = (union aux_ext *)cur_fdr->iauxBase;	} else {		cur_fdr = (FDR*)(cur_hdr->cbFdOffset);		ax = 0;	}	/* Reading .o files */	if (es->asym.sc == scUndefined || es->asym.sc == scNil) {		char *what;		switch (es->asym.st) {		case stStaticProc:		case stProc:	what = "procedure"; n_undef_procs++;  break;		case stGlobal:	what = "variable";  n_undef_vars++;   break;		case stLabel:	what = "label";     n_undef_labels++; break;		default :	what = "symbol";                      break;		}		n_undef_symbols++;		/* FIXME:  Turn this into a complaint? */		if (info_verbose)		    printf_filtered("Warning: %s `%s' is undefined (in %s)\n",			 what, es->asym.iss, fdr_name((char *)cur_fdr->rss));		return;	}	switch (es->asym.st) {	case stProc:		/* If we have full symbols we do not need more */		if (skip_procedures)			return;		if (mylookup_symbol ((char *)es->asym.iss, top_stack->cur_block,				     VAR_NAMESPACE, LOC_BLOCK))			break;		/* fall through */	case stGlobal:	case stLabel:		/*		 * Note that the case of a symbol with indexNil		 * must be handled anyways by parse_symbol().		 */		parse_symbol(&es->asym, ax, bigend);		break;	default:		break;	}}/* Parse the line number info for file descriptor FH into   GDB's linetable LT.  MIPS' encoding requires a little bit   of magic to get things out.  Note also that MIPS' line   numbers can go back and forth, apparently we can live   with that and do not need to reorder our linetables */static voidparse_lines(fh, lt)	FDR *fh;	struct linetable *lt;{	unsigned char *base = (unsigned char*)fh->cbLineOffset;	int j, k;	int delta, count, lineno = 0;	PDR *pr;	if (base == 0)		return;	/* Scan by procedure descriptors */	j = 0, k = 0;	for (pr = (PDR*)IPDFIRST(cur_hdr,fh); j < fh->cpd; j++, pr++) {		int l, halt;		/* No code for this one */		if (pr->iline == ilineNil ||		    pr->lnLow == -1 || pr->lnHigh == -1)			continue;		/*		 *	Aurgh! To know where to stop expanding we		 *	must look-ahead.		 */		for (l = 1; l < (fh->cpd - j); l++)			if (pr[l].iline != -1)				break;		if (l == (fh->cpd - j))			halt = fh->cline;		else			halt = pr[l].iline;		/*		 * When procedures are moved around the linenumbers		 * are attributed to the next procedure up		 */		if (pr->iline >= halt) continue;		base = (unsigned char*)pr->cbLineOffset;		l = pr->adr >> 2;	/* in words */		halt += (pr->adr >> 2) - pr->iline;		for (lineno = pr->lnLow; l < halt;) {			count = *base & 0x0f;			delta = *base++ >> 4;			if (delta >= 8)				delta -= 16;			if (delta == -8) {				delta = (base[0] << 8) | base[1];				if (delta >= 0x8000)					delta -= 0x10000;				base += 2;			}			lineno += delta;/* first delta is 0 */			k = add_line(lt, lineno, l, k);			l += count + 1;		}	}}/* Master parsing procedure for first-pass reading of file symbols   into a partial_symtab.   Parses the symtab described by the global symbolic header CUR_HDR.   END_OF_TEXT_SEG gives the address just after the text segment for   the symtab we are reading.  */static voidparse_partial_symbols (end_of_text_seg, objfile, section_offsets)     int end_of_text_seg;     struct objfile *objfile;     struct section_offsets *section_offsets;

⌨️ 快捷键说明

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