Compare commits

..

No commits in common. "master" and "libucontext-0.10" have entirely different histories.

122 changed files with 385 additions and 3953 deletions

11
.gitignore vendored
View File

@ -1,16 +1,5 @@
include/libucontext/bits.h
*.o
examples/cooperative_threading
test_libucontext
test_libucontext_posix
test_libucontext_bare_posixabi
libucontext.a
libucontext.so
libucontext.so.*
libucontext_posix.a
libucontext_posix.so
libucontext_posix.so.*
libucontext.pc
*.tar.xz
core
*.core

View File

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

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2022 Ariadne Conill <ariadne@dereferenced.org>
Copyright (c) 2018-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

276
Makefile
View File

@ -1,284 +1,52 @@
SCDOC := scdoc
ARCH := $(shell uname -m)
ifeq ($(ARCH),$(filter $(ARCH),i386 i686))
override ARCH = x86
endif
ifeq ($(ARCH),$(filter $(ARCH),sh2 sh4))
override ARCH = sh
endif
ifeq ($(ARCH),$(filter $(ARCH),ppc64le))
override ARCH = ppc64
endif
ifeq ($(ARCH),$(filter $(ARCH),armv7l))
override ARCH = arm
endif
ifeq ($(ARCH),$(filter $(ARCH),arm64))
override ARCH = aarch64
endif
prefix = /usr
libdir = ${prefix}/lib
shared_libdir = ${libdir}
static_libdir = ${libdir}
includedir = ${prefix}/include
pkgconfigdir = ${prefix}/lib/pkgconfig
CFLAGS ?= -ggdb3 -O2 -Wall
CPPFLAGS := -Iinclude -Iarch/${ARCH} -Iarch/common
ifneq ($(shell uname),Darwin)
EXPORT_UNPREFIXED := yes
else
# Darwin does not support aliases
EXPORT_UNPREFIXED := no
endif
FREESTANDING := no
ifeq ($(FREESTANDING),yes)
CPPFLAGS += -DFREESTANDING
EXPORT_UNPREFIXED = no
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)
CPPFLAGS += -DEXPORT_UNPREFIXED
endif
CFLAGS = -ggdb3 -O2 -Wall -Iarch/${ARCH} -Iarch/common
LIBUCONTEXT_C_SRC = $(wildcard arch/${ARCH}/*.c)
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_OBJ = ${LIBUCONTEXT_C_SRC:.c=.o} ${LIBUCONTEXT_S_SRC:.S=.o}
LIBUCONTEXT_SOVERSION = 1
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_SOVERSION = 0
LIBUCONTEXT_NAME = libucontext.so
LIBUCONTEXT_STATIC_NAME = libucontext.a
LIBUCONTEXT_PC = libucontext.pc
LIBUCONTEXT_PATH = ${shared_libdir}/${LIBUCONTEXT_SONAME}
LIBUCONTEXT_STATIC_PATH = ${static_libdir}/${LIBUCONTEXT_STATIC_NAME}
LIBUCONTEXT_HEADERS = \
include/libucontext/libucontext.h \
include/libucontext/bits.h
LIBUCONTEXT_EXAMPLES = \
examples/cooperative_threading
LIBUCONTEXT_POSIX_STATIC_NAME = libucontext_posix.a
LIBUCONTEXT_POSIX_C_SRC = libucontext_posix.c
LIBUCONTEXT_POSIX_OBJ = ${LIBUCONTEXT_POSIX_C_SRC:.c=.o}
LIBUCONTEXT_POSIX_PATH = ${shared_libdir}/${LIBUCONTEXT_POSIX_SONAME}
LIBUCONTEXT_POSIX_STATIC_PATH = ${static_libdir}/${LIBUCONTEXT_POSIX_STATIC_NAME}
LIBUCONTEXT_SONAME = libucontext.so.${LIBUCONTEXT_SOVERSION}
LIBUCONTEXT_PATH = /lib/${LIBUCONTEXT_SONAME}
LIBUCONTEXT_STATIC_PATH = /lib/${LIBUCONTEXT_STATIC_NAME}
ifeq ($(FREESTANDING),yes)
LIBUCONTEXT_POSIX_NAME =
LIBUCONTEXT_POSIX_STATIC_NAME =
endif
all: ${LIBUCONTEXT_SONAME} ${LIBUCONTEXT_STATIC_NAME}
all: ${LIBUCONTEXT_SONAME} ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_POSIX_NAME} ${LIBUCONTEXT_POSIX_STATIC_NAME} ${LIBUCONTEXT_PC}
${LIBUCONTEXT_POSIX_NAME}: ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_POSIX_OBJ}
$(CC) -fPIC -o ${LIBUCONTEXT_POSIX_NAME} ${LIBUCONTEXT_POSIX_LINKER_FLAGS} ${LIBUCONTEXT_POSIX_OBJ} -L. -lucontext ${LDFLAGS}
${LIBUCONTEXT_POSIX_STATIC_NAME}: ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_POSIX_OBJ}
$(AR) rcs ${LIBUCONTEXT_POSIX_STATIC_NAME} ${LIBUCONTEXT_POSIX_OBJ}
${LIBUCONTEXT_POSIX_SONAME}: ${LIBUCONTEXT_POSIX_NAME}
ln -sf ${LIBUCONTEXT_POSIX_NAME} ${LIBUCONTEXT_POSIX_SONAME}
${LIBUCONTEXT_STATIC_NAME}: ${LIBUCONTEXT_HEADERS} ${LIBUCONTEXT_OBJ}
${LIBUCONTEXT_STATIC_NAME}: ${LIBUCONTEXT_OBJ}
$(AR) rcs ${LIBUCONTEXT_STATIC_NAME} ${LIBUCONTEXT_OBJ}
${LIBUCONTEXT_NAME}: ${LIBUCONTEXT_HEADERS} ${LIBUCONTEXT_OBJ}
$(CC) -fPIC -o ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_LINKER_FLAGS} ${LIBUCONTEXT_OBJ} ${LDFLAGS}
${LIBUCONTEXT_NAME}: ${LIBUCONTEXT_OBJ}
$(CC) -o ${LIBUCONTEXT_NAME} -Wl,-soname,${LIBUCONTEXT_SONAME} \
-shared ${LIBUCONTEXT_OBJ} ${LDFLAGS}
${LIBUCONTEXT_SONAME}: ${LIBUCONTEXT_NAME}
ln -sf ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_SONAME}
${LIBUCONTEXT_PC}: libucontext.pc.in
sed -e s:@LIBUCONTEXT_VERSION@:${LIBUCONTEXT_VERSION}:g \
-e s:@LIBUCONTEXT_SHARED_LIBDIR@:${shared_libdir}:g \
-e s:@LIBUCONTEXT_STATIC_LIBDIR@:${static_libdir}:g \
-e s:@LIBUCONTEXT_INCLUDEDIR@:${includedir}:g $< > $@
MANPAGES_SYMLINKS_3 = \
libucontext_getcontext.3 \
libucontext_makecontext.3 \
libucontext_setcontext.3 \
libucontext_swapcontext.3
MANPAGES_3 = doc/libucontext.3
MANPAGES = ${MANPAGES_3}
.scd.3:
${SCDOC} < $< > $@
.SUFFIXES: .scd .3
docs: ${MANPAGES}
.c.o:
$(CC) -std=gnu99 -D_BSD_SOURCE -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
$(CC) -std=c99 -D_BSD_SOURCE -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
.S.o:
$(CC) -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} ${ASFLAGS} -c -o $@ $<
$(CC) -fPIC -DPIC ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
${LIBUCONTEXT_NAME}_clean:
rm -f ${LIBUCONTEXT_NAME}
${LIBUCONTEXT_SONAME}_clean:
rm -f ${LIBUCONTEXT_SONAME}
${LIBUCONTEXT_STATIC_NAME}_clean:
rm -f ${LIBUCONTEXT_STATIC_NAME}
libucontext_obj_clean:
rm -f ${LIBUCONTEXT_OBJ}
${LIBUCONTEXT_PC}_clean:
rm -f ${LIBUCONTEXT_PC}
bits_clean:
rm -f include/libucontext/bits.h
${LIBUCONTEXT_POSIX_NAME}_clean:
rm -f ${LIBUCONTEXT_POSIX_NAME}
${LIBUCONTEXT_POSIX_SONAME}_clean:
rm -f ${LIBUCONTEXT_POSIX_SONAME}
${LIBUCONTEXT_POSIX_STATIC_NAME}_clean:
rm -f ${LIBUCONTEXT_POSIX_STATIC_NAME}
libucontext_posix_obj_clean:
rm -f ${LIBUCONTEXT_POSIX_OBJ}
check_clean: check_bare_clean check_posix_clean check_bare_posixabi_clean
check_bare_clean:
rm -f test_libucontext
check_posix_clean:
rm -f test_libucontext_posix
check_bare_posixabi_clean:
rm -f test_libucontext_bare_posixabi
docs_clean:
rm -f ${MANPAGES}
clean: ${LIBUCONTEXT_NAME}_clean
clean: ${LIBUCONTEXT_SONAME}_clean
clean: ${LIBUCONTEXT_STATIC_NAME}_clean
clean: ${LIBUCONTEXT_PC}_clean
clean: bits_clean
clean: ${LIBUCONTEXT_POSIX_NAME}_clean
clean: ${LIBUCONTEXT_POSIX_SONAME}_clean
clean: ${LIBUCONTEXT_POSIX_STATIC_NAME}_clean
clean: libucontext_posix_obj_clean
clean: libucontext_obj_clean
clean: check_clean
clean: docs_clean
clean:
rm -f ${LIBUCONTEXT_NAME} ${LIBUCONTEXT_SONAME} ${LIBUCONTEXT_STATIC_NAME} \
${LIBUCONTEXT_OBJ} test_libucontext
install: all
install -D -m755 ${LIBUCONTEXT_NAME} ${DESTDIR}${LIBUCONTEXT_PATH}
install -D -m664 ${LIBUCONTEXT_STATIC_NAME} ${DESTDIR}${LIBUCONTEXT_STATIC_PATH}
ln -sf ${LIBUCONTEXT_SONAME} ${DESTDIR}${shared_libdir}/${LIBUCONTEXT_NAME}
for i in ${LIBUCONTEXT_HEADERS}; do \
destfn=$$(echo $$i | sed s:include/::g); \
install -D -m644 $$i ${DESTDIR}${includedir}/$$destfn; \
done
install -D -m644 ${LIBUCONTEXT_PC} ${DESTDIR}${pkgconfigdir}/${LIBUCONTEXT_PC}
if [ -n "${LIBUCONTEXT_POSIX_NAME}" ]; then \
install -D -m755 ${LIBUCONTEXT_POSIX_NAME} ${DESTDIR}${LIBUCONTEXT_POSIX_PATH}; \
install -D -m644 ${LIBUCONTEXT_POSIX_STATIC_NAME} ${DESTDIR}${LIBUCONTEXT_POSIX_STATIC_PATH}; \
fi
install -D -m755 ${LIBUCONTEXT_NAME} ${DESTDIR}/${LIBUCONTEXT_PATH}
install -D -m664 ${LIBUCONTEXT_STATIC_NAME} ${DESTDIR}/${LIBUCONTEXT_STATIC_PATH}
ln -sf ${LIBUCONTEXT_SONAME} ${DESTDIR}/lib/${LIBUCONTEXT_NAME}
install_docs: docs
install -D -m644 doc/libucontext.3 ${DESTDIR}/usr/share/man/man3/libucontext.3
for i in ${MANPAGES_SYMLINKS_3}; do \
ln -s libucontext.3 ${DESTDIR}/usr/share/man/man3/$$i; \
done
ifneq (${FREESTANDING},yes)
check: check_libucontext_posix
check_libucontext_posix: test_libucontext_posix ${LIBUCONTEXT_POSIX_SONAME} ${LIBUCONTEXT_SONAME}
env LD_LIBRARY_PATH=$(shell pwd) ./test_libucontext_posix
test_libucontext_posix: test_libucontext_posix.c ${LIBUCONTEXT_POSIX_NAME}
$(CC) -std=gnu99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} $@.c -o $@ -L. -lucontext -lucontext_posix
endif
ifeq ($(EXPORT_UNPREFIXED),yes)
check: check_libucontext_bare_posixabi
check_libucontext_bare_posixabi: test_libucontext_bare_posixabi ${LIBUCONTEXT_SONAME}
env LD_LIBRARY_PATH=$(shell pwd) ./test_libucontext_bare_posixabi
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
endif
check_libucontext: test_libucontext ${LIBUCONTEXT_SONAME}
check: test_libucontext ${LIBUCONTEXT_SONAME}
env LD_LIBRARY_PATH=$(shell pwd) ./test_libucontext
check: check_libucontext
test_libucontext: test_libucontext.c ${LIBUCONTEXT_NAME}
$(CC) -std=gnu99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} $@.c -o $@ -L. -lucontext
$(CC) -std=c99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} $@.c -o $@ -L. -lucontext
examples: ${LIBUCONTEXT_EXAMPLES}
examples/cooperative_threading: examples/cooperative_threading.c ${LIBUCONTEXT_NAME}
$(CC) -std=gnu99 -D_BSD_SOURCE ${CFLAGS} ${CPPFLAGS} $@.c -o $@ -L. -lucontext
ifeq ($(FREESTANDING),no)
include/libucontext/bits.h: arch/common/include/libucontext/bits.h
cp $< $@
else
include/libucontext/bits.h: arch/${ARCH}/include/libucontext/bits.h
cp $< $@
endif
PACKAGE_NAME = libucontext
PACKAGE_VERSION = ${LIBUCONTEXT_VERSION}
DIST_NAME = ${PACKAGE_NAME}-${PACKAGE_VERSION}
DIST_TARBALL = ${DIST_NAME}.tar.xz
distcheck: check dist
dist: ${DIST_TARBALL}
${DIST_TARBALL}:
git archive --format=tar --prefix=${DIST_NAME}/ -o ${DIST_NAME}.tar ${DIST_NAME}
xz ${DIST_NAME}.tar
.PHONY: check dist
.PHONY: check

85
NEWS
View File

@ -1,88 +1,3 @@
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
--------------------------
* Implement common libucontext_trampoline, written in C with inline
assembly.
* Added Renesas / Hitachi SH-2/SH-4 port (sh).
* Added Meson build system, primarily for the convenience of using
libucontext with qemu as a subproject.
* Added support for Mach-O ABI.
* Fixed deficiencies in libucontext ABI, SONAME has been bumped due
to the ABI regressions in 0.13.
Changes from 0.13 to 0.13.1
---------------------------
* Fix installation of libucontext.pc.
Patch contributed by Ömer Faruk IRMAK.
Changes from 0.12 to 0.13
-------------------------
* Aligned RISC-V RV64 port's header usage with musl 1.2 to remove
warnings and ensure consistent register name usage.
* Added Motorola 680X0 / NXP ColdFire port (m68k).
* Added support for building for bare-metal targets with newlib via
make FREESTANDING=yes. Other OS are also supported (for example,
the m68k freestanding port was tested on AmigaOS), PowerPC requires
kernel assistance and cannot be built with FREESTANDING=yes. Not
all ports have support for FREESTANDING yet, patches welcome.
Changes from 0.11 to 0.12
-------------------------
* Fixed compilation of RISC-V RV64 port with modern musl releases.
Changes from 0.10 to 0.11
-------------------------
* Added RISC-V RV64 port.
* Fixed compilation with clang.
Patch contributed by Khem Raj.
* Add ${LIBDIR} variable to build system.
Patch contributed by Khem Raj.
Changes from 0.9.0 to 0.10
--------------------------

View File

@ -6,33 +6,25 @@ it faithfully follows the kernel process ABI when doing context swaps.
Notably, when combined with `gcompat`, it provides a fully compatible implementation of the ucontext
functions that are ABI compatible with glibc.
Since version 0.13, for some architectures, you can deploy to bare metal using newlib via the
`FREESTANDING=yes` make option. Systems which use a syscall cannot work this way. The table
below shows which architecture ports have been adapted to build with `FREESTANDING=yes`.
Adding support for new architectures is easy, but you need to know assembly language for the
target to do it.
## supported architectures
Adding support for new architectures is easy, but you need to know assembly language to do it.
## supported features
Right now these archs are supported and should work on bare metal:
| Architecture | Works on musl | Syscall | Supports FREESTANDING | Common trampoline |
|--------------|---------------|---------|-----------------------|-------------------|
| aarch64 | ✓ | | ✓ | ✓ |
| arm | ✓ | | ✓ | ✓ |
| loongarch64 | ✓ | | ✓ | |
| m68k | ✓ | | ✓ | ✓ |
| mips | ✓ | | ✓ | |
| mips64 | ✓ | | ✓ | |
| or1k | ✓ | | ✓ | ✓ |
| ppc | ✓ | ✓ | | |
| ppc64 | ✓ | ✓ | | |
| riscv32 | ✓ | | ✓ | ✓ |
| riscv64 | ✓ | | ✓ | ✓ |
| s390x | ✓ | | ✓ | |
| sh | ✓ | | ✓ | ✓ |
| x86 | ✓ | | ✓ | ✓ |
| x86_64 | ✓ | | ✓ | ✓ |
* x86
* x86_64
* armv6+ (`arm`)
* aarch64
* s390x
* mips (O32 ABI only)
* mips64 (N32/N64 ABI only, like Alpine, only N64 ABI has been tested)
These archs require kernel assistance and use a syscall:
* ppc
* ppc64 (ELFv2 ABI spec only, ELFv1 not supported)
## building
@ -46,60 +38,8 @@ $ make ARCH=x86_64 check
$ make ARCH=x86_64 DESTDIR=out install
```
There are a few options:
* `ARCH`: The architecture libucontext is being built for. Must be set to one of the architectures
listed in the feature support table. If unset, the build system will attempt to guess based on what
architecture the host is running. Setting this option explicitly is highly recommended.
## support
* `FREESTANDING`: If this is set to `yes`, the system ucontext.h headers will not be used. Instead,
the headers in `arch/${ARCH}/freestanding` will be used for definitions where appropriate.
Default is `no`.
* `EXPORT_UNPREFIXED`: If this is set to `yes`, the POSIX 2004 names `getcontext`, `setcontext`,
`swapcontext` and `makecontext` will be provided as weak symbols aliased against their `libucontext_`
namespaced equivalents. This is necessary for libucontext to provide these functions on musl
systems, but you may wish to disable this when using `FREESTANDING` mode to avoid conflicts with
the target's libc. Default is `yes`.
* `DESTDIR`: If this variable is set, the installed files will be installed to the specified path instead
of the system root.
If you have `scdoc` installed, you can build manpages and install them:
```
$ make docs
$ 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
`libucontext`, while largely functionally equivalent does have some differences over traditional POSIX
ucontext functions:
* Saving and restoring the signal mask is not implemented by default in order to avoid kernel syscall
overhead. Use `-lucontext_posix` if you actually need this functionality, which provides a POSIX
compliant implementation at the cost of performance.
* 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
vector processing (AltiVec/AVX/NEON) registers. Adding this capability detection would significantly
increase the complexity of the project and thus is not implemented. Support for compiling in code to
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
does not really matter, code using these functions are unlikely to be impacted by this design
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.
`libucontext` is offered as part of the `gcompat` project. Accordingly, please address all questions
and bug reports to gcompat@lists.adelielinux.org.

View File

@ -1 +0,0 @@
1.2

View File

@ -9,7 +9,6 @@
#define SP_OFFSET 432
#define PC_OFFSET 440
#define PSTATE_OFFSET 448
#define FPSIMD_CONTEXT_OFFSET 464
#ifndef FPSIMD_MAGIC
# define FPSIMD_MAGIC 0x46508001
@ -19,9 +18,6 @@
# define ESR_MAGIC 0x45535201
#endif
#define FETCH_LINKPTR(dest) \
asm("mov %0, x19" : "=r" ((dest)))
#include "common-defs.h"
#endif

View File

@ -12,14 +12,9 @@
#include "defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
ALIAS(getcontext, __getcontext)
.global PROC_NAME(libucontext_getcontext);
.align 2;
TYPE(libucontext_getcontext)
ENT(libucontext_getcontext)
PROC_NAME(libucontext_getcontext):
FUNC(__getcontext)
str xzr, [x0, #REG_OFFSET(0)]
/* save GPRs */
@ -50,12 +45,8 @@ PROC_NAME(libucontext_getcontext):
/* save pstate */
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]
/* TODO: SIMD / FPRs */
mov x0, #0
ret
END(libucontext_getcontext)
END(__getcontext)

