1/**
2 * \file
3 * \brief Arch specific debugging functions
4 */
5
6/*
7 * Copyright (c) 2010, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdio.h>
16#include <barrelfish/barrelfish.h>
17#include <barrelfish/caddr.h>
18#include <barrelfish/debug.h>
19#include <barrelfish/dispatch.h>
20#include <if/monitor_defs.h>
21#include <stdarg.h>
22#include <stdlib.h>
23#include <string.h>
24#include <inttypes.h>
25
26#define NR_OF_DISPLAYED_RET_ADDRS   10
27
28/**
29 * \brief Dump out various memory regions and a partial backtrace.
30 *
31 * Mainly for debugging traps and faults in the dispatcher handlers.
32 */
33void debug_dump(arch_registers_state_t *archregs)
34{
35    struct registers_x86_64 *regs = archregs;
36
37    debug_printf("Dumping stack (0x%lx)...\n", regs->rsp);
38    debug_dump_mem_around_addr(regs->rsp);
39    // debug_printf("Dumping code (0x%lx)...\n", regs->rip);
40    // debug_dump_mem_around_addr(regs->rip);
41    // debug_printf("Dumping memory around rbp (0x%lx)\n", regs->rbp);
42    // debug_dump_mem_around_addr(regs->rbp);
43}
44
45static void debug_call_chain_rbp(uintptr_t bp)
46{
47    uintptr_t ret_addr;
48    uintptr_t user_rbp = bp;
49
50    for (int it = 0; it < NR_OF_DISPLAYED_RET_ADDRS; it++) {
51        if (user_rbp < BASE_PAGE_SIZE || (user_rbp % sizeof(uintptr_t)) != 0) {
52            break;
53        }
54        // get return address
55        ret_addr = *(uintptr_t *)(user_rbp + sizeof(uintptr_t));
56        debug_printf("return address = 0x%" PRIxPTR "\n", ret_addr);
57        // get next RBP
58        user_rbp = *(uintptr_t *)user_rbp;
59    }
60}
61
62void debug_call_chain(arch_registers_state_t *archregs)
63{
64    debug_call_chain_rbp(archregs->rbp);
65}
66
67/**
68 * \brief Print out the registers in a dispatcher save area, for trap handlers.
69 */
70void debug_print_save_area(arch_registers_state_t *state)
71{
72//#define P(x) debug_printf("%16lx "#x"\n", (uintptr_t)state->x);
73#define P(x) printf("%16lx "#x"\n", (uintptr_t)state->x);
74
75    P(rip);
76    P(rsp);
77    P(rbp);
78    P(rax);
79    P(rbx);
80    P(rcx);
81    P(rdx);
82    P(rdi);
83    P(rsi);
84    P(r8);
85    P(r9);
86    P(r10);
87    P(r11);
88    P(r12);
89    P(r13);
90    P(r14);
91    P(r15);
92    P(eflags);
93    P(fs);
94    P(gs);
95
96#undef P
97    printf("mxcsr: %04x  mxcsr_mask: %04x\n", state->fxsave_area.mxcsr, state->fxsave_area.mxcsr_mask);
98#define PXMM(x)     printf("xmm"#x" : %016lx%016lx\n", state->fxsave_area.xmm[x][1], state->fxsave_area.xmm[x][0])
99    PXMM(0);
100    PXMM(1);
101    PXMM(2);
102    PXMM(3);
103    PXMM(4);
104    PXMM(5);
105    PXMM(6);
106    PXMM(7);
107    PXMM(8);
108    PXMM(9);
109    PXMM(10);
110    PXMM(11);
111    PXMM(12);
112    PXMM(13);
113    PXMM(14);
114    PXMM(15);
115#undef PXMM
116}
117
118void debug_return_addresses(void)
119{
120    printf("return address = %p\n", __builtin_return_address(0));
121    printf("return address = %p\n", __builtin_return_address(1));
122    printf("return address = %p\n", __builtin_return_address(2));
123    printf("return address = %p\n", __builtin_return_address(3));
124    printf("return address = %p\n", __builtin_return_address(4));
125}
126