printstack and env

main
magical 2023-04-16 19:04:10 -07:00
parent 9f0de41e02
commit 3b2e88e661
4 changed files with 158 additions and 1 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
/true /true
/false /false
/cat /cat
/printstack
/env

View File

@ -5,7 +5,7 @@ LD = $(TARGET)-ld
.SUFFIXES: .SUFFIXES:
.PHONY: all .PHONY: all
all: true false cat all: true false cat env
#all: echo #all: echo
%: %.o %: %.o

71
env.s 100644
View File

@ -0,0 +1,71 @@
.globl _start
.option rvc # enable compressed instructions
.section .rodata
newline: .ascii "\n"
# TODO: sort env, buffer output
.text
_start:
# arguments are passed on the stack:
# --bottom of stack--
# dd argc
# dd argv[0]
# dd ...
# dd 0
# dd envp[0]
# dd ...
# dd 0
ld s0, 0(sp) # get argc
addi s1, sp, 16 # add 8 for argc, 8 for the NULL at the end of argv
# compute start of envp
# we could use a sh3add instruction
# but the tools i'm using don't support the bitmanip extension
#sh3add s1, sp, s0
sll t0, s0, 3 # argc*8
add s1, s1, t0
loop:
# check for null pointer, which signals the end of envp
ld a1, 0(s1)
beqz a1, end
# compute length of string
mv t1, a1
strlen:
lbu t0, 0(t1)
addi t1, t1, 1
bnez t0, strlen
sub a2, t1, a1
# print string
li a7, 64
li a0, 1
# a1 already set to start of string
# a2 already set to string length
ecall
# print newline
li a7, 64
li a0, 1
la a1, newline
li a2, 1
ecall
# increment envp and loop
addi s1, s1, 8
j loop
end:
li a7, 93 # exit
li a0, 0
ecall
write_error:
li a7, 93 # exit
li a0, 1
ecall

84
printstack.s 100644
View File

@ -0,0 +1,84 @@
.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