View File

@ -1,34 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
typedef unsigned long libucontext_greg_t;
typedef unsigned long libucontext_gregset_t[34];
typedef struct {
__uint128_t vregs[32];
unsigned int fpsr;
unsigned int fpcr;
} libucontext_fpregset_t;
typedef struct sigcontext {
unsigned long fault_address;
unsigned long regs[31];
unsigned long sp, pc, pstate;
long double __reserved[256];
} 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[136];
libucontext_mcontext_t uc_mcontext;
} libucontext_ucontext_t;
#endif

View File

@ -10,24 +10,21 @@
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include "defs.h"
#include <libucontext/libucontext.h>
extern void libucontext_trampoline(void);
extern void __start_context(void);
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.regs[0]) == R0_OFFSET, "R0_OFFSET is invalid");
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.sp) == SP_OFFSET, "SP_OFFSET is invalid");
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.pc) == PC_OFFSET, "PC_OFFSET is invalid");
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.pstate) == PSTATE_OFFSET, "PSTATE_OFFSET is invalid");
void
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
unsigned long *sp;
unsigned long *regp;
@ -41,7 +38,7 @@ libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int arg
ucp->uc_mcontext.sp = (uintptr_t) sp;
ucp->uc_mcontext.pc = (uintptr_t) func;
ucp->uc_mcontext.regs[19] = (uintptr_t) ucp->uc_link;
ucp->uc_mcontext.regs[30] = (uintptr_t) &libucontext_trampoline;
ucp->uc_mcontext.regs[30] = (uintptr_t) &__start_context;
va_start(va, argc);
@ -56,7 +53,5 @@ libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int arg
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
extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext")));

