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

📄 loadsomcofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
     * 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;        }    /*     * make sure all allocated segments are aligned OK.     * This will always be true if the memory is malloc'ed,     * since SEG_ALIGN, and _MEM_ALIGN, and the maximum     * possible subspace alignment are all "8"     */    pText = (char *) ROUND_UP (seg.addrText, SEG_ALIGN);    pData = (char *) ROUND_UP (seg.addrData, SEG_ALIGN);    pBss  = (char *) ROUND_UP (seg.addrBss, SEG_ALIGN);    pComm = (char *) ((int)pBss + seg.sizeBss                      - ROUND_UP(commSize, SEG_ALIGN));    if ( (pText != seg.addrText) ||         (pData != seg.addrData) ||         (pBss  != seg.addrBss) )        {        printErr ("loadModuleAtSym: segment alignment error\n");        goto error;        }    DBG_PUT ("pText = 0x%x, pData = 0x%x, pBss = 0x%x pComm = 0x%x\n",             (int)pText, (int)pData, (int)pBss, (int)pComm);    DBG_PUT ("sizeText = 0x%x, sizeData = 0x%x, sizeBss = 0x%x\n",             seg.sizeText, seg.sizeData, seg.sizeBss);    /* load all subspaces into memory */    if (loadSubspaces (fd, &somHdr, pSubInfo, pSubspace, pText, pData, pBss)                      != OK)        {        errno = S_loadSomCoffLib_LOAD_SPACE;        goto error;        }    /* 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 = rdSymtab (pSymBuf, somHdr.symbol_total, pSubspace,                       pSubInfo, symFlag, symTbl, &pGlobal, pComm, group);    /* Perform linker fixup requests on the subspaces */    if (somHdr.version_id == NEW_VERSION_ID)        {        if (somHdr.fixup_request_total != 0)            (void) linkSubspaces ((UCHAR *) pReloc, pSubspace,                                    somHdr.subspace_total, pSubInfo, pSymBuf,                                    somHdr.symbol_total,                                   symTbl, pGlobal, moduleId);        }    else        {        errno = S_loadSomCoffLib_RELOC_VERSION;        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);    /* flush text to memory */    CACHE_TEXT_UPDATE (pText, seg.sizeText);    /*     * 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);                    /* error:     * clean up dynamically allocated temporary buffers and return ERROR */error:done:    if (pSubInfo != NULL)        free ((char *) pSubInfo);    if (pSpaceStrings != NULL)        free ((char *) pSpaceStrings);    if (pSpace!= NULL)        free ((char *) pSpace);    if (pSubspace!= NULL)        free ((char *) pSubspace);    if (pSymBuf != NULL)        free ((char *) pSymBuf);    if (pSymStr != NULL)        free ((char *) pSymStr);    if (pReloc!= NULL)        free ((char *) pReloc);    if (status == OK)        return (moduleId);    else        {        moduleDelete (moduleId);        return (NULL);        }    }/******************************************************************************** symbolNameSet - make all symbols records point to their name strings*/  static void symbolNameSet    (    SYMREC *   pSym,           /* pointer to symbol table */    int        nSyms,          /* # of entries in symbol table */    char *     pSymStr,        /* pointer to symbol string table */    SUBSPACE * pSubspace,      /* pointer to subspace dictionary */    int        nSubs,          /* number of subspaces */    char *     pSpaceStr,      /* pointer to space name string table */    SPACE *    pSpace,	       /* pointer to space dictionary */    int        nSpaces	       /* number of spaces */    )    {    int ix;    for (ix = 0; ix < nSyms; ix++)        pSym[ix].symbol_name = pSymStr + pSym[ix].name.n_strx;    for (ix = 0; ix < nSubs; ix++)        pSubspace[ix].subspace_name = pSpaceStr + pSubspace[ix].name.n_strx;    for (ix = 0; ix < nSpaces; ix++)        pSpace[ix].space_name = pSpaceStr + pSpace[ix].name.n_strx;    }/********************************************************************************* commSizeGet - this routine go through the symbol table to calculate the *                  size of STORAGE data for relocatable files** STORAGE requests (i.e., "common data") are simply turned into BSS* by this loader (and all other VxWorks loaders). The loader adds* an area for these symbols by increasing the normal BSS area.* This allows us to not have to malloc memory for each STORAGE symbol.** As a side effect, all the STORAGE symbols are partially relocated.* That is - the symbol_value field of the symbols SYMREC structure* is turned into an offset from the start of the STORAGE segment*/static void commSizeGet    (    SYMREC * pSymBuf,              /* symbol dictionary */    int      nEnts,                /* number of symbols */    SUBSPACE *pSubspace,           /* subspace relocation info */    int *    pCommSize             /* where to return comm size */    )    {    SYMREC * pSym = pSymBuf;    int      size =  0;    int      subspaceIndex;    int      ix;    int      iy;    SYMREC * pSearch;    int      symSize;    for (ix = 0; ix < nEnts; ix ++)        {        if (pSym->symbol_type == ST_STORAGE)            {            pSearch = pSymBuf;            /* XXX - search for the previous record for same symbol             * in symbol table. For some reason STORAGE symbols             * sometime appear in pairs.             */            for (iy = 0; iy < ix; iy ++)                {                if (strcmp(pSym->symbol_name, pSearch->symbol_name) == 0)                    break;                pSearch ++;                }            /* deal with a new storage symbol */            if (iy == ix)                {                subspaceIndex = pSym->symbol_info;                size = ROUND_UP (size, pSubspace[subspaceIndex].alignment);                symSize = pSym->symbol_value;                pSym->symbol_value = size;                size += symSize;                pSym->secondary_def = 0;                }            /* duplicate storage symbol */            else                {                pSym->secondary_def = 1;                }            }        pSym ++;        }    *pCommSize = size;    }/********************************************************************************* rdSymtab - Process the VxWorks symbol table** This is passed a pointer to an HP-PA SOM symbol table and processes* each of the external symbols defined therein.  This processing performs* two functions:*  1) New symbols are entered in the system symbol table as*     specified by the "symFlag" argument:*        ALL_SYMBOLS    = all defined symbols (LOCAL and GLOBAL) are added,*        GLOBAL_SYMBOLS = only external (GLOBAL) symbols are added,*        NO_SYMBOLS     = no symbols are added;*  2) Undefined externals are looked up in the system table.*     If an undefined external cannot be found in the 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*     reported.** Absolute symbols are automatically discarded.** RETURNS: OK or ERROR*/static STATUS rdSymtab     (    SYMREC *   pSymBuf,		/* pointer to symbol table */    FAST int   nEnts,           /* # of entries in symbol table */    SUBSPACE * pSubspace,       /* pointer to subspace dictionary */    SUB_INFO * pSubInfo,        /* subspace relocation info */    int        symFlag,         /* symbols to be added to table                                  *   ([NO|GLOBAL|ALL]_SYMBOLS) */    SYMTAB_ID  symTbl,          /* symbol table to use */    SYMREC **  pSymGlobal,      /* '$global$' symbol entry pointer */    char *     pComm,           /* start of comm area (within bss segment) */    int        group            /* symbol group */    )    {    char *   name;              /* symbol name (plus EOS) */    SYMREC * pSym = (SYMREC *) pSymBuf;  /* symbol entry pointer */    int      ix;		/* symbols subspace index */    SYM_TYPE vxSymType;         /* symbol type */    UCHAR    arg_reloc;		/* argument relocation info */    int      status  = OK;      /* return status */    *pSymGlobal = NULL;    for (; nEnts > 0; nEnts -= 1, pSym ++)        {        /* throw away absolute symbols */        if (pSym->symbol_type == ST_ABSOLUTE)            continue;        /* throw away symbol and argument extentions */        if (pSym->symbol_type == ST_SYM_EXT)            continue;        if (pSym->symbol_type == ST_ARG_EXT)            continue;        /* throw away invalid symbols */        if (pSym->symbol_type == ST_NULL)            continue;        /* get the symbol name */        name = pSym->symbol_name;        /* keep the symbol $global$ handy */        if ( (pSym->symbol_type == ST_DATA) && (!strcmp(name, "$global$")) )            *pSymGlobal = pSym;        if (!pSubspace[pSym->symbol_info].is_loadable)            WARN ("Warning: symbol %s is unloadable!\n", name);        if (pSym->must_qualify)            WARN ("Warning: symbol %s must qualify!\n", name);        if (pSym->is_common || pSym->dup_common)            WARN ("Warning: symbol %s is a common block!\n", name);        /* add new symbols to the symbol table */        if ((pSym->symbol_scope == SS_UNIVERSAL) ||            (pSym->symbol_scope == SS_LOCAL))            {            /* relocate the symbol relative to it's associated subspace */            ix = pSym->symbol_info;            pSym->symbol_value = pSym->symbol_value                                 - pSubspace[ix].subspace_start                                 + (unsigned int)pSubInfo[ix].loadAddr;            switch (pSym->symbol_type)                {                /* Data or BSS symbols */                case ST_DATA:                    if (pSubInfo[ix].loadType == LOAD_BSS)                        {                        vxSymType = N_BSS;                        DBG_PUT ("new BSS symbol %s (0x%x)\n", name,                                 pSym->symbol_value);                        }                    else                        {                        vxSymType = N_DATA;                        DBG_PUT ("new DATA symbol %s (0x%x)\n", name,                                  pSym->symbol_value);                        }                    arg_reloc = 0;                    break;                /* Text symbols */                case ST_CODE:                case ST_PRI_PROG:                case ST_SEC_PROG:                case ST_MILLICODE:                case ST_ENTRY:                    vxSymType = N_TEXT | ((UCHAR)(pSym->arg_reloc & 3) << 6);                    arg_reloc = (UCHAR)(pSym->arg_reloc >> 2);                    pSym->symbol_value &= 0xfffffffc;                    break;                /* ignore stubs */                case ST_STUB:                    continue;                /* These have never popped up yet */                case ST_MODULE:                case ST_PLABEL:                case ST_OCT_DIS:                case ST_MILLI_EXT:                default:                    WARN ("Warning: symbol %s is of type %d\n",                               name, pSym->symbol_type);                    continue;                }            if ( (pSym->symbol_scope == SS_UNIVERSAL) && (!pSym->hidden) )                vxSymType |= N_EXT;            if ( ((symFlag & LOAD_LOCAL_SYMBOLS) && !(vxSymType & N_EXT)) ||                ((symFlag & LOAD_GLOBAL_SYMBOLS) && (vxSymType & N_EXT)) )                {                DBG_PUT ("adding symbol %s to symTbl\n", name);                if (externSymAdd (symTbl, name, (char*)pSym->symbol_value,                            vxSymType, group, arg_reloc) != OK)                    {                    printErr ("can't add symbol %s (errno=%#x)\n",                                name, errnoGet());                    }                }            }        /* Add STORAGE (common) symbols as BSS */

⌨️ 快捷键说明

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