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

📄 loadcofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    RELOC  *relsPtr[MAX_SCNS]; 		/* section relocation */    SEG_INFO seg;			/* file segment info */    BOOL tablesAreLE;			/* boolean for table sex */    BOOL symsAbsolute = FALSE;          /* TRUE if already absolutely located*/    int status;				/* return value */    int ix;				/* temp counter */    int nbytes;				/* temp counter */    char *pCommons;                     /* start of common symbols in bss */    char *addrBss;    char        fileName[255];    UINT16      group;    MODULE_ID   moduleId;    /* Initialization */    memset ((void *)&seg, 0, sizeof (seg));#if (CPU_FAMILY == I960)    /* check for fast load */    if ((symFlag & BAL_LOAD) || (symFlag == NO_SYMBOLS))	{	fast_load = FALSE;	if (symFlag != NO_SYMBOLS)	    symFlag &= ~BAL_LOAD;	}    else        fast_load = TRUE;#endif    /* Set up the module */    ioctl (fd, FIOGETNAME, (int) fileName);    moduleId = loadModuleGet (fileName, MODULE_ECOFF, &symFlag);    if (moduleId == NULL)        return (NULL);    group = moduleId->group;    /* init section pointers to NULL */    for (ix = 0; ix < MAX_SCNS; ix++)	{	scnAddr[ix] = NULL;	relsPtr[ix] = NULL;	bzero((char *) &scnHdr[ix], (int) sizeof(SCNHDR));	}    /* read object module header */    if (coffHdrRead (fd, &hdr, &tablesAreLE) != OK)	{	/*  Preserve errno value from subroutine. */	goto error;	}    /* read in optional header */    if (hdr.f_opthdr)                   /* if there is an optional header */        {        if (coffOpthdrRead (fd, &optHdr, tablesAreLE) != OK)            {            errnoSet(S_loadLib_OPTHDR_READ);            goto error;            }        }    /* read in section headers */    if (coffSecHdrRead (fd, &scnHdr[0], &hdr, tablesAreLE) != OK)	{	errnoSet(S_loadLib_SCNHDR_READ);	goto error;	}    /* Determine segment sizes */    /*      * XXX seg.flagsXxx mustn't be used between coffSegSizes() and      * loadSegmentsAllocate().     */    coffSegSizes(&hdr, scnHdr, &seg);    /*  If object file is already absolutely located (by linker on host),     *  then override parameters pText, pData and pBss.     */    if (   (hdr.f_flags & F_EXEC)        && (hdr.f_flags & F_RELFLG))        {        if (hdr.f_opthdr)               /* if there is an optional header */            {            symsAbsolute = TRUE;            pText = (INT8 *)(optHdr.text_start);            pData = (INT8 *)(optHdr.data_start);            /* bss follows data segment */            pBss = (INT8 *) pData + optHdr.dsize;            pBss += dataAlign(MAX_ALIGNMENT, pBss);	    }	}    seg.addrText = pText;    seg.addrData = pData;    /*     * If pBss is set to LD_NO_ADDRESS, change it to something else.     * The coff loader allocates one large BSS segment later on, and     * loadSegmentsAllocate doesn't work correctly for it.     */    seg.addrBss = (pBss == LD_NO_ADDRESS ? LD_NO_ADDRESS + 1 : pBss);    /*      * SPR #21836: loadSegmentsAllocate() allocate memory aligned on      * the max value of sections alignement saved in seg.flagsText,     * seg.flagsData, seg.flagsBss.     */    if (loadSegmentsAllocate (&seg) != OK)        {        printErr ("Could not allocate segments\n");        goto error;        }    else        {        pText = seg.addrText;        pData = seg.addrData;        }    /*  Ensure that section starts on the appropriate alignment.     */    pText += dataAlign(MAX_ALIGNMENT, pText);    if (pData == LD_NO_ADDRESS)        {	pData = pText + seg.sizeText;        }    /*  Ensure that section starts on the appropriate alignment.     */    pData += dataAlign(MAX_ALIGNMENT, pData);    seg.addrText = pText;    seg.addrData = pData;    /* load text and data sections */    if (coffLoadSections (fd, &scnHdr[0], &scnAddr[0], pText, pData) != OK)	{	errnoSet (S_loadLib_LOAD_SECTIONS);	goto error;	}    /* get section relocation info */    if (coffReadRelocInfo (fd, &scnHdr[0], &relsPtr[0], tablesAreLE) != OK)	{	errnoSet (S_loadLib_RELOC_READ);	goto error;	}    /* read symbols */    if (coffReadExtSyms (fd, &externalSyms, &externalsBuf, &hdr, tablesAreLE)        != OK)	{	errnoSet (S_loadLib_EXTSYM_READ);	goto error;	}    /* read string table */    if (coffReadExtStrings (fd, &stringsBuf, tablesAreLE) != OK)	{	errnoSet (S_loadLib_EXTSTR_READ);	goto error;	}    /*  Determine additional amount of memory required to append     *  common symbols on to the end of the BSS section.     */    nbytes = coffTotalCommons(externalSyms, hdr.f_nsyms, seg.sizeBss);    /* set up for bss */    seg.sizeBss += nbytes;    if (pBss == LD_NO_ADDRESS)        {        if (seg.sizeBss != 0)            {            if ((pBss = malloc (seg.sizeBss)) == NULL)                 goto error;            else                                 		seg.flagsBss |= SEG_FREE_MEMORY;              }        else            {            pBss = (char *) ((long) pData + (long) seg.sizeData);            }        }    pBss += dataAlign(MAX_ALIGNMENT, pBss);    seg.addrBss = pBss;    /* fix up start address of bss sections */    addrBss = pBss;    for (ix = 0; ix < max_scns; ix++)        {        if (scnHdr[ix].s_flags & STYP_BSS)	    {#if (CPU_FAMILY == I960) 	    addrBss += dataAlign (scnHdr[ix].s_align, addrBss);#else /* (CPU_FAMILY == I960) */	    addrBss += dataAlign (MAX_ALIGNMENT, addrBss);#endif /* (CPU_FAMILY == I960) */	    scnAddr[ix] = addrBss;	    addrBss += scnHdr[ix].s_size;            }        }	        /* set up address for first common symbol */    pCommons = (char *) ((long) seg.addrBss + (seg.sizeBss - nbytes));    /* add segment names to symbol table before other symbols */    if (symFlag != LOAD_NO_SYMBOLS)        addSegNames (fd, pText, pData, pBss, symTbl, group);    /* process symbol table */    status = coffSymTab (fd, &hdr, (SYMENT *)externalSyms, &externalsBuf, 			 symFlag, &seg, stringsBuf, symTbl, pCommons, scnHdr,			 scnAddr, symsAbsolute, tablesAreLE, group);    /* relocate text and data segments     *     *   note: even if symbol table had missing symbols, continue with     *   relocation of those symbols that were found.     *   note: relocation is for changing the values of the relocated     *   symbols.  bss is uninitialized data, so it is not relocated     *   in the symbol table.     */    if ((status == OK) || (errnoGet() == S_symLib_SYMBOL_NOT_FOUND))        for (ix = 0; ix < max_scns; ix++)	    {	    if ((relsPtr[ix] != NULL)			&&		!(scnHdr[ix].s_flags & STYP_INFO)	&&		!(scnHdr[ix].s_flags & STYP_NOLOAD)	&&		 (scnHdr[ix].s_flags != STYP_REG)	&& 		!(scnHdr[ix].s_flags & STYP_PAD))		{#if (CPU_FAMILY == ARM)                if (coffRelSegmentArm(relsPtr[ix], scnHdr, externalsBuf,                               externalSyms, &seg, ix, symTbl) != OK)#else#if (CPU_FAMILY == AM29XXX)                if (coffRelSegmentAm29K(relsPtr[ix], scnHdr, externalsBuf,                                externalSyms, &seg, ix, symTbl) != OK)#else /* (CPU_FAMILY == I960) */                if (coffRelSegmentI960(relsPtr[ix], scnHdr, scnAddr[ix],				       externalsBuf, externalSyms, &seg, ix,				       symTbl) != OK)#endif /* (CPU_FAMILY == AM29XXX) */#endif /* (CPU_FAMILY == ARM) */		    {	            goto error;		    }		}	    }    coffFree(externalsBuf, externalSyms, stringsBuf, relsPtr);    /* write protect the text if text segment protection is turned on */    if (seg.flagsText & SEG_WRITE_PROTECTION)	{	if (VM_STATE_SET (NULL, pText, seg.sizeProtectedText,			  VM_STATE_MASK_WRITABLE,			  VM_STATE_WRITABLE_NOT) == ERROR)	    goto error;	}    /* return load addresses, where called for */    if (ppText != NULL)        *ppText = pText;    if (ppData != NULL)        *ppData = pData;    if (ppBss != NULL)        *ppBss = pBss;    /* clear out bss */    bzero (pBss, (int) seg.sizeBss);    /*     * Add the segments to the module.     * This has to happen after the relocation gets done.     * If the relocation happens first, the checksums won't be     * correct.     */    moduleSegAdd (moduleId, SEGMENT_TEXT, pText, seg.sizeText, seg.flagsText);    moduleSegAdd (moduleId, SEGMENT_DATA, pData, seg.sizeData, seg.flagsData);    moduleSegAdd (moduleId, SEGMENT_BSS, pBss, seg.sizeBss, seg.flagsBss);    if (status == OK)        return (moduleId);    else        return (NULL);    /* error:     * clean up dynamically allocated temporary buffers and return ERROR     */error:    coffFree(externalsBuf, externalSyms, stringsBuf, relsPtr);    moduleDelete (moduleId);    return (NULL);    }/********************************************************************************* coffFree - free any malloc'd memory**/LOCAL void coffFree    (    char **pExternalsBuf,       /* pointers to external symbols */    char *pExternalSyms,        /* buffer for external symbols */    char *pStringsBuf,		/* string table pointer */    RELOC  **pRelsPtr 		/* section relocation */    )    {    int ix;    if (pStringsBuf != NULL)	free (pStringsBuf);    if (pExternalsBuf != NULL)	free ((char *) pExternalsBuf);    if (pExternalSyms != NULL)	free ((char *) pExternalSyms);    for (ix = 0; ix < MAX_SCNS; ix++)	{	if (*pRelsPtr != NULL)	    free((char *) *pRelsPtr);        pRelsPtr++;	}    }/********************************************************************************* coffSegSizes - determine segment sizes** This function fills in the size fields in the SEG_INFO structure.* Note that the bss size may need to be readjusted for common symbols. */LOCAL void coffSegSizes    (    FILHDR *pHdr,               /* pointer to file header */    SCNHDR *pScnHdrArray,       /* pointer to array of section headers */    SEG_INFO *pSeg	       /* section addresses and sizes */    )    {    int ix;    int nbytes;             /* additional bytes required for alignment */    SCNHDR *pScnHdr;            /* pointer to a section header */    pSeg->sizeText = 0;    pSeg->sizeData = 0;    pSeg->sizeBss = 0;    /*      * SPR #21836: pSeg->flagsText, pSeg->flagsData, pSeg->flagsBss are used     * to save the max value of each segments. These max values are computed     * for each sections. These fields of pSeg are only used on output, then     * a temporary use is allowed.     */    pSeg->flagsText = _ALLOC_ALIGN_SIZE;    pSeg->flagsData = _ALLOC_ALIGN_SIZE;    pSeg->flagsBss  = _ALLOC_ALIGN_SIZE;    for (ix=0; ix < pHdr->f_nscns; ix++) /* loop thru all sections */        {        pScnHdr = pScnHdrArray + ix;        if (pScnHdr->s_flags & STYP_TEXT)            {            /*  Assume that there was a previous section of same type.             *  First, align data to boundary from section header.             *  Add the size of this section to the total segment size.             */#if (CPU_FAMILY == ARM)            sprFixTextOff[ix] = pSeg->sizeText;#endif#if (CPU_FAMILY == I960)            nbytes = dataAlign(pScnHdr->s_align, pSeg->sizeText);	    /* SPR #21836 */

⌨️ 快捷键说明

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