hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 3d39248bb3adb5421a787c1549c467e3635057af
parent e952359b927844a2176aeffb9d82adad69ba647b
Author: Mykyta Holubakha <hilobakho@gmail.com>
Date:   Sun, 25 Apr 2021 15:42:54 +0300

rt: add functions to walk stack frames

Co-authored-by: Drew DeVault <sir@cmpwn.com>
Signed-off-by: Mykyta Holubakha <hilobakho@gmail.com>
Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Art/+aarch64/backtrace.ha | 19+++++++++++++++++++
Art/+aarch64/getfp.s | 5+++++
Art/+x86_64/backtrace.ha | 20++++++++++++++++++++
Art/+x86_64/getfp.s | 5+++++
Mscripts/gen-stdlib | 7+++++++
Mstdlib.mk | 14++++++++++++++
6 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/rt/+aarch64/backtrace.ha b/rt/+aarch64/backtrace.ha @@ -0,0 +1,19 @@ +fn getfp() **void; + +// Details for a stack frame. Contents are architecture-specific. +export type frame = struct { + fp: nullable *frame, + lr: nullable *void, +}; + +// Returns the caller's stack frame. Call [[nextframe]] to walk the stack. +export fn backtrace() frame = *(getfp(): *frame); + +// Returns the frame above the current frame, if any. +export fn nextframe(fp: *frame) (frame | void) = { + return match (fp.fp) { + null => void, + fp: *frame => *fp, + }; +}; + diff --git a/rt/+aarch64/getfp.s b/rt/+aarch64/getfp.s @@ -0,0 +1,5 @@ +.global rt.getfp +.type rt.getfp,@function +rt.getfp: + mov x0, x29 + ret diff --git a/rt/+x86_64/backtrace.ha b/rt/+x86_64/backtrace.ha @@ -0,0 +1,20 @@ +fn getfp() **void; + +// Details for a stack frame. Contents are architecture-specific. +export type frame = struct { + addr: *void +}; + +// Returns the current stack frame. See [[nextframe]] to walk the stack. +export fn backtrace() frame = frame { + addr = getfp() +}; + +// Returns the frame above the current frame, if any. +export fn nextframe(sframe: frame) (frame | void) = { + let addr = sframe.addr: *nullable *void; + return match (*addr) { + null => void, + a: *void => frame { addr = a } + }; +}; diff --git a/rt/+x86_64/getfp.s b/rt/+x86_64/getfp.s @@ -0,0 +1,5 @@ +.global rt.getfp +.type rt.getfp,@function +rt.getfp: + mov (%rbp),%rax + ret diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -29,6 +29,7 @@ gensrcs_rt() { '$(PLATFORM)/stat.ha' \ '$(PLATFORM)/socket.ha' \ '$(ARCH)/jmp.ha' \ + '$(ARCH)/backtrace.ha' \ ensure.ha \ jmp.ha \ malloc.ha \ @@ -66,6 +67,7 @@ ${stdlib}_asm=\$($cache)/rt/syscall.o \\ \$($cache)/rt/setjmp.o \\ \$($cache)/rt/longjmp.o \\ \$($cache)/rt/restore.o \\ + \$($cache)/rt/getfp.o \\ \$($cache)/rt/start.o \$($cache)/rt/syscall.o: \$(STDLIB)/rt/\$(PLATFORM)/syscall\$(ARCH).s @@ -88,6 +90,11 @@ ${stdlib}_asm=\$($cache)/rt/syscall.o \\ @mkdir -p \$($cache)/rt @\$(AS) -o \$@ \$< +\$($cache)/rt/getfp.o: \$(STDLIB)/rt/\$(ARCH)/getfp.s + @printf 'AS \t\$@\n' + @mkdir -p \$($cache)/rt + @\$(AS) -o \$@ \$< + \$($cache)/rt/rt.a: \$($cache)/rt/rt.o \$(${stdlib}_asm) @printf 'AR\t\$@\n' @\$(AR) -csr \$@ \$($cache)/rt/rt.o \$(${stdlib}_asm) diff --git a/stdlib.mk b/stdlib.mk @@ -16,6 +16,7 @@ stdlib_rt_srcs= \ $(STDLIB)/rt/$(PLATFORM)/stat.ha \ $(STDLIB)/rt/$(PLATFORM)/socket.ha \ $(STDLIB)/rt/$(ARCH)/jmp.ha \ + $(STDLIB)/rt/$(ARCH)/backtrace.ha \ $(STDLIB)/rt/ensure.ha \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ @@ -40,6 +41,7 @@ stdlib_asm=$(HARECACHE)/rt/syscall.o \ $(HARECACHE)/rt/setjmp.o \ $(HARECACHE)/rt/longjmp.o \ $(HARECACHE)/rt/restore.o \ + $(HARECACHE)/rt/getfp.o \ $(HARECACHE)/rt/start.o $(HARECACHE)/rt/syscall.o: $(STDLIB)/rt/$(PLATFORM)/syscall$(ARCH).s @@ -62,6 +64,11 @@ $(HARECACHE)/rt/restore.o: $(STDLIB)/rt/$(ARCH)/restore.s @mkdir -p $(HARECACHE)/rt @$(AS) -o $@ $< +$(HARECACHE)/rt/getfp.o: $(STDLIB)/rt/$(ARCH)/getfp.s + @printf 'AS \t$@\n' + @mkdir -p $(HARECACHE)/rt + @$(AS) -o $@ $< + $(HARECACHE)/rt/rt.a: $(HARECACHE)/rt/rt.o $(stdlib_asm) @printf 'AR\t$@\n' @$(AR) -csr $@ $(HARECACHE)/rt/rt.o $(stdlib_asm) @@ -905,6 +912,7 @@ testlib_rt_srcs= \ $(STDLIB)/rt/$(PLATFORM)/stat.ha \ $(STDLIB)/rt/$(PLATFORM)/socket.ha \ $(STDLIB)/rt/$(ARCH)/jmp.ha \ + $(STDLIB)/rt/$(ARCH)/backtrace.ha \ $(STDLIB)/rt/ensure.ha \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ @@ -933,6 +941,7 @@ testlib_asm=$(TESTCACHE)/rt/syscall.o \ $(TESTCACHE)/rt/setjmp.o \ $(TESTCACHE)/rt/longjmp.o \ $(TESTCACHE)/rt/restore.o \ + $(TESTCACHE)/rt/getfp.o \ $(TESTCACHE)/rt/start.o $(TESTCACHE)/rt/syscall.o: $(STDLIB)/rt/$(PLATFORM)/syscall$(ARCH).s @@ -955,6 +964,11 @@ $(TESTCACHE)/rt/restore.o: $(STDLIB)/rt/$(ARCH)/restore.s @mkdir -p $(TESTCACHE)/rt @$(AS) -o $@ $< +$(TESTCACHE)/rt/getfp.o: $(STDLIB)/rt/$(ARCH)/getfp.s + @printf 'AS \t$@\n' + @mkdir -p $(TESTCACHE)/rt + @$(AS) -o $@ $< + $(TESTCACHE)/rt/rt.a: $(TESTCACHE)/rt/rt.o $(testlib_asm) @printf 'AR\t$@\n' @$(AR) -csr $@ $(TESTCACHE)/rt/rt.o $(testlib_asm)