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

📄 mipsuwnd.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 3 页
字号:
        ControlPc = FunctionEntry->PrologEndAddress;        DEBUGMSG(ZONE_SEH,(L"RtlVirtualUnwind: within function, new ControPc=%x\r\n", ControlPc));    }    // Allocate an array of OPERATION's that will hold the entire prologue.    // Note that the prologue may include the body of a helper function. If this is the case,    // the call and return won't be stored in Ops, so we add the size of the largest    // prologue helper, minus the call to and return from the helper.    OpCount = BYTES_TO_OPCOUNT(FunctionEntry->BeginAddress, ControlPc) + MIPS_PROLHELPER_OPCOUNT(ControlPc) - 2;    Ops = (POPERATION) _alloca(OpCount * sizeof(OPERATION));    // Build an operation list of all instructions from the function start    // to the control PC.    OpCount = BuildOps (Ops, OpCount, FunctionEntry->BeginAddress, ControlPc);    DEBUGMSG(ZONE_SEH,(L"RtlVirtualUnwind: build op list with %d elements\r\n", OpCount));    // We were unable to build the op list    if (OpCount < 0) {        return 0;    }    NextPc = Reverse (Ops, OpCount, ContextRecord);    DEBUGMSG(ZONE_SEH,(L"Reverse executed RA=%x SP=%x\r\n", ContextRecord->IntRa, ContextRecord->IntSp));        *EstablisherFrame = ContextRecord->IntSp;    // Make sure that integer register zero is really zero.    ContextRecord->IntZero = 0;    return NextPc;}#else#define INST_SIZE   4// Define saved register masks.#define SAVED_FLOATING_MASK 0xfff00000  // saved floating registers#define SAVED_INTEGER_MASK 0xf3ffff02   // saved integer registersULONGRtlVirtualUnwind(    IN ULONG ControlPc,    IN PRUNTIME_FUNCTION FunctionEntry,    IN OUT PCONTEXT ContextRecord,    OUT PBOOLEAN InFunction,    OUT PULONG EstablisherFrame)/*++Routine Description:    This function virtually unwinds the specfified function by executing its    prologue code backwards.    If the function is a leaf function, then the address where control left    the previous frame is obtained from the context record. If the function    is a nested function, but not an exception or interrupt frame, then the    prologue code is executed backwards and the address where control left    the previous frame is obtained from the updated context record.    Otherwise, an exception or interrupt entry to the system is being unwound    and a specially coded prologue restores the return address twice. Once    from the fault instruction address and once from the saved return address    register. The first restore is returned as the function value and the    second restore is place in the updated context record.    If a context pointers record is specified, then the address where each    nonvolatile registers is restored from is recorded in the appropriate    element of the context pointers record.Arguments:    ControlPc - Supplies the address where control left the specified        function.    FunctionEntry - Supplies the address of the function table entry for the        specified function.    ContextRecord - Supplies the address of a context record.    InFunction - Supplies a pointer to a variable that receives whether the        control PC is within the current function.    EstablisherFrame - Supplies a pointer to a variable that receives the        the establisher frame pointer value.    ContextPointers - Supplies an optional pointer to a context pointers        record.Return Value:    The address where control left the previous frame is returned as the    function value.--*/{    ULONG Address;    ULONG DecrementOffset;    ULONG DecrementRegister;    PULONG FloatingRegister;    ULONG Function;    MIPS_INSTRUCTION Instruction;    PULONG IntegerRegister;    ULONG NextPc;    LONG Offset;    ULONG Opcode;    ULONG Rd;    BOOLEAN RestoredRa;    BOOLEAN RestoredSp;    ULONG Rs;    ULONG Rt;    // Set the base address of the integer and floating register arrays.    FloatingRegister = &ContextRecord->FltF0;    IntegerRegister = &ContextRecord->IntZero;    *InFunction = FALSE;    // If the instruction at the point where control left the specified    // function is a return, then any saved registers have been restored    // with the possible exception of the stack pointer and the control    // PC is not considered to be in the function (i.e., an epilogue).    if (*((PULONG)ControlPc) == JUMP_RA) {        Instruction.Long = *((PULONG)ControlPc + 1);        Opcode = Instruction.i_format.Opcode;        Offset = Instruction.i_format.Simmediate;        Rd = Instruction.r_format.Rd;        Rs = Instruction.i_format.Rs;        Rt = Instruction.i_format.Rt;        Function = Instruction.r_format.Function;        // If the opcode is an add immediate unsigned op and both the source        // and destination registers are SP, then add the signed offset value        // to SP. Otherwise, if the opcode is a special op, the operation is        // an add unsigned, and the source and destination registers are both        // SP, then add the register specified by Rd to SP.        if ((Opcode == ADDIU_OP) && (Rt == SP) && (Rs == SP)) {            IntegerRegister[SP] += Offset;        } else if ((Opcode == SPEC_OP) && (Function == ADDU_OP) &&                   (Rd == SP) && (Rs == SP)) {            IntegerRegister[SP] += IntegerRegister[Rt];        }        *EstablisherFrame = ContextRecord->IntSp;        return ContextRecord->IntRa - INST_SIZE;    }    // If the address where control left the specified function is outside    // the limits of the prologue, then the control PC is considered to be    // within the function and the control address is set to the end of    // the prologue. Otherwise, the control PC is not considered to be    // within the function (i.e., it is within the prologue).    if ((ControlPc < FunctionEntry->BeginAddress) ||        (ControlPc >= FunctionEntry->PrologEndAddress)) {        *InFunction = TRUE;        ControlPc = FunctionEntry->PrologEndAddress;    }    // Scan backward through the prologue and reload callee registers that    // were stored.    DecrementRegister = 0;    *EstablisherFrame = ContextRecord->IntSp;    NextPc = ContextRecord->IntRa - INST_SIZE;    RestoredRa = FALSE;    RestoredSp = FALSE;    while (ControlPc > FunctionEntry->BeginAddress) {        // Get instruction value, decode fields, case of opcode value, and        // reverse store operations.        ControlPc -= INST_SIZE;        Instruction.Long = *((PULONG)ControlPc);        Opcode = Instruction.i_format.Opcode;        Offset = Instruction.i_format.Simmediate;        Rd = Instruction.r_format.Rd;        Rs = Instruction.i_format.Rs;        Rt = Instruction.i_format.Rt;        Address = Offset + IntegerRegister[Rs];        if (Opcode == SW_OP) {            // Store word.            //            // If the base register is SP and the source register is an            // integer register, then reload the register value.            if (Rs == SP) {                IntegerRegister[Rt] = *((PULONG)Address);                // If the destination register is RA and this is the first                // time that RA is being restored, then set the address of                // where control left the previous frame. Otherwise, this                // is an interrupt or exception and the return PC should be                // biased by INST_SIZE. Otherwise, if the destination register is                // SP and this is the first time that SP is being restored,                // then set the establisher frame pointer.                if (Rt == RA) {                    if (RestoredRa == FALSE) {                        NextPc = ContextRecord->IntRa - INST_SIZE;                        RestoredRa = TRUE;                    } else                        NextPc += INST_SIZE;                } else if (Rt == SP) {                    if (RestoredSp == FALSE) {                        *EstablisherFrame = ContextRecord->IntSp;                        RestoredSp = TRUE;                    }                }            }        } else if (Opcode == SWC1_OP) {            // Store word coprocessor 1.            //            // If the base register is SP and the source register is a            // floating register, then reload the register value.            if (Rs == SP) {                FloatingRegister[Rt] = *((PULONG)Address);            }        } else if (Opcode == SDC1_OP) {            // Store double coprocessor 1.            //            // If the base register is SP and the source register is a            // floating register, then reload the register and the next            // register values.            if (Rs == SP) {                FloatingRegister[Rt] = *((PULONG)Address);                FloatingRegister[Rt + 1] = *((PULONG)(Address + 4));            }        } else if (Opcode == ADDIU_OP) {            // Add immediate unsigned.            //            // If both the source and destination registers are SP, then            // a standard stack allocation was performed and the signed            // displacement value should be subtracted from SP. Otherwise,            // if the destination register is the decrement register and            // the source register is zero, then add the decrement value            // to SP.            if ((Rs == SP) && (Rt == SP)) {                IntegerRegister[SP] -= Offset;                if (RestoredSp == FALSE) {                    *EstablisherFrame = ContextRecord->IntSp;                    RestoredSp = TRUE;                }            } else if ((Rt == DecrementRegister) && (Rs == ZERO)) {                IntegerRegister[SP] += Offset;                if (RestoredSp == FALSE) {                    *EstablisherFrame = ContextRecord->IntSp;                    RestoredSp = TRUE;                }            }        } else if (Opcode == ORI_OP) {            // Or immediate.            //            // If both the destination and source registers are the decrement            // register, then save the decrement value. Otherwise, if the            // destination register is the decrement register and the source            // register is zero, then add the decrement value to SP.            if ((Rs == DecrementRegister) && (Rt == DecrementRegister)) {                DecrementOffset = (Offset & 0xffff);            } else if ((Rt == DecrementRegister) && (Rs == ZERO)) {                IntegerRegister[SP] += (Offset & 0xffff);                if (RestoredSp == FALSE) {                    *EstablisherFrame = ContextRecord->IntSp;                    RestoredSp = TRUE;                }            }        } else if (Opcode == SPEC_OP) {            // Special operation.            //            // The real opcode is in the function field of special opcode            // instructions.            Function = Instruction.r_format.Function;            if ((Function == ADDU_OP) || (Function == OR_OP)) {                // Add unsigned or an or operation.                //                // If one of the source registers is ZERO, then the                // operation is a move operation and the destination                // register should be moved to the appropriate source                // register.                if (Rt == ZERO) {                    IntegerRegister[Rs] = IntegerRegister[Rd];                    // If the destination register is RA and this is the                    // first time that RA is being restored, then set the                    // address of where control left the previous frame.                    // Otherwise, this an interrupt or exception and the                    // return PC should be biased by INST_SIZE.                    if (Rs == RA) {                        if (RestoredRa == FALSE) {                            NextPc = ContextRecord->IntRa - INST_SIZE;                            RestoredRa = TRUE;                        } else                            NextPc += INST_SIZE;                    }                } else if (Rs == ZERO) {                    IntegerRegister[Rt] = IntegerRegister[Rd];                    // If the destination register is RA and this is the                    // first time that RA is being restored, then set the                    // address of where control left the previous frame.                    // Otherwise, this an interrupt or exception and the                    // return PC should be biased by INST_SIZE.                    if (Rt == RA) {                        if (RestoredRa == FALSE) {                            NextPc = ContextRecord->IntRa - INST_SIZE;                            RestoredRa = TRUE;                        } else                            NextPc += INST_SIZE;                    }                }            } else if (Function == SUBU_OP) {                // Subtract unsigned.                //                // If the destination register is SP and the source register                // is SP, then a stack allocation greater than 32kb has been                // performed and source register number of the decrement must                // be saved for later use.                if ((Rd == SP) && (Rs == SP))                    DecrementRegister = Rt;            }        } else if (Opcode == LUI_OP) {            // Load upper immediate.            //            // If the destination register is the decrement register, then            // compute the decrement value, add it from SP, and clear the            // decrement register number.            if (Rt == DecrementRegister) {                DecrementRegister = 0;                IntegerRegister[SP] += (DecrementOffset + (Offset << 16));                if (RestoredSp == FALSE) {                    *EstablisherFrame = ContextRecord->IntSp;                    RestoredSp = TRUE;                }            }        }    }    // Make sure that integer register zero is really zero.    ContextRecord->IntZero = 0;    return NextPc;}#endif

⌨️ 快捷键说明

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