View File

@ -12,14 +12,9 @@
#include "defs.h"
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext)
ALIAS(setcontext, __setcontext)
.global PROC_NAME(libucontext_setcontext);
.align 2;
TYPE(libucontext_setcontext)
ENT(libucontext_setcontext)
PROC_NAME(libucontext_setcontext):
FUNC(__setcontext)
/* restore GPRs */
ldp x18, x19, [x0, #REG_OFFSET(18)]
ldp x20, x21, [x0, #REG_OFFSET(20)]
@ -33,11 +28,7 @@ PROC_NAME(libucontext_setcontext):
ldr x2, [x0, #SP_OFFSET]
mov sp, x2
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]
/* TODO: SIMD / FPRs */
/* save current program counter in link register */
ldr x16, [x0, #PC_OFFSET]
@ -50,4 +41,4 @@ PROC_NAME(libucontext_setcontext):
/* jump to new PC */
br x16
END(libucontext_setcontext)
END(__setcontext)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
* 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
@ -10,20 +10,13 @@
* from the use of this software.
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include "defs.h"
__attribute__ ((visibility ("hidden")))
void
libucontext_trampoline(void)
{
register libucontext_ucontext_t *uc_link = NULL;
FUNC(__start_context)
/* get the proper context into position and test for NULL */
mov x0, x19
cbnz x0, __setcontext
FETCH_LINKPTR(uc_link);
if (uc_link == NULL)
exit(0);
libucontext_setcontext(uc_link);
}
/* something went wrong, exit */
b exit
END(__start_context)

View File

@ -12,14 +12,9 @@
#include "defs.h"
ALIAS(swapcontext, libucontext_swapcontext)
ALIAS(__swapcontext, libucontext_swapcontext)
ALIAS(swapcontext, __swapcontext)
.global PROC_NAME(libucontext_swapcontext);
.align 2;
TYPE(libucontext_swapcontext)
ENT(libucontext_swapcontext)
PROC_NAME(libucontext_swapcontext):
FUNC(__swapcontext)
str xzr, [x0, #REG_OFFSET(0)]
/* save GPRs */
@ -49,21 +44,15 @@ PROC_NAME(libucontext_swapcontext):
/* save pstate */
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 */
/* store our link register in x28 */
mov x28, x30
/* move x1 to x0 and call setcontext */
mov x0, x1
bl PROC_NAME(libucontext_setcontext)
bl __setcontext
/* hmm, we came back here try to return */
mov x30, x28
ret
END(libucontext_swapcontext)
END(__swapcontext)

View File

@ -1,3 +0,0 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"

View File

@ -2,13 +2,8 @@
#define REG_SZ (4)
#define MCONTEXT_GREGS (32)
#define VFP_MAGIC_OFFSET (232)
#define VFP_D8_OFFSET (304)
#define TYPE(__proc) .type __proc, %function;
#define FETCH_LINKPTR(dest) \
asm("movs %0, r4" : "=r" ((dest)))
#define TYPE(__proc)
#include "common-defs.h"

View File

@ -12,38 +12,16 @@
#include "defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
ALIAS(getcontext, __getcontext)
FUNC(libucontext_getcontext)
FUNC(__getcontext)
/* copy all of the current registers into the ucontext structure */
add r1, r0, #REG_OFFSET(4)
stmia r1, {r4-r12}
str r13, [r0, #REG_OFFSET(13)]
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 */
mov r0, #0
mov pc, lr
END(libucontext_getcontext)
END(__getcontext)

View File

@ -1,30 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
typedef int libucontext_greg_t, libucontext_gregset_t[18];
typedef struct {
unsigned long trap_no, error_code, oldmask;
unsigned long arm_r0, arm_r1, arm_r2, arm_r3;
unsigned long arm_r4, arm_r5, arm_r6, arm_r7;
unsigned long arm_r8, arm_r9, arm_r10, arm_fp;
unsigned long arm_ip, arm_sp, arm_lr, arm_pc;
unsigned long arm_cpsr, fault_address;
} 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;
libucontext_mcontext_t uc_mcontext;
unsigned long uc_sigmask[128 / sizeof(long)];
unsigned long long uc_regspace[64];
} libucontext_ucontext_t;
#endif

View File

@ -10,22 +10,23 @@
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include "defs.h"
#include <libucontext/libucontext.h>
extern void libucontext_trampoline(void);
extern void __start_context(void);
void
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
unsigned long *sp;
unsigned long *regp;
@ -41,7 +42,7 @@ libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int arg
ucp->uc_mcontext.arm_sp = (uintptr_t) sp;
ucp->uc_mcontext.arm_pc = (uintptr_t) func;
ucp->uc_mcontext.arm_r4 = (uintptr_t) ucp->uc_link;
ucp->uc_mcontext.arm_lr = (uintptr_t) &libucontext_trampoline;
ucp->uc_mcontext.arm_lr = (uintptr_t) &__start_context;
va_start(va, argc);
@ -56,7 +57,5 @@ libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int arg
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
extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext")));

View File

@ -12,26 +12,9 @@
#include "defs.h"
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, 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
ALIAS(setcontext, __setcontext)
FUNC(__setcontext)
/* copy all of the current registers into the ucontext structure */
add r14, r0, #REG_OFFSET(0)
ldmia r14, {r0-r12}
@ -40,4 +23,4 @@ FUNC(libucontext_setcontext)
/* load link register and jump to new context */
ldmia r14, {r14, pc}
END(libucontext_setcontext)
END(__setcontext)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Peng Fan <fanpeng@loongson.cn>
* 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
@ -10,24 +10,14 @@
* from the use of this software.
*/
#define LOCALSZ (4)
.globl __start_context;
.fnstart
.cantunwind
nop
__start_context:
/* get the proper context into position and test for NULL */
movs r0, r4
bne __setcontext@plt
#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)
/* we are returning into a null context, it seems, so maybe we should exit */
b exit@plt

View File

@ -12,40 +12,19 @@
#include "defs.h"
ALIAS(swapcontext, libucontext_swapcontext)
ALIAS(__swapcontext, libucontext_swapcontext)
ALIAS(swapcontext, __swapcontext)
FUNC(libucontext_swapcontext)
FUNC(__swapcontext)
/* copy all of the current registers into the ucontext structure */
add r2, r0, #REG_OFFSET(0)
stmia r2, {r0-r12}
str r13, [r0,#REG_OFFSET(13)]
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 */
add r14, r1, #REG_OFFSET(0)
ldmia r14, {r0-r12}
ldr r13, [r14, #52]
add r14, r14, #56
ldmia r14, {r14, pc}
END(libucontext_swapcontext)
END(__swapcontext)

View File

@ -1,3 +0,0 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"

View File

@ -18,43 +18,24 @@
#endif
#ifndef TYPE
# ifdef __clang__
# define TYPE(__proc) // .type not supported
# else
# define TYPE(__proc) .type __proc, @function;
#endif
#endif
#ifndef PROC_NAME
# ifdef __MACH__
# define PROC_NAME(__proc) _ ## __proc
# else
# define PROC_NAME(__proc) __proc
# endif
# define TYPE(__proc) .type __proc, @function;
#endif
#define FUNC(__proc) \
.global PROC_NAME(__proc); \
.global __proc; \
.align 2; \
TYPE(__proc) \
ENT(__proc) \
PROC_NAME(__proc): \
__proc: \
SETUP_FRAME(__proc)
#ifdef __clang__
#define END(__proc)
#else
#define END(__proc) \
.end __proc; \
.size __proc,.-__proc;
#endif
#ifdef EXPORT_UNPREFIXED
#define ALIAS(__alias, __real) \
.weak __alias; \
__alias = __real;
#else
#define ALIAS(...)
#endif
#define REG_OFFSET(__reg) (MCONTEXT_GREGS + ((__reg) * REG_SZ))

View File

@ -1,13 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
#ifndef FREESTANDING
#include <ucontext.h>
typedef greg_t libucontext_greg_t;
typedef ucontext_t libucontext_ucontext_t;
#endif
#endif

View File

@ -1,76 +0,0 @@
#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

View File

@ -1,43 +0,0 @@
#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

View File

@ -1,46 +0,0 @@
/*
* 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)

View File

@ -1,108 +0,0 @@
/*
* 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)

View File

@ -1,55 +0,0 @@
/*
* 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)

View File

@ -1,89 +0,0 @@
/*
* 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)

View File

@ -1,34 +0,0 @@
#ifndef __ARCH_M68K_DEFS_H
#define __ARCH_M68K_DEFS_H
#define REG_SZ (4)
#define MCONTEXT_GREGS (24)
#define REG_D0 (0)
#define REG_D1 (1)
#define REG_D2 (2)
#define REG_D3 (3)
#define REG_D4 (4)
#define REG_D5 (5)
#define REG_D6 (6)
#define REG_D7 (7)
#define REG_A0 (8)
#define REG_A1 (9)
#define REG_A2 (10)
#define REG_A3 (11)
#define REG_A4 (12)
#define REG_A5 (13)
#define REG_A6 (14)
#define REG_A7 (15)
#define REG_SP (15)
#define REG_PC (16)
#define REG_PS (17)
#define PC_OFFSET REG_OFFSET(REG_PC)
#define FETCH_LINKPTR(dest) \
asm("mov.l (%%sp, %%d7.l * 4), %0" :: "r" ((dest)))
#include "common-defs.h"
#endif

View File

@ -1,30 +0,0 @@
/*
* 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)
move.l 4(%sp), %a0 /* load ucontext_t pointer from stack */
movem.l %d2-%d7, REG_OFFSET(REG_D2)(%a0) /* preserve $d2 through $d7 */
movem.l %a2-%a6, REG_OFFSET(REG_A2)(%a0) /* preserve $a2 through $a6 */
lea 4(%sp), %a1 /* load stack pointer into $a1 */
move.l %a1, REG_OFFSET(REG_SP)(%a0) /* store $a1 in ucontext */
move.l (%sp), REG_OFFSET(REG_PC)(%a0) /* store return address in ucontext's PC register */
clr.l %d0 /* return 0 */
rts
END(libucontext_getcontext)

View File

@ -1,28 +0,0 @@
#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[18];
typedef struct {
int f_pcr, f_psr, f_fpiaddr, f_fpregs[8][3];
} libucontext_fpregset_t;
typedef struct {
int version;
libucontext_gregset_t gregs;
libucontext_fpregset_t fpregs;
} 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

View File

@ -1,61 +0,0 @@
/*
* 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 <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 + 2);
sp = (libucontext_greg_t *) (((uintptr_t) sp & ~0x3));
/* set up the ucontext structure */
ucp->uc_mcontext.gregs[REG_SP] = (libucontext_greg_t) sp;
ucp->uc_mcontext.gregs[REG_A6] = 0;
ucp->uc_mcontext.gregs[REG_D7] = argc;
ucp->uc_mcontext.gregs[REG_PC] = (libucontext_greg_t) func;
/* return address */
*sp++ = (libucontext_greg_t) libucontext_trampoline;
va_start(va, argc);
/* all arguments overflow into stack */
for (i = 0; i < argc; i++)
*sp++ = va_arg (va, libucontext_greg_t);
va_end(va);
/* link pointer */
*sp++ = (libucontext_greg_t) ucp->uc_link;
}
#ifdef EXPORT_UNPREFIXED
extern __typeof(libucontext_makecontext) makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
extern __typeof(libucontext_makecontext) __makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
#endif

View File

@ -1,31 +0,0 @@
/*
* 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.l 4(%sp), %a0 /* load ucontext_t pointer from stack */
move.l REG_OFFSET(REG_SP)(%a0), %sp /* load new stack pointer */
movem.l REG_OFFSET(REG_D2)(%a0), %d2-%d7 /* load $d2 through $d7 */
movem.l REG_OFFSET(REG_A2)(%a0), %a2-%a6 /* load $a2 through $a6 */
clr.l %d0 /* clear $d0 */
move.l REG_OFFSET(REG_PC)(%a0), %a1 /* load jump target */
jmp (%a1) /* jump to *$a1 */
END(libucontext_setcontext)

View File

@ -1,40 +0,0 @@
/*
* 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.l 4(%sp), %a0 /* load save ucontext_t pointer from stack */
movem.l %d2-%d7, REG_OFFSET(REG_D2)(%a0) /* preserve $d2 through $d7 */
movem.l %a2-%a6, REG_OFFSET(REG_A2)(%a0) /* preserve $a2 through $a6 */
lea 4(%sp), %a1 /* load stack pointer into $a1 */
move.l %a1, REG_OFFSET(REG_SP)(%a0) /* store $a1 in ucontext */
move.l (%sp), REG_OFFSET(REG_PC)(%a0) /* store return address in ucontext's PC register */
move.l 8(%sp), %a0 /* load new ucontext_t pointer from stack */
move.l REG_OFFSET(REG_SP)(%a0), %sp /* load new stack pointer */
movem.l REG_OFFSET(REG_D2)(%a0), %d2-%d7 /* load $d2 through $d7 */
movem.l REG_OFFSET(REG_A2)(%a0), %a2-%a6 /* load $a2 through $a6 */
clr.l %d0 /* clear $d0 */
move.l REG_OFFSET(REG_PC)(%a0), %a1 /* load jump target */
jmp (%a1) /* jump to *$a1 */
END(libucontext_swapcontext)

View File

@ -1,3 +0,0 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"

View File

@ -14,16 +14,15 @@ LOCALSZ = 1
#include "defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
ALIAS(getcontext, __getcontext)
FUNC(libucontext_getcontext)
FUNC(__getcontext)
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
move $a2, $gp
move $a3, $sp
move $a1, $fp
PUSH_FRAME(libucontext_getcontext)
PUSH_FRAME(__getcontext)
/* set registers */
sw $s0, REG_OFFSET(16)($a0)
@ -41,7 +40,7 @@ FUNC(libucontext_getcontext)
sw $ra, REG_OFFSET(31)($a0)
sw $ra, (MCONTEXT_PC)($a0)
POP_FRAME(libucontext_getcontext)
POP_FRAME(__getcontext)
jr $ra
END(libucontext_getcontext)
END(__getcontext)

View File

@ -1,27 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
typedef unsigned long long libucontext_greg_t, libucontext_gregset_t[32];
typedef struct {
unsigned regmask, status;
unsigned long long pc, gregs[32], fpregs[32];
unsigned ownedfp, fpc_csr, fpc_eir, used_math, dsp;
unsigned long long mdhi, mdlo;
unsigned long hi1, lo1, hi2, lo2, hi3, lo3;
} libucontext_mcontext_t;
typedef struct {
void *ss_sp;
size_t ss_size;
int ss_flags;
} 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

View File

@ -21,11 +21,10 @@ A3_OFF = FRAMESZ + (3 * REG_SZ)
* assembly rather than C. Annoying, that...
*/
ALIAS(makecontext, libucontext_makecontext)
ALIAS(__makecontext, libucontext_makecontext)
ALIAS(makecontext, __makecontext)
FUNC(libucontext_makecontext)
PUSH_FRAME(libucontext_makecontext)
FUNC(__makecontext)
PUSH_FRAME(__makecontext)
/* store $a3 through $a7 to the stack frame. */
sw $a3, A3_OFF($sp)
@ -77,7 +76,7 @@ no_more_arguments:
addiu $t0, -(4 * REG_SZ)
/* trampoline setup. */
la $t9, libucontext_trampoline
la $t9, __start_context
/* copy link pointer as $s0... */
lw $v1, UCONTEXT_UC_LINK($a0)
@ -95,7 +94,7 @@ no_more_arguments:
/* set our $pc */
sw $a1, MCONTEXT_PC($a0)
POP_FRAME(libucontext_makecontext)
POP_FRAME(__makecontext)
jr $ra
END(libucontext_makecontext)
END(__makecontext)

View File

@ -14,11 +14,10 @@ LOCALSZ = 1
#include "defs.h"
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext)
ALIAS(setcontext, __setcontext)
FUNC(libucontext_setcontext)
PUSH_FRAME(libucontext_setcontext)
FUNC(__setcontext)
PUSH_FRAME(__setcontext)
/* move the context to $v0 */
move $v0, $a0
@ -47,5 +46,5 @@ FUNC(libucontext_setcontext)
move $v0, $zero
jr $t9
POP_FRAME(libucontext_setcontext)
END(libucontext_setcontext)
POP_FRAME(__setcontext)
END(__setcontext)

View File

@ -14,8 +14,7 @@ LOCALSZ = 1
#include "defs.h"
.hidden libucontext_trampoline
FUNC(libucontext_trampoline)
FUNC(__start_context)
move $gp, $s1
/* we receive our initial ucontext in $s0, so if $s0 is nil, bail */
@ -23,7 +22,7 @@ FUNC(libucontext_trampoline)
/* call setcontext */
move $a0, $s0
la $t9, PROC_NAME(libucontext_setcontext)
la $t9, __setcontext
jr $t9
@ -32,4 +31,4 @@ no_linked_context:
la $t9, exit
jalr $t9
nop
END(libucontext_trampoline)
END(__start_context)

View File

@ -16,15 +16,14 @@ LOCALSZ = 2
A1_OFFSET = FRAMESZ - (1 * REG_SZ)
ALIAS(swapcontext, libucontext_swapcontext)
ALIAS(__swapcontext, libucontext_swapcontext)
ALIAS(swapcontext, __swapcontext)
FUNC(libucontext_swapcontext)
FUNC(__swapcontext)
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
move $a2, $gp
move $a3, $sp
PUSH_FRAME(libucontext_swapcontext)
PUSH_FRAME(__swapcontext)
/* set registers */
sd $s0, REG_OFFSET(16)($a0)
@ -75,8 +74,8 @@ FUNC(libucontext_swapcontext)
fail:
la $t9, exit
POP_FRAME(libucontext_swapcontext)
POP_FRAME(__swapcontext)
move $v0, $zero
jalr $t9
END(libucontext_swapcontext)
END(__swapcontext)

View File

@ -14,16 +14,15 @@ LOCALSZ = 1
#include "defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
ALIAS(getcontext, __getcontext)
FUNC(libucontext_getcontext)
FUNC(__getcontext)
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
move $a2, $gp
move $a3, $sp
move $a4, $fp
PUSH_FRAME(libucontext_getcontext)
PUSH_FRAME(__getcontext)
/* set registers */
sd $s0, REG_OFFSET(16)($a0)
@ -41,7 +40,7 @@ FUNC(libucontext_getcontext)
sd $ra, REG_OFFSET(31)($a0)
sd $ra, (MCONTEXT_PC)($a0)
POP_FRAME(libucontext_getcontext)
POP_FRAME(__getcontext)
jr $ra
END(libucontext_getcontext)
END(__getcontext)

View File

@ -1,47 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
typedef unsigned long long libucontext_greg_t, libucontext_gregset_t[32];
typedef struct {
union {
double fp_dregs[32];
struct {
float _fp_fregs;
unsigned _fp_pad;
} fp_fregs[32];
} fp_r;
} libucontext_fpregset_t;
typedef struct {
libucontext_gregset_t gregs;
libucontext_fpregset_t fpregs;
libucontext_greg_t mdhi;
libucontext_greg_t hi1;
libucontext_greg_t hi2;
libucontext_greg_t hi3;
libucontext_greg_t mdlo;
libucontext_greg_t lo1;
libucontext_greg_t lo2;
libucontext_greg_t lo3;
libucontext_greg_t pc;
unsigned int fpc_csr;
unsigned int used_math;
unsigned int dsp;
unsigned int reserved;
} libucontext_mcontext_t;
typedef struct {
void *ss_sp;
size_t ss_size;
int ss_flags;
} 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

View File

@ -26,11 +26,10 @@ A7_OFF = FRAMESZ - (1 * REG_SZ)
* assembly rather than C. Annoying, that...
*/
ALIAS(makecontext, libucontext_makecontext)
ALIAS(__makecontext, libucontext_makecontext)
ALIAS(makecontext, __makecontext)
FUNC(libucontext_makecontext)
PUSH_FRAME(libucontext_makecontext)
FUNC(__makecontext)
PUSH_FRAME(__makecontext)
/* store $a3 through $a7 to the stack frame. */
sd $a3, A3_OFF($sp)
@ -83,7 +82,7 @@ store_stack_arg:
no_more_arguments:
/* trampoline setup. */
dla $t9, libucontext_trampoline
dla $t9, __start_context
/* copy link pointer as $s0... */
ld $v1, UCONTEXT_UC_LINK($a0)
@ -101,7 +100,7 @@ no_more_arguments:
/* set our $pc */
sd $a1, MCONTEXT_PC($a0)
POP_FRAME(libucontext_makecontext)
POP_FRAME(__makecontext)
jr $ra
END(libucontext_makecontext)
END(__makecontext)

View File

@ -14,11 +14,10 @@ LOCALSZ = 1
#include "defs.h"
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext)
ALIAS(setcontext, __setcontext)
FUNC(libucontext_setcontext)
PUSH_FRAME(libucontext_setcontext)
FUNC(__setcontext)
PUSH_FRAME(__setcontext)
/* move the context to $v0 */
move $v0, $a0
@ -51,5 +50,5 @@ FUNC(libucontext_setcontext)
move $v0, $zero
jr $t9
POP_FRAME(libucontext_setcontext)
END(libucontext_setcontext)
POP_FRAME(__setcontext)
END(__setcontext)

View File

@ -14,8 +14,7 @@ LOCALSZ = 1
#include "defs.h"
.hidden libucontext_trampoline
FUNC(libucontext_trampoline)
FUNC(__start_context)
move $gp, $s1
/* we receive our initial ucontext in $s0, so if $s0 is nil, bail */
@ -23,7 +22,7 @@ FUNC(libucontext_trampoline)
/* call setcontext */
move $a0, $s0
dla $t9, PROC_NAME(libucontext_setcontext)
dla $t9, __setcontext
jr $t9
@ -32,4 +31,4 @@ no_linked_context:
dla $t9, exit
jalr $t9
nop
END(libucontext_trampoline)
END(__start_context)

View File

@ -16,16 +16,15 @@ LOCALSZ = 2
A1_OFFSET = FRAMESZ - (1 * REG_SZ)
ALIAS(swapcontext, libucontext_swapcontext)
ALIAS(__swapcontext, libucontext_swapcontext)
ALIAS(swapcontext, __swapcontext)
FUNC(libucontext_swapcontext)
FUNC(__swapcontext)
/* copy $gp, $sp, $fp to temporary registers so we don't clobber them */
move $a2, $gp
move $a3, $sp
move $a4, $fp
PUSH_FRAME(libucontext_swapcontext)
PUSH_FRAME(__swapcontext)
/* set registers */
sd $s0, REG_OFFSET(16)($a0)
@ -80,8 +79,8 @@ FUNC(libucontext_swapcontext)
fail:
dla $t9, exit
POP_FRAME(libucontext_swapcontext)
POP_FRAME(__swapcontext)
move $v0, $zero
jalr $t9
END(libucontext_swapcontext)
END(__swapcontext)

View File

@ -1,22 +0,0 @@
#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

View File

@ -1,39 +0,0 @@
/*
* 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)

View File

@ -1,28 +0,0 @@
#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

View File

@ -1,61 +0,0 @@
/*
* 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

View File

@ -1,48 +0,0 @@
/*
* 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)

View File

@ -1,68 +0,0 @@
/*
* 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)

View File

@ -1,3 +0,0 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"

View File

@ -59,6 +59,4 @@
/* lnk register is actually r32 */
#define REG_LNK REG_R36
#include "common-defs.h"
#endif

View File

@ -10,13 +10,11 @@
* from the use of this software.
*/
#include "common-defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
.hidden __libucontext_swapcontext
FUNC(libucontext_getcontext)
.global __getcontext
.hidden __swapcontext
__getcontext:
li 4, 0
b __libucontext_swapcontext@local
END(libucontext_getcontext)
b __swapcontext@local
.weak getcontext
getcontext = __getcontext

View File

@ -11,33 +11,34 @@
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stdarg.h>
#include <signal.h>
#include <stdint.h>
#include "defs.h"
#include <libucontext/libucontext.h>
extern void libucontext_trampoline(void);
extern void __start_context(void);
void
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(), int argc, ...)
__makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)
{
libucontext_greg_t *sp;
greg_t *sp;
va_list va;
int i;
unsigned int stack_args;
stack_args = argc > 8 ? argc - 8 : 0;
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp -= stack_args + 2;
sp = (libucontext_greg_t *) ((uintptr_t) sp & -16L);
sp = (greg_t *) ((uintptr_t) sp & -16L);
ucp->uc_mcontext.gregs[REG_NIP] = (uintptr_t) func;
ucp->uc_mcontext.gregs[REG_LNK] = (uintptr_t) &libucontext_trampoline;
ucp->uc_mcontext.gregs[REG_LNK] = (uintptr_t) &__start_context;
ucp->uc_mcontext.gregs[REG_R31] = (uintptr_t) ucp->uc_link;
ucp->uc_mcontext.gregs[REG_SP] = (uintptr_t) sp;
@ -47,15 +48,13 @@ libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(), int argc, .
for (i = 0; i < argc; i++) {
if (i < 8)
ucp->uc_mcontext.gregs[i + 3] = va_arg (va, libucontext_greg_t);
ucp->uc_mcontext.gregs[i + 3] = va_arg (va, greg_t);
else
sp[i-8 + 2] = va_arg (va, libucontext_greg_t);
sp[i-8 + 2] = va_arg (va, 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
extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext")));

View File

@ -10,14 +10,12 @@
* from the use of this software.
*/
#include "common-defs.h"
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext)
.hidden __libucontext_swapcontext
FUNC(libucontext_setcontext)
.global __setcontext
.hidden __swapcontext
__setcontext:
mr 4, 3
li 3, 0
b __libucontext_swapcontext@local
END(libucontext_setcontext)
b __swapcontext@local
.weak setcontext
setcontext = __setcontext

View File

@ -10,10 +10,8 @@
* from the use of this software.
*/
#include "common-defs.h"
.hidden libucontext_trampoline
FUNC(libucontext_trampoline)
.globl __start_context;
__start_context:
/* get the proper context into position and test for NULL */
mr. 3,31
@ -21,8 +19,7 @@ FUNC(libucontext_trampoline)
beq no_linked_context
/* jump to setcontext */
bl libucontext_setcontext@local
bl __setcontext@local
no_linked_context:
b exit@GOT
END(libucontext_trampoline)

View File

@ -10,20 +10,14 @@
* from the use of this software.
*/
#include "common-defs.h"
ALIAS(swapcontext, __libucontext_swapcontext)
ALIAS(__swapcontext, __libucontext_swapcontext)
/* make sure this is visible regardless of EXPORT_UNPREFIXED */
.weak libucontext_swapcontext
libucontext_swapcontext = __libucontext_swapcontext
FUNC(__libucontext_swapcontext)
.global __swapcontext
__swapcontext:
li 0, 249 # SYS_swapcontext
li 5, 1184 # sizeof(ucontext_t)
sc
.hidden __retfromsyscall
b __retfromsyscall@local
END(__libucontext_swapcontext)
.weak swapcontext
swapcontext = __swapcontext

View File

@ -62,6 +62,4 @@
/* lnk register is actually %r36 */
#define REG_LNK REG_R36
#include "common-defs.h"
#endif

View File

@ -10,18 +10,16 @@
* from the use of this software.
*/
#include "common-defs.h"
.global __getcontext
.hidden __swapcontext
__getcontext:
addis 2, 12, .TOC.-__getcontext@ha
addi 2, 12, .TOC.-__getcontext@l
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
.hidden __libucontext_swapcontext
FUNC(libucontext_getcontext)
addis 2, 12, .TOC.-libucontext_getcontext@ha
addi 2, 12, .TOC.-libucontext_getcontext@l
.localentry libucontext_getcontext,.-libucontext_getcontext
.localentry __getcontext,.-__getcontext
li 4, 0
b __libucontext_swapcontext
END(libucontext_getcontext)
b __swapcontext
.weak getcontext
getcontext = __getcontext

View File

@ -11,33 +11,34 @@
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stdarg.h>
#include <signal.h>
#include <stdint.h>
#include "defs.h"
#include <libucontext/libucontext.h>
extern void libucontext_trampoline(void);
extern void __start_context(void);
void
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(), int argc, ...)
__makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)
{
libucontext_greg_t *sp;
greg_t *sp;
va_list va;
int i;
unsigned int stack_args;
stack_args = argc > 8 ? argc : 0;
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp -= stack_args + 4;
sp = (libucontext_greg_t *) ((uintptr_t) sp & -16L);
sp = (greg_t *) ((uintptr_t) sp & -16L);
ucp->uc_mcontext.gp_regs[REG_NIP] = (uintptr_t) func;
ucp->uc_mcontext.gp_regs[REG_LNK] = (uintptr_t) &libucontext_trampoline;
ucp->uc_mcontext.gp_regs[REG_LNK] = (uintptr_t) &__start_context;
ucp->uc_mcontext.gp_regs[REG_SP] = (uintptr_t) sp;
ucp->uc_mcontext.gp_regs[REG_ENTRY] = (uintptr_t) func;
ucp->uc_mcontext.gp_regs[REG_R31] = (uintptr_t) ucp->uc_link;
@ -48,15 +49,13 @@ libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(), int argc, .
for (i = 0; i < argc; i++) {
if (i < 8)
ucp->uc_mcontext.gp_regs[i + 3] = va_arg (va, libucontext_greg_t);
ucp->uc_mcontext.gp_regs[i + 3] = va_arg (va, greg_t);
else
sp[i + 4] = va_arg (va, libucontext_greg_t);
sp[i + 4] = va_arg (va, 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
extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext")));

View File

@ -10,19 +10,17 @@
* from the use of this software.
*/
#include "common-defs.h"
.global __setcontext
.hidden __swapcontext
__setcontext:
addis 2, 12, .TOC.-__setcontext@ha
addi 2, 12, .TOC.-__setcontext@l
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext)
.hidden __libucontext_swapcontext
FUNC(libucontext_setcontext)
addis 2, 12, .TOC.-libucontext_setcontext@ha
addi 2, 12, .TOC.-libucontext_setcontext@l
.localentry libucontext_setcontext,.-libucontext_setcontext
.localentry __setcontext,.-__setcontext
mr 4, 3
li 3, 0
b __libucontext_swapcontext
END(libucontext_setcontext)
b __swapcontext
.weak setcontext
setcontext = __setcontext

View File

@ -10,10 +10,9 @@
* from the use of this software.
*/
#include "common-defs.h"
.hidden libucontext_trampoline
FUNC(libucontext_trampoline)
.globl __start_context;
.hidden __start_context;
__start_context:
cmpdi 31,0 /* test if ucontext link pointer is null */
beq no_linked_context /* if it is, exit */
@ -30,4 +29,3 @@ FUNC(libucontext_trampoline)
no_linked_context:
b exit@GOT
nop
END(libucontext_trampoline)

View File

@ -10,20 +10,12 @@
* from the use of this software.
*/
#include "common-defs.h"
.global __swapcontext
__swapcontext:
addis 2, 12, .TOC.-__swapcontext@ha
addi 2, 12, .TOC.-__swapcontext@l
ALIAS(swapcontext, __libucontext_swapcontext)
ALIAS(__swapcontext, __libucontext_swapcontext)
/* make sure this is visible regardless of EXPORT_UNPREFIXED */
.weak libucontext_swapcontext
libucontext_swapcontext = __libucontext_swapcontext
FUNC(__libucontext_swapcontext)
addis 2, 12, .TOC.-__libucontext_swapcontext@ha
addi 2, 12, .TOC.-__libucontext_swapcontext@l
.localentry __libucontext_swapcontext,.-__libucontext_swapcontext
.localentry __swapcontext,.-__swapcontext
li 0, 249 # SYS_swapcontext
li 5, 1696 # sizeof(ucontext_t)
@ -31,4 +23,6 @@ FUNC(__libucontext_swapcontext)
.hidden __retfromsyscall
b __retfromsyscall
END(__libucontext_swapcontext)
.weak swapcontext
swapcontext = __swapcontext

View File

@ -1,55 +0,0 @@
#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

View File

@ -1,45 +0,0 @@
/*
* 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)

View File

@ -1,48 +0,0 @@
#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

View File

@ -1,62 +0,0 @@
/*
* 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

View File

@ -1,56 +0,0 @@
/*
* 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)

View File

@ -1,81 +0,0 @@
/*
* 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)

View File

@ -1,3 +0,0 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"

View File

@ -1,55 +0,0 @@
#ifndef __ARCH_RISCV64_DEFS_H
#define __ARCH_RISCV64_DEFS_H
#define REG_SZ (8)
#define MCONTEXT_GREGS (176)
/* 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

View File

@ -1,45 +0,0 @@
/*
* 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)
sd ra, REG_OFFSET(REG_PC)(a0)
sd ra, REG_OFFSET(REG_RA)(a0)
sd sp, REG_OFFSET(REG_SP)(a0)
/* first saved register block */
sd s0, REG_OFFSET(REG_S0)(a0)
sd s1, REG_OFFSET(REG_S1)(a0)
/* return register block */
sd a0, REG_OFFSET(REG_A0)(a0)
sd a1, REG_OFFSET(REG_A1)(a0)
/* second saved register block */
sd s2, REG_OFFSET(REG_S2)(a0)
sd s3, REG_OFFSET(REG_S3)(a0)
sd s4, REG_OFFSET(REG_S4)(a0)
sd s5, REG_OFFSET(REG_S5)(a0)
sd s6, REG_OFFSET(REG_S6)(a0)
sd s7, REG_OFFSET(REG_S7)(a0)
sd s8, REG_OFFSET(REG_S8)(a0)
sd s9, REG_OFFSET(REG_S9)(a0)
sd s10, REG_OFFSET(REG_S10)(a0)
sd s11, REG_OFFSET(REG_S11)(a0)
/* done saving, return */
ret
END(libucontext_getcontext)

View File

@ -1,48 +0,0 @@
#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

View File

@ -1,62 +0,0 @@
/*
* 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

View File

@ -1,56 +0,0 @@
/*
* 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
ld t1, PC_OFFSET(t0)
ld ra, REG_OFFSET(REG_RA)(t0)
ld sp, REG_OFFSET(REG_SP)(t0)
/* first saved register block */
ld s0, REG_OFFSET(REG_S0)(t0)
ld s1, REG_OFFSET(REG_S1)(t0)
/* return register block */
ld a0, REG_OFFSET(REG_A0)(t0)
ld a1, REG_OFFSET(REG_A1)(t0)
/* argument register block */
ld a2, REG_OFFSET(REG_A2)(t0)
ld a3, REG_OFFSET(REG_A3)(t0)
ld a4, REG_OFFSET(REG_A4)(t0)
ld a5, REG_OFFSET(REG_A5)(t0)
ld a6, REG_OFFSET(REG_A6)(t0)
ld a7, REG_OFFSET(REG_A7)(t0)
/* second saved register block */
ld s2, REG_OFFSET(REG_S2)(t0)
ld s3, REG_OFFSET(REG_S3)(t0)
ld s4, REG_OFFSET(REG_S4)(t0)
ld s5, REG_OFFSET(REG_S5)(t0)
ld s6, REG_OFFSET(REG_S6)(t0)
ld s7, REG_OFFSET(REG_S7)(t0)
ld s8, REG_OFFSET(REG_S8)(t0)
ld s9, REG_OFFSET(REG_S9)(t0)
ld s10, REG_OFFSET(REG_S10)(t0)
ld s11, REG_OFFSET(REG_S11)(t0)
/* done restoring, jump to new pc in S1 */
jr t1
END(libucontext_setcontext)

View File

@ -1,81 +0,0 @@
/*
* 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
sd ra, REG_OFFSET(REG_PC)(a0)
sd ra, REG_OFFSET(REG_RA)(a0)
sd sp, REG_OFFSET(REG_SP)(a0)
/* first saved register block */
sd s0, REG_OFFSET(REG_S0)(a0)
sd s1, REG_OFFSET(REG_S1)(a0)
/* return register block */
sd a0, REG_OFFSET(REG_A0)(a0)
sd a1, REG_OFFSET(REG_A1)(a0)
/* second saved register block */
sd s2, REG_OFFSET(REG_S2)(a0)
sd s3, REG_OFFSET(REG_S3)(a0)
sd s4, REG_OFFSET(REG_S4)(a0)
sd s5, REG_OFFSET(REG_S5)(a0)
sd s6, REG_OFFSET(REG_S6)(a0)
sd s7, REG_OFFSET(REG_S7)(a0)
sd s8, REG_OFFSET(REG_S8)(a0)
sd s9, REG_OFFSET(REG_S9)(a0)
sd s10, REG_OFFSET(REG_S10)(a0)
sd s11, REG_OFFSET(REG_S11)(a0)
/* restore the other context from $t0. */
ld t1, REG_OFFSET(REG_PC)(t0)
ld ra, REG_OFFSET(REG_RA)(t0)
ld sp, REG_OFFSET(REG_SP)(t0)
/* first saved register block */
ld s0, REG_OFFSET(REG_S0)(t0)
ld s1, REG_OFFSET(REG_S1)(t0)
/* return register block */
ld a0, REG_OFFSET(REG_A0)(t0)
ld a1, REG_OFFSET(REG_A1)(t0)
/* argument register block */
ld a2, REG_OFFSET(REG_A2)(t0)
ld a3, REG_OFFSET(REG_A3)(t0)
ld a4, REG_OFFSET(REG_A4)(t0)
ld a5, REG_OFFSET(REG_A5)(t0)
ld a6, REG_OFFSET(REG_A6)(t0)
ld a7, REG_OFFSET(REG_A7)(t0)
/* second saved register block */
ld s2, REG_OFFSET(REG_S2)(t0)
ld s3, REG_OFFSET(REG_S3)(t0)
ld s4, REG_OFFSET(REG_S4)(t0)
ld s5, REG_OFFSET(REG_S5)(t0)
ld s6, REG_OFFSET(REG_S6)(t0)
ld s7, REG_OFFSET(REG_S7)(t0)
ld s8, REG_OFFSET(REG_S8)(t0)
ld s9, REG_OFFSET(REG_S9)(t0)
ld s10, REG_OFFSET(REG_S10)(t0)
ld s11, REG_OFFSET(REG_S11)(t0)
/* done swapping, jump to new PC in S1 */
jr t1
END(libucontext_swapcontext)

View File

@ -1,3 +0,0 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"

View File

@ -12,10 +12,9 @@
#include "defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
ALIAS(getcontext, __getcontext)
FUNC(libucontext_getcontext)
FUNC(__getcontext)
lgr %r1, %r2 /* use %r1 as our working register */
la %r2, 0 /* we will return 0 */
@ -23,4 +22,4 @@ FUNC(libucontext_getcontext)
stmg %r0, %r15, REG_OFFSET(0)(%r1) /* store general-purpose registers */
br %r14 /* return to where we came from */
END(libucontext_getcontext)
END(__getcontext)

View File

@ -1,41 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
typedef unsigned long libucontext_greg_t, libucontext_gregset_t[27];
typedef struct {
unsigned long mask;
unsigned long addr;
} libucontext_psw_t;
typedef union {
double d;
float f;
} libucontext_fpreg_t;
typedef struct {
unsigned fpc;
libucontext_fpreg_t fprs[16];
} libucontext_fpregset_t;
typedef struct {
libucontext_psw_t psw;
unsigned long gregs[16];
unsigned aregs[16];
libucontext_fpregset_t 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;
libucontext_mcontext_t uc_mcontext;
} libucontext_ucontext_t;
#endif

View File

@ -10,46 +10,47 @@
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include "defs.h"
#include <libucontext/libucontext.h>
extern void libucontext_trampoline(void);
extern int libucontext_setcontext(const libucontext_ucontext_t *ucp);
extern void __start_context(void);
extern int __setcontext(const ucontext_t *ucp);
void
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
libucontext_greg_t *sp;
greg_t *sp;
va_list va;
int i;
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp = (libucontext_greg_t *) (((uintptr_t) sp & -8L));
sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp = (greg_t *) (((uintptr_t) sp & -8L));
ucp->uc_mcontext.gregs[7] = (uintptr_t) func;
ucp->uc_mcontext.gregs[8] = (uintptr_t) ucp->uc_link;
ucp->uc_mcontext.gregs[9] = (uintptr_t) &libucontext_setcontext;
ucp->uc_mcontext.gregs[14] = (uintptr_t) &libucontext_trampoline;
ucp->uc_mcontext.gregs[9] = (uintptr_t) &__setcontext;
ucp->uc_mcontext.gregs[14] = (uintptr_t) &__start_context;
va_start(va, argc);
for (i = 0; i < argc && i < 5; i++)
ucp->uc_mcontext.gregs[i + 2] = va_arg (va, libucontext_greg_t);
ucp->uc_mcontext.gregs[i + 2] = va_arg (va, greg_t);
if (argc > 5)
{
sp -= argc - 5;
for (i = 5; i < argc; i++)
sp[i - 5] = va_arg (va, libucontext_greg_t);
sp[i - 5] = va_arg (va, greg_t);
}
va_end(va);
@ -62,7 +63,5 @@ libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int arg
ucp->uc_mcontext.gregs[15] = (uintptr_t) sp;
}
#ifdef EXPORT_UNPREFIXED
extern __typeof(libucontext_makecontext) makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
extern __typeof(libucontext_makecontext) __makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
#endif
extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext")));

View File

@ -12,14 +12,13 @@
#include "defs.h"
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext)
ALIAS(setcontext, __setcontext)
FUNC(libucontext_setcontext)
FUNC(__setcontext)
lgr %r1, %r2 /* use %r1 as our working register */
lam %a2, %a15, AREG_OFFSET(2)(%r1) /* load access registers, but skip %a0 and %a1 which are for TLS */
lmg %r0, %r15, REG_OFFSET(0)(%r1) /* store general-purpose registers */
br %r14 /* return to new link register address */
END(libucontext_setcontext)
END(__setcontext)

View File

@ -12,8 +12,7 @@
#include "defs.h"
.hidden libucontext_trampoline
FUNC(libucontext_trampoline)
FUNC(__start_context)
basr %r14, %r7 /* run function pointer (%r7) and return here */
ltgr %r8, %r8 /* check to see if uc_link (%r8) is null */
@ -27,4 +26,4 @@ no_linked_context:
brasl %r14, exit@plt /* call exit */
j .+2 /* crash if exit returns */
END(libucontext_trampoline)
END(__start_context)

View File

@ -12,10 +12,9 @@
#include "defs.h"
ALIAS(swapcontext, libucontext_swapcontext)
ALIAS(__swapcontext, libucontext_swapcontext)
ALIAS(swapcontext, __swapcontext)
FUNC(libucontext_swapcontext)
FUNC(__swapcontext)
lgr %r1, %r2 /* use %r1 to save current context to */
lgr %r0, %r3 /* use %r0 for source context */
@ -27,4 +26,4 @@ FUNC(libucontext_swapcontext)
lmg %r0, %r15, REG_OFFSET(0)(%r2) /* load general-purpose registers */
br %r14 /* return to new link register address */
END(libucontext_swapcontext)
END(__swapcontext)

View File

@ -1,20 +0,0 @@
#ifndef __ARCH_SH4_DEFS_H
#define __ARCH_SH4_DEFS_H
#define REG_SZ (4)
#define MCONTEXT_GREGS (24)
#define REG_SP (15)
#define REG_PC (16)
#define REG_PR (17)
#define REG_SR (18)
#define REG_GBR (19)
#define REG_MACH (20)
#define REG_MACL (21)
#define FETCH_LINKPTR(dest) \
asm("mov r8, %0" : "=r" (dest));
#include "common-defs.h"
#endif

View File

@ -1,56 +0,0 @@
/*
* 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)
mov r4, r0 /* move r4 to r0, and increment by REG_OFFSET(REG_MACL) + REG_SZ. */
add #(REG_OFFSET(REG_MACL + 1)), r0
sts.l macl, @-r0 /* save macl/mach registers */
sts.l mach, @-r0
stc.l gbr, @-r0 /* save gbr register */
movt r1 /* load T-flag into r1 */
mov.l r1, @-r0 /* save T-flag as SR register */
sts.l pr, @-r0 /* save current PR */
sts.l pr, @-r0 /* save current PR as PC as well */
mov.l r15, @-r0 /* preserve registers backwards, from r15 to r1 */
mov.l r14, @-r0
mov.l r13, @-r0
mov.l r12, @-r0
mov.l r11, @-r0
mov.l r10, @-r0
mov.l r9, @-r0
mov.l r8, @-r0
mov.l r7, @-r0
mov.l r6, @-r0
mov.l r5, @-r0
mov.l r4, @-r0
mov.l r3, @-r0
mov.l r2, @-r0
mov.l r1, @-r0
mov r0, r1
mov #0, r0
mov.l r0, @-r1 /* preserve r0 as explicit zero */
mov #0, r0 /* set return value as zero */
rts
END(libucontext_getcontext)

View File

@ -1,29 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
typedef unsigned long libucontext_greg_t, libucontext_gregset_t[16];
typedef unsigned long libucontext_freg_t, libucontext_fpregset_t[16];
typedef struct sigcontext {
unsigned long oldmask;
unsigned long gregs[16];
unsigned long pc, pr, sr;
unsigned long gbr, mach, macl;
unsigned long fpregs[16];
unsigned long xfpregs[16];
unsigned int fpscr, fpul, ownedfp;
} 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;
libucontext_mcontext_t uc_mcontext;
} libucontext_ucontext_t;
#endif

