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

📄 loadpecofflib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* fix up start address of bss sections */    addrBss = pBss;    for (ix = 0; ix < max_scns; ix++)        {        if (scnHdr[ix].s_flags & STYP_BSS)	    {	    addrBss += dataAlign (MAX_ALIGNMENT, addrBss);	    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 = pecoffSymTab (fd, &hdr, (SYMENT *)externalSyms, &externalsBuf, 			 symFlag, &seg, stringsBuf, symTbl, pCommons, scnHdr,			 scnAddr, symsAbsolute, tablesAreLE, group,                         optHdr.image_base);    /* 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 (pecoffRelSegmentI386 (relsPtr[ix], scnHdr, externalsBuf,                                externalSyms, &seg, ix, symTbl) != OK)		    {	            goto error;		    }		}	    }    pecoffFree(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:    pecoffFree(externalsBuf, externalSyms, stringsBuf, relsPtr);    moduleDelete (moduleId);    return (NULL);    }/******************************************************************************** loadPecoffInit - initialize the system for pecoff load modules.** This routine initializes VxWorks to use a PECOFF format for loading * modules.** RETURNS: OK** SEE ALSO: loadModuleAt()*/STATUS loadPecoffInit    (    )    {    /* XXX check for installed? */    loadRoutine = (FUNCPTR) ldPecoffModAtSym;    return (OK);    }/********************************************************************************* pecoffFree - free any malloc'd memory**/LOCAL void pecoffFree    (    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++;	}    }/********************************************************************************* pecoffSegSizes - 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 pecoffSegSizes    (    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.             */            nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeText);            pSeg->sizeText += pScnHdr->s_size + nbytes;	    /* SPR #21836 */	    if (MAX_ALIGNMENT > pSeg->flagsText)		pSeg->flagsText = MAX_ALIGNMENT;            }        else if (pScnHdr->s_flags & STYP_DATA)            {            nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeData);            pSeg->sizeData += pScnHdr->s_size + nbytes;	    /* SPR #21836 */	    if (MAX_ALIGNMENT > pSeg->flagsData)		pSeg->flagsData = MAX_ALIGNMENT;            }        else if (pScnHdr->s_flags & STYP_BSS)            {            nbytes = dataAlign(MAX_ALIGNMENT, pSeg->sizeBss);            pSeg->sizeBss += pScnHdr->s_size + nbytes;	    /* SPR #21836 */	    if (MAX_ALIGNMENT > pSeg->flagsBss)		pSeg->flagsBss = MAX_ALIGNMENT;            }        }    }/********************************************************************************* pecoffLoadSections - read sections into memory* */LOCAL STATUS pecoffLoadSections    (    int     fd,    SCNHDR  *pScnHdr,    char    **pScnAddr,    char    *pText,    char    *pData    )    {    int     ix;    int     textCount = 0;    int     dataCount = 0;    INT32   size;               /* section size */    int     nbytes;             /* additional bytes required for alignment */    char    *pLoad;             /* address to load data at */    for (ix = 0; ix < max_scns; ix++)	{        pLoad = NULL;        size = pScnHdr->s_size;	if (size != 0 && pScnHdr->s_scnptr != 0)	    {            if (pScnHdr->s_flags & STYP_TEXT)                {                pLoad = pText;                nbytes = dataAlign(MAX_ALIGNMENT, pLoad);                pLoad += nbytes;                pText = (char *) ((int) pLoad + size); /* for next load */                textCount += size + nbytes;                }            else if (pScnHdr->s_flags & STYP_DATA)                {                pLoad = pData;                nbytes = dataAlign(MAX_ALIGNMENT, pLoad);                pLoad += nbytes;                pData = (char *) ((int) pLoad + size); /* for next load */                dataCount += size + nbytes;                }            else                {                /* ignore all other sections */                pScnAddr[ix] = pLoad;      	        pScnHdr++;		continue;                }            /*  Advance to position in file             *  and read section directly into memory.             */	    if ((lseek (fd, pScnHdr->s_scnptr, SEEK_SET) == ERROR) ||		(fioRead (fd, pLoad, size) != size))		{		return (ERROR);		}	    }        pScnAddr[ix] = pLoad;	pScnHdr++;	}    return (OK);    }/********************************************************************************* pecoffSymTab -** This is passed a pointer to a pecoff symbol table and processes* each of the external symbols defined therein.  This processing performs* two functions:**  1) Defined symbols are entered in the system symbol table as*     specified by the "symFlag" argument:*	LOAD_ALL_SYMBOLS = all defined symbols (LOCAL and GLOBAL) are added,*	LOAD_GLOBAL_SYMBOLS = only external (GLOBAL) symbols are added,*	LOAD_NO_SYMBOLS	= no symbols are added;**  2) Any undefined externals are looked up in the system symbol table to*     determine their values.  The values are entered into the specified*     'externals' array.  This array is indexed by the symbol number*     (position in the symbol table).*     Note that all symbol values, not just undefined externals, are entered*     into the 'externals' array.  The values are used to perform relocations.**     Note that "common" symbols have type undefined external - the value*     field of the symbol will be non-zero for type common, indicating*     the size of the object.** If an undefined external cannot be found in the system symbol table,* an error message is printed, but ERROR is not returned until the entire* symbol table has been read, which allows all undefined externals to be* looked up.** RETURNS: OK or ERROR*/LOCAL STATUS pecoffSymTab    (    int fd,    FILHDR *pHdr,               /* pointer to file header */    SYMENT *externalSyms,	/* pointer to symbols array */    char ***externals,		/* pointer to pointer to array to fill in 				   symbol absolute values */    int symFlag,		/* symbols to be added to table 				 *   ([NO|GLOBAL|ALL]_SYMBOLS) */    SEG_INFO *pSeg,		/* pointer to segment information */    char *symStrings,		/* symbol string table */    SYMTAB_ID symTbl,		/* symbol table to use */    char *pNextCommon,		/* next common address in bss */    SCNHDR *pScnHdrArray,	/* pointer to PECOFF section header array */    char **pScnAddr,		/* pointer to section loaded address array */    BOOL symsAbsolute,          /* TRUE if symbols already absolutely located*/    BOOL    swapTables,    UINT16 group,    int    imageBase    )    {    int status  = OK;		/* return status */    FAST char *name;		/* symbol name (plus EOS) */    SYMENT *symbol;		/* symbol struct */    SYM_TYPE vxSymType;		/* vxWorks symbol type */    int symNum;			/* symbol index */    char *adrs;			/* table resident symbol address */    char *bias;			/* section relative address */    ULONG bssAlignment;		/* alignment value of common type */    long scnFlags;              /* flags from section header */    int auxEnts = 0;            /* auxiliary symbol entries to skip */    SCNHDR *pScnHdr = NULL;	/* pointer to a PECOFF section header */    char *scnAddr = NULL;	/* section loaded address */    char nameTemp[SYMNMLEN+1];  /* temporary for symbol name string */    /*  Loop thru all symbol table entries in object file     */    for (symNum = 0, symbol = externalSyms; symNum < pHdr->f_nsyms; 	 symbol++, symNum++)	{        if (auxEnts)                    /* if this is an auxiliary entry */            {            auxEnts--;            continue;                   /* skip it */            }        auxEnts = symbol->n_numaux;      /* # of aux entries for this symbol */        if (symbol->n_scnum == N_DEBUG)            continue;	/* Setup pointer to symbol name string	 */        if (symbol->n_zeroes)            /* if name is in symbol entry */            {            name = symbol->n_name;            if ( *(name + SYMNMLEN -1) != '\0')                {                /*  If the symbol name array is full,                 *  the string is not terminated by a null.                 *  So, move the string to a temporary array,                 *  where it can be null terminated.                 */                bcopy(name, nameTemp, SYMNMLEN);                nameTemp[SYMNMLEN] = '\0';                name = nameTemp;                }            }        else            name = symStrings + symbol->n_offset;        if (   ! PECOFF_UNDF(symbol)            && ! PECOFF_COMM(symbol))            {            /*  Symbol is not an undefined external.             *             *  Determine symbol's section and address bias             */            if (symbol->n_scnum > 0)                {                pScnHdr = pScnHdrArray + (symbol->n_scnum - 1);		scnAddr = pScnAddr[symbol->n_scnum - 1];                scnFlags = pScnHdr->s_flags;                }            else                {                scnFlags = 0;       /* section has no text, data or bss */                continue;                }            if (symbol->n_scnum == N_ABS) /* special check for absolute syms */                {                bias = 0;                vxSymType = VX_ABS;                }            else if (scnFlags & STYP_TEXT)                {/* define GNU_LD_ADDS_VMA if ldsimpc -r gets fixed */#ifdef GNU_LD_ADDS_VMA                bias = (char *) (scnAddr - (char *) pScnHdr->s_vaddr);#else                bias = (char *) scnAddr;#endif                vxSymType = VX_TEXT;                }            else if (scnFlags & STYP_DATA)                {#ifdef GNU_LD_ADDS_VMA                bias = (char *) (scnAddr - (char *) pScnHdr->s_vaddr);#else                bias = (char *) scnAddr;#endif                vxSymType = VX_DATA;                }            else if (scnFlags & STYP_BSS)                {#ifdef GNU_LD_ADDS_VMA                bias = (char *) (scnAddr - (char *) pScnHdr->s_vaddr);#else                bias = (char *) scnAddr;#endif

⌨️ 快捷键说明

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