Compare commits
50 Commits
libucontex
...
master
Author | SHA1 | Date |
---|---|---|
matoro | be80075e95 | |
Ariadne Conill | 4c2cfc54ac | |
L. Pereira | 0f625a86ee | |
Ismael Luceno | 8e1397f5a2 | |
Ariadne Conill | 33ff253d52 | |
Richard Campbell | 3044c2b908 | |
Ariadne Conill | 128e4fdc4b | |
Richard Campbell | 5244775fb9 | |
Richard Campbell | 9abcd8afe0 | |
Richard Campbell | 7bc3e90984 | |
Ariadne Conill | 4dde3417b4 | |
Ariadne Conill | 6ec3e63877 | |
Ariadne Conill | 69ebc5e51b | |
Ariadne Conill | 0a72eff002 | |
Ariadne Conill | 973e61441a | |
Ariadne Conill | 00128f7575 | |
Ariadne Conill | 7fc08a6dc6 | |
Ariadne Conill | e26a93806e | |
Ariadne Conill | 5d2f30f96a | |
Ariadne Conill | a51dce6e2c | |
Ariadne Conill | a5ed584aa8 | |
Ariadne Conill | 9943d4f5fc | |
Ariadne Conill | 9403b481bc | |
Ariadne Conill | 2c0c0e5d29 | |
Ariadne Conill | c8fe721e69 | |
Ariadne Conill | c50182d98c | |
Ariadne Conill | 55c91428ba | |
Ariadne Conill | 18aa732212 | |
Ariadne Conill | 8215aedb56 | |
Ariadne Conill | 8efa9e8b85 | |
Torrekie Gen | 6ddefbbbb4 | |
Ariadne Conill | b1b4fe9665 | |
Richard Campbell | 1e37bf30f9 | |
Ariadne Conill | 14d9859c00 | |
Richard Campbell | 06303df1cd | |
Ariadne Conill | ae058b1f38 | |
Peng Fan | a182fee66a | |
Ariadne Conill | 0108623531 | |
Khem Raj | a530eed9e7 | |
Ariadne Conill | 335ee864ef | |
Ariadne Conill | 4d8abf9b3b | |
Ariadne Conill | 7b8f3f6d04 | |
Ariadne Conill | fb1d203677 | |
Ariadne Conill | 1ad20e03e5 | |
Ariadne Conill | 464f98a01b | |
osy | 9b1d8f01a6 | |
osy | 5d66c194a7 | |
osy | f3e1b876c7 | |
Ariadne Conill | f04d423e63 | |
Leandro Pereira | 7823593b6f |
|
@ -0,0 +1,40 @@
|
||||||
|
pipeline:
|
||||||
|
build-x86_64:
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache build-base
|
||||||
|
- make check ARCH=x86_64
|
||||||
|
when:
|
||||||
|
platform: linux/amd64
|
||||||
|
|
||||||
|
build-s390x:
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache build-base
|
||||||
|
- make check ARCH=s390x
|
||||||
|
when:
|
||||||
|
platform: linux/s390x
|
||||||
|
|
||||||
|
build-ppc64le:
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache build-base
|
||||||
|
- make check ARCH=ppc64le
|
||||||
|
when:
|
||||||
|
platform: linux/ppc64le
|
||||||
|
|
||||||
|
build-armv7:
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache build-base
|
||||||
|
- make check ARCH=arm
|
||||||
|
when:
|
||||||
|
platform: linux/arm
|
||||||
|
|
||||||
|
build-aarch64:
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache build-base
|
||||||
|
- make check ARCH=aarch64
|
||||||
|
when:
|
||||||
|
platform: linux/arm64
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2018-2020 Ariadne Conill <ariadne@dereferenced.org>
|
Copyright (c) 2018-2022 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
|
112
Makefile
112
Makefile
|
@ -10,48 +10,91 @@ endif
|
||||||
ifeq ($(ARCH),$(filter $(ARCH),ppc64le))
|
ifeq ($(ARCH),$(filter $(ARCH),ppc64le))
|
||||||
override ARCH = ppc64
|
override ARCH = ppc64
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(ARCH),$(filter $(ARCH),armv7l))
|
||||||
|
override ARCH = arm
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),$(filter $(ARCH),arm64))
|
||||||
|
override ARCH = aarch64
|
||||||
|
endif
|
||||||
|
|
||||||
LIBDIR := /lib
|
prefix = /usr
|
||||||
INCLUDEDIR := /usr/include
|
libdir = ${prefix}/lib
|
||||||
PKGCONFIGDIR := /usr/lib/pkgconfig
|
shared_libdir = ${libdir}
|
||||||
CFLAGS := -ggdb3 -O2 -Wall
|
static_libdir = ${libdir}
|
||||||
|
includedir = ${prefix}/include
|
||||||
|
pkgconfigdir = ${prefix}/lib/pkgconfig
|
||||||
|
|
||||||
|
CFLAGS ?= -ggdb3 -O2 -Wall
|
||||||
CPPFLAGS := -Iinclude -Iarch/${ARCH} -Iarch/common
|
CPPFLAGS := -Iinclude -Iarch/${ARCH} -Iarch/common
|
||||||
EXPORT_UNPREFIXED := yes
|
ifneq ($(shell uname),Darwin)
|
||||||
|
EXPORT_UNPREFIXED := yes
|
||||||
|
else
|
||||||
|
# Darwin does not support aliases
|
||||||
|
EXPORT_UNPREFIXED := no
|
||||||
|
endif
|
||||||
FREESTANDING := no
|
FREESTANDING := no
|
||||||
|
|
||||||
ifeq ($(FREESTANDING),yes)
|
ifeq ($(FREESTANDING),yes)
|
||||||
CFLAGS += -DFREESTANDING -isystem arch/${ARCH}/freestanding
|
CPPFLAGS += -DFREESTANDING
|
||||||
EXPORT_UNPREFIXED = no
|
EXPORT_UNPREFIXED = no
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
FORCE_SOFT_FLOAT := no
|
||||||
|
|
||||||
|
ifeq ($(FORCE_SOFT_FLOAT),yes)
|
||||||
|
CPPFLAGS += -DFORCE_SOFT_FLOAT
|
||||||
|
endif
|
||||||
|
|
||||||
|
FORCE_HARD_FLOAT := no
|
||||||
|
|
||||||
|
ifeq ($(FORCE_HARD_FLOAT),yes)
|
||||||
|
CPPFLAGS += -DFORCE_HARD_FLOAT
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(EXPORT_UNPREFIXED),yes)
|
ifeq ($(EXPORT_UNPREFIXED),yes)
|
||||||
CFLAGS += -DEXPORT_UNPREFIXED
|
CPPFLAGS += -DEXPORT_UNPREFIXED
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBUCONTEXT_C_SRC = $(wildcard arch/${ARCH}/*.c)
|
LIBUCONTEXT_C_SRC = $(wildcard arch/${ARCH}/*.c)
|
||||||
LIBUCONTEXT_S_SRC = $(wildcard arch/${ARCH}/*.S)
|
LIBUCONTEXT_S_SRC = $(wildcard arch/${ARCH}/*.S)
|
||||||
|
|
||||||
|
ifeq ($(shell test -d arch/${ARCH}/include; echo $?),0)
|
||||||
|
CPPFLAGS += -Iarch/${ARCH}/include
|
||||||
|
endif
|
||||||
|
|
||||||
LIBUCONTEXT_VERSION := $(shell head -n 1 VERSION)
|
LIBUCONTEXT_VERSION := $(shell head -n 1 VERSION)
|
||||||
LIBUCONTEXT_OBJ = ${LIBUCONTEXT_C_SRC:.c=.o} ${LIBUCONTEXT_S_SRC:.S=.o}
|
LIBUCONTEXT_OBJ = ${LIBUCONTEXT_C_SRC:.c=.o} ${LIBUCONTEXT_S_SRC:.S=.o}
|
||||||
LIBUCONTEXT_SOVERSION = 1
|
LIBUCONTEXT_SOVERSION = 1
|
||||||
LIBUCONTEXT_NAME = libucontext.so
|
ifeq ($(shell uname),Darwin)
|
||||||
|
LIBUCONTEXT_NAME = libucontext.dylib
|
||||||
|
LIBUCONTEXT_SONAME = libucontext.${LIBUCONTEXT_SOVERSION}.dylib
|
||||||
|
LIBUCONTEXT_POSIX_NAME = libucontext_posix.dylib
|
||||||
|
LIBUCONTEXT_POSIX_SONAME = libucontext_posix.${LIBUCONTEXT_SOVERSION}.dylib
|
||||||
|
LIBUCONTEXT_LINKER_FLAGS = -Wl,-dynamiclib,-install_name,${LIBUCONTEXT_SONAME},-current_version,${LIBUCONTEXT_SOVERSION},-compatibility_version,${LIBUCONTEXT_SOVERSION}
|
||||||
|
LIBUCONTEXT_POSIX_LINKER_FLAGS = -Wl,-dynamiclib,-install_name,${LIBUCONTEXT_POSIX_SONAME},-current_version,${LIBUCONTEXT_SOVERSION},-compatibility_version,${LIBUCONTEXT_SOVERSION}
|
||||||
|
else
|
||||||
|
LIBUCONTEXT_NAME = libucontext.so
|
||||||
|
LIBUCONTEXT_SONAME = libucontext.so.${LIBUCONTEXT_SOVERSION}
|
||||||
|
LIBUCONTEXT_POSIX_NAME = libucontext_posix.so
|
||||||
|
LIBUCONTEXT_POSIX_SONAME = libucontext_posix.so.${LIBUCONTEXT_SOVERSION}
|
||||||
|
LIBUCONTEXT_LINKER_FLAGS = -shared -Wl,-soname,${LIBUCONTEXT_SONAME} -Wl,-z,noexecstack
|
||||||
|
LIBUCONTEXT_POSIX_LINKER_FLAGS = -shared -Wl,-soname,${LIBUCONTEXT_POSIX_SONAME} -Wl,-z,noexecstack
|
||||||
|
ASFLAGS = -Wa,--noexecstack
|
||||||
|
endif
|
||||||
LIBUCONTEXT_STATIC_NAME = libucontext.a
|
LIBUCONTEXT_STATIC_NAME = libucontext.a
|
||||||
LIBUCONTEXT_PC = libucontext.pc
|
LIBUCONTEXT_PC = libucontext.pc
|
||||||
LIBUCONTEXT_SONAME = libucontext.so.${LIBUCONTEXT_SOVERSION}
|
LIBUCONTEXT_PATH = ${shared_libdir}/${LIBUCONTEXT_SONAME}
|
||||||
LIBUCONTEXT_PATH = ${LIBDIR}/${LIBUCONTEXT_SONAME}
|
LIBUCONTEXT_STATIC_PATH = ${static_libdir}/${LIBUCONTEXT_STATIC_NAME}
|
||||||
LIBUCONTEXT_STATIC_PATH = ${LIBDIR}/${LIBUCONTEXT_STATIC_NAME}
|
|
||||||
LIBUCONTEXT_HEADERS = \
|
LIBUCONTEXT_HEADERS = \
|
||||||
include/libucontext/libucontext.h \
|
include/libucontext/libucontext.h \
|
||||||
include/libucontext/bits.h
|
include/libucontext/bits.h
|
||||||
LIBUCONTEXT_EXAMPLES = \
|
LIBUCONTEXT_EXAMPLES = \
|
||||||
examples/cooperative_threading
|
examples/cooperative_threading
|
||||||
LIBUCONTEXT_POSIX_NAME = libucontext_posix.so
|
|
||||||
LIBUCONTEXT_POSIX_STATIC_NAME = libucontext_posix.a
|
LIBUCONTEXT_POSIX_STATIC_NAME = libucontext_posix.a
|
||||||
LIBUCONTEXT_POSIX_C_SRC = libucontext_posix.c
|
LIBUCONTEXT_POSIX_C_SRC = libucontext_posix.c
|
||||||
LIBUCONTEXT_POSIX_OBJ = ${LIBUCONTEXT_POSIX_C_SRC:.c=.o}
|
LIBUCONTEXT_POSIX_OBJ = ${LIBUCONTEXT_POSIX_C_SRC:.c=.o}
|
||||||
LIBUCONTEXT_POSIX_SONAME = libucontext_posix.so.${LIBUCONTEXT_SOVERSION}
|
LIBUCONTEXT_POSIX_PATH = ${shared_libdir}/${LIBUCONTEXT_POSIX_SONAME}
|
||||||
LIBUCONTEXT_POSIX_PATH = ${LIBDIR}/${LIBUCONTEXT_POSIX_SONAME}
|
LIBUCONTEXT_POSIX_STATIC_PATH = ${static_libdir}/${LIBUCONTEXT_POSIX_STATIC_NAME}
|
||||||
LIBUCONTEXT_POSIX_STATIC_PATH = ${LIBDIR}/${LIBUCONTEXT_POSIX_STATIC_NAME}
|
|
||||||
|
|
||||||
ifeq ($(FREESTANDING),yes)
|
ifeq ($(FREESTANDING),yes)
|
||||||
LIBUCONTEXT_POSIX_NAME =
|
LIBUCONTEXT_POSIX_NAME =
|
||||||
|
@ -61,8 +104,7 @@ endif
|
||||||
all: ${LIBUCONTEXT_SONAME} ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_POSIX_NAME} ${LIBUCONTEXT_POSIX_STATIC_NAME} ${LIBUCONTEXT_PC}
|
all: ${LIBUCONTEXT_SONAME} ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_POSIX_NAME} ${LIBUCONTEXT_POSIX_STATIC_NAME} ${LIBUCONTEXT_PC}
|
||||||
|
|
||||||
${LIBUCONTEXT_POSIX_NAME}: ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_POSIX_OBJ}
|
${LIBUCONTEXT_POSIX_NAME}: ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_POSIX_OBJ}
|
||||||
$(CC) -fPIC -o ${LIBUCONTEXT_POSIX_NAME} -Wl,-soname,${LIBUCONTEXT_POSIX_SONAME} \
|
$(CC) -fPIC -o ${LIBUCONTEXT_POSIX_NAME} ${LIBUCONTEXT_POSIX_LINKER_FLAGS} ${LIBUCONTEXT_POSIX_OBJ} -L. -lucontext ${LDFLAGS}
|
||||||
-shared ${LIBUCONTEXT_POSIX_OBJ} ${LDFLAGS}
|
|
||||||
|
|
||||||
${LIBUCONTEXT_POSIX_STATIC_NAME}: ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_POSIX_OBJ}
|
${LIBUCONTEXT_POSIX_STATIC_NAME}: ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_POSIX_OBJ}
|
||||||
$(AR) rcs ${LIBUCONTEXT_POSIX_STATIC_NAME} ${LIBUCONTEXT_POSIX_OBJ}
|
$(AR) rcs ${LIBUCONTEXT_POSIX_STATIC_NAME} ${LIBUCONTEXT_POSIX_OBJ}
|
||||||
|
@ -74,16 +116,16 @@ ${LIBUCONTEXT_STATIC_NAME}: ${LIBUCONTEXT_HEADERS} ${LIBUCONTEXT_OBJ}
|
||||||
$(AR) rcs ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_OBJ}
|
$(AR) rcs ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_OBJ}
|
||||||
|
|
||||||
${LIBUCONTEXT_NAME}: ${LIBUCONTEXT_HEADERS} ${LIBUCONTEXT_OBJ}
|
${LIBUCONTEXT_NAME}: ${LIBUCONTEXT_HEADERS} ${LIBUCONTEXT_OBJ}
|
||||||
$(CC) -fPIC -o ${LIBUCONTEXT_NAME} -Wl,-soname,${LIBUCONTEXT_SONAME} \
|
$(CC) -fPIC -o ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_LINKER_FLAGS} ${LIBUCONTEXT_OBJ} ${LDFLAGS}
|
||||||
-shared ${LIBUCONTEXT_OBJ} ${LDFLAGS}
|
|
||||||
|
|
||||||
${LIBUCONTEXT_SONAME}: ${LIBUCONTEXT_NAME}
|
${LIBUCONTEXT_SONAME}: ${LIBUCONTEXT_NAME}
|
||||||
ln -sf ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_SONAME}
|
ln -sf ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_SONAME}
|
||||||
|
|
||||||
${LIBUCONTEXT_PC}: libucontext.pc.in
|
${LIBUCONTEXT_PC}: libucontext.pc.in
|
||||||
sed -e s:@LIBUCONTEXT_VERSION@:${LIBUCONTEXT_VERSION}:g \
|
sed -e s:@LIBUCONTEXT_VERSION@:${LIBUCONTEXT_VERSION}:g \
|
||||||
-e s:@LIBUCONTEXT_LIBDIR@:${LIBDIR}:g \
|
-e s:@LIBUCONTEXT_SHARED_LIBDIR@:${shared_libdir}:g \
|
||||||
-e s:@LIBUCONTEXT_INCLUDEDIR@:${INCLUDEDIR}:g $< > $@
|
-e s:@LIBUCONTEXT_STATIC_LIBDIR@:${static_libdir}:g \
|
||||||
|
-e s:@LIBUCONTEXT_INCLUDEDIR@:${includedir}:g $< > $@
|
||||||
|
|
||||||
MANPAGES_SYMLINKS_3 = \
|
MANPAGES_SYMLINKS_3 = \
|
||||||
libucontext_getcontext.3 \
|
libucontext_getcontext.3 \
|
||||||
|
@ -105,7 +147,7 @@ docs: ${MANPAGES}
|
||||||
$(CC) -std=gnu99 -D_BSD_SOURCE -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
|
$(CC) -std=gnu99 -D_BSD_SOURCE -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
|
||||||
|
|
||||||
.S.o:
|
.S.o:
|
||||||
$(CC) -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
|
$(CC) -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} ${ASFLAGS} -c -o $@ $<
|
||||||
|
|
||||||
${LIBUCONTEXT_NAME}_clean:
|
${LIBUCONTEXT_NAME}_clean:
|
||||||
rm -f ${LIBUCONTEXT_NAME}
|
rm -f ${LIBUCONTEXT_NAME}
|
||||||
|
@ -128,6 +170,9 @@ bits_clean:
|
||||||
${LIBUCONTEXT_POSIX_NAME}_clean:
|
${LIBUCONTEXT_POSIX_NAME}_clean:
|
||||||
rm -f ${LIBUCONTEXT_POSIX_NAME}
|
rm -f ${LIBUCONTEXT_POSIX_NAME}
|
||||||
|
|
||||||
|
${LIBUCONTEXT_POSIX_SONAME}_clean:
|
||||||
|
rm -f ${LIBUCONTEXT_POSIX_SONAME}
|
||||||
|
|
||||||
${LIBUCONTEXT_POSIX_STATIC_NAME}_clean:
|
${LIBUCONTEXT_POSIX_STATIC_NAME}_clean:
|
||||||
rm -f ${LIBUCONTEXT_POSIX_STATIC_NAME}
|
rm -f ${LIBUCONTEXT_POSIX_STATIC_NAME}
|
||||||
|
|
||||||
|
@ -154,6 +199,7 @@ clean: ${LIBUCONTEXT_STATIC_NAME}_clean
|
||||||
clean: ${LIBUCONTEXT_PC}_clean
|
clean: ${LIBUCONTEXT_PC}_clean
|
||||||
clean: bits_clean
|
clean: bits_clean
|
||||||
clean: ${LIBUCONTEXT_POSIX_NAME}_clean
|
clean: ${LIBUCONTEXT_POSIX_NAME}_clean
|
||||||
|
clean: ${LIBUCONTEXT_POSIX_SONAME}_clean
|
||||||
clean: ${LIBUCONTEXT_POSIX_STATIC_NAME}_clean
|
clean: ${LIBUCONTEXT_POSIX_STATIC_NAME}_clean
|
||||||
clean: libucontext_posix_obj_clean
|
clean: libucontext_posix_obj_clean
|
||||||
clean: libucontext_obj_clean
|
clean: libucontext_obj_clean
|
||||||
|
@ -163,13 +209,13 @@ clean: docs_clean
|
||||||
install: all
|
install: all
|
||||||
install -D -m755 ${LIBUCONTEXT_NAME} ${DESTDIR}${LIBUCONTEXT_PATH}
|
install -D -m755 ${LIBUCONTEXT_NAME} ${DESTDIR}${LIBUCONTEXT_PATH}
|
||||||
install -D -m664 ${LIBUCONTEXT_STATIC_NAME} ${DESTDIR}${LIBUCONTEXT_STATIC_PATH}
|
install -D -m664 ${LIBUCONTEXT_STATIC_NAME} ${DESTDIR}${LIBUCONTEXT_STATIC_PATH}
|
||||||
ln -sf ${LIBUCONTEXT_SONAME} ${DESTDIR}${LIBDIR}/${LIBUCONTEXT_NAME}
|
ln -sf ${LIBUCONTEXT_SONAME} ${DESTDIR}${shared_libdir}/${LIBUCONTEXT_NAME}
|
||||||
for i in ${LIBUCONTEXT_HEADERS}; do \
|
for i in ${LIBUCONTEXT_HEADERS}; do \
|
||||||
destfn=$$(echo $$i | sed s:include/::g); \
|
destfn=$$(echo $$i | sed s:include/::g); \
|
||||||
install -D -m644 $$i ${DESTDIR}${INCLUDEDIR}/$$destfn; \
|
install -D -m644 $$i ${DESTDIR}${includedir}/$$destfn; \
|
||||||
done
|
done
|
||||||
install -D -m644 ${LIBUCONTEXT_PC} ${DESTDIR}${PKGCONFIGDIR}/${LIBUCONTEXT_PC}
|
install -D -m644 ${LIBUCONTEXT_PC} ${DESTDIR}${pkgconfigdir}/${LIBUCONTEXT_PC}
|
||||||
if [ -n ${LIBUCONTEXT_POSIX_NAME} ]; then \
|
if [ -n "${LIBUCONTEXT_POSIX_NAME}" ]; then \
|
||||||
install -D -m755 ${LIBUCONTEXT_POSIX_NAME} ${DESTDIR}${LIBUCONTEXT_POSIX_PATH}; \
|
install -D -m755 ${LIBUCONTEXT_POSIX_NAME} ${DESTDIR}${LIBUCONTEXT_POSIX_PATH}; \
|
||||||
install -D -m644 ${LIBUCONTEXT_POSIX_STATIC_NAME} ${DESTDIR}${LIBUCONTEXT_POSIX_STATIC_PATH}; \
|
install -D -m644 ${LIBUCONTEXT_POSIX_STATIC_NAME} ${DESTDIR}${LIBUCONTEXT_POSIX_STATIC_PATH}; \
|
||||||
fi
|
fi
|
||||||
|
@ -183,7 +229,7 @@ install_docs: docs
|
||||||
ifneq (${FREESTANDING},yes)
|
ifneq (${FREESTANDING},yes)
|
||||||
check: check_libucontext_posix
|
check: check_libucontext_posix
|
||||||
|
|
||||||
check_libucontext_posix: test_libucontext_posix ${LIBUCONTEXT_POSIX_SONAME}
|
check_libucontext_posix: test_libucontext_posix ${LIBUCONTEXT_POSIX_SONAME} ${LIBUCONTEXT_SONAME}
|
||||||
env LD_LIBRARY_PATH=$(shell pwd) ./test_libucontext_posix
|
env LD_LIBRARY_PATH=$(shell pwd) ./test_libucontext_posix
|
||||||
|
|
||||||
test_libucontext_posix: test_libucontext_posix.c ${LIBUCONTEXT_POSIX_NAME}
|
test_libucontext_posix: test_libucontext_posix.c ${LIBUCONTEXT_POSIX_NAME}
|
||||||
|
@ -200,9 +246,11 @@ test_libucontext_bare_posixabi: test_libucontext_posix.c ${LIBUCONTEXT_NAME}
|
||||||
$(CC) -std=gnu99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} test_libucontext_posix.c -o $@ -L. -lucontext
|
$(CC) -std=gnu99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} test_libucontext_posix.c -o $@ -L. -lucontext
|
||||||
endif
|
endif
|
||||||
|
|
||||||
check: test_libucontext ${LIBUCONTEXT_SONAME}
|
check_libucontext: test_libucontext ${LIBUCONTEXT_SONAME}
|
||||||
env LD_LIBRARY_PATH=$(shell pwd) ./test_libucontext
|
env LD_LIBRARY_PATH=$(shell pwd) ./test_libucontext
|
||||||
|
|
||||||
|
check: check_libucontext
|
||||||
|
|
||||||
test_libucontext: test_libucontext.c ${LIBUCONTEXT_NAME}
|
test_libucontext: test_libucontext.c ${LIBUCONTEXT_NAME}
|
||||||
$(CC) -std=gnu99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} $@.c -o $@ -L. -lucontext
|
$(CC) -std=gnu99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} $@.c -o $@ -L. -lucontext
|
||||||
|
|
||||||
|
@ -212,13 +260,13 @@ examples/cooperative_threading: examples/cooperative_threading.c ${LIBUCONTEXT_N
|
||||||
|
|
||||||
ifeq ($(FREESTANDING),no)
|
ifeq ($(FREESTANDING),no)
|
||||||
|
|
||||||
include/libucontext/bits.h: arch/common/bits.h
|
include/libucontext/bits.h: arch/common/include/libucontext/bits.h
|
||||||
cp arch/common/bits.h $@
|
cp $< $@
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
include/libucontext/bits.h: arch/${ARCH}/freestanding/bits.h
|
include/libucontext/bits.h: arch/${ARCH}/include/libucontext/bits.h
|
||||||
cp arch/${ARCH}/freestanding/bits.h $@
|
cp $< $@
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
33
NEWS
33
NEWS
|
@ -1,3 +1,36 @@
|
||||||
|
Changes from 1.1 to 1.2
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* Added Loongarch64 port.
|
||||||
|
|
||||||
|
* Added OpenRISC (or1k) port.
|
||||||
|
|
||||||
|
* Fixed various build system issues:
|
||||||
|
- libucontext_posix.so is no longer underlinked
|
||||||
|
- Executable stacks are now disabled when using GNU-like toolchains
|
||||||
|
- CPPFLAGS is used consistently
|
||||||
|
- Users may now build on Darwin without using Meson
|
||||||
|
|
||||||
|
* aarch64 now implements the necessary SIMD register save/restore as
|
||||||
|
mandatory in AAPCS64.
|
||||||
|
Patches contributed by Richard Campbell.
|
||||||
|
|
||||||
|
Changes from 1.0 to 1.1
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* Added RISC-V RV32 port.
|
||||||
|
|
||||||
|
* Cleaned up use of _GNU_SOURCE in C code.
|
||||||
|
Partially from patches contributed by osy.
|
||||||
|
|
||||||
|
* Added automatic detection of armv7l architecture.
|
||||||
|
Patch contributed by Leandro Pereira.
|
||||||
|
|
||||||
|
* Fixed installation path of libucontext_posix.a.
|
||||||
|
|
||||||
|
* Work around deficiency in clang built-in assembler on AArch64 targets.
|
||||||
|
Patch contributed by osy.
|
||||||
|
|
||||||
Changes from 0.13.1 to 1.0
|
Changes from 0.13.1 to 1.0
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
|
25
README.md
25
README.md
|
@ -20,11 +20,14 @@ target to do it.
|
||||||
|--------------|---------------|---------|-----------------------|-------------------|
|
|--------------|---------------|---------|-----------------------|-------------------|
|
||||||
| aarch64 | ✓ | | ✓ | ✓ |
|
| aarch64 | ✓ | | ✓ | ✓ |
|
||||||
| arm | ✓ | | ✓ | ✓ |
|
| arm | ✓ | | ✓ | ✓ |
|
||||||
|
| loongarch64 | ✓ | | ✓ | |
|
||||||
| m68k | ✓ | | ✓ | ✓ |
|
| m68k | ✓ | | ✓ | ✓ |
|
||||||
| mips | ✓ | | ✓ | |
|
| mips | ✓ | | ✓ | |
|
||||||
| mips64 | ✓ | | ✓ | |
|
| mips64 | ✓ | | ✓ | |
|
||||||
|
| or1k | ✓ | | ✓ | ✓ |
|
||||||
| ppc | ✓ | ✓ | | |
|
| ppc | ✓ | ✓ | | |
|
||||||
| ppc64 | ✓ | ✓ | | |
|
| ppc64 | ✓ | ✓ | | |
|
||||||
|
| riscv32 | ✓ | | ✓ | ✓ |
|
||||||
| riscv64 | ✓ | | ✓ | ✓ |
|
| riscv64 | ✓ | | ✓ | ✓ |
|
||||||
| s390x | ✓ | | ✓ | |
|
| s390x | ✓ | | ✓ | |
|
||||||
| sh | ✓ | | ✓ | ✓ |
|
| sh | ✓ | | ✓ | ✓ |
|
||||||
|
@ -70,15 +73,26 @@ $ make DESTDIR=out install_docs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## real-world use cases
|
||||||
|
|
||||||
|
`libucontext` is used on almost all musl distributions to provide the legacy `ucontext.h` API.
|
||||||
|
Additionally, it is used by:
|
||||||
|
|
||||||
|
* [UTM](https://getutm.app) -- friendly qemu distribution for macOS and iOS devices. UTM uses libucontext
|
||||||
|
as qemu's coroutine backend.
|
||||||
|
|
||||||
|
* [Lwan](https://lwan.ws) -- a high-performance embeddable asynchronous web server. Lwan uses libucontext
|
||||||
|
to provide green threads when building on non-x86 architectures.
|
||||||
|
|
||||||
|
|
||||||
## caveats
|
## caveats
|
||||||
|
|
||||||
`libucontext`, while largely functionally equivalent does have some differences over traditional POSIX
|
`libucontext`, while largely functionally equivalent does have some differences over traditional POSIX
|
||||||
ucontext functions:
|
ucontext functions:
|
||||||
|
|
||||||
* Saving and restoring the signal mask is not implemented. This is largely a non-issue because most
|
* Saving and restoring the signal mask is not implemented by default in order to avoid kernel syscall
|
||||||
uses of these functions did not modify the signal mask anyway, but saving/restoring the signal mask
|
overhead. Use `-lucontext_posix` if you actually need this functionality, which provides a POSIX
|
||||||
(even though it is unmodified in basically all cases in practice) induces a significant performance
|
compliant implementation at the cost of performance.
|
||||||
penalty due to having to make kernel syscalls.
|
|
||||||
|
|
||||||
* Only basic GPR registers are saved and restored when context swapping. The glibc implementation uses
|
* Only basic GPR registers are saved and restored when context swapping. The glibc implementation uses
|
||||||
hardware capability detection to save/restore other register groups, such as the FPU registers or
|
hardware capability detection to save/restore other register groups, such as the FPU registers or
|
||||||
|
@ -87,4 +101,5 @@ ucontext functions:
|
||||||
save/restore FPU registers or vector registers may be added in a later release as a build-time
|
save/restore FPU registers or vector registers may be added in a later release as a build-time
|
||||||
setting -- for now, we assume a soft-float ABI with no optional processor features. In practice, this
|
setting -- for now, we assume a soft-float ABI with no optional processor features. In practice, this
|
||||||
does not really matter, code using these functions are unlikely to be impacted by this design
|
does not really matter, code using these functions are unlikely to be impacted by this design
|
||||||
assumption.
|
assumption. This is a work in progress, as newer compilers will spill even non-floating-point state
|
||||||
|
through floating point registers when allowed to do so.
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#define SP_OFFSET 432
|
#define SP_OFFSET 432
|
||||||
#define PC_OFFSET 440
|
#define PC_OFFSET 440
|
||||||
#define PSTATE_OFFSET 448
|
#define PSTATE_OFFSET 448
|
||||||
|
#define FPSIMD_CONTEXT_OFFSET 464
|
||||||
|
|
||||||
#ifndef FPSIMD_MAGIC
|
#ifndef FPSIMD_MAGIC
|
||||||
# define FPSIMD_MAGIC 0x46508001
|
# define FPSIMD_MAGIC 0x46508001
|
||||||
|
|
|
@ -15,7 +15,11 @@
|
||||||
ALIAS(getcontext, libucontext_getcontext)
|
ALIAS(getcontext, libucontext_getcontext)
|
||||||
ALIAS(__getcontext, libucontext_getcontext)
|
ALIAS(__getcontext, libucontext_getcontext)
|
||||||
|
|
||||||
FUNC(libucontext_getcontext)
|
.global PROC_NAME(libucontext_getcontext);
|
||||||
|
.align 2;
|
||||||
|
TYPE(libucontext_getcontext)
|
||||||
|
ENT(libucontext_getcontext)
|
||||||
|
PROC_NAME(libucontext_getcontext):
|
||||||
str xzr, [x0, #REG_OFFSET(0)]
|
str xzr, [x0, #REG_OFFSET(0)]
|
||||||
|
|
||||||
/* save GPRs */
|
/* save GPRs */
|
||||||
|
@ -46,7 +50,11 @@ FUNC(libucontext_getcontext)
|
||||||
/* save pstate */
|
/* save pstate */
|
||||||
str xzr, [x0, #PSTATE_OFFSET]
|
str xzr, [x0, #PSTATE_OFFSET]
|
||||||
|
|
||||||
/* TODO: SIMD / FPRs */
|
add x2, x0, #FPSIMD_CONTEXT_OFFSET
|
||||||
|
stp q8, q9, [x2, #144]
|
||||||
|
stp q10, q11, [x2, #176]
|
||||||
|
stp q12, q13, [x2, #208]
|
||||||
|
stp q14, q15, [x2, #240]
|
||||||
|
|
||||||
mov x0, #0
|
mov x0, #0
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -15,7 +15,11 @@
|
||||||
ALIAS(setcontext, libucontext_setcontext)
|
ALIAS(setcontext, libucontext_setcontext)
|
||||||
ALIAS(__setcontext, libucontext_setcontext)
|
ALIAS(__setcontext, libucontext_setcontext)
|
||||||
|
|
||||||
FUNC(libucontext_setcontext)
|
.global PROC_NAME(libucontext_setcontext);
|
||||||
|
.align 2;
|
||||||
|
TYPE(libucontext_setcontext)
|
||||||
|
ENT(libucontext_setcontext)
|
||||||
|
PROC_NAME(libucontext_setcontext):
|
||||||
/* restore GPRs */
|
/* restore GPRs */
|
||||||
ldp x18, x19, [x0, #REG_OFFSET(18)]
|
ldp x18, x19, [x0, #REG_OFFSET(18)]
|
||||||
ldp x20, x21, [x0, #REG_OFFSET(20)]
|
ldp x20, x21, [x0, #REG_OFFSET(20)]
|
||||||
|
@ -29,7 +33,11 @@ FUNC(libucontext_setcontext)
|
||||||
ldr x2, [x0, #SP_OFFSET]
|
ldr x2, [x0, #SP_OFFSET]
|
||||||
mov sp, x2
|
mov sp, x2
|
||||||
|
|
||||||
/* TODO: SIMD / FPRs */
|
add x2, x0, #FPSIMD_CONTEXT_OFFSET
|
||||||
|
ldp q8, q9, [x2, #144]
|
||||||
|
ldp q10, q11, [x2, #176]
|
||||||
|
ldp q12, q13, [x2, #208]
|
||||||
|
ldp q14, q15, [x2, #240]
|
||||||
|
|
||||||
/* save current program counter in link register */
|
/* save current program counter in link register */
|
||||||
ldr x16, [x0, #PC_OFFSET]
|
ldr x16, [x0, #PC_OFFSET]
|
||||||
|
|
|
@ -15,7 +15,11 @@
|
||||||
ALIAS(swapcontext, libucontext_swapcontext)
|
ALIAS(swapcontext, libucontext_swapcontext)
|
||||||
ALIAS(__swapcontext, libucontext_swapcontext)
|
ALIAS(__swapcontext, libucontext_swapcontext)
|
||||||
|
|
||||||
FUNC(libucontext_swapcontext)
|
.global PROC_NAME(libucontext_swapcontext);
|
||||||
|
.align 2;
|
||||||
|
TYPE(libucontext_swapcontext)
|
||||||
|
ENT(libucontext_swapcontext)
|
||||||
|
PROC_NAME(libucontext_swapcontext):
|
||||||
str xzr, [x0, #REG_OFFSET(0)]
|
str xzr, [x0, #REG_OFFSET(0)]
|
||||||
|
|
||||||
/* save GPRs */
|
/* save GPRs */
|
||||||
|
@ -45,6 +49,12 @@ FUNC(libucontext_swapcontext)
|
||||||
/* save pstate */
|
/* save pstate */
|
||||||
str xzr, [x0, #PSTATE_OFFSET]
|
str xzr, [x0, #PSTATE_OFFSET]
|
||||||
|
|
||||||
|
add x2, x0, #FPSIMD_CONTEXT_OFFSET
|
||||||
|
stp q8, q9, [x2, #144]
|
||||||
|
stp q10, q11, [x2, #176]
|
||||||
|
stp q12, q13, [x2, #208]
|
||||||
|
stp q14, q15, [x2, #240]
|
||||||
|
|
||||||
/* context to swap to is in x1 so... we move to x0 and call setcontext */
|
/* context to swap to is in x1 so... we move to x0 and call setcontext */
|
||||||
/* store our link register in x28 */
|
/* store our link register in x28 */
|
||||||
mov x28, x30
|
mov x28, x30
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
#define REG_SZ (4)
|
#define REG_SZ (4)
|
||||||
#define MCONTEXT_GREGS (32)
|
#define MCONTEXT_GREGS (32)
|
||||||
|
#define VFP_MAGIC_OFFSET (232)
|
||||||
|
#define VFP_D8_OFFSET (304)
|
||||||
|
|
||||||
#define TYPE(__proc)
|
#define TYPE(__proc) .type __proc, %function;
|
||||||
|
|
||||||
#define FETCH_LINKPTR(dest) \
|
#define FETCH_LINKPTR(dest) \
|
||||||
asm("movs %0, r4" : "=r" ((dest)))
|
asm("movs %0, r4" : "=r" ((dest)))
|
||||||
|
|
|
@ -22,6 +22,27 @@ FUNC(libucontext_getcontext)
|
||||||
str r13, [r0, #REG_OFFSET(13)]
|
str r13, [r0, #REG_OFFSET(13)]
|
||||||
str r14, [r0, #REG_OFFSET(15)]
|
str r14, [r0, #REG_OFFSET(15)]
|
||||||
|
|
||||||
|
#ifndef FORCE_SOFT_FLOAT
|
||||||
|
#ifndef FORCE_HARD_FLOAT
|
||||||
|
/* test for vfp, set kernel-defined magic number in uc_regspace */
|
||||||
|
push {r0-r1,fp,lr}
|
||||||
|
mov r0, #16
|
||||||
|
bl getauxval
|
||||||
|
tst r0, #64
|
||||||
|
pop {r0-r1,fp,lr}
|
||||||
|
moveq r2, #0
|
||||||
|
ldrne r2, =#0x56465001
|
||||||
|
str r2, [r0, #VFP_MAGIC_OFFSET]
|
||||||
|
beq 1f
|
||||||
|
#endif
|
||||||
|
/* if vfp detected, save d8-d15 */
|
||||||
|
.fpu vfp
|
||||||
|
add r1, r0, #VFP_D8_OFFSET
|
||||||
|
vstmia r1, {d8-d15}
|
||||||
|
.fpu softvfp
|
||||||
|
1:
|
||||||
|
#endif
|
||||||
|
|
||||||
/* return 0 */
|
/* return 0 */
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
|
|
@ -23,6 +23,8 @@ typedef struct libucontext_ucontext {
|
||||||
struct libucontext_ucontext *uc_link;
|
struct libucontext_ucontext *uc_link;
|
||||||
libucontext_stack_t uc_stack;
|
libucontext_stack_t uc_stack;
|
||||||
libucontext_mcontext_t uc_mcontext;
|
libucontext_mcontext_t uc_mcontext;
|
||||||
|
unsigned long uc_sigmask[128 / sizeof(long)];
|
||||||
|
unsigned long long uc_regspace[64];
|
||||||
} libucontext_ucontext_t;
|
} libucontext_ucontext_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -10,9 +10,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -16,6 +16,22 @@ ALIAS(setcontext, libucontext_setcontext)
|
||||||
ALIAS(__setcontext, libucontext_setcontext)
|
ALIAS(__setcontext, libucontext_setcontext)
|
||||||
|
|
||||||
FUNC(libucontext_setcontext)
|
FUNC(libucontext_setcontext)
|
||||||
|
#ifndef FORCE_SOFT_FLOAT
|
||||||
|
#ifndef FORCE_HARD_FLOAT
|
||||||
|
/* test for vfp magic number set by getcontext */
|
||||||
|
ldr r2, [r0, #VFP_MAGIC_OFFSET]
|
||||||
|
ldr r3, =#0x56465001
|
||||||
|
cmp r2, r3
|
||||||
|
bne 1f
|
||||||
|
#endif
|
||||||
|
/* if vfp in use, restore d8-d15 from uc_regspace */
|
||||||
|
.fpu vfp
|
||||||
|
add r14, r0, #VFP_D8_OFFSET
|
||||||
|
vldmia r14, {d8-d15}
|
||||||
|
.fpu softvfp
|
||||||
|
1:
|
||||||
|
#endif
|
||||||
|
|
||||||
/* copy all of the current registers into the ucontext structure */
|
/* copy all of the current registers into the ucontext structure */
|
||||||
add r14, r0, #REG_OFFSET(0)
|
add r14, r0, #REG_OFFSET(0)
|
||||||
ldmia r14, {r0-r12}
|
ldmia r14, {r0-r12}
|
||||||
|
|
|
@ -22,6 +22,26 @@ FUNC(libucontext_swapcontext)
|
||||||
str r13, [r0,#REG_OFFSET(13)]
|
str r13, [r0,#REG_OFFSET(13)]
|
||||||
str r14, [r0,#REG_OFFSET(15)]
|
str r14, [r0,#REG_OFFSET(15)]
|
||||||
|
|
||||||
|
#ifndef FORCE_SOFT_FLOAT
|
||||||
|
#ifndef FORCE_HARD_FLOAT
|
||||||
|
/* test for vfp magic number, copy to other ucontext */
|
||||||
|
ldr r3, [r1, #VFP_MAGIC_OFFSET]
|
||||||
|
ldr r4, =#0x56465001
|
||||||
|
str r3, [r0, #VFP_MAGIC_OFFSET]
|
||||||
|
cmp r3, r4
|
||||||
|
bne 1f
|
||||||
|
#endif
|
||||||
|
/* if vfp in use, save and restore d8-d15 */
|
||||||
|
.fpu vfp
|
||||||
|
add r2, r0, #VFP_D8_OFFSET
|
||||||
|
vstmia r2, {d8-d15}
|
||||||
|
|
||||||
|
add r14, r1, #VFP_D8_OFFSET
|
||||||
|
vldmia r14, {d8-d15}
|
||||||
|
.fpu softvfp
|
||||||
|
1:
|
||||||
|
#endif
|
||||||
|
|
||||||
/* load new registers from the second ucontext structure */
|
/* load new registers from the second ucontext structure */
|
||||||
add r14, r1, #REG_OFFSET(0)
|
add r14, r1, #REG_OFFSET(0)
|
||||||
ldmia r14, {r0-r12}
|
ldmia r14, {r0-r12}
|
||||||
|
|
|
@ -18,7 +18,7 @@ __attribute__ ((visibility ("hidden")))
|
||||||
void
|
void
|
||||||
libucontext_trampoline(void)
|
libucontext_trampoline(void)
|
||||||
{
|
{
|
||||||
register libucontext_ucontext_t *uc_link;
|
register libucontext_ucontext_t *uc_link = NULL;
|
||||||
|
|
||||||
FETCH_LINKPTR(uc_link);
|
FETCH_LINKPTR(uc_link);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef __ARCH_LOONGARCH64_DEFS_H
|
||||||
|
#define __ARCH_LOONGARCH64_DEFS_H
|
||||||
|
|
||||||
|
#define REG_SZ (8)
|
||||||
|
|
||||||
|
#define REG_R0 (0)
|
||||||
|
#define REG_R1 (1)
|
||||||
|
#define REG_R2 (2)
|
||||||
|
#define REG_R3 (3)
|
||||||
|
#define REG_R4 (4)
|
||||||
|
#define REG_R5 (5)
|
||||||
|
#define REG_R6 (6)
|
||||||
|
#define REG_R7 (7)
|
||||||
|
#define REG_R8 (8)
|
||||||
|
#define REG_R9 (9)
|
||||||
|
#define REG_R10 (10)
|
||||||
|
#define REG_R11 (11)
|
||||||
|
#define REG_R12 (12)
|
||||||
|
#define REG_R13 (13)
|
||||||
|
#define REG_R14 (14)
|
||||||
|
#define REG_R15 (15)
|
||||||
|
#define REG_R16 (16)
|
||||||
|
#define REG_R17 (17)
|
||||||
|
#define REG_R18 (18)
|
||||||
|
#define REG_R19 (19)
|
||||||
|
#define REG_R20 (20)
|
||||||
|
#define REG_R21 (21)
|
||||||
|
#define REG_R22 (22)
|
||||||
|
#define REG_R23 (23)
|
||||||
|
#define REG_R24 (24)
|
||||||
|
#define REG_R25 (25)
|
||||||
|
#define REG_R26 (26)
|
||||||
|
#define REG_R27 (27)
|
||||||
|
#define REG_R28 (28)
|
||||||
|
#define REG_R29 (29)
|
||||||
|
#define REG_R30 (30)
|
||||||
|
#define REG_R31 (31)
|
||||||
|
|
||||||
|
/* $a0 is $4 , also $v0, same as $5, $a1 and $v1*/
|
||||||
|
#define REG_A0 (4)
|
||||||
|
|
||||||
|
/* stack pointer is actually $3 */
|
||||||
|
#define REG_SP (3)
|
||||||
|
|
||||||
|
/* frame pointer is actually $22 */
|
||||||
|
#define REG_FP (22)
|
||||||
|
|
||||||
|
/* offset to mc_gregs in ucontext_t */
|
||||||
|
#define MCONTEXT_GREGS (48)
|
||||||
|
|
||||||
|
/* offset to PC in ucontext_t */
|
||||||
|
#define MCONTEXT_PC (40)
|
||||||
|
|
||||||
|
/* offset to uc_link in ucontext_t */
|
||||||
|
#define UCONTEXT_UC_LINK (8)
|
||||||
|
|
||||||
|
/* offset to uc_stack.ss_sp in ucontext_t */
|
||||||
|
#define UCONTEXT_STACK_PTR (16)
|
||||||
|
|
||||||
|
/* offset to uc_stack.ss_size in ucontext_t */
|
||||||
|
#define UCONTEXT_STACK_SIZE (32)
|
||||||
|
|
||||||
|
/* Stack alignment, from Kernel source */
|
||||||
|
#define ALSZ 15
|
||||||
|
#define ALMASK ~15
|
||||||
|
#define FRAMESZ (((LOCALSZ * REG_SZ) + ALSZ) & ALMASK)
|
||||||
|
|
||||||
|
#define PUSH_FRAME(__proc) \
|
||||||
|
addi.d $sp, $sp, -FRAMESZ;
|
||||||
|
|
||||||
|
#define POP_FRAME(__proc) \
|
||||||
|
addi.d $sp, $sp, FRAMESZ;
|
||||||
|
|
||||||
|
#include <common-defs.h>
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef LIBUCONTEXT_BITS_H
|
||||||
|
#define LIBUCONTEXT_BITS_H
|
||||||
|
|
||||||
|
typedef unsigned long long libucontext_greg_t, libucontext_gregset_t[32];
|
||||||
|
|
||||||
|
/* Container for all general registers. */
|
||||||
|
typedef __loongarch_mc_gp_state gregset_t;
|
||||||
|
|
||||||
|
/* Container for floating-point state. */
|
||||||
|
typedef union __loongarch_mc_fp_state fpregset_t;
|
||||||
|
|
||||||
|
union __loongarch_mc_fp_state {
|
||||||
|
unsigned int __val32[256 / 32];
|
||||||
|
unsigned long long __val64[256 / 64];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct mcontext_t {
|
||||||
|
unsigned long long __pc;
|
||||||
|
unsigned long long __gregs[32];
|
||||||
|
unsigned int __flags;
|
||||||
|
|
||||||
|
unsigned int __fcsr;
|
||||||
|
unsigned int __vcsr;
|
||||||
|
unsigned long long __fcc;
|
||||||
|
union __loongarch_mc_fp_state __fpregs[32] __attribute__((__aligned__ (32)));
|
||||||
|
|
||||||
|
unsigned int __reserved;
|
||||||
|
} mcontext_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *ss_sp;
|
||||||
|
int ss_flags;
|
||||||
|
size_t ss_size;
|
||||||
|
} libucontext_stack_t;
|
||||||
|
|
||||||
|
typedef struct libucontext_ucontext {
|
||||||
|
unsigned long uc_flags;
|
||||||
|
struct libucontext_ucontext *uc_link;
|
||||||
|
libucontext_stack_t uc_stack;
|
||||||
|
libucontext_mcontext_t uc_mcontext;
|
||||||
|
} libucontext_ucontext_t;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Peng Fan <fanpeng@loongson.cn>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOCALSZ (1)
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(getcontext, libucontext_getcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_getcontext)
|
||||||
|
/* copy $sp, $fp to temporary registers so we don't clobber them */
|
||||||
|
move $a2, $sp
|
||||||
|
move $a3, $fp
|
||||||
|
|
||||||
|
PUSH_FRAME(libucontext_getcontext)
|
||||||
|
|
||||||
|
/* set registers */
|
||||||
|
st.d $s0, $a0, REG_OFFSET(23)
|
||||||
|
st.d $s1, $a0, REG_OFFSET(24)
|
||||||
|
st.d $s2, $a0, REG_OFFSET(25)
|
||||||
|
st.d $s3, $a0, REG_OFFSET(26)
|
||||||
|
st.d $s4, $a0, REG_OFFSET(27)
|
||||||
|
st.d $s5, $a0, REG_OFFSET(28)
|
||||||
|
st.d $s6, $a0, REG_OFFSET(29)
|
||||||
|
st.d $s7, $a0, REG_OFFSET(30)
|
||||||
|
st.d $s8, $a0, REG_OFFSET(31)
|
||||||
|
|
||||||
|
st.d $a2, $a0, REG_OFFSET(3)
|
||||||
|
st.d $a3, $a0, REG_OFFSET(22)
|
||||||
|
st.d $ra, $a0, REG_OFFSET(1)
|
||||||
|
|
||||||
|
st.d $ra, $a0, (MCONTEXT_PC)
|
||||||
|
|
||||||
|
POP_FRAME(libucontext_getcontext)
|
||||||
|
|
||||||
|
jr $ra
|
||||||
|
END(libucontext_getcontext)
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Peng Fan <fanpeng@loongson.cn>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
#define LOCALSZ (6)
|
||||||
|
|
||||||
|
#define A3_OFF (FRAMESZ - (5 * REG_SZ))
|
||||||
|
#define A4_OFF (FRAMESZ - (4 * REG_SZ))
|
||||||
|
#define A5_OFF (FRAMESZ - (3 * REG_SZ))
|
||||||
|
#define A6_OFF (FRAMESZ - (2 * REG_SZ))
|
||||||
|
#define A7_OFF (FRAMESZ - (1 * REG_SZ))
|
||||||
|
|
||||||
|
ALIAS(makecontext, libucontext_makecontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_makecontext)
|
||||||
|
PUSH_FRAME(libucontext_makecontext)
|
||||||
|
|
||||||
|
move $t5, $a0
|
||||||
|
move $t4, $a1
|
||||||
|
|
||||||
|
/* store $a3 through $a7 to the stack frame. */
|
||||||
|
st.d $a3, $sp, A3_OFF
|
||||||
|
st.d $a4, $sp, A4_OFF
|
||||||
|
st.d $a5, $sp, A5_OFF
|
||||||
|
st.d $a6, $sp, A6_OFF
|
||||||
|
st.d $a7, $sp, A7_OFF
|
||||||
|
|
||||||
|
/* set $zero in the mcontext to 1. */
|
||||||
|
addi.d $v0, $zero, 1
|
||||||
|
st.d $v0, $t5, REG_OFFSET(0)
|
||||||
|
|
||||||
|
/* ensure the stack is aligned on a quad-word boundary. */
|
||||||
|
ld.d $t0, $t5, UCONTEXT_STACK_PTR
|
||||||
|
ld.d $t2, $t5, UCONTEXT_STACK_SIZE
|
||||||
|
/* the third argument(from zero), that's the first argument of func() */
|
||||||
|
addi.d $t1, $sp, A3_OFF
|
||||||
|
add.d $t0, $t0, $t2
|
||||||
|
|
||||||
|
addi.d $t7, $zero, ALMASK
|
||||||
|
and $t0, $t0, $t7
|
||||||
|
|
||||||
|
/* number of args */
|
||||||
|
beq $a2, $zero, no_more_arguments
|
||||||
|
bltu $a2, $zero, no_more_arguments
|
||||||
|
|
||||||
|
/* store register arguments. */
|
||||||
|
addi.d $t2, $t5, MCONTEXT_GREGS + (4 * REG_SZ)
|
||||||
|
move $t3, $zero
|
||||||
|
|
||||||
|
store_register_arg:
|
||||||
|
addi.d $t3, $t3, 1
|
||||||
|
ld.d $v1, $t1, 0
|
||||||
|
addi.d $t1, $t1, REG_SZ
|
||||||
|
st.d $v1, $t2, 0
|
||||||
|
addi.d $t2, $t2, REG_SZ
|
||||||
|
addi.d $t6, $zero, 8
|
||||||
|
bltu $t3, $t6, store_register_arg
|
||||||
|
bgeu $t3, $a2, no_more_arguments
|
||||||
|
|
||||||
|
/* make room for stack arguments. */
|
||||||
|
sub.d $t2, $a2, $t3
|
||||||
|
|
||||||
|
addi.d $t6, $zero, 3
|
||||||
|
sll.d $t2, $t2, $t6
|
||||||
|
|
||||||
|
sub.d $t0, $t0, $t2
|
||||||
|
|
||||||
|
addi.d $t6, $zero, ALMASK
|
||||||
|
and $t0, $t0, $t6
|
||||||
|
|
||||||
|
/* store stack arguments. */
|
||||||
|
move $t2, $t0
|
||||||
|
|
||||||
|
store_stack_arg:
|
||||||
|
addi.d $t3, $t3, 1
|
||||||
|
ld.d $v1, $t1, 0
|
||||||
|
addi.d $t1, $t1, REG_SZ
|
||||||
|
st.d $v1, $t2, 0
|
||||||
|
addi.d $t2, $t2, REG_SZ
|
||||||
|
bltu $t3, $a2, store_stack_arg
|
||||||
|
|
||||||
|
no_more_arguments:
|
||||||
|
/* trampoline setup. */
|
||||||
|
la.got $t8, libucontext_trampoline
|
||||||
|
|
||||||
|
ld.d $v1, $t5, UCONTEXT_UC_LINK
|
||||||
|
st.d $v1, $t5, REG_OFFSET(23)
|
||||||
|
|
||||||
|
st.d $t0, $t5, REG_OFFSET(3)
|
||||||
|
|
||||||
|
st.d $t8, $t5, REG_OFFSET(1)
|
||||||
|
|
||||||
|
st.d $t4, $t5, MCONTEXT_PC
|
||||||
|
|
||||||
|
POP_FRAME(libucontext_makecontext)
|
||||||
|
|
||||||
|
jr $ra
|
||||||
|
END(libucontext_makecontext)
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Peng Fan <fanpeng@loongson.cn>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOCALSZ (1)
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(setcontext, libucontext_setcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_setcontext)
|
||||||
|
PUSH_FRAME(libucontext_setcontext)
|
||||||
|
|
||||||
|
/* move the context to $v0, in LA, $v0 = $a0 = $4 */
|
||||||
|
move $t5, $a0
|
||||||
|
|
||||||
|
/* load the registers */
|
||||||
|
ld.d $a0, $t5, REG_OFFSET(4)
|
||||||
|
ld.d $a1, $t5, REG_OFFSET(5)
|
||||||
|
ld.d $a2, $t5, REG_OFFSET(6)
|
||||||
|
ld.d $a3, $t5, REG_OFFSET(7)
|
||||||
|
ld.d $a4, $t5, REG_OFFSET(8)
|
||||||
|
ld.d $a5, $t5, REG_OFFSET(9)
|
||||||
|
ld.d $a6, $t5, REG_OFFSET(10)
|
||||||
|
ld.d $a7, $t5, REG_OFFSET(11)
|
||||||
|
|
||||||
|
ld.d $s0, $t5, REG_OFFSET(23)
|
||||||
|
ld.d $s1, $t5, REG_OFFSET(24)
|
||||||
|
ld.d $s2, $t5, REG_OFFSET(25)
|
||||||
|
ld.d $s3, $t5, REG_OFFSET(26)
|
||||||
|
ld.d $s4, $t5, REG_OFFSET(27)
|
||||||
|
ld.d $s5, $t5, REG_OFFSET(28)
|
||||||
|
ld.d $s6, $t5, REG_OFFSET(29)
|
||||||
|
ld.d $s7, $t5, REG_OFFSET(30)
|
||||||
|
ld.d $s8, $t5, REG_OFFSET(31)
|
||||||
|
|
||||||
|
ld.d $sp, $t5, REG_OFFSET(3)
|
||||||
|
ld.d $fp, $t5, REG_OFFSET(22)
|
||||||
|
ld.d $ra, $t5, REG_OFFSET(1)
|
||||||
|
|
||||||
|
ld.d $t8, $t5, (MCONTEXT_PC)
|
||||||
|
|
||||||
|
jr $t8
|
||||||
|
move $v0, $zero
|
||||||
|
|
||||||
|
POP_FRAME(libucontext_setcontext)
|
||||||
|
END(libucontext_setcontext)
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Peng Fan <fanpeng@loongson.cn>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOCALSZ (4)
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
FUNC(libucontext_trampoline)
|
||||||
|
|
||||||
|
/* call setcontext */
|
||||||
|
move $a0, $s0
|
||||||
|
/* we receive our initial ucontext in $s0, so if $s0 is nil, bail */
|
||||||
|
beqz $s0, no_linked_context
|
||||||
|
|
||||||
|
la.got $t8, libucontext_setcontext
|
||||||
|
|
||||||
|
jr $t8
|
||||||
|
|
||||||
|
no_linked_context:
|
||||||
|
move $a0, $zero
|
||||||
|
la.global $t8, exit
|
||||||
|
jr $t8
|
||||||
|
|
||||||
|
END(libucontext_trampoline)
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Peng Fan <fanpeng@loongson.cn>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOCALSZ (4)
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
#define A1_OFFSET (FRAMESZ - (1 * REG_SZ))
|
||||||
|
|
||||||
|
ALIAS(swapcontext, libucontext_swapcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_swapcontext)
|
||||||
|
/* copy $sp, $fp to temporary registers so we don't clobber them */
|
||||||
|
move $a3, $sp
|
||||||
|
move $a4, $fp
|
||||||
|
|
||||||
|
move $t5, $a0
|
||||||
|
|
||||||
|
PUSH_FRAME(libucontext_swapcontext)
|
||||||
|
|
||||||
|
/* set registers */
|
||||||
|
st.d $s0, $t5, REG_OFFSET(23)
|
||||||
|
st.d $s1, $t5, REG_OFFSET(24)
|
||||||
|
st.d $s2, $t5, REG_OFFSET(25)
|
||||||
|
st.d $s3, $t5, REG_OFFSET(26)
|
||||||
|
st.d $s4, $t5, REG_OFFSET(27)
|
||||||
|
st.d $s5, $t5, REG_OFFSET(28)
|
||||||
|
st.d $s6, $t5, REG_OFFSET(29)
|
||||||
|
st.d $s7, $t5, REG_OFFSET(30)
|
||||||
|
st.d $s8, $t5, REG_OFFSET(31)
|
||||||
|
|
||||||
|
st.d $a3, $t5, REG_OFFSET(3)
|
||||||
|
st.d $a4, $t5, REG_OFFSET(22)
|
||||||
|
st.d $ra, $t5, REG_OFFSET(1)
|
||||||
|
|
||||||
|
st.d $ra, $t5, (MCONTEXT_PC)
|
||||||
|
|
||||||
|
/* copy new context address in $a1 to stack */
|
||||||
|
st.d $a1, $sp, A1_OFFSET
|
||||||
|
|
||||||
|
/* load new context address into $v0 */
|
||||||
|
ld.d $t4, $sp, A1_OFFSET
|
||||||
|
|
||||||
|
/* load the registers */
|
||||||
|
ld.d $a0, $t4, REG_OFFSET(4)
|
||||||
|
ld.d $a1, $t4, REG_OFFSET(5)
|
||||||
|
ld.d $a2, $t4, REG_OFFSET(6)
|
||||||
|
ld.d $a3, $t4, REG_OFFSET(7)
|
||||||
|
ld.d $a4, $t4, REG_OFFSET(8)
|
||||||
|
ld.d $a5, $t4, REG_OFFSET(9)
|
||||||
|
ld.d $a6, $t4, REG_OFFSET(10)
|
||||||
|
ld.d $a7, $t4, REG_OFFSET(11)
|
||||||
|
|
||||||
|
ld.d $s0, $t4, REG_OFFSET(23)
|
||||||
|
ld.d $s1, $t4, REG_OFFSET(24)
|
||||||
|
ld.d $s2, $t4, REG_OFFSET(25)
|
||||||
|
ld.d $s3, $t4, REG_OFFSET(26)
|
||||||
|
ld.d $s4, $t4, REG_OFFSET(27)
|
||||||
|
ld.d $s5, $t4, REG_OFFSET(28)
|
||||||
|
ld.d $s6, $t4, REG_OFFSET(29)
|
||||||
|
ld.d $s7, $t4, REG_OFFSET(30)
|
||||||
|
ld.d $s8, $t4, REG_OFFSET(31)
|
||||||
|
|
||||||
|
ld.d $sp, $t4, REG_OFFSET(3)
|
||||||
|
ld.d $fp, $t4, REG_OFFSET(22)
|
||||||
|
ld.d $ra, $t4, REG_OFFSET(1)
|
||||||
|
|
||||||
|
ld.d $t8, $t4, (MCONTEXT_PC)
|
||||||
|
|
||||||
|
jr $t8
|
||||||
|
move $v0, $zero
|
||||||
|
|
||||||
|
fail:
|
||||||
|
la.global $t8, exit
|
||||||
|
|
||||||
|
POP_FRAME(libucontext_swapcontext)
|
||||||
|
|
||||||
|
jirl $ra, $t8, 0
|
||||||
|
move $v0, $zero
|
||||||
|
END(libucontext_swapcontext)
|
|
@ -10,9 +10,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef __ARCH_OR1K_DEFS_H
|
||||||
|
#define __ARCH_OR1K_DEFS_H
|
||||||
|
|
||||||
|
#define REG_SZ (4)
|
||||||
|
#define MCONTEXT_GREGS (20)
|
||||||
|
|
||||||
|
#define REG_SP (1)
|
||||||
|
#define REG_FP (2)
|
||||||
|
#define REG_RA (9)
|
||||||
|
#define REG_SA (11)
|
||||||
|
#define REG_LR (14)
|
||||||
|
#define REG_PC (33)
|
||||||
|
#define REG_SR (34)
|
||||||
|
|
||||||
|
#define PC_OFFSET REG_OFFSET(REG_PC)
|
||||||
|
|
||||||
|
#define FETCH_LINKPTR(dest) \
|
||||||
|
asm("l.ori %0, r14, 0" :: "r" ((dest)))
|
||||||
|
|
||||||
|
#include "common-defs.h"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(getcontext, libucontext_getcontext)
|
||||||
|
ALIAS(__getcontext, libucontext_getcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_getcontext)
|
||||||
|
l.sw REG_OFFSET(1)(r3), r1 /* store r1 and r2 */
|
||||||
|
l.sw REG_OFFSET(2)(r3), r2
|
||||||
|
|
||||||
|
l.sw REG_OFFSET(9)(r3), r9 /* store r9 to both r9 and r11 in the context */
|
||||||
|
l.sw REG_OFFSET(11)(r3), r9
|
||||||
|
|
||||||
|
l.sw REG_OFFSET(10)(r3), r10 /* store r10 for TLS */
|
||||||
|
|
||||||
|
l.sw REG_OFFSET(14)(r3), r14 /* store r14 through r30 even */
|
||||||
|
l.sw REG_OFFSET(16)(r3), r16
|
||||||
|
l.sw REG_OFFSET(18)(r3), r18
|
||||||
|
l.sw REG_OFFSET(20)(r3), r20
|
||||||
|
l.sw REG_OFFSET(22)(r3), r22
|
||||||
|
l.sw REG_OFFSET(24)(r3), r24
|
||||||
|
l.sw REG_OFFSET(26)(r3), r26
|
||||||
|
l.sw REG_OFFSET(28)(r3), r28
|
||||||
|
l.sw REG_OFFSET(30)(r3), r30
|
||||||
|
|
||||||
|
l.jr r9
|
||||||
|
l.ori r11, r0, 0
|
||||||
|
END(libucontext_getcontext)
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef LIBUCONTEXT_BITS_H
|
||||||
|
#define LIBUCONTEXT_BITS_H
|
||||||
|
|
||||||
|
typedef struct sigaltstack {
|
||||||
|
void *ss_sp;
|
||||||
|
int ss_flags;
|
||||||
|
size_t ss_size;
|
||||||
|
} libucontext_stack_t;
|
||||||
|
|
||||||
|
typedef int libucontext_greg_t, libucontext_gregset_t[32];
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
libucontext_gregset_t gpr;
|
||||||
|
libucontext_greg_t pc;
|
||||||
|
libucontext_greg_t sr;
|
||||||
|
} regs;
|
||||||
|
unsigned long oldmask;
|
||||||
|
} libucontext_mcontext_t;
|
||||||
|
|
||||||
|
typedef struct libucontext_ucontext {
|
||||||
|
unsigned long uc_flags;
|
||||||
|
struct libucontext_ucontext *uc_link;
|
||||||
|
libucontext_stack_t uc_stack;
|
||||||
|
libucontext_mcontext_t uc_mcontext;
|
||||||
|
} libucontext_ucontext_t;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "defs.h"
|
||||||
|
#include <libucontext/libucontext.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern void libucontext_trampoline(void);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
|
||||||
|
{
|
||||||
|
libucontext_greg_t *sp;
|
||||||
|
va_list va;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* set up and align the stack. */
|
||||||
|
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
|
||||||
|
sp -= argc < 6 ? 0 : (argc - 6);
|
||||||
|
sp = (libucontext_greg_t *) (((uintptr_t) sp & ~0x3));
|
||||||
|
|
||||||
|
/* set up the ucontext structure */
|
||||||
|
ucp->uc_mcontext.regs.gpr[REG_SP] = (libucontext_greg_t) sp;
|
||||||
|
ucp->uc_mcontext.regs.gpr[REG_RA] = (libucontext_greg_t) &libucontext_trampoline;
|
||||||
|
ucp->uc_mcontext.regs.gpr[REG_FP] = 0;
|
||||||
|
ucp->uc_mcontext.regs.gpr[REG_SA] = (libucontext_greg_t) func;
|
||||||
|
ucp->uc_mcontext.regs.gpr[REG_LR] = (libucontext_greg_t) ucp->uc_link;
|
||||||
|
|
||||||
|
va_start(va, argc);
|
||||||
|
|
||||||
|
/* args less than argv[6] have dedicated registers, else they overflow onto stack */
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (i < 6)
|
||||||
|
ucp->uc_mcontext.regs.gpr[i + 3] = va_arg (va, libucontext_greg_t);
|
||||||
|
else
|
||||||
|
sp[i - 6] = va_arg (va, libucontext_greg_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXPORT_UNPREFIXED
|
||||||
|
extern __typeof(libucontext_makecontext) makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
|
||||||
|
extern __typeof(libucontext_makecontext) __makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
|
||||||
|
#endif
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(setcontext, libucontext_setcontext)
|
||||||
|
ALIAS(__setcontext, libucontext_setcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_setcontext)
|
||||||
|
l.ori r30, r3, 0 /* avoid clobbering r3 by copying to r30 */
|
||||||
|
|
||||||
|
l.lwz r3, REG_OFFSET(3)(r30) /* restore r3-r8 (argument registers) */
|
||||||
|
l.lwz r4, REG_OFFSET(4)(r30)
|
||||||
|
l.lwz r5, REG_OFFSET(5)(r30)
|
||||||
|
l.lwz r6, REG_OFFSET(6)(r30)
|
||||||
|
l.lwz r7, REG_OFFSET(7)(r30)
|
||||||
|
l.lwz r8, REG_OFFSET(8)(r30)
|
||||||
|
|
||||||
|
l.lwz r1, REG_OFFSET(1)(r30) /* restore stack/frame pointers */
|
||||||
|
l.lwz r2, REG_OFFSET(2)(r30)
|
||||||
|
|
||||||
|
l.lwz r9, REG_OFFSET(9)(r30) /* restore link register and starting address register */
|
||||||
|
l.lwz r11, REG_OFFSET(11)(r30)
|
||||||
|
|
||||||
|
l.lwz r10, REG_OFFSET(10)(r30) /* restore TLS register */
|
||||||
|
|
||||||
|
l.lwz r14, REG_OFFSET(14)(r30) /* restore r14-r30, even only */
|
||||||
|
l.lwz r16, REG_OFFSET(16)(r30)
|
||||||
|
l.lwz r18, REG_OFFSET(18)(r30)
|
||||||
|
l.lwz r20, REG_OFFSET(20)(r30)
|
||||||
|
l.lwz r22, REG_OFFSET(22)(r30)
|
||||||
|
l.lwz r24, REG_OFFSET(24)(r30)
|
||||||
|
l.lwz r26, REG_OFFSET(26)(r30)
|
||||||
|
l.lwz r28, REG_OFFSET(28)(r30)
|
||||||
|
l.lwz r30, REG_OFFSET(30)(r30)
|
||||||
|
|
||||||
|
l.jr r11 /* jump to new starting address */
|
||||||
|
l.ori r11, r0, 0
|
||||||
|
END(libucontext_setcontext)
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(swapcontext, libucontext_swapcontext)
|
||||||
|
ALIAS(__swapcontext, libucontext_swapcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_swapcontext)
|
||||||
|
/* copy context into r3 like getcontext */
|
||||||
|
l.sw REG_OFFSET(1)(r3), r1 /* store r1 and r2 */
|
||||||
|
l.sw REG_OFFSET(2)(r3), r2
|
||||||
|
|
||||||
|
l.sw REG_OFFSET(9)(r3), r9 /* store r9 to both r9 and r11 in the context */
|
||||||
|
l.sw REG_OFFSET(11)(r3), r9
|
||||||
|
|
||||||
|
l.sw REG_OFFSET(10)(r3), r10 /* store r10 for TLS */
|
||||||
|
|
||||||
|
l.sw REG_OFFSET(14)(r3), r14 /* store r14 through r30 even */
|
||||||
|
l.sw REG_OFFSET(16)(r3), r16
|
||||||
|
l.sw REG_OFFSET(18)(r3), r18
|
||||||
|
l.sw REG_OFFSET(20)(r3), r20
|
||||||
|
l.sw REG_OFFSET(22)(r3), r22
|
||||||
|
l.sw REG_OFFSET(24)(r3), r24
|
||||||
|
l.sw REG_OFFSET(26)(r3), r26
|
||||||
|
l.sw REG_OFFSET(28)(r3), r28
|
||||||
|
l.sw REG_OFFSET(30)(r3), r30
|
||||||
|
|
||||||
|
/* set the new context from r4 */
|
||||||
|
l.ori r30, r4, 0 /* copy r4 to r30 to avoid clobbering */
|
||||||
|
|
||||||
|
l.lwz r3, REG_OFFSET(3)(r30) /* restore r3-r8 (argument registers) */
|
||||||
|
l.lwz r4, REG_OFFSET(4)(r30)
|
||||||
|
l.lwz r5, REG_OFFSET(5)(r30)
|
||||||
|
l.lwz r6, REG_OFFSET(6)(r30)
|
||||||
|
l.lwz r7, REG_OFFSET(7)(r30)
|
||||||
|
l.lwz r8, REG_OFFSET(8)(r30)
|
||||||
|
|
||||||
|
l.lwz r1, REG_OFFSET(1)(r30) /* restore stack/frame pointers */
|
||||||
|
l.lwz r2, REG_OFFSET(2)(r30)
|
||||||
|
|
||||||
|
l.lwz r9, REG_OFFSET(9)(r30) /* restore link register and starting address register */
|
||||||
|
l.lwz r11, REG_OFFSET(11)(r30)
|
||||||
|
|
||||||
|
l.lwz r10, REG_OFFSET(10)(r30) /* restore TLS register */
|
||||||
|
|
||||||
|
l.lwz r14, REG_OFFSET(14)(r30) /* restore r14-r30, even only */
|
||||||
|
l.lwz r16, REG_OFFSET(16)(r30)
|
||||||
|
l.lwz r18, REG_OFFSET(18)(r30)
|
||||||
|
l.lwz r20, REG_OFFSET(20)(r30)
|
||||||
|
l.lwz r22, REG_OFFSET(22)(r30)
|
||||||
|
l.lwz r24, REG_OFFSET(24)(r30)
|
||||||
|
l.lwz r26, REG_OFFSET(26)(r30)
|
||||||
|
l.lwz r28, REG_OFFSET(28)(r30)
|
||||||
|
l.lwz r30, REG_OFFSET(30)(r30)
|
||||||
|
|
||||||
|
l.jr r11 /* jump to new starting address */
|
||||||
|
l.ori r11, r0, 0
|
||||||
|
END(libucontext_swapcontext)
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include "defs.h"
|
||||||
|
#include <libucontext/libucontext.h>
|
||||||
|
#include "common-trampoline.c"
|
|
@ -11,9 +11,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef __ARCH_RISCV64_DEFS_H
|
||||||
|
#define __ARCH_RISCV64_DEFS_H
|
||||||
|
|
||||||
|
#define REG_SZ (4)
|
||||||
|
#define MCONTEXT_GREGS (160)
|
||||||
|
|
||||||
|
/* program counter is saved in x0 as well as x1, similar to mips */
|
||||||
|
#ifndef REG_PC
|
||||||
|
#define REG_PC (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RA
|
||||||
|
#define REG_RA (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_SP
|
||||||
|
#define REG_SP (2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_S0
|
||||||
|
#define REG_S0 (8)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REG_S1 (9)
|
||||||
|
|
||||||
|
#ifndef REG_A0
|
||||||
|
#define REG_A0 (10)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REG_A1 (11)
|
||||||
|
#define REG_A2 (12)
|
||||||
|
#define REG_A3 (13)
|
||||||
|
#define REG_A4 (14)
|
||||||
|
#define REG_A5 (15)
|
||||||
|
#define REG_A6 (16)
|
||||||
|
#define REG_A7 (17)
|
||||||
|
#define REG_S2 (18)
|
||||||
|
#define REG_S3 (19)
|
||||||
|
#define REG_S4 (20)
|
||||||
|
#define REG_S5 (21)
|
||||||
|
#define REG_S6 (22)
|
||||||
|
#define REG_S7 (23)
|
||||||
|
#define REG_S8 (24)
|
||||||
|
#define REG_S9 (25)
|
||||||
|
#define REG_S10 (26)
|
||||||
|
#define REG_S11 (27)
|
||||||
|
|
||||||
|
#define PC_OFFSET REG_OFFSET(REG_PC)
|
||||||
|
|
||||||
|
#define FETCH_LINKPTR(dest) \
|
||||||
|
asm("mv %0, s1" : "=r" ((dest)))
|
||||||
|
|
||||||
|
#include "common-defs.h"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(getcontext, libucontext_getcontext)
|
||||||
|
ALIAS(__getcontext, libucontext_getcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_getcontext)
|
||||||
|
sw ra, REG_OFFSET(REG_PC)(a0)
|
||||||
|
sw ra, REG_OFFSET(REG_RA)(a0)
|
||||||
|
sw sp, REG_OFFSET(REG_SP)(a0)
|
||||||
|
|
||||||
|
/* first saved register block */
|
||||||
|
sw s0, REG_OFFSET(REG_S0)(a0)
|
||||||
|
sw s1, REG_OFFSET(REG_S1)(a0)
|
||||||
|
|
||||||
|
/* return register block */
|
||||||
|
sw a0, REG_OFFSET(REG_A0)(a0)
|
||||||
|
sw a1, REG_OFFSET(REG_A1)(a0)
|
||||||
|
|
||||||
|
/* second saved register block */
|
||||||
|
sw s2, REG_OFFSET(REG_S2)(a0)
|
||||||
|
sw s3, REG_OFFSET(REG_S3)(a0)
|
||||||
|
sw s4, REG_OFFSET(REG_S4)(a0)
|
||||||
|
sw s5, REG_OFFSET(REG_S5)(a0)
|
||||||
|
sw s6, REG_OFFSET(REG_S6)(a0)
|
||||||
|
sw s7, REG_OFFSET(REG_S7)(a0)
|
||||||
|
sw s8, REG_OFFSET(REG_S8)(a0)
|
||||||
|
sw s9, REG_OFFSET(REG_S9)(a0)
|
||||||
|
sw s10, REG_OFFSET(REG_S10)(a0)
|
||||||
|
sw s11, REG_OFFSET(REG_S11)(a0)
|
||||||
|
|
||||||
|
/* done saving, return */
|
||||||
|
ret
|
||||||
|
END(libucontext_getcontext)
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "defs.h"
|
||||||
|
#include <libucontext/libucontext.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern void libucontext_trampoline(void);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
|
||||||
|
{
|
||||||
|
libucontext_greg_t *sp, *regp;
|
||||||
|
va_list va;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* set up and align the stack. */
|
||||||
|
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
|
||||||
|
sp -= argc < 8 ? 0 : argc - 8;
|
||||||
|
sp = (libucontext_greg_t *) (((uintptr_t) sp & -16L));
|
||||||
|
|
||||||
|
/* set up the ucontext structure */
|
||||||
|
ucp->uc_mcontext.__gregs[REG_RA] = (libucontext_greg_t) libucontext_trampoline;
|
||||||
|
ucp->uc_mcontext.__gregs[REG_S0] = 0;
|
||||||
|
ucp->uc_mcontext.__gregs[REG_S1] = (libucontext_greg_t) ucp->uc_link;
|
||||||
|
ucp->uc_mcontext.__gregs[REG_SP] = (libucontext_greg_t) sp;
|
||||||
|
ucp->uc_mcontext.__gregs[REG_PC] = (libucontext_greg_t) func;
|
||||||
|
|
||||||
|
va_start(va, argc);
|
||||||
|
|
||||||
|
/* first 8 args go in $a0 through $a7. */
|
||||||
|
regp = &(ucp->uc_mcontext.__gregs[REG_A0]);
|
||||||
|
|
||||||
|
for (i = 0; (i < argc && i < 8); i++)
|
||||||
|
*regp++ = va_arg (va, libucontext_greg_t);
|
||||||
|
|
||||||
|
/* remainder overflows into stack */
|
||||||
|
for (; i < argc; i++)
|
||||||
|
*sp++ = va_arg (va, libucontext_greg_t);
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXPORT_UNPREFIXED
|
||||||
|
extern __typeof(libucontext_makecontext) makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
|
||||||
|
extern __typeof(libucontext_makecontext) __makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
|
||||||
|
#endif
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(setcontext, libucontext_setcontext)
|
||||||
|
ALIAS(__setcontext, libucontext_setcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_setcontext)
|
||||||
|
/* move $a0 to $t0 to avoid clobbering. */
|
||||||
|
mv t0, a0
|
||||||
|
|
||||||
|
lw t1, PC_OFFSET(t0)
|
||||||
|
lw ra, REG_OFFSET(REG_RA)(t0)
|
||||||
|
lw sp, REG_OFFSET(REG_SP)(t0)
|
||||||
|
|
||||||
|
/* first saved register block */
|
||||||
|
lw s0, REG_OFFSET(REG_S0)(t0)
|
||||||
|
lw s1, REG_OFFSET(REG_S1)(t0)
|
||||||
|
|
||||||
|
/* return register block */
|
||||||
|
lw a0, REG_OFFSET(REG_A0)(t0)
|
||||||
|
lw a1, REG_OFFSET(REG_A1)(t0)
|
||||||
|
|
||||||
|
/* argument register block */
|
||||||
|
lw a2, REG_OFFSET(REG_A2)(t0)
|
||||||
|
lw a3, REG_OFFSET(REG_A3)(t0)
|
||||||
|
lw a4, REG_OFFSET(REG_A4)(t0)
|
||||||
|
lw a5, REG_OFFSET(REG_A5)(t0)
|
||||||
|
lw a6, REG_OFFSET(REG_A6)(t0)
|
||||||
|
lw a7, REG_OFFSET(REG_A7)(t0)
|
||||||
|
|
||||||
|
/* second saved register block */
|
||||||
|
lw s2, REG_OFFSET(REG_S2)(t0)
|
||||||
|
lw s3, REG_OFFSET(REG_S3)(t0)
|
||||||
|
lw s4, REG_OFFSET(REG_S4)(t0)
|
||||||
|
lw s5, REG_OFFSET(REG_S5)(t0)
|
||||||
|
lw s6, REG_OFFSET(REG_S6)(t0)
|
||||||
|
lw s7, REG_OFFSET(REG_S7)(t0)
|
||||||
|
lw s8, REG_OFFSET(REG_S8)(t0)
|
||||||
|
lw s9, REG_OFFSET(REG_S9)(t0)
|
||||||
|
lw s10, REG_OFFSET(REG_S10)(t0)
|
||||||
|
lw s11, REG_OFFSET(REG_S11)(t0)
|
||||||
|
|
||||||
|
/* done restoring, jump to new pc in S1 */
|
||||||
|
jr t1
|
||||||
|
END(libucontext_setcontext)
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
ALIAS(swapcontext, libucontext_swapcontext)
|
||||||
|
ALIAS(__swapcontext, libucontext_swapcontext)
|
||||||
|
|
||||||
|
FUNC(libucontext_swapcontext)
|
||||||
|
/* move $a1 to $t0 to avoid clobbering. */
|
||||||
|
mv t0, a1
|
||||||
|
|
||||||
|
sw ra, REG_OFFSET(REG_PC)(a0)
|
||||||
|
sw ra, REG_OFFSET(REG_RA)(a0)
|
||||||
|
sw sp, REG_OFFSET(REG_SP)(a0)
|
||||||
|
|
||||||
|
/* first saved register block */
|
||||||
|
sw s0, REG_OFFSET(REG_S0)(a0)
|
||||||
|
sw s1, REG_OFFSET(REG_S1)(a0)
|
||||||
|
|
||||||
|
/* return register block */
|
||||||
|
sw a0, REG_OFFSET(REG_A0)(a0)
|
||||||
|
sw a1, REG_OFFSET(REG_A1)(a0)
|
||||||
|
|
||||||
|
/* second saved register block */
|
||||||
|
sw s2, REG_OFFSET(REG_S2)(a0)
|
||||||
|
sw s3, REG_OFFSET(REG_S3)(a0)
|
||||||
|
sw s4, REG_OFFSET(REG_S4)(a0)
|
||||||
|
sw s5, REG_OFFSET(REG_S5)(a0)
|
||||||
|
sw s6, REG_OFFSET(REG_S6)(a0)
|
||||||
|
sw s7, REG_OFFSET(REG_S7)(a0)
|
||||||
|
sw s8, REG_OFFSET(REG_S8)(a0)
|
||||||
|
sw s9, REG_OFFSET(REG_S9)(a0)
|
||||||
|
sw s10, REG_OFFSET(REG_S10)(a0)
|
||||||
|
sw s11, REG_OFFSET(REG_S11)(a0)
|
||||||
|
|
||||||
|
/* restore the other context from $t0. */
|
||||||
|
lw t1, REG_OFFSET(REG_PC)(t0)
|
||||||
|
lw ra, REG_OFFSET(REG_RA)(t0)
|
||||||
|
lw sp, REG_OFFSET(REG_SP)(t0)
|
||||||
|
|
||||||
|
/* first saved register block */
|
||||||
|
lw s0, REG_OFFSET(REG_S0)(t0)
|
||||||
|
lw s1, REG_OFFSET(REG_S1)(t0)
|
||||||
|
|
||||||
|
/* return register block */
|
||||||
|
lw a0, REG_OFFSET(REG_A0)(t0)
|
||||||
|
lw a1, REG_OFFSET(REG_A1)(t0)
|
||||||
|
|
||||||
|
/* argument register block */
|
||||||
|
lw a2, REG_OFFSET(REG_A2)(t0)
|
||||||
|
lw a3, REG_OFFSET(REG_A3)(t0)
|
||||||
|
lw a4, REG_OFFSET(REG_A4)(t0)
|
||||||
|
lw a5, REG_OFFSET(REG_A5)(t0)
|
||||||
|
lw a6, REG_OFFSET(REG_A6)(t0)
|
||||||
|
lw a7, REG_OFFSET(REG_A7)(t0)
|
||||||
|
|
||||||
|
/* second saved register block */
|
||||||
|
lw s2, REG_OFFSET(REG_S2)(t0)
|
||||||
|
lw s3, REG_OFFSET(REG_S3)(t0)
|
||||||
|
lw s4, REG_OFFSET(REG_S4)(t0)
|
||||||
|
lw s5, REG_OFFSET(REG_S5)(t0)
|
||||||
|
lw s6, REG_OFFSET(REG_S6)(t0)
|
||||||
|
lw s7, REG_OFFSET(REG_S7)(t0)
|
||||||
|
lw s8, REG_OFFSET(REG_S8)(t0)
|
||||||
|
lw s9, REG_OFFSET(REG_S9)(t0)
|
||||||
|
lw s10, REG_OFFSET(REG_S10)(t0)
|
||||||
|
lw s11, REG_OFFSET(REG_S11)(t0)
|
||||||
|
|
||||||
|
/* done swapping, jump to new PC in S1 */
|
||||||
|
jr t1
|
||||||
|
END(libucontext_swapcontext)
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include "defs.h"
|
||||||
|
#include <libucontext/libucontext.h>
|
||||||
|
#include "common-trampoline.c"
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef LIBUCONTEXT_BITS_H
|
||||||
|
#define LIBUCONTEXT_BITS_H
|
||||||
|
|
||||||
|
typedef unsigned long libucontext_greg_t;
|
||||||
|
typedef unsigned long libucontext__riscv_mc_gp_state[32];
|
||||||
|
|
||||||
|
struct libucontext__riscv_mc_f_ext_state {
|
||||||
|
unsigned int __f[32];
|
||||||
|
unsigned int __fcsr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct libucontext__riscv_mc_d_ext_state {
|
||||||
|
unsigned long long __f[32];
|
||||||
|
unsigned int __fcsr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct libucontext__riscv_mc_q_ext_state {
|
||||||
|
unsigned long long __f[64] __attribute__((aligned(16)));
|
||||||
|
unsigned int __fcsr;
|
||||||
|
unsigned int __reserved[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
union libucontext__riscv_mc_fp_state {
|
||||||
|
struct libucontext__riscv_mc_f_ext_state __f;
|
||||||
|
struct libucontext__riscv_mc_d_ext_state __d;
|
||||||
|
struct libucontext__riscv_mc_q_ext_state __q;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct libucontext_mcontext {
|
||||||
|
libucontext__riscv_mc_gp_state __gregs;
|
||||||
|
union libucontext__riscv_mc_fp_state __fpregs;
|
||||||
|
} libucontext_mcontext_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *ss_sp;
|
||||||
|
int ss_flags;
|
||||||
|
size_t ss_size;
|
||||||
|
} libucontext_stack_t;
|
||||||
|
|
||||||
|
typedef struct libucontext_ucontext {
|
||||||
|
unsigned long uc_flags;
|
||||||
|
struct libucontext_ucontext *uc_link;
|
||||||
|
libucontext_stack_t uc_stack;
|
||||||
|
unsigned char __pad[128];
|
||||||
|
libucontext_mcontext_t uc_mcontext;
|
||||||
|
} libucontext_ucontext_t;
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,9 +10,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef __ARCH_X86_DEFS_H
|
#ifndef __ARCH_X86_DEFS_H
|
||||||
#define __ARCH_X86_DEFS_H
|
#define __ARCH_X86_DEFS_H
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#ifndef REG_GS
|
#ifndef REG_GS
|
||||||
# define REG_GS (0)
|
# define REG_GS (0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,7 +52,6 @@
|
||||||
#ifndef REG_EIP
|
#ifndef REG_EIP
|
||||||
# define REG_EIP (14)
|
# define REG_EIP (14)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#define REG_SZ (4)
|
#define REG_SZ (4)
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -1,29 +1,95 @@
|
||||||
#ifndef __ARCH_X86_64_DEFS_H
|
#ifndef __ARCH_X86_64_DEFS_H
|
||||||
#define __ARCH_X86_64_DEFS_H
|
#define __ARCH_X86_64_DEFS_H
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef REG_R8
|
||||||
# define REG_R8 (0)
|
# define REG_R8 (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_R9
|
||||||
# define REG_R9 (1)
|
# define REG_R9 (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_R10
|
||||||
# define REG_R10 (2)
|
# define REG_R10 (2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_R11
|
||||||
# define REG_R11 (3)
|
# define REG_R11 (3)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_R12
|
||||||
# define REG_R12 (4)
|
# define REG_R12 (4)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_R13
|
||||||
# define REG_R13 (5)
|
# define REG_R13 (5)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_R14
|
||||||
# define REG_R14 (6)
|
# define REG_R14 (6)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_R15
|
||||||
# define REG_R15 (7)
|
# define REG_R15 (7)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RDI
|
||||||
# define REG_RDI (8)
|
# define REG_RDI (8)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RSI
|
||||||
# define REG_RSI (9)
|
# define REG_RSI (9)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RBP
|
||||||
# define REG_RBP (10)
|
# define REG_RBP (10)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RBX
|
||||||
# define REG_RBX (11)
|
# define REG_RBX (11)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RDX
|
||||||
# define REG_RDX (12)
|
# define REG_RDX (12)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RAX
|
||||||
# define REG_RAX (13)
|
# define REG_RAX (13)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RCX
|
||||||
# define REG_RCX (14)
|
# define REG_RCX (14)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RSP
|
||||||
# define REG_RSP (15)
|
# define REG_RSP (15)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_RIP
|
||||||
# define REG_RIP (16)
|
# define REG_RIP (16)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_EFL
|
||||||
# define REG_EFL (17)
|
# define REG_EFL (17)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_CSGSFS
|
||||||
# define REG_CSGSFS (18)
|
# define REG_CSGSFS (18)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_ERR
|
||||||
# define REG_ERR (19)
|
# define REG_ERR (19)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_TRAPNO
|
||||||
# define REG_TRAPNO (20)
|
# define REG_TRAPNO (20)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_OLDMASK
|
||||||
# define REG_OLDMASK (21)
|
# define REG_OLDMASK (21)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef REG_CR2
|
||||||
# define REG_CR2 (22)
|
# define REG_CR2 (22)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
* from the use of this software.
|
* from the use of this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
scdoc = find_program('scdoc', required: true)
|
||||||
|
|
||||||
|
custom_target(
|
||||||
|
'libucontext.3',
|
||||||
|
output: 'libucontext.3',
|
||||||
|
input: 'libucontext.scd',
|
||||||
|
command: [ scdoc ],
|
||||||
|
feed: true,
|
||||||
|
capture: true,
|
||||||
|
install: true,
|
||||||
|
install_dir: get_option('mandir') / 'man3'
|
||||||
|
)
|
||||||
|
|
||||||
|
if meson.version().version_compare('>=0.61.0')
|
||||||
|
foreach link : [ 'get', 'make', 'set', 'swap' ]
|
||||||
|
install_symlink('libucontext_' + link + 'context.3',
|
||||||
|
pointing_to: 'libucontext.3',
|
||||||
|
install_dir: get_option('mandir') / 'man3'
|
||||||
|
)
|
||||||
|
endforeach
|
||||||
|
endif
|
|
@ -4,9 +4,17 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <libucontext/bits.h>
|
#include <libucontext/bits.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
int libucontext_getcontext(libucontext_ucontext_t *);
|
int libucontext_getcontext(libucontext_ucontext_t *);
|
||||||
void libucontext_makecontext(libucontext_ucontext_t *, void (*)(), int, ...);
|
void libucontext_makecontext(libucontext_ucontext_t *, void (*)(), int, ...);
|
||||||
int libucontext_setcontext(const libucontext_ucontext_t *);
|
int libucontext_setcontext(const libucontext_ucontext_t *);
|
||||||
int libucontext_swapcontext(libucontext_ucontext_t *, const libucontext_ucontext_t *);
|
int libucontext_swapcontext(libucontext_ucontext_t *, const libucontext_ucontext_t *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
libdir=@LIBUCONTEXT_LIBDIR@
|
libdir=@LIBUCONTEXT_SHARED_LIBDIR@
|
||||||
|
static_libdir=@LIBUCONTEXT_STATIC_LIBDIR@
|
||||||
includedir=@LIBUCONTEXT_INCLUDEDIR@
|
includedir=@LIBUCONTEXT_INCLUDEDIR@
|
||||||
|
|
||||||
Name: libucontext
|
Name: libucontext
|
||||||
Version: @LIBUCONTEXT_VERSION@
|
Version: @LIBUCONTEXT_VERSION@
|
||||||
Description: ucontext library implementation (standalone)
|
Description: ucontext library implementation (standalone)
|
||||||
Libs: -L${libdir} -lucontext
|
Libs: -L${libdir} -L${static_libdir} -lucontext
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|
19
meson.build
19
meson.build
|
@ -1,12 +1,16 @@
|
||||||
project(
|
project(
|
||||||
'libucontext',
|
'libucontext',
|
||||||
'c',
|
'c',
|
||||||
meson_version : '>=0.55.0',
|
meson_version : '>=0.59.0',
|
||||||
default_options: ['c_std=gnu11', 'default_library=both'],
|
default_options: ['c_std=gnu11', 'default_library=both'],
|
||||||
version : run_command('head', files('VERSION')).stdout()
|
version : run_command('head', files('VERSION')).stdout()
|
||||||
)
|
)
|
||||||
|
|
||||||
cpu = host_machine.cpu_family()
|
cpu = get_option('cpu')
|
||||||
|
if cpu == ''
|
||||||
|
cpu = host_machine.cpu_family()
|
||||||
|
endif
|
||||||
|
|
||||||
if cpu == 'sh4'
|
if cpu == 'sh4'
|
||||||
cpu = 'sh'
|
cpu = 'sh'
|
||||||
endif
|
endif
|
||||||
|
@ -70,9 +74,11 @@ if freestanding
|
||||||
build_args += '-DFREESTANDING'
|
build_args += '-DFREESTANDING'
|
||||||
build_posix = false
|
build_posix = false
|
||||||
export_unprefixed = false
|
export_unprefixed = false
|
||||||
project_headers += ['arch' / cpu / 'freestanding/bits.h']
|
project_headers += ['arch' / cpu / 'include/libucontext/bits.h']
|
||||||
|
project_includes += ['arch' / cpu / 'include']
|
||||||
else
|
else
|
||||||
project_headers += ['arch/common/bits.h']
|
project_headers += ['arch/common/include/libucontext/bits.h']
|
||||||
|
project_includes += ['arch/common/include']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if export_unprefixed
|
if export_unprefixed
|
||||||
|
@ -138,9 +144,8 @@ endif
|
||||||
# Docs
|
# Docs
|
||||||
# ====
|
# ====
|
||||||
|
|
||||||
# TODO: meson.build for docs
|
if not meson.is_subproject() and get_option('docs')
|
||||||
if not meson.is_subproject()
|
subdir('doc')
|
||||||
#subdir('docs')
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# ==========
|
# ==========
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
option('freestanding', type : 'boolean', value : false,
|
option('freestanding', type : 'boolean', value : false,
|
||||||
description: 'Do not use system headers')
|
description: 'Do not use system headers')
|
||||||
option('export_unprefixed', type : 'boolean', value : true,
|
option('export_unprefixed', type : 'boolean', value : true,
|
||||||
description: 'Export POSIX 2004 ucontext names as alises')
|
description: 'Export POSIX 2004 ucontext names as alises')
|
||||||
|
option('cpu', type : 'string', value : '',
|
||||||
|
description: 'Target CPU architecture for cross compile')
|
||||||
|
option('docs', type : 'boolean', value : false,
|
||||||
|
description: 'Build and install man pages')
|
||||||
|
|
Loading…
Reference in New Issue