src/debugger/stack-trace.c (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/internal/debugger/stack-trace.h>
7
8#include <mgba/core/core.h>
9
10DEFINE_VECTOR(mStackFrames, struct mStackFrame);
11
12void mStackTraceInit(struct mStackTrace* stack, size_t registersSize) {
13 mStackFramesInit(&stack->stack, 0);
14}
15
16void mStackTraceDeinit(struct mStackTrace* stack) {
17 mStackTraceClear(stack);
18 mStackFramesDeinit(&stack->stack);
19}
20
21void mStackTraceClear(struct mStackTrace* stack) {
22 ssize_t i = mStackTraceGetDepth(stack) - 1;
23 while (i >= 0) {
24 free(mStackTraceGetFrame(stack, i)->regs);
25 --i;
26 }
27}
28
29size_t mStackTraceGetDepth(struct mStackTrace* stack) {
30 return mStackFramesSize(&stack->stack);
31}
32
33struct mStackFrame* mStackTracePush(struct mStackTrace* stack, uint32_t instruction, uint32_t pc, uint32_t destAddress, uint32_t sp, void* regs) {
34 struct mStackFrame* frame = mStackFramesAppend(&stack->stack);
35 frame->instruction = instruction;
36 frame->callAddress = pc;
37 frame->entryAddress = destAddress;
38 frame->frameBaseAddress = sp;
39 frame->regs = malloc(stack->registersSize);
40 frame->finished = false;
41 frame->breakWhenFinished = false;
42 memcpy(frame->regs, regs, stack->registersSize);
43 return frame;
44}
45
46struct mStackFrame* mStackTraceGetFrame(struct mStackTrace* stack, size_t frame) {
47 size_t depth = mStackTraceGetDepth(stack);
48 if (frame >= depth) {
49 return NULL;
50 }
51 return mStackFramesGetPointer(&stack->stack, depth - frame - 1);
52}
53
54void mStackTracePop(struct mStackTrace* stack) {
55 size_t depth = mStackTraceGetDepth(stack);
56 if (depth == 0) {
57 return;
58 }
59 struct mStackFrame* frame = mStackFramesGetPointer(&stack->stack, depth - 1);
60 free(frame->regs);
61 mStackFramesResize(&stack->stack, depth - 1);
62}