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

📄 loadelflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }     /********************************************************************************* elfRelocRelEntryRd - read in ELF relocation entry for REL relocation* * This routine fills a relocation structure with information from the object* module in memory. ** RETURNS : the address of the next relocation entry or ERROR if entry not read.*/int elfRelocRelEntryRd    (    int          fd,            /* file to read in */    int          posRelocEntry, /* position of reloc. command in object file */    Elf32_Rel *  pReloc		/* ptr on relocation structure to fill */    )    {    int nbytes;         /* number of bytes to copy */    nbytes = sizeof (Elf32_Rel);    if ((ioctl (fd, FIOSEEK, posRelocEntry)) == ERROR)        return ERROR;     if ((fioRead (fd, (char *) pReloc, nbytes)) == ERROR)        return ERROR;    return (posRelocEntry + nbytes);    }#if     (CPU_FAMILY == PPC)/********************************************************************************* elfPpcSegReloc - 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.** This function handles the following types of relocation commands* for the PowerPC processor:** System V ABI:*	R_PPC_NONE		: none*	R_PPC_ADDR32		: word32,	S + A*	R_PPC_ADDR24		: low24,	(S + A) >> 2*	R_PPC_ADDR16		: half16,	S + A*	R_PPC_ADDR16_LO		: half16,	#lo(S + A)*	R_PPC_ADDR16_HI		: half16,	#hi(S + A)*	R_PPC_ADDR16_HA		: half16,	#ha(S + A)*	R_PPC_ADDR14		: low14,	(S + A) >> 2*	R_PPC_ADDR14_BRTAKEN	: low14,	(S + A) >> 2*	R_PPC_ADDR14_BRNTAKEN	: low14,	(S + A) >> 2*	R_PPC_REL24		: low24,	(S + A - P) >> 2*	R_PPC_REL14		: low14,	(S + A - P) >> 2*	R_PPC_REL14_BRTAKEN	: low14,	(S + A - P) >> 2*	R_PPC_REL14_BRNTAKEN	: low14,	(S + A - P) >> 2*	R_PPC_UADDR32		: word32,	S + A*	R_PPC_UADDR16		: half16,	S + A*	R_PPC_REL32		: word32,	S + A - P*	R_PPC_SDAREL		: half16,	S + A - SDA_BASE** PowerPC EABI:*	R_PPC_EMB_NADDR32	: uword32,	A - S*	R_PPC_EMB_NADDR16	: uhalf16,	A - S*	R_PPC_EMB_NADDR16_LO	: uhalf16,	#lo(A - S)*	R_PPC_EMB_NADDR16_HI	: uhalf16,	#hi(A - S)*	R_PPC_EMB_NADDR16_HA	: uhalf16,	#ha(A - S)*	R_PPC_EMB_MRKREF	: none*	R_PPC_EMB_SDA21		: ulow21,	complex*	R_PPC_EMB_SDA2REL	: uhalf16,	S + A - SDA2_BASE*	R_PPC_EMB_RELSDA	: uhalf16,	complex** RETURNS: OK or ERROR*/LOCAL STATUS elfPpcSegReloc    (    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,	/* not used */    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_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 */    /* Some sanity checking */    if (pRelHdr->sh_type != SHT_RELA)	{        errnoSet (S_loadElfLib_RELA_SECTION);	return (OK);	}    if (pRelHdr->sh_entsize != sizeof (Elf32_Rela))	{        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_PPC_NONE):				/* none */		break;	    case (R_PPC_ADDR32):			/* word32, S + A */		if (elfPpcAddr32Reloc (pAdrs, &relocCmd, symInfoTbl,				       moduleId) != OK)		    status = ERROR;		break;	    case (R_PPC_ADDR24):			/* low24, (S+A) >> 2 */		if (elfPpcAddr24Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_ADDR16):			/* half16, S + A */		if (elfPpcAddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_ADDR16_LO):			/* half16, #lo(S + A) */		if (elfPpcAddr16LoReloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_ADDR16_HI):			/* half16, #hi(S + A) */		if (elfPpcAddr16HiReloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_ADDR16_HA):			/* half16, #ha(S + A) */		if (elfPpcAddr16HaReloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_ADDR14):	    case (R_PPC_ADDR14_BRTAKEN):	    case (R_PPC_ADDR14_BRNTAKEN):		/* low14, (S+A) >> 2 */		if (elfPpcAddr14Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_REL24):				/* low24, (S+A-P) >> 2*/		if (elfPpcRel24Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_REL14):	    case (R_PPC_REL14_BRTAKEN):	    case (R_PPC_REL14_BRNTAKEN):		/* low14, (S+A-P) >> 2*/		if (elfPpcRel14Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_UADDR32):			/* word32, S + A */		if (elfPpcUaddr32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_UADDR16):			/* half16, S + A */		if (elfPpcUaddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_REL32):				/* word32, S + A - P */		if (elfPpcRel32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_EMB_NADDR32):			/* uword32, A - S */		if (elfPpcEmbNaddr32Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_EMB_NADDR16):			/* uhalf16, A - S */		if (elfPpcEmbNaddr16Reloc (pAdrs, &relocCmd, symInfoTbl) != OK)		    status = ERROR;		break;	    case (R_PPC_EMB_NADDR16_LO):		/* uhalf16, #lo(A - S)*/		if (elfPpcEmbNaddr16LoReloc (pAdrs, &relocCmd, symInfoTbl) 						!= OK)		    status = ERROR;		break;	    case (R_PPC_EMB_NADDR16_HI):		/* uhalf16, #hi(A - S)*/		if (elfPpcEmbNaddr16HiReloc (pAdrs, &relocCmd, symInfoTbl) 						!= OK)		    status = ERROR;		break;	    case (R_PPC_EMB_NADDR16_HA):		/* uhalf16, #ha(A - S)*/		if (elfPpcEmbNaddr16HaReloc (pAdrs, &relocCmd, symInfoTbl) 						!= OK)		    status = ERROR;		break;	    case (R_PPC_EMB_MRKREF):			/* none */		break;#ifdef INCLUDE_SDA	    case (R_PPC_SDAREL):		/* half16, S + A - SDA_BASE */		if (elfPpcSdaRel16Reloc (pAdrs, &relocCmd, symInfoTbl,					 pSeg) != OK)		    status = ERROR;		break;	    case (R_PPC_EMB_SDA21):			/* ulow21, complex ! */		if (elfPpcEmbSda21Reloc (pAdrs, &relocCmd, symInfoTbl,					 pSeg) != OK)		    status = ERROR;		break;	    case (R_PPC_EMB_SDA2REL):		/* uhalf16, S + A - SDA2_BASE */		if (elfPpcEmbSda2RelReloc (pAdrs, &relocCmd, symInfoTbl,					   pSeg) != OK)		    status = ERROR;		break;	    case (R_PPC_EMB_RELSDA):			/* uhalf16, complex ! */		if (elfPpcEmbRelSdaReloc (pAdrs, &relocCmd, symInfoTbl,					  pSeg) != OK)		    status = ERROR;		break;#endif /* INCLUDE_SDA */	    default:        	printErr ("Unsupported relocation type %d\n",			      ELF32_R_TYPE (relocCmd.r_info));        	status = ERROR;        	break;	    }	}    return (status);    }/********************************************************************************* elfPpcAddr32Reloc - perform the R_PPC_ADDR32 relocation* * This routine handles the R_PPC_ADDR32 relocation (word32, S + A).** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory.*/LOCAL STATUS elfPpcAddr32Reloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl,	/* array of absolute symbol values and types */    MODULE_ID	 moduleId	/* module id */    )    {    UINT32	 value;		/* relocation value */    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend;    *((UINT32 *)pAdrs) = value;    return (OK);    }/********************************************************************************* elfPpcAddr24Reloc - perform the R_PPC_ADDR24 relocation* * This routine handles the R_PPC_ADDR24 relocation (low24, S + A).** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory or offset too large for relocation.*/LOCAL STATUS elfPpcAddr24Reloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl	/* array of absolute symbol values and types */    )    {    UINT32	 value;		/* relocation value */    UINT32	 offset;	/* previous value in memory */    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend;    /*     * Do some checking: R_PPC_ADDR24 relocation must fit in     * 24 bits and lower 2 bits should always be null.     */    if (!CHECK_LOW24 (value))	{        printErr ("Relocation value does not fit in 24 bits.\n");	return (ERROR);	}    if (value & 0x3)        printErr ("Relocation value's lower 2 bits not zero.\n");    offset = *((UINT32 *)pAdrs);     LOW24_INSERT (offset, value);    *((UINT32 *)pAdrs) = offset;    return (OK);    }/********************************************************************************* elfPpcAddr16Reloc - perform the R_PPC_ADDR16 relocation* * This routine handles the R_PPC_ADDR16 relocation (half16, S + A).** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory or offset too large for relocation.*/LOCAL STATUS elfPpcAddr16Reloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl	/* array of absolute symbol values and types */    )    {    UINT32	 value;		/* relocation value */    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend;    /*     * Do some checking: R_PPC_ADDR16 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);    }/********************************************************************************* elfPpcAddr16LoReloc - perform the R_PPC_ADDR16_LO relocation* * This routine handles the R_PPC_ADDR16_LO relocation (half16, #lo(S + A)).** RETURNS : OK or ERROR if computed value can't be written down in target*	    memory.*/LOCAL STATUS elfPpcAddr16LoReloc    (    void *	 pAdrs,		/* relocation address */    Elf32_Rela * pRelocCmd,	/* points to a relocation structure */    SYM_INFO_TBL symInfoTbl	/* array of absolute symbol values and types */    )    {    UINT32	 value;		/* relocation value */    value = (UINT32)symInfoTbl [ELF32_R_SYM (pRelocCmd->r_info)].pAddr +	    pRelocCmd->r_addend;    *((UINT16 *)pAdrs) = (UINT16) LO_VALUE (value);    return (OK);    }

⌨️ 快捷键说明

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