riscv-utils/printstack.s

85 lines
1.7 KiB
ArmAsm

.globl _start
.option rvc # enable compressed instructions
#.option norelax
.data
sigaction:
.dword segv # sa_handler
.dword 0 # sa_flags
.dword 0 # sa_mask
.data
buf: .zero 8
.text
_start:
# set up the gp register so that relaxed loads work
.option norelax
la gp, __global_pointer$
.option relax
# the following is what the la instruction above gets expanded to,
# but writing it out explicitly like this causes ld to segfault
#auipc gp, %pcrel_hi(__global_pointer$)
#addi gp, gp, %pcrel_lo(__global_pointer$)
# set up a signal handler for SIGSEGV
# XXX we don't actually need this because write will
# return EFAULT if the address isn't mapped
li a7, 134 # sys_rt_sigaction
li a0, 11 # SIGSEGv
la a1, sigaction # action
li a2, 0 # oldact = NULL
li a3, 8 # signal set size (bytes)
ecall
# save sp
la s7, buf
sd sp, 0(s7)
# print sp
li a7, 64 # sys_write
li a0, 1 # fd = stdout
mv a1, s7 # pointer to string
li a2, 8 # size of data
ecall
bltz a0, write_error
# round sp down to multiple of 512
# and move to s0
andi s0, sp, -512
loop:
# print sp
sd s0, 0(s7)
li a7, 64 # sys_write
li a0, 1 # fd = stdout
mv a1, s7 # pointer to string
li a2, 8 # size of data
ecall
bltz a0, write_error
# print 512 bytes of stack
li a7, 64 # sys_write
li a0, 1
mv a1, s0
li a2, 512
ecall
bltz a0, write_error
# increment sp by 512
addi s0, s0, 512
beqz s0, segv
j loop
write_error:
li a7, 93 # exit
li a0, 1
ecall
segv:
li a7, 93 # exit
li a0, 0
ecall