diff --git a/src/Makefile b/src/Makefile index d7564e5..ed49762 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,14 @@ CPPFLAGS = \ $(MRUBY_FLAGS) \ -DKERNAUX_DEBUG \ -OBJS = multiboot2.c.o start.S.o main.c.o libc.c.o logger.c.o panic.c.o +OBJS = \ + libc.c.o \ + logger.c.o \ + main.c.o \ + multiboot2.c.o \ + panic.c.o \ + stack_trace.c.o \ + start.S.o all: $(MRUBYVISOR) diff --git a/src/main.c b/src/main.c index 2b1db4a..38b0c5d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include "libc.h" #include "logger.h" #include "panic.h" +#include "stack_trace.h" #include #include @@ -17,7 +18,6 @@ static mrb_state *mrb = NULL; static mrbc_context *context = NULL; -static void load_elf_symbols(const struct KernAux_Multiboot2_Info *multiboot2_info); static bool load_module(const char *source, size_t size, const char *cmdline); static mrb_value ruby_console_puts(mrb_state *mrb, mrb_value self); @@ -32,7 +32,7 @@ void main( ASSERT(multiboot2_info_magic == KERNAUX_MULTIBOOT2_INFO_MAGIC); ASSERT(KernAux_Multiboot2_Info_is_valid(multiboot2_info)); - load_elf_symbols(multiboot2_info); + stack_trace_init(multiboot2_info); ASSERT(mrb = mrb_open()); ASSERT(context = mrbc_context_new(mrb)); @@ -71,101 +71,6 @@ void main( } } -#include - -struct SectionEntry { - uint32_t name; - uint32_t type; - uint32_t flags; - uint32_t vaddr; - uint32_t file_offset; - uint32_t file_size; - uint32_t link; - uint32_t info; - uint32_t alignment; - uint32_t ent_size; -} -KERNAUX_PACKED; - -#include - -void load_elf_symbols( - const struct KernAux_Multiboot2_Info *const multiboot2_info -) { - const struct KernAux_Multiboot2_ITag_ELFSymbols *const elf_symbols_tag = - (const struct KernAux_Multiboot2_ITag_ELFSymbols*) - KernAux_Multiboot2_Info_first_tag_with_type( - multiboot2_info, - KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS - ); - - if (!elf_symbols_tag) { - kernaux_drivers_console_puts("ELF symbols tag not found"); - return; - } - - const struct SectionEntry *const section_headers = - // FIXME: GRUB 2 doesn't conform the spec! - // https://www.mail-archive.com/grub-devel@gnu.org/msg30790.html - // (const struct SectionEntry*)KERNAUX_MULTIBOOT2_DATA(elf_symbols_tag); - (const struct SectionEntry*)(&((uint8_t*)elf_symbols_tag)[20]); - - kernaux_drivers_console_puts("ELF symbols tag:"); - KernAux_Multiboot2_ITag_ELFSymbols_print( - elf_symbols_tag, - kernaux_drivers_console_printf - ); - kernaux_drivers_console_printf(" data: 0x%p\n", (void*)section_headers); - kernaux_drivers_console_putc('\n'); - - const struct SectionEntry *const shstrtab = - // FIXME: GRUB 2 doesn't conform the spec! - // https://www.mail-archive.com/grub-devel@gnu.org/msg30790.html - // §ion_headers[elf_symbols_tag->shndx]; - §ion_headers[(uint32_t)(((uint8_t*)elf_symbols_tag)[16])]; - - if (shstrtab == section_headers) return; - - size_t debug_info_index = 0; - size_t debug_abbrev_index = 0; - size_t debug_str_index = 0; - - for (size_t index = 0; index < elf_symbols_tag->num; ++index) { - const struct SectionEntry *const section_header = - §ion_headers[index]; - - const char *const section_name = - &((const char*)shstrtab->vaddr)[section_header->name]; - - kernaux_drivers_console_printf("section %lu: %s\n", - index, section_name); - - if (strcmp(section_name, ".debug_info") == 0) { - debug_info_index = index; - } else if (strcmp(section_name, ".debug_abbrev") == 0) { - debug_abbrev_index = index; - } else if (strcmp(section_name, ".debug_str") == 0) { - debug_str_index = index; - } - } - - kernaux_drivers_console_putc('\n'); - - kernaux_drivers_console_printf(".debug_info: %lu\n", debug_info_index); - kernaux_drivers_console_printf(".debug_abbrev: %lu\n", debug_abbrev_index); - kernaux_drivers_console_printf(".debug_str: %lu\n", debug_str_index); - kernaux_drivers_console_putc('\n'); - - if (!debug_info_index || !debug_abbrev_index || !debug_str_index) return; - - const struct SectionEntry *const debug_info = - §ion_headers[debug_info_index]; - const struct SectionEntry *const debug_abbrev = - §ion_headers[debug_abbrev_index]; - const struct SectionEntry *const debug_str = - §ion_headers[debug_str_index]; -} - bool load_module( const char *const source, const size_t size, diff --git a/src/stack_trace.c b/src/stack_trace.c new file mode 100644 index 0000000..a67f9db --- /dev/null +++ b/src/stack_trace.c @@ -0,0 +1,102 @@ +#include "stack_trace.h" + +#include + +#include +#include + +#include + +struct SectionEntry { + uint32_t name; + uint32_t type; + uint32_t flags; + uint32_t vaddr; + uint32_t file_offset; + uint32_t file_size; + uint32_t link; + uint32_t info; + uint32_t alignment; + uint32_t ent_size; +} +KERNAUX_PACKED; + +#include + +void stack_trace_init( + const struct KernAux_Multiboot2_Info *const multiboot2_info +) { + const struct KernAux_Multiboot2_ITag_ELFSymbols *const elf_symbols_tag = + (const struct KernAux_Multiboot2_ITag_ELFSymbols*) + KernAux_Multiboot2_Info_first_tag_with_type( + multiboot2_info, + KERNAUX_MULTIBOOT2_ITAG_ELF_SYMBOLS + ); + + if (!elf_symbols_tag) { + kernaux_drivers_console_puts("ELF symbols tag not found"); + return; + } + + const struct SectionEntry *const section_headers = + // FIXME: GRUB 2 doesn't conform the spec! + // https://www.mail-archive.com/grub-devel@gnu.org/msg30790.html + // (const struct SectionEntry*)KERNAUX_MULTIBOOT2_DATA(elf_symbols_tag); + (const struct SectionEntry*)(&((uint8_t*)elf_symbols_tag)[20]); + + kernaux_drivers_console_puts("ELF symbols tag:"); + KernAux_Multiboot2_ITag_ELFSymbols_print( + elf_symbols_tag, + kernaux_drivers_console_printf + ); + kernaux_drivers_console_printf(" data: 0x%p\n", (void*)section_headers); + kernaux_drivers_console_putc('\n'); + + const struct SectionEntry *const shstrtab = + // FIXME: GRUB 2 doesn't conform the spec! + // https://www.mail-archive.com/grub-devel@gnu.org/msg30790.html + // §ion_headers[elf_symbols_tag->shndx]; + §ion_headers[(uint32_t)(((uint8_t*)elf_symbols_tag)[16])]; + + if (shstrtab == section_headers) return; + + size_t debug_info_index = 0; + size_t debug_abbrev_index = 0; + size_t debug_str_index = 0; + + for (size_t index = 0; index < elf_symbols_tag->num; ++index) { + const struct SectionEntry *const section_header = + §ion_headers[index]; + + const char *const section_name = + &((const char*)shstrtab->vaddr)[section_header->name]; + + kernaux_drivers_console_printf("section %lu: %s\n", + index, section_name); + + if (strcmp(section_name, ".debug_info") == 0) { + debug_info_index = index; + } else if (strcmp(section_name, ".debug_abbrev") == 0) { + debug_abbrev_index = index; + } else if (strcmp(section_name, ".debug_str") == 0) { + debug_str_index = index; + } + } + + kernaux_drivers_console_putc('\n'); + + kernaux_drivers_console_printf(".debug_info: %lu\n", debug_info_index); + kernaux_drivers_console_printf(".debug_abbrev: %lu\n", debug_abbrev_index); + kernaux_drivers_console_printf(".debug_str: %lu\n", debug_str_index); + kernaux_drivers_console_putc('\n'); + + if (!debug_info_index || !debug_abbrev_index || !debug_str_index) return; +/* + const struct SectionEntry *const debug_info = + §ion_headers[debug_info_index]; + const struct SectionEntry *const debug_abbrev = + §ion_headers[debug_abbrev_index]; + const struct SectionEntry *const debug_str = + §ion_headers[debug_str_index]; +*/ +} diff --git a/src/stack_trace.h b/src/stack_trace.h new file mode 100644 index 0000000..87c17bb --- /dev/null +++ b/src/stack_trace.h @@ -0,0 +1,8 @@ +#ifndef INCLUDED_STACK_TRACE +#define INCLUDED_STACK_TRACE + +#include + +void stack_trace_init(const struct KernAux_Multiboot2_Info *multiboot2_info); + +#endif