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

📄 loadelflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    SYM_INFO_TBL symInfoTbl	/* array of absolute symbol values and types */    )    {    UINT32	 value;		/* relocation value */    value = pRelocCmd->r_addend -	    (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr;    *((UINT16 *)pAdrs) = (UINT16) HA_VALUE (value);    return (OK);    }#ifdef INCLUDE_SDA/********************************************************************************* elfPpcSdaRel16Reloc - perform the R_PPC_SDAREL relocation* * This routine handles the R_PPC_SDAREL relocation (half16, S + A - SDA_BASE).** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory or offset too large for relocation.*/LOCAL STATUS elfPpcSdaRel16Reloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl,	/* array of absolute symbol values and types */    SEG_INFO *	 pSeg		/* section addresses and sizes */    )    {    UINT32	 value;		/* relocation value */    if ((symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA) 					!= SYM_SDA)	{        printErr ("Referenced symbol does not belong to SDA.\n");	return (ERROR);	}    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend -	    (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);    /*     * Do some checking: R_PPC_SDAREL relocation must fit in     * 16 bits.     */    if (!CHECK_LOW16 (value))	{        printErr ("Relocation value does not fit in 16 bits.\n");	return (ERROR);	}    /* handle unalignment */    *((UINT16 *)pAdrs) = (UINT16) value;    return (OK);    }/********************************************************************************* elfPpcEmbSda21Reloc - perform the R_PPC_EMB_SDA21 relocation* * This routine handles the R_PPC_EMB_SDA21 relocation. The most significant 11* bits of the address pointed to by the relocation entry are untouched (opcode* and rS/rD field). The next most significant 5 bits (rA field) will hold the* value 13 (SDA symbol) or 2 (SDA2 symbol). The least significant 16 bits are* set to the two's complement of the following computation:*     symbol address + r_addend value - SDA_BASE (or SDA2_BASE) value.** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory.*/LOCAL STATUS elfPpcEmbSda21Reloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl,	/* array of absolute symbol values and types */    SEG_INFO *	 pSeg		/* section addresses and sizes */    )    {    UINT32	 value;		/* relocation value */    UINT32	 instr;		/* previous instruction in memory */    BOOL	 symbolIsInSda;	/* TRUE if symbol belongs to the SDA area */    BOOL	 sizeFit;	/* TRUE if computed value is 16 bit long */    /*     * Only symbols (or reference to) belonging to a .sdata, .sbss, .sdata2     * or .sbss2 section are supported.     */    switch (symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA_MASK)	{	case (SYM_SDA):	    symbolIsInSda = TRUE;	    break;	case (SYM_SDA2):	    symbolIsInSda = FALSE;	    break;	default:	    printErr ("Referenced symbol does not belong to SDA/SDA2.\n");	    return (ERROR);	    break;	}    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend;    instr = *((UINT32 *)pAdrs);    /*     * We applied here the same relocation process as the GNU does since     * the EABI document is totally phony on this one...     */    if (symbolIsInSda)	{	value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);	sizeFit = CHECK_LOW16_STRICT (value);	value = (instr & ~RA_MSK) | GPR13_MSK | ((~value + 1) & 0xffff);	}    else	{	value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);	sizeFit = CHECK_LOW16_STRICT (value);	value = (instr & ~RA_MSK) | GPR2_MSK | ((~value + 1) & 0xffff);	}    /*     * Do some checking: R_PPC_EMB_SDA21 relocation must fit in     * 21 bits, thus the offset must fit in 16 bits.     */    if (!sizeFit)	{        printErr ("Relocation offset does not fit in 16 bits.\n");	return (ERROR);	}    *((UINT32 *)pAdrs) = value;    return (OK);    }/********************************************************************************* elfPpcEmbSda2RelReloc - perform the R_PPC_EMB_SDA2REL relocation* * This routine handles the R_PPC_EMB_SDA2REL relocation (uhalf16,* S + A - SDA2_BASE).** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory.*/LOCAL STATUS elfPpcEmbSda2RelReloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl,	/* array of absolute symbol values and types */    SEG_INFO *	 pSeg		/* section addresses and sizes */    )    {    UINT32	 value;		/* relocation value */    if ((symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA2)				!= SYM_SDA2)	{        printErr ("Referenced symbol does not belong to SDA2.\n");	return (ERROR);	}    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend -	    (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);    *((UINT16 *)pAdrs) = (UINT16) value;    return (OK);    }/********************************************************************************* elfPpcEmbRelSdaReloc - perform the R_PPC_EMB_RELSDA relocation* * This routine handles the R_PPC_EMB_RELSDA relocation.** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory.*/LOCAL STATUS elfPpcEmbRelSdaReloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl,	/* array of absolute symbol values and types */    SEG_INFO *	 pSeg		/* section addresses and sizes */    )    {    UINT32	 value;		/* relocation value */    BOOL	 symbolIsInSda;	/* TRUE if symbol belongs to the SDA area */    /*     * Only symbols (or reference to) belonging to a .sdata, .sbss, .sdata2     * or .sbss2 section are supported.     */    switch (symInfoTbl[ELF32_R_SYM (pRelocCmd->r_info)].type & SYM_SDA_MASK)	{	case (SYM_SDA):	    symbolIsInSda = TRUE;	    break;	case (SYM_SDA2):	    symbolIsInSda = FALSE;	    break;	default:	    printErr ("Referenced symbol does not belong to SDA/SDA2.\n");	    return (ERROR);	    break;	}    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend;    if (symbolIsInSda)	value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sdaBaseAddr);    else	value -= (UINT32)(((SDA_INFO *)pSeg->pAdnlInfo)->sda2BaseAddr);    /*     * Do some checking: R_PPC_EMB_RELSDA relocation must fit in     * 16 bits.     */    if (!CHECK_LOW16 (value))	{        printErr ("Relocation value does not fit in 16 bits.\n");	return (ERROR);	}    *((UINT16 *)pAdrs) = (UINT16) value;    return (OK);    }#endif 	/* INCLUDE_SDA */ #endif 	/* CPU_FAMILY == PPC */#if	(CPU_FAMILY == SIMSPARCSOLARIS)/********************************************************************************* elfSparcSegReloc - perform relocation for the PowerPC family** This routine reads the specified relocation command segment and performs* all the relocations specified therein. Only relocation command from sections* with section type SHT_RELA are considered here.** Absolute symbol addresses are looked up in the 'externals' table.** RETURNS: OK or ERROR*/STATUS elfSparcSegReloc    (    int		 fd,		/* file to read in */    MODULE_ID	 moduleId,	/* module id */    int		 loadFlag,	/* not used */    int		 posCurRelocCmd,/* position of current relocation command */    Elf32_Shdr * pScnHdrTbl,	/* pointer to section header table */    Elf32_Shdr * pRelHdr,	/* pointer to relocation section header */    SCN_ADRS *	 pScnAddr,	/* section address once loaded */    SYM_INFO_TBL symInfoTbl,	/* array of absolute symbol values and types */    Elf32_Sym *	 pSymsArray,	/* pointer to symbols array */    SYMTAB_ID 	 symTbl,	/* not used */    SEG_INFO *	 pSeg		/* section addresses and sizes */    )    {    Elf32_Shdr * pScnHdr;	/* section to which the relocations apply */    Elf32_Rela   relocCmd;	/* relocation structure */    UINT32	 relocNum;	/* number of reloc entries in section */    UINT32	 relocIdx;	/* index of the reloc entry being processed */    void *	 pAdrs;		/* relocation address */    Elf32_Sym *	 pSym;		/* pointer to an external symbol */    STATUS	 status = OK;	/* whether or not the relocation was ok */    pScnHdr = pScnHdrTbl + pRelHdr->sh_info;    /* Some sanity checking */    if (pRelHdr->sh_type != SHT_RELA)	{	errnoSet (S_loadElfLib_RELA_SECTION);	printErr ("Relocation sections of type %d are not supported.\n",		     pRelHdr->sh_type);	return (OK);	}    if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))	{	printErr ("Wrong relocation entry size.\n");	errnoSet (S_loadElfLib_RELA_SECTION);	return (ERROR);	}    /* Relocation loop */    relocNum = pRelHdr->sh_size / pRelHdr->sh_entsize;    for (relocIdx = 0; relocIdx < relocNum; relocIdx++)	{	/* read relocation command */	if ((posCurRelocCmd = 	     elfRelocRelaEntryRd (fd, posCurRelocCmd, &relocCmd)) == ERROR)	    {	    errnoSet (S_loadElfLib_READ_SECTIONS);	    return (ERROR);	    }	/*	 * Calculate actual remote address that needs relocation, and	 * perform external or section relative relocation.	 */	pAdrs = (void *)((Elf32_Addr)*pScnAddr + relocCmd.r_offset);	pSym = pSymsArray + ELF32_R_SYM (relocCmd.r_info);	/*	 * System V ABI defines the following notations:	 *	 * A - the addend used to compute the value of the relocatable field.	 * S - the value (address) of the symbol whose index resides in the	 *     relocation entry. Note that this function uses the value stored	 *     in the external symbol value array instead of the symbol's	 *     st_value field.	 * P - the place (section offset or address) of the storage unit being	 *     relocated (computed using r_offset) prior to the relocation.	 */        switch (ELF32_R_TYPE (relocCmd.r_info))            {	    case (R_SPARC_8):		if (elfSparc8Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_16):		if (elfSparc16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_32):		if (elfSparc32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_DISP8):		if (elfSparcDisp8Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_DISP16):		if (elfSparcDisp16Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_DISP32):		if (elfSparcDisp32Reloc(pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_WDISP30):		if (elfSparcWDisp30Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_WDISP22):		if (elfSparcWDisp22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_HI22):		if (elfSparcHi22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_22):		if (elfSparc22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_13):		if (elfSparc13Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_LO10):		if (elfSparcLo10Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_PC10):		if (elfSparcPc10Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_PC22):		if (elfSparcPc22Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_SPARC_UA32):	    case (R_SPARC_GLOB_DAT):		if (elfSparcUa32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;

⌨️ 快捷键说明

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