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

📄 loadpecofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                vxSymType = VX_DATA;		}            else if (scnFlags & STYP_BSS)                {                bias = (char *) scnAddr;                vxSymType = VX_BSS;		}            else if (scnFlags & STYP_DRECTVE)                {		/* Ignore this section */                continue;                }            else                {		/*		 * Lets not print error messages for debug-related symbols		 * that are not flagged as N_DEBUG...		 */		if (!strcmp (name, ".stab") || !strcmp (name, ".stabstr"))		    continue;                printErr (cantConvSymbolType, name, errnoGet());                continue;                }	    /*	     * Since, in the VxWorks simulator's image all the symbols' values	     * are offsets from zero a bias has to be introduced to get the	     * real (post-installation) addresses of these symbols in	     * Windows' memory space. The bias computation is however	     * different from the one for the regular object modules and must	     * overwrite whatever has been computed just above: the bias is	     * the base address of the simulator in Windows' memory space	     * plus the offset to the section which holds the symbol.	     *	     * Note: the section header's s_vaddr field holds this offset	     *       _not_ a real virtual address...	     */            if (fullyLinked)		bias = (char *)(pScnHdr->s_vaddr + imageBase);            /*  Determine if symbol should be put into symbol table */            if (((symFlag & LOAD_LOCAL_SYMBOLS) && !PECOFF_EXT(symbol))                || ((symFlag & LOAD_GLOBAL_SYMBOLS) && PECOFF_EXT(symbol)))                {                if (PECOFF_EXT(symbol))                    vxSymType |= VX_EXT;                /*  Add symbol to symbol table but cut out Local tags */                if (name[0] != '$')    		    if (symSAdd (symTbl, name, symbol->U_SYM_VALUE + bias,			     vxSymType, group) != OK)		        printErr (cantAddSymErrMsg, name, errnoGet());                }            /* Add symbol address to externals table.             * For PECOFF, 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;	    }	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 (PECOFF_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 checks for a matching                     *  common symbol. If a matching common symbol is not                     *  found the symbol value is read		     *  (which contains the symbol size) and the symbol is                     *  placed in the bss section.  The function dataAlign uses		     *  the next possible address for a common symbol to		     *  determine the proper alignment.		     */		                          if (loadPecoffCommonManage (name, symTbl, (void *) &adrs,                        &vxSymType, symFlag) != OK)	                {	                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;    }/********************************************************************************* pecoffRelSegmentI386 - perform relocation for the I386 family** This routine reads the specified relocation command segment and performs* all the relocation specified therein.* Absuolute symbol addresses are looked up in the 'externals' table.** This function handles the following types of relocation commands for the* I386 family of processor:* 	IMAGE_REL_I386_DIR32  - direct 32 bit relocation* 	IMAGE_REL_I386_REL32  - relative 32b bit relocation** RETURNS: OK or ERROR*/LOCAL STATUS pecoffRelSegmentI386    (    RELOC *	pRelCmds,	/* list of relocation commands */    SCNHDR *	pScnHdrArray, 	/* array of section headers */    char **	pExternals,	/* array of absolute symbols values */    SYMENT *	pExtSyms,	/* pointer to object file symbols */     SEG_INFO * 	pSeg,		/* section addresses and sizes */    int         section         /* section number -1 for relocation */    )    {    long *      pAdrs = NULL;   /* relocation address */    int         nCmds;          /* # reloc commands for seg */    RELOC       relocCmd;       /* relocation structure */    SCNHDR *    pScnHdr;        /* section header for relocation */    STATUS      status = OK;    pScnHdr = pScnHdrArray + section;    for (nCmds = pScnHdr->s_nreloc; nCmds > 0; nCmds--)        {        /* read relocation command */        relocCmd = *pRelCmds++;	/*         * Calculate actual address in memory that needs relocation.	 * XXX PAD - we now apply the fix for SPR 70767          */	if (pScnHdr->s_flags & STYP_TEXT)	    {	    if (!(pScnHdr->s_flags & STYP_LIT))		{		pAdrs = (long *)((long) pSeg->addrText + relocCmd.r_vaddr);		}	    else		{		printf ("STYP_LIT type sections are unsupported.\n");		return ERROR;		}	    }	else	    /*	     * The computation of the address of relocable data symbol              * should take into account the offset from the beginning of the             * file that the compiler toolchain may require to account for             * in some cases. The code was fixed to substract this offset             * for data symbol, SPR 73145. 	     */	    {	    pAdrs = (long *)((long) pSeg->addrData +		             (relocCmd.r_vaddr - pScnHdr->s_vaddr));	    }	/* do relocations */        switch (relocCmd.r_type)            {	    case IMAGE_REL_I386_DIR32:		/*		 * This relocation is preformed by adding the absolute address		 * of the symbol to the relocation value in the code.		 */		*pAdrs += (INT32) pExternals [relocCmd.r_symndx];  		break;	    case IMAGE_REL_I386_REL32:		/*		 * Call near, displacement relative to the next instruction.		 * First, find the next instruction addr, then subtract it from		 * the addr of the found symbol to obtain the relocation addr.		 */	                *pAdrs = (UINT32)pExternals[relocCmd.r_symndx] -		         ((UINT32)pAdrs + 4);                break;	    default:		printf("Unknown Relocation Error\n");		errnoSet (S_loadLib_UNRECOGNIZED_RELOCENTRY);		status = ERROR;		break;            }        }    return status;    }/********************************************************************************* pecoffHdrRead - read in PECOFF header and swap if necessary* * Note:  To maintain code portability, we can not just read sizeof(FILHDR) *	bytes.  Compilers pad structures differently,*	resulting in different structure sizes.*	So, we read the structure in an element at a time, using the size*	of each element.*/LOCAL STATUS pecoffHdrRead    (    int fd,    FILHDR *pHdr,    BOOL *pSwap    )    {    int status;    int i;    struct dosheader dhead;    *pSwap = 0;    ioctl(fd, FIOSEEK, 0);    if (fioRead (fd, (char *) &(pHdr->f_magic), sizeof (pHdr->f_magic))		!= sizeof (pHdr->f_magic))	{	errnoSet (S_loadLib_FILE_READ_ERROR);	return ERROR;	}    switch (pHdr->f_magic)	{	case (SWAB_SHORT(IMAGE_DOS_SIGNATURE)):            *pSwap = TRUE;	case (IMAGE_DOS_SIGNATURE):	    /* Remove DOS EXE header */            fioRead(fd,(char *)&dhead + 2,sizeof(dhead)-2);	    lseek (fd, dhead.e_lfanew, SEEK_SET);            /* Check for NT SIGNATURE */            fioRead (fd, (char *)&i, 4);            if ( i != IMAGE_NT_SIGNATURE )                {                printf("Bad Image Signature %x %x\n",i,IMAGE_NT_SIGNATURE);		errnoSet (S_loadLib_HDR_READ);                return ERROR;                }            fioRead (fd, (char *)&pHdr->f_magic, 2);	    break;	case (SWAB_SHORT(IMAGE_FILE_MACHINE_I386)):            *pSwap = TRUE;	    break;        case (IMAGE_FILE_MACHINE_I386):	    *pSwap = FALSE;	    break;	    	default:#ifndef MULTIPLE_LOADERS	    printErr (fileTypeUnsupported, pHdr->f_magic);#endif	    errnoSet (S_loadLib_FILE_ENDIAN_ERROR);	    return ERROR;	    break;	}    status = fileRead (fd, &pHdr->f_nscns, sizeof(pHdr->f_nscns), *pSwap);    status |= fileRead (fd, &pHdr->f_timdat, sizeof(pHdr->f_timdat), *pSwap);    status |= fileRead (fd, &pHdr->f_symptr, sizeof(pHdr->f_symptr), *pSwap);    status |= fileRead (fd, &pHdr->f_nsyms, sizeof(pHdr->f_nsyms), *pSwap);    status |= fileRead (fd, &pHdr->f_opthdr, sizeof(pHdr->f_opthdr), *pSwap);    status |= fileRead (fd, &pHdr->f_flags, sizeof(pHdr->f_flags), *pSwap);    max_scns = pHdr->f_nscns;    return status;    }/********************************************************************************* pecoffOpthdrRead - read in PECOFF optional header and swap if necessary* */LOCAL STATUS pecoffOpthdrRead    (    int     	fd,    PEOPTION 	*pOptHdr,    BOOL    	swapTables    )    {    int status;    status = fileRead(fd, &pOptHdr->magic, sizeof(pOptHdr->magic),                            swapTables);    status |= fileRead(fd, &pOptHdr->vstamp, sizeof(pOptHdr->vstamp),                            swapTables);    status |= fileRead(fd, &pOptHdr->tsize, sizeof(pOptHdr->tsize),                            swapTables);    status |= fileRead(fd, &pOptHdr->dsize, sizeof(pOptHdr->dsize),                            swapTables);    status |= fileRead(fd, &pOptHdr->bsize, sizeof(pOptHdr->bsize),                            swapTables);    status |= fileRead(fd, &pOptHdr->entry, sizeof(pOptHdr->entry),                            swapTables);    status |= fileRead(fd, &pOptHdr->text_start, sizeof(pOptHdr->text_start),                            swapTables);    status |= fileRead(fd, &pOptHdr->data_start, sizeof(pOptHdr->data_start),                            swapTables);    status |= fileRead(fd, &pOptHdr->image_base, sizeof(pOptHdr->image_base),                            swapTables);    status |= fileRead(fd, &pOptHdr->section_align, sizeof(pOptHdr->section_align),                            swapTables);    status |= fileRead(fd, &pOptHdr->file_align, sizeof(pOptHdr->file_align),                            swapTables);    return (status);    }/********************************************************************************* pecoffSecHdrRead - read in PECOFF section header and swap if necessary* */LOCAL STATUS pecoffSecHdrRead    (    int    fd,    SCNHDR *pScnHdr,    FILHDR *pHdr,    BOOL   swapTables    )    {    int ix;    int status = 0;    /* check for correct section count */    if (pHdr->f_nscns > MAX_SCNS)	{	return (ERROR);	}    for (ix = 0; ix < pHdr->f_nscns; ix++)	{        status = fileRead(fd, pScnHdr->s_name, sizeof(pScnHdr->s_name),                          FALSE);        status |= fileRead(fd, &pScnHdr->s_paddr, sizeof(pScnHdr->s_paddr),                           swapTables);        status |= fileRead(fd, &pScnHdr->s_vaddr, sizeof(pScnHdr->s_vaddr),                            swapTables);        status |= fileRead(fd, &pScnHdr->s_size, sizeof(pScnHdr->s_size),                            swapTables);        status |= fileRead(fd, &pScnHdr->s_scnptr, sizeof(pScnHdr->s_scnptr),                            swapTables);        status |= fileRead(fd, &pScnHdr->s_relptr, sizeof(pScnHdr->s_relptr),                            swapTables);        status |= fileRead(fd, &pScnHdr->s_lnnoptr, sizeof(pScnHdr->s_lnnoptr),                            swapTables);        status |= fileRead(fd, &pScnHdr->s_nreloc, sizeof(pScnHdr->s_nreloc),                            swapTables);        status |= fileRead(fd, &pScnHdr->s_nlnno, sizeof(pScnHdr->s_nlnno),                            swapTables);        status |= fileRead(fd, &pScnHdr->s_flags, sizeof(pScnHdr->s_flags),                            swapTables);	/*	 * In order to comply with an obscure requirement from Microsoft, the	 * GNU toolchain puts the size of the bss section in the section	 * header's physical address field. This piece of code addresses the	 * SPR 70767 by reseting the s_size field as appropriate for the rest	 * of the loader code.	 */	if (pScnHdr->s_flags & STYP_BSS)	    {	    if ((pScnHdr->s_size == 0) && (pScnHdr->s_paddr != 0))		pScnHdr->s_size = pScnHdr->s_paddr;	    }	pScnHdr++;	}    return (status);    }/********************************************************************************* pecoffReadRelocInfo - read in PECOFF relocation info and swap if necessary* * Assumptions:  The file pointer is positioned at the start of the relocation*		records.**		The relocation records are ordered by section.*/LOCAL STATUS pecoffReadRelocInfo    (    int     fd,    SCNHDR  *pScnHdr,    RELOC   **pRelsPtr,    BOOL    swapTables    )    {    int ix;    int iy;    int relocSize;    int status = OK;    RELOC *pRels;                       /* pointer to single reloc entry */    for (ix = 0; ix < max_scns; ix++)	{        if (pScnHdr->s_nreloc > 0)	    {	    relocSize = (int) pScnHdr->s_nreloc * RELSZ;	    if ((*pRelsPtr = (RELOC *)malloc (relocSize)) == NULL)		{		return (ERROR);		}	if (lseek (fd, pScnHdr->s_relptr, SEEK_SET) == ERROR)	    {	    return (ERROR);	    }            for (iy = 0, pRels = *pRelsPtr;                 (iy < (int) pScnHdr->s_nreloc) && (status == OK);                 iy++, pRels++)                {                status = fileRead(fd, &pRels->r_vaddr,                                   sizeof(pRels->r_vaddr), swapTables);                status |= fileRead(fd, &pRels->r_symndx,                                   sizeof(pRels->r_symndx), swapTables);                status |= fileRead(fd, &pRels->r_type,                                   sizeof(pRels->r_type), swapTables);                }            if (status != OK)                return(status);	    }	pScnHdr++;	pRelsPtr++;        }    return (OK);

⌨️ 快捷键说明

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