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:
parent
a531468114
commit
635a702255
3 changed files with 201 additions and 0 deletions
62
libs/libucontext/Makefile
Normal file
62
libs/libucontext/Makefile
Normal 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))
|
17
libs/libucontext/patches/010-return_values_fix.patch
Normal file
17
libs/libucontext/patches/010-return_values_fix.patch
Normal 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)
|
122
libs/libucontext/patches/020-honor_return_values_fix.patch
Normal file
122
libs/libucontext/patches/020-honor_return_values_fix.patch
Normal 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();
|
Loading…
Reference in a new issue