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

📄 loadecofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                    /* following cast to short guarantees sign extension */		    relocConstant = (*pAddress << 16) + 			(int) ((short)(LS16BITS & *pNextAddress));		    targetAddr = (long) pExternals[relocCmd.r_symndx] + 			relocConstant;		    if ((LS16BITS & targetAddr) >= OVERFLOW)			targetAddr += OVERFLOW_COMPENSATION;		    *pAddress = (MS16BITS & *pAddress) + 			((unsigned) targetAddr >> 16);		    *pNextAddress = (MS16BITS & *pNextAddress) + 			(LS16BITS & targetAddr);	            break;	        case R_REFLO:    		/*    		*  Since a REFHI must occur with a REFLO pair (lui, addi 		*  instructions) it was originally thought that a REFLO 		*  entry would never be seen alone.  This turned out to be 		*  an incorrect assumption.  If a R_REFLO is by itself, it 		*  is assumed to belong to the last R_REFHI entry.    		*/                    /* following cast to short guarantees sign extension */		    relocConstant = refhiConstant +                         (int) ((short)(LS16BITS & *pAddress));		    targetAddr = (long) pExternals[relocCmd.r_symndx] + 			relocConstant;		    if ((LS16BITS & targetAddr) >= OVERFLOW)			targetAddr += OVERFLOW_COMPENSATION;		    *pAddress = (MS16BITS & *pAddress) + 			(LS16BITS & targetAddr);		    break;	        case R_GPREL:	        case R_LITERAL:		    printErr (gpRelativeReloc);	    	    errnoSet (S_loadEcoffLib_GPREL_REFERENCE);		    return (ERROR); 	/* gp reg addressing not supported */		    break;	        case R_ABS:		    break;		/* relocation already performed */	        default:		    printErr("Unrecognized ext relocation type %d\n",		        relocCmd.r_type);	    	    errnoSet (S_loadEcoffLib_UNRECOGNIZED_RELOCENTRY);		    return (ERROR);		    break;	        }	    }	else	/* local relocation */	    {	    switch (relocCmd.r_symndx)		{		case R_SN_INIT:		case R_SN_TEXT:		    relSegment = RTEXT;	    	    break;		case R_SN_DATA:		case R_SN_RDATA:			case R_SN_SDATA:	/* treat as data with no GP */		    relSegment = RDATA;	            break;		case R_SN_BSS:		case R_SN_SBSS:		/* treat as bss with no GP  */		    relSegment = RBSS;		    break;		case R_SN_LIT4:			case R_SN_LIT8:			    printErr (gpRelativeReloc);	    	    errnoSet (S_loadEcoffLib_GPREL_REFERENCE);		    return (ERROR);		    break;		default:		    printErr ("Unknown symbol number %d\n", relocCmd.r_symndx);	    	    errnoSet (S_loadEcoffLib_UNRECOGNIZED_RELOCENTRY);		    return (ERROR); 			    break;		} 	    switch (relocCmd.r_type)		{		case R_REFWORD:				/*		*  This relocation is performed by adding the 32 bit address		*  of the symbol to the contents of pAddress.  The address of		*  the symbol is found by adding the relative segment address		*  to the contents of the address we are relocating.		*  See IDT Assembly language programmers guide pg. 10-16		*/		    if (relSegment == RTEXT)			{			relocOffset = *pAddress; 			*pAddress = ((long) pSeg->addrText + relocOffset);			}		    else if (relSegment == RDATA)			{			relocOffset = *pAddress - pSeg->sizeText; 			*pAddress = ((long) pSeg->addrData + relocOffset);			}		    else /* relSegment == RBSS */			{			relocOffset = *pAddress - pSeg->sizeText - 			    pSeg->sizeData; 			*pAddress = ((long) pSeg->addrBss + relocOffset);			}		    break;		case R_REFHALF: 	/* WARNING: UNTESTED */		/* 		*  This case is not well documented by MIPS, and has never		*  been generated.  REFWORD and REFHALF relocation entries		*  are generally used for pointers, and a case where you have		*  a 16 bit pointer is very unlikely to occur on a 32 bit		*  architecture.		*/		    if (relSegment == RTEXT)			{			relocOffset = *pAddress; 			*pAddress = ((long) pSeg->addrText + relocOffset);			}		    else if (relSegment == RDATA)			{			relocOffset = *pAddress - pSeg->sizeText; 			*pAddress = ((long) pSeg->addrData + relocOffset);			}		    else /* relSegment == RBSS */			{			relocOffset = *pAddress - pSeg->sizeText - 			    pSeg->sizeData; 			*pAddress = ((long) pSeg->addrBss + relocOffset);			}		    if (LS16BITS & *pAddress >= OVERFLOW)		        {		        errnoSet (S_loadEcoffLib_REFHALF_OVFL);		        return (ERROR);		        }		    break;		case R_JMPADDR:		/* 		*  For this relocation type the loader determines the address		*  for the jump, shifts the address right two bits, and adds 		*  the lower 26 bits of the result to the low 26 bits of the 		*  instruction at pAddress (after sign extension).  The		*  results go back into the low 26 bits at pAddress.		*  The initial check is to see if the jump is within range.  		*  The current address is incremented by 4 because the jump		*  actually takes place in the branch delay slot of the		*  current address.  The address for the jump is dependant 		*  on the contents of the address we are relocating and		*  the address of the relative section.		*  See IDT Assembly language programmers guide pg. 10-16		*/		    if (relSegment == RTEXT)			{		        targetAddr = (((LS26BITS & *pAddress) << 2)			    + (MS4BITS & (long) pAddress )		            + (long) pSeg->addrText);			}		    else if (relSegment == RDATA)			{			targetAddr = (((LS26BITS & *pAddress) << 2)		            + (MS4BITS & (long) pAddress )			    + (long) pSeg->addrData);			}		    else /* relSegment == RBSS */			{			targetAddr = (((LS26BITS & *pAddress) << 2)		            + (MS4BITS & (long) pAddress )			    + (long) pSeg->addrBss);			}                    if (MS4BITS & targetAddr !=		        (MS4BITS & ((long) pAddress + sizeof(INSTR))))		        {		        errnoSet (S_loadEcoffLib_JMPADDR_ERROR);		        return (ERROR);		        }		    targetAddr = (unsigned) targetAddr >> 2;                    /* checking for overflows here is not valid */		    targetAddr &= LS26BITS;		    *pAddress =  (MS6BITS & *pAddress) | targetAddr;		    break;		case R_REFHI:		/*		*  A refhi relocation is done by reading the next relocation		*  entry (always the coresponding reflo entry).  This least		*  significant 16 bits are taken from the refhi instruction 		*  and shifted left to form a 32 bit value.  This value is 		*  added to the least significant 16 bits of the reflo 		*  instruction (taking into account sign extention) to form 		*  a 32 bit reference pointer.  The target address is added 		*  to this constant and placed back in the least significant 		*  16 bits of each instruction address.  The contents of the 		*  lower 16 bits of pAddress (refhiConstant) are saved for any 		*  other reflo entries that the refhi entry may correspond to.		*  See IDT Assembly language programmers guide pg. 10-16		*/		    refhiConstant = (*pAddress << 16);		    nextRelocCmd = *pRelCmds++;		    nCmds -= 1;	    	    if (nextRelocCmd.r_type != R_REFLO) 			{	    	        errnoSet (S_loadEcoffLib_NO_REFLO_PAIR);		        return (ERROR);			}        	    if (segment == RTEXT)			{	    	        pNextAddress = (long *) ((long) pSeg->addrText + 			    nextRelocCmd.r_vaddr);			}		    else /* segment == RDATA */			{	    		pNextAddress = (long *) ((long) pSeg->addrData + 			    (nextRelocCmd.r_vaddr - 			    (long) pSeg->sizeText));			}		    /* following cast to short guarantees sign extension */		    relocConstant = ((LS16BITS & *pAddress) << 16)		        + (int) ((short) (LS16BITS & *pNextAddress));		    if (relSegment == RTEXT)			{			targetAddr = relocConstant + (long) pSeg->addrText;			}		    else if (relSegment == RDATA)			{			relocConstant = relocConstant - pSeg->sizeText;		        targetAddr = relocConstant + (long) pSeg->addrData;			}		    else /* relSegment == RBSS */			{			relocConstant = relocConstant - pSeg->sizeText - 			    pSeg->sizeData;		        targetAddr = relocConstant + (long) pSeg->addrBss;			}                    if ((LS16BITS & targetAddr) >= OVERFLOW)		        targetAddr += OVERFLOW_COMPENSATION;		    *pAddress = ((MS16BITS & *pAddress) |		 	((unsigned) (MS16BITS & targetAddr) >> 16));		    *pNextAddress = (MS16BITS & *pNextAddress) | 			(LS16BITS & targetAddr);	            break;		case R_REFLO:		/*		*  Since a REFHI must occur with a REFLO pair (lui, addi 		*  instructions) it was originally thought that a REFLO 		*  entry would never be seen alone.  This turned out to 		*  be an incorrect assumption.  If a R_REFLO is by itself, 		*  it is assumed to belong to the last R_REFHI entry.		*/                    /* following cast to short guarantees sign extension */		    relocConstant = (LS16BITS & refhiConstant) 			+ (int) ((short) (LS16BITS & *pAddress));		    if (relSegment == RTEXT)			{			targetAddr = relocConstant + 			    (long) pSeg->addrText;			}		    else if (relSegment == RDATA)			{			relocConstant = relocConstant - pSeg->sizeText;		        targetAddr = relocConstant + (long) pSeg->addrData;			}		    else /* relSegment == RBSS */			{			relocConstant = relocConstant - pSeg->sizeText - 			    pSeg->sizeData;		        targetAddr = relocConstant + (long) pSeg->addrBss;			}		    if ((LS16BITS & targetAddr) >= OVERFLOW)			targetAddr += OVERFLOW_COMPENSATION;		    *pAddress = ((MS16BITS & *pAddress) | 			(LS16BITS & targetAddr));		    break;		case R_GPREL:		case R_LITERAL:		    printErr (gpRelativeReloc);	    	    errnoSet (S_loadEcoffLib_GPREL_REFERENCE);		    return (ERROR);  /* gp relative addressing not supported */		    break;		case R_ABS:		    break;	/* relocation already completed */		default:		    printErr ("Unknown relocation type %d\n", relocCmd.r_type);	    	    errnoSet (S_loadEcoffLib_UNRECOGNIZED_RELOCENTRY);		    return (ERROR); /* unrecognized relocation type */		    break;		}	    }	}    return (OK);    }/********************************************************************************* softSeek - seek forward into a file** This procedure seeks forward into a file without actually using seek* calls.  It is usefull since seek does not work on all devices.** RETURNS:* OK, or* ERROR if forward seek could not be accomplished**/LOCAL STATUS softSeek     (    int fd,			/* fd to seek with */    int startOfFileOffset 	/* byte index to seek to */    )    {    int position;		/* present file position */    int bytesToRead;		/* bytes needed to read */    char tempBuffer[BUFSIZE];	/* temp buffer for bytes */    position = ioctl (fd, FIOWHERE, (int) 0);    if (position > startOfFileOffset)	return(ERROR);    /* calculate bytes to read */    bytesToRead = startOfFileOffset - position;    while (bytesToRead >= BUFSIZE)	{        if (fioRead (fd, tempBuffer, BUFSIZE) != BUFSIZE)	    return (ERROR);	bytesToRead -= BUFSIZE;	}    if (bytesToRead > 0)	{        if (fioRead (fd, tempBuffer, bytesToRead) != bytesToRead)	    return (ERROR);	}    return(OK);    }/********************************************************************************* ecoffToVxSym - Translate an ecoff symbol type to a VxWorks symbol type** This procedure translates an ecoff symbol type to a symbol type that the * VxWorks symbol table can understand.** RETURNS:* OK, or* ERROR if the symbol could not be tranlated.**/LOCAL STATUS ecoffToVxSym    (    EXTR *symbol,		/* ecoff symbol to convert */    SYM_TYPE *pVxSymType 	/* where to place conversion */    )    {    switch(symbol->U_SYM_TYPE)	{	case scText:	    *pVxSymType = (SYM_TYPE) N_TEXT;	    break;	case scData:	case scRData:        case scSData:	    *pVxSymType = (SYM_TYPE) N_DATA;	    break;	case scBss:        case scSBss:	    *pVxSymType = (SYM_TYPE) N_BSS;	    break;	case scCommon:	case scSCommon:	    *pVxSymType = (SYM_TYPE) N_COMM;	    break;        case scUndefined:	case scSUndefined:        case scNil:	case scAbs:	    errnoSet (S_loadEcoffLib_UNEXPECTED_SYM_CLASS);	    return (ERROR);	    break;	default:	    errnoSet (S_loadEcoffLib_UNRECOGNIZED_SYM_CLASS);	    return (ERROR);	    break;	}    /* convert to global symbol ? */    if (COFF_EXT(symbol))	*pVxSymType |= (SYM_TYPE) N_EXT;    return (OK);    }/********************************************************************************* nameToRelocSection - Convert COFF section name to integer representation** This procedure converts a COFF section name to it's appropriate integer* designator.  ** RETURNS:* Integer value of section name* or ERROR if section relocation is not supported.**/LOCAL int nameToRelocSection    (    char * pName         /* section name */    )    {    if (strcmp (pName,_TEXT) == 0)        return (R_SN_TEXT);    else if (strcmp (pName,_RDATA) == 0)        return (R_SN_RDATA);    else if (strcmp (pName,_DATA) == 0)        return (R_SN_DATA);    else if (strcmp (pName,_SDATA) == 0)        return (ERROR);			/* R_SN_SDATA: no gp rel sections */    else if (strcmp (pName,_SBSS) == 0)        return (ERROR);			/* R_SN_SBSS: no gp rel sections */    else if (strcmp (pName,_BSS) == 0)        return (ERROR);			/* R_SN_BSS: bss not relocatable */    else if (strcmp (pName,_INIT) == 0)	return (R_SN_INIT);    else if (strcmp (pName,_LIT8) == 0)        return (ERROR);			/* R_SN_LIT8: no gp rel sections */    else if (strcmp (pName,_LIT4) == 0)        return (ERROR);			/* R_SN_LIT8: no gp rel sections */    else        return (ERROR);     		/* return ERROR */    }/********************************************************************************* swapCoffscnHdr - swap endianess of COFF section header* */LOCAL void swapCoffscnHdr    (    SCNHDR *pScnHdr 		/* module's ECOFF section header */    )    {    SCNHDR tempScnHdr;    bcopy ((char *) &pScnHdr->s_name[0], (char *) &tempScnHdr.s_name[0], 8);    swabLong ((char *) &pScnHdr->s_paddr, (char *) &tempScnHdr.s_paddr);    swabLong ((char *) &pScnHdr->s_vaddr, (char *) &tempScnHdr.s_vaddr);    swabLong ((char *) &pScnHdr->s_size, (char *) &tempScnHdr.s_size);    swabLong ((char *) &pScnHdr->s_scnptr, (char *) &tempScnHdr.s_scnptr);    swabLong ((char *) &pScnHdr->s_relptr, (char *) &tempScnHdr.s_relptr);    swabLong ((char *) &pScnHdr->s_lnnoptr, (char *) &tempScnHdr.s_lnnoptr);    swab ((char *) &pScnHdr->s_nreloc, (char *) &tempScnHdr.s_nreloc, 

⌨️ 快捷键说明

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