View File

@ -1,59 +0,0 @@
/*
* 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 <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) & -4L);
sp -= argc > 4 ? argc - 4 : 0;
/* set up the context */
ucp->uc_mcontext.gregs[REG_SP] = (libucontext_greg_t) sp;
ucp->uc_mcontext.pr = (libucontext_greg_t) libucontext_trampoline;
ucp->uc_mcontext.pc = (libucontext_greg_t) func;
ucp->uc_mcontext.gregs[8] = (libucontext_greg_t) ucp->uc_link;
/* pass up to four args in r4-r7, rest on stack */
va_start(va, argc);
regp = &ucp->uc_mcontext.gregs[4];
for (i = 0; i < argc && i < 4; i++)
*regp++ = va_arg(va, libucontext_greg_t);
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

View File

@ -1,60 +0,0 @@
/*
* 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)
mov r4, r0
add #(REG_OFFSET(5)), r0 /* restore GPRs r5-15 */
mov.l @r0+, r5
mov.l @r0+, r6
mov.l @r0+, r7
mov.l @r0+, r8
mov.l @r0+, r9
mov.l @r0+, r10
mov.l @r0+, r11
mov.l @r0+, r12
mov.l @r0+, r13
mov.l @r0+, r14
mov.l @r0+, r15
mov.l @r0+, r2 /* restore PR */
lds.l @r0+, pr
mov.l @r0+, r1 /* restore T-flag */
shlr r1
add #REG_SZ, r0 /* skip GBR (used for TLS) */
lds.l @r0+, mach /* load mach/macl registers */
lds.l @r0+, macl
mov r4, r0 /* bring r0 back to the top of the context */
add #(REG_OFFSET(0)), r1 /* restore r0 into r1 (temporarily) */
mov.l r1, @-r15 /* push to stack from r1 */
mov.l r2, @-r15 /* push PC to stack */
mov.l @(REG_OFFSET(1), r0), r1 /* restore real r1 */
mov.l @(REG_OFFSET(2), r0), r2 /* restore real r2 */
mov.l @(REG_OFFSET(3), r0), r3 /* restore real r2 */
mov.l @(REG_OFFSET(4), r0), r4 /* restore real r2 */
mov.l @r15+, r0 /* pop PC from stack */
jmp @r0 /* jump to new PC */
mov.l @r15+, r0 /* pop original r0 from stack */
END(libucontext_setcontext)

