Exemple #1
0
static unsigned GetRegInfo1 (CodeSeg* S,
                             CodeEntry* E,
                             int Index,
                             Collection* Visited,
                             unsigned Used,
                             unsigned Unused,
                             unsigned Wanted)
/* Recursively called subfunction for GetRegInfo. */
{
    /* Remember the current count of the line collection */
    unsigned Count = CollCount (Visited);

    /* Call the worker routine */
    unsigned R = GetRegInfo2 (S, E, Index, Visited, Used, Unused, Wanted);

    /* Restore the old count, unmarking all new entries */
    unsigned NewCount = CollCount (Visited);
    while (NewCount-- > Count) {
        CodeEntry* E = CollAt (Visited, NewCount);
        CE_ResetMark (E);
        CollDelete (Visited, NewCount);
    }

    /* Return the registers used */
    return R;
}
Exemple #2
0
void CS_ResetMarks (CodeSeg* S, unsigned First, unsigned Last)
/* Remove all user marks from the entries in the given range */
{
    while (First <= Last) {
        CE_ResetMark (CS_GetEntry (S, First++));
    }
}
Exemple #3
0
int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last)
/* Check if the given code segment range is a basic block. That is, check if
 * First is the only entrance and Last is the only exit. This means that no
 * jump/branch inside the block may jump to an insn below First or after(!)
 * Last, and that no insn may jump into this block from the outside.
 */
{
    unsigned I;

    /* Don't accept invalid ranges */
    CHECK (First <= Last);

    /* First pass: Walk over the range and remove all marks from the entries */
    CS_ResetMarks (S, First, Last);

    /* Second pass: Walk over the range checking all labels. Note: There may be
     * label on the first insn which is ok.
     */
    I = First + 1;
    while (I <= Last) {

        /* Get the next entry */
        CodeEntry* E = CS_GetEntry (S, I);

        /* Check if this entry has one or more labels, if so, check which
         * entries jump to this label.
         */
        unsigned LabelCount = CE_GetLabelCount (E);
        unsigned LabelIndex;
        for (LabelIndex = 0; LabelIndex < LabelCount; ++LabelIndex) {

            /* Get this label */
            CodeLabel* L = CE_GetLabel (E, LabelIndex);

            /* Walk over all entries that jump to this label. Check for each
             * of the entries if it is out of the range.
             */
            unsigned RefCount = CL_GetRefCount (L);
            unsigned RefIndex;
            for (RefIndex = 0; RefIndex < RefCount; ++RefIndex) {

                /* Get the code entry that jumps here */
                CodeEntry* Ref = CL_GetRef (L, RefIndex);

                /* Walk over out complete range and check if we find the
                 * refering entry. This is cheaper than using CS_GetEntryIndex,
                 * because CS_GetEntryIndex will search the complete code
                 * segment and not just our range.
                 */
                unsigned J;
                for (J = First; J <= Last; ++J) {
                    if (Ref == CS_GetEntry (S, J)) {
                        break;
                    }
                }
                if (J > Last) {
                    /* We did not find the entry. This means that the jump to
                     * out code segment entry E came from outside the range,
                     * which in turn means that the given range is not a basic
                     * block.
                     */
                    CS_ResetMarks (S, First, Last);
                    return 0;
                }

                /* If we come here, we found the entry. Mark it, so we know
                 * that the branch to the label is in range.
                 */
                CE_SetMark (Ref);
            }
        }

        /* Next entry */
        ++I;
    }

    /* Third pass: Walk again over the range and check all branches. If we
     * find a branch that is not marked, its target is not inside the range
     * (since we checked all the labels in the range before).
     */
    I = First;
    while (I <= Last) {

        /* Get the next entry */
        CodeEntry* E = CS_GetEntry (S, I);

        /* Check if this is a branch and if so, if it has a mark */
        if (E->Info & (OF_UBRA | OF_CBRA)) {
            if (!CE_HasMark (E)) {
                /* No mark means not a basic block. Before bailing out, be sure
                 * to remove the marks from the remaining entries.
                 */
                CS_ResetMarks (S, I+1, Last);
                return 0;
            }

            /* Remove the mark */
            CE_ResetMark (E);
        }

        /* Next entry */
        ++I;
    }

    /* Done - this is a basic block */
    return 1;
}