:: limine / common / lib / trace.s2.c 2.0 KB raw

1
#include <stddef.h>
2
#include <stdint.h>
3
#include <lib/trace.h>
4
#include <lib/misc.h>
5
#include <lib/config.h>
6
#include <lib/print.h>
7
#include <lib/uri.h>
8
#include <fs/file.h>
9
#include <mm/pmm.h>
10
11
#if defined (BIOS)
12
extern symbol stage2_map;
13
#elif defined (UEFI)
14
extern symbol __slide;
15
#endif
16
17
extern symbol full_map;
18
19
static char *trace_address(size_t *off, size_t addr) {
20
    char *limine_map;
21
22
#if defined (BIOS)
23
    if (!stage3_loaded)
24
        limine_map = stage2_map;
25
    else
26
        limine_map = full_map;
27
#elif defined (UEFI)
28
    limine_map = full_map;
29
30
    addr -= (size_t)__slide;
31
#endif
32
33
    uintptr_t prev_addr = 0;
34
    char     *prev_sym  = NULL;
35
36
    for (size_t i = 0;;) {
37
        if (*((uintptr_t *)&limine_map[i]) >= addr) {
38
            *off = addr - prev_addr;
39
            return prev_sym;
40
        }
41
        prev_addr = *((uintptr_t *)&limine_map[i]);
42
        i += sizeof(uintptr_t);
43
        prev_sym  = &limine_map[i];
44
        while (limine_map[i++] != 0);
45
    }
46
}
47
48
void print_stacktrace(size_t *base_ptr) {
49
    if (base_ptr == NULL) {
50
        asm volatile (
51
#if defined (__i386__)
52
            "movl %%ebp, %0"
53
#elif defined (__x86_64__)
54
            "movq %%rbp, %0"
55
#elif defined (__aarch64__)
56
            "mov %0, x29"
57
#elif defined (__riscv)
58
            "mv %0, fp;  addi %0, %0, -16"
59
#elif defined (__loongarch64)
60
            "move %0, $fp;  addi.d %0, %0, -16"
61
#endif
62
            : "=r"(base_ptr)
63
            :: "memory"
64
        );
65
    }
66
    print("Stacktrace:\n");
67
    for (;;) {
68
        size_t old_bp = base_ptr[0];
69
        size_t ret_addr = base_ptr[1];
70
        if (!ret_addr)
71
            break;
72
        size_t off;
73
        char *name = trace_address(&off, ret_addr);
74
        if (name)
75
            print("  [%p] <%s+%p>\n", ret_addr, name, off);
76
        else
77
            print("  [%p]\n", ret_addr);
78
        if (!old_bp)
79
            break;
80
#if defined (__riscv) || defined (__loongarch64)
81
        base_ptr = (void *)(old_bp - 16);
82
#else
83
        base_ptr = (void*)old_bp;
84
#endif
85
    }
86
    print("End of trace. ");
87
}
tab: 248 wrap: offon