[PATCH] RFC: user context control for TI C6X
Timon ter Braak
timonterbraak at gmail.com
Thu Feb 14 09:52:51 UTC 2013
I am attempting to support the Go language on the TI C6X. Therefore,
support is required for user context control.
I implemented those (see patch below), and it works for small test
programs. However, that does not mean that it is entirely correct.
I have some points that are not entirely clear to me:
* the registers (A0-A15,B0-B16) are saved and restored. I probably could
leave out some of them?
* mcontext_t specifies a 'PC' register, but its offset is too large to
use it conveniently, so it is saved elsewhere (in ucontext_regspace). Is
that a problem?
* register B16 seems to hold the program counter, but that is fairly
undocumented.
* C6000 EABI specifies 10 registers to hold function arguments, but
Linux assumes (and exposes) only 6 of them. The implementation below
also only uses 6 registers for this. Am I getting into trouble when
makecontext targets a function with more than 6 arguments?
* I use the callee-preserved register A14 to hold the pointer to the
next context (uc_link). Any issues here?
Until I run into trouble, I use this implementation myself, but I hope
it might end up being supported by uClibc.c
--- a/include/ucontext.h 2011-04-27 17:44:16.000000000 +0200
+++ b/include/ucontext.h 2013-02-13 17:27:51.694339000 +0100
@@ -16,6 +16,8 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+/* System V ABI compliant user-level context switching support. */
+
#ifndef _UCONTEXT_H
#define _UCONTEXT_H 1
@@ -24,9 +26,28 @@
/* Get machine dependent definition of data structures. */
#include <sys/ucontext.h>
-/* The System V ABI user-level context switching support functions
- * are marked obsolescent by SuSv3, and are not implemented by
- * uClibc. This header is therefore empty. */
+__BEGIN_DECLS
+
+/* Get user context and store it in variable pointed to by UCP. */
+extern int getcontext (ucontext_t *__ucp) __THROW;
+
+/* Set user context from information of variable pointed to by UCP. */
+extern int setcontext (__const ucontext_t *__ucp) __THROW;
+
+/* Save current context in context variable pointed to by OUCP and set
+ context from variable pointed to by UCP. */
+extern int swapcontext (ucontext_t *__restrict __oucp,
+ __const ucontext_t *__restrict __ucp) __THROW;
+
+/* Manipulate user context UCP to continue with calling functions FUNC
+ and the ARGC-1 parameters following ARGC when the context is used
+ the next time in `setcontext' or `swapcontext'.
+
+ We cannot say anything about the parameters FUNC takes; `void'
+ is as good as any other choice. */
+extern void makecontext (ucontext_t *__ucp, void (*__func) (),
+ int __argc, ...) __THROW;
+__END_DECLS
#endif /* ucontext.h */
--- a/libc/sysdeps/linux/c6x/getcontext.S 1970-01-01
01:00:00.000000000 +0100
+++ b/libc/sysdeps/linux/c6x/getcontext.S 2013-02-13
17:28:11.970339000 +0100
@@ -0,0 +1,93 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ucontext_i.h>
+
+/* int getcontext (ucontext_t *ucp) */
+
+.global __getcontext
+.type __getcontext,%function
+.align 2
+__getcontext:
+ STW .D1T1 A0,*+A4(MCONTEXT_C6X_A0)
+ STW .D1T1 A1,*+A4(MCONTEXT_C6X_A1)
+ STW .D1T1 A2,*+A4(MCONTEXT_C6X_A2)
+ STW .D1T1 A3,*+A4(MCONTEXT_C6X_A3)
+ STW .D1T1 A4,*+A4(MCONTEXT_C6X_A4)
+ STW .D1T1 A5,*+A4(MCONTEXT_C6X_A5)
+ STW .D1T1 A6,*+A4(MCONTEXT_C6X_A6)
+ STW .D1T1 A7,*+A4(MCONTEXT_C6X_A7)
+ STW .D1T1 A8,*+A4(MCONTEXT_C6X_A8)
+ STW .D1T1 A9,*+A4(MCONTEXT_C6X_A9)
+
+ STW .D1T2 B0,*+A4(MCONTEXT_C6X_B0)
+ STW .D1T2 B1,*+A4(MCONTEXT_C6X_B1)
+ STW .D1T2 B2,*+A4(MCONTEXT_C6X_B2)
+ STW .D1T2 B3,*+A4(MCONTEXT_C6X_B3)
+ STW .D1T2 B4,*+A4(MCONTEXT_C6X_B4)
+ STW .D1T2 B5,*+A4(MCONTEXT_C6X_B5)
+ STW .D1T2 B6,*+A4(MCONTEXT_C6X_B6)
+ STW .D1T2 B7,*+A4(MCONTEXT_C6X_B7)
+ STW .D1T2 B8,*+A4(MCONTEXT_C6X_B8)
+ STW .D1T2 B9,*+A4(MCONTEXT_C6X_B9)
+
+ MV .D2X A4,B6
+|| MV .S1 A4,A6
+
+ ADDK .S1 UCONTEXT_REGSPACE,A6
+|| ADDK .S2 UCONTEXT_REGSPACE,B6
+
+ STW .D1T1 A10,*+A6(0)
+|| STW .D2T2 B10,*+B6(4)
+ STW .D1T1 A11,*+A6(8)
+|| STW .D2T2 B11,*+B6(12)
+ STW .D1T1 A12,*+A6(16)
+|| STW .D2T2 B12,*+B6(20)
+ STW .D1T1 A13,*+A6(24)
+|| STW .D2T2 B13,*+B6(28)
+ STW .D1T1 A14,*+A6(32)
+|| STW .D2T2 B14,*+B6(36)
+ STW .D1T1 A15,*+A6(40)
+|| STW .D2T2 B15,*+B6(44)
+ STW .D1T1 A16,*+A6(48)
+|| STW .D2T2 B16,*+B6(52)
+
+ ; Save ucontext_t* across the next call
+ MV .D1 A4,A8
+|| MVK .S1 UCONTEXT_SIGMASK,A6 ; uc_sigmask address
+
+ ; int sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask))
+ ; A4: SIG_BLOCK
+ ; B4: 0
+ ; A6: uc_sigmask
+ MVK .D1 SIG_BLOCK,A4
+|| ZERO .S2 B4
+|| ADD .S1 A8,A6,A6
+
+ B .S2 sigprocmask
+ mvkl .S2 1f, B3
+ mvkh .S2 1f, B3
+ nop 3
+1:
+ ; Restore clobbered link register
+ LDW .D1T2 *+A8(MCONTEXT_C6X_B3),B3
+
+ ; Return with value 0
+ ZERO .L1 A4
+|| RET .S2 B3
+
+ NOP 5 ; Delay slots for branch
+
+.size __getcontext,.-__getcontext
+weak_alias(__getcontext, getcontext)
--- a/libc/sysdeps/linux/c6x/makecontext.c 1970-01-01
01:00:00.000000000 +0100
+++ b/libc/sysdeps/linux/c6x/makecontext.c 2013-02-13
17:28:11.970339000 +0100
@@ -0,0 +1,87 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdarg.h>
+#include <ucontext.h>
+
+/* Number of arguments that go in registers.
+ Note: convention says 10!?
+ Linux sigcontext.h only exposes 6.
+*/
+#define NREG_ARGS 6
+
+/* Take a context previously prepared via getcontext() and set to
+ call func() with the given int only args. */
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __startcontext (void);
+ unsigned long *funcstack;
+ va_list vl;
+ int misaligned;
+ int i;
+
+ /* Start at the top of stack. */
+ funcstack = (unsigned long *) (ucp->uc_stack.ss_sp +
ucp->uc_stack.ss_size);
+
+ /* Ensure the stack stays eight byte aligned. */
+ misaligned = ((unsigned long) funcstack & 4) != 0;
+
+ if ((argc > NREG_ARGS) && (argc & 1) != 0)
+ misaligned = !misaligned;
+
+ if (misaligned)
+ funcstack -= 1;
+
+ /* Reserve space for the on-stack arguments. */
+ if (argc > NREG_ARGS)
+ funcstack -= (argc - NREG_ARGS);
+
+ /* Exit to startcontext() with the next context in A14 */
+ ucp->uc_regspace[A14] = (unsigned long) ucp->uc_link;
+ ucp->uc_mcontext.sc_b3 = (unsigned long) __startcontext;
+
+ ucp->uc_regspace[B15] = (unsigned long) funcstack;
+ ucp->uc_regspace[B16] = (unsigned long) func;
+
+ va_start (vl, argc);
+ for (i = 0; i < argc ; i++) {
+ /* The first ten arguments go into registers. */
+ switch (i) {
+ case 0:
+ ucp->uc_mcontext.sc_a4 = va_arg(vl, unsigned long);
+ break;
+ case 1:
+ ucp->uc_mcontext.sc_b4 = va_arg(vl, unsigned long);
+ break;
+ case 2:
+ ucp->uc_mcontext.sc_a6 = va_arg(vl, unsigned long);
+ break;
+ case 3:
+ ucp->uc_mcontext.sc_b6 = va_arg(vl, unsigned long);
+ break;
+ case 4:
+ ucp->uc_mcontext.sc_a8 = va_arg(vl, unsigned long);
+ break;
+ case 5:
+ ucp->uc_mcontext.sc_b8 = va_arg(vl, unsigned long);
+ break;
+ default:
+ /* And the remainder on the stack. */
+ *funcstack++ = va_arg (vl, unsigned long);
+ }
+ }
+ va_end (vl);
+}
+weak_alias (__makecontext, makecontext)
--- a/libc/sysdeps/linux/c6x/Makefile.arch 2011-04-27
17:43:11.000000000 +0200
+++ b/libc/sysdeps/linux/c6x/Makefile.arch 2013-02-13
17:27:51.690339000 +0100
@@ -13,3 +13,27 @@ SSRC := __longjmp.S bsd-_setjmp.S bsd-se
# libc-nonshared-y += $(ARCH_OUT)/_syscall.os
+ifeq ($(UCLIBC_HAS_CONTEXT_FUNCS),y)
+CSRC += makecontext.c swapcontext.c
+SSRC += getcontext.S setcontext.S
+
+LIBC_ARCH_DIR := $(top_srcdir)/libc/sysdeps/linux/$(TARGET_ARCH)
+LIBC_ARCH_OUT := $(top_builddir)/libc/sysdeps/linux/$(TARGET_ARCH)
+
+libc_arch_headers: $(LIBC_ARCH_OUT)/ucontext_i.h
+headers_clean-y += libc_arch_headers_clean
+
+CFLAGS-ucontext_i.c = -S
+
+$(LIBC_ARCH_OUT)/ucontext_i.c: $(LIBC_ARCH_DIR)/ucontext_i.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(LIBC_ARCH_OUT)/ucontext_i.s: $(LIBC_ARCH_OUT)/ucontext_i.c
+ $(compile.c)
+
+$(LIBC_ARCH_OUT)/ucontext_i.h: $(LIBC_ARCH_OUT)/ucontext_i.s
+ $(do_sed) -n
"s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define
\1 \2/p" $< > $@
+
+libc_arch_headers_clean:
+ $(do_rm) $(addprefix $(LIBC_ARCH_OUT)/ucontext_i., c h s)
+endif
--- a/libc/sysdeps/linux/c6x/setcontext.S 1970-01-01
01:00:00.000000000 +0100
+++ b/libc/sysdeps/linux/c6x/setcontext.S 2013-02-13
17:28:11.970339000 +0100
@@ -0,0 +1,148 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ucontext_i.h>
+
+.text
+.macro do_call fn
+#ifdef _TMS320C6400_PLUS
+ callp .s2 (\fn), B3
+#elif defined(_TMS320C6400)
+ call .s2 (\fn)
+ addkpc .s2 9f, B3, 0
+ nop 4
+9:
+#else
+ call .s2 (\fn)
+ mhkl .s2 9f, B3
+ mhkh .s2 9f, B3
+ nop 3
+9:
+#endif
+.endm
+
+/* int setcontext (const ucontext_t *ucp) */
+
+.global __setcontext
+.type __setcontext,%function
+.align 2
+__setcontext:
+ MV .D1 A4,A8 ; save ucontext_t* across next call
+
+ ; int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
+ ; A4: Set signal mask
+ ; B4: Signal mask pointer
+ ; A6: 0 -> do not store current signal mask
+ MV .D2X A4,B4 ; ucontext_t address
+|| MVK .D1 SIG_SETMASK,A4
+
+ ADDK .S2 UCONTEXT_SIGMASK,B4 ; uc_sigmask address
+|| ZERO .S1 A6
+
+ B .S2 sigprocmask
+ mvkl .S2 1f, B3
+ mvkh .S2 1f, B3
+ nop 3
+1:
+
+ MV .D1 A8,A4
+|| MV .D2X A8,B4
+
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A0),A0
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B0),B0
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A1),A1
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B1),B1
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A2),A2
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B2),B2
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A3),A3
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B3),B3
+ ; Base registers are loaded later
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A5),A5
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B5),B5
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A6),A6
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B6),B6
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A7),A7
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B7),B7
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A8),A8
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B8),B8
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A9),A9
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B9),B9
+
+ MV .D1 A4,A10 ; Keep copy of ucontext_t*
+|| MV .D2X A4,B10 ; Keep copy of ucontext_t*
+
+ ADDK .S1 UCONTEXT_REGSPACE,A10 ; uc_regspace address
+|| ADDK .S2 UCONTEXT_REGSPACE,B10 ; uc_regspace address
+
+ LDW .D1T1 *+A10(8),A11
+|| LDW .D2T2 *+B10(12),B11
+
+ LDW .D1T1 *+A10(16),A12
+|| LDW .D2T2 *+B10(20),B12
+
+ LDW .D1T1 *+A10(24),A13
+|| LDW .D2T2 *+B10(28),B13
+
+ ; Load PC into B10 so that it is ready for the branch
+ LDW .D1T1 *+A10(40), A15
+|| LDW .D2T2 *+B10(52),B10
+
+ LDW .D1T1 *+A10(32),A14
+|| LDW .D2T2 *+B10(36),B14
+
+ ;; Loads have 4 delay slots. Take advantage of this to restore the
+ ;; scratch registers and stack pointer before the base registers
+ ;; disappear. We also need to make sure no interrupts occur,
+ ;; so put the whole thing in the delay slots of a dummy branch
+ ;; We can not move the ret earlier as that would cause it to occur
+ ;; before the last load completes
+ B .S1 (2f)
+
+ LDW .D1T1 *+A4(MCONTEXT_C6X_A4), A4
+|| LDW .D2T2 *+B4(MCONTEXT_C6X_B4), B4
+
+ LDW .D2T2 *+B10(44),B15
+
+ NOP 1
+
+ RET .S2 B10
+
+ LDW .D1T1 *+A10(0), A10
+|| LDW .D2T2 *+B10(4), B10
+
+ NOP 1
+2:
+ NOP 3
+
+.size __setcontext,.-__setcontext
+weak_alias(__setcontext, setcontext)
+
+/* This is the helper code which gets called if a function which is
+ registered with 'makecontext' returns. In this case we have to
+ install the context listed in the uc_link element of the context
+ 'makecontext' manipulated at the time of the 'makecontext' call.
+ If the pointer is NULL the process must terminate. */
+.global __startcontext
+.type __startcontext,%function
+.align 2
+__startcontext:
+ MV .D1 A14,A0
+
+ [A0] B .S1 __setcontext
+|| [A0] MV .D1 A0,A4
+
+ [!A0] B .S2 _exit
+
+ NOP 6
+
--- a/libc/sysdeps/linux/c6x/swapcontext.c 1970-01-01
01:00:00.000000000 +0100
+++ b/libc/sysdeps/linux/c6x/swapcontext.c 2013-02-13
17:27:51.690339000 +0100
@@ -0,0 +1,25 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdarg.h>
+#include <ucontext.h>
+
+int
+swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
+{
+ if(getcontext(oucp) == 0)
+ setcontext(ucp);
+ // TODO: set errno if we know why it failed
+ return -1;
+}
--- a/libc/sysdeps/linux/c6x/sys/ucontext.h 2011-04-27
17:43:11.000000000 +0200
+++ b/libc/sysdeps/linux/c6x/sys/ucontext.h 2013-02-13
17:28:11.970339000 +0100
@@ -26,6 +26,37 @@
/* A machine context is exactly a sigcontext. */
typedef struct sigcontext mcontext_t;
+enum {
+ A10,
+#define A10 A10
+ B10,
+#define B10 B10
+ A11,
+#define A11 A11
+ B11,
+#define B11 B11
+ A12,
+#define A12 A12
+ B12,
+#define B12 B12
+ A13,
+#define A13 A13
+ B13,
+#define B13 B13
+ A14,
+#define A14 A14
+ B14,
+#define B14 B14
+ A15,
+#define A15 A15
+ B15,
+#define B15 B15
+ A16,
+#define A16 A16
+ B16
+#define B16 B16
+};
+
/* Userlevel context. */
typedef struct ucontext
{
@@ -34,6 +65,7 @@ typedef struct ucontext
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
+ unsigned long uc_regspace[96] __attribute__((__aligned__(8)));
} ucontext_t;
#endif /* sys/ucontext.h */
--- a/libc/sysdeps/linux/c6x/ucontext_i.sym 1970-01-01
01:00:00.000000000 +0100
+++ b/libc/sysdeps/linux/c6x/ucontext_i.sym 2013-02-13
17:28:11.970339000 +0100
@@ -0,0 +1,40 @@
+#include <inttypes.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/ucontext.h>
+
+SIG_BLOCK
+SIG_SETMASK
+
+-- Offsets of the fields in the ucontext_t structure.
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+
+UCONTEXT_SIGMASK ucontext (uc_sigmask)
+UCONTEXT_REGSPACE ucontext (uc_regspace)
+
+MCONTEXT_C6X_SP mcontext(sc_sp)
+MCONTEXT_C6X_PC mcontext(sc_pc)
+
+MCONTEXT_C6X_A0 mcontext(sc_a0)
+MCONTEXT_C6X_A1 mcontext(sc_a1)
+MCONTEXT_C6X_A2 mcontext(sc_a2)
+MCONTEXT_C6X_A3 mcontext(sc_a3)
+MCONTEXT_C6X_A4 mcontext(sc_a4)
+MCONTEXT_C6X_A5 mcontext(sc_a5)
+MCONTEXT_C6X_A6 mcontext(sc_a6)
+MCONTEXT_C6X_A7 mcontext(sc_a7)
+MCONTEXT_C6X_A8 mcontext(sc_a8)
+MCONTEXT_C6X_A9 mcontext(sc_a9)
+
+MCONTEXT_C6X_B0 mcontext(sc_b0)
+MCONTEXT_C6X_B1 mcontext(sc_b1)
+MCONTEXT_C6X_B2 mcontext(sc_b2)
+MCONTEXT_C6X_B3 mcontext(sc_b3)
+MCONTEXT_C6X_B4 mcontext(sc_b4)
+MCONTEXT_C6X_B5 mcontext(sc_b5)
+MCONTEXT_C6X_B6 mcontext(sc_b6)
+MCONTEXT_C6X_B7 mcontext(sc_b7)
+MCONTEXT_C6X_B8 mcontext(sc_b8)
+MCONTEXT_C6X_B9 mcontext(sc_b9)
+
--- a/Makefile.in 2011-04-27 17:44:45.000000000 +0200
+++ b/Makefile.in 2013-02-13 17:27:51.694339000 +0100
@@ -162,6 +162,7 @@ headers: $(top_builddir)include/bits/uCl
subdirs: $(addprefix $(top_builddir),$(subdirs))
pregen-headers: $(top_builddir)include/bits/sysnum.h $(pregen-headers-y)
pregen: pregen-headers
+ $(Q)$(MAKE) libc_arch_headers
$(Q)$(if $(UCLIBC_HAS_LOCALE),$(MAKE) -C extra/locale locale_headers)
$(top_builddir)include/bits/sysnum.h:
$(top_srcdir)extra/scripts/gen_bits_syscall_h.sh |
$(top_builddir)include/bits
More information about the uClibc
mailing list