all repos — mgba @ fadd0391d6f2b143a470c97d6ae129346a789239

mGBA Game Boy Advance Emulator

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}