libucontext: Add package

Description (from libucontext github page):
libucontext (https://https://github.com/kaniini/libucontext) is a
library which provides the ucontext.h C API. Unlike other
implementations, it faithfully follows the kernel process ABI when
doing context swaps. libucontext is used on almost all musl
distributions to provide the legacy ucontext.h API.

This package is meant as a development package. There is no need
to install a package on the router if an application or library
is linked against the static libraries. Though, shared libraries
are provided also.

It is used to link libraries/applications against it which need the
system calls

* makecontext
* swapcontext
* getcontext
* setcontext

E.g. the asynchronous API of libmariadb (c-connector) uses this
system calls. Because libmusl didn't provide that system calls this
synchronous API is currently (without libucontexe) not working - it
segfaults.

Co-developed-by: Tianling Shen <cnsztl@immortalwrt.org>
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
Signed-off-by: Volker Christian <me@vchrist.at>
This commit is contained in:
Volker Christian 2023-09-01 16:53:28 +02:00 committed by Tianling Shen
parent a531468114
commit 635a702255
3 changed files with 201 additions and 0 deletions

62
libs/libucontext/Makefile Normal file
View File

@ -0,0 +1,62 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libucontext
PKG_VERSION:=1.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/kaniini/libucontext/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=2657e087c493263e7bbbde152a5bc08ce22dc5a7970887ac4fd251b90b58401f
PKG_MAINTAINER:=Volker Christian <me@vchrist.at>
PKG_LICENSE:=ISC
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_FLAGS:=no-mips16
PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/meson.mk
define Package/libucontext
SECTION:=libs
CATEGORY:=Libraries
TITLE:=libucontext is a library which provides the ucontext.h C API
URL:=https://github.com/kaniini/libucontext
DEPENDS:=@USE_MUSL
endef
define Package/libucontext-tests
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Test applications for libucontext
URL:=https://github.com/kaniini/libucontext
DEPENDS:=libucontext
endef
define Package/libucontext/description
Thie package is a development package aimed to be linked to
libraries/applications which need the SYS-V ucontext API.
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig
$(CP) $(PKG_INSTALL_DIR)/usr/include/libucontext $(1)/usr/include/
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libucontext* $(1)/usr/lib/
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libucontext.pc $(1)/usr/lib/pkgconfig/
endef
define Package/libucontext/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libucontext*.so.* $(1)/usr/lib/
endef
define Package/libucontext-tests/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(MESON_BUILD_DIR)/test_libucontext_posix $(1)/usr/bin/
$(INSTALL_BIN) $(MESON_BUILD_DIR)/test_libucontext $(1)/usr/bin/
endef
$(eval $(call BuildPackage,libucontext))
$(eval $(call BuildPackage,libucontext-tests))

View File

@ -0,0 +1,17 @@
--- a/arch/arm/swapcontext.S
+++ b/arch/arm/swapcontext.S
@@ -17,10 +17,12 @@ ALIAS(__swapcontext, libucontext_swapcon
FUNC(libucontext_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)]
+ add r2, r0, #REG_OFFSET(0)
+ /* copy r0 with value 0 to indicate success (return value 0) */
+ mov r0, #0
+ stmia r2, {r0-r12}
/* load new registers from the second ucontext structure */
add r14, r1, #REG_OFFSET(0)

View File

@ -0,0 +1,122 @@
--- a/test_libucontext.c
+++ b/test_libucontext.c
@@ -9,6 +9,9 @@
#include <string.h>
#include <libucontext/libucontext.h>
+#define handle_error(msg) \
+ do { perror(msg); exit(EXIT_FAILURE); } while (0)
+
static libucontext_ucontext_t ctx[3];
@@ -36,7 +39,8 @@ static void f1 (int a, int b, int c, int
printf("looks like all arguments are passed correctly\n");
printf("swap back to f2\n");
- libucontext_swapcontext(&ctx[1], &ctx[2]);
+ if (libucontext_swapcontext(&ctx[1], &ctx[2]) != 0)
+ handle_error("libucontext_swapcontext");
printf("finish f1\n");
}
@@ -44,7 +48,8 @@ static void f1 (int a, int b, int c, int
static void f2 (void) {
printf("start f2\n");
printf("swap to f1\n");
- libucontext_swapcontext(&ctx[2], &ctx[1]);
+ if (libucontext_swapcontext(&ctx[2], &ctx[1]) != 0)
+ handle_error("libucontext_swapcontext");
printf("finish f2, should swap to f1\n");
}
@@ -63,7 +68,8 @@ int main (int argc, const char *argv[])
printf("setting up context 1\n");
- libucontext_getcontext(&ctx[1]);
+ if (libucontext_getcontext(&ctx[1]) != 0)
+ handle_error("libucontext_getcontext");
ctx[1].uc_stack.ss_sp = st1;
ctx[1].uc_stack.ss_size = sizeof st1;
ctx[1].uc_link = &ctx[0];
@@ -83,16 +89,20 @@ int main (int argc, const char *argv[])
printf("doing initial swapcontext\n");
- libucontext_swapcontext(&ctx[0], &ctx[2]);
+ if (libucontext_swapcontext(&ctx[0], &ctx[2]) != 0)
+ handle_error("libucontext_swapcontext");
printf("returned from initial swapcontext\n");
/* test ability to use getcontext/setcontext without makecontext */
- libucontext_getcontext(&ctx[1]);
+ if (libucontext_getcontext(&ctx[1]) != 0)
+ handle_error("libucontext_getcontext");
printf("done = %d\n", done);
- if (done++ == 0) libucontext_setcontext(&ctx[1]);
+ if (done++ == 0)
+ if (libucontext_setcontext(&ctx[1]) != 0)
+ handle_error("libucontext_setcontext");
if (done != 2) {
fprintf(stderr, "wrong value for done. got %d, expected 2\n", done);
abort();
--- a/test_libucontext_posix.c
+++ b/test_libucontext_posix.c
@@ -9,6 +9,9 @@
#include <string.h>
#include <ucontext.h>
+#define handle_error(msg) \
+ do { perror(msg); exit(EXIT_FAILURE); } while (0)
+
static ucontext_t ctx[3];
@@ -36,7 +39,8 @@ static void f1 (int a, int b, int c, int
printf("looks like all arguments are passed correctly\n");
printf("swap back to f2\n");
- swapcontext(&ctx[1], &ctx[2]);
+ if (swapcontext(&ctx[1], &ctx[2]) != 0)
+ handle_error("swapcontext");
printf("finish f1\n");
}
@@ -44,7 +48,8 @@ static void f1 (int a, int b, int c, int
static void f2 (void) {
printf("start f2\n");
printf("swap to f1\n");
- swapcontext(&ctx[2], &ctx[1]);
+ if (swapcontext(&ctx[2], &ctx[1]) != 0)
+ handle_error("swapcontext");
printf("finish f2, should swap to f1\n");
}
@@ -83,16 +88,19 @@ int main (int argc, const char *argv[])
printf("doing initial swapcontext\n");
- swapcontext(&ctx[0], &ctx[2]);
-
+ if (swapcontext(&ctx[0], &ctx[2]) != 0)
+ handle_error("swapcontext");
printf("returned from initial swapcontext\n");
/* test ability to use getcontext/setcontext without makecontext */
- getcontext(&ctx[1]);
+ if (getcontext(&ctx[1]) != 0)
+ handle_error("getcontext");
printf("done = %d\n", done);
- if (done++ == 0) setcontext(&ctx[1]);
+ if (done++ == 0)
+ if (setcontext(&ctx[1]) != 0)
+ handle_error("setcontext");
if (done != 2) {
fprintf(stderr, "wrong value for done. got %d, expected 2\n", done);
abort();