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

📄 dld_section.c

📁 Omap5910 上实现双核通信 DSP GateWay
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif	u8 *dst;	section_for_each(scn, list) {#ifdef DEBUG_RELOCATE		if (scn->nreloc) {			prmsg("%s: reloc entries\n", scn->name);			prmsg("%3s %8s %-20s %8s %8s   %-16s %8s  %8s\n",			      "ent", "addr", "symbol", "sym:olg", "sym:new",			      "type", "original", "new");		}#endif		for (i = 0; i < scn->nreloc; i++) {			/*			 * XXX: ___pinit__ blames.			 * we disable the value check at the moment.			 */#if 0			int safe_relocation = 1;#else			int safe_relocation = 0;#endif			rel = &scn->reloc[i];			if (rel->type & COFF_R_EXTRA_BIT) {				if ((i = extra_relocate(scn, i)) < 0)					return -1;				continue;			}			if (!strcmp(rel->sym.sym->name, "cinit")) {				/*				 * If the module has been compiled with				 * RAM model initialization, it should				 * not refer to the "cinit" symbol, but				 * otherwise there can be this reference.				 * the kernel side, cinit is dummy and				 * the value is illegal (maybe ffffffff).				 *				 * We allow the case the module has not				 * been compiled with RAM model.				 */				safe_relocation = 0;			}			vaddr_relative = rel->vaddr - scn->vaddr_orig;#ifdef DEBUG_RELOCATE			delta = rel_sym_delta(scn, rel, &sym_org, &sym_new);#else			delta = rel_sym_delta(scn, rel);#endif			dst = &scn->data[vaddr_relative];			switch (rel->type) {			case COFF_R_ABS:	/* no relocation */				break;			case COFF_R_LD3_k4:	/* unsigned 4-bit shift immed. */				val = (dst[0] >> 4) + delta;				if (safe_relocation && (val > 0xf))					goto val_invalid;				dst[0] = (val << 4) & (dst[0] & 0xf);				break;			case COFF_R_RELBYTE:	/* 8-bit */			case COFF_R_LD3_K8:	/* 8-bit signed direct */				val = dst[0] + delta;				if (safe_relocation &&				    (val > 0x7f) && (val < 0xffffff80))					goto val_invalid;				dst[0] = val;				break;			case COFF_R_LD3_k8:	/* 8-bit unsigned direct */				val = dst[0] + delta;				if (safe_relocation && (val > 0xff))					goto val_invalid;				dst[0] = val;				break;			case COFF_R_RELWORD:	/* 16-bit */			case COFF_R_LD3_K16:	/* 16-bit signed direct */				val = COFF_SHORT_H(dst) + delta;				if (safe_relocation &&				    (val > 0x7fff) && (val < 0xffff8000))					goto val_invalid;				COFF_PUT_SHORT_H(val, dst);				break;			case COFF_R_LD3_REL16:	/* speculation */			case COFF_R_LD3_k16:	/* 16-bit unsigned direct */				val = COFF_SHORT_H(dst) + delta;				if (safe_relocation && (val > 0xffff))					goto val_invalid;				COFF_PUT_SHORT_H(val, dst);				break;			case COFF_R_REL24:	/* 24-bit */			case COFF_R_LD3_REL23:	/* 23-bit unsigned value in 24-bit field */				val = COFF_24BIT_H(dst) + delta;				if (safe_relocation && (val > 0xffffff))					goto val_invalid;				COFF_PUT_24BIT_H(val, dst);				break;			case COFF_R_RELLONG:				val = COFF_LONG_H(dst) + delta;				COFF_PUT_LONG_H(val, dst);				break;			/*			 * FIXME:			 * Not sure how those types shold be handled			 */			case COFF_R_LD3_DMA:	/* 7 MSBs in a byte (unsigned) */			case COFF_R_LD3_MDP:	/* 7 bits spanning 2bytes (unsigned) */			case COFF_R_LD3_PDP:	/* 9 bits spanning 2bytes (unsigned) */			case COFF_R_LD3_l8:	/* 8-bit unsigned relative */			case COFF_R_LD3_l16:	/* 16-bit unsigned relative */			case COFF_R_LD3_L8:	/* 8-bit signed relative */			case COFF_R_LD3_L16:	/* 16-bit signed relative */			case COFF_R_LD3_k5:	/* unsigned 5-bit shift immed. */			case COFF_R_LD3_K5:	/* signed 5-bit shift immed. */			case COFF_R_LD3_k6:	/* unsigned 6-bit shift immed. */			case COFF_R_LD3_k12:	/* unsigned 12-bit shift immed. */			default:				prmsg("We can't handle this type of "				      "relocation [%04x]! "				      "(section %s, entry %d)\n"				      "Please contact to developer.\n",				      rel->type, scn->name, i);				return -1;			}#ifdef DEBUG_RELOCATE			prmsg(" %2d %08lx %-20s %08lx %08lx"			      "   %04x(%-10s) %08lx  %08lx\n",			      i, vaddr_relative, rel->sym.sym->name,			      sym_org, sym_new,			      rel->type, reloc_name(rel->type),			      val - delta, val);#endif		}	}	return 0;val_invalid:#ifdef DEBUG_RELOCATE	prmsg(" %2d %08lx %-20s %08lx %08lx"	      "   %04x(%-10s) %08lx  %08lx\n",	      i, vaddr_relative, rel->sym.sym->name, sym_org, sym_new,	      rel->type, reloc_name(rel->type), val - delta, val);#endif	prmsg("relocated value %x is invalid for relocation type %s!\n",	      val, reloc_name(rel->type));	return -1;}static int extra_relocate(struct section *scn, int i){	u32 vaddr = scn->reloc[i].vaddr;	u32 vaddr_relative = vaddr - scn->vaddr_orig;#define STKSZ	10	u32 stack[STKSZ];	int sp = 0;	for (; i < scn->nreloc; i++) {		struct reloc *rel = &scn->reloc[i];		if (rel->vaddr != vaddr)			break;		switch (rel->type) {			case COFF_R_EX_PSHSYM:				stack[sp++] = rel_sym_val(scn, rel);				break;			case COFF_R_EX_PSHVAL:				stack[sp++] = rel->sym.val;				break;			case COFF_R_EX_PSHINTOFF:				/*				 * internal reloc + offset value				 */				stack[sp++] = scn->vaddr + rel->sym.val;				break;			case COFF_R_EX_ADD:				stack[0] += stack[--sp];				break;			case COFF_R_EX_SUB:				stack[0] -= stack[--sp];				break;			case COFF_R_EX_RSHIFT:				stack[0] >>= stack[--sp];				break;			case COFF_R_EX_MASK:				stack[0] &= stack[--sp];				break;			/*			 * XXX:			 * Couldn't find out the difference among			 * three below.			 */			case COFF_R_EX_WRITE1:			case COFF_R_EX_WRITE2:			case COFF_R_EX_WRITE3:			{				u8 roff, loff, masksz;				u32 msb_ptr;				u32 parm, mask, offset;				u8 *dst;				parm = rel->sym.val;				roff   = (parm >> 16) & 0xff;				masksz = (parm >>  8) & 0xff;				loff   =  parm        & 0xff;				if ((masksz > 32) || (roff > 32) || (loff > 32) ||				    (roff & 0x07)) {					prmsg("illegal writeback parm [%08x]! "					      "(section %s, entry %d)\n"					      "Please contact to developer.\n",					      parm, scn->name, i);					return -1;				}				mask = 0xffffffff >> (32-masksz) << loff;				msb_ptr = vaddr_relative + (roff-loff+7)/8 - 4;				dst = &scn->data[msb_ptr];				offset = COFF_LONG_H(dst);				stack[0] = (offset & ~mask) |					   ((stack[0] << loff) & mask);				COFF_PUT_LONG_H(stack[0],dst);				break;			}			default:				prmsg("We can't handle this type of relocation [%04x]! "				      "(section %s, entry %d)\n"				      "Please contact to developer.\n",				      rel->type, scn->name, i);		}#ifdef DEBUG_RELOCATE		switch (rel->type) {			case COFF_R_EX_PSHSYM:				prmsg(" %2d %08lx %-20s %8s %08lx"				      "   %04x(%-10s)\n",				      i, vaddr_relative,				      rel->sym.sym->name,				      "", stack[sp-1],				      rel->type, reloc_name(rel->type));				break;			case COFF_R_EX_PSHVAL:			case COFF_R_EX_PSHINTOFF:				prmsg(" %2d %08lx   %08lx%10s %8s %8s"				      "   %04x(%-10s)\n",				      i, vaddr_relative, rel->sym.val,				      "", "", "",				      rel->type, reloc_name(rel->type));				break;			case COFF_R_EX_ADD:			case COFF_R_EX_SUB:			case COFF_R_EX_RSHIFT:			case COFF_R_EX_MASK:				prmsg(" %2d %08lx %-20s %8s %8s"				      "   %04x(%-10s) %8s (%08lx)\n",				      i, vaddr_relative, "", "", "",				      rel->type, reloc_name(rel->type),				      "", stack[0]);				break;			case COFF_R_EX_WRITE1:			case COFF_R_EX_WRITE2:			case COFF_R_EX_WRITE3:				prmsg(" %2d %08lx   %08lx%10s %8s %8s"				      "   %04x(%-10s) %8s (%08lx)\n",				      i, vaddr_relative, rel->sym.val,				      "", "", "",				      rel->type, reloc_name(rel->type),				      "", stack[0]);				break;		}#endif	}	return i-1;}inline int rel_sym_field_type(u16 type){	switch (type) {		case COFF_R_RELBYTE:		case COFF_R_RELWORD:		case COFF_R_LD3_REL16:		case COFF_R_REL24:		case COFF_R_LD3_REL23:		case COFF_R_RELLONG:		case COFF_R_LD3_DMA:		case COFF_R_LD3_MDP:		case COFF_R_LD3_PDP:		case COFF_R_LD3_k8:		case COFF_R_LD3_k16:		case COFF_R_LD3_K8:		case COFF_R_LD3_K16:		case COFF_R_LD3_l8:		case COFF_R_LD3_l16:		case COFF_R_LD3_L8:		case COFF_R_LD3_L16:		case COFF_R_LD3_k4:		case COFF_R_LD3_k5:		case COFF_R_LD3_K5:		case COFF_R_LD3_k6:		case COFF_R_LD3_k12:		case COFF_R_EX_PSHSYM:			return RELOC_SYMBOL_FIELD_TYPE_SYMBOL;		case COFF_R_EX_PSHVAL:		case COFF_R_EX_PSHINTOFF:		case COFF_R_EX_WRITE1:		case COFF_R_EX_WRITE2:		case COFF_R_EX_WRITE3:			return RELOC_SYMBOL_FIELD_TYPE_VALUE;		default:			return RELOC_SYMBOL_FIELD_TYPE_INVALID;	}}static char *reloc_name(u16 type){	switch (type) {		case COFF_R_ABS:		return("ABS");		case COFF_R_REL24:		return("REL24");		case COFF_R_RELBYTE:		return("RELBYTE");		case COFF_R_RELWORD:		return("RELWORD");		case COFF_R_RELLONG:		return("RELLONG");		case COFF_R_LD3_DMA:		return("LD3_DMA");		case COFF_R_LD3_MDP:		return("LD3_MDP");		case COFF_R_LD3_PDP:		return("LD3_PDP");		case COFF_R_LD3_REL23:		return("LD3_REL23");		case COFF_R_LD3_k8:		return("LD3_k8");		case COFF_R_LD3_k16:		return("LD3_k16");		case COFF_R_LD3_K8:		return("LD3_K8");		case COFF_R_LD3_K16:		return("LD3_K16");		case COFF_R_LD3_l8:		return("LD3_l8");		case COFF_R_LD3_l16:		return("LD3_l16");		case COFF_R_LD3_L8:		return("LD3_L8");		case COFF_R_LD3_L16:		return("LD3_L16");		case COFF_R_LD3_k4:		return("LD3_k4");		case COFF_R_LD3_k5:		return("LD3_k5");		case COFF_R_LD3_K5:		return("LD3_K5");		case COFF_R_LD3_k6:		return("LD3_k6");		case COFF_R_LD3_k12:		return("LD3_k12");		case COFF_R_LD3_REL16:		return("LD3_REL16");		case COFF_R_EX_ADD:		return("EX_ADD");		case COFF_R_EX_SUB:		return("EX_SUB");		case COFF_R_EX_RSHIFT:		return("EX_RSHIFT");		case COFF_R_EX_MASK:		return("EX_MASK");		case COFF_R_EX_WRITE1:		return("EX_WRITE1");		case COFF_R_EX_WRITE2:		return("EX_WRITE2");		case COFF_R_EX_PSHSYM:		return("EX_PSHSYM");		case COFF_R_EX_PSHVAL:		return("EX_PSHVAL");		case COFF_R_EX_PSHINTOFF:	return("EX_PSHINTOFF");		case COFF_R_EX_WRITE3:		return("EX_WRITE3");	}	return("unknown");}#ifdef DEBUG_RELOCATEstatic u32 __rel_sym_val(struct section *scn, struct reloc *rel,			 u32 *org, u32 *new, int delta)#elsestatic u32 __rel_sym_val(struct section *scn, struct reloc *rel, int delta)#endif{	struct symbol *sym;	struct section *scn_target;	u32 _org, _new, val;	sym = rel->sym.sym;	if (sym == &symbol_internalreloc) {		_org = scn->vaddr_orig;		_new = scn->vaddr;		scn_target = scn;	} else {		_org = sym->value_orig;		_new = sym->value;		scn_target = sym->scn;	}	/*	 * text pointer: byte address	 * data pointer: word address	 */	if (!(scn_target->flags & COFF_STYP_TEXT)) {		_org >>= 1;		_new >>= 1;	}	val = delta ? _new - _org : _new;#ifdef DEBUG_RELOCATE	/* debug info return */	if (org)		*org = _org;	if (new)		*new = _new;#endif	return val;}static int section_loadtype(struct section *scn){	if (scn->size == 0)		return LDTYP_ZEROSZ;	if (scn->data == NULL) {		if (scn->flags & COFF_STYP_BSS)			return LDTYP_LOAD;		else			return LDTYP_NODATA;	}	if (scn->flags & (COFF_STYP_DSECT | COFF_STYP_NOLOAD | COFF_STYP_PAD))		return LDTYP_NOLOAD;	if (scn->flags & COFF_STYP_COPY) {		if (!strcmp(scn->name, ".cinit"))			return LDTYP_CINIT_RAM;		else			return LDTYP_NOLOAD;	}	return LDTYP_LOAD;}static struct section *section_find_by_addr(struct list_head *list, u32 addr){	struct section *scn;	section_for_each(scn, list) {		if ((addr >= scn->vaddr) &&		    (addr < scn->vaddr + scn->size) &&		    !(scn->flags & (COFF_STYP_DSECT |				    COFF_STYP_NOLOAD |				    COFF_STYP_PAD |				    COFF_STYP_COPY)))			return scn;	}	/* not found */	return NULL;}struct section *section_find_by_name(struct list_head *list, char *name){	struct section *scn;	section_for_each(scn, list) {		if (!strcmp(scn->name, name))			return scn;	}	/* not found */	return NULL;}void section_sendstat(struct list_head *list, int fd){	char buf[256];	size_t strsz = 256 - SERVER_EVENT_HDRSZ;	struct server_event *e = (struct server_event *)buf;	struct section *scn;	int cnt;#ifdef STICKY_LIST	if (list == NULL)		list = &g_scnlist;#endif	e->event = DLD_EVENT_STRING;	cnt = snprintf(e->data.s, strsz, "%-20s %8s  %8s  %4s %10s\n",		       "name", "vaddr", "size", "nrel", "flags");	e->len = SERVER_EVENT_HDRSZ + cnt;	write(fd, e, e->len);	section_for_each(scn, list) {		int real_addr;		real_addr = (scn->flags & (COFF_STYP_DSECT |					   COFF_STYP_NOLOAD |					   COFF_STYP_PAD |					   COFF_STYP_COPY)) ? 0 : 1;		cnt = snprintf(e->data.s, strsz,			       "%-20s 0x%06lx%c 0x%06lx%c %4ld 0x%08lx\n",			       scn->name,			       scn->vaddr, real_addr ? ' ' : '-',			       scn->size,  scn->data ? ' ' : '-',			       scn->nreloc, scn->flags);		e->len = SERVER_EVENT_HDRSZ + cnt;		write(fd, e, e->len);	}}/* * debug stuff */void section_printstat(struct list_head *list){	struct section *scn;	prmsg("section list status ...\n");	prmsg("  %-20s %8s  %8s  %4s %10s\n",	      "name", "vaddr", "size", "nrel", "flags");	section_for_each(scn, list) {		int real_addr;		real_addr = (scn->flags & (COFF_STYP_DSECT |					   COFF_STYP_NOLOAD |					   COFF_STYP_PAD |					   COFF_STYP_COPY)) ? 0 : 1;		prmsg("  %-20s 0x%06lx%c 0x%06lx%c %4ld 0x%08lx\n",		      scn->name,		      scn->vaddr, real_addr ? ' ' : '-',		      scn->size,  scn->data ? ' ' : '-',		      scn->nreloc,		      scn->flags);	}}

⌨️ 快捷键说明

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