View File

@ -1,95 +0,0 @@
/*
* 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)
mov r4, r0 /* move r4 to r0, and increment by REG_OFFSET(REG_MACL) + REG_SZ. */
add #(REG_OFFSET(REG_MACL + 1)), r0
sts.l macl, @-r0 /* save macl/mach registers */
sts.l mach, @-r0
stc.l gbr, @-r0 /* save gbr register */
movt r1 /* load T-flag into r1 */
mov.l r1, @-r0 /* save T-flag as SR register */
sts.l pr, @-r0 /* save current PR */
sts.l pr, @-r0 /* save current PR as PC as well */
mov.l r15, @-r0 /* preserve registers backwards, from r15 to r1 */
mov.l r14, @-r0
mov.l r13, @-r0
mov.l r12, @-r0
mov.l r11, @-r0
mov.l r10, @-r0
mov.l r9, @-r0
mov.l r8, @-r0
mov.l r7, @-r0
mov.l r6, @-r0
mov.l r5, @-r0
mov.l r4, @-r0
mov.l r3, @-r0
mov.l r2, @-r0
mov.l r1, @-r0
mov r0, r1
mov #0, r0
mov.l r0, @-r1 /* preserve r0 as explicit zero */
mov r5, r0 /* now restore the new context */
add #(REG_OFFSET(6)), r0 /* restore GPRs r6-15 */
mov.l @r0+, r6
mov.l @r0+, r7
mov.l @r0+, r8
mov.l @r0+, r9
mov.l @r0+, r10
mov.l @r0+, r11
mov.l @r0+, r12
mov.l @r0+, r13
mov.l @r0+, r14
mov.l @r0+, r15
mov.l @r0+, r2 /* restore PR */
lds.l @r0+, pr
mov.l @r0+, r1 /* restore T-flag */
shlr r1
add #REG_SZ, r0 /* skip GBR (used for TLS) */
lds.l @r0+, mach /* load mach/macl registers */
lds.l @r0+, macl
mov r5, r0 /* bring r0 back to the top of the context */
add #(REG_OFFSET(0)), r1 /* restore r0 into r1 (temporarily) */
mov.l r1, @-r15 /* push to stack from r1 */
mov.l r2, @-r15 /* push PC to stack */
mov.l @(REG_OFFSET(1), r0), r1 /* restore real r1 */
mov.l @(REG_OFFSET(2), r0), r2 /* restore real r2 */
mov.l @(REG_OFFSET(3), r0), r3 /* restore real r3 */
mov.l @(REG_OFFSET(4), r0), r4 /* restore real r4 */
mov.l @(REG_OFFSET(5), r0), r5 /* restore real r5 */
mov.l @r15+, r0 /* pop PC from stack */
jmp @r0 /* jump to new PC */
mov.l @r15+, r0 /* pop original r0 from stack */
END(libucontext_swapcontext)

