[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