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

📄 loadcofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	     */	    if ((scnFlags & STYP_TEXT) &&		((unsigned char)symbol->n_sclass == C_THUMBEXTFUNC ||		 (unsigned char)symbol->n_sclass == C_THUMBSTATFUNC))		{		bias = (char *)((UINT32)bias | 1);		}#endif /* CPU_FAMILY == ARM */            /* Add symbol address to externals table.             * For COFF, we add all symbol addresses into the externals             * table, not only those symbols saved in the vxWorks symbol             * table.             */            (*externals) [symNum] = symbol->U_SYM_VALUE + bias;#ifdef DEBUG	DPRINTF("new symbol=%#x \n", (unsigned) (symbol->U_SYM_VALUE + bias));#endif  /* DEBUG */	    }	else	    {	    /* Undefined external symbol or "common" symbol             *	     *   A common symbol type is denoted by undefined external             *   with its value set to non-zero.	     */	    /* if symbol is a common, then allocate space and add to	     * symbol table as BSS	     */	    /* common symbol - create new symbol */            if (COFF_COMM(symbol))		{		if (symFlag == LOAD_NO_SYMBOLS)		    ;		else		    {		    /* 		     *  common symbol - create new symbol 		     *		     *  Common symbols are now tacked to the end of the bss		     *  section.  This is done to accomodate systems that have		     *  multiple boards sharing memory with common symbols		     *  over the system bus.  		     *  This portion of code reads the symbol value		     *  (which contains the symbol size) and places the symbol		     *  in the bss section.  The function dataAlign uses		     *  the next possible address for a common symbol to determine		     *  the proper alignment.		     */		    		    adrs = pNextCommon;		    bssAlignment = dataAlign (symbol->U_SYM_VALUE, (ULONG) adrs);		    adrs += bssAlignment;		    pNextCommon += (symbol->U_SYM_VALUE + bssAlignment);		    		    if (symSAdd (symTbl, name, adrs, (VX_BSS | VX_EXT), group) != OK)		    printErr (cantAddSymErrMsg, name, errnoGet());		    		    }		}	    /* look up undefined external symbol in symbol table */	    else if (symFindByNameAndType (symTbl, name, &adrs, &vxSymType,					   VX_EXT, VX_EXT) != OK)                {                /* symbol not found in symbol table */                printErr ("undefined symbol: %s\n", name);                adrs = NULL;                status = ERROR;                }	    /* add symbol address to externals table             */	    (*externals) [symNum] = adrs;	    }	}    return (status);    }#if (CPU_FAMILY == AM29XXX)/********************************************************************************* CoffRelSegmentAm29K - perform relocation for the Am29K 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 Am29K family of processor:** 	- R_IREL	instruction relative (jmp/call)* 	- R_IABS	instruction absolute (jmp/call)* 	- R_ILOHALF	instruction low half  (const)* 	- R_IHIHALF	instruction high half (consth) part 1* 	- R_IHCONST	instruction high half (consth) part 2*			constant offset of R_IHIHALF relocation* 	- R_BYTE	relocatable byte value* 	- R_HWORD	relocatable halfword value* 	- R_WORD	relocatable word value** 	- R_IGLBLRC	instruction global register RC* 	- R_IGLBLRA	instruction global register RA* 	- R_IGLBLRB	instruction global register RB**		* RETURNS: OK or ERROR* * INTERNAL* Note that we don't support multi-sections management for the Am29k * architecture.*/LOCAL STATUS coffRelSegmentAm29K    (    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 */    )    {    long *	pAdrs;		/* relocation address */    int		nCmds;		/* # reloc commands for seg */    RELOC 	relocCmd;	/* relocation structure */    STATUS 	status = OK;    UINT32	unsignedValue;	/* const and consth values */    UINT32	symVal;		/* value associated with symbol */    SYMENT *	pSym;		/* pointer to an external symbol */    SCNHDR *	pScnHdr;	/* section header for relocation */    INT32	signedValue;	/* IREL case temporary */    /*     * The 29k loader needs to keep track of some values between     * the IHICONST and ICONST relocation processing. We use static     * variables here which makes the loader not re-entrant.     * This should be fixed later.     */    static BOOL consthActive;	/* CONSTH processing in progress flag */    static UINT32 consthValue;	/* CONSTH processing in progress value */    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 = (long *) ((long) pSeg->addrText + relocCmd.r_vaddr);	    else	    /* 	     * The lit section is located after the text section, we take 	     * care of this by adding the "real" text size to the text address.	     * A better solution would be to add .lit fields in the 	     * SEG_INFO structure.	     */		pAdrs = (long *) ((long) pSeg->addrText + textSize 				   + relocCmd.r_vaddr - pScnHdr->s_vaddr);	    }	else 	    {	    pAdrs = (long *) ((long) pSeg->addrData + 		(relocCmd.r_vaddr - pScnHdr->s_vaddr));	    }#ifdef DEBUG        DPRINTF("r_vaddr=%02x pAdrs=%08x ",                 relocCmd.r_vaddr, (int) pAdrs);#endif  /* DEBUG */        switch (relocCmd.r_type)            {        case R_IABS:	    /* Nothing to do in this case */#ifdef DEBUG            DPRINTF("IABS ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    break;        case R_IREL:	    /* 	     * Relative jmp/call: in this case we must calculate the address	     * of the target using the symbol value and the offset 	     * found in the instruction.	     */#ifdef DEBUG            DPRINTF("IREL ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    signedValue = EXTRACT_HWORD(*pAdrs) << 2;	    signedValue = SIGN_EXTEND_HWORD(signedValue);	    signedValue += (unsigned) pExternals [relocCmd.r_symndx];	    /*	     * Now if its an absolute jmp/call set the absolute bit (A) of	     * the instruction.	     * See gnu compiler sources src/bfd/coff-a29k.c	     */	    if ((signedValue &~ 0x3ffff) == 0)		{		*pAdrs = *pAdrs | (1 << 24);		}	    else		{		signedValue -= relocCmd.r_vaddr;		if (signedValue > 0x1ffff || signedValue < -0x20000)		    printErr (outOfRangeErrMsg);		}	    	    signedValue = signedValue >> 2;	    *pAdrs = INSERT_HWORD(*pAdrs, signedValue);	    break;	case R_ILOHALF:	    /*	     * This is a CONST instruction, put the 16 lower bits of the	     * symbol value at the right place in the instruction.	     *	     * CONST instruction format:  |OP|const bit 15-8|RA|const bit 7-0|	     */#ifdef DEBUG            DPRINTF("ILOHALF ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */    	    pSym = pExtSyms + relocCmd.r_symndx;#ifdef DEBUG            DPRINTF("pSym=%08x ", (unsigned) pSym);#endif  /* DEBUG */	    unsignedValue = EXTRACT_HWORD(*(UINT32 *)pAdrs);	    unsignedValue += (unsigned) pExternals [relocCmd.r_symndx];	    *(UINT32 *)pAdrs = INSERT_HWORD(*(UINT32 *)pAdrs, unsignedValue);	    break;	case R_IHIHALF:	    /*	     * This is the first stage of a CONSTH instruction relocation, 	     * just keep track of the fact and keep the value.	     * We don't modify the instruction until R_IHCONST.	     *	     * CONSTH instruction format:  |OP|const bit 15-8|RA|const bit 7-0|	     */#ifdef DEBUG            DPRINTF("IHIHALF ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    pSym = pExtSyms + relocCmd.r_symndx;#ifdef DEBUG            DPRINTF("pSym=%08x ", (unsigned) pSym);#endif  /* DEBUG */	    consthActive = TRUE;	    consthValue = (unsigned) pExternals [relocCmd.r_symndx];	    break;	case R_IHCONST:	    /*	     * This is the second stage of a CONSTH instruction relocation, 	     * put the 16 higher bits of the symbol value at the right place 	     * in the instruction.	     *	     * CONSTH instruction format:  |OP|const bit 15-8|RA|const bit 7-0|	     */#ifdef DEBUG            DPRINTF("IHCONST ");            DPRINTF("relocOffset=%08x ", relocCmd.r_symndx);#endif  /* DEBUG */	    if (!consthActive)		{		printErr (hiHalfErrMsg);		break;		}/*  * If the parameter to a CONSTH instruction is a relocatable type, two * relocation records are written.  The first has an r_type of R_IHIHALF * (33 octal) and a normal r_vaddr and r_symndx.  The second relocation * record has an r_type of R_IHCONST (34 octal), a normal r_vaddr (which * is redundant), and an r_symndx containing the 32-bit constant offset * to the relocation instead of the actual symbol table index.  This * second record is always written, even if the constant offset is zero. * The constant fields of the instruction are set to zero. */            unsignedValue = relocCmd.r_symndx;            unsignedValue += consthValue ;	    unsignedValue = unsignedValue >> 16;	    *(UINT32 *)pAdrs = INSERT_HWORD(*(UINT32 *)pAdrs, unsignedValue);	    consthActive = FALSE;	    break;	case R_BYTE:	    /* Relocatable byte, just set *pAdrs with byte value. */#ifdef DEBUG            DPRINTF("BYTE ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    pSym = pExtSyms + relocCmd.r_symndx;#ifdef DEBUG            DPRINTF("pSym=%08x *pAdrs %08x", (unsigned)pSym, *(char *)pAdrs);#endif  /* DEBUG */	    symVal = (UINT32) pExternals[relocCmd.r_symndx];    	    *(UINT8 *)pAdrs = *(UINT8*) pAdrs + symVal;	    break;			case R_HWORD:	    /* Relocatable half word, just set *pAdrs with half word value. */#ifdef DEBUG            DPRINTF("HWORD ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    pSym = pExtSyms + relocCmd.r_symndx;#ifdef DEBUG            DPRINTF("pSym=%08x *pAdrs %08x", (unsigned)pSym, *(short *)pAdrs);#endif  /* DEBUG */	    symVal = (UINT32) pExternals[relocCmd.r_symndx];    	    *(UINT16 *)pAdrs = *(UINT16*) pAdrs + symVal;	    break;	case R_WORD:	    /* Relocatable word, just add symbol to current address content. */#ifdef DEBUG            DPRINTF("WORD ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    pSym = pExtSyms + relocCmd.r_symndx;#ifdef DEBUG            DPRINTF("pSym=%08x *pAdrs %08x", (unsigned)pSym, (unsigned)*pAdrs);#endif  /* DEBUG */	    symVal = (UINT32) pExternals[relocCmd.r_symndx];    	    *(UINT32 *)pAdrs = *(UINT32*) pAdrs + symVal;	    break;	case R_IGLBLRA:	    /*	     * This is a global register A relocation, we have to set the	     * register A field of the current instruction to the value	     * associated with symbol.	     *	     * instruction format: |OP|RC|RA|RB|	     */#ifdef DEBUG            DPRINTF("IGLBLRA ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    symVal = (UINT32) pExternals[relocCmd.r_symndx];	    *(UINT32 *)pAdrs = (*(UINT32 *)pAdrs | 			        ((symVal & REG_MASK) << REG_A_OFFSET));	    break;	case R_IGLBLRB:	    /*	     * This is a global register B relocation, we have to set the	     * register B field of the current instruction to the value	     * associated with symbol.	     *	     * instruction format: |OP|RC|RA|RB|	     */#ifdef DEBUG            DPRINTF("IGLBLRB ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    symVal = (UINT32) pExternals[relocCmd.r_symndx];	    *(UINT32 *)pAdrs = (*(UINT32 *)pAdrs | 			        ((symVal & REG_MASK) << REG_B_OFFSET));	    break;	case R_IGLBLRC:	    /*	     * This is a global register C relocation, we have to set the	     * register C field of the current instruction to the value	     * associated with symbol.	     *	     * instruction format: |OP|RC|RA|RB|	     */#ifdef DEBUG            DPRINTF("IGLBLRC ");            DPRINTF("sym=%08x ", (unsigned) pExternals [relocCmd.r_symndx]);#endif  /* DEBUG */	    symVal = (UINT32) pExternals[relocCmd.r_symndx];	    *(UINT32 *)pAdrs = (*(UINT32 *)pAdrs | 			        ((symVal & REG_MASK) << REG_C_OFFSET));	    break;	default:            printErr("Unrecognized relocation type %d\n",                     relocCmd.r_type);            errnoSet (S_loadLib_UNRECOGNIZED_RELOCENTRY);            return (ERROR);            break;	    }#ifdef DEBUG            DPRINTF("\n");

⌨️ 快捷键说明

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