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

📄 loadsomcofflib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            mask = 0x1fffff;            break;        case i_exp11:            value = de_low_sign_ext (value, 11);            mask = 0x7ff;            break;        case i_rel17:        case i_abs17:            value = de_assemble_17 (value >> 2);            mask = 0x001f1ffd;            break;        case i_rel12:            value = de_assemble_12 (value >> 2);            mask = 0x1ffd;            break;        case i_data:            mask = 0xffffffff;            break;        case i_milli:        case i_break:        default:            mask = 0;            break;        }    *adrs = ((*adrs) & ~mask) | (value & mask);    }/********************************************************************************* linkSubspaces - perform linker fixup commands for relocation.** RETURNS: OK or ERROR*/static STATUS linkSubspaces    (    UCHAR *   pRelCmds,        /* list of relocation commands */    SUBSPACE *pSubspace,       /* subspace dictionary */    int       nSubs,           /* number of subspaces */    SUB_INFO *pSubInfo,        /* load information for the subspaces */    SYMREC *  pSym,            /* symbols dictionary */    int       numSyms,         /* number of symbols */    SYMTAB_ID pSymTab,         /* VxWorks symbol table */    SYMREC *  pSymGlobal,      /* pointer to '$global$' entry */    MODULE_ID moduleId         /* module being linked */    )    {    int status = OK;		/* function return value */    /*     * generic fixup variables     *     * For each subspace, we must process a stream of fixup requests     * in order to complete the relocation. The fixup requests are     * variable size, and there are no "markers" to separate the     * fixups - so ya gotta be real careful. The first byte of each     * fixup request is called the opCode.     */    int ix;			/* index of subspace being fixed up */    UCHAR * pThisFixup;		/* start of relocation fixup stream */    UCHAR * pLastFixup;		/* end of stream */    UCHAR opCode;               /* the type of fixup request */    char *relAdr;               /* address that need fixing */    int relValue;               /* value to apply (e.g., a function address) */    /*     * Variables for maintaining the REPEAT_PREV_FIXUP list.     *     * The linker maintains a list of the last 4 multibyte     * fixup requests. When a REPEAT_PREV_FIXUP fixup occurs,     * we repeat one of the fixups from our list.     */    LIST prevFixupList;         /* previous fixup list */    PREV_FIXUP prevFixupNodes[4];    /* the nodes in the list */    PREV_FIXUP *pPrevFixupNode; /* pointer to some node in the list */    UCHAR *pOldFixup = 0;       /* before executing a previous fixup, we save                                 * our current place in the fixup stream */    BOOL usingPrevFixup;        /* are we currently are using a queued fixup? */    /*     * variables for fixups that manipulate the expession stack.     *     * An expession stack is used to evaluate complex combinations of values.     * The R_COMPX fixups either push a value on the expression stack or     * modifies what is on top of the stack (e.g., it might pop the top     * two elements, and push their sum).     * These fixups have a secondary opCode which describes what to do.     * The value at the top of the expession stack is used in the     * R_DATA_EXPR and R_CODE_EXPR fixups.     * XXX - these have not been tested yet.     */    UCHAR opCode2;              /* 2nd opcode for stack manipulation fixups */    int * pExpStack;                /* initial stack pointer */    int * sp;			/* current stack pointer */    int top1;                   /* first item on stack */    int top2;                   /* second item on stack */    int C;                      /* condition code for stack operation */    /*     * variables to hold the fixup request parameters.     *     * Most fixup requests pass us parameters (e.g., the symbol number     * which we need to branch to). The parameters passed depend on     * the fixup. The way the parameters are encoded in the fixup stream     * also depends on the fixup.     */    int L;                      /* number of bytes to relocate */    int S;                      /* symbol index used */    int R = 0;                  /* parameter relocation bits */    int V = 0;                  /* variable or fix up constant */    int U;			/* stack unwind bits */    int F;			/* procedure stack frame size */    int D;                      /* difference of operation code */    int X;			/* previous fixup index */    int M;			/* number of bytes for R_REPEATED_INIT */    int N;			/* statement number in R_STATEMENT */    /*     * variables for handling the rounding mode during fixups     *     * Many fixups come in pairs, where we move the left (high order)     * bits of a value in the first fixup, and the right (low order)     * bits in the next fixup. Before applying a fixup value     * at an address, it must be rounded.     * The rounded constant is then applied to the address.     *     * The field selector specifies if we should apply the     * left bits (LSEL), the right bits (RSEL), or everything (FSEL).     * The field selector depends on the current instruction, but     * can be overridden with a feild selector override fixup.     *     * The interpretation of the field selector depends on the current     * rounding mode. The rounding mode selector can be     * round down (N_MODE), round to nearest page (S_MODE), round up (D_MODE),     * or round down with adjusted constant (R_MODE).     * The rounding mode is persistent until explicity changed by     * a mode select fixup request. The default at the begining of each     * subspace is N_MODE.     *     * The function fieldGetDefault() computes the field selector     * (and adjusted constant if we are in R_MODE) based on the current     * instruction and rounding mode. It also computes how to     * apply the rounded constant to a given instruction.     */    int fixConstant;            /* adjusted constant used in R_MODE rounding */    int modeSel;                /* mode select */    int fieldSel;               /* field select */    int fieldOverride;		/* field select override flag */    int dataOverride;           /* data override flag */    int relFormat;		/* how to apply the rounded constant */    /*      * variables for stub manipulation.     *     * The linker must generate "long branch stubs" and "parameter     * relocation stubs" whenever needed. Read the INTERNAL     * comments at the begining of the file for more info.     * The long branch stubs are generated per subspace, while     * the parameter relocation stubs are generated per module.     */    LIST stubList;              /* list of current long branch stubs */    char *pLongBranchStubs;     /* starting address this subspaces stubs */    char *pStub;                /* address of current stub */    int stubIx;                 /* current stubs index in the list */    LIST argRelocStubList;	/* list of argument relocation stubs */    /*     * variables for stack unwind generation     *     * The PA-RISC has no frame pointer. To calculate the frame pointer,     * the linker must generate an array of stack unwind descriptors     * which, for each function, specifies its starting address, ending     * address, and the amount of stack space it requires.      */    LIST unwindList;		/* linked list of unwind descriptors */    UNWIND_NODE *pUnwindNode = NULL;	/* pointer to an unwind descriptor */    /* scratch variables */    char *tmpBuf;               /* tempoaray buffer */    int bufSize;                /* size of temporary buffer */    /* create the expression stack */    if ((pExpStack = (int *) calloc (1, REL_STACK_SIZE)) == NULL)        {        printErr ("ld error: unable to allocate relocation stack\n");        return (ERROR);        }    /* Initialize the previous fixup queue */    lstInit (&prevFixupList);    for (ix = 0; ix < 4; ix++)        {        lstAdd (&prevFixupList, &(prevFixupNodes[ix].node));        prevFixupNodes[ix].pFixup = NULL;        }    /* initialize the list of long branch and parameter relocation stubs */    lstInit (&stubList);    lstInit (&argRelocStubList);    /* initialize the stack unwind list */    lstInit (&unwindList);    /* perform linker fixups on each subspace */    for (ix = 0; ix < nSubs; ix ++, pSubspace++)        {        if (!pSubspace->is_loadable)            {            DBG_PUT ("linker: skipping fixups for unloadable subspace\n");            continue;            }        if (pSubspace->fixup_request_quantity == 0)            {            continue;            }        DBG_PUT ("\n\n\nsubSpace: 0x%x - 0x%x\n", (int)(pSubInfo[ix].loadAddr),                 (int)(pSubInfo[ix].loadAddr) + pSubspace->subspace_length);        /* Initialize the long branch stub list for this subspace to be empty */        lstFree (&stubList);        pLongBranchStubs = pSubInfo[ix].loadAddr +                           pSubspace->subspace_length;        pLongBranchStubs = (char *)ROUND_UP (pLongBranchStubs,                           pSubspace->alignment);        /* get the starting address for this subspace */        relAdr = (pSubInfo + ix)->loadAddr;        /* get the list of fixup requests for this subspace */        pThisFixup = pRelCmds + pSubspace->fixup_request_index;        pLastFixup = pThisFixup + pSubspace->fixup_request_quantity;        /* set some default modes */        modeSel = R_N_MODE;	/* default rounding mode for each subspace */        fieldSel = R_FSEL;      /* default field selector. XXX - needed? */        dataOverride = FALSE;        fieldOverride = FALSE;        usingPrevFixup = FALSE;        sp = pExpStack;		/* each subspace starts with a fresh                                 * expression stack. XXX - added */        /* process this subspaces fixups in a huge switch statement */        while (pThisFixup < pLastFixup)            {            opCode = *pThisFixup;            DBG_PUT ("opCode (0x%x) = %d. relAdr = 0x%x.\n", (int)pThisFixup,                     opCode, (int)relAdr);            /* keep track of the last 4 multibyte fixup requests */            if (fixupLen[opCode] > 1)                {                pPrevFixupNode = (PREV_FIXUP *)lstNth (&prevFixupList, 4);                lstDelete (&prevFixupList, &(pPrevFixupNode->node));                pPrevFixupNode->pFixup = pThisFixup;                lstInsert (&prevFixupList, NULL, &(pPrevFixupNode->node));                }            pThisFixup++;            /* perform the fixup based on the opCode */            if (/* opCode >= R_NO_RELOCATION && */ opCode < R_ZEROES )                {                /* 00-1f: n words, not relocatable */                if (opCode < 24)                    {                    D = opCode - R_NO_RELOCATION;                    L = (D + 1) * 4;                    }                else if (opCode >= 24 && opCode < 28)                    {                    D = opCode - 24;                    L = ((D << 8) + B1 + 1) * 4;                    }                else if (opCode >= 28 && opCode < 31)                    {                    D = opCode - 28;                    L = ((D << 16) + B2 + 1) * 4;                    }                else                    {                    D = opCode - 31;                    L = B3 + 1;                    }                DBG_PUT ("R_NO_RELOCATION: 0x%x bytes\n", L);                relAdr += L;                }            else if (opCode >= R_ZEROES && opCode < R_UNINIT)                {                /* 20-21: n words, all zero */                if (opCode == R_ZEROES)                    {                    L = (B1 + 1) * 4;                    }                else                    {                    L = B3 + 1;                    }                /* insert L bytes zero */                bufSize = (int)(pSubInfo+ix)->loadAddr +                        pSubspace->subspace_length - (int)relAdr;                tmpBuf = malloc (bufSize);                 if (tmpBuf == NULL)                        printErr ("ld error: reloc malloc failed\n");                DBG_PUT ("inserting %d zeros at 0x%x\n",                            L, (int)relAdr);                bcopy (relAdr, tmpBuf, bufSize);                bzero (relAdr, L);                relAdr += L;                bcopy (tmpBuf, relAdr, bufSize - L);                free ((char *) tmpBuf);                }            else if (opCode >= R_UNINIT && opCode < R_RELOCATION)                {                /* 22-23: n words, uninitialized */                if (opCode == R_UNINIT)                    {                    L = (B1 + 1) * 4;                    }                else                    {                    L = B3 + 1;                    }                /* skip L bytes */                bufSize = (int)(pSubInfo+ix)->loadAddr +                                pSubspace->subspace_length - (int)relAdr;                tmpBuf = malloc (bufSize);                 if (tmpBuf == NULL)                        printErr ("ld error: reloc malloc failed\n");                DBG_PUT ("skipping %d bytes at 0x%x.\n", L, (int)relAdr);                bcopy ((char *) relAdr, tmpBuf, bufSize);                bzero (relAdr, L);                relAdr += L;                bcopy (tmpBuf, relAdr, bufSize - L);                free ((char *) tmpBuf);                }            else if (opCode == R_RELOCATION)                {	/* XXX - untested */                /* 24: 1 word relocatable data */                relValue = *(int *)relAdr + (int)(pSubInfo[ix].loadAddr);                *((unsigned int *)(relAdr)) = relValue;                WARN ("Warning: R_RELOCATION fixup is untested\n");                WARN ("address = 0x%x\n", (int)relAdr);                relAdr += 4;                }            else if (opCode >= R_DATA_ONE_SYMBOL && opCode < R_DATA_PLABEL)                {                /* 25-26: 1 word, data external reference */                if (opCode == R_DATA_ONE_SYMBOL)                    {                    S = B1;                    }                else                    {                    S = B3;                    }                relValue = *(int *)relAdr + (pSym + S)->symbol_value;                *((int *)relAdr) = relValue;                DBG_PUT ("R_DATA_ONE_SYMBOL: relAdr = 0x%x\n", (int)relAdr);                relAdr +=4;                }            else if (opCode >= R_DATA

⌨️ 快捷键说明

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