View File

@ -1,3 +0,0 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"

View File

@ -3,53 +3,17 @@
#ifndef REG_GS
# define REG_GS (0)
#endif
#ifndef REG_FS
# define REG_FS (1)
#endif
#ifndef REG_ES
# define REG_ES (2)
#endif
#ifndef REG_DS
# define REG_DS (3)
#endif
#ifndef REG_EDI
# define REG_EDI (4)
#endif
#ifndef REG_ESI
# define REG_ESI (5)
#endif
#ifndef REG_EBP
# define REG_EBP (6)
#endif
#ifndef REG_ESP
# define REG_ESP (7)
#endif
#ifndef REG_EBX
# define REG_EBX (8)
#endif
#ifndef REG_EDX
# define REG_EDX (9)
#endif
#ifndef REG_ECX
# define REG_ECX (10)
#endif
#ifndef REG_EAX
# define REG_EAX (11)
#endif
#ifndef REG_EIP
# define REG_EIP (14)
#endif
@ -57,9 +21,6 @@
#define MCONTEXT_GREGS (20)
#define FETCH_LINKPTR(dest) \
asm("movl (%%esp, %%ebx, 4), %0" : "=r" ((dest)));
#include "common-defs.h"
#endif

View File

@ -12,10 +12,9 @@
#include "defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
ALIAS(getcontext, __getcontext)
FUNC(libucontext_getcontext)
FUNC(__getcontext)
/* load address of the ucontext structure */
movl 4(%esp), %eax
@ -47,4 +46,4 @@ FUNC(libucontext_getcontext)
/* we're all done here, return 0 */
xorl %eax, %eax
ret
END(libucontext_getcontext)
END(__getcontext)

