printstack and env
parent
9f0de41e02
commit
3b2e88e661
|
@ -1,3 +1,5 @@
|
||||||
/true
|
/true
|
||||||
/false
|
/false
|
||||||
/cat
|
/cat
|
||||||
|
/printstack
|
||||||
|
/env
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue