9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 4c21257b1984c358159853bf4ae683cae0b96404
Author: Dimitris Papastamos <dimitris.papastamos@arm.com>
Date:   Wed, 10 Oct 2018 14:10:04 +0100

Initial commit

Diffstat:
AMakefile | 23+++++++++++++++++++++++
AREADME | 33+++++++++++++++++++++++++++++++++
Aarch/Makefile | 10++++++++++
Aarch/amd64/Makefile | 18++++++++++++++++++
Aarch/amd64/arch.s | 1+
Aarch/amd64/crt-bsd.s | 22++++++++++++++++++++++
Aarch/amd64/crt-linux.s | 15+++++++++++++++
Aarch/amd64/panic.c | 9+++++++++
Aarch/amd64/ram.c | 18++++++++++++++++++
Aarch/amd64/rom.c | 18++++++++++++++++++
Aarch/arm64/Makefile | 23+++++++++++++++++++++++
Aarch/arm64/arch.s | 33+++++++++++++++++++++++++++++++++
Aarch/arm64/macros.s | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aarch/arm64/panic.c | 42++++++++++++++++++++++++++++++++++++++++++
Aarch/arm64/ram-crt-linux.s | 7+++++++
Aarch/arm64/ram-crt-none.s | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aarch/arm64/ram.c | 18++++++++++++++++++
Aarch/arm64/rom-crt-linux.s | 7+++++++
Aarch/arm64/rom-crt-none.s | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aarch/arm64/rom.c | 23+++++++++++++++++++++++
Aconfig/amd64-bsd.mk | 8++++++++
Aconfig/amd64-linux.mk | 8++++++++
Aconfig/arm64-linux.mk | 10++++++++++
Aconfig/arm64-none.mk | 9+++++++++
Ainclude/assert.h | 10++++++++++
Ainclude/bits/amd64/arch/limits.h | 17+++++++++++++++++
Ainclude/bits/amd64/arch/setjmp.h | 1+
Ainclude/bits/amd64/arch/stddef.h | 14++++++++++++++
Ainclude/bits/amd64/arch/stdint.h | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/amd64/arch/stdio.h | 15+++++++++++++++
Ainclude/bits/amd64/arch/stdlib.h | 14++++++++++++++
Ainclude/bits/amd64/arch/string.h | 3+++
Ainclude/bits/arm64/arch/limits.h | 23+++++++++++++++++++++++
Ainclude/bits/arm64/arch/machine.h | 17+++++++++++++++++
Ainclude/bits/arm64/arch/setjmp.h | 1+
Ainclude/bits/arm64/arch/stddef.h | 15+++++++++++++++
Ainclude/bits/arm64/arch/stdint.h | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/arm64/arch/stdio.h | 15+++++++++++++++
Ainclude/bits/arm64/arch/stdlib.h | 13+++++++++++++
Ainclude/bits/arm64/arch/string.h | 10++++++++++
Ainclude/bits/bsd/sys/errno.h | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/bsd/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/bits/linux/sys/errno.h | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/linux/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/bits/none/sys/errno.h | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/none/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/ctype.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Ainclude/errno.h | 10++++++++++
Ainclude/limits.h | 9+++++++++
Ainclude/rcode.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/setjmp.h | 11+++++++++++
Ainclude/stdarg.h | 10++++++++++
Ainclude/stdbool.h | 9+++++++++
Ainclude/stddef.h | 12++++++++++++
Ainclude/stdint.h | 6++++++
Ainclude/stdio.h | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/stdlib.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/string.h | 34++++++++++++++++++++++++++++++++++
Ainclude/types.h | 10++++++++++
Ascripts/gentbl.sh | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ascripts/rmu.cmd | 43+++++++++++++++++++++++++++++++++++++++++++
Ascripts/rules.mk | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Makefile | 16++++++++++++++++
Asrc/libc/Makefile | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/__assert.c | 10++++++++++
Asrc/libc/__putc.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/_flsbuf.c | 22++++++++++++++++++++++
Asrc/libc/abort.c | 10++++++++++
Asrc/libc/arch/amd64/_Exit-bsd.s | 8++++++++
Asrc/libc/arch/amd64/_Exit-linux.s | 8++++++++
Asrc/libc/arch/amd64/_getpid-bsd.s | 8++++++++
Asrc/libc/arch/amd64/_getpid-linux.s | 8++++++++
Asrc/libc/arch/amd64/_kill-bsd.s | 8++++++++
Asrc/libc/arch/amd64/_kill-linux.s | 8++++++++
Asrc/libc/arch/amd64/_write-bsd.s | 8++++++++
Asrc/libc/arch/amd64/_write-linux.s | 8++++++++
Asrc/libc/arch/amd64/longjmp.s | 20++++++++++++++++++++
Asrc/libc/arch/amd64/setjmp.s | 17+++++++++++++++++
Asrc/libc/arch/arm64/_Exit-linux.s | 8++++++++
Asrc/libc/arch/arm64/_Exit-none.s | 9+++++++++
Asrc/libc/arch/arm64/_getpid-linux.s | 8++++++++
Asrc/libc/arch/arm64/_getpid-none.s | 9+++++++++
Asrc/libc/arch/arm64/_kill-linux.s | 8++++++++
Asrc/libc/arch/arm64/_kill-none.s | 9+++++++++
Asrc/libc/arch/arm64/_write-linux.s | 8++++++++
Asrc/libc/arch/arm64/_write-none.s | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/arch/arm64/longjmp.s | 22++++++++++++++++++++++
Asrc/libc/arch/arm64/raise.c | 9+++++++++
Asrc/libc/arch/arm64/setjmp.s | 20++++++++++++++++++++
Asrc/libc/atexit.c | 17+++++++++++++++++
Asrc/libc/ctype.c | 24++++++++++++++++++++++++
Asrc/libc/errno.c | 1+
Asrc/libc/exit.c | 13+++++++++++++
Asrc/libc/ferror.c | 8++++++++
Asrc/libc/fprintf.c | 15+++++++++++++++
Asrc/libc/fputc.c | 8++++++++
Asrc/libc/fputs.c | 12++++++++++++
Asrc/libc/isalnum.c | 8++++++++
Asrc/libc/isalpha.c | 8++++++++
Asrc/libc/isascii.c | 8++++++++
Asrc/libc/isblank.c | 7+++++++
Asrc/libc/iscntrl.c | 8++++++++
Asrc/libc/isdigit.c | 8++++++++
Asrc/libc/isgraph.c | 8++++++++
Asrc/libc/islower.c | 8++++++++
Asrc/libc/isprint.c | 8++++++++
Asrc/libc/ispunct.c | 8++++++++
Asrc/libc/isspace.c | 8++++++++
Asrc/libc/isupper.c | 8++++++++
Asrc/libc/isxdigit.c | 8++++++++
Asrc/libc/memchr.c | 12++++++++++++
Asrc/libc/memcmp.c | 14++++++++++++++
Asrc/libc/memcpy.c | 13+++++++++++++
Asrc/libc/memmove.c | 18++++++++++++++++++
Asrc/libc/memset.c | 12++++++++++++
Asrc/libc/printf.c | 15+++++++++++++++
Asrc/libc/printk.c | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/putc.c | 8++++++++
Asrc/libc/putchar.c | 8++++++++
Asrc/libc/puts.c | 12++++++++++++
Asrc/libc/raise.c | 14++++++++++++++
Asrc/libc/rand.c | 18++++++++++++++++++
Asrc/libc/signal.h | 35+++++++++++++++++++++++++++++++++++
Asrc/libc/snprintf.c | 16++++++++++++++++
Asrc/libc/sprintf.c | 16++++++++++++++++
Asrc/libc/stdio.c | 33+++++++++++++++++++++++++++++++++
Asrc/libc/strcat.c | 14++++++++++++++
Asrc/libc/strchr.c | 10++++++++++
Asrc/libc/strcmp.c | 10++++++++++
Asrc/libc/strcoll.c | 10++++++++++
Asrc/libc/strcpy.c | 12++++++++++++
Asrc/libc/strcspn.c | 21+++++++++++++++++++++
Asrc/libc/strerror.c | 12++++++++++++
Asrc/libc/strftime.c | 246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/strlen.c | 12++++++++++++
Asrc/libc/strncat.c | 15+++++++++++++++
Asrc/libc/strncmp.c | 14++++++++++++++
Asrc/libc/strncpy.c | 14++++++++++++++
Asrc/libc/strnlen.c | 13+++++++++++++
Asrc/libc/strpbrk.c | 20++++++++++++++++++++
Asrc/libc/strrchr.c | 14++++++++++++++
Asrc/libc/strspn.c | 21+++++++++++++++++++++
Asrc/libc/strstr.c | 18++++++++++++++++++
Asrc/libc/strtok.c | 25+++++++++++++++++++++++++
Asrc/libc/strxfrm.c | 12++++++++++++
Asrc/libc/syscall.h | 8++++++++
Asrc/libc/toupper.c | 8++++++++
Asrc/libc/vfprintf.c | 311+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/vsnprintf.c | 25+++++++++++++++++++++++++
Asrc/libc/vsprintf.c | 12++++++++++++
Asrc/librmu/Makefile | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/librmu/RMU_Crypto_Random.c | 7+++++++
Asrc/librmu/RMU_Local_Load.c | 7+++++++
Asrc/librmu/RMU_Local_Status.c | 7+++++++
Asrc/librmu/RMU_Local_Validate.c | 7+++++++
Asrc/librmu/RMU_REC_Prepare.c | 7+++++++
Asrc/librmu/RMU_REC_ReadGeneralPurposeRegister.c | 7+++++++
Asrc/librmu/RMU_REC_ReadSystemRegister.c | 7+++++++
Asrc/librmu/RMU_REC_ReadVectorRegister.c | 7+++++++
Asrc/librmu/RMU_REC_Register.c | 7+++++++
Asrc/librmu/RMU_REC_Release.c | 7+++++++
Asrc/librmu/RMU_REC_Size.c | 7+++++++
Asrc/librmu/RMU_REC_WriteGeneralPurposeRegister.c | 7+++++++
Asrc/librmu/RMU_REC_WriteSystemRegister.c | 7+++++++
Asrc/librmu/RMU_REC_WriteVectorRegister.c | 7+++++++
Asrc/librmu/RMU_Realm_Activate.c | 7+++++++
Asrc/librmu/RMU_Realm_AttestationReport.c | 7+++++++
Asrc/librmu/RMU_Realm_AttestationReportInit.c | 7+++++++
Asrc/librmu/RMU_Realm_AttestationReportSize.c | 7+++++++
Asrc/librmu/RMU_Realm_CreateZeroMetadata.c | 7+++++++
Asrc/librmu/RMU_Realm_DeriveBindingKey.c | 7+++++++
Asrc/librmu/RMU_Realm_ExtendBindingKeySeedValue.c | 7+++++++
Asrc/librmu/RMU_Realm_GetBindingKeySeedValue.c | 7+++++++
Asrc/librmu/RMU_Realm_GetMetadata.c | 7+++++++
Asrc/librmu/RMU_Realm_GetParameterInheritance.c | 7+++++++
Asrc/librmu/RMU_Realm_GetParameterValue.c | 7+++++++
Asrc/librmu/RMU_Realm_Info.c | 7+++++++
Asrc/librmu/RMU_Realm_Initialize.c | 7+++++++
Asrc/librmu/RMU_Realm_Invalidate.c | 7+++++++
Asrc/librmu/RMU_Realm_InvalidateCurrent.c | 7+++++++
Asrc/librmu/RMU_Realm_Populate.c | 7+++++++
Asrc/librmu/RMU_Realm_Prepare.c | 7+++++++
Asrc/librmu/RMU_Realm_ReadMemory.c | 7+++++++
Asrc/librmu/RMU_Realm_Register.c | 7+++++++
Asrc/librmu/RMU_Realm_Release.c | 7+++++++
Asrc/librmu/RMU_Realm_SetBindingKeySeedLock.c | 7+++++++
Asrc/librmu/RMU_Realm_SetCommandTrap.c | 7+++++++
Asrc/librmu/RMU_Realm_SetMetadata.c | 7+++++++
Asrc/librmu/RMU_Realm_SetParameterInheritance.c | 7+++++++
Asrc/librmu/RMU_Realm_SetParameterValue.c | 7+++++++
Asrc/librmu/RMU_Realm_WriteMemory.c | 7+++++++
Asrc/librmu/RMU_System_Enable.c | 7+++++++
Asrc/librmu/RMU_System_InterfaceVersion.c | 7+++++++
Asrc/librmu/RMU_System_Status.c | 7+++++++
Asrc/libtypes/Makefile | 13+++++++++++++
Asrc/libtypes/pack.c | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libtypes/unpack.c | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ramfw/Makefile | 16++++++++++++++++
Asrc/rmc.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/romfw/Makefile | 16++++++++++++++++
Asrc/romfw/rmc.c | 33+++++++++++++++++++++++++++++++++
Atest/.gitignore | 2++
Atest/Makefile | 16++++++++++++++++
Atest/chktest.sh | 13+++++++++++++
Atest/test1/.gitignore | 43+++++++++++++++++++++++++++++++++++++++++++
Atest/test1/Makefile | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/test1/genrmu.sh | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/test1/test.c | 26++++++++++++++++++++++++++
Atest/test1/test.sh | 27+++++++++++++++++++++++++++
Atest/test2/Makefile | 13+++++++++++++
Atest/test2/test.c | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/test2/test.exp | 256+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/test2/test.sh | 11+++++++++++
213 files changed, 5363 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,23 @@ +PROJECTDIR = . +include scripts/rules.mk + +all: arch/$(ARCH) + +test: all FORCE + @+cd test/ && $(MAKE) test + +arch/$(ARCH): src + +src: lib bin + +bin lib: + mkdir $@ + +src arch/$(ARCH): FORCE + +@cd $@ && $(MAKE) + +clean: + +@cd src && $(MAKE) clean + +@cd arch && $(MAKE) clean + +@cd test && $(MAKE) clean + rm -rf lib bin diff --git a/README b/README @@ -0,0 +1,33 @@ +Building rcode +============== + +PATH=<path-to-aarch64-elf-toolchain>:$PATH +export PATH +make + +Running rcode +============= + +You need the ATG Bowmore model. Launch the model with the following +options: + +#!/bin/sh + +bl1_path=<path-to-bl1.bin> +fip_path=<path-to-fip.bin> +romfw_path=<path-to-rcode-romfw.bin> + +isim_system \ + -p -S -R \ + -C bp.pl011_uart0.uart_enable=1 \ + -C bp.pl011_uart0.out_file=uart0.out \ + -C cluster0.NUM_CORES=1 \ + -C cluster0.has_bowmore=1 \ + -C cluster0.cpu0.RVBAR_R=0x2e000000 \ + -C cluster0.cpu0.RVBAR=0 \ + -C cluster0.granule_ownership_table_address=0x803f80000 \ + -C cluster0.max_32bit_el=0 \ + -C cluster0.has_rmode=1 \ + -C bp.secureflashloader.fname="$bl1_path" \ + -C bp.flashloader0.fname="$fip_path" \ + --data cluster0.cpu0="$romfw_path"@0x2e000000 diff --git a/arch/Makefile b/arch/Makefile @@ -0,0 +1,10 @@ +PROJECTDIR=.. +include $(PROJECTDIR)/scripts/rules.mk + +DIRS=arm64 amd64 + +all: + +@cd $(ARCH) && $(MAKE) + +clean: + $(FORALL) diff --git a/arch/amd64/Makefile b/arch/amd64/Makefile @@ -0,0 +1,18 @@ +PROJECTDIR = ../.. +include $(PROJECTDIR)/scripts/rules.mk + +ROMOBJS = crt-$(SYS).o panic.o arch.o rom.o $(SRCDIR)/romfw/builtin.o +RAMOBJS = crt-$(SYS).o panic.o arch.o rom.o $(SRCDIR)/ramfw/builtin.o + +TARGET = $(BINDIR)/romfw.elf $(BINDIR)/ramfw.elf +LIBS = -lrmu -lc +LIBDEP = $(LIBDIR)/librmu.a $(LIBDIR)/libc.a + + +all: $(TARGET) + +$(BINDIR)/romfw.elf: $(ROMOBJS) $(LIBDEP) + $(LD) $(RCODE_LDFLAGS) $(ROMOBJS) $(LIBS) -o $@ + +$(BINDIR)/ramfw.elf: $(RAMOBJS) $(LIBDEP) + $(LD) $(RCODE_LDFLAGS) $(RAMOBJS) $(LIBS) -o $@ diff --git a/arch/amd64/arch.s b/arch/amd64/arch.s @@ -0,0 +1 @@ + .file "arch.s" diff --git a/arch/amd64/crt-bsd.s b/arch/amd64/crt-bsd.s @@ -0,0 +1,22 @@ + .file "crt-bsd.s" + + .bss + .globl _environ +_environ: + .quad 0 + + .text + .align 8 + .globl _start,_Exit +_start: + movq %rsp,%rbp + + /* load argc, argv, envp from stack */ + movq (%rbp),%rdi /* argc */ + leaq 8(%rbp),%rsi /* argv */ + leaq 16(%rbp,%rax,8),%rcx /* envp = argv + 8*argc + 8 */ + movq %rdx,_environ + + call main + movl %eax,%edi + jmp _Exit diff --git a/arch/amd64/crt-linux.s b/arch/amd64/crt-linux.s @@ -0,0 +1,15 @@ + .file "crt-linux.s" + + .text + .globl _start,_Exit +_start: + movq %rsp,%rbp + + /* load argc, argv, envp from stack */ + movq (%rbp),%rdi /* argc */ + leaq 8(%rbp),%rsi /* argv */ + leaq 16(%rbp,%rax,8),%rcx /* envp = argv + 8*argc + 8 */ + + call main + movl %eax,%edi + jmp _Exit diff --git a/arch/amd64/panic.c b/arch/amd64/panic.c @@ -0,0 +1,9 @@ +#include <rcode.h> + +void +panic(const char *msg) +{ + dbg(msg); + for (;;) + ; +} diff --git a/arch/amd64/ram.c b/arch/amd64/ram.c @@ -0,0 +1,18 @@ +#include <stdint.h> + +#include <rcode.h> + +int +main(int argc, char *argv[]) +{ + unsigned i, j; + Ctx ctx; + + for (i = 0; i <= 9; i++) { + for (j = 0; j <= 14; j++) { + printk("%u\t%u\t", i, j); + rmc(i, j, &ctx); + } + } + return 0; +} diff --git a/arch/amd64/rom.c b/arch/amd64/rom.c @@ -0,0 +1,18 @@ +#include <stdint.h> + +#include <rcode.h> + +int +main(int argc, char *argv[]) +{ + unsigned i, j; + Ctx ctx; + + for (i = 0; i <= 9; i++) { + for (j = 0; j <= 14; j++) { + printk("%u\t%u\t", i, j); + rmc(i, j, &ctx); + } + } + return 0; +} diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile @@ -0,0 +1,23 @@ +PROJECTDIR = ../.. +include $(PROJECTDIR)/scripts/rules.mk + +ROMOBJS = rom-crt-$(SYS).o panic.o arch.o rom.o $(SRCDIR)/romfw/builtin.o +RAMOBJS = ram-crt-$(SYS).o panic.o arch.o ram.o $(SRCDIR)/ramfw/builtin.o + +TARGET = $(BINDIR)/romfw.bin $(BINDIR)/ramfw.bin +LIBS = -lrmu -lc +LIBDEP = $(LIBDIR)/librmu.a $(LIBDIR)/libc.a + +all: $(TARGET) + +rom-crt-$(SYS).o: macros.s + +$(BINDIR)/romfw.elf: $(ROMOBJS) $(LIBDEP) + $(LD) $(RCODE_LDFLAGS) $(ROMOBJS) $(LIBS) -o $@ + +$(BINDIR)/ramfw.elf: $(RAMOBJS) $(LIBDEP) + $(LD) $(RCODE_LDFLAGS) $(ROMOBJS) $(LIBS) -o $@ + +clean: + rm -f $(TARGET:.bin=.elf) + rm -f $(TARGET:.bin=.tst) diff --git a/arch/arm64/arch.s b/arch/arm64/arch.s @@ -0,0 +1,33 @@ + .file "arch.s" + + .text + .globl panic,panic_helper + .align 2 +panic: stp x1,x0,[sp,#-16]! + stp x3,x2,[sp,#-16]! + stp x5,x4,[sp,#-16]! + stp x7,x6,[sp,#-16]! + stp x9,x8,[sp,#-16]! + stp x11,x10,[sp,#-16]! + stp x13,x12,[sp,#-16]! + stp x15,x14,[sp,#-16]! + stp x17,x16,[sp,#-16]! + stp x19,x18,[sp,#-16]! + stp x21,x20,[sp,#-16]! + stp x23,x22,[sp,#-16]! + stp x25,x24,[sp,#-16]! + stp x27,x26,[sp,#-16]! + stp x29,x28,[sp,#-16]! + mov x1,sp + stp x1,x30,[sp,#-16]! + + mrs x3,S3_6_C4_C0_6 /* SPSR_R */ + mrs x2,S3_6_C4_C0_3 /* ELR_R */ + stp x3,x2,[sp,#-16]! + + mrs x1,S3_6_C6_C0_6 /* FAR_R */ + mrs x0,S3_6_C5_C2_6 /* ESR_R */ + stp x1,x0,[sp,#-16]! + + mov x1,sp + b cpanic diff --git a/arch/arm64/macros.s b/arch/arm64/macros.s @@ -0,0 +1,65 @@ +.macro vempty + .align 3 + adr x0,badtrap + b panic +.endm + +.macro vector name + .align 3 + b \name +.endm + +.macro handler target + stp x1,x0,[sp,#-16]! + stp x3,x2,[sp,#-16]! + stp x5,x4,[sp,#-16]! + stp x7,x6,[sp,#-16]! + stp x9,x8,[sp,#-16]! + stp x11,x10,[sp,#-16]! + stp x13,x12,[sp,#-16]! + stp x15,x14,[sp,#-16]! + stp x17,x16,[sp,#-16]! + stp x19,x18,[sp,#-16]! + stp x21,x20,[sp,#-16]! + stp x23,x22,[sp,#-16]! + stp x25,x24,[sp,#-16]! + stp x27,x26,[sp,#-16]! + stp x29,x28,[sp,#-16]! + stp xzr,x30,[sp,#-16]! /* SP = 0, only useful in panic() */ + + mrs x1,S3_6_C4_C0_6 /* SPSR_R */ + mrs x0,S3_6_C4_C0_3 /* ELR_R */ + stp x1,x0,[sp,#-16]! + + mrs x1,S3_6_C6_C0_6 /* FAR_R */ + mrs x0,S3_6_C5_C2_6 /* ESR_R */ + stp x1,x0,[sp,#-16]! + + mov x0,sp + bl \target + + ldp x1,x0,[sp],#16 + msr S3_6_C6_C0_6,x1 /* FAR_R */ + msr S3_6_C5_C2_6,x0 /* ESR_R */ + + ldp x1,x0,[sp],#16 + msr S3_6_C4_C0_6,x1 /* SPSR_R */ + msr S3_6_C4_C0_3,x0 /* ELR_R */ + + ldp xzr,x30,[sp],#16 + ldp x29,x28,[sp],#16 + ldp x27,x26,[sp],#16 + ldp x25,x24,[sp],#16 + ldp x23,x22,[sp],#16 + ldp x21,x20,[sp],#16 + ldp x19,x18,[sp],#16 + ldp x17,x16,[sp],#16 + ldp x15,x14,[sp],#16 + ldp x13,x12,[sp],#16 + ldp x11,x10,[sp],#16 + ldp x9,x8,[sp],#16 + ldp x7,x6,[sp],#16 + ldp x5,x4,[sp],#16 + ldp x3,x2,[sp],#16 + ldp x1,x0,[sp],#16 +.endm diff --git a/arch/arm64/panic.c b/arch/arm64/panic.c @@ -0,0 +1,42 @@ +#include <rcode.h> +#include <arch/machine.h> + +void +cpanic(const char *msg, struct trapframe *fp) +{ + struct bssmap *bm = bss; + void **bp; + + if (bm->in_panic) + goto htl; + + bm->in_panic = 1; + printk("panic: %s\n" + "x0=%llx\tx1=%llx\tx2=%llx\tx3=%llx\n" + "x4=%llx\tx5=%llx\tx6=%llx\tx7=%llx\n" + "x8=%llx\tx9=%llx\tx10=%llx\tx11=%llx\n" + "x12=%llx\tx13=%llx\tx14=%llx\tx15=%llx\n" + "x16=%llx\tx17=%llx\tx18=%llx\tx19=%llx\n" + "x20=%llx\tx21=%llx\tx22=%llx\tx23=%llx\n" + "x24=%llx\tx25=%llx\tx26=%llx\tx27=%llx\n" + "x28=%llx\tx29=%llx\tx30=%llx\telr=%llx\n" + "spsr=%llx\tesr=%llx\tfar=%llx\n" + "sp=%llx\n" + "stack trace:\n", + msg, + fp->x0, fp->x1, fp->x2, fp->x3, + fp->x4, fp->x5, fp->x6, fp->x7, + fp->x8, fp->x9, fp->x10, fp->x11, + fp->x12, fp->x13, fp->x14, fp->x15, + fp->x16, fp->x17, fp->x18, fp->x19, + fp->x20, fp->x21, fp->x22, fp->x23, + fp->x24, fp->x25, fp->x26, fp->x27, + fp->x28, fp->x29, fp->x30, fp->elr, + fp->spsr, fp->esr, fp->far, fp->sp); + + for (bp = (void **) fp->x29; *bp; bp = (void **) *bp) + printk("%llx\n", bp[1]); +htl: + for (;;) + ; +} diff --git a/arch/arm64/ram-crt-linux.s b/arch/arm64/ram-crt-linux.s @@ -0,0 +1,7 @@ + .file "ram-crt-linux.s" + + .text + .globl _start +_start: + bl main + b _Exit diff --git a/arch/arm64/ram-crt-none.s b/arch/arm64/ram-crt-none.s @@ -0,0 +1,68 @@ + .file "rom-crt-none.s" + + .include "macros.s" + +/* TODO: extract data section address from RSCB */ +BSS = 0x2E00F000 +BSSSIZ = 1024 +PAGESIZ = 4096 + + .text + .globl _start +_start: + adr x0,vectbl + msr S3_6_C12_C0_6,x0 /* VBAR_R */ + isb + + /* Stack grows down towards BSS */ + msr spsel,#1 + ldr x0,=BSS + mov x1,#(PAGESIZ-16) + add x0,x0,x1 + mov sp,x0 + mov x29,sp + stp xzr,xzr,[x29] /* zero FP/LR to terminate backtrace */ + + ldr x0,=BSS + mov x1,#0 + mov x2,BSSSIZ + bl memset + + bl _uart_init + + mrs x0,rvbar_el3 + handler main + eret + +/* Top level AArch32/AArch64 Sync exception handler */ +_synchdl: + handler synchdl + eret + + .align 11 +vectbl: + /* Current EL with SP0 */ + vempty /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + + /* Current EL with SPx */ + vempty /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + + /* Lower EL using AArch64 */ + vector _synchdl /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + + /* Lower EL using AArch32 */ + vector _synchdl /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + +badtrap: .asciz "bad exception" diff --git a/arch/arm64/ram.c b/arch/arm64/ram.c @@ -0,0 +1,18 @@ +#include <stdint.h> + +#include <rcode.h> + +int +main(int argc, char *argv[]) +{ + unsigned i, j; + Ctx ctx; + + for (i = 0; i <= 9; i++) { + for (j = 0; j <= 14; j++) { + printk("%u\t%u\t", i, j); + rmc(i, j, &ctx); + } + } + return 0; +} diff --git a/arch/arm64/rom-crt-linux.s b/arch/arm64/rom-crt-linux.s @@ -0,0 +1,7 @@ + .file "rom-crt-linux.s" + + .text + .globl _start +_start: + bl main + b _Exit diff --git a/arch/arm64/rom-crt-none.s b/arch/arm64/rom-crt-none.s @@ -0,0 +1,68 @@ + .file "rom-crt-none.s" + + .include "macros.s" + +/* TODO: extract data section address from RSCB */ +BSS = 0x2E00F000 +BSSSIZ = 1024 +PAGESIZ = 4096 + + .text + .globl _start +_start: + adr x0,vectbl + msr S3_6_C12_C0_6,x0 /* VBAR_R */ + isb + + /* Stack grows down towards BSS */ + msr spsel,#1 + ldr x0,=BSS + mov x1,#(PAGESIZ-16) + add x0,x0,x1 + mov sp,x0 + mov x29,sp + stp xzr,xzr,[x29] /* zero FP/LR to terminate backtrace */ + + ldr x0,=BSS + mov x1,#0 + mov x2,BSSSIZ + bl memset + + bl _uart_init + + mrs x0,rvbar_el3 + handler main + eret + +/* Top level AArch32/AArch64 Sync exception handler */ +_synchdl: + handler synchdl + eret + + .align 11 +vectbl: + /* Current EL with SP0 */ + vempty /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + + /* Current EL with SPx */ + vempty /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + + /* Lower EL using AArch64 */ + vector _synchdl /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + + /* Lower EL using AArch32 */ + vector _synchdl /* Sync */ + vempty /* IRQ/vIRQ */ + vempty /* FIQ/vFIQ */ + vempty /* SError/VSError */ + +badtrap: .asciz "bad exception" diff --git a/arch/arm64/rom.c b/arch/arm64/rom.c @@ -0,0 +1,23 @@ +#include <string.h> + +#include <arch/machine.h> +#include <rcode.h> + +void +synchdl(struct trapframe *fp) +{ + dbg("sync handler\n"); +} + +int +main(struct trapframe *fp) +{ + unsigned long long rvbar_el3; + + rvbar_el3 = fp->x0; + /* Clear all regs to avoid leaking info to EL3h */ + memset(fp, 0, sizeof(*fp)); + fp->elr = rvbar_el3; + fp->spsr = 0xf << 6 | 0xd; + return 0; +} diff --git a/config/amd64-bsd.mk b/config/amd64-bsd.mk @@ -0,0 +1,8 @@ +ARCH = amd64 +SYSCFLAGS = -g -static -nostdinc -ffreestanding -std=c99 -fno-stack-protector -MD -Wall +SYSLDFLAGS = -static -z nodefaultlib +COMP = gcc +ASM = as +LINKER = ld +SYS = bsd +CROSS_COMPILE = diff --git a/config/amd64-linux.mk b/config/amd64-linux.mk @@ -0,0 +1,8 @@ +ARCH = amd64 +SYSCFLAGS = -g -static -nostdinc -ffreestanding -std=c99 -fno-stack-protector -MD -Wall +SYSLDFLAGS = -static -z nodefaultlib +COMP = gcc +ASM = as +LINKER = ld +SYS = linux +CROSS_COMPILE = diff --git a/config/arm64-linux.mk b/config/arm64-linux.mk @@ -0,0 +1,10 @@ +ARCH = arm64 +SYSCFLAGS = -g -static -nostdinc -ffreestanding -std=c99 -fno-stack-protector -MD -Wall +SYSLDFLAGS = -static -z nodefaultlib +CROSS_COMPILE = aarch64-linux-gnu- +SYS=linux +COMP = gcc +ASM = as +LINKER = ld +EMU = qemu-aarch64-static +OBJCOPY = objcopy diff --git a/config/arm64-none.mk b/config/arm64-none.mk @@ -0,0 +1,9 @@ +ARCH = arm64 +SYSCFLAGS = -g -static -nostdinc -ffreestanding -std=c99 -mgeneral-regs-only -fno-stack-protector -MD -Wall +SYSLDFLAGS = -static -z nodefaultlib -Ttext=0 +CROSS_COMPILE = aarch64-elf- +SYS=none +COMP = gcc +ASM = as +LINKER = ld +OBJCOPY = objcopy diff --git a/include/assert.h b/include/assert.h @@ -0,0 +1,10 @@ + +void __assert(char *exp, char *file, long line); + +#undef assert +#ifndef NDEBUG +# define assert(exp) ((exp) ? (void) 0 : __assert(#exp, __FILE__, __LINE__)) +#else +# define assert(exp) ((void)0) +#endif + diff --git a/include/bits/amd64/arch/limits.h b/include/bits/amd64/arch/limits.h @@ -0,0 +1,17 @@ +#define SCHAR_MAX 0x7F +#define SCHAR_MIN (-SCHAR_MIN-1) +#define CHAR_MAX 0x7F +#define CHAR_MIN (-CHAR_MAX-1) +#define UCHAR_MAX 0xFF +#define SHRT_MAX 0x7FFF +#define SHRT_MIN (-SHRT_MAX-1) +#define USHRT_MAX 0xFFFF +#define INT_MAX 0x7FFFFFFF +#define INT_MIN (-INT_MAX-1) +#define UINT_MAX 0xFFFFFFFF +#define LONG_MAX 0x7FFFFFFFFFFFFFFF +#define LONG_MIN (-LONG_MAX-1) +#define ULONG_MAX 0xFFFFFFFFFFFFFFFF +#define LLONG_MAX 0x7FFFFFFFFFFFFFFF +#define LLONG_MIN (-LLONG_MAX-1) +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFF diff --git a/include/bits/amd64/arch/setjmp.h b/include/bits/amd64/arch/setjmp.h @@ -0,0 +1 @@ +typedef unsigned long long jmp_buf[8]; diff --git a/include/bits/amd64/arch/stddef.h b/include/bits/amd64/arch/stddef.h @@ -0,0 +1,14 @@ +#ifndef _SIZET +typedef unsigned long size_t; +#define _SIZET +#endif + +#ifndef _WCHAR_T +typedef int wchar_t; +#define _WCHAR_T +#endif + +#ifndef _PTRDIFF_T +typedef long ptrdiff_t; +#define _PTRDIFF_T +#endif diff --git a/include/bits/amd64/arch/stdint.h b/include/bits/amd64/arch/stdint.h @@ -0,0 +1,115 @@ +#define INT8_MAX 0x7F +#define INT8_MIN (-INT8_MAX-1) +#define UINT8_MAX 0xFF + +#define INT16_MAX 0x7FFF +#define INT16_MIN (-INT16_MAX-1) +#define UINT16_MAX 0xFFFF + +#define INT32_MAX 0x7FFFFFFF +#define INT32_MIN (-INT32_MAX-1) +#define UINT32_MAX 0xFFFFFFFF + +#define INT64_MAX 0x7FFFFFFFFFFFFFFF +#define INT64_MIN (-INT64_MAX-1) +#define UINT64_MAX 0xFFFFFFFFFFFFFFFF + +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define UINT_LEAST8_MAX UINT8_MAX + +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define UINT_LEAST16_MAX UINT16_MAX + +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define UINT_LEAST32_MAX UINT32_MAX + +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +#define INT_FAST8_MIN INT32_MIN +#define INT_FAST8_MAX INT32_MAX +#define UINT_FAST8_MAX UINT32_MAX + +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST16_MAX INT32_MAX +#define UINT_FAST16_MAX UINT32_MAX + +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define UINT_FAST32_MAX UINT32_MAX + +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST64_MAX UINT64_MAX + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX + +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +#define SIZE_MAX UINT64_MAX + +#define WCHAR_MIN INT32_MIN +#define WCHAR_MAX INT32_MAX + +#define INT8_C(x) x +#define INT16_C(x) x +#define INT32_C(x) x +#define INT64_C(x) x ## L + +#define UINT8_C(x) x +#define UINT16_C(x) x +#define UINT32_C(x) x ## U +#define UINT64_C(x) x ## UL + +#define INTMAX_C(x) x ## L +#define UINTMAX_C(x) x ## UL + +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned uint32_t; +typedef unsigned long uint64_t; + +typedef signed char int8_least_t; +typedef short int16_least_t; +typedef int int32_least_t; +typedef long int64_least_t; + +typedef unsigned char uint8_least_t; +typedef unsigned short uint16_least_t; +typedef unsigned uint32_least_t; +typedef unsigned long uint64_least_t; + +typedef int int8_fast_t; +typedef int int16_fast_t; +typedef int int32_fast_t; +typedef long int64_fast_t; + +typedef unsigned uint8_fast_t; +typedef unsigned uint16_fast_t; +typedef unsigned uint32_fast_t; +typedef unsigned long uint64_fast_t; + +typedef long intptr_t; +typedef unsigned long uintptr_t; + +typedef long intmax_t; +typedef unsigned long uintmax_t; diff --git a/include/bits/amd64/arch/stdio.h b/include/bits/amd64/arch/stdio.h @@ -0,0 +1,15 @@ +#ifndef _SIZET +typedef unsigned long size_t; +#define _SIZET +#endif + +#define BUFSIZ 512 +#define FILENAME_MAX 256 +#define FOPEN_MAX 16 + +#define TMP_MAX 25 +#define L_tmpnam 256 + +#define _TMPNAME "/tmp/tmp.0000000" + +typedef int fpos_t; diff --git a/include/bits/amd64/arch/stdlib.h b/include/bits/amd64/arch/stdlib.h @@ -0,0 +1,14 @@ +#ifndef _SIZET +typedef unsigned long size_t; +#define _SIZET +#endif + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +#ifndef _WCHAR_T +typedef int wchar_t; +#define _WCHAR_T +#endif + +#define _ALIGNTYPE long double diff --git a/include/bits/amd64/arch/string.h b/include/bits/amd64/arch/string.h @@ -0,0 +1,3 @@ +#ifndef _SIZET +typedef unsigned long size_t; +#endif diff --git a/include/bits/arm64/arch/limits.h b/include/bits/arm64/arch/limits.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define SCHAR_MAX 0x7F +#define SCHAR_MIN (-SCHAR_MIN - 1) +#define CHAR_MAX 0x7F +#define CHAR_MIN (-CHAR_MAX - 1) +#define UCHAR_MAX 0xFFU +#define SHRT_MAX 0x7FFF +#define SHRT_MIN (-SHRT_MAX - 1) +#define USHRT_MAX 0xFFFFU +#define INT_MAX 0x7FFFFFFF +#define INT_MIN (-INT_MAX - 1) +#define UINT_MAX 0xFFFFFFFFU +#define LONG_MAX 0x7FFFFFFFFFFFFFFFL +#define LONG_MIN (-LONG_MAX - 1L) +#define ULONG_MAX 0xFFFFFFFFFFFFFFFFUL +#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL +#define LLONG_MIN (-LLONG_MAX - 1LL) +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL diff --git a/include/bits/arm64/arch/machine.h b/include/bits/arm64/arch/machine.h @@ -0,0 +1,17 @@ +struct trapframe { + unsigned long long far; + unsigned long long esr; + unsigned long long spsr; + unsigned long long elr; + unsigned long long sp; + unsigned long long x30,x29,x28,x27; + unsigned long long x26,x25,x24,x23; + unsigned long long x22,x21,x20,x19; + unsigned long long x18,x17,x16,x15; + unsigned long long x14,x13,x12,x11; + unsigned long long x10,x9,x8,x7; + unsigned long long x6,x5,x4,x3; + unsigned long long x2,x1,x0; +}; + +extern void cpanic(const char *msg, struct trapframe *fp); diff --git a/include/bits/arm64/arch/setjmp.h b/include/bits/arm64/arch/setjmp.h @@ -0,0 +1 @@ +typedef unsigned long long jmp_buf[22]; diff --git a/include/bits/arm64/arch/stddef.h b/include/bits/arm64/arch/stddef.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SIZET_ +typedef unsigned long size_t; +#define SIZET_ +#endif + +#ifndef _PTRDIFF_T +typedef long ptrdiff_t; +#define _PTRDIFF_T +#endif diff --git a/include/bits/arm64/arch/stdint.h b/include/bits/arm64/arch/stdint.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define INT8_MAX 0x7F +#define INT8_MIN (-INT8_MAX - 1) +#define UINT8_MAX 0xFFU + +#define INT16_MAX 0x7FFF +#define INT16_MIN (-INT16_MAX - 1) +#define UINT16_MAX 0xFFFFU + +#define INT32_MAX 0x7FFFFFFF +#define INT32_MIN (-INT32_MAX - 1) +#define UINT32_MAX 0xFFFFFFFFU + +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL +#define INT64_MIN (-INT64_MAX - 1LL) +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL + +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define UINT_LEAST8_MAX UINT8_MAX + +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define UINT_LEAST16_MAX UINT16_MAX + +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define UINT_LEAST32_MAX UINT32_MAX + +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +#define INT_FAST8_MIN INT32_MIN +#define INT_FAST8_MAX INT32_MAX +#define UINT_FAST8_MAX UINT32_MAX + +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST16_MAX INT32_MAX +#define UINT_FAST16_MAX UINT32_MAX + +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define UINT_FAST32_MAX UINT32_MAX + +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST64_MAX UINT64_MAX + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX + +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX + +#define SIZE_MAX UINT64_MAX + +#define INT8_C(x) x +#define INT16_C(x) x +#define INT32_C(x) x +#define INT64_C(x) x ## LL + +#define UINT8_C(x) x +#define UINT16_C(x) x +#define UINT32_C(x) x ## U +#define UINT64_C(x) x ## ULL + +#define INTMAX_C(x) x ## L +#define UINTMAX_C(x) x ## ULL + +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +typedef signed char int8_least_t; +typedef short int16_least_t; +typedef int int32_least_t; +typedef long long int64_least_t; + +typedef unsigned char uint8_least_t; +typedef unsigned short uint16_least_t; +typedef unsigned int uint32_least_t; +typedef unsigned long long uint64_least_t; + +typedef int int8_fast_t; +typedef int int16_fast_t; +typedef int int32_fast_t; +typedef long long int64_fast_t; + +typedef unsigned int uint8_fast_t; +typedef unsigned int uint16_fast_t; +typedef unsigned int uint32_fast_t; +typedef unsigned long long uint64_fast_t; + +typedef long intptr_t; +typedef unsigned long uintptr_t; + +typedef long intmax_t; +typedef unsigned long uintmax_t; diff --git a/include/bits/arm64/arch/stdio.h b/include/bits/arm64/arch/stdio.h @@ -0,0 +1,15 @@ +#ifndef _SIZET +typedef unsigned long size_t; +#define _SIZET +#endif + +#define BUFSIZ 512 +#define FILENAME_MAX 256 +#define FOPEN_MAX 16 + +#define TMP_MAX 25 +#define L_tmpnam 256 + +#define _TMPNAME "/tmp/tmp.0000000" + +typedef int fpos_t; diff --git a/include/bits/arm64/arch/stdlib.h b/include/bits/arm64/arch/stdlib.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SIZET_ +typedef unsigned long size_t; +#define SIZET_ +#endif + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 diff --git a/include/bits/arm64/arch/string.h b/include/bits/arm64/arch/string.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SIZET_ +typedef unsigned long size_t; +#define SIZET_ +#endif diff --git a/include/bits/bsd/sys/errno.h b/include/bits/bsd/sys/errno.h @@ -0,0 +1,98 @@ +#define EWOULDBLOCK EAGAIN +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EDEADLK 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define ENOTBLK 15 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define ETXTBSY 26 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EAGAIN 35 +#define EINPROGRESS 36 +#define EALREADY 37 +#define ENOTSOCK 38 +#define EDESTADDRREQ 39 +#define EMSGSIZE 40 +#define EPROTOTYPE 41 +#define ENOPROTOOPT 42 +#define EPROTONOSUPPORT 43 +#define ESOCKTNOSUPPORT 44 +#define EOPNOTSUPP 45 +#define EPFNOSUPPORT 46 +#define EAFNOSUPPORT 47 +#define EADDRINUSE 48 +#define EADDRNOTAVAIL 49 +#define ENETDOWN 50 +#define ENETUNREACH 51 +#define ENETRESET 52 +#define ECONNABORTED 53 +#define ECONNRESET 54 +#define ENOBUFS 55 +#define EISCONN 56 +#define ENOTCONN 57 +#define ESHUTDOWN 58 +#define ETOOMANYREFS 59 +#define ETIMEDOUT 60 +#define ECONNREFUSED 61 +#define ELOOP 62 +#define ENAMETOOLONG 63 +#define EHOSTDOWN 64 +#define EHOSTUNREACH 65 +#define ENOTEMPTY 66 +#define EPROCLIM 67 +#define EUSERS 68 +#define EDQUOT 69 +#define ESTALE 70 +#define EREMOTE 71 +#define EBADRPC 72 +#define ERPCMISMATCH 73 +#define EPROGUNAVAIL 74 +#define EPROGMISMATCH 75 +#define EPROCUNAVAIL 76 +#define ENOLCK 77 +#define ENOSYS 78 +#define EFTYPE 79 +#define EAUTH 80 +#define ENEEDAUTH 81 +#define EIDRM 82 +#define ENOMSG 83 +#define EOVERFLOW 84 +#define EILSEQ 85 +#define ENOTSUP 86 +#define ECANCELED 87 +#define EBADMSG 88 +#define ENODATA 89 +#define ENOSR 90 +#define ENOSTR 91 +#define ETIME 92 +#define ENOATTR 93 +#define EMULTIHOP 94 +#define ENOLINK 95 +#define ELAST 96 +#define EPROTO 96 diff --git a/include/bits/bsd/sys/signal.h b/include/bits/bsd/sys/signal.h @@ -0,0 +1,27 @@ +typedef int sig_atomic_t; + +#define SIG_ERR ((void (*)(int))-1) +#define SIG_DFL ((void (*)(int)) 0) +#define SIG_IGN ((void (*)(int)) 1) + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGABRT 6 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGSSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 + +#define __NR_SIGNALS 23 diff --git a/include/bits/linux/sys/errno.h b/include/bits/linux/sys/errno.h @@ -0,0 +1,131 @@ +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define ENOTBLK 15 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define ETXTBSY 26 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 35 +#define ENAMETOOLONG 36 +#define ENOLCK 37 +#define ENOSYS 38 +#define ENOTEMPTY 39 +#define ELOOP 40 +#define ENOMSG 42 +#define EIDRM 43 +#define ECHRNG 44 +#define EL2NSYNC 45 +#define EL3HLT 46 +#define EL3RST 47 +#define ELNRNG 48 +#define EUNATCH 49 +#define ENOCSI 50 +#define EL2HLT 51 +#define EBADE 52 +#define EBADR 53 +#define EXFULL 54 +#define ENOANO 55 +#define EBADRQC 56 +#define EBADSLT 57 +#define EBFONT 59 +#define ENOSTR 60 +#define ENODATA 61 +#define ETIME 62 +#define ENOSR 63 +#define ENONET 64 +#define ENOPKG 65 +#define EREMOTE 66 +#define ENOLINK 67 +#define EADV 68 +#define ESRMNT 69 +#define ECOMM 70 +#define EPROTO 71 +#define EMULTIHOP 72 +#define EDOTDOT 73 +#define EBADMSG 74 +#define EOVERFLOW 75 +#define ENOTUNIQ 76 +#define EBADFD 77 +#define EREMCHG 78 +#define ELIBACC 79 +#define ELIBBAD 80 +#define ELIBSCN 81 +#define ELIBMAX 82 +#define ELIBEXEC 83 +#define EILSEQ 84 +#define ERESTART 85 +#define ESTRPIPE 86 +#define EUSERS 87 +#define ENOTSOCK 88 +#define EDESTADDRREQ 89 +#define EMSGSIZE 90 +#define EPROTOTYPE 91 +#define ENOPROTOOPT 92 +#define EPROTONOSUPPORT 93 +#define ESOCKTNOSUPPORT 94 +#define EOPNOTSUPP 95 +#define EPFNOSUPPORT 96 +#define EAFNOSUPPORT 97 +#define EADDRINUSE 98 +#define EADDRNOTAVAIL 99 +#define ENETDOWN 100 +#define ENETUNREACH 101 +#define ENETRESET 102 +#define ECONNABORTED 103 +#define ECONNRESET 104 +#define ENOBUFS 105 +#define EISCONN 106 +#define ENOTCONN 107 +#define ESHUTDOWN 108 +#define ETOOMANYREFS 109 +#define ETIMEDOUT 110 +#define ECONNREFUSED 111 +#define EHOSTDOWN 112 +#define EHOSTUNREACH 113 +#define EALREADY 114 +#define EINPROGRESS 115 +#define ESTALE 116 +#define EUCLEAN 117 +#define ENOTNAM 118 +#define ENAVAIL 119 +#define EISNAM 120 +#define EREMOTEIO 121 +#define EDQUOT 122 +#define ENOMEDIUM 123 +#define EMEDIUMTYPE 124 +#define ECANCELED 125 +#define ENOKEY 126 +#define EKEYEXPIRED 127 +#define EKEYREVOKED 128 +#define EKEYREJECTED 129 +#define EOWNERDEAD 130 +#define ENOTRECOVERABLE 131 +#define ERFKILL 132 +#define EHWPOISON 133 diff --git a/include/bits/linux/sys/signal.h b/include/bits/linux/sys/signal.h @@ -0,0 +1,27 @@ +typedef int sig_atomic_t; + +#define SIG_ERR ((void (*)(int))-1) +#define SIG_DFL ((void (*)(int)) 0) +#define SIG_IGN ((void (*)(int)) 1) + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGABRT 6 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGSSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 + +#define __NR_SIGNALS 23 diff --git a/include/bits/none/sys/errno.h b/include/bits/none/sys/errno.h @@ -0,0 +1,131 @@ +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define ENOTBLK 15 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define ETXTBSY 26 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 35 +#define ENAMETOOLONG 36 +#define ENOLCK 37 +#define ENOSYS 38 +#define ENOTEMPTY 39 +#define ELOOP 40 +#define ENOMSG 42 +#define EIDRM 43 +#define ECHRNG 44 +#define EL2NSYNC 45 +#define EL3HLT 46 +#define EL3RST 47 +#define ELNRNG 48 +#define EUNATCH 49 +#define ENOCSI 50 +#define EL2HLT 51 +#define EBADE 52 +#define EBADR 53 +#define EXFULL 54 +#define ENOANO 55 +#define EBADRQC 56 +#define EBADSLT 57 +#define EBFONT 59 +#define ENOSTR 60 +#define ENODATA 61 +#define ETIME 62 +#define ENOSR 63 +#define ENONET 64 +#define ENOPKG 65 +#define EREMOTE 66 +#define ENOLINK 67 +#define EADV 68 +#define ESRMNT 69 +#define ECOMM 70 +#define EPROTO 71 +#define EMULTIHOP 72 +#define EDOTDOT 73 +#define EBADMSG 74 +#define EOVERFLOW 75 +#define ENOTUNIQ 76 +#define EBADFD 77 +#define EREMCHG 78 +#define ELIBACC 79 +#define ELIBBAD 80 +#define ELIBSCN 81 +#define ELIBMAX 82 +#define ELIBEXEC 83 +#define EILSEQ 84 +#define ERESTART 85 +#define ESTRPIPE 86 +#define EUSERS 87 +#define ENOTSOCK 88 +#define EDESTADDRREQ 89 +#define EMSGSIZE 90 +#define EPROTOTYPE 91 +#define ENOPROTOOPT 92 +#define EPROTONOSUPPORT 93 +#define ESOCKTNOSUPPORT 94 +#define EOPNOTSUPP 95 +#define EPFNOSUPPORT 96 +#define EAFNOSUPPORT 97 +#define EADDRINUSE 98 +#define EADDRNOTAVAIL 99 +#define ENETDOWN 100 +#define ENETUNREACH 101 +#define ENETRESET 102 +#define ECONNABORTED 103 +#define ECONNRESET 104 +#define ENOBUFS 105 +#define EISCONN 106 +#define ENOTCONN 107 +#define ESHUTDOWN 108 +#define ETOOMANYREFS 109 +#define ETIMEDOUT 110 +#define ECONNREFUSED 111 +#define EHOSTDOWN 112 +#define EHOSTUNREACH 113 +#define EALREADY 114 +#define EINPROGRESS 115 +#define ESTALE 116 +#define EUCLEAN 117 +#define ENOTNAM 118 +#define ENAVAIL 119 +#define EISNAM 120 +#define EREMOTEIO 121 +#define EDQUOT 122 +#define ENOMEDIUM 123 +#define EMEDIUMTYPE 124 +#define ECANCELED 125 +#define ENOKEY 126 +#define EKEYEXPIRED 127 +#define EKEYREVOKED 128 +#define EKEYREJECTED 129 +#define EOWNERDEAD 130 +#define ENOTRECOVERABLE 131 +#define ERFKILL 132 +#define EHWPOISON 133 diff --git a/include/bits/none/sys/signal.h b/include/bits/none/sys/signal.h @@ -0,0 +1,27 @@ +typedef int sig_atomic_t; + +#define SIG_ERR ((void (*)(int))-1) +#define SIG_DFL ((void (*)(int)) 0) +#define SIG_IGN ((void (*)(int)) 1) + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGABRT 6 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGSSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 + +#define __NR_SIGNALS 23 diff --git a/include/ctype.h b/include/ctype.h @@ -0,0 +1,45 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +extern int isalnum(int c); +extern int isalpha(int c); +extern int islower(int c); +extern int isupper(int c); +extern int isdigit(int c); +extern int isxdigit(int c); +extern int iscntrl(int c); +extern int isgraph(int c); +extern int isspace(int c); +extern int isblank(int c); +extern int isprint(int c); +extern int ispunct(int c); +extern int tolower(int c); +extern int toupper(int c); + + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex char */ +#define _SP 0x80 /* hard space (0x20) */ + +extern unsigned char __ctype[]; + +#define isalnum(c) ((__ctype+1)[c] & (_U|_L|_D)) +#define isalpha(c) ((__ctype+1)[c] & (_U|_L)) +#define iscntrl(c) ((__ctype+1)[c] & (_C)) +#define isdigit(c) ((__ctype+1)[c] & (_D)) +#define isgraph(c) ((__ctype+1)[c] & (_P|_U|_L|_D)) +#define islower(c) ((__ctype+1)[c] & (_L)) +#define isprint(c) ((__ctype+1)[c] & (_P|_U|_L|_D|_SP)) +#define ispunct(c) ((__ctype+1)[c] & (_P)) +#define isspace(c) ((__ctype+1)[c] & (_S)) +#define isupper(c) ((__ctype+1)[c] & (_U)) +#define isxdigit(c) ((__ctype+1)[c] & (_D|_X)) + +#define isascii(c) ((unsigned)(c)<=0x7f) + +#endif diff --git a/include/errno.h b/include/errno.h @@ -0,0 +1,10 @@ +#ifndef _ERRNO_H +#define _ERRNO_H + +#include <sys/errno.h> + +extern int errno; +extern char *_sys_errlist[]; +extern int _sys_nerr; + +#endif diff --git a/include/limits.h b/include/limits.h @@ -0,0 +1,9 @@ +#ifndef _LIMITS_H +#define _LIMITS_H + +#include <arch/limits.h> + +#define CHAR_BIT 8 +#define MB_LEN_MAX 1 + +#endif diff --git a/include/rcode.h b/include/rcode.h @@ -0,0 +1,51 @@ +#include <stdint.h> +#include <setjmp.h> + +#ifndef NDEBUG +#define dbg printk +#else +#define dbg(fmt, ...) +#endif + +#define PAGESIZE 4096 + +typedef uint64_t lock_t; +typedef struct context Ctx; +typedef struct rscb Rscb; + +struct bssmap { + char in_panic; +}; + +struct rowidx { + unsigned char off; + unsigned char cnt; +}; + +#ifdef setjmp +struct context { + unsigned char imm1, imm2; + jmp_buf recover; + int error; +}; +#endif + +static inline struct bssmap * +bss(void) +{ + uintptr_t addr; + + addr = ((uintptr_t)&addr & ~(PAGESIZE-1)); + return (struct bssmap *)addr; +} +#define bss bss() + +extern void rmc(unsigned imm1, unsigned imm2, Ctx *ctx); +extern void lock(lock_t *lck); +extern void unlock(lock_t *lck); + +extern const struct rowidx rowidx[]; +extern void (*const handler[])(void); + +extern void printk(const char * restrict fmt, ...); +extern void panic(const char *msg); diff --git a/include/setjmp.h b/include/setjmp.h @@ -0,0 +1,11 @@ +#ifndef _SETJMP_H +#define _SETJMP_H + +#include <arch/setjmp.h> + +extern int setjmp(jmp_buf env); +extern void longjmp(jmp_buf env, int val); + +#define setjmp setjmp + +#endif diff --git a/include/stdarg.h b/include/stdarg.h @@ -0,0 +1,10 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef __builtin_va_list va_list; +#define va_start(ap, last) __builtin_va_start(ap, last) +#define va_end(ap) __builtin_va_end(ap) +#define va_copy(to, from) __builtin_va_copy(to, from) +#define va_arg(to, type) __builtin_va_arg(to, type) + +#endif diff --git a/include/stdbool.h b/include/stdbool.h @@ -0,0 +1,9 @@ +#ifndef _STDBOOL_H +#define _STDBOOL_H + +#define bool _Bool +#define true 1 +#define false 0 +#define __bool_true_false_are_defined 1 + +#endif diff --git a/include/stddef.h b/include/stddef.h @@ -0,0 +1,12 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +#include <arch/stddef.h> + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define offsetof(st, m) ((size_t)&(((st *)0)->m)) + +#endif diff --git a/include/stdint.h b/include/stdint.h @@ -0,0 +1,6 @@ +#ifndef _STDINT_H_ +#define _STDINT_H_ + +#include <arch/stdint.h> + +#endif diff --git a/include/stdio.h b/include/stdio.h @@ -0,0 +1,123 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#include <arch/stdio.h> + +#ifndef FOPEN_MAX +#define FOPEN_MAX 12 +#endif + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define EOF -1 +#define SEEK_CUR 0 +#define SEEK_END 1 +#define SEEK_SET 2 + + +#define _IOWRITE (1 << 0) +#define _IOREAD (1 << 1) +#define _IORW (1 << 2) +#define _IOEOF (1 << 3) +#define _IOERR (1 << 4) +#define _IOSTRG (1 << 5) +#define _IOTXT (1 << 6) +#define _IOFBF (1 << 7) +#define _IOLBF (1 << 8) +#define _IONBF (1 << 9) +#define _IOALLOC (1 <<10) + +typedef struct { + int fd; /* file descriptor */ + unsigned char *buf; /* pointer to i/o buffer */ + unsigned char *rp; /* read pointer */ + unsigned char *wp; /* write pointer */ + unsigned char *lp; /* write pointer used when line-buffering */ + size_t len; /* actual length of buffer */ + unsigned short flags; + unsigned char unbuf[1]; /* tiny buffer for unbuffered io */ +} FILE; + +extern FILE __iob[FOPEN_MAX]; + +#define stdin (&__iob[0]) +#define stdout (&__iob[1]) +#define stderr (&__iob[2]) + +extern int remove(const char *filename); +extern int rename(const char *old, const char *new); +extern FILE *tmpfile(void); +extern char *tmpnam(char *s); +extern int fclose(FILE *fp); +extern int fflush(FILE *fp); +extern FILE *fopen(const char * restrict fname, const char * restrict mode); +extern FILE *freopen(const char * restrict fname, const char * restrict mode, + FILE * restrict fp); +extern void setbuf(FILE * restrict fp, char * restrict buf); +extern int setvbuf(FILE * restrict fp, + char * restrict buf, int mode, size_t size); +extern int fprintf(FILE * restrict fp, const char * restrict fmt, ...); +extern int fscanf(FILE * restrict fp, const char * restrict fmt, ...); +extern int printf(const char * restrict fmt, ...); +extern int scanf(const char * restrict fmt, ...); +extern int snprintf(char * restrict s, + size_t n, const char * restrict fmt, ...); +extern int sprintf(char * restrict s, const char * restrict fmt, ...); +extern int sscanf(const char * restrict s, const char * restrict fmt, ...); + +#ifdef _STDARG_H +extern int vfprintf(FILE * restrict fp, + const char * restrict fmt, va_list arg); +extern int vfscanf(FILE * restrict fp, + const char * restrict fmt, va_list arg); +extern int vprintf(const char * restrict fmt, va_list arg); +extern int vscanf(const char * restrict fmt, va_list arg); +extern int vsnprintf(char * restrict s, size_t n, const char * restrict fmt, + va_list arg); +extern int vsprintf(char * restrict s, + const char * restrict fmt, va_list arg); +extern int vsscanf(const char * restrict s, + const char * restrict fmt, va_list arg); +#endif + +extern int fgetc(FILE *fp); +extern char *fgets(char * restrict s, int n, FILE * restrict fp); +extern int fputc(int c, FILE *fp); +extern int fputs(const char * restrict s, FILE * restrict fp); +extern int getc(FILE *fp); +extern int getchar(void); +extern char *gets(char *s); +extern int putc(int c, FILE *fp); +extern int putchar(int c); +extern int puts(const char *s); +extern int ungetc(int c, FILE *fp); +extern size_t fread(void * restrict ptr, size_t size, size_t nmemb, + FILE * restrict fp); +extern size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, + FILE * restrict fp); +extern int fgetpos(FILE * restrict fp, fpos_t * restrict pos); +extern int fseek(FILE *fp, long int offset, int whence); +extern int fsetpos(FILE *fp, const fpos_t *pos); +extern long int ftell(FILE *fp); +extern void rewind(FILE *fp); +extern void clearerr(FILE *fp); +extern int feof(FILE *fp); +extern int ferror(FILE *fp); +extern void perror(const char *s); + +extern int __getc(FILE *fp); +extern int __putc(int, FILE *fp); + +#define getc(fp) ((fp)->rp >= (fp)->wp ? __getc(fp) : *(fp)->rp++) +#define putc(c, fp) ((fp)->wp >= (fp)->rp ? __putc(c,fp) : (*(fp)->wp++ = c)) + +#define ferror(fp) ((fp)->flags & _IOERR) +#define feof(fp) ((fp)->flags & _IOEOF) +#define clearerr(fp) (void) ((fp)->flags &= ~(_IOERR|_IOEOF)) +#define getchar() getc(stdin) +#define putchar(c) putc((c), stdout) +#define setbuf(fp, b) (void) setvbuf(fp, b, b ? _IOFBF:_IONBF, BUFSIZ) + +#endif diff --git a/include/stdlib.h b/include/stdlib.h @@ -0,0 +1,64 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#include <arch/stdlib.h> + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define _ATEXIT_MAX 32 + +#define MB_CUR_MAX 1 +#define RAND_MAX 32767 + +typedef struct { + int quot, rem; +} div_t; + +typedef struct { + long quot, rem; +} ldiv_t; + +typedef struct { + long long quot, rem; +} lldiv_t; + +extern double atof(const char *nptr); +extern int atoi(const char *nptr); +extern long int atol(const char *nptr); +extern long long int atoll(const char *nptr); +extern double strtod(const char * restrict nptr, char ** restrict endptr); +extern float strtof(const char * restrict nptr, char ** restrict endptr); +extern long double strtold(const char * restrict nptr, char ** restrict endptr); +extern long int strtol(const char * restrict nptr, char ** restrict endptr, int base); +extern long long int strtoll(const char * restrict nptr, char ** restrict endptr, + int base); +extern unsigned long int strtoul(const char * restrict nptr, char ** restrict endptr, + int base); +extern unsigned long long int strtoull(const char * restrict nptr, + char ** restrict endptr, int base); +extern int rand(void); +extern void srand(unsigned int seed); +extern void *calloc(size_t nmemb, size_t size); +extern void free(void *ptr); +extern void *malloc(size_t size); +extern void *realloc(void *ptr, size_t size); +extern void abort(void); +extern int atexit(void (*func)(void)); +extern void exit(int status); +extern void _Exit(int status); +extern char *getenv(const char *name); +extern int system(const char *string); +extern void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +extern void qsort(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +extern int abs(int j); +extern long int labs(long int j); +extern long long int llabs(long long int j); +extern div_t div(int numer, int denom); +extern ldiv_t ldiv(long int numer, long int denom); +extern lldiv_t lldiv(long long int numer, long long int denom); + +#endif diff --git a/include/string.h b/include/string.h @@ -0,0 +1,34 @@ +#ifndef _STRING_H +#define _STRING_H + +#include <arch/string.h> + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +extern void *memcpy(void * restrict s1, const void * restrict s2, size_t n); +extern void *memmove(void *s1, const void *s2, size_t n); +extern char *strcpy(char * restrict s1, const char * restrict s2); +extern char *strncpy(char * restrict s1, const char * restrict s2, size_t n); +extern char *strcat(char * restrict s1, const char * restrict s2); +extern char *strncat(char * restrict s1, const char * restrict s2, size_t n); +extern int memcmp(const void *s1, const void *s2, size_t n); +extern int strcmp(const char *s1, const char *s2); +extern int strcoll(const char *s1, const char *s2); +extern int strncmp(const char *s1, const char *s2, size_t n); +extern size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n); +extern void *memchr(const void *s, int c, size_t n); +extern char *strchr(const char *s, int c); +extern size_t strcspn(const char *s1, const char *s2); +extern char *strpbrk(const char *s1, const char *s2); +extern char *strrchr(const char *s, int c); +extern size_t strspn(const char *s1, const char *s2); +extern char *strstr(const char *s1, const char *s2); +extern char *strtok(char * restrict s1, const char * restrict s2); +extern void *memset(void *s, int c, size_t n); +extern char *strerror(int errnum); +extern size_t strlen(const char *s); +extern size_t strnlen(const char *s, size_t maxlen); + +#endif diff --git a/include/types.h b/include/types.h @@ -0,0 +1,10 @@ +#if __GNUC__ || __clang__ +#define UNPACKFMT __attribute__ ((format (scanf, 2, 3))) +#define PACKFMT __attribute__ ((format (printf, 2, 3))) +#else +#define UNPACKFMT +#define PACKFMT +#endif + +extern int unpack(uint64_t buf[], const char *fmt, ...) UNPACKFMT; +extern int pack(uint64_t buf[], const char *fmt, ...) PACKFMT; diff --git a/scripts/gentbl.sh b/scripts/gentbl.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +in=rmu.cmd +out=rmutbl.c +tmp=gentbl.$$ + +for i +do + case $i in + -o) + out=$2 + shift 2 + ;; + -i) + in=$2 + shift 2 + ;; + --) + shift + ;; + -*) + echo i=$i + echo usage: gentbl.sh [-o file] >&2 + exit 1 + ;; + esac +done + +trap "rm -f $tmp" 0 2 3 + +sort -n -k1,2 < $in | +awk ' +BEGIN { + print "#include <rcode.h>\n" +}; + +NF == 3 && $1 ~ /[0-9]*/ && $2 ~ /[0-9]*/ { + rowcnt[$1]++ + gsub(/\./, "_", $3) + cmds[$1,$2] = $3 + next +} + +{ + print "Invalid RMU command description" > "/dev/stderr" + exit -1 +} + +END { + for (cmd in cmds) + print "extern void " cmds[cmd] "(void);" + print "" + + print "const struct rowidx rowidx[256] = {" + for (row in rowcnt) { + begin[row] = colcnt + printf "\t[%d] = {.off = %d, .cnt = %d},\n", row, colcnt, rowcnt[row] + colcnt += rowcnt[row] + } + print "};" + + print "void (*const handler[])(void) = {" + for (row in rowcnt) + for (col = 0; col < rowcnt[row]; col++) + printf "\t[%d] = %s,\n", begin[row] + col, cmds[row,col] + print "};" +}' > $tmp && mv $tmp rmctbl.c diff --git a/scripts/rmu.cmd b/scripts/rmu.cmd @@ -0,0 +1,43 @@ +0 0 RMU.System.InterfaceVersion +0 1 RMU.System.Status +0 2 RMU.System.Enable +1 0 RMU.Local.Status +1 1 RMU.Local.Load +1 2 RMU.Local.Validate +2 0 RMU.Crypto.Random +3 0 RMU.Realm.Register +3 1 RMU.Realm.Release +4 0 RMU.Realm.InvalidateCurrent +5 0 RMU.Realm.Invalidate +5 1 RMU.Realm.GetParameterValue +5 2 RMU.Realm.SetParameterValue +5 3 RMU.Realm.GetParameterInheritance +5 4 RMU.Realm.SetParameterInheritance +5 5 RMU.Realm.Initialize +5 6 RMU.Realm.Prepare +5 7 RMU.Realm.Populate +5 8 RMU.Realm.Activate +5 9 RMU.Realm.Info +5 10 RMU.Realm.ReadMemory +5 11 RMU.Realm.WriteMemory +5 12 RMU.Realm.SetMetadata +5 13 RMU.Realm.GetMetadata +5 14 RMU.Realm.CreateZeroMetadata +6 0 RMU.Realm.SetCommandTrap +7 0 RMU.Realm.AttestationReportSize +7 1 RMU.Realm.AttestationReportInit +7 2 RMU.Realm.AttestationReport +8 0 RMU.Realm.ExtendBindingKeySeedValue +8 1 RMU.Realm.SetBindingKeySeedLock +8 2 RMU.Realm.DeriveBindingKey +8 3 RMU.Realm.GetBindingKeySeedValue +9 0 RMU.REC.Size +9 1 RMU.REC.Register +9 2 RMU.REC.Prepare +9 3 RMU.REC.Release +9 4 RMU.REC.ReadGeneralPurposeRegister +9 5 RMU.REC.WriteGeneralPurposeRegister +9 6 RMU.REC.ReadVectorRegister +9 7 RMU.REC.WriteVectorRegister +9 8 RMU.REC.ReadSystemRegister +9 9 RMU.REC.WriteSystemRegister diff --git a/scripts/rules.mk b/scripts/rules.mk @@ -0,0 +1,85 @@ +CONF = arm64-none +include $(PROJECTDIR)/config/$(CONF).mk + +INCDIR = $(PROJECTDIR)/include +LIBDIR = $(PROJECTDIR)/lib +BINDIR = $(PROJECTDIR)/bin +ARCHDIR = $(PROJECTDIR)/arch/$(ARCH) +SRCDIR = $(PROJECTDIR)/src +SCRIPTDIR= $(PROJECTDIR)/scripts +INCLUDES = -I$(INCDIR) -I$(INCDIR)/bits/$(ARCH)/ -I$(INCDIR)/bits/$(SYS) + +RCODE_CFLAGS = $(MORECFLAGS) \ + $(INCLUDES) \ + $(SYSCFLAGS) \ + $(CFLAGS) + +RCODE_LDFLAGS = $(MORELDFLAGS) \ + -L$(LIBDIR) \ + $(SYSLDFLAGS) \ + $(LDFLAGS) + +RCODE_ASFLAGS = $(MOREAFLAGS) \ + $(SYSASFLAGS) \ + $(ASFLAGS) + +CBMC_FLAGS = $(CFLAGS) --bounds-check --object-bits 16 +CBMC_PATHS = arch/$(ARCH)/*.c src/libc/arch/$(ARCH)/*.c src/*/*.c + +EMUCMD = $(EMU) $(EMUFLAGS) + +CC = $(CROSS_COMPILE)$(COMP) +AS = $(CROSS_COMPILE)$(ASM) +LD = $(CROSS_COMPILE)$(LINKER) +OC = $(CROSS_COMPILE)$(OBJCOPY) + +.c.o: + $(CC) $(RCODE_CFLAGS) -o $@ -c $< + +FORALL= +@set -e ;\ + pwd=$$PWD; \ + for i in $(DIRS); \ + do \ + cd $$i; \ + $(MAKE) $@; \ + cd $$pwd; \ + done + +all: + +FORCE: + +.SUFFIXES: .elf .bin .tst + +.c.s: + $(CC) $(RCODE_CFLAGS) -o $@ -S $< + +.elf.bin: + $(OC) -O binary $< $@ + +$(BINDIR)/ramfw.bin: $(BINDIR)/ramfw.tst +$(BINDIR)/romfw.bin: $(BINDIR)/romfw.tst + +.elf.tst: + @size $< | \ + awk 'NR == 2 {\ + if ($$2 != 0 || $$3 != 0) {\ + printf("image %s with data section!\n",\ + "$<") > "/dev/stderr";\ + exit 1;\ + }\ + }' + touch $@ + +cbmc: all FORCE + cbmc $(INCLUDES) $(CBMC_FLAGS) $(CBMC_PATHS) + +run_test: run FORCE + EMUCMD='$(EMUCMD)' SCRIPTDIR=$(SCRIPTDIR) ./test.sh + +clean: clean-files + +clean-files: + rm -f *.d *.o *.a $(TARGET) + +-include *.d diff --git a/src/Makefile b/src/Makefile @@ -0,0 +1,16 @@ +PROJECTDIR=.. +include $(PROJECTDIR)/scripts/rules.mk + +LIBS = libc librmu libtypes +IMGS = ramfw romfw +DIRS = $(LIBS) $(IMGS) + +all: $(IMGS) rmc.o + +$(IMGS): $(LIBS) + +$(DIRS): FORCE + +@cd $@ && $(MAKE) + +clean: + $(FORALL) diff --git a/src/libc/Makefile b/src/libc/Makefile @@ -0,0 +1,68 @@ +PROJECTDIR =../.. +LIBCARCH = arch/$(ARCH) +include $(PROJECTDIR)/scripts/rules.mk + +MORECFLAGS = -I. + +OBJS = abort.o \ + __assert.o \ + memchr.o \ + memcmp.o \ + memcpy.o \ + memmove.o \ + memset.o \ + printk.o \ + __putc.o \ + ctype.o \ + isalnum.o \ + isalpha.o \ + isascii.o \ + isblank.o \ + iscntrl.o \ + isdigit.o \ + isgraph.o \ + islower.o \ + isprint.o \ + ispunct.o \ + isspace.o \ + isupper.o \ + isxdigit.o \ + printf.o \ + putc.o \ + snprintf.o \ + sprintf.o \ + stdio.o \ + vfprintf.o \ + vsnprintf.o \ + vsprintf.o \ + toupper.o \ + strnlen.o \ + ferror.o \ + _flsbuf.o \ + errno.o \ + atexit.o \ + exit.o \ + fputc.o \ + fputs.o \ + fprintf.o \ + putchar.o \ + puts.o \ + rand.o \ + raise.o \ + $(LIBCARCH)/setjmp.o \ + $(LIBCARCH)/longjmp.o \ + $(LIBCARCH)/_Exit-$(SYS).o \ + $(LIBCARCH)/_write-$(SYS).o \ + $(LIBCARCH)/_getpid-$(SYS).o \ + $(LIBCARCH)/_kill-$(SYS).o + +TARGET = $(PROJECTDIR)/lib/libc.a + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(AR) $(ARFLAGS) $@ $? + ranlib $@ + +clean: + rm -f arch/*/*.o arch/*/*.d diff --git a/src/libc/__assert.c b/src/libc/__assert.c @@ -0,0 +1,10 @@ +#include <assert.h> +#include <stdlib.h> + +extern void printk(const char * restrict fmt, ...); + +void __assert(char *exp, char *file, long line) +{ + printk("%s:%ld: assertion failed '%s'\n", file, line, exp); + abort(); +} diff --git a/src/libc/__putc.c b/src/libc/__putc.c @@ -0,0 +1,76 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +extern int _flsbuf(FILE *fp); + +int +fflush(FILE *fp) +{ + int err; + + if (fp) + return _flsbuf(fp); + + err = 0; + for (fp = __iob; fp < &__iob[FOPEN_MAX]; ++fp) { + if ((fp->flags & _IOWRITE) == 0 && _flsbuf(fp)) + err = EOF; + } + return err; +} + +static void +cleanup(void) +{ + fflush(NULL); +} + +int +__putc(int ch, FILE *fp) +{ + static int first = 1; + + if (fp->flags & _IOERR) + return EOF; + + if (fp->flags & _IOREAD) { + fp->flags |= _IOERR; + errno = EBADF; + return EOF; + } + + if (fp->flags & _IOSTRG) { + fp->flags |= _IOERR; + return EOF; + } + + if (first) { + if (atexit(cleanup)) { + fp->flags |= _IOERR; + errno = ENOMEM; + return EOF; + } + first = 0; + } + + if (fp->flags & _IOLBF) { + if (fp->lp == fp->rp && _flsbuf(fp)) + return EOF; + *fp->lp++ = ch; + if (ch == '\n' && _flsbuf(fp)) + return EOF; + } else if (fp->flags & _IOFBF) { + if (fp->wp == fp->rp && _flsbuf(fp)) + return EOF; + *fp->wp++ = ch; + } else { + *fp->wp++ = ch; + if (_flsbuf(fp)) + return EOF; + } + +done: + fp->flags |= _IOWRITE; + return ch & 0xFF; +} diff --git a/src/libc/_flsbuf.c b/src/libc/_flsbuf.c @@ -0,0 +1,22 @@ +#include <errno.h> +#include <stdio.h> +#include "syscall.h" + +int +_flsbuf(FILE *fp) +{ + int lnbuf = fp->flags & _IOLBF; + unsigned char *p; + size_t cnt; + + p = (lnbuf) ? fp->lp : fp->wp; + cnt = p - fp->buf; + + if (_write(fp->fd, fp->buf, cnt) != cnt) { + fp->flags |= _IOERR; + return EOF; + } + fp->lp = fp->rp = fp->wp = fp->buf; + + return 0; +} diff --git a/src/libc/abort.c b/src/libc/abort.c @@ -0,0 +1,10 @@ +#include <signal.h> +#include <stdlib.h> +#undef abort + +void +abort(void) +{ + raise(SIGABRT); + _Exit(127); +} diff --git a/src/libc/arch/amd64/_Exit-bsd.s b/src/libc/arch/amd64/_Exit-bsd.s @@ -0,0 +1,8 @@ + .file "_Exit-bsd.s" + + .text + .globl _Exit +_Exit: + movq $1,%rax + syscall + ret diff --git a/src/libc/arch/amd64/_Exit-linux.s b/src/libc/arch/amd64/_Exit-linux.s @@ -0,0 +1,8 @@ + .file "_Exit-linux.s" + + .text + .globl _Exit +_Exit: + movq $60,%rax + syscall + ret diff --git a/src/libc/arch/amd64/_getpid-bsd.s b/src/libc/arch/amd64/_getpid-bsd.s @@ -0,0 +1,8 @@ + .file "_getpid-bsd.s" + + .text + .globl _getpid +_getpid: + movq $20,%rax + syscall + ret diff --git a/src/libc/arch/amd64/_getpid-linux.s b/src/libc/arch/amd64/_getpid-linux.s @@ -0,0 +1,8 @@ + .file "_getpid-linux.s" + + .text + .globl _getpid +_getpid: + movq $20,%rax + syscall + ret diff --git a/src/libc/arch/amd64/_kill-bsd.s b/src/libc/arch/amd64/_kill-bsd.s @@ -0,0 +1,8 @@ + .file "_kill-bsd.s" + + .text + .globl _kill +_kill: + movq $37,%rax + syscall + ret diff --git a/src/libc/arch/amd64/_kill-linux.s b/src/libc/arch/amd64/_kill-linux.s @@ -0,0 +1,8 @@ + .file "_kill-linux.s" + + .text + .globl _kill +_kill: + movq $37,%rax + syscall + ret diff --git a/src/libc/arch/amd64/_write-bsd.s b/src/libc/arch/amd64/_write-bsd.s @@ -0,0 +1,8 @@ + .file "_write-bsd.s" + + .text + .globl _write +_write: + movq $4,%rax + syscall + ret diff --git a/src/libc/arch/amd64/_write-linux.s b/src/libc/arch/amd64/_write-linux.s @@ -0,0 +1,8 @@ + .file "_write-linux.s" + + .text + .globl _write +_write: + movq $1,%rax + syscall + ret diff --git a/src/libc/arch/amd64/longjmp.s b/src/libc/arch/amd64/longjmp.s @@ -0,0 +1,20 @@ + .file "longjmp" + + .text + .globl longjmp +longjmp: + mov %rsi,%rax + test %rax,%rax + jnz 1f + inc %rax +1: + mov (%rdi),%rbx + mov 8(%rdi),%rbp + mov 16(%rdi),%r12 + mov 24(%rdi),%r13 + mov 32(%rdi),%r14 + mov 40(%rdi),%r15 + mov 48(%rdi),%rdx + mov %rdx,%rsp + mov 56(%rdi),%rdx + jmp *%rdx diff --git a/src/libc/arch/amd64/setjmp.s b/src/libc/arch/amd64/setjmp.s @@ -0,0 +1,17 @@ + .file "setjmp.s" + + .text + .globl setjmp +setjmp: + mov %rbx,(%rdi) + mov %rbp,8(%rdi) + mov %r12,16(%rdi) + mov %r13,24(%rdi) + mov %r14,32(%rdi) + mov %r15,40(%rdi) + lea 8(%rsp),%rdx + mov %rdx,48(%rdi) + mov (%rsp),%rdx + mov %rdx,56(%rdi) + xor %rax,%rax + ret diff --git a/src/libc/arch/arm64/_Exit-linux.s b/src/libc/arch/arm64/_Exit-linux.s @@ -0,0 +1,8 @@ + .file "_Exit-linux.s" + + .text + .globl _Exit +_Exit: + mov x8,#93 + svc 0 + ret diff --git a/src/libc/arch/arm64/_Exit-none.s b/src/libc/arch/arm64/_Exit-none.s @@ -0,0 +1,9 @@ + .file "_Exit-none.s" + + .text + .globl _Exit,panic +_Exit: + ldr x0,=msg + b panic + +msg: .asciz "_Exit" diff --git a/src/libc/arch/arm64/_getpid-linux.s b/src/libc/arch/arm64/_getpid-linux.s @@ -0,0 +1,8 @@ + .file "_getpid-linux.s" + + .text + .globl _getpid +_getpid: + mov x8,#172 + svc 0 + ret diff --git a/src/libc/arch/arm64/_getpid-none.s b/src/libc/arch/arm64/_getpid-none.s @@ -0,0 +1,9 @@ + .file "_getpid-none.s" + + .text + .globl _getpid +_getpid: + ldr x0,=msg + b panic + +msg: .asciz "_getpid" diff --git a/src/libc/arch/arm64/_kill-linux.s b/src/libc/arch/arm64/_kill-linux.s @@ -0,0 +1,8 @@ + .file "_kill-linux.s" + + .text + .globl _kill +_kill: + mov x8,#129 + svc 0 + ret diff --git a/src/libc/arch/arm64/_kill-none.s b/src/libc/arch/arm64/_kill-none.s @@ -0,0 +1,9 @@ + .file "_kill-none.s" + + .text + .globl _kill,panic +_kill: + ldr x0,=msg + b panic + +msg: .asciz "_kill" diff --git a/src/libc/arch/arm64/_write-linux.s b/src/libc/arch/arm64/_write-linux.s @@ -0,0 +1,8 @@ + .file "_write-linux.s" + + .text + .globl _write +_write: + mov x8,#64 + svc 0 + ret diff --git a/src/libc/arch/arm64/_write-none.s b/src/libc/arch/arm64/_write-none.s @@ -0,0 +1,80 @@ + .file "_write-none.s" + +BASE = 0x1c090000 +CLK = 24000000 +BAUD = 115200 + +CR = 0x30 +LCR_H = 0x2c +FBRD = 0x28 +IBRD = 0x24 +FR = 0x18 +ECR = 0x04 +DR = 0x0 + +CR_RXE = (1<<9) +CR_TXE = (1<<8) +CR_EN = (1<<0) + +LCR_H_FEN = (1<<4) +LCR_H_WLEN_8 = (3<<5) + +FR_TXFF_BIT = 5 +FR_BUSY_BIT = 3 + + .text + .globl _uart_init,_write + +_uart_init: + ldr x0,=BASE + ldr x1,=CLK + ldr x2,=BAUD + + ldr w3,[x0,CR] + mov w4,CR_EN + bic w3, w3, w4 + str w3,[x0,CR] + lsl w1,w1,2 + udiv w2,w1,w2 + lsr w1,w2,6 + str w1,[x0,IBRD] + and w1,w2,0x3f + str w1,[x0,FBRD] + mov w1,LCR_H_FEN|LCR_H_WLEN_8 + str w1,[x0,LCR_H] + str wzr,[x0,ECR] + mov w1,CR_RXE|CR_TXE|CR_EN + str w1,[x0,CR] + + adr x1,ansism + mov x2,5 + b _write + +/* + * x0 = fd (unused) + * x1 = buf + * x2 = cnt + */ +_write: ldr x3,=BASE + +noready: + ldr w4,[x3,FR] + tbnz w4,FR_TXFF_BIT,noready + + ldrb w4,[x1],#1 + str w4,[x3,DR] + subs x2,x2,#1 + cbnz x2,noready + + mov w5,'\n' + cmp w4,w0 + b.eq busy + ret + +busy: + ldr w2,[x3,FR] + tbnz w2,FR_BUSY_BIT,busy + ret + +ansism: .byte 0x1b + .ascii "[20h" diff --git a/src/libc/arch/arm64/longjmp.s b/src/libc/arch/arm64/longjmp.s @@ -0,0 +1,22 @@ + .file "longjmp.s" + + .text + .globl longjmp +longjmp: + ldp x19, x20, [x0,#0] + ldp x21, x22, [x0,#16] + ldp x23, x24, [x0,#32] + ldp x25, x26, [x0,#48] + ldp x27, x28, [x0,#64] + ldp x29, x30, [x0,#80] + ldr x2, [x0,#104] + mov sp, x2 + ldp d8 , d9, [x0,#112] + ldp d10, d11, [x0,#128] + ldp d12, d13, [x0,#144] + ldp d14, d15, [x0,#160] + + mov x0, x1 + cbnz x1, 1f + mov x0, #1 +1: br x30 diff --git a/src/libc/arch/arm64/raise.c b/src/libc/arch/arm64/raise.c @@ -0,0 +1,9 @@ +#include "signal.h" + +#undef raise + +int +raise(int signum) +{ + panic("aborted"); +} diff --git a/src/libc/arch/arm64/setjmp.s b/src/libc/arch/arm64/setjmp.s @@ -0,0 +1,20 @@ + .file "setjmp.s" + + .text + .globl setjmp +setjmp: + // IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers + stp x19, x20, [x0,#0] + stp x21, x22, [x0,#16] + stp x23, x24, [x0,#32] + stp x25, x26, [x0,#48] + stp x27, x28, [x0,#64] + stp x29, x30, [x0,#80] + mov x2, sp + str x2, [x0,#104] + stp d8, d9, [x0,#112] + stp d10, d11, [x0,#128] + stp d12, d13, [x0,#144] + stp d14, d15, [x0,#160] + mov x0, #0 + ret diff --git a/src/libc/atexit.c b/src/libc/atexit.c @@ -0,0 +1,17 @@ +#include <stdlib.h> +#include <errno.h> +#undef atexit + +extern void (*_exitf[_ATEXIT_MAX])(void); +extern unsigned _exitn; + +int +atexit(void (*fun)(void)) +{ + if (_exitn == _ATEXIT_MAX) { + errno = ENOMEM; + return -1; + } + _exitf[_exitn++] = fun; + return 0; +} diff --git a/src/libc/ctype.c b/src/libc/ctype.c @@ -0,0 +1,24 @@ +#include <ctype.h> + +int __ctmp; + +/* __ctype is shifted by one to match EOF */ +unsigned char __ctype[257] = { + 0, /* EOF */ + _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ + _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ + _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ + _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ + _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ + _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ + _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ + _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ + _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ + _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ + _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ + _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ + _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ + _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ + _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ + _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +}; diff --git a/src/libc/errno.c b/src/libc/errno.c @@ -0,0 +1 @@ +int errno; diff --git a/src/libc/exit.c b/src/libc/exit.c @@ -0,0 +1,13 @@ +#include <stdlib.h> +#undef exit + +void (*_exitf[_ATEXIT_MAX])(void); +unsigned _exitn; + +void +exit(int status) +{ + while (_exitn > 0) + (*_exitf[--_exitn])(); + _Exit(status); +} diff --git a/src/libc/ferror.c b/src/libc/ferror.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#undef ferror + +int +ferror(FILE *fp) +{ + return fp->flags & _IOERR; +} diff --git a/src/libc/fprintf.c b/src/libc/fprintf.c @@ -0,0 +1,15 @@ +#include <stdarg.h> +#include <stdio.h> +#undef fprintf + +int +fprintf(FILE * restrict fp, const char * restrict fmt, ...) +{ + va_list va; + int cnt; + + va_start(va, fmt); + cnt = vfprintf(fp, fmt, va); + va_end(va); + return cnt; +} diff --git a/src/libc/fputc.c b/src/libc/fputc.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#undef fputc + +int +fputc(int c, FILE *fp) +{ + return putc(c, fp); +} diff --git a/src/libc/fputs.c b/src/libc/fputs.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#undef fputs + +int +fputs(const char * restrict bp, FILE * restrict fp) +{ + int r, ch; + + while (ch = *bp++) + r = putc(ch, fp); + return r; +} diff --git a/src/libc/isalnum.c b/src/libc/isalnum.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isalnum + +int +isalnum(int c) +{ + return (__ctype+1)[c] & (_U|_L|_D); +} diff --git a/src/libc/isalpha.c b/src/libc/isalpha.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isalpha + +int +isalpha(int c) +{ + return (__ctype+1)[c] & (_U|_L); +} diff --git a/src/libc/isascii.c b/src/libc/isascii.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isascii + +int +isascii(int c) +{ + return c <= 0x7f; +} diff --git a/src/libc/isblank.c b/src/libc/isblank.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int +isblank(int c) +{ + return (c == ' ') || (c == '\t'); +} diff --git a/src/libc/iscntrl.c b/src/libc/iscntrl.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef iscntrl + +int +iscntrl(int c) +{ + return (__ctype+1)[c] & (_C); +} diff --git a/src/libc/isdigit.c b/src/libc/isdigit.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isdigit + +int +isdigit(int c) +{ + return (__ctype+1)[c] & (_D); +} diff --git a/src/libc/isgraph.c b/src/libc/isgraph.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isgraph + +int +isgraph(int c) +{ + return (__ctype+1)[c] & (_P|_U|_L|_D); +} diff --git a/src/libc/islower.c b/src/libc/islower.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef islower + +int +islower(int c) +{ + return (__ctype+1)[c] & _L; +} diff --git a/src/libc/isprint.c b/src/libc/isprint.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isprint + +int +isprint(int c) +{ + return (__ctype+1)[c] & (_P|_U|_L|_D|_SP); +} diff --git a/src/libc/ispunct.c b/src/libc/ispunct.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef ispunct + +int +ispunct(int c) +{ + return (__ctype+1)[c] & (_P); +} diff --git a/src/libc/isspace.c b/src/libc/isspace.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isspace + +int +isspace(int c) +{ + return (__ctype+1)[c] & _S; +} diff --git a/src/libc/isupper.c b/src/libc/isupper.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isupper + +int +isupper(int c) +{ + return (__ctype+1)[c] & _U; +} diff --git a/src/libc/isxdigit.c b/src/libc/isxdigit.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef isxdigit + +int +isxdigit(int c) +{ + return (__ctype+1)[c] & (_D|_X); +} diff --git a/src/libc/memchr.c b/src/libc/memchr.c @@ -0,0 +1,12 @@ +#include <string.h> +#undef memchr + +void * +memchr(const void *s, int c, size_t n) +{ + unsigned char *bp = (unsigned char *) s; + + while (n > 0 && *bp++ != c) + --n; + return (n == 0) ? NULL : bp-1; +} diff --git a/src/libc/memcmp.c b/src/libc/memcmp.c @@ -0,0 +1,14 @@ +#include <string.h> +#undef memcmp + +int +memcmp(const void *s1, const void *s2, size_t n) +{ + const char *s = s1; + const char *t = s2; + + for ( ; n > 0 && *s == *t; --n) + ++s, ++t; + + return (n > 0) ? *(unsigned char *) s - *(unsigned char *) t : 0; +} diff --git a/src/libc/memcpy.c b/src/libc/memcpy.c @@ -0,0 +1,13 @@ +#include <string.h> +#undef memcpy + +void * +memcpy(void * restrict dst, const void * restrict src, size_t n) +{ + char *s1 = dst; + const char *s2 = src; + + while (n-- > 0) + *s1++ = *s2++; + return dst; +} diff --git a/src/libc/memmove.c b/src/libc/memmove.c @@ -0,0 +1,18 @@ +#include <string.h> +#undef memmove + +void * +memmove(void *dst, const void *src, size_t n) +{ + char *d = dst, *s = (char *) src; + + if (d < s) { + while (n-- > 0) + *d++ = *s++; + } else { + s += n-1, d += n-1; + while (n-- > 0) + *d-- = *s--; + } + return dst; +} diff --git a/src/libc/memset.c b/src/libc/memset.c @@ -0,0 +1,12 @@ +#include <string.h> +#undef memset + +void * +memset(void *s, int c, size_t n) +{ + char *m = s; + + while (n-- > 0) + *m++ = c; + return s; +} diff --git a/src/libc/printf.c b/src/libc/printf.c @@ -0,0 +1,15 @@ +#include <stdarg.h> +#include <stdio.h> +#undef printf + +int +printf(const char * restrict fmt, ...) +{ + int cnt; + va_list va; + + va_start(va, fmt); + cnt = vfprintf(stdout, fmt, va); + va_end(va); + return cnt; +} diff --git a/src/libc/printk.c b/src/libc/printk.c @@ -0,0 +1,117 @@ + +#include <stdarg.h> +#include <stddef.h> + +#include "syscall.h" + +static void +putch(int c) +{ + _write(1, &c, 1); +} + +static void +printn(long long n, int base, int sign) +{ + int first, d; + unsigned long long div; + const static char digits[] = "0123456789ABCDEF"; + + switch (base) { + case 8: + div = 01000000000000000000000u; + break; + case 10: + div = 10000000000000000000u; + break; + case 16: + div = 0x1000000000000000u; + break; + } + + if (sign && n < 0) { + n = -n; + putch('-'); + } + + for (first = 1; div > 0; div /= base) { + d = n / div; + if (d == 0 && first && div != 1) + continue; + n -= d * div; + putch(digits[d]); + first = 0; + } +} + +static long long +getnum(va_list *va, int size) +{ + switch (size) { + case 0: + return va_arg(*va, int); + case 1: + return va_arg(*va, long); + case 2: + return va_arg(*va, long long); + case 3: + default: + return (long long) va_arg(*va, void *); + } +} + +void +printk(const char * restrict fmt, ...) +{ + char c; + va_list va; + int base, sign, size; + char *s; + + va_start(va, fmt); + while (( c = *fmt++) != '\0') { + if (c != '%') { + putch(c); + continue; + } + + sign = 0; + size = 0; +flags: + switch (c = *fmt++) { + case 'l': + size++; + goto flags; + case 'o': + base = 8; + goto print_number; + case 'd': + sign = 1; + case 'u': + base = 10; + goto print_number; + case 'p': + size = 3; + case 'X': + case 'x': + base = 16; + print_number: + printn(getnum(&va, size), base, sign); + break; + case 's': + for (s = va_arg(va, char *); *s; s++) + putch(*s); + break; + case 'c': + c = va_arg(va, int); + case '%': + putch(c); + break; + case '\0': + goto out_loop; + } + } + +out_loop: + va_end(va); +} diff --git a/src/libc/putc.c b/src/libc/putc.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#undef putc + +int +putc(int ch, FILE *fp) +{ + return (fp->wp >= fp->rp) ? __putc(ch,fp) : (*fp->wp++ = ch); +} diff --git a/src/libc/putchar.c b/src/libc/putchar.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#undef putchar + +int +putchar(int ch) +{ + return putc(ch, stdout); +} diff --git a/src/libc/puts.c b/src/libc/puts.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#undef puts + +int +puts(const char *str) +{ + int ch; + + while (ch = *str++) + putchar(ch); + return putchar('\n'); +} diff --git a/src/libc/raise.c b/src/libc/raise.c @@ -0,0 +1,14 @@ + +#include <stddef.h> +#include "signal.h" + +extern int _getpid(void); +extern int _kill(int pid, int signum); + +#undef raise + +int +raise(int signum) +{ + return _kill(_getpid(), signum); +} diff --git a/src/libc/rand.c b/src/libc/rand.c @@ -0,0 +1,18 @@ +#include <stdlib.h> +#undef rand +#undef srand + +static unsigned long next; + +void +srand(unsigned seed) +{ + next = seed; +} + +int +rand(void) /* RAND_MAX assumed to be 32767. */ +{ + next = next * 1103515245 + 12345; + return (unsigned)(next/65536) % 32768; +} diff --git a/src/libc/signal.h b/src/libc/signal.h @@ -0,0 +1,35 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + +typedef int sig_atomic_t; + +#define SIG_ERR ((void (*)(int))-1) +#define SIG_DFL ((void (*)(int)) 0) +#define SIG_IGN ((void (*)(int)) 1) + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGABRT 6 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGSSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 + +#define __NR_SIGNALS 23 + +void ( *signal(int signum, void (*handler)(int)) ) (int); +int raise(int sig); + +#endif diff --git a/src/libc/snprintf.c b/src/libc/snprintf.c @@ -0,0 +1,16 @@ +#include <stdarg.h> +#include <stdio.h> +#undef snprintf + +int +snprintf(char * restrict s, size_t siz, const char * restrict fmt, ...) +{ + int r; + va_list va; + + va_start(va, fmt); + r = vsnprintf(s, siz, fmt, va); + va_end(va); + + return r; +} diff --git a/src/libc/sprintf.c b/src/libc/sprintf.c @@ -0,0 +1,16 @@ +#include <stdarg.h> +#include <stdio.h> +#undef sprintf + +int +sprintf(char * restrict s, const char * restrict fmt, ...) +{ + int r; + + va_list va; + va_start(va, fmt); + r = vsprintf(s, fmt, va); + va_end(va); + + return r; +} diff --git a/src/libc/stdio.c b/src/libc/stdio.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +static unsigned char inbuf[BUFSIZ]; +static unsigned char outbuf[BUFSIZ]; + +FILE __iob[FOPEN_MAX] = { + { + .fd = 0, + .buf = inbuf, + .len = BUFSIZ, + .flags = _IOREAD, + .lp = inbuf, + .rp = inbuf, + .wp = inbuf, + }, + { + .fd = 1, + .buf = outbuf, + .len = BUFSIZ, + .flags = _IOWRITE | _IOLBF, + .lp = outbuf, + .rp = outbuf, + .wp = outbuf, + }, + { + .fd = 2, + .buf = stderr->unbuf, + .len = sizeof(stderr->unbuf), + .flags = _IOWRITE | _IONBF, + .rp = stderr->unbuf, + .wp = stderr->unbuf, + }, +}; diff --git a/src/libc/strcat.c b/src/libc/strcat.c @@ -0,0 +1,14 @@ +#include <string.h> +#undef strcat + +char * +strcat(char * restrict dst, const char * restrict src) +{ + char *ret = dst; + + while (*dst) + ++dst; + while (*dst++ = *src++) + ; + return ret; +} diff --git a/src/libc/strchr.c b/src/libc/strchr.c @@ -0,0 +1,10 @@ +#include <string.h> +#undef strchr + +char * +strchr(const char *s, int c) +{ + while (*s && *s != c) + ++s; + return (*s == c) ? (char *)s : NULL; +} diff --git a/src/libc/strcmp.c b/src/libc/strcmp.c @@ -0,0 +1,10 @@ +#include <string.h> +#undef strcmp + +int +strcmp(const char *s1, const char *s2) +{ + while (*s1 && *s2 && *s1 == *s2) + ++s1, ++s2; + return *(unsigned char *)s1 - *(unsigned char *)s2; +} diff --git a/src/libc/strcoll.c b/src/libc/strcoll.c @@ -0,0 +1,10 @@ +#include <string.h> +#undef strcoll + +int +strcoll(const char *s1, const char *s2) +{ + while (*s1 && *s2 && *s1 == *s2) + ++s1, ++s2; + return *(unsigned char *) s1 - *(unsigned char *) s2; +} diff --git a/src/libc/strcpy.c b/src/libc/strcpy.c @@ -0,0 +1,12 @@ +#include <string.h> +#undef strcpy + +char * +strcpy(char * restrict dst, const char * restrict src) +{ + char *ret = dst; + + while (*dst++ = *src++) + ; + return ret; +} diff --git a/src/libc/strcspn.c b/src/libc/strcspn.c @@ -0,0 +1,21 @@ +#include <string.h> +#undef strcspn + +size_t +strcspn(const char *s1, const char *s2) +{ + const unsigned char *s = s1; + const unsigned char *accept = s2; + unsigned ch; + size_t n; + char buf[__NUMCHARS]; + + memset(buf, 0, sizeof(buf)); + while (ch = *accept++) + buf[ch] = 1; + + for (n = 0; (ch = *s++) && !buf[ch]; ++n) + ; + + return n; +} diff --git a/src/libc/strerror.c b/src/libc/strerror.c @@ -0,0 +1,12 @@ +#include <errno.h> +#include <string.h> +#undef strerror + +char * +strerror(int errnum) +{ + if (errnum < _sys_nerr) + return _sys_errlist[errnum]; + else + return "Unknown error"; +} diff --git a/src/libc/strftime.c b/src/libc/strftime.c @@ -0,0 +1,246 @@ +#include <time.h> +#include <string.h> +#include "libc.h" +#undef strftime + +static char *days[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", +}; + +static char *months[] = { + "January", "February", "March", "April", + "May", "June", "July", "August", + "September", "October", "November", "December" +}; + +static char *am_pm[] = {"AM", "PM"}; + +static size_t +sval(char *s, size_t siz, char **strs, int abrev, int idx, int max) +{ + char *str; + size_t len; + + if (idx < 0 && idx >= max) + goto wrong; + + str = strs[idx]; + len = (!abrev) ? strlen(str) : 3; + if (len > siz) + goto wrong; + + memcpy(s, str, len); + return len; + +wrong: + *s = '?'; + return 1; +} + +static size_t +dval(char *s, size_t siz, int prec, int fill, int val) +{ + char *t; + int n; + static char digits[] = "0123456789"; + + if (prec > siz || val < 0) { + *s = '?'; + return 1; + } + + n = prec; + do { + s[--n] = digits[val % 10]; + val /= 10; + } while (n > 0 && val > 0); + + while (n > 0) + s[--n] = fill; + + return prec; +} + +static size_t +timezone(char *s, size_t prec, const struct tm * restrict tm) +{ + long off = tm->tm_gmtoff; + + if (prec < 5) { + *s = '?'; + return 1; + } + + if (off >= 0) { + *s++ = '+'; + } else { + *s++ = '-'; + off = -off; + } + + dval(s, 2, 2, '0', off / 3600); + dval(s, 2, 2, '0', (off % 3600) / 60); + + return 5; +} + +size_t +strftime(char * restrict s, size_t siz, + const char * restrict fmt, + const struct tm * restrict tm) +{ + int ch, abrev, val, fill, width; + size_t n, inc; + char *tfmt; + + for (n = siz-1; (ch = *fmt++) && n > 0; s += inc, n -= inc) { + if (ch != '%') { + *s = ch; + inc = 1; + continue; + } + + abrev = 0; + fill = '0'; + width = 2; + + switch (*fmt++) { + case 'Z': + if (!tm->tm_zone) + break; + inc = sval(s, n, &tm->tm_zone, 0, 0, 1); + break; + case 'a': + abrev = 1; + case 'A': + inc = sval(s, n, days, abrev, tm->tm_wday, 7); + break; + case 'h': + case 'b': + abrev = 1; + case 'B': + inc = sval(s, n, months, abrev, tm->tm_mon, 12); + break; + case 'p': + inc = sval(s, n, am_pm, 0, tm->tm_hour > 12, 2); + break; + case 'c': + tfmt = "%a %b %e %T %Y"; + goto recursive; + case 'D': + tfmt = "%m/%d/%y"; + goto recursive; + case 'F': + tfmt = "%Y-%m-%d"; + goto recursive; + case 'R': + tfmt = "%H:%M"; + goto recursive; + case 'X': + case 'T': + tfmt = "%H:%M:%S"; + goto recursive; + case 'r': + tfmt = "%I:%M:%S %p"; + goto recursive; + case 'x': + tfmt = "%m/%d/%y"; + goto recursive; + recursive: + inc = strftime(s, n+1, tfmt, tm) - 1; + break; + case 'n': + val = '\n'; + goto character; + case 't': + val = '\t'; + goto character; + case '%': + val = '%'; + character: + *s = val; + inc = 1; + break; + case 'e': + fill = ' '; + val = tm->tm_mday; + goto number; + case 'd': + val = tm->tm_mday; + goto number; + case 'V': + case 'g': + case 'G': + /* TODO */ + break; + case 'C': + val = tm->tm_year / 100; + goto number; + case 'H': + val = tm->tm_hour; + goto number; + case 'I': + val = tm->tm_hour; + if (val == 0) + val = 12; + if (val > 12) + val -= 12; + goto number; + case 'j': + width = 3; + val = tm->tm_yday+1; + goto number; + case 'm': + val = tm->tm_mon+1; + goto number; + case 'M': + val = tm->tm_min; + goto number; + case 'S': + val = tm->tm_sec; + goto number; + case 'u': + width = 1; + val = tm->tm_wday+1; + goto number; + case 'U': + val = tm->tm_yday / 7; + if (_newyear(tm->tm_year) == SAT) + val++; + goto number; + case 'W': + val = tm->tm_yday / 7; + if (_newyear(tm->tm_year) == MON) + val++; + goto number; + case 'w': + width = 1; + val = tm->tm_wday; + goto number; + case 'y': + val = tm->tm_year%100; + goto number; + case 'Y': + width = 4; + val = 1900 + tm->tm_year; + number: + inc = dval(s, n, width, fill, val); + break; + case 'z': + inc = timezone(s, n, tm); + break; + case 'E': + case 'O': + if (*fmt != '\0') + fmt += 2;; + case '\0': + inc = 0; + --fmt; + break; + } + } + *s = '\0'; + + return siz - n; +} diff --git a/src/libc/strlen.c b/src/libc/strlen.c @@ -0,0 +1,12 @@ +#include <string.h> +#undef strlen + +size_t +strlen(const char *s) +{ + const char *t; + + for (t = s; *t; ++t) + ; + return t - s; +} diff --git a/src/libc/strncat.c b/src/libc/strncat.c @@ -0,0 +1,15 @@ +#include <string.h> +#undef strncat + +char * +strncat(char * restrict dst, const char * restrict src, size_t n) +{ + char *ret = dst; + + while (*dst) + ++dst; + while (n-- > 0 && *src) + *dst++ = *src++; + *dst = '\0'; + return ret; +} diff --git a/src/libc/strncmp.c b/src/libc/strncmp.c @@ -0,0 +1,14 @@ +#include <string.h> +#undef strncmp + +int +strncmp(const char *s1, const char *s2, size_t n) +{ + int c; + + for ( ; n > 0 && (c = *s1) && c == *s2; --n) + ++s1, ++s2; + if (n == 0) + return 0; + return *(unsigned char *) s1 - *(unsigned char *) s2; +} diff --git a/src/libc/strncpy.c b/src/libc/strncpy.c @@ -0,0 +1,14 @@ +#include <string.h> +#undef strncpy + +char * +strncpy(char * restrict dst, const char * restrict src, size_t n) +{ + char *ret = dst; + + for (; n > 0 && *src; --n) + *dst++ = *src++; + while (n-- > 0) + *dst++ = '\0'; + return ret; +} diff --git a/src/libc/strnlen.c b/src/libc/strnlen.c @@ -0,0 +1,13 @@ +#include <string.h> + +#undef strnlen + +size_t +strnlen(const char *s, size_t maxlen) +{ + size_t n; + + for (n = 0; n < maxlen && *s++; ++n) + ; + return n; +} diff --git a/src/libc/strpbrk.c b/src/libc/strpbrk.c @@ -0,0 +1,20 @@ +#include <string.h> +#undef strpbrk + +char * +strpbrk(const char *s1, const char *s2) +{ + const unsigned char *s = s1; + const unsigned char *accept = s2; + unsigned ch; + char buf[__NUMCHARS]; + + memset(buf, 0, sizeof(buf)); + while (ch = *accept++) + buf[ch] = 1; + + while ((ch = *s) && !buf[ch]) + s++; + + return (ch == '\0') ? NULL : (char *) s; +} diff --git a/src/libc/strrchr.c b/src/libc/strrchr.c @@ -0,0 +1,14 @@ +#include <string.h> +#undef strrchr + +char * +strrchr(const char *s, int c) +{ + const char *t = s; + + while (*t) + ++t; + while (t > s && *t != c) + --t; + return (*t == c) ? (char *)t : NULL; +} diff --git a/src/libc/strspn.c b/src/libc/strspn.c @@ -0,0 +1,21 @@ +#include <string.h> +#undef strspn + +size_t +strspn(const char *s1, const char *s2) +{ + const unsigned char *s = s1; + const unsigned char *accept = s2; + unsigned ch; + size_t n; + char buf[__NUMCHARS]; + + memset(buf, 0, sizeof(buf)); + while (ch = *accept++) + buf[ch] = 1; + + for (n = 0; (ch = *s++) && buf[ch]; ++n) + ; + + return n; +} diff --git a/src/libc/strstr.c b/src/libc/strstr.c @@ -0,0 +1,18 @@ +#include <stddef.h> +#include <string.h> +#undef strstr + +char * +strstr(const char *s1, const char *s2) +{ + const char *p; + int c = *s2; + + if (c == '\0') + return NULL; + for (p = s1; p = strchr(p, c); ++p) { + if (!strcmp(p, s2)) + return (char *) p; + } + return NULL; +} diff --git a/src/libc/strtok.c b/src/libc/strtok.c @@ -0,0 +1,25 @@ +#include <string.h> +#undef strtok + +char * +strtok(char * restrict s, const char * restrict delim) +{ + static char *line; + + if (s) + line = s; + if (!s && !line) + return NULL; + + s = line + strspn(line, delim); + if (*s == '\0') + return line = NULL; + + line = s + strcspn(s, delim); + if (*line != '\0') + *line++ = '\0'; + else + line = NULL; + + return s; +} diff --git a/src/libc/strxfrm.c b/src/libc/strxfrm.c @@ -0,0 +1,12 @@ +#include <string.h> +#undef strxfrm + +size_t +strxfrm(char * restrict dst, const char * restrict src, size_t n) +{ + size_t len = strlen(src); + + if (len < n) + strcpy(dst, src); + return len; +} diff --git a/src/libc/syscall.h b/src/libc/syscall.h @@ -0,0 +1,8 @@ +extern void *_brk(void *addr); +extern int _open(const char *path, int flags); +extern int _close(int fd); +extern int _read(int fd, void *buf, size_t n); +extern int _write(int fd, void *buf, size_t n); +extern int _lseek(int fd, long off, int whence); +extern void _Exit(int status); +extern int _access(char *path, int mode); diff --git a/src/libc/toupper.c b/src/libc/toupper.c @@ -0,0 +1,8 @@ +#include <ctype.h> +#undef toupper + +int +toupper(int c) +{ + return (islower(c)) ? c & ~0x20 : c; +} diff --git a/src/libc/vfprintf.c b/src/libc/vfprintf.c @@ -0,0 +1,311 @@ +#include <ctype.h> +#include <limits.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#undef vfprintf + +enum { + LONG = 1 << 0, + LLONG = 1 << 1, + SHORT = 1 << 2, + CHAR = 1 << 3, + SIZET = 1 << 4, + PTRDIFF = 1 << 5, + INTMAX = 1 << 6, + VOIDPTR = 1 << 7, + UNSIGNED = 1 << 8, + ALTFORM = 1 << 9, +}; + +#define MAXPREC 50 + +struct conv { + int sign; + int prec; + char *digs; + int base; +}; + +static uintmax_t +getnum(va_list *va, int flags, int *sign) +{ + uintmax_t uval; + intmax_t val; + + if (flags & CHAR) { + val = va_arg(*va, int); + uval = (unsigned char) val; + } else if (flags & SHORT) { + val = va_arg(*va, int); + uval = (unsigned short) val; + } else if (flags & LONG) { + val = va_arg(*va, long); + uval = (unsigned long) val; + } else if (flags & LLONG) { + val = va_arg(*va, long long); + uval = (unsigned long long) val; + } else if (flags & SIZET) { + uval = va_arg(*va, size_t); + } else if (flags & INTMAX) { + val = va_arg(*va, intmax_t); + uval = (uintmax_t) val; + } else if (flags & VOIDPTR) { + uval = (uintmax_t) va_arg(*va, void *); + } else { + val = va_arg(*va, int); + uval = (unsigned) val; + } + + if ((flags & UNSIGNED) == 0 && val < 0) { + *sign = '-'; + uval = -uval; + } + return uval; +} + +static char * +numtostr(uintmax_t val, int flags, struct conv *conv, char *buf) +{ + char *buf0 = buf; + int base = conv->base, prec = conv->prec; + uintmax_t oval = val; + + if (prec == -1) + prec = 1; + + for (*buf = '\0'; val > 0; val /= base) + *--buf = conv->digs[val % base]; + while (buf0 - buf < prec) + *--buf = '0'; + + if (flags & ALTFORM) { + if (base == 8 && *buf != '0') { + *--buf = '0'; + } else if (base == 16 && oval != 0) { + *--buf = conv->digs[16]; + *--buf = '0'; + } + } + if (conv->sign) + *--buf = conv->sign; + + return buf; +} + +static void +savecnt(va_list *va, int flags, int cnt) +{ + if (flags & CHAR) + *va_arg(*va, char*) = cnt; + else if (flags & SHORT) + *va_arg(*va, short*) = cnt; + else if (flags & LONG) + *va_arg(*va, long*) = cnt; + else if (flags & LLONG) + *va_arg(*va, long long*) = cnt; + else if (flags & SIZET) + *va_arg(*va, size_t*) = cnt; + else if (flags & INTMAX) + *va_arg(*va, intmax_t*) = cnt; + else + *va_arg(*va, int*) = cnt; +} + +static size_t +strout(char *s, size_t len, int width, int fill, FILE * restrict fp) +{ + int left = 0, adjust, ch, prefix; + size_t cnt = 0; + + if (width < 0) { + left = 1; + width = -width; + } + + adjust = (len < width) ? width - len : 0; + cnt = adjust + len; + if (left) + adjust = -adjust; + + if (fill == '0') { + if (*s == '-' || *s == '+') + prefix = 1; + else if (*s == '0' && toupper(s[1]) == 'X') + prefix = 2; + else + prefix = 0; + while (prefix--) { + putc(*s++, fp); + --len; + } + } + + for ( ; adjust > 0; adjust--) + putc(fill, fp); + + while (ch = *s++) + putc(ch, fp); + + for ( ; adjust < 0; adjust++) + putc(' ', fp); + + return cnt; +} + +int +vfprintf(FILE * restrict fp, const char *fmt, va_list va) +{ + int ch, n, flags, width, left, fill, cnt = 0; + size_t inc, len; + char *s; + struct conv conv; + char buf[MAXPREC+1]; + va_list va2; + + va_copy(va2, va); + for (cnt = 0; ch = *fmt++; cnt += inc) { + if (ch != '%') { + putc(ch, fp); + inc = 1; + continue; + } + + fill = ' '; + left = flags = width = 0; + conv.prec = -1; + conv.base = 10; + conv.sign = '\0'; + conv.digs = "0123456789ABCDEFX"; + +flags: + switch (*fmt++) { + case ' ': + if (conv.sign == '\0') + conv.sign = ' '; + goto flags; + case '+': + conv.sign = '+'; + goto flags; + case '#': + flags |= ALTFORM; + goto flags; + case '.': + if (*fmt == '*') { + fmt++; + n = va_arg(va2, int); + } else { + for (n = 0; isdigit(ch = *fmt); fmt++) + n = n * 10 + ch - '0'; + } + if (n > MAXPREC) + n = MAXPREC; + if (n > 0) + conv.prec = n; + goto flags; + case '*': + width = va_arg(va2, int); + goto flags; + case '-': + left = 1; + ++fmt; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + --fmt; + for (n = 0; isdigit(ch = *fmt); ++fmt) + n = n * 10 + ch - '0'; + if (left) + n = -n; + width = n; + goto flags; + case '0': + fill = '0'; + goto flags; + case 'l': + flags += LONG; + goto flags; + case 'h': + flags += SHORT; + goto flags; + case '%': + ch = '%'; + goto cout; + case 'c': + ch = va_arg(va2, int); + cout: + buf[0] = ch; + buf[1] = '\0'; + s = buf; + len = 1; + goto strout; + case 'j': + flags |= INTMAX; + goto flags; + case 't': + flags |= PTRDIFF; + goto flags; + case 'z': + flags |= SIZET; + goto flags; + case 'u': + flags |= UNSIGNED; + case 'i': + case 'd': + conv.base = 10; + goto numeric; + case 'p': + flags |= VOIDPTR | ALTFORM; + goto numeric16; + case 'x': + conv.digs = "0123456789abcdefx"; + case 'X': + numeric16: + conv.base = 16; + flags |= UNSIGNED; + goto numeric; + case 'o': + conv.base = 8; + flags |= UNSIGNED; + numeric: + if (conv.prec != -1) + fill = ' '; + s = numtostr(getnum(&va2, flags, &conv.sign), + flags, + &conv, + &buf[MAXPREC]); + len = &buf[MAXPREC] - s; + goto strout; + case 'L': + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + /* TODO */ + case 's': + s = va_arg(va2, char *); + len = strnlen(s, conv.prec); + strout: + inc = strout(s, len, width, fill, fp); + break; + case 'n': + savecnt(&va2, flags, cnt); + break; + case '\0': + goto out_loop; + } + } + +out_loop: + return (ferror(fp)) ? EOF : cnt; +} diff --git a/src/libc/vsnprintf.c b/src/libc/vsnprintf.c @@ -0,0 +1,25 @@ +#include <stdarg.h> +#include <stdio.h> +#undef vsnprintf + +int +vsnprintf(char * restrict s, size_t siz, const char * restrict fmt, va_list ap) +{ + FILE f; + int r; + + f.flags = _IORW | _IOSTRG; + f.len = siz; + f.buf = s; + f.wp = s; + f.rp = s + siz; + + r = vfprintf(&f, fmt, ap); + if (s) { + if (f.wp == f.rp) + --f.wp; + *f.wp = '\0'; + } + + return r; +} diff --git a/src/libc/vsprintf.c b/src/libc/vsprintf.c @@ -0,0 +1,12 @@ +#include <limits.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#undef vsprintf + + +int +vsprintf(char * restrict s, const char * restrict fmt, va_list va) +{ + return vsnprintf(s, SIZE_MAX, fmt, va); +} diff --git a/src/librmu/Makefile b/src/librmu/Makefile @@ -0,0 +1,54 @@ +PROJECTDIR=../.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = RMU_Crypto_Random.o \ + RMU_Local_Load.o \ + RMU_Local_Status.o \ + RMU_Local_Validate.o \ + RMU_REC_Prepare.o \ + RMU_REC_ReadGeneralPurposeRegister.o \ + RMU_REC_ReadSystemRegister.o \ + RMU_REC_ReadVectorRegister.o \ + RMU_REC_Register.o \ + RMU_REC_Release.o \ + RMU_REC_Size.o \ + RMU_REC_WriteGeneralPurposeRegister.o \ + RMU_REC_WriteSystemRegister.o \ + RMU_REC_WriteVectorRegister.o \ + RMU_Realm_Activate.o \ + RMU_Realm_AttestationReport.o \ + RMU_Realm_AttestationReportInit.o \ + RMU_Realm_AttestationReportSize.o \ + RMU_Realm_CreateZeroMetadata.o \ + RMU_Realm_DeriveBindingKey.o \ + RMU_Realm_ExtendBindingKeySeedValue.o \ + RMU_Realm_GetBindingKeySeedValue.o \ + RMU_Realm_GetMetadata.o \ + RMU_Realm_GetParameterInheritance.o \ + RMU_Realm_GetParameterValue.o \ + RMU_Realm_Info.o \ + RMU_Realm_Initialize.o \ + RMU_Realm_Invalidate.o \ + RMU_Realm_InvalidateCurrent.o \ + RMU_Realm_Populate.o \ + RMU_Realm_Prepare.o \ + RMU_Realm_ReadMemory.o \ + RMU_Realm_Register.o \ + RMU_Realm_Release.o \ + RMU_Realm_SetBindingKeySeedLock.o \ + RMU_Realm_SetCommandTrap.o \ + RMU_Realm_SetMetadata.o \ + RMU_Realm_SetParameterInheritance.o \ + RMU_Realm_SetParameterValue.o \ + RMU_Realm_WriteMemory.o \ + RMU_System_Enable.o \ + RMU_System_InterfaceVersion.o \ + RMU_System_Status.o \ + +TARGET = $(LIBDIR)/librmu.a + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(AR) $(ARFLAGS) $@ $? + ranlib $@ diff --git a/src/librmu/RMU_Crypto_Random.c b/src/librmu/RMU_Crypto_Random.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Crypto_Random(void) +{ + dbg("RMU_Crypto_Random\n"); +} diff --git a/src/librmu/RMU_Local_Load.c b/src/librmu/RMU_Local_Load.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Local_Load(void) +{ + dbg("RMU_Local_Load\n"); +} diff --git a/src/librmu/RMU_Local_Status.c b/src/librmu/RMU_Local_Status.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Local_Status(void) +{ + dbg("RMU_Local_Status\n"); +} diff --git a/src/librmu/RMU_Local_Validate.c b/src/librmu/RMU_Local_Validate.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Local_Validate(void) +{ + dbg("RMU_Local_Validate\n"); +} diff --git a/src/librmu/RMU_REC_Prepare.c b/src/librmu/RMU_REC_Prepare.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_Prepare(void) +{ + dbg("RMU_REC_Prepare\n"); +} diff --git a/src/librmu/RMU_REC_ReadGeneralPurposeRegister.c b/src/librmu/RMU_REC_ReadGeneralPurposeRegister.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_ReadGeneralPurposeRegister(void) +{ + dbg("RMU_REC_ReadGeneralPurposeRegister\n"); +} diff --git a/src/librmu/RMU_REC_ReadSystemRegister.c b/src/librmu/RMU_REC_ReadSystemRegister.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_ReadSystemRegister(void) +{ + dbg("RMU_REC_ReadSystemRegister\n"); +} diff --git a/src/librmu/RMU_REC_ReadVectorRegister.c b/src/librmu/RMU_REC_ReadVectorRegister.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_ReadVectorRegister(void) +{ + dbg("RMU_REC_ReadVectorRegister\n"); +} diff --git a/src/librmu/RMU_REC_Register.c b/src/librmu/RMU_REC_Register.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_Register(void) +{ + dbg("RMU_REC_Register\n"); +} diff --git a/src/librmu/RMU_REC_Release.c b/src/librmu/RMU_REC_Release.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_Release(void) +{ + dbg("RMU_REC_Release\n"); +} diff --git a/src/librmu/RMU_REC_Size.c b/src/librmu/RMU_REC_Size.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_Size(void) +{ + dbg("RMU_REC_Size\n"); +} diff --git a/src/librmu/RMU_REC_WriteGeneralPurposeRegister.c b/src/librmu/RMU_REC_WriteGeneralPurposeRegister.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_WriteGeneralPurposeRegister(void) +{ + dbg("RMU_REC_WriteGeneralPurposeRegister\n"); +} diff --git a/src/librmu/RMU_REC_WriteSystemRegister.c b/src/librmu/RMU_REC_WriteSystemRegister.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_WriteSystemRegister(void) +{ + dbg("RMU_REC_WriteSystemRegister\n"); +} diff --git a/src/librmu/RMU_REC_WriteVectorRegister.c b/src/librmu/RMU_REC_WriteVectorRegister.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_REC_WriteVectorRegister(void) +{ + dbg("RMU_REC_WriteVectorRegister\n"); +} diff --git a/src/librmu/RMU_Realm_Activate.c b/src/librmu/RMU_Realm_Activate.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Activate(void) +{ + dbg("RMU_Realm_Activate\n"); +} diff --git a/src/librmu/RMU_Realm_AttestationReport.c b/src/librmu/RMU_Realm_AttestationReport.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_AttestationReport(void) +{ + dbg("RMU_Realm_AttestationReport\n"); +} diff --git a/src/librmu/RMU_Realm_AttestationReportInit.c b/src/librmu/RMU_Realm_AttestationReportInit.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_AttestationReportInit(void) +{ + dbg("RMU_Realm_AttestationReportInit\n"); +} diff --git a/src/librmu/RMU_Realm_AttestationReportSize.c b/src/librmu/RMU_Realm_AttestationReportSize.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_AttestationReportSize(void) +{ + dbg("RMU_Realm_AttestationReportSize\n"); +} diff --git a/src/librmu/RMU_Realm_CreateZeroMetadata.c b/src/librmu/RMU_Realm_CreateZeroMetadata.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_CreateZeroMetadata(void) +{ + dbg("RMU_Realm_CreateZeroMetadata\n"); +} diff --git a/src/librmu/RMU_Realm_DeriveBindingKey.c b/src/librmu/RMU_Realm_DeriveBindingKey.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_DeriveBindingKey(void) +{ + dbg("RMU_Realm_DeriveBindingKey\n"); +} diff --git a/src/librmu/RMU_Realm_ExtendBindingKeySeedValue.c b/src/librmu/RMU_Realm_ExtendBindingKeySeedValue.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_ExtendBindingKeySeedValue(void) +{ + dbg("RMU_Realm_ExtendBindingKeySeedValue\n"); +} diff --git a/src/librmu/RMU_Realm_GetBindingKeySeedValue.c b/src/librmu/RMU_Realm_GetBindingKeySeedValue.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_GetBindingKeySeedValue(void) +{ + dbg("RMU_Realm_GetBindingKeySeedValue\n"); +} diff --git a/src/librmu/RMU_Realm_GetMetadata.c b/src/librmu/RMU_Realm_GetMetadata.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_GetMetadata(void) +{ + dbg("RMU_Realm_GetMetadata\n"); +} diff --git a/src/librmu/RMU_Realm_GetParameterInheritance.c b/src/librmu/RMU_Realm_GetParameterInheritance.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_GetParameterInheritance(void) +{ + dbg("RMU_Realm_GetParameterInheritance\n"); +} diff --git a/src/librmu/RMU_Realm_GetParameterValue.c b/src/librmu/RMU_Realm_GetParameterValue.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_GetParameterValue(void) +{ + dbg("RMU_Realm_GetParameterValue\n"); +} diff --git a/src/librmu/RMU_Realm_Info.c b/src/librmu/RMU_Realm_Info.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Info(void) +{ + dbg("RMU_Realm_Info\n"); +} diff --git a/src/librmu/RMU_Realm_Initialize.c b/src/librmu/RMU_Realm_Initialize.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Initialize(void) +{ + dbg("RMU_Realm_Initialize\n"); +} diff --git a/src/librmu/RMU_Realm_Invalidate.c b/src/librmu/RMU_Realm_Invalidate.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Invalidate(void) +{ + dbg("RMU_Realm_Invalidate\n"); +} diff --git a/src/librmu/RMU_Realm_InvalidateCurrent.c b/src/librmu/RMU_Realm_InvalidateCurrent.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_InvalidateCurrent(void) +{ + dbg("RMU_Realm_InvalidateCurrent\n"); +} diff --git a/src/librmu/RMU_Realm_Populate.c b/src/librmu/RMU_Realm_Populate.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Populate(void) +{ + dbg("RMU_Realm_Populate\n"); +} diff --git a/src/librmu/RMU_Realm_Prepare.c b/src/librmu/RMU_Realm_Prepare.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Prepare(void) +{ + dbg("RMU_Realm_Prepare\n"); +} diff --git a/src/librmu/RMU_Realm_ReadMemory.c b/src/librmu/RMU_Realm_ReadMemory.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_ReadMemory(void) +{ + dbg("RMU_Realm_ReadMemory\n"); +} diff --git a/src/librmu/RMU_Realm_Register.c b/src/librmu/RMU_Realm_Register.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Register(void) +{ + dbg("RMU_Realm_Register\n"); +} diff --git a/src/librmu/RMU_Realm_Release.c b/src/librmu/RMU_Realm_Release.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_Release(void) +{ + dbg("RMU_Realm_Release\n"); +} diff --git a/src/librmu/RMU_Realm_SetBindingKeySeedLock.c b/src/librmu/RMU_Realm_SetBindingKeySeedLock.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_SetBindingKeySeedLock(void) +{ + dbg("RMU_Realm_SetBindingKeySeedLock\n"); +} diff --git a/src/librmu/RMU_Realm_SetCommandTrap.c b/src/librmu/RMU_Realm_SetCommandTrap.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_SetCommandTrap(void) +{ + dbg("RMU_Realm_SetCommandTrap\n"); +} diff --git a/src/librmu/RMU_Realm_SetMetadata.c b/src/librmu/RMU_Realm_SetMetadata.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_SetMetadata(void) +{ + dbg("RMU_Realm_SetMetadata\n"); +} diff --git a/src/librmu/RMU_Realm_SetParameterInheritance.c b/src/librmu/RMU_Realm_SetParameterInheritance.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_SetParameterInheritance(void) +{ + dbg("RMU_Realm_SetParameterInheritance\n"); +} diff --git a/src/librmu/RMU_Realm_SetParameterValue.c b/src/librmu/RMU_Realm_SetParameterValue.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_SetParameterValue(void) +{ + dbg("RMU_Realm_SetParameterValue\n"); +} diff --git a/src/librmu/RMU_Realm_WriteMemory.c b/src/librmu/RMU_Realm_WriteMemory.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_Realm_WriteMemory(void) +{ + dbg("RMU_Realm_WriteMemory\n"); +} diff --git a/src/librmu/RMU_System_Enable.c b/src/librmu/RMU_System_Enable.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_System_Enable(void) +{ + dbg("RMU_System_Enable\n"); +} diff --git a/src/librmu/RMU_System_InterfaceVersion.c b/src/librmu/RMU_System_InterfaceVersion.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_System_InterfaceVersion(void) +{ + dbg("RMU_System_InterfaceVersion\n"); +} diff --git a/src/librmu/RMU_System_Status.c b/src/librmu/RMU_System_Status.c @@ -0,0 +1,7 @@ +#include <rcode.h> + +void +RMU_System_Status(void) +{ + dbg("RMU_System_Status\n"); +} diff --git a/src/libtypes/Makefile b/src/libtypes/Makefile @@ -0,0 +1,13 @@ +PROJECTDIR=../.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = pack.o unpack.o +TARGET = $(LIBDIR)/libtypes.a + +$(TARGET): $(OBJS) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(AR) $(ARFLAGS) $@ $? + ranlib $@ diff --git a/src/libtypes/pack.c b/src/libtypes/pack.c @@ -0,0 +1,123 @@ +#include <stdarg.h> +#include <stdint.h> + +#include <types.h> + +static uint64_t +setbits(uint64_t dst, uint64_t src, int pos, int num) +{ + uint64_t mask; + + if (num == 64) { + mask = 0; + } else { + mask = ~(~0ull << num); + mask = ~(mask << pos); + } + + dst &= mask; + dst |= src << pos; + return dst; +} + +/* + * This function stores a field of length `num` in the logical bitstream + * represented by `buf[]` with the value from `v` starting at + * position `pos`. Each word in `buf[]` is 64 bits. If the field + * spans 2 words in `buf[]` then the required bits of both words are stored. + */ +static void +setfield(uint64_t buf[], uint64_t v, int pos, int num) +{ + int n, word, bit, rem; + + word = pos / 64; /* 1st word of the field */ + bit = pos % 64; /* offset in the 1st word */ + + n = (bit + num < 64) ? num : 64 - bit; + buf[word] = setbits(buf[word], v, bit, n); + rem = num - n; + if (rem != 0) + buf[word+1] = setbits(buf[word+1], v >> n, 0, rem); +} + +int +pack(uint64_t buf[], const char *fmt, ...) +{ + va_list va; + int pos, nbits, ret = -1; + + va_start(va, fmt); + for (pos = 0; *fmt; pos += nbits) { + int d, size; + unsigned long long v; + + nbits = 0; + if (*fmt == ' ') { + fmt++; + continue; + } + + if (*fmt++ != '%') + goto err; + + while (*fmt >= '0' && *fmt <= '9') { + d = *fmt++ - '0'; + nbits = nbits * 10 + d; + } + if (nbits == 0) + goto err; + + size = 0; +flags: + switch (*fmt++) { + case 'c': + if (nbits > 8) + goto err; + v = va_arg(va, unsigned); + setfield(buf, v, pos, nbits); + break; + case 'h': + size = 1; + goto flags; + case 'l': + size += 2; + goto flags; + case 'u': + switch (size) { + case 0: + if (nbits > 16) + goto err; + v = va_arg(va, unsigned); + setfield(buf, v, pos, nbits); + break; + case 1: + if (nbits > 16) + goto err; + v = va_arg(va, unsigned); + setfield(buf, v, pos, nbits); + break; + case 2: + if (nbits > 32) + goto err; + v = va_arg(va, unsigned long); + setfield(buf, v, pos, nbits); + break; + case 4: + if (nbits > 64) + goto err; + v = va_arg(va, unsigned long long); + setfield(buf, v, pos, nbits); + break; + default: + goto err; + } + break; + } + } + va_end(va); + + ret = nbits; +err: + return ret; +} diff --git a/src/libtypes/unpack.c b/src/libtypes/unpack.c @@ -0,0 +1,113 @@ +#include <stdarg.h> +#include <stdint.h> + +#include <types.h> + +static uint64_t +getbits(uint64_t v, int pos, int num) +{ + uint64_t mask = (num == 64) ? ~0ull : ~(~0ull << num); + + return (v >> pos) & mask; +} + +/* + * This function extracts a field of length `num` in the + * logical bitstream represented by `buf[]` starting at position `pos`. + * Each word in `buf[]` is 64 bits. If the field spans 2 words + * then it extracts the bits from the two words and returns the composed result. + */ +static uint64_t +getfield(uint64_t buf[], int pos, int num) +{ + int n, word, bit, rem; + unsigned long long v; + + word = pos / 64; /* 1st word of the field */ + bit = pos % 64; /* offset in the 1st word */ + + n = (bit + num < 64) ? num : 64 - bit; + v = getbits(buf[word], bit, n); + rem = num - n; + if (rem != 0) + v |= getbits(buf[word+1], 0, rem) << n; + + return v; +} + +int +unpack(uint64_t buf[], const char *fmt, ...) +{ + va_list va; + int pos, nbits, ret = -1; + + va_start(va, fmt); + for (pos = 0; *fmt; pos += nbits) { + int d, size; + unsigned long long v; + + nbits = 0; + if (*fmt == ' ') { + fmt++; + continue; + } + + if (*fmt++ != '%') + goto err; + + while (*fmt >= '0' && *fmt <= '9') { + d = *fmt++ - '0'; + nbits = nbits * 10 + d; + } + if (nbits == 0) + goto err; + + size = 0; + v = getfield(buf, pos, nbits); +flags: + switch (*fmt++) { + case 'c': + if (nbits > 8) + goto err; + *va_arg(va, unsigned char *) = v; + break; + case 'h': + size = 1; + goto flags; + case 'l': + size += 2; + goto flags; + case 'u': + switch (size) { + case 0: + if (nbits > 16) + goto err; + *va_arg(va, unsigned *) = v; + break; + case 1: + if (nbits > 16) + goto err; + *va_arg(va, unsigned short *) = v; + break; + case 2: + if (nbits > 32) + goto err; + *va_arg(va, unsigned long *) = v; + break; + case 4: + if (nbits > 64) + goto err; + *va_arg(va, unsigned long long *) = v; + break; + default: + goto err; + } + break; + } + } + va_end(va); + + ret = nbits; +err: + return ret; +} diff --git a/src/ramfw/Makefile b/src/ramfw/Makefile @@ -0,0 +1,16 @@ +PROJECTDIR=../.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = ../rmc.o \ + rmctbl.o \ + +all: builtin.o + +builtin.o: $(OBJS) + $(LD) $(RCODE_LDFLAGS) -r -o $@ $(OBJS) + +rmctbl.c: $(SCRIPTDIR)/rmu.cmd + $(SCRIPTDIR)/gentbl.sh -o $@ -i $(SCRIPTDIR)/rmu.cmd + +clean: + rm -f rmctbl.c diff --git a/src/rmc.c b/src/rmc.c @@ -0,0 +1,52 @@ +#include <rcode.h> + +void +bad_rmc(Ctx *ctx, int error) +{ + dbg("bad RMC: %d, %d = %d\n", ctx->imm1, ctx->imm2, error); + ctx->error = error; + longjmp(ctx->recover, 1); +} + +/* + * The dispatcher cannot be implemented using a table + * because the rmu command number is composed by two + * immediates, imm1 and imm2, which don't generate + * consecutive values. The approach is to use a sparse + * matrix, where we store all the function pointers + * consecutive and we create a row index table which + * the offset from the beginning of the handler table + * and number of entries in that table for that row. + * + * rowidx handler + * --------------- -------- + * | off = 0,cnt=1 | | fun0 | + * --------------- -------- + * imm1--> | off = 1,cnt=2 | ---> off + imm2 --> | fun1 | + * --------------- -------- + * | off = 3,cnt=1 | | fun2 | + * --------------- -------- + * ... ... + */ +void +rmc(unsigned imm1, unsigned imm2, Ctx *ctx) +{ + const struct rowidx *idx; + + if (setjmp(ctx->recover)) + return; + + if (imm1 > 255 || imm2 > 255) + panic("rmc"); + + ctx->imm1 = imm1; + ctx->imm2 = imm2; + + idx = &rowidx[imm1]; + if (imm2 >= idx->cnt) + bad_rmc(ctx, 1); + + (*handler[idx->off + imm2])(); + + ctx->error = 0; +} diff --git a/src/romfw/Makefile b/src/romfw/Makefile @@ -0,0 +1,16 @@ +PROJECTDIR=../.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = ../rmc.o \ + rmctbl.o \ + +all: builtin.o + +builtin.o: $(OBJS) + $(LD) $(RCODE_LDFLAGS) -r -o $@ $(OBJS) + +rmctbl.c: $(SCRIPTDIR)/rmu.cmd + $(SCRIPTDIR)/gentbl.sh -o $@ -i $(SCRIPTDIR)/rmu.cmd + +clean: + rm -f rmctbl.c diff --git a/src/romfw/rmc.c b/src/romfw/rmc.c @@ -0,0 +1,33 @@ +#include <rcode.h> + +void +bad_rmc(Ctx *ctx, int error) +{ + dbg("bad RMC: %d, %d = %d\n", ctx->imm1, ctx->imm2, error); + ctx->error = error; + longjmp(ctx->recover, 1); +} + +void +rmc(unsigned imm1, unsigned imm2, Ctx *ctx) +{ + const struct rowidx *idx; + int offset; + + if (setjmp(ctx->recover)) + return; + + if (imm1 > 255 || imm2 > 255) + panic("rmc"); + + ctx->imm1 = imm1; + ctx->imm2 = imm2; + + idx = &rowidx[imm1]; + if (imm2 >= idx->cnt) + bad_rmc(ctx, 1); + + (*handler[idx->off + imm2])(); + + ctx->error = 0; +} diff --git a/test/.gitignore b/test/.gitignore @@ -0,0 +1,2 @@ +test.log +run diff --git a/test/Makefile b/test/Makefile @@ -0,0 +1,16 @@ +PROJECTDIR = .. +include $(PROJECTDIR)/scripts/rules.mk + +DIRS = test1 test2 + +all: $(DIRS) + +test: FORCE + @MAKE=$(MAKE) ./chktest.sh + +$(DIRS): FORCE + +@cd $@ && $(MAKE) + +clean: + $(FORALL) + rm -f test.log diff --git a/test/chktest.sh b/test/chktest.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +rm -f test.log +pwd=$PWD + +for i in test* +do + cd $i && + $MAKE run_test >> ../test.log 2>&1 && + printf '[PASS]' || printf '[FAIL]' + printf "\t%s\n" $i + cd $pwd +done diff --git a/test/test1/.gitignore b/test/test1/.gitignore @@ -0,0 +1,43 @@ +RMU_Crypto_Random.c +RMU_Local_Load.c +RMU_Local_Status.c +RMU_Local_Validate.c +RMU_REC_Prepare.c +RMU_REC_ReadGeneralPurposeRegister.c +RMU_REC_ReadSystemRegister.c +RMU_REC_ReadVectorRegister.c +RMU_REC_Register.c +RMU_REC_Release.c +RMU_REC_Size.c +RMU_REC_WriteGeneralPurposeRegister.c +RMU_REC_WriteSystemRegister.c +RMU_REC_WriteVectorRegister.c +RMU_Realm_Activate.c +RMU_Realm_AttestationReport.c +RMU_Realm_AttestationReportInit.c +RMU_Realm_AttestationReportSize.c +RMU_Realm_CreateZeroMetadata.c +RMU_Realm_DeriveBindingKey.c +RMU_Realm_ExtendBindingKeySeedValue.c +RMU_Realm_GetBindingKeySeedValue.c +RMU_Realm_GetMetadata.c +RMU_Realm_GetParameterInheritance.c +RMU_Realm_GetParameterValue.c +RMU_Realm_Info.c +RMU_Realm_Initialize.c +RMU_Realm_Invalidate.c +RMU_Realm_InvalidateCurrent.c +RMU_Realm_Populate.c +RMU_Realm_Prepare.c +RMU_Realm_ReadMemory.c +RMU_Realm_Register.c +RMU_Realm_Release.c +RMU_Realm_SetBindingKeySeedLock.c +RMU_Realm_SetCommandTrap.c +RMU_Realm_SetMetadata.c +RMU_Realm_SetParameterInheritance.c +RMU_Realm_SetParameterValue.c +RMU_Realm_WriteMemory.c +RMU_System_Enable.c +RMU_System_InterfaceVersion.c +RMU_System_Status.c diff --git a/test/test1/Makefile b/test/test1/Makefile @@ -0,0 +1,69 @@ +PROJECTDIR = ../.. +include $(PROJECTDIR)/scripts/rules.mk + +LIBOBJ = RMU_Crypto_Random.o \ + RMU_Local_Load.o \ + RMU_Local_Status.o \ + RMU_Local_Validate.o \ + RMU_REC_Prepare.o \ + RMU_REC_ReadGeneralPurposeRegister.o \ + RMU_REC_ReadSystemRegister.o \ + RMU_REC_ReadVectorRegister.o \ + RMU_REC_Register.o \ + RMU_REC_Release.o \ + RMU_REC_Size.o \ + RMU_REC_WriteGeneralPurposeRegister.o \ + RMU_REC_WriteSystemRegister.o \ + RMU_REC_WriteVectorRegister.o \ + RMU_Realm_Activate.o \ + RMU_Realm_AttestationReport.o \ + RMU_Realm_AttestationReportInit.o \ + RMU_Realm_AttestationReportSize.o \ + RMU_Realm_CreateZeroMetadata.o \ + RMU_Realm_DeriveBindingKey.o \ + RMU_Realm_ExtendBindingKeySeedValue.o \ + RMU_Realm_GetBindingKeySeedValue.o \ + RMU_Realm_GetMetadata.o \ + RMU_Realm_GetParameterInheritance.o \ + RMU_Realm_GetParameterValue.o \ + RMU_Realm_Info.o \ + RMU_Realm_Initialize.o \ + RMU_Realm_Invalidate.o \ + RMU_Realm_InvalidateCurrent.o \ + RMU_Realm_Populate.o \ + RMU_Realm_Prepare.o \ + RMU_Realm_ReadMemory.o \ + RMU_Realm_Register.o \ + RMU_Realm_Release.o \ + RMU_Realm_SetBindingKeySeedLock.o \ + RMU_Realm_SetCommandTrap.o \ + RMU_Realm_SetMetadata.o \ + RMU_Realm_SetParameterInheritance.o \ + RMU_Realm_SetParameterValue.o \ + RMU_Realm_WriteMemory.o \ + RMU_System_Enable.o \ + RMU_System_InterfaceVersion.o \ + RMU_System_Status.o \ + +OBJS = $(ARCHDIR)/crt-$(SYS).o $(SRCDIR)/romfw/builtin.o test.o +LIBS = -lrmu -lc +LIBDEP = librmu.a $(LIBDIR)/libc.a + +TARGET = run + +all: $(TARGET) + +$(TARGET): $(OBJS) $(LIBDEP) + $(LD) $(RCODE_LDFLAGS) $(OBJS) $(LIBS) -o $@ + +librmu.a: $(LIBOBJ) + $(AR) $(ARFLAGS) $@ $? + ranlib $@ + +$(LIBOBJ): $(LIBOBJ:.o=.c) + +$(LIBOBJ:.o=.c): genrmu.sh + ./genrmu.sh + +clean: + rm -f $(LIBOBJ:.o=.c) *.a diff --git a/test/test1/genrmu.sh b/test/test1/genrmu.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +genfile() +{ + cat <<FILE >$i.c +#include <rcode.h> + +void +$1(void) +{ + dbg("$1\n"); +} +FILE +} + + +cat <<EOF | while read i; do genfile $i; done +RMU_REC_WriteVectorRegister +RMU_Realm_SetMetadata +RMU_Realm_GetParameterValue +RMU_REC_ReadSystemRegister +RMU_Realm_GetMetadata +RMU_Realm_SetParameterValue +RMU_REC_WriteSystemRegister +RMU_Realm_CreateZeroMetadata +RMU_Realm_GetParameterInheritance +RMU_Realm_SetParameterInheritance +RMU_Realm_Initialize +RMU_Realm_Prepare +RMU_Local_Status +RMU_Realm_Populate +RMU_Local_Load +RMU_Realm_Activate +RMU_Local_Validate +RMU_Realm_Info +RMU_Realm_SetCommandTrap +RMU_Crypto_Random +RMU_Realm_AttestationReportSize +RMU_Realm_AttestationReportInit +RMU_Realm_AttestationReport +RMU_Realm_Register +RMU_Realm_Release +RMU_Realm_ExtendBindingKeySeedValue +RMU_Realm_SetBindingKeySeedLock +RMU_Realm_DeriveBindingKey +RMU_Realm_GetBindingKeySeedValue +RMU_Realm_InvalidateCurrent +RMU_REC_Size +RMU_REC_Register +RMU_System_InterfaceVersion +RMU_REC_Prepare +RMU_System_Status +RMU_REC_Release +RMU_System_Enable +RMU_REC_ReadGeneralPurposeRegister +RMU_REC_WriteGeneralPurposeRegister +RMU_Realm_ReadMemory +RMU_REC_ReadVectorRegister +RMU_Realm_WriteMemory +RMU_Realm_Invalidate +EOF diff --git a/test/test1/test.c b/test/test1/test.c @@ -0,0 +1,26 @@ +#include <assert.h> + +#include <rcode.h> + +int +main(int argc, char *argv[]) +{ + unsigned i, j; + Ctx ctx; + + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + dbg("%u\t%u\t", i, j); + rmc(i, j, &ctx); + } + } + return 0; +} + +void +panic(const char *msg) +{ + printk("panic: %s\n", msg); + for (;;) + ; +} diff --git a/test/test1/test.sh b/test/test1/test.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +set -e + +tmp1=`mktemp` +tmp2=`mktemp` +trap "rm -f $tmp1 $tmp2;exit 1" EXIT INT QUIT TERM + +$EMUCMD ./run | grep -v 'bad RMC' > $tmp1 +sed 's/\./_/g' < $SCRIPTDIR/rmu.cmd > $tmp2 +diff -u $tmp1 $tmp2 + +$EMUCMD ./run | awk ' +/[0-9]+ [0-9]+/ {rmc[$1, $2] = 1} +END { + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) { + if (!rmc[i, j]) { + print "fail", i, j + exit 1 + } + } + } +}' + +rm $tmp1 $tmp2 +trap - EXIT diff --git a/test/test2/Makefile b/test/test2/Makefile @@ -0,0 +1,13 @@ +PROJECTDIR = ../.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = $(ARCHDIR)/crt-$(SYS).o test.o +LIBS = -ltypes -lc +LIBDEP = $(LIBDIR)/libtypes.a $(LIBDIR)/libc.a + +TARGET = run + +all: $(TARGET) + +$(TARGET): $(OBJS) $(LIBDEP) + $(LD) $(RCODE_LDFLAGS) $(OBJS) $(LIBS) -o $@ diff --git a/test/test2/test.c b/test/test2/test.c @@ -0,0 +1,189 @@ +#include <assert.h> +#include <limits.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <types.h> + +#define ITER 1048576*4 + +void +test_pack(void) +{ + uint64_t buf[2]; + unsigned long long v1 = 1, v2 = 0, msb; + int i; + + for (i = 0; i < 128; i++) { + pack(buf, "%64llu %64llu", v1, v2); + printf("0x%llx 0x%llx\n", buf[1], buf[0]); + msb = v1 & 1ull << 63; + v1 <<= 1; + v2 <<= 1; + v2 |= msb != 0; + } +} + +void +test_unpack(void) +{ + uint64_t buf[2]; + unsigned long long v1 = 1, v2 = 0, msb; + int i; + + buf[0] = 1; + buf[1] = 0; + for (i = 0; i < 128; i++) { + unpack(buf, "%64llu %64llu", &v1, &v2); + printf("0x%llx 0x%llx\n", v2, v1); + msb = buf[0] & 1ull << 63; + buf[0] <<= 1; + buf[1] <<= 1; + buf[1] |= msb != 0; + } +} + +long long +rand64(void) +{ + unsigned long long v, i; + + for (v = i = 0; i < sizeof(v); i++) { + v <<= CHAR_BIT; + v |= rand() % UCHAR_MAX; + } + return v; +} + +void +test_pack_unpack_c(uint64_t buf[]) +{ + char fmt[32]; + unsigned char v1, v2, v3, v4; + int b1, b2; + + v1 = rand64(); + v2 = rand64(); + b1 = (rand() % 8) + 1; + b2 = (rand() % 8) + 1; + v1 &= ~(~0ull << b1); + v2 &= ~(~0ull << b2); + snprintf(fmt, sizeof(fmt), "%%%dc %%%dc", b1, b2); + assert(pack(buf, fmt, v1, v2) != -1); + assert(unpack(buf, fmt, &v3, &v4) != -1); + assert(v1 == v3 && v2 == v4); +} + +void +test_pack_unpack_h(uint64_t buf[]) +{ + char fmt[32]; + unsigned short v1, v2, v3, v4; + int b1, b2; + + v1 = rand64(); + v2 = rand64(); + b1 = (rand() % 16) + 1; + b2 = (rand() % 16) + 1; + v1 &= ~(~0ull << b1); + v2 &= ~(~0ull << b2); + snprintf(fmt, sizeof(fmt), "%%%dhu %%%dhu", b1, b2); + assert(pack(buf, fmt, v1, v2) != -1); + assert(unpack(buf, fmt, &v3, &v4) != -1); + assert(v1 == v3 && v2 == v4); +} + +void +test_pack_unpack_u(uint64_t buf[]) +{ + char fmt[32]; + unsigned int v1, v2, v3, v4; + int b1, b2; + + v1 = rand64(); + v2 = rand64(); + b1 = (rand() % 16) + 1; + b2 = (rand() % 16) + 1; + v1 &= ~(~0ull << b1); + v2 &= ~(~0ull << b2); + snprintf(fmt, sizeof(fmt), "%%%du %%%du", b1, b2); + assert(pack(buf, fmt, v1, v2) != -1); + assert(unpack(buf, fmt, &v3, &v4) != -1); + assert(v1 == v3 && v2 == v4); +} + +void +test_pack_unpack_lu(uint64_t buf[]) +{ + char fmt[32]; + unsigned long v1, v2, v3, v4; + int b1, b2; + + v1 = rand64(); + v2 = rand64(); + b1 = (rand() % 32) + 1; + b2 = (rand() % 32) + 1; + v1 &= ~(~0ull << b1); + v2 &= ~(~0ull << b2); + snprintf(fmt, sizeof(fmt), "%%%dlu %%%dlu", b1, b2); + assert(pack(buf, fmt, v1, v2) != -1); + assert(unpack(buf, fmt, &v3, &v4) != -1); + assert(v1 == v3 && v2 == v4); +} + +void +test_pack_unpack_llu(uint64_t buf[]) +{ + char fmt[32]; + unsigned long long v1, v2, v3, v4; + int b1, b2; + + v1 = rand64(); + v2 = rand64(); + b1 = (rand() % 64) + 1; + b2 = (rand() % 64) + 1; + v1 &= ~(~0ull << b1); + v2 &= ~(~0ull << b2); + snprintf(fmt, sizeof(fmt), "%%%dllu %%%dllu", b1, b2); + assert(pack(buf, fmt, v1, v2) != -1); + assert(unpack(buf, fmt, &v3, &v4) != -1); + assert(v1 == v3 && v2 == v4); +} + +void +test_pack_unpack(void) +{ + uint64_t buf[2] = { 0 }; + unsigned long long i; + + for (i = 0; i < ITER; i++) { + switch (rand() % 5) { + case 0: + test_pack_unpack_c(buf); + break; + case 1: + test_pack_unpack_h(buf); + break; + case 2: + test_pack_unpack_u(buf); + break; + case 3: + test_pack_unpack_lu(buf); + break; + case 4: + test_pack_unpack_llu(buf); + break; + } + } +} + +int +main(int argc, char *argv[]) +{ + test_pack(); + test_unpack(); + test_pack_unpack(); + return 0; +} diff --git a/test/test2/test.exp b/test/test2/test.exp @@ -0,0 +1,256 @@ +0x0 0x1 +0x0 0x2 +0x0 0x4 +0x0 0x8 +0x0 0x10 +0x0 0x20 +0x0 0x40 +0x0 0x80 +0x0 0x100 +0x0 0x200 +0x0 0x400 +0x0 0x800 +0x0 0x1000 +0x0 0x2000 +0x0 0x4000 +0x0 0x8000 +0x0 0x10000 +0x0 0x20000 +0x0 0x40000 +0x0 0x80000 +0x0 0x100000 +0x0 0x200000 +0x0 0x400000 +0x0 0x800000 +0x0 0x1000000 +0x0 0x2000000 +0x0 0x4000000 +0x0 0x8000000 +0x0 0x10000000 +0x0 0x20000000 +0x0 0x40000000 +0x0 0x80000000 +0x0 0x100000000 +0x0 0x200000000 +0x0 0x400000000 +0x0 0x800000000 +0x0 0x1000000000 +0x0 0x2000000000 +0x0 0x4000000000 +0x0 0x8000000000 +0x0 0x10000000000 +0x0 0x20000000000 +0x0 0x40000000000 +0x0 0x80000000000 +0x0 0x100000000000 +0x0 0x200000000000 +0x0 0x400000000000 +0x0 0x800000000000 +0x0 0x1000000000000 +0x0 0x2000000000000 +0x0 0x4000000000000 +0x0 0x8000000000000 +0x0 0x10000000000000 +0x0 0x20000000000000 +0x0 0x40000000000000 +0x0 0x80000000000000 +0x0 0x100000000000000 +0x0 0x200000000000000 +0x0 0x400000000000000 +0x0 0x800000000000000 +0x0 0x1000000000000000 +0x0 0x2000000000000000 +0x0 0x4000000000000000 +0x0 0x8000000000000000 +0x1 0x0 +0x2 0x0 +0x4 0x0 +0x8 0x0 +0x10 0x0 +0x20 0x0 +0x40 0x0 +0x80 0x0 +0x100 0x0 +0x200 0x0 +0x400 0x0 +0x800 0x0 +0x1000 0x0 +0x2000 0x0 +0x4000 0x0 +0x8000 0x0 +0x10000 0x0 +0x20000 0x0 +0x40000 0x0 +0x80000 0x0 +0x100000 0x0 +0x200000 0x0 +0x400000 0x0 +0x800000 0x0 +0x1000000 0x0 +0x2000000 0x0 +0x4000000 0x0 +0x8000000 0x0 +0x10000000 0x0 +0x20000000 0x0 +0x40000000 0x0 +0x80000000 0x0 +0x100000000 0x0 +0x200000000 0x0 +0x400000000 0x0 +0x800000000 0x0 +0x1000000000 0x0 +0x2000000000 0x0 +0x4000000000 0x0 +0x8000000000 0x0 +0x10000000000 0x0 +0x20000000000 0x0 +0x40000000000 0x0 +0x80000000000 0x0 +0x100000000000 0x0 +0x200000000000 0x0 +0x400000000000 0x0 +0x800000000000 0x0 +0x1000000000000 0x0 +0x2000000000000 0x0 +0x4000000000000 0x0 +0x8000000000000 0x0 +0x10000000000000 0x0 +0x20000000000000 0x0 +0x40000000000000 0x0 +0x80000000000000 0x0 +0x100000000000000 0x0 +0x200000000000000 0x0 +0x400000000000000 0x0 +0x800000000000000 0x0 +0x1000000000000000 0x0 +0x2000000000000000 0x0 +0x4000000000000000 0x0 +0x8000000000000000 0x0 +0x0 0x1 +0x0 0x2 +0x0 0x4 +0x0 0x8 +0x0 0x10 +0x0 0x20 +0x0 0x40 +0x0 0x80 +0x0 0x100 +0x0 0x200 +0x0 0x400 +0x0 0x800 +0x0 0x1000 +0x0 0x2000 +0x0 0x4000 +0x0 0x8000 +0x0 0x10000 +0x0 0x20000 +0x0 0x40000 +0x0 0x80000 +0x0 0x100000 +0x0 0x200000 +0x0 0x400000 +0x0 0x800000 +0x0 0x1000000 +0x0 0x2000000 +0x0 0x4000000 +0x0 0x8000000 +0x0 0x10000000 +0x0 0x20000000 +0x0 0x40000000 +0x0 0x80000000 +0x0 0x100000000 +0x0 0x200000000 +0x0 0x400000000 +0x0 0x800000000 +0x0 0x1000000000 +0x0 0x2000000000 +0x0 0x4000000000 +0x0 0x8000000000 +0x0 0x10000000000 +0x0 0x20000000000 +0x0 0x40000000000 +0x0 0x80000000000 +0x0 0x100000000000 +0x0 0x200000000000 +0x0 0x400000000000 +0x0 0x800000000000 +0x0 0x1000000000000 +0x0 0x2000000000000 +0x0 0x4000000000000 +0x0 0x8000000000000 +0x0 0x10000000000000 +0x0 0x20000000000000 +0x0 0x40000000000000 +0x0 0x80000000000000 +0x0 0x100000000000000 +0x0 0x200000000000000 +0x0 0x400000000000000 +0x0 0x800000000000000 +0x0 0x1000000000000000 +0x0 0x2000000000000000 +0x0 0x4000000000000000 +0x0 0x8000000000000000 +0x1 0x0 +0x2 0x0 +0x4 0x0 +0x8 0x0 +0x10 0x0 +0x20 0x0 +0x40 0x0 +0x80 0x0 +0x100 0x0 +0x200 0x0 +0x400 0x0 +0x800 0x0 +0x1000 0x0 +0x2000 0x0 +0x4000 0x0 +0x8000 0x0 +0x10000 0x0 +0x20000 0x0 +0x40000 0x0 +0x80000 0x0 +0x100000 0x0 +0x200000 0x0 +0x400000 0x0 +0x800000 0x0 +0x1000000 0x0 +0x2000000 0x0 +0x4000000 0x0 +0x8000000 0x0 +0x10000000 0x0 +0x20000000 0x0 +0x40000000 0x0 +0x80000000 0x0 +0x100000000 0x0 +0x200000000 0x0 +0x400000000 0x0 +0x800000000 0x0 +0x1000000000 0x0 +0x2000000000 0x0 +0x4000000000 0x0 +0x8000000000 0x0 +0x10000000000 0x0 +0x20000000000 0x0 +0x40000000000 0x0 +0x80000000000 0x0 +0x100000000000 0x0 +0x200000000000 0x0 +0x400000000000 0x0 +0x800000000000 0x0 +0x1000000000000 0x0 +0x2000000000000 0x0 +0x4000000000000 0x0 +0x8000000000000 0x0 +0x10000000000000 0x0 +0x20000000000000 0x0 +0x40000000000000 0x0 +0x80000000000000 0x0 +0x100000000000000 0x0 +0x200000000000000 0x0 +0x400000000000000 0x0 +0x800000000000000 0x0 +0x1000000000000000 0x0 +0x2000000000000000 0x0 +0x4000000000000000 0x0 +0x8000000000000000 0x0 diff --git a/test/test2/test.sh b/test/test2/test.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +tmp1=`mktemp` +trap "rm -f $tmp1;exit 1" EXIT INT QUIT TERM + +$EMUCMD ./run > $tmp1 +diff -u $tmp1 test.exp +rm $tmp1 +trap - EXIT