misc: Implement stacktrace
This commit is contained in:
parent
36b5be1380
commit
8460cee5ca
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
|
/**/*.gen
|
||||||
|
/**/*.map
|
||||||
/**/*.o
|
/**/*.o
|
||||||
/**/*.d
|
/**/*.d
|
||||||
/**/*.a
|
/**/*.a
|
||||||
|
8
Makefile
8
Makefile
@ -8,6 +8,7 @@ all: stage2 decompressor
|
|||||||
gzip -n -9 < stage2/stage2.bin > stage2/stage2.bin.gz
|
gzip -n -9 < stage2/stage2.bin > stage2/stage2.bin.gz
|
||||||
cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin
|
cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin
|
||||||
cd pxeboot && nasm bootsect.asm -fbin -o ../limine-pxe.bin
|
cd pxeboot && nasm bootsect.asm -fbin -o ../limine-pxe.bin
|
||||||
|
cp stage2/stage2.map ./
|
||||||
|
|
||||||
clean: stage2-clean decompressor-clean test-clean
|
clean: stage2-clean decompressor-clean test-clean
|
||||||
rm -f stage2/stage2.bin.gz
|
rm -f stage2/stage2.bin.gz
|
||||||
@ -55,6 +56,7 @@ echfs-test: limine-install test.img
|
|||||||
|
|
||||||
ext2-test: limine-install test.img
|
ext2-test: limine-install test.img
|
||||||
$(MAKE) -C test
|
$(MAKE) -C test
|
||||||
|
cp stage2.map test/
|
||||||
rm -rf test_image/
|
rm -rf test_image/
|
||||||
mkdir test_image
|
mkdir test_image
|
||||||
sudo losetup -Pf --show test.img > loopback_dev
|
sudo losetup -Pf --show test.img > loopback_dev
|
||||||
@ -62,8 +64,7 @@ ext2-test: limine-install test.img
|
|||||||
sudo mkfs.ext2 `cat loopback_dev`p1
|
sudo mkfs.ext2 `cat loopback_dev`p1
|
||||||
sudo mount `cat loopback_dev`p1 test_image
|
sudo mount `cat loopback_dev`p1 test_image
|
||||||
sudo mkdir test_image/boot
|
sudo mkdir test_image/boot
|
||||||
sudo cp test/test.elf test_image/boot/
|
sudo cp -rv test/* test_image/boot/
|
||||||
sudo cp test/limine.cfg test_image/
|
|
||||||
sync
|
sync
|
||||||
sudo umount test_image/
|
sudo umount test_image/
|
||||||
sudo losetup -d `cat loopback_dev`
|
sudo losetup -d `cat loopback_dev`
|
||||||
@ -80,8 +81,7 @@ fat32-test: limine-install test.img
|
|||||||
sudo mkfs.fat -F 32 `cat loopback_dev`p1
|
sudo mkfs.fat -F 32 `cat loopback_dev`p1
|
||||||
sudo mount `cat loopback_dev`p1 test_image
|
sudo mount `cat loopback_dev`p1 test_image
|
||||||
sudo mkdir test_image/boot
|
sudo mkdir test_image/boot
|
||||||
sudo cp test/test.elf test_image/boot/
|
sudo cp -rv test/* test_image/boot/
|
||||||
sudo cp test/limine.cfg test_image/
|
|
||||||
sync
|
sync
|
||||||
sudo umount test_image/
|
sudo umount test_image/
|
||||||
sudo losetup -d `cat loopback_dev`
|
sudo losetup -d `cat loopback_dev`
|
||||||
|
@ -9,8 +9,17 @@ void entry(uint8_t *compressed_stage2, size_t stage2_size, uint8_t boot_drive, i
|
|||||||
|
|
||||||
tinf_gzip_uncompress(dest, compressed_stage2, stage2_size);
|
tinf_gzip_uncompress(dest, compressed_stage2, stage2_size);
|
||||||
|
|
||||||
__attribute__((noreturn))
|
asm volatile (
|
||||||
void (*stage2)(uint8_t boot_drive, int pxe) = (void *)dest;
|
"mov esp, 0x7c00\n\t"
|
||||||
|
"xor ebp, ebp\n\t"
|
||||||
|
"push %1\n\t"
|
||||||
|
"push %0\n\t"
|
||||||
|
"push 0\n\t"
|
||||||
|
"jmp 0x8000\n\t"
|
||||||
|
:
|
||||||
|
: "r" ((uint32_t)boot_drive), "r" (pxe)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
|
||||||
stage2(boot_drive, pxe);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
BIN
limine-pxe.bin
BIN
limine-pxe.bin
Binary file not shown.
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
@ -1,9 +1,10 @@
|
|||||||
CC = i386-elf-gcc
|
CC = i386-elf-gcc
|
||||||
LD = i386-elf-gcc
|
LD = i386-elf-gcc
|
||||||
OBJCOPY = i386-elf-objcopy
|
OBJCOPY = i386-elf-objcopy
|
||||||
|
OBJDUMP = i386-elf-objdump
|
||||||
|
|
||||||
WERROR = -Werror
|
WERROR = -Werror
|
||||||
CFLAGS = -flto -Os -pipe -Wall -Wextra $(WERROR)
|
CFLAGS = -Os -pipe -Wall -Wextra $(WERROR)
|
||||||
|
|
||||||
INTERNAL_CFLAGS = \
|
INTERNAL_CFLAGS = \
|
||||||
-std=gnu11 \
|
-std=gnu11 \
|
||||||
@ -11,7 +12,7 @@ INTERNAL_CFLAGS = \
|
|||||||
-ffreestanding \
|
-ffreestanding \
|
||||||
-fno-stack-protector \
|
-fno-stack-protector \
|
||||||
-fno-pic \
|
-fno-pic \
|
||||||
-fomit-frame-pointer \
|
-fno-omit-frame-pointer \
|
||||||
-Wno-address-of-packed-member \
|
-Wno-address-of-packed-member \
|
||||||
-masm=intel \
|
-masm=intel \
|
||||||
-mno-80387 \
|
-mno-80387 \
|
||||||
@ -23,7 +24,7 @@ INTERNAL_CFLAGS = \
|
|||||||
-I. \
|
-I. \
|
||||||
-I..
|
-I..
|
||||||
|
|
||||||
LDFLAGS = -flto -Os
|
LDFLAGS = -Os
|
||||||
|
|
||||||
INTERNAL_LDFLAGS = \
|
INTERNAL_LDFLAGS = \
|
||||||
-lgcc \
|
-lgcc \
|
||||||
@ -41,11 +42,17 @@ ASM_FILES := $(shell find ./ -type f -name '*.asm' | sort)
|
|||||||
OBJ := $(ASM_FILES:.asm=.o) $(C_FILES:.c=.o)
|
OBJ := $(ASM_FILES:.asm=.o) $(C_FILES:.c=.o)
|
||||||
HEADER_DEPS := $(C_FILES:.c=.d)
|
HEADER_DEPS := $(C_FILES:.c=.d)
|
||||||
|
|
||||||
all: stage2.bin
|
all: stage2.map stage2.bin
|
||||||
|
|
||||||
stage2.bin: $(OBJ)
|
stage2.map: stage2.elf
|
||||||
$(LD) $(OBJ) $(LDFLAGS) $(INTERNAL_LDFLAGS) -o stage2.elf
|
./gensyms.sh $(OBJDUMP)
|
||||||
$(OBJCOPY) -O binary stage2.elf stage2.bin
|
nasm symlist.gen -f bin -o $@
|
||||||
|
|
||||||
|
stage2.bin: stage2.elf
|
||||||
|
$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
|
stage2.elf: $(OBJ)
|
||||||
|
$(LD) $(OBJ) $(LDFLAGS) $(INTERNAL_LDFLAGS) -o $@
|
||||||
|
|
||||||
-include $(HEADER_DEPS)
|
-include $(HEADER_DEPS)
|
||||||
|
|
||||||
@ -56,4 +63,4 @@ stage2.bin: $(OBJ)
|
|||||||
nasm $< -f elf32 -o $@
|
nasm $< -f elf32 -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f stage2.bin stage2.elf $(OBJ) $(HEADER_DEPS)
|
rm -f symlist.gen stage2.map stage2.bin stage2.elf $(OBJ) $(HEADER_DEPS)
|
||||||
|
17
stage2/gensyms.sh
Executable file
17
stage2/gensyms.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMP1=$(mktemp)
|
||||||
|
TMP2=$(mktemp)
|
||||||
|
TMP3=$(mktemp)
|
||||||
|
|
||||||
|
$1 -t stage2.elf | sed '/\bd\b/d' | sort > "$TMP1"
|
||||||
|
grep "\.text" < "$TMP1" | cut -d' ' -f1 > "$TMP2"
|
||||||
|
grep "\.text" < "$TMP1" | awk 'NF{ print $NF }' > "$TMP3"
|
||||||
|
|
||||||
|
paste -d'$' "$TMP2" "$TMP3" | sed 's/^/dd 0x/g' | sed 's/$/", 0/g' | sed 's/\$/\ndb "/g' > symlist.gen
|
||||||
|
|
||||||
|
echo "dd 0xffffffff" >> symlist.gen
|
||||||
|
|
||||||
|
rm "$TMP1" "$TMP2" "$TMP3"
|
@ -4,6 +4,7 @@
|
|||||||
#include <lib/libc.h>
|
#include <lib/libc.h>
|
||||||
#include <lib/blib.h>
|
#include <lib/blib.h>
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
|
#include <lib/trace.h>
|
||||||
|
|
||||||
uint8_t boot_drive;
|
uint8_t boot_drive;
|
||||||
|
|
||||||
@ -73,6 +74,9 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
|
|||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
|
print("\n");
|
||||||
|
print_stacktrace(NULL);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
asm volatile ("hlt" ::: "memory");
|
asm volatile ("hlt" ::: "memory");
|
||||||
}
|
}
|
||||||
|
75
stage2/lib/trace.c
Normal file
75
stage2/lib/trace.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <lib/trace.h>
|
||||||
|
#include <lib/blib.h>
|
||||||
|
#include <lib/config.h>
|
||||||
|
#include <lib/print.h>
|
||||||
|
#include <lib/uri.h>
|
||||||
|
#include <fs/file.h>
|
||||||
|
#include <mm/pmm.h>
|
||||||
|
|
||||||
|
static char *stage2_map = NULL;
|
||||||
|
|
||||||
|
void trace_init(void) {
|
||||||
|
char map_filename[80];
|
||||||
|
if (!config_get_value(map_filename, 0, 80, "STAGE2_MAP"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct file_handle stage2_map_file;
|
||||||
|
if (!uri_open(&stage2_map_file, map_filename))
|
||||||
|
panic("Could not open stage2 map file `%s`", map_filename);
|
||||||
|
|
||||||
|
stage2_map = ext_mem_alloc(stage2_map_file.size);
|
||||||
|
fread(&stage2_map_file, stage2_map, 0, stage2_map_file.size);
|
||||||
|
|
||||||
|
print("trace: Stage 2 map file `%s` loaded.\n", map_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *trace_address(size_t *off, size_t addr) {
|
||||||
|
if (!stage2_map)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
uint32_t prev_addr = 0;
|
||||||
|
char *prev_sym = NULL;
|
||||||
|
|
||||||
|
for (size_t i = 0;;) {
|
||||||
|
if (*((uint32_t *)&stage2_map[i]) >= addr) {
|
||||||
|
*off = addr - prev_addr;
|
||||||
|
return prev_sym;
|
||||||
|
}
|
||||||
|
prev_addr = *((uint32_t *)&stage2_map[i]);
|
||||||
|
i += sizeof(uint32_t);
|
||||||
|
prev_sym = &stage2_map[i];
|
||||||
|
while (stage2_map[i++] != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_stacktrace(size_t *base_ptr) {
|
||||||
|
if (!stage2_map)
|
||||||
|
print("trace: Symbol names won't be resolved due to missing map file.\n");
|
||||||
|
|
||||||
|
if (base_ptr == NULL) {
|
||||||
|
asm volatile (
|
||||||
|
"mov %0, ebp"
|
||||||
|
: "=g"(base_ptr)
|
||||||
|
:: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
print("Stacktrace:\n");
|
||||||
|
for (;;) {
|
||||||
|
size_t old_bp = base_ptr[0];
|
||||||
|
size_t ret_addr = base_ptr[1];
|
||||||
|
if (!ret_addr)
|
||||||
|
break;
|
||||||
|
size_t off;
|
||||||
|
char *name = trace_address(&off, ret_addr);
|
||||||
|
if (name)
|
||||||
|
print(" [%x] <%s+%x>\n", ret_addr, name, off);
|
||||||
|
else
|
||||||
|
print(" [%x]\n", ret_addr);
|
||||||
|
if (!old_bp)
|
||||||
|
break;
|
||||||
|
base_ptr = (void*)old_bp;
|
||||||
|
}
|
||||||
|
print("End of trace.\n");
|
||||||
|
}
|
10
stage2/lib/trace.h
Normal file
10
stage2/lib/trace.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __LIB__TRACE_H__
|
||||||
|
#define __LIB__TRACE_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void trace_init(void);
|
||||||
|
char *trace_address(size_t *off, size_t addr);
|
||||||
|
void print_stacktrace(size_t *base_ptr);
|
||||||
|
|
||||||
|
#endif
|
@ -5,6 +5,7 @@
|
|||||||
#include <lib/libc.h>
|
#include <lib/libc.h>
|
||||||
#include <lib/part.h>
|
#include <lib/part.h>
|
||||||
#include <lib/config.h>
|
#include <lib/config.h>
|
||||||
|
#include <lib/trace.h>
|
||||||
#include <sys/e820.h>
|
#include <sys/e820.h>
|
||||||
#include <sys/a20.h>
|
#include <sys/a20.h>
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
@ -67,6 +68,8 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace_init();
|
||||||
|
|
||||||
char *cmdline = menu();
|
char *cmdline = menu();
|
||||||
|
|
||||||
char proto[32];
|
char proto[32];
|
||||||
|
@ -3,21 +3,25 @@ TIMEOUT=3
|
|||||||
GRAPHICS=yes
|
GRAPHICS=yes
|
||||||
MENU_RESOLUTION=1024x768
|
MENU_RESOLUTION=1024x768
|
||||||
E9_OUTPUT=yes
|
E9_OUTPUT=yes
|
||||||
|
STAGE2_MAP=bios://:1/boot/stage2.map
|
||||||
|
|
||||||
THEME_COLOURS=60000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa
|
THEME_COLOURS=60000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa
|
||||||
THEME_MARGIN=64
|
THEME_MARGIN=64
|
||||||
|
|
||||||
BACKGROUND_PATH=guid://@GUID@/bg.bmp
|
BACKGROUND_PATH=bios://:1/boot/bg.bmp
|
||||||
|
|
||||||
:Stivale Test
|
:Stivale Test
|
||||||
|
|
||||||
PROTOCOL=stivale
|
PROTOCOL=stivale
|
||||||
KERNEL_PATH=guid://@GUID@/boot/test.elf
|
KERNEL_PATH=bios://:1/boot/test.elf
|
||||||
KERNEL_CMDLINE=Hi! This is an example!
|
KERNEL_CMDLINE=Hi! This is an example!
|
||||||
|
|
||||||
MODULE_PATH=bios://:1/boot/test.elf
|
MODULE_PATH=bios://:1/boot/test.elf
|
||||||
MODULE_STRING=yooooo
|
MODULE_STRING=yooooo
|
||||||
|
|
||||||
|
MODULE_PATH=bios://:1/boot/bg.bmp
|
||||||
|
MODULE_STRING=yooooo
|
||||||
|
|
||||||
:Stivale2 Test
|
:Stivale2 Test
|
||||||
|
|
||||||
PROTOCOL=stivale2
|
PROTOCOL=stivale2
|
||||||
@ -25,5 +29,5 @@ RESOLUTION=640x480x16
|
|||||||
KERNEL_PATH=bios://:1/boot/test.elf
|
KERNEL_PATH=bios://:1/boot/test.elf
|
||||||
KERNEL_CMDLINE=Woah! Another example!
|
KERNEL_CMDLINE=Woah! Another example!
|
||||||
|
|
||||||
MODULE_PATH=guid://@GUID@/boot/test.elf
|
MODULE_PATH=bios://:1/boot/bg.bmp
|
||||||
MODULE_STRING=yooooo
|
MODULE_STRING=yooooo
|
||||||
|
Loading…
Reference in New Issue
Block a user