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

📄 loadelflib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
	    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 == MIPS)/********************************************************************************* 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.**/LOCAL 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);    ioctl(fd, FIOSEEK, posRelocEntry);    fioRead(fd, (char *) pReloc, nbytes);    return (posRelocEntry + nbytes);    }/********************************************************************************* relSegmentRela - perform relocation commands for MIPS RELA segments** This routine reads a relocation command segments and performs all the* relocations specified therein.  The relocation commands reside in the* sections with section type SHT_RELA.  RELA segments are assumed to contain* SDE style relocations** RETURNS: OK or ERROR** NOMANUAL*/LOCAL STATUS relMipsSegmentRela    (    int          fd,            /* file descriptor */    Elf32_Shdr * pSh,           /* relocation section header */    SCN_ADRS   * pScnAddr,      /* section address once loaded */    Elf32_Sym  * pSymsArray,    /* elf symbols */    int          posRelocEntry, /* relocation information */    SYM_INFO_TBL symInfoTbl     /* array of absolute symbol values and types */    )    {    int iy;    int nRel;    UINT32 insn;    void * relBaseAddr;    UINT32 relVal;    void * relAddr;    Elf32_Rela	relocCmd;	/* relocation structure */    Elf32_Sym	* pst;		/* symbol table entry */    if (pSh->sh_entsize != sizeof (Elf32_Rela))        {        errnoSet (S_loadElfLib_RELA_SECTION);        return (ERROR);        }    nRel = pSh->sh_size / pSh->sh_entsize;    relBaseAddr = (void *) *pScnAddr;    DBG(("\nrelBaseAddr = 0x%08x\n", relBaseAddr));    for (iy = 0; iy < nRel; iy++)	{	posRelocEntry = elfRelocRelaEntryRd (fd, posRelocEntry, &relocCmd);	if (ELF32_R_TYPE (relocCmd.r_info) & 0x80)	    /* old SDE-ELF section-relative relocation */	    relVal = (UINT32) symInfoTbl [ELF32_R_SYM (relocCmd.r_info)].pAddr;	else	    {	    /* standard ELF reloc */	    pst     = pSymsArray + ELF32_R_SYM (relocCmd.r_info);	    if (pst->st_info == ELF32_ST_INFO(STB_LOCAL, STT_SECTION))		/* section-relative relocation */		relVal  = (UINT32) 			symInfoTbl [ELF32_R_SYM (relocCmd.r_info)].pAddr; 	    else		/* symbol-relative relocation */		relVal = pst->st_value;	    }	relVal += relocCmd.r_addend;	relAddr = (void*) ((UINT32) relBaseAddr + relocCmd.r_offset);	switch (ELF32_R_TYPE(relocCmd.r_info) & 0x7f)	    {	    case R_SDE_8:		DBG (("R_SDE_8 relAddr=0x%x(0x%x) reloc=0x%x\n",			relAddr, *(unsigned char *)relAddr, relVal));		*(UINT8 *) relAddr = relVal;		break;	    case R_SDE_16:		DBG (("R_SDE_16 relAddr=0x%x(0x%x) reloc=0x%x\n",			relAddr, *(unsigned short *)relAddr, relVal));		*(USHORT *) relAddr = relVal;		break;			    case R_SDE_32:		DBG (("R_SDE_32 relAddr=0x%x(0x%x) reloc=0x%x\n",			relAddr, *(unsigned int *)relAddr, relVal));	     	*(UINT32 *) relAddr = relVal;		break;	    case R_SDE_ILALO:		/* "lw $m, addr" low part ref */		DBG (("R_SDE_ILALO\n"));		insn = *(UINT32 *) relAddr;			insn = (insn & ~0xffff) | (relVal & 0xffff);		*(UINT32 *) relAddr = insn;		break;	    case R_SDE_ILA:		/* "lw $m, addr" low and high combined */		DBG (("R_SDE_ILA\n"));		insn = *(UINT32 *) ((UINT32)relAddr + 4);		insn = (insn & ~0xffff) | (relVal & 0xffff);		*(UINT32 *) ((UINT32) relAddr + 4) = insn;		/* FALL THROUGH */	    case R_SDE_ILAHI:		/* "lw $m, addr" high part reference		 * (adjusting for low-half sign extension) */		DBG (("R_SDE_ILAHI\n"));		relVal += ((relVal & 0x8000) << 1); /* yowza */		insn = *(UINT32 *) relAddr;		insn = (insn & ~0xffff) | ((relVal >> 16) & 0xffff);		*(UINT32 *)relAddr = insn;		break;	    case R_SDE_IJMP:		DBG (("R_SDE_IJMP\n"));		/* 26-bit absolute jump (top 4 bits of pc stay the same) */		if ((relVal >> 28) != (((UINT32) relAddr + 4) >> 28))		    {		    errnoSet (S_loadElfLib_JMPADDR_ERROR);		    return (ERROR);		    }		insn = *(UINT32 *) relAddr;		insn = (insn & ~0x03ffffff) | ((relVal>>2) & 0x03ffffff);		*(UINT32 *) relAddr = insn;		break;	    case R_SDE_IBRA:		/* 16 bit pc relative branch */		/* assembler includes the -4 in the relocation addend */		DBG (("R_SDE_IBRA\n"));		relVal -= (UINT32) relAddr;		insn = *(UINT32 *) relAddr;		insn = (insn & ~0xffff) | ((relVal >> 2) & 0xffff);		*(UINT32 *) relAddr = insn;		break;	    case R_SDE_ILITERAL:		/* "li.d $fn,1.234" reference */	    case R_SDE_IGPREL:		errnoSet (S_loadElfLib_GPREL_REFERENCE);		printErr ("loadLib error: can't relocate, ");		printErr ("recompile module with -G 0 flags.\n");		return (ERROR);	      default:		errnoSet (S_loadElfLib_UNRECOGNIZED_RELOCENTRY);		printErr ("Unrecognized relocation type %d\n",			  ELF32_R_TYPE (relocCmd.r_info) & 0x7f);		return (ERROR);		}	}    return (OK);    }		/**************************************************************************** relMipsSegmentRel - perform relocation commands for MIPS REL segments** This routine reads a relocation command segments and performs all the * relocations specified therein.  The relocation commands reside in the * sections with section type SHT_REL.  REL segments are assumed to contain* MIPS-ABI style relocations** RETURNS: OK or ERROR** NOMANUAL*/LOCAL STATUS relMipsSegmentRel    (    int		 fd,		/* file descriptor */    Elf32_Shdr * pSh,		/* relocation section header */    SCN_ADRS   * pScnAddr,	/* section address once loaded */    Elf32_Sym  * pSymsArray,	/* elf symbols */    int  	 posRelocEntry,	/* relocation information */    SYM_INFO_TBL symInfoTbl	/* array of absolute symbol values and types */    )    {    int		nRel;		/* number of relocation entries  */    UINT32	insn;		/* instruction at relocation address */    void *	relBaseAddr;	/* relocation base address */    UINT32	relVal;		/* relocation value */    void *	relAddr;	/* relocation address */    Elf32_Sym	* pst;		/* symbol table entry */    UINT32	hinsn=0;		    Elf32_Sym	*refhi_pst=NULL;	    UINT32	refhi_insn=0;	    void *	refhi_addr=0;    BOOL	refhi_relocated = FALSE;    Elf32_Rel	relocCmd;	/* relocation structure */    unsigned int x;    int iy;			/* index */    if (pSh->sh_entsize != sizeof (Elf32_Rel))	{        errnoSet (S_loadElfLib_REL_SECTION);	return (ERROR);	}    nRel = pSh->sh_size / pSh->sh_entsize;    relBaseAddr = (void *) *pScnAddr;    DBG(("\nrelBaseAddr = 0x%08x\n", relBaseAddr));    for (iy = 0; iy < nRel; iy++)	{	/* read relocation command */	posRelocEntry = elfRelocRelEntryRd (fd, posRelocEntry, &relocCmd);	relAddr = (void *)((UINT32)relBaseAddr + relocCmd.r_offset);	pst     = pSymsArray + ELF32_R_SYM (relocCmd.r_info);	relVal  = (UINT32) symInfoTbl [ELF32_R_SYM (relocCmd.r_info)].pAddr;	/* Part of the relocation is included in the instruction */	if (ELF32_R_TYPE(relocCmd.r_info) == R_MIPS_16)	    {	    insn = 0;	    insn = *((UINT16 *)relAddr);	    }	else	    insn = *((UINT32 *)relAddr);  	DBG(("%08x: %08x %08x ", relAddr, insn, relVal));	switch (ELF32_R_TYPE(relocCmd.r_info))	    {	    case R_MIPS_NONE:		DBG(("R_MIPS_NONE"));	    	break;	    case R_MIPS_16:		DBG (("R_MIPS_16"));	    	insn = insn + relVal;	    	if (insn & ~0xffff)		    {		    errnoSet (S_loadElfLib_RELOC);		    return (ERROR);		    }	    	break;	    case R_MIPS_32:		DBG(("R_MIPS_32"));	    	insn = insn + relVal;	    	break;	    	    case R_MIPS_26:		DBG(("R_MIPS_26"));		/* 26/28-bit absolute jump (top 4 bits of $pc stay the same) */	    	if (pst)		    /* external relocation (symbol relative) sign extend */		    x = (((int)insn & 0x03ffffff) << 6) >> 4;	    	else		    /* local relocation (section relative) */		    x = ((insn & 0x03ffffff) << 2) 			| ((UINT32)relAddr & 0xf0000000);	    	    	x += relVal;	    	insn = (insn & ~0x03ffffff) | ((x >> 2) & 0x03ffffff);	    	break;	    case R_MIPS_HI16:		DBG(("R_MIPS_HI16\n"));

⌨️ 快捷键说明

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