static bool advanceCursor(KSStackCursor *cursor) { MachineContextCursor* context = (MachineContextCursor*)cursor->context; uintptr_t nextAddress = 0; if(cursor->state.currentDepth >= context->maxStackDepth) { cursor->state.hasGivenUp = true; return false; } if(context->instructionAddress == 0) { context->instructionAddress = kscpu_instructionAddress(context->machineContext); if(context->instructionAddress == 0) { return false; } nextAddress = context->instructionAddress; goto successfulExit; } if(context->linkRegister == 0 && !context->isPastFramePointer) { // Link register, if available, is the second address in the trace. context->linkRegister = kscpu_linkRegister(context->machineContext); if(context->linkRegister != 0) { nextAddress = context->linkRegister; goto successfulExit; } } if(context->currentFrame.previous == NULL) { if(context->isPastFramePointer) { return false; } context->currentFrame.previous = (struct FrameEntry*)kscpu_framePointer(context->machineContext); context->isPastFramePointer = true; } if(!ksmem_copySafely(context->currentFrame.previous, &context->currentFrame, sizeof(context->currentFrame))) { return false; } if(context->currentFrame.previous == 0 || context->currentFrame.return_address == 0) { return false; } nextAddress = context->currentFrame.return_address; successfulExit: cursor->stackEntry.address = kscpu_normaliseInstructionPointer(nextAddress); cursor->state.currentDepth++; return true; }
static bool advanceCursor(KSStackCursor *cursor) { MachineContextCursor* cursorContext = (MachineContextCursor*)cursor->context; if(cursor->state.currentDepth >= cursor->state.maxDepth) { return false; } if(cursorContext->instructionAddress == 0) { return false; } if(cursorContext->linkRegister == 0 && !cursorContext->isPastFramePointer) { // Link register, if available, is the second address in the trace. cursorContext->linkRegister = kscpu_linkRegister(cursorContext->machineContext); if(cursorContext->linkRegister != 0) { cursor->stackEntry.address = cursorContext->linkRegister; cursor->state.currentDepth++; return true; } } if(cursorContext->currentFrame.previous == NULL) { if(cursorContext->isPastFramePointer) { return false; } cursorContext->currentFrame.previous = (struct FrameEntry*)kscpu_framePointer(cursorContext->machineContext); cursorContext->isPastFramePointer = true; } if(!ksmem_copySafely(cursorContext->currentFrame.previous, &cursorContext->currentFrame, sizeof(cursorContext->currentFrame))) { return false; } if(cursorContext->currentFrame.previous == 0 || cursorContext->currentFrame.return_address == 0) { return false; } cursor->stackEntry.address = cursorContext->currentFrame.return_address; cursor->state.currentDepth++; return true; }