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

📄 loadcofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif  /* DEBUG */	}    return(status);    }#endif /* (CPU_FAMILY == AM29XXX) */#if (CPU_FAMILY == I960)/********************************************************************************* coffRelSegmentI960 - perform relocation for the I960 family** This routine reads the specified relocation command segment and performs* all the relocations specified therein.* Absolute symbol addresses are looked up in the 'externals' table.** This function handles the following types of relocation commands* for the i960 processor:*	R_RELLONG  - direct 32 bit relocation*	R_IPRMED   - 24-bit IP-relative relocation*       R_OPTCALL  - optimizable call (check if can be changed to BAL)*       R_OPTCALLX - optimizable callx (check if can be changed to BALX)*		* RETURNS: OK or ERROR*/LOCAL STATUS coffRelSegmentI960    (    RELOC *pRelCmds,		/* list of relocation commands */    SCNHDR *pScnHdrArray,	/* array of section headers */    char *scnAddr,		/* section loaded address */    char **pExternals,		/* array of absolute symbol values */    SYMENT *pExtSyms,         /* pointer to object file symbols */    SEG_INFO *pSeg,		/* section addresses and sizes */    int section,                /* section number -1 for relocation */    SYMTAB_ID symTbl		/* symbol table to use */    )    {    FAST long *pAdrs;           /* relocation address */    int nCmds;                  /* # reloc commands for seg */    RELOC relocCmd;             /* relocation structure */    INT8 *symVal0 = 0;          /* absolute symbol value */    INT8 *symVal1 = 0;          /* leaf-proc absolute symbol value */    INT32 offset;	        /* relocation value accumulator */    char symName[MAX_SYS_SYM_LEN + 1];      /* temp buffer for symbol name */    SYM_TYPE symType;           /* type from sys symbol table */    STATUS status = OK;    SYMENT *pSym;             /* pointer to an external symbol */    SCNHDR *pScnHdr;		/* section header for relocation */    pScnHdr = pScnHdrArray + section;    for (nCmds = pScnHdr->s_nreloc; nCmds > 0; nCmds--)	{	/* read relocation command */	relocCmd = *pRelCmds++;	/* 	 * Calculate actual address in memory that needs relocation.	 */        if (pScnHdr->s_flags & STYP_TEXT)	    {	    pAdrs = (long *) ((long) scnAddr + (relocCmd.r_vaddr - pScnHdr->s_vaddr));	    }	else                            /* (pScnHdr->s_flags & STYP_DATA) */	    {	    pAdrs = (long *) ((long) scnAddr + (relocCmd.r_vaddr - pScnHdr->s_vaddr));	    }#ifdef DEBUG        DPRINTF("r_vaddr=%02x *pAdrs=%08x ",                 relocCmd.r_vaddr, *(UINT32 *)pAdrs);#endif  /* DEBUG */        switch (relocCmd.r_type)            {        case R_OPTCALL:        case R_OPTCALLX:            /* Check for a call to a leaf procedure.  If it is, then             * replace the CALL opcode with BAL and correct the displacement.             */#ifdef DEBUG            if (relocCmd.r_type == R_OPTCALL)                {                DPRINTF("OPTCALL ");                }            else                {                DPRINTF("OPTCALLX ");                }#endif	    if (fast_load == FALSE)		{		if (symFindByValue (symTbl, (UINT)symVal0, (char *) symName,				    (int *) &symVal0, &symType)		    != OK)		    {		    printErr (symNotFoundErrMsg);		    status = ERROR;		    break; 		/* skip to next symbol */		    }		if (symType & BAL_ENTRY)		    {		    /* get symbol value from externals table */		    symVal0 = (INT8 *) (pExternals[relocCmd.r_symndx]);		    /* cat a ".lf" on the end of the symName */		    strcat ((char *)symName, ".lf");		    /* Now check if a symbol exists as name.lf		     * If it does, it is the BAL entry for the leaf proc.		     * start at symName[1] to ignore the '_'.		     */		    if (symFindByName (symTbl, &symName[1],				       &symVal1, &symType) == OK)			{#ifdef DEBUG			DPRINTF("LEAF ");#endif  /* DEBUG */			/* A call to a leaf procedure: replace			 * CALL opcode with BAL.			 */			if (relocCmd.r_type == R_OPTCALL)			    {			    offset = (INT32) *pAdrs;			    offset &= OFFSET24_MASK;	/* clear opcode */			    offset |= ~OFFSET24_MASK;	/* sign extend */			    offset += ((INT32) symVal1 - (INT32) symVal0);			    offset &= OFFSET24_MASK;			    *(UINT32 *)pAdrs = BAL_OPCODE | offset;			    }			else                /* R_OPTCALLX */			    {			    /*  Put in opcode for BALX with:			     *      absolute displacement addressing mode and			     *      register g14 for the return address.			     */			    *(UINT32 *)pAdrs = BALXG14_OPCODE;			    *(UINT32 *)(pAdrs+1) +=                            (INT32) symVal1 - (INT32) symVal0; #ifdef DEBUG			    DPRINTF("*(pAdrs+1)=%08x ", *(UINT32 *)(pAdrs+1));#endif  /* DEBUG */			    }			}		    }		else		    {#ifdef DEBUG		    DPRINTF("NO LEAF ");#endif  /* DEBUG */		    /* No leaf proc entry.		     * Do nothing with the OPTCALL.		     * This is a normal call/return routine.		     */		    }		}            break;        case R_RELLONG:            /*             *  This relocation is performed by adding the absolute address             *  of the symbol to the relocation value in the code and             *  subtracting the symbol's value (relative to the section).             *             * The new reloc_value =             *   symbol_absolute_addr + reloc_value_in_code - symbol_value;             *             *  Both reloc_value_in_code and symbol_value are relative to             *  the beginning of the first section in the object file.             *  For undefined externals, reloc_value_in_code = 0             *  and symbol_value = 0.             */#ifdef DEBUG            DPRINTF("RELLONG ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */            offset = (INT32) pExternals[relocCmd.r_symndx];            pSym = pExtSyms + relocCmd.r_symndx;            if (! COFF_COMM(pSym))                {                offset -= pSym->n_value;#ifdef DEBUG                DPRINTF("n_value=0x%x ", pSym->n_value);#endif  /* DEBUG */                }            *pAdrs += offset;            break;        case R_IPRMED:#ifdef DEBUG            DPRINTF("IPRMED  ");#endif  /* DEBUG */            pSym = pExtSyms + relocCmd.r_symndx;            if (COFF_UNDF(pSym))        /* if symbol was undefined external */                {                /* Code to be relocated contains an offset                 * to the beginning of the first section in the object file.                 * To relocate it, add the absolute address                 * of the referenced symbol and subtract the                 * amount by which the input section will be                 * relocated.                 */                offset = (INT32) *pAdrs;                offset &= OFFSET24_MASK;	/* clear opcode */                offset |= ~OFFSET24_MASK;	/* sign extend */                offset += (INT32) pExternals [relocCmd.r_symndx];#ifdef DEBUG                DPRINTF("sym=%08x ", (unsigned)pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */                /* IP-relative relocations were done assuming                 * text starts at 0. Adjust for actual start of text. */                offset -= (INT32)scnAddr - pScnHdr->s_vaddr;                offset &= 0x00ffffff;                *(UINT32 *)pAdrs = (*(UINT32 *)pAdrs & 0xff000000) | offset;                }            else                {#ifdef DEBUG                DPRINTF("NO RELOC ");#endif  /* DEBUG */                /* The symbol we are relocating to came from                 * the same input file as the code that                 * references it.  The relative distance                 * between the two will not change.  Do nothing.                 */                }            break;	default:            printErr("Unrecognized relocation type %d\n",                     relocCmd.r_type);            errnoSet (S_loadLib_UNRECOGNIZED_RELOCENTRY);            return (ERROR);            break;	    }#ifdef DEBUG        DPRINTF("*pAdrs=%08x\n", *(UINT32 *)pAdrs);#endif  /* DEBUG */	}    return(status);    }#endif /* (CPU_FAMILY == I960) */#if (CPU_FAMILY == ARM)/********************************************************************************            * CoffRelSegmentArm - perform relocation for the ARM family** This routine reads the specified relocation command segment and performs* all the relocations specified therein.* Absolute symbol addresses are looked up in the 'externals' table.** This function handles the following types of relocation commands* for the ARM family of processor:**	- R_RELBYTE	Byte PC Relative*	- R_RELWORD	Word PC Relative*	- R_RELARMLONG	Long PC Relative*	- R_RELARM26	26 bit PC Relative*	- R_DONEARM26	completed 26 bit PC relative*	- R_THUMB9	Thumb  9 bit PC-relative*	- R_THUMB12	Thumb 12 bit PC-relative*	- R_THUMB23	Thumb 23 bit PC-relative*	- R_DONETHUMB23	completed Thumb 23 bit PC-relative** Note that RVA32 relocations are never produced in ARM code.** RETURNS: OK or ERROR** INTERNAL* Large parts of this code were taken lifted from the host-based loader* when it had not been fully tested and the tool-chain was full of* problems. Consequently, there may be bugs...* The handling of literal sections (.lit/.rdata) is taken from the* Am29k code above.*/ LOCAL STATUS coffRelSegmentArm    (    RELOC *	pRelCmds,	/* list of relocation commands */    SCNHDR *	pScnHdrArray,	/* array of section headers */    char **	pExternals,	/* array of absolute symbol values */    SYMENT *	pExtSyms,	/* pointer to object file symbols */    SEG_INFO *	pSeg,		/* section addresses and sizes */    int		section,	/* section number -1 for relocation */    SYMTAB_ID	symTbl		/* symbol table to use */    )    {    void *	pAdrs;		/* relocation address */    int		nCmds;		/* # reloc commands for seg */    RELOC	relocCmd;	/* relocation structure */    STATUS	status = OK;    ULONG	value;		/* value being relocated */    SCNHDR *	pScnHdr;	/* section header for relocation */    SYMENT *	pSym;		/* pointer to external symbol */     pScnHdr = pScnHdrArray + section;     for (nCmds = pScnHdr->s_nreloc; nCmds > 0; nCmds--)	{	/* read relocation command */	relocCmd = *pRelCmds++; 	/* calculate actual address in memory that needs relocation  */ 	if (pScnHdr->s_flags & STYP_TEXT)	    {	    if (!(pScnHdr->s_flags & STYP_LIT))	        {		pAdrs = (void *) ((long) pSeg->addrText + relocCmd.r_vaddr -		pScnHdr->s_vaddr + sprFixTextOff[section]); 		}	    else	        {		/*		 * The lit/rdata section is located after the text section.		 * We take care of this by adding the "real" text size to the		 * text address, just like the AM29K. A better solution would		 * be to add .lit fields in the SEG_INFO structure.		 */		pAdrs = (void *) ((long) pSeg->addrText + sprFixTextOff[section]					+ relocCmd.r_vaddr - pScnHdr->s_vaddr);	        }	    }	else	    pAdrs = (void *) ((long) pSeg->addrData +		(relocCmd.r_vaddr - pScnHdr->s_vaddr));  	/* now relocate according to type */ 	switch (relocCmd.r_type)	    {	    case R_RELBYTE:	/* relocate a byte */		value = *(UINT8 *)pAdrs;		/*		 * add address of symbol to the relocation value,		 * subtracting the symbol's value relative to the section		 */		value += (UINT32)pExternals[relocCmd.r_symndx];		pSym = pExtSyms + relocCmd.r_symndx;		if (!COFF_COMM(pSym))		    value -= pSym->n_value;		/* check for overflow */		if ((value & ~0xFF) != 0)		    {		    printErr (outOfRangeErrMsg);		    status = ERROR;		    break;		    }		*(UINT8 *)pAdrs = value;		break;  	    case R_RELWORD:	/* relocate a 16 bit word */		value = *(UINT16 *)pAdrs;		/*		 * add address of symbol to the relocation value,		 * subtracting the symbol's value relative to the section		 */		value += (UINT32)pExternals[relocCmd.r_symndx];		pSym = pExtSyms + relocCmd.r_symndx;		if (!COFF_COMM(pSym))		    value -= pSym->n_value;		/* check for overflow */		if ((value & ~0xFFFF) != 0)		    {		    printErr (outOfRangeErrMsg);		    status = ERROR;		    break;		    }		*(UINT16 *)pAdrs = value;		break;	    case R_RELARMLONG:	/* relocate a long */		{		char symName[MAX_SYS_SYM_LEN + 1];  /* buffer for sym name */		int symVal0, symVal1;		SYM_TYPE symType;		value = *(UINT32 *)pAdrs;		/*		 * add address of symbol to the relocation value,		 * subtracting the symbol's value relative to the section		 */		symVal0

⌨️ 快捷键说明

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