mirror of https://github.com/tailix/libkernaux.git
77 lines
1.6 KiB
C
77 lines
1.6 KiB
C
/**
|
|
* The code was inspired by the Limine bootloader.
|
|
*
|
|
* Copyright (c) 2020-2022 mintsuki
|
|
* Copyright (c) 2022 Alex Kotov
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <kernaux/assert.h>
|
|
#include <kernaux/macro.h>
|
|
#include <kernaux/stack_trace.h>
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create()
|
|
{
|
|
struct KernAux_StackTrace_Frame frame = { .cur_ptr = NULL };
|
|
|
|
#if defined(ASM_I386)
|
|
const size_t *cur_ptr;
|
|
KERNAUX_ASM("movl %%ebp, %0" : "=g" (cur_ptr) :: "memory");
|
|
frame.cur_ptr = cur_ptr;
|
|
#elif defined(ASM_X86_64)
|
|
const size_t *cur_ptr;
|
|
KERNAUX_ASM("movq %%rbp, %0" : "=g" (cur_ptr) :: "memory");
|
|
frame.cur_ptr = cur_ptr;
|
|
#endif
|
|
|
|
return frame;
|
|
}
|
|
|
|
bool KernAux_StackTrace_Frame_has_next(const KernAux_StackTrace_Frame frame)
|
|
{
|
|
KERNAUX_ASSERT(frame);
|
|
|
|
if (!frame->cur_ptr) return false;
|
|
|
|
#if defined(ASM_X86)
|
|
const size_t *const cur_ptr = frame->cur_ptr;
|
|
return cur_ptr[1];
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
void KernAux_StackTrace_Frame_use_next(const KernAux_StackTrace_Frame frame)
|
|
{
|
|
KERNAUX_ASSERT(frame);
|
|
|
|
if (!frame->cur_ptr) return;
|
|
|
|
#if defined(ASM_X86)
|
|
const size_t *const cur_ptr = frame->cur_ptr;
|
|
frame->cur_ptr = (const void*)cur_ptr[0];
|
|
#endif
|
|
}
|
|
|
|
const void *KernAux_StackTrace_Frame_get_ptr(
|
|
const KernAux_StackTrace_Frame frame
|
|
) {
|
|
KERNAUX_ASSERT(frame);
|
|
|
|
if (!frame->cur_ptr) return NULL;
|
|
|
|
#if defined(ASM_X86)
|
|
const size_t *const cur_ptr = frame->cur_ptr;
|
|
return (const void*)cur_ptr[1];
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|