View File

@ -1,48 +0,0 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
#define REG_GS (0)
#define REG_FS (1)
#define REG_ES (2)
#define REG_DS (3)
#define REG_EDI (4)
#define REG_ESI (5)
#define REG_EBP (6)
#define REG_ESP (7)
#define REG_EBX (8)
#define REG_EDX (9)
#define REG_ECX (10)
#define REG_EAX (11)
#define REG_EIP (14)
typedef int libucontext_greg_t, libucontext_gregset_t[19];
typedef struct libucontext_fpstate {
unsigned long cw, sw, tag, ipoff, cssel, dataoff, datasel;
struct {
unsigned short significand[4], exponent;
} _st[8];
unsigned long status;
} *libucontext_fpregset_t;
typedef struct {
libucontext_gregset_t gregs;
libucontext_fpregset_t fpregs;
unsigned long oldmask, cr2;
} 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;
libucontext_mcontext_t uc_mcontext;
} libucontext_ucontext_t;
#endif

View File

@ -1,6 +1,5 @@
/*
* Copyright (c) 2018 Ariadne Conill <ariadne@dereferenced.org>
* Copyright (c) 2019 A. Wilcox <awilfox@adelielinux.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
@ -11,49 +10,47 @@
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include "defs.h"
#include <libucontext/libucontext.h>
extern void libucontext_trampoline(void);
extern void __start_context(void);
void
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
libucontext_greg_t *sp, *argp;
greg_t *sp, *argp;
va_list va;
int i;
unsigned int uc_link;
uc_link = (argc > 6 ? argc - 6 : 0) + 1;
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp -= uc_link;
sp = (libucontext_greg_t *) (((uintptr_t) sp & -16L) - 8);
sp = (greg_t *) (((uintptr_t) sp & -16L) - 8);
ucp->uc_mcontext.gregs[REG_EIP] = (uintptr_t) func;
ucp->uc_mcontext.gregs[REG_EBX] = (uintptr_t) argc;
ucp->uc_mcontext.gregs[REG_ESP] = (uintptr_t) sp;
argp = sp;
*argp++ = (uintptr_t) &libucontext_trampoline;
*argp++ = (uintptr_t) &__start_context;
va_start(va, argc);
for (i = 0; i < argc; i++)
*argp++ = va_arg (va, libucontext_greg_t);
*argp++ = va_arg (va, greg_t);
va_end(va);
*argp++ = (uintptr_t) ucp->uc_link;
}
#ifdef EXPORT_UNPREFIXED
extern __typeof(libucontext_makecontext) makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
extern __typeof(libucontext_makecontext) __makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
#endif
extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext")));

Some files were not shown because too many files have changed in this diff Show More