summaryrefslogtreecommitdiff
path: root/libc-parts
diff options
context:
space:
mode:
authorneal <neal>2008-01-24 12:45:03 +0000
committerneal <neal>2008-01-24 12:45:03 +0000
commit102c941601c8d9a190f4697be23365c3b3166ee7 (patch)
tree79b19c0fd51c59bbcba6217794112da91c6e836d /libc-parts
parentdaf9af1f4dc690cdddc7db6d7093d775a861f18f (diff)
libc-parts/
2008-01-24 Neal H. Walfield <neal@gnu.org> * Makefile.am (ARCH_SOURCES): Rename from this... (ARCH_COMMON_SOURCES): ... to this. (ARCH_USER_SOURCES): New variable. (ARCH_KERNEL_SOURCES): Likewise. (noinst_LIBRARIES): Add libc-kernel.a. (common_sources): New variable. (libc_parts_a_SOURCES): Move most files to common_sources. Add $(ARCH_COMMON_SOURCES), $(ARCH_USER_SOURCES) (libc_parts_a_CPPFLAGS): Add -I$(LIBC)/include. (libc_kernel_a_SOURCES): New variable. (libc_kernel_a_CPPFLAGS): Likewise. (libc_kernel_a_LIBADD): Likewise. * s_printf.c: Move from ../ruth/output.c. (s_putchar) [RM_INTERN || _L4_TEST_ENVIRONMENT]: Add appropriate implementation. * _exit.c: New file. * getpagesize.c: Likewise. * ia32-cmain.c: Copied from ../ruth/ia32-cmain.c. Removed dead code. Don't include "ruth.h". Add prototype for main. (program_name): New variable. (finish): Setup program_name based on ARGV[0]. * ia32-crt0.S: Copied from ../ruth/ia32-crt0.c. * panic.c: Copied from ../ruth/panic.c. (panic_): Call _exit. * startup.c: New file. ruth/ 2008-01-24 Neal H. Walfield <neal@gnu.org> * Makefile.am (ARCH_SOURCES): Remove variable. (ruth_SOURCES): Set to ruth.c. (COMMON_CPPFLAGS): Remove -I$(top_builddir)/newlib/include, add -I$@LIBC@/include. * output.c: Move to ../libc-parts/s_printf.c. * output.h: Remove file. * panic.c: Move to ../libc-parts/panic.c. * ruth.h: Remove file. * malloc.c: Likewise. * malloc-wrap.c: Likewise. * ia32-cmain.c: Move to ../libc-parts/ia32-cmain.c. * ia32-crt0.S: Move to ../libc-parts/ia32-crt0.c. * ruth.c: Include <stdio.h>. Don't include "ruth.h". (output_debug): Declare, don't define. (exit): Remove function. (abort): Likewise. (getpagesize): Likewise. laden/ 2008-01-24 Neal H. Walfield <neal@gnu.org> * Makefile.am (laden_LDADD): Set to ../libc-parts/libc-kernel.a, not ../libc-parts/libc-parts.a. viengoos/ 2008-01-24 Neal H. Walfield <neal@gnu.org> * Makefile.am (viengoos_LDADD): Link with ../libc-parts/libc-kernel.a, not ../libc-parts/libc-parts.a
Diffstat (limited to 'libc-parts')
-rw-r--r--libc-parts/ChangeLog28
-rw-r--r--libc-parts/Makefile.am28
-rw-r--r--libc-parts/_exit.c60
-rw-r--r--libc-parts/getpagesize.c29
-rw-r--r--libc-parts/ia32-cmain.c143
-rw-r--r--libc-parts/ia32-crt0.S55
-rw-r--r--libc-parts/panic.c45
-rw-r--r--libc-parts/s_printf.c232
-rw-r--r--libc-parts/startup.c19
9 files changed, 632 insertions, 7 deletions
diff --git a/libc-parts/ChangeLog b/libc-parts/ChangeLog
index 52f7144..a769e7c 100644
--- a/libc-parts/ChangeLog
+++ b/libc-parts/ChangeLog
@@ -1,5 +1,33 @@
2008-01-24 Neal H. Walfield <neal@gnu.org>
+ * Makefile.am (ARCH_SOURCES): Rename from this...
+ (ARCH_COMMON_SOURCES): ... to this.
+ (ARCH_USER_SOURCES): New variable.
+ (ARCH_KERNEL_SOURCES): Likewise.
+ (noinst_LIBRARIES): Add libc-kernel.a.
+ (common_sources): New variable.
+ (libc_parts_a_SOURCES): Move most files to common_sources. Add
+ $(ARCH_COMMON_SOURCES), $(ARCH_USER_SOURCES)
+ (libc_parts_a_CPPFLAGS): Add -I$(LIBC)/include.
+ (libc_kernel_a_SOURCES): New variable.
+ (libc_kernel_a_CPPFLAGS): Likewise.
+ (libc_kernel_a_LIBADD): Likewise.
+ * s_printf.c: Move from ../ruth/output.c.
+ (s_putchar) [RM_INTERN || _L4_TEST_ENVIRONMENT]: Add appropriate
+ implementation.
+ * _exit.c: New file.
+ * getpagesize.c: Likewise.
+ * ia32-cmain.c: Copied from ../ruth/ia32-cmain.c. Removed dead
+ code. Don't include "ruth.h". Add prototype for main.
+ (program_name): New variable.
+ (finish): Setup program_name based on ARGV[0].
+ * ia32-crt0.S: Copied from ../ruth/ia32-crt0.c.
+ * panic.c: Copied from ../ruth/panic.c.
+ (panic_): Call _exit.
+ * startup.c: New file.
+
+2008-01-24 Neal H. Walfield <neal@gnu.org>
+
* Makefile.am (t_setjmp_CPPFLAGS): Remove -D_L4_TEST_ENVIRONMENT.
Add -DS_PRINTF=printf.
diff --git a/libc-parts/Makefile.am b/libc-parts/Makefile.am
index d1436d5..eaac137 100644
--- a/libc-parts/Makefile.am
+++ b/libc-parts/Makefile.am
@@ -19,20 +19,33 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
if ARCH_IA32
- ARCH_SOURCES = ia32-setjmp.S
+ ARCH_COMMON_SOURCES = ia32-setjmp.S
+ ARCH_USER_SOURCES = ia32-cmain.c ia32-crt0.S
+ ARCH_KERNEL_SOURCES =
endif
COMMON_CPPFLAGS = -I$(srcdir) -I$(top_builddir)/include \
-I$(top_srcdir)/libc-parts -D_GNU_SOURCE -Wall -std=gnu99 -g
-noinst_LIBRARIES = libc-parts.a
+noinst_LIBRARIES = libc-parts.a libc-kernel.a
-libc_parts_a_CPPFLAGS = $(COMMON_CPPFLAGS)
-libc_parts_a_SOURCES = $(ARCH_SOURCES) \
- assert.h ctype.h c-ctype.h c-ctype.c \
- errno.h errno.c \
+common_sources = assert.h \
strtol.c strtoll.c strtoul.c strtoull.c \
- setjmp.h backtrace.c
+ setjmp.h backtrace.c s_printf.c startup.c \
+ panic.c _exit.c
+
+libc_parts_a_CPPFLAGS = -I$(LIBC)/include $(COMMON_CPPFLAGS)
+libc_parts_a_SOURCES = \
+ $(ARCH_COMMON_SOURCES) $(ARCH_USER_SOURCES) \
+ ctype.h c-ctype.h c-ctype.c \
+ getpagesize.c \
+ $(common_sources)
+
+libc_kernel_a_CPPFLAGS = $(COMMON_CPPFLAGS) -DRM_INTERN
+libc_kernel_a_SOURCES = \
+ $(ARCH_COMMON_SOURCES) $(ARCH_KERNEL_SOURCES) \
+ errno.h errno.c \
+ $(common_sources)
# For the following routines we want to take the possibly optimized
# versions from the target's GNU C library, rather than duplicating
@@ -54,6 +67,7 @@ routines_objects := $(shell $(NM) --print-armap @STATIC_GLIBC@ 2>/dev/null \
# routines_objects in Makefile.in by automake, which doesn't work at all.
routines_varname := routines_objects
libc_parts_a_LIBADD = $($(routines_varname))
+libc_kernel_a_LIBADD = $($(routines_varname))
$(routines_objects): %.$(OBJEXT): @STATIC_GLIBC@
$(AR) -x $< $@
diff --git a/libc-parts/_exit.c b/libc-parts/_exit.c
new file mode 100644
index 0000000..74250fc
--- /dev/null
+++ b/libc-parts/_exit.c
@@ -0,0 +1,60 @@
+/* _exit.c - Exit implementation.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <hurd/stddef.h>
+#include <hurd/startup.h>
+#include <hurd/folio.h>
+
+int __global_zero;
+
+void
+_exit (int ret)
+{
+#if defined (RM_INTERN)
+# if defined (__i386__)
+ /* Try to invoke the debugger. */
+ asm ("int $3");
+# endif
+#else
+ extern struct hurd_startup_data *__hurd_startup_data;
+
+ addr_t folio = addr_chop (__hurd_startup_data->activity,
+ FOLIO_OBJECTS_LOG2);
+ int index = addr_extract (__hurd_startup_data->activity,
+ FOLIO_OBJECTS_LOG2);
+
+ error_t err;
+ err = rm_folio_object_alloc (ADDR_VOID, folio, index,
+ cap_void, OBJECT_POLICY_VOID,
+ (uintptr_t) ret,
+ ADDR_VOID, ADDR_VOID);
+
+ assert_perror (err);
+#endif
+
+ debug (0, "Failed to die gracefully; doing the ultra-violent.");
+
+ volatile int j = ret / __global_zero;
+ for (;;)
+ {
+ j --;
+ l4_yield ();
+ }
+}
diff --git a/libc-parts/getpagesize.c b/libc-parts/getpagesize.c
new file mode 100644
index 0000000..feaa5b9
--- /dev/null
+++ b/libc-parts/getpagesize.c
@@ -0,0 +1,29 @@
+/* getpagesize.c - getpagesize() implementation.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd 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 Hurd 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <hurd/stddef.h>
+
+size_t
+getpagesize (void)
+{
+ return PAGESIZE;
+}
diff --git a/libc-parts/ia32-cmain.c b/libc-parts/ia32-cmain.c
new file mode 100644
index 0000000..9b640c9
--- /dev/null
+++ b/libc-parts/ia32-cmain.c
@@ -0,0 +1,143 @@
+/* ia32-cmain.c - Startup code for the ia32.
+ Copyright (C) 2003, 2004, 2005, 2008 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <alloca.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <l4/globals.h>
+#include <l4/init.h>
+#include <l4/stubs.h>
+#include <l4/stubs-init.h>
+
+#include <hurd/startup.h>
+#include <hurd/mm.h>
+#include <hurd/stddef.h>
+
+
+/* Initialized by the machine-specific startup-code. */
+extern struct hurd_startup_data *__hurd_startup_data;
+
+
+extern void exit (int status) __attribute__ ((__noreturn__));
+extern int main (int, char *[]);
+
+const char program_name[30];
+
+static void
+finish (void)
+{
+ int argc = 0;
+ char **argv = 0;
+
+ char *str = __hurd_startup_data->argz;
+ if (str)
+ /* A command line was passed. */
+ {
+ int nr = 0;
+
+ /* First time around we count the number of arguments. */
+ argc = 1;
+ while (*str && *str == ' ')
+ str++;
+
+ while (*str)
+ if (*(str++) == ' ')
+ {
+ while (*str && *str == ' ')
+ str++;
+ if (*str)
+ argc++;
+ }
+ argv = alloca (sizeof (char *) * (argc + 1));
+
+ /* Second time around we fill in the argv. */
+ str = (char *) __hurd_startup_data->argz;
+
+ while (*str && *str == ' ')
+ str++;
+ argv[nr++] = str;
+
+ while (*str)
+ {
+ if (*str == ' ')
+ {
+ *(str++) = '\0';
+ while (*str && *str == ' ')
+ str++;
+ if (*str)
+ argv[nr++] = str;
+ }
+ else
+ str++;
+ }
+ argv[nr] = 0;
+ }
+ else
+ {
+ argc = 1;
+
+ argv = alloca (sizeof (char *) * 2);
+ argv[0] = (char *) program_name;
+ argv[1] = 0;
+ }
+
+ char *n = "unknown";
+ if (argv[0])
+ n = argv[0];
+
+ memcpy ((char *) program_name, n,
+ sizeof (program_name) > strlen (n)
+ ? strlen (n) : sizeof (program_name));
+ ((char *) program_name)[sizeof (program_name)] = 0;
+
+ /* Now invoke the main function. */
+ exit (main (argc, argv));
+}
+
+/* Initialize libl4, setup the argument vector, and pass control over
+ to the main function. */
+void
+cmain (void)
+{
+ l4_init ();
+ l4_init_stubs ();
+
+ s_printf ("In cmain\n");
+
+ mm_init (__hurd_startup_data->activity);
+
+ extern void *(*_pthread_init_routine)(void);
+ if (_pthread_init_routine)
+ {
+ void *sp = _pthread_init_routine ();
+
+ /* Switch stacks. */
+ l4_start_sp_ip (l4_myself (), (l4_word_t) sp, (l4_word_t) &finish);
+ }
+ else
+ finish ();
+
+ /* Never reached. */
+}
diff --git a/libc-parts/ia32-crt0.S b/libc-parts/ia32-crt0.S
new file mode 100644
index 0000000..bc803e7
--- /dev/null
+++ b/libc-parts/ia32-crt0.S
@@ -0,0 +1,55 @@
+/* ia32-crt0.S - Startup code for ia32.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+/* The size of our stack (4KB). */
+#define STACK_SIZE 0x1000
+
+ .text
+
+ .globl start, _start
+start:
+_start:
+ /* The location of the Hurd startup data is stored in esp. */
+ movl %esp, __hurd_startup_data
+
+ /* Initialize the stack pointer. */
+ movl $(stack + STACK_SIZE), %esp
+
+ /* Reset EFLAGS. */
+ pushl $0
+ popf
+
+ /* Now enter the cmain function. */
+ call cmain
+
+ /* Not reached. */
+loop: hlt
+ jmp loop
+
+ /* Our stack area. */
+ .comm stack, STACK_SIZE
+
+
+ .data
+
+ /* This variable holds a pointer to the Hurd startup data. */
+ .global __hurd_startup_data
+__hurd_startup_data:
+ .long 0
diff --git a/libc-parts/panic.c b/libc-parts/panic.c
new file mode 100644
index 0000000..93e1886
--- /dev/null
+++ b/libc-parts/panic.c
@@ -0,0 +1,45 @@
+/* panic.h - Panic interface.
+ Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <hurd/stddef.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+extern const char program_name[];
+
+extern void _exit (int);
+
+void
+panic_ (const char *func, int line, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ s_printf ("%s:%s:%d:%x: error: ", program_name, func, line, l4_myself ());
+ s_vprintf (fmt, ap);
+ s_printf ("\n");
+ va_end (ap);
+
+ _exit (127);
+ for (;;)
+ l4_yield ();
+}
+
diff --git a/libc-parts/s_printf.c b/libc-parts/s_printf.c
new file mode 100644
index 0000000..4a215cb
--- /dev/null
+++ b/libc-parts/s_printf.c
@@ -0,0 +1,232 @@
+/* s_printf.c - Simply output routines.
+ Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+/* This implementation of printf is special in that it works in place
+ and does not dynamically allocate memory. This makes it
+ appropriate for use in debugging code before malloc is functional
+ or if the state is uncertain, for instance, if assert or panic is
+ called. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <hurd/rm.h>
+
+/* Print the single character CHR on the output device. */
+int
+s_putchar (int chr)
+{
+#if defined(RM_INTERN) || defined(_L4_TEST_ENVIRONMENT)
+ /* For Viengoos, use driver putchar routine. For the test
+ environment, just use the stdio putchar. */
+ extern int putchar (int chr);
+
+ return putchar (chr);
+#else
+ rm_putchar (chr);
+ return 0;
+#endif
+}
+
+int
+s_puts (const char *str)
+{
+ while (*str != '\0')
+ s_putchar (*(str++));
+
+ s_putchar ('\n');
+
+ return 0;
+}
+
+
+static void
+print_nr (unsigned long long nr, int base)
+{
+ static char *digits = "0123456789abcdef";
+ char str[30];
+ int i = 0;
+
+ do
+ {
+ str[i++] = digits[nr % base];
+ nr = nr / base;
+ }
+ while (nr);
+
+ i--;
+ while (i >= 0)
+ s_putchar (str[i--]);
+}
+
+
+static void
+print_signed_nr (long long nr, int base)
+{
+ unsigned long long unr;
+
+ if (nr < 0)
+ {
+ s_putchar ('-');
+ unr = -nr;
+ }
+ else
+ unr = nr;
+
+ print_nr (unr, base);
+}
+
+
+int
+s_vprintf (const char *fmt, va_list ap)
+{
+ const char *p = fmt;
+
+ while (*p != '\0')
+ {
+ if (*p != '%')
+ {
+ s_putchar (*(p++));
+ continue;
+ }
+
+ p++;
+ switch (*p)
+ {
+ case '%':
+ s_putchar ('%');
+ p++;
+ break;
+
+ case 'l':
+ p++;
+ if (*p != 'l')
+ {
+ s_putchar ('%');
+ s_putchar ('l');
+ s_putchar (*(p++));
+ continue;
+ }
+ p++;
+ switch (*p)
+ {
+ case 'o':
+ print_nr (va_arg (ap, unsigned long long), 8);
+ p++;
+ break;
+
+ case 'd':
+ case 'i':
+ print_signed_nr (va_arg (ap, long long), 10);
+ p++;
+ break;
+
+ case 'x':
+ case 'X':
+ print_nr (va_arg (ap, unsigned long long), 16);
+ p++;
+ break;
+
+ case 'u':
+ print_nr (va_arg (ap, unsigned long long), 10);
+ p++;
+ break;
+
+ default:
+ s_putchar ('%');
+ s_putchar ('l');
+ s_putchar ('l');
+ s_putchar (*(p++));
+ break;
+ }
+ break;
+
+ case 'o':
+ print_nr (va_arg (ap, unsigned int), 8);
+ p++;
+ break;
+
+ case 'd':
+ case 'i':
+ print_signed_nr (va_arg (ap, int), 10);
+ p++;
+ break;
+
+ case 'x':
+ case 'X':
+ print_nr (va_arg (ap, unsigned int), 16);
+ p++;
+ break;
+
+ case 'u':
+ print_nr (va_arg (ap, unsigned int), 10);
+ p++;
+ break;
+
+ case 'c':
+ s_putchar (va_arg (ap, int));
+ p++;
+ break;
+
+ case 's':
+ {
+ char *str = va_arg (ap, char *);
+ if (str)
+ while (*str)
+ s_putchar (*(str++));
+ else
+ {
+ s_putchar ('N');
+ s_putchar ('U');
+ s_putchar ('L');
+ s_putchar ('L');
+ }
+ }
+ p++;
+ break;
+
+ case 'p':
+ print_nr ((unsigned int) va_arg (ap, void *), 16);
+ p++;
+ break;
+
+ default:
+ s_putchar ('%');
+ s_putchar (*p);
+ p++;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int
+s_printf (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ int r = s_vprintf (fmt, ap);
+ va_end (ap);
+ return r;
+}
diff --git a/libc-parts/startup.c b/libc-parts/startup.c
new file mode 100644
index 0000000..cb6a1be
--- /dev/null
+++ b/libc-parts/startup.c
@@ -0,0 +1,19 @@
+/* startup.c - Architecture independent startup.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ GNU Hurd 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 3 of the
+ License, or (at your option) any later version.
+
+ GNU Hurd 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 GNU Hurd. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+int output_debug;