added sparc newlib backend
authorAndrew Waterman <waterman@r53.millennium.berkeley.edu>
Wed, 5 Aug 2009 01:39:32 +0000 (18:39 -0700)
committerAndrew Waterman <waterman@r53.millennium.berkeley.edu>
Wed, 5 Aug 2009 01:39:32 +0000 (18:39 -0700)
37 files changed:
gccinclude/sparc/float.h [new file with mode: 0644]
gccinclude/sparc/iso646.h [new file with mode: 0644]
gccinclude/sparc/ssp/ssp.h [new file with mode: 0644]
gccinclude/sparc/ssp/stdio.h [new file with mode: 0644]
gccinclude/sparc/ssp/string.h [new file with mode: 0644]
gccinclude/sparc/ssp/unistd.h [new file with mode: 0644]
gccinclude/sparc/stdarg.h [new file with mode: 0644]
gccinclude/sparc/stdbool.h [new file with mode: 0644]
gccinclude/sparc/stddef.h [new file with mode: 0644]
gccinclude/sparc/stdfix.h [new file with mode: 0644]
gccinclude/sparc/tgmath.h [new file with mode: 0644]
gccinclude/sparc/unwind.h [new file with mode: 0644]
gccinclude/sparc/varargs.h [new file with mode: 0644]
kern/arch/sparc/sparc.h
kern/arch/sparc/timer.c
kern/include/ros/syscall.h
kern/src/Makefrag
kern/src/kfs.c
kern/src/syscall.c
user/Makefrag
user/apps/parlib/Makefrag
user/apps/parlib/apps.ld [deleted file]
user/apps/parlib/apps_i386.ld [new file with mode: 0644]
user/apps/parlib/apps_sparc.ld [new file with mode: 0644]
user/apps/parlib/matrix.c
user/parlib/src/Makefrag
user/parlib/src/entry_i386.S [deleted file]
user/parlib/src/entry_sparc.S [deleted file]
user/parlib/src/i386/entry.S [new file with mode: 0644]
user/parlib/src/i386/newlib_backend.c [new file with mode: 0644]
user/parlib/src/i386/syscall.c [new file with mode: 0644]
user/parlib/src/newlib_backend.c [deleted file]
user/parlib/src/sparc/entry.S [new file with mode: 0644]
user/parlib/src/sparc/newlib_backend.c [new file with mode: 0644]
user/parlib/src/sparc/syscall.c [new file with mode: 0644]
user/parlib/src/syscall_i386.c [deleted file]
user/parlib/src/syscall_sparc.c [deleted file]

diff --git a/gccinclude/sparc/float.h b/gccinclude/sparc/float.h
new file mode 100644 (file)
index 0000000..23ce8f4
--- /dev/null
@@ -0,0 +1,241 @@
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/*
+ * ISO C Standard:  5.2.4.2.2  Characteristics of floating types <float.h>
+ */
+
+#ifndef _FLOAT_H___
+#define _FLOAT_H___
+
+/* Radix of exponent representation, b. */
+#undef FLT_RADIX
+#define FLT_RADIX      __FLT_RADIX__
+
+/* Number of base-FLT_RADIX digits in the significand, p.  */
+#undef FLT_MANT_DIG
+#undef DBL_MANT_DIG
+#undef LDBL_MANT_DIG
+#define FLT_MANT_DIG   __FLT_MANT_DIG__
+#define DBL_MANT_DIG   __DBL_MANT_DIG__
+#define LDBL_MANT_DIG  __LDBL_MANT_DIG__
+
+/* Number of decimal digits, q, such that any floating-point number with q
+   decimal digits can be rounded into a floating-point number with p radix b
+   digits and back again without change to the q decimal digits,
+
+       p * log10(b)                    if b is a power of 10
+       floor((p - 1) * log10(b))       otherwise
+*/
+#undef FLT_DIG
+#undef DBL_DIG
+#undef LDBL_DIG
+#define FLT_DIG                __FLT_DIG__
+#define DBL_DIG                __DBL_DIG__
+#define LDBL_DIG       __LDBL_DIG__
+
+/* Minimum int x such that FLT_RADIX**(x-1) is a normalized float, emin */
+#undef FLT_MIN_EXP
+#undef DBL_MIN_EXP
+#undef LDBL_MIN_EXP
+#define FLT_MIN_EXP    __FLT_MIN_EXP__
+#define DBL_MIN_EXP    __DBL_MIN_EXP__
+#define LDBL_MIN_EXP   __LDBL_MIN_EXP__
+
+/* Minimum negative integer such that 10 raised to that power is in the
+   range of normalized floating-point numbers,
+
+       ceil(log10(b) * (emin - 1))
+*/
+#undef FLT_MIN_10_EXP
+#undef DBL_MIN_10_EXP
+#undef LDBL_MIN_10_EXP
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+#define LDBL_MIN_10_EXP        __LDBL_MIN_10_EXP__
+
+/* Maximum int x such that FLT_RADIX**(x-1) is a representable float, emax.  */
+#undef FLT_MAX_EXP
+#undef DBL_MAX_EXP
+#undef LDBL_MAX_EXP
+#define FLT_MAX_EXP    __FLT_MAX_EXP__
+#define DBL_MAX_EXP    __DBL_MAX_EXP__
+#define LDBL_MAX_EXP   __LDBL_MAX_EXP__
+
+/* Maximum integer such that 10 raised to that power is in the range of
+   representable finite floating-point numbers,
+
+       floor(log10((1 - b**-p) * b**emax))
+*/
+#undef FLT_MAX_10_EXP
+#undef DBL_MAX_10_EXP
+#undef LDBL_MAX_10_EXP
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+#define LDBL_MAX_10_EXP        __LDBL_MAX_10_EXP__
+
+/* Maximum representable finite floating-point number,
+
+       (1 - b**-p) * b**emax
+*/
+#undef FLT_MAX
+#undef DBL_MAX
+#undef LDBL_MAX
+#define FLT_MAX                __FLT_MAX__
+#define DBL_MAX                __DBL_MAX__
+#define LDBL_MAX       __LDBL_MAX__
+
+/* The difference between 1 and the least value greater than 1 that is
+   representable in the given floating point type, b**1-p.  */
+#undef FLT_EPSILON
+#undef DBL_EPSILON
+#undef LDBL_EPSILON
+#define FLT_EPSILON    __FLT_EPSILON__
+#define DBL_EPSILON    __DBL_EPSILON__
+#define LDBL_EPSILON   __LDBL_EPSILON__
+
+/* Minimum normalized positive floating-point number, b**(emin - 1).  */
+#undef FLT_MIN
+#undef DBL_MIN
+#undef LDBL_MIN
+#define FLT_MIN                __FLT_MIN__
+#define DBL_MIN                __DBL_MIN__
+#define LDBL_MIN       __LDBL_MIN__
+
+/* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown.  */
+/* ??? This is supposed to change with calls to fesetround in <fenv.h>.  */
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+/* The floating-point expression evaluation method.
+        -1  indeterminate
+         0  evaluate all operations and constants just to the range and
+            precision of the type
+         1  evaluate operations and constants of type float and double
+            to the range and precision of the double type, evaluate
+            long double operations and constants to the range and
+            precision of the long double type
+         2  evaluate all operations and constants to the range and
+            precision of the long double type
+
+   ??? This ought to change with the setting of the fp control word;
+   the value provided by the compiler assumes the widest setting.  */
+#undef FLT_EVAL_METHOD
+#define FLT_EVAL_METHOD        __FLT_EVAL_METHOD__
+
+/* Number of decimal digits, n, such that any floating-point number in the
+   widest supported floating type with pmax radix b digits can be rounded
+   to a floating-point number with n decimal digits and back again without
+   change to the value,
+
+       pmax * log10(b)                 if b is a power of 10
+       ceil(1 + pmax * log10(b))       otherwise
+*/
+#undef DECIMAL_DIG
+#define DECIMAL_DIG    __DECIMAL_DIG__
+
+#endif /* C99 */
+
+#ifdef __STDC_WANT_DEC_FP__
+/* Draft Technical Report 24732, extension for decimal floating-point
+   arithmetic: Characteristic of decimal floating types <float.h>.  */
+
+/* Number of base-FLT_RADIX digits in the significand, p.  */
+#undef DEC32_MANT_DIG
+#undef DEC64_MANT_DIG
+#undef DEC128_MANT_DIG
+#define DEC32_MANT_DIG __DEC32_MANT_DIG__
+#define DEC64_MANT_DIG __DEC64_MANT_DIG__
+#define DEC128_MANT_DIG        __DEC128_MANT_DIG__
+
+/* Minimum exponent. */
+#undef DEC32_MIN_EXP
+#undef DEC64_MIN_EXP
+#undef DEC128_MIN_EXP
+#define DEC32_MIN_EXP  __DEC32_MIN_EXP__
+#define DEC64_MIN_EXP  __DEC64_MIN_EXP__
+#define DEC128_MIN_EXP __DEC128_MIN_EXP__
+
+/* Maximum exponent. */
+#undef DEC32_MAX_EXP
+#undef DEC64_MAX_EXP
+#undef DEC128_MAX_EXP
+#define DEC32_MAX_EXP  __DEC32_MAX_EXP__
+#define DEC64_MAX_EXP  __DEC64_MAX_EXP__
+#define DEC128_MAX_EXP __DEC128_MAX_EXP__
+
+/* Maximum representable finite decimal floating-point number
+   (there are 6, 15, and 33 9s after the decimal points respectively). */
+#undef DEC32_MAX
+#undef DEC64_MAX
+#undef DEC128_MAX
+#define DEC32_MAX   __DEC32_MAX__
+#define DEC64_MAX   __DEC64_MAX__
+#define DEC128_MAX  __DEC128_MAX__
+
+/* The difference between 1 and the least value greater than 1 that is
+   representable in the given floating point type. */
+#undef DEC32_EPSILON
+#undef DEC64_EPSILON
+#undef DEC128_EPSILON
+#define DEC32_EPSILON  __DEC32_EPSILON__
+#define DEC64_EPSILON  __DEC64_EPSILON__
+#define DEC128_EPSILON __DEC128_EPSILON__
+
+/* Minimum normalized positive floating-point number. */
+#undef DEC32_MIN
+#undef DEC64_MIN
+#undef DEC128_MIN
+#define DEC32_MIN      __DEC32_MIN__
+#define DEC64_MIN      __DEC64_MIN__
+#define DEC128_MIN     __DEC128_MIN__
+
+/* Minimum denormalized positive floating-point number. */
+#undef DEC32_DEN
+#undef DEC64_DEN
+#undef DEC128_DEN
+#define DEC32_DEN       __DEC32_DEN__
+#define DEC64_DEN       __DEC64_DEN__
+#define DEC128_DEN      __DEC128_DEN__
+
+/* The floating-point expression evaluation method.
+         -1  indeterminate
+         0  evaluate all operations and constants just to the range and
+            precision of the type
+         1  evaluate operations and constants of type _Decimal32 
+           and _Decimal64 to the range and precision of the _Decimal64 
+            type, evaluate _Decimal128 operations and constants to the 
+           range and precision of the _Decimal128 type;
+        2  evaluate all operations and constants to the range and
+           precision of the _Decimal128 type.  */
+
+#undef DECFLT_EVAL_METHOD
+#define DECFLT_EVAL_METHOD     __DECFLT_EVAL_METHOD__
+
+#endif /* __STDC_WANT_DEC_FP__ */
+
+#endif /* _FLOAT_H___ */
diff --git a/gccinclude/sparc/iso646.h b/gccinclude/sparc/iso646.h
new file mode 100644 (file)
index 0000000..445d372
--- /dev/null
@@ -0,0 +1,48 @@
+/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/*
+ * ISO C Standard:  7.9  Alternative spellings  <iso646.h>
+ */
+
+#ifndef _ISO646_H
+#define _ISO646_H
+
+#ifndef __cplusplus
+#define and    &&
+#define and_eq &=
+#define bitand &
+#define bitor  |
+#define compl  ~
+#define not    !
+#define not_eq !=
+#define or     ||
+#define or_eq  |=
+#define xor    ^
+#define xor_eq ^=
+#endif
+
+#endif
diff --git a/gccinclude/sparc/ssp/ssp.h b/gccinclude/sparc/ssp/ssp.h
new file mode 100644 (file)
index 0000000..bd7d6d4
--- /dev/null
@@ -0,0 +1,66 @@
+/* Object size checking support macros.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC 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 GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with
+   GCC to produce an executable, this does not cause the resulting executable
+   to be covered by the GNU General Public License. This exception does not
+   however invalidate any other reasons why the executable file might be
+   covered by the GNU General Public License.  */
+
+#ifndef _SSP_H
+#define _SSP_H 1
+
+#if _FORTIFY_SOURCE > 0 && __OPTIMIZE__ > 0 \
+    && defined __GNUC__ \
+    && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \
+    && !defined __cplusplus
+# if _FORTIFY_SOURCE == 1
+#  define __SSP_FORTIFY_LEVEL 1
+# elif _FORTIFY_SOURCE > 1
+#  define __SSP_FORTIFY_LEVEL 2
+# endif
+#endif
+
+#if __SSP_FORTIFY_LEVEL > 0
+# include <stddef.h>
+# define __ssp_bos(ptr) __builtin_object_size (ptr, __SSP_FORTIFY_LEVEL > 1)
+# define __ssp_bos0(ptr) __builtin_object_size (ptr, 0)
+
+# define __SSP_REDIRECT(name, proto, alias) \
+  name proto __asm__ (__SSP_ASMNAME (#alias))
+# define __SSP_ASMNAME(cname)  __SSP_ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+# define __SSP_ASMNAME2(prefix, cname) __SSP_ASMNAME3 (prefix) cname
+# define __SSP_ASMNAME3(prefix) #prefix
+
+# undef __SSP_HAVE_VSNPRINTF
+
+extern void __chk_fail (void) __attribute__((__noreturn__));
+#endif
+
+#endif /* _SSP_H */
diff --git a/gccinclude/sparc/ssp/stdio.h b/gccinclude/sparc/ssp/stdio.h
new file mode 100644 (file)
index 0000000..00c687f
--- /dev/null
@@ -0,0 +1,101 @@
+/* Checking macros for stdio functions.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC 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 GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with
+   GCC to produce an executable, this does not cause the resulting executable
+   to be covered by the GNU General Public License. This exception does not
+   however invalidate any other reasons why the executable file might be
+   covered by the GNU General Public License.  */
+
+#ifndef _SSP_STDIO_H
+#define _SSP_STDIO_H 1
+
+#include <ssp.h>
+#include_next <stdio.h>
+
+#if __SSP_FORTIFY_LEVEL > 0
+
+#include <stdarg.h>
+
+#undef sprintf
+#undef vsprintf
+#undef snprintf
+#undef vsnprintf
+#undef gets
+#undef fgets
+
+extern int __sprintf_chk (char *__restrict__ __s, int __flag, size_t __slen,
+                         __const char *__restrict__ __format, ...);
+extern int __vsprintf_chk (char *__restrict__ __s, int __flag, size_t __slen,
+                          __const char *__restrict__ __format,
+                          va_list __ap);
+
+#define sprintf(str, ...) \
+  __builtin___sprintf_chk (str, 0, __ssp_bos (str), \
+                          __VA_ARGS__)
+#define vsprintf(str, fmt, ap) \
+  __builtin___vsprintf_chk (str, 0, __ssp_bos (str), fmt, ap)
+
+extern int __snprintf_chk (char *__restrict__ __s, size_t __n, int __flag,
+                          size_t __slen, __const char *__restrict__ __format,
+                          ...);
+extern int __vsnprintf_chk (char *__restrict__ __s, size_t __n, int __flag,
+                           size_t __slen, __const char *__restrict__ __format,
+                           va_list __ap);
+
+#define snprintf(str, len, ...) \
+  __builtin___snprintf_chk (str, len, 0, __ssp_bos (str), __VA_ARGS__)
+#define vsnprintf(str, len, fmt, ap) \
+  __builtin___vsnprintf_chk (str, len, 0, __ssp_bos (str), fmt, ap)
+
+extern char *__gets_chk (char *__str, size_t);
+extern char *__SSP_REDIRECT (__gets_alias, (char *__str), gets);
+
+extern inline __attribute__((__always_inline__)) char *
+gets (char *__str)
+{
+  if (__ssp_bos (__str) != (size_t) -1)
+    return __gets_chk (__str, __ssp_bos (__str));
+  return __gets_alias (__str);
+}
+
+extern char *__SSP_REDIRECT (__fgets_alias,
+                            (char *__restrict__ __s, int __n,
+                             FILE *__restrict__ __stream), fgets);
+
+extern inline __attribute__((__always_inline__)) char *
+fgets (char *__restrict__ __s, int __n, FILE *__restrict__ __stream)
+{
+  if (__ssp_bos (__s) != (size_t) -1 && (size_t) __n > __ssp_bos (__s))
+    __chk_fail ();
+  return __fgets_alias (__s, __n, __stream);
+}
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+#endif /* _SSP_STDIO_H */
diff --git a/gccinclude/sparc/ssp/string.h b/gccinclude/sparc/ssp/string.h
new file mode 100644 (file)
index 0000000..57a17cf
--- /dev/null
@@ -0,0 +1,168 @@
+/* Checking macros for string functions.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC 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 GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with
+   GCC to produce an executable, this does not cause the resulting executable
+   to be covered by the GNU General Public License. This exception does not
+   however invalidate any other reasons why the executable file might be
+   covered by the GNU General Public License.  */
+
+#ifndef _SSP_STRING_H
+#define _SSP_STRING_H 1
+
+#include <ssp.h>
+#include_next <string.h>
+
+#if __SSP_FORTIFY_LEVEL > 0
+
+#undef memcpy
+#undef memmove
+#undef memset
+#undef strcat
+#undef strcpy
+#undef strncat
+#undef strncpy
+#undef mempcpy
+#undef stpcpy
+#undef bcopy
+#undef bzero
+
+#define memcpy(dest, src, len) \
+  ((__ssp_bos0 (dest) != (size_t) -1)                                  \
+   ? __builtin___memcpy_chk (dest, src, len, __ssp_bos0 (dest))                \
+   : __memcpy_ichk (dest, src, len))
+static inline __attribute__((__always_inline__)) void *
+__memcpy_ichk (void *__restrict__ __dest, const void *__restrict__ __src,
+              size_t __len)
+{
+  return __builtin___memcpy_chk (__dest, __src, __len, __ssp_bos0 (__dest));
+}
+
+
+#define memmove(dest, src, len) \
+  ((__ssp_bos0 (dest) != (size_t) -1)                                  \
+   ? __builtin___memmove_chk (dest, src, len, __ssp_bos0 (dest))               \
+   : __memmove_ichk (dest, src, len))
+static inline __attribute__((__always_inline__)) void *
+__memmove_ichk (void *__dest, const void *__src, size_t __len)
+{
+  return __builtin___memmove_chk (__dest, __src, __len, __ssp_bos0 (__dest));
+}
+
+
+#define mempcpy(dest, src, len) \
+  ((__ssp_bos0 (dest) != (size_t) -1)                                  \
+   ? __builtin___mempcpy_chk (dest, src, len, __ssp_bos0 (dest))       \
+   : __mempcpy_ichk (dest, src, len))
+static inline __attribute__((__always_inline__)) void *
+__mempcpy_ichk (void *__restrict__ __dest, const void *__restrict__ __src,
+               size_t __len)
+{
+  return __builtin___mempcpy_chk (__dest, __src, __len, __ssp_bos0 (__dest));
+}
+
+
+#define memset(dest, ch, len) \
+  ((__ssp_bos0 (dest) != (size_t) -1)                                  \
+   ? __builtin___memset_chk (dest, ch, len, __ssp_bos0 (dest))         \
+   : __memset_ichk (dest, ch, len))
+static inline __attribute__((__always_inline__)) void *
+__memset_ichk (void *__dest, int __ch, size_t __len)
+{
+  return __builtin___memset_chk (__dest, __ch, __len, __ssp_bos0 (__dest));
+}
+
+#define bcopy(src, dest, len) ((void) \
+ ((__ssp_bos0 (dest) != (size_t) -1)                                   \
+   ? __builtin___memmove_chk (dest, src, len, __ssp_bos0 (dest))       \
+   : __memmove_ichk (dest, src, len)))
+#define bzero(dest, len) ((void) \
+  ((__ssp_bos0 (dest) != (size_t) -1)                                  \
+   ? __builtin___memset_chk (dest, '\0', len, __ssp_bos0 (dest))       \
+   : __memset_ichk (dest, '\0', len)))
+
+
+#define strcpy(dest, src) \
+  ((__ssp_bos (dest) != (size_t) -1)                                   \
+   ? __builtin___strcpy_chk (dest, src, __ssp_bos (dest))              \
+   : __strcpy_ichk (dest, src))
+static inline __attribute__((__always_inline__)) char *
+__strcpy_ichk (char *__restrict__ __dest, const char *__restrict__ __src)
+{
+  return __builtin___strcpy_chk (__dest, __src, __ssp_bos (__dest));
+}
+
+
+#define stpcpy(dest, src) \
+  ((__ssp_bos (dest) != (size_t) -1)                                   \
+   ? __builtin___stpcpy_chk (dest, src, __ssp_bos (dest))              \
+   : __stpcpy_ichk (dest, src))
+static inline __attribute__((__always_inline__)) char *
+__stpcpy_ichk (char *__restrict__ __dest, const char *__restrict__ __src)
+{
+  return __builtin___stpcpy_chk (__dest, __src, __ssp_bos (__dest));
+}
+
+
+#define strncpy(dest, src, len) \
+  ((__ssp_bos (dest) != (size_t) -1)                                   \
+   ? __builtin___strncpy_chk (dest, src, len, __ssp_bos (dest))                \
+   : __strncpy_ichk (dest, src, len))
+static inline __attribute__((__always_inline__)) char *
+__strncpy_ichk (char *__restrict__ __dest, const char *__restrict__ __src,
+               size_t __len)
+{
+  return __builtin___strncpy_chk (__dest, __src, __len, __ssp_bos (__dest));
+}
+
+
+#define strcat(dest, src) \
+  ((__ssp_bos (dest) != (size_t) -1)                                   \
+   ? __builtin___strcat_chk (dest, src, __ssp_bos (dest))              \
+   : __strcat_ichk (dest, src))
+static inline __attribute__((__always_inline__)) char *
+__strcat_ichk (char *__restrict__ __dest, const char *__restrict__ __src)
+{
+  return __builtin___strcat_chk (__dest, __src, __ssp_bos (__dest));
+}
+
+
+#define strncat(dest, src, len) \
+  ((__ssp_bos (dest) != (size_t) -1)                                   \
+   ? __builtin___strncat_chk (dest, src, len, __ssp_bos (dest))                \
+   : __strncat_ichk (dest, src, len))
+static inline __attribute__((__always_inline__)) char *
+__strncat_ichk (char *__restrict__ __dest, const char *__restrict__ __src,
+               size_t __len)
+{
+  return __builtin___strncat_chk (__dest, __src, __len, __ssp_bos (__dest));
+}
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+#endif /* _SSP_STRING_H */
diff --git a/gccinclude/sparc/ssp/unistd.h b/gccinclude/sparc/ssp/unistd.h
new file mode 100644 (file)
index 0000000..de62166
--- /dev/null
@@ -0,0 +1,85 @@
+/* Checking macros for unistd functions.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC 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 GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with
+   GCC to produce an executable, this does not cause the resulting executable
+   to be covered by the GNU General Public License. This exception does not
+   however invalidate any other reasons why the executable file might be
+   covered by the GNU General Public License.  */
+
+#ifndef _SSP_UNISTD_H
+#define _SSP_UNISTD_H 1
+
+#include <ssp.h>
+#include_next <unistd.h>
+
+#if __SSP_FORTIFY_LEVEL > 0
+
+#undef read
+#undef readlink
+#undef getcwd
+
+extern ssize_t __SSP_REDIRECT (__read_alias, (int __fd, void *__buf,
+                                             size_t __nbytes), read);
+
+extern inline __attribute__((__always_inline__)) ssize_t
+read (int __fd, void *__buf, size_t __nbytes)
+{
+  if (__ssp_bos0 (__buf) != (size_t) -1 && __nbytes > __ssp_bos0 (__buf))
+    __chk_fail ();
+  return __read_alias (__fd, __buf, __nbytes);
+}
+
+extern int __SSP_REDIRECT (__readlink_alias,
+                          (const char *__restrict__ __path,
+                           char *__restrict__ __buf, size_t __len),
+                          readlink);
+
+extern inline __attribute__((__always_inline__)) int
+readlink (const char *__restrict__ __path, char *__restrict__ __buf,
+         size_t __len)
+{
+  if (__ssp_bos (__buf) != (size_t) -1 && __len > __ssp_bos (__buf))
+    __chk_fail ();
+  return __readlink_alias (__path, __buf, __len);
+}
+
+extern char *__SSP_REDIRECT (__getcwd_alias,
+                            (char *__buf, size_t __size), getcwd);
+
+extern inline __attribute__((__always_inline__)) char *
+getcwd (char *__buf, size_t __size)
+{
+  if (__ssp_bos (__buf) != (size_t) -1 && __size > __ssp_bos (__buf))
+    __chk_fail ();
+  return __getcwd_alias (__buf, __size);
+}
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+#endif /* _SSP_UNISTD_H */
diff --git a/gccinclude/sparc/stdarg.h b/gccinclude/sparc/stdarg.h
new file mode 100644 (file)
index 0000000..c9ddd6b
--- /dev/null
@@ -0,0 +1,133 @@
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/*
+ * ISO C Standard:  7.15  Variable arguments  <stdarg.h>
+ */
+
+#ifndef _STDARG_H
+#ifndef _ANSI_STDARG_H_
+#ifndef __need___va_list
+#define _STDARG_H
+#define _ANSI_STDARG_H_
+#endif /* not __need___va_list */
+#undef __need___va_list
+
+/* Define __gnuc_va_list.  */
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+typedef __builtin_va_list __gnuc_va_list;
+#endif
+
+/* Define the standard macros for the user,
+   if this invocation was from the user program.  */
+#ifdef _STDARG_H
+
+#define va_start(v,l)  __builtin_va_start(v,l)
+#define va_end(v)      __builtin_va_end(v)
+#define va_arg(v,l)    __builtin_va_arg(v,l)
+#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
+#define va_copy(d,s)   __builtin_va_copy(d,s)
+#endif
+#define __va_copy(d,s) __builtin_va_copy(d,s)
+
+/* Define va_list, if desired, from __gnuc_va_list. */
+/* We deliberately do not define va_list when called from
+   stdio.h, because ANSI C says that stdio.h is not supposed to define
+   va_list.  stdio.h needs to have access to that data type, 
+   but must not use that name.  It should use the name __gnuc_va_list,
+   which is safe because it is reserved for the implementation.  */
+
+#ifdef _HIDDEN_VA_LIST  /* On OSF1, this means varargs.h is "half-loaded".  */
+#undef _VA_LIST
+#endif
+
+#ifdef _BSD_VA_LIST
+#undef _BSD_VA_LIST
+#endif
+
+#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST))
+/* SVR4.2 uses _VA_LIST for an internal alias for va_list,
+   so we must avoid testing it and setting it here.
+   SVR4 uses _VA_LIST as a flag in stdarg.h, but we should
+   have no conflict with that.  */
+#ifndef _VA_LIST_
+#define _VA_LIST_
+#ifdef __i860__
+#ifndef _VA_LIST
+#define _VA_LIST va_list
+#endif
+#endif /* __i860__ */
+typedef __gnuc_va_list va_list;
+#ifdef _SCO_DS
+#define __VA_LIST
+#endif
+#endif /* _VA_LIST_ */
+#else /* not __svr4__ || _SCO_DS */
+
+/* The macro _VA_LIST_ is the same thing used by this file in Ultrix.
+   But on BSD NET2 we must not test or define or undef it.
+   (Note that the comments in NET 2's ansi.h
+   are incorrect for _VA_LIST_--see stdio.h!)  */
+#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT)
+/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5  */
+#ifndef _VA_LIST_DEFINED
+/* The macro _VA_LIST is used in SCO Unix 3.2.  */
+#ifndef _VA_LIST
+/* The macro _VA_LIST_T_H is used in the Bull dpx2  */
+#ifndef _VA_LIST_T_H
+/* The macro __va_list__ is used by BeOS.  */
+#ifndef __va_list__
+typedef __gnuc_va_list va_list;
+#endif /* not __va_list__ */
+#endif /* not _VA_LIST_T_H */
+#endif /* not _VA_LIST */
+#endif /* not _VA_LIST_DEFINED */
+#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__))
+#define _VA_LIST_
+#endif
+#ifndef _VA_LIST
+#define _VA_LIST
+#endif
+#ifndef _VA_LIST_DEFINED
+#define _VA_LIST_DEFINED
+#endif
+#ifndef _VA_LIST_T_H
+#define _VA_LIST_T_H
+#endif
+#ifndef __va_list__
+#define __va_list__
+#endif
+
+#endif /* not _VA_LIST_, except on certain systems */
+
+#endif /* not __svr4__ */
+
+#endif /* _STDARG_H */
+
+#endif /* not _ANSI_STDARG_H_ */
+#endif /* not _STDARG_H */
diff --git a/gccinclude/sparc/stdbool.h b/gccinclude/sparc/stdbool.h
new file mode 100644 (file)
index 0000000..b36e650
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/*
+ * ISO C Standard:  7.16  Boolean type and values  <stdbool.h>
+ */
+
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+#ifndef __cplusplus
+
+#define bool   _Bool
+#define true   1
+#define false  0
+
+#else /* __cplusplus */
+
+/* Supporting <stdbool.h> in C++ is a GCC extension.  */
+#define _Bool  bool
+#define bool   bool
+#define false  false
+#define true   true
+
+#endif /* __cplusplus */
+
+/* Signal that all the definitions are present.  */
+#define __bool_true_false_are_defined  1
+
+#endif /* stdbool.h */
diff --git a/gccinclude/sparc/stddef.h b/gccinclude/sparc/stddef.h
new file mode 100644 (file)
index 0000000..2bab2c2
--- /dev/null
@@ -0,0 +1,421 @@
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2002, 2004
+   Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/*
+ * ISO C Standard:  7.17  Common definitions  <stddef.h>
+ */
+#if (!defined(_STDDEF_H) && !defined(_STDDEF_H_) && !defined(_ANSI_STDDEF_H) \
+     && !defined(__STDDEF_H__)) \
+    || defined(__need_wchar_t) || defined(__need_size_t) \
+    || defined(__need_ptrdiff_t) || defined(__need_NULL) \
+    || defined(__need_wint_t)
+
+/* Any one of these symbols __need_* means that GNU libc
+   wants us just to define one data type.  So don't define
+   the symbols that indicate this file's entire job has been done.  */
+#if (!defined(__need_wchar_t) && !defined(__need_size_t)       \
+     && !defined(__need_ptrdiff_t) && !defined(__need_NULL)    \
+     && !defined(__need_wint_t))
+#define _STDDEF_H
+#define _STDDEF_H_
+/* snaroff@next.com says the NeXT needs this.  */
+#define _ANSI_STDDEF_H
+/* Irix 5.1 needs this.  */
+#define __STDDEF_H__
+#endif
+
+#ifndef __sys_stdtypes_h
+/* This avoids lossage on SunOS but only if stdtypes.h comes first.
+   There's no way to win with the other order!  Sun lossage.  */
+
+/* On 4.3bsd-net2, make sure ansi.h is included, so we have
+   one less case to deal with in the following.  */
+#if defined (__BSD_NET2__) || defined (____386BSD____) || (defined (__FreeBSD__) && (__FreeBSD__ < 5)) || defined(__NetBSD__)
+#include <machine/ansi.h>
+#endif
+/* On FreeBSD 5, machine/ansi.h does not exist anymore... */
+#if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
+#include <sys/_types.h>
+#endif
+
+/* In 4.3bsd-net2, machine/ansi.h defines these symbols, which are
+   defined if the corresponding type is *not* defined.
+   FreeBSD-2.1 defines _MACHINE_ANSI_H_ instead of _ANSI_H_ */
+#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_)
+#if !defined(_SIZE_T_) && !defined(_BSD_SIZE_T_)
+#define _SIZE_T
+#endif
+#if !defined(_PTRDIFF_T_) && !defined(_BSD_PTRDIFF_T_)
+#define _PTRDIFF_T
+#endif
+/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
+   instead of _WCHAR_T_. */
+#if !defined(_WCHAR_T_) && !defined(_BSD_WCHAR_T_)
+#ifndef _BSD_WCHAR_T_
+#define _WCHAR_T
+#endif
+#endif
+/* Undef _FOO_T_ if we are supposed to define foo_t.  */
+#if defined (__need_ptrdiff_t) || defined (_STDDEF_H_)
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#if defined (__need_size_t) || defined (_STDDEF_H_)
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#if defined (__need_wchar_t) || defined (_STDDEF_H_)
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+#endif /* defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) */
+
+/* Sequent's header files use _PTRDIFF_T_ in some conflicting way.
+   Just ignore it.  */
+#if defined (__sequent__) && defined (_PTRDIFF_T_)
+#undef _PTRDIFF_T_
+#endif
+
+/* On VxWorks, <type/vxTypesBase.h> may have defined macros like
+   _TYPE_size_t which will typedef size_t.  fixincludes patched the
+   vxTypesBase.h so that this macro is only defined if _GCC_SIZE_T is
+   not defined, and so that defining this macro defines _GCC_SIZE_T.
+   If we find that the macros are still defined at this point, we must
+   invoke them so that the type is defined as expected.  */
+#if defined (_TYPE_ptrdiff_t) && (defined (__need_ptrdiff_t) || defined (_STDDEF_H_))
+_TYPE_ptrdiff_t;
+#undef _TYPE_ptrdiff_t
+#endif
+#if defined (_TYPE_size_t) && (defined (__need_size_t) || defined (_STDDEF_H_))
+_TYPE_size_t;
+#undef _TYPE_size_t
+#endif
+#if defined (_TYPE_wchar_t) && (defined (__need_wchar_t) || defined (_STDDEF_H_))
+_TYPE_wchar_t;
+#undef _TYPE_wchar_t
+#endif
+
+/* In case nobody has defined these types, but we aren't running under
+   GCC 2.00, make sure that __PTRDIFF_TYPE__, __SIZE_TYPE__, and
+   __WCHAR_TYPE__ have reasonable values.  This can happen if the
+   parts of GCC is compiled by an older compiler, that actually
+   include gstddef.h, such as collect2.  */
+
+/* Signed type of difference of two pointers.  */
+
+/* Define this type if we are doing the whole job,
+   or if we want this type in particular.  */
+#if defined (_STDDEF_H) || defined (__need_ptrdiff_t)
+#ifndef _PTRDIFF_T     /* in case <sys/types.h> has defined it. */
+#ifndef _T_PTRDIFF_
+#ifndef _T_PTRDIFF
+#ifndef __PTRDIFF_T
+#ifndef _PTRDIFF_T_
+#ifndef _BSD_PTRDIFF_T_
+#ifndef ___int_ptrdiff_t_h
+#ifndef _GCC_PTRDIFF_T
+#define _PTRDIFF_T
+#define _T_PTRDIFF_
+#define _T_PTRDIFF
+#define __PTRDIFF_T
+#define _PTRDIFF_T_
+#define _BSD_PTRDIFF_T_
+#define ___int_ptrdiff_t_h
+#define _GCC_PTRDIFF_T
+#ifndef __PTRDIFF_TYPE__
+#define __PTRDIFF_TYPE__ long int
+#endif
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#endif /* _GCC_PTRDIFF_T */
+#endif /* ___int_ptrdiff_t_h */
+#endif /* _BSD_PTRDIFF_T_ */
+#endif /* _PTRDIFF_T_ */
+#endif /* __PTRDIFF_T */
+#endif /* _T_PTRDIFF */
+#endif /* _T_PTRDIFF_ */
+#endif /* _PTRDIFF_T */
+
+/* If this symbol has done its job, get rid of it.  */
+#undef __need_ptrdiff_t
+
+#endif /* _STDDEF_H or __need_ptrdiff_t.  */
+
+/* Unsigned type of `sizeof' something.  */
+
+/* Define this type if we are doing the whole job,
+   or if we want this type in particular.  */
+#if defined (_STDDEF_H) || defined (__need_size_t)
+#ifndef __size_t__     /* BeOS */
+#ifndef __SIZE_T__     /* Cray Unicos/Mk */
+#ifndef _SIZE_T        /* in case <sys/types.h> has defined it. */
+#ifndef _SYS_SIZE_T_H
+#ifndef _T_SIZE_
+#ifndef _T_SIZE
+#ifndef __SIZE_T
+#ifndef _SIZE_T_
+#ifndef _BSD_SIZE_T_
+#ifndef _SIZE_T_DEFINED_
+#ifndef _SIZE_T_DEFINED
+#ifndef _BSD_SIZE_T_DEFINED_   /* Darwin */
+#ifndef _SIZE_T_DECLARED       /* FreeBSD 5 */
+#ifndef ___int_size_t_h
+#ifndef _GCC_SIZE_T
+#ifndef _SIZET_
+#ifndef __size_t
+#define __size_t__     /* BeOS */
+#define __SIZE_T__     /* Cray Unicos/Mk */
+#define _SIZE_T
+#define _SYS_SIZE_T_H
+#define _T_SIZE_
+#define _T_SIZE
+#define __SIZE_T
+#define _SIZE_T_
+#define _BSD_SIZE_T_
+#define _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED
+#define _BSD_SIZE_T_DEFINED_   /* Darwin */
+#define _SIZE_T_DECLARED       /* FreeBSD 5 */
+#define ___int_size_t_h
+#define _GCC_SIZE_T
+#define _SIZET_
+#if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
+/* __size_t is a typedef on FreeBSD 5!, must not trash it. */
+#else
+#define __size_t
+#endif
+#ifndef __SIZE_TYPE__
+#define __SIZE_TYPE__ long unsigned int
+#endif
+#if !(defined (__GNUG__) && defined (size_t))
+typedef __SIZE_TYPE__ size_t;
+#ifdef __BEOS__
+typedef long ssize_t;
+#endif /* __BEOS__ */
+#endif /* !(defined (__GNUG__) && defined (size_t)) */
+#endif /* __size_t */
+#endif /* _SIZET_ */
+#endif /* _GCC_SIZE_T */
+#endif /* ___int_size_t_h */
+#endif /* _SIZE_T_DECLARED */
+#endif /* _BSD_SIZE_T_DEFINED_ */
+#endif /* _SIZE_T_DEFINED */
+#endif /* _SIZE_T_DEFINED_ */
+#endif /* _BSD_SIZE_T_ */
+#endif /* _SIZE_T_ */
+#endif /* __SIZE_T */
+#endif /* _T_SIZE */
+#endif /* _T_SIZE_ */
+#endif /* _SYS_SIZE_T_H */
+#endif /* _SIZE_T */
+#endif /* __SIZE_T__ */
+#endif /* __size_t__ */
+#undef __need_size_t
+#endif /* _STDDEF_H or __need_size_t.  */
+
+
+/* Wide character type.
+   Locale-writers should change this as necessary to
+   be big enough to hold unique values not between 0 and 127,
+   and not (wchar_t) -1, for each defined multibyte character.  */
+
+/* Define this type if we are doing the whole job,
+   or if we want this type in particular.  */
+#if defined (_STDDEF_H) || defined (__need_wchar_t)
+#ifndef __wchar_t__    /* BeOS */
+#ifndef __WCHAR_T__    /* Cray Unicos/Mk */
+#ifndef _WCHAR_T
+#ifndef _T_WCHAR_
+#ifndef _T_WCHAR
+#ifndef __WCHAR_T
+#ifndef _WCHAR_T_
+#ifndef _BSD_WCHAR_T_
+#ifndef _BSD_WCHAR_T_DEFINED_    /* Darwin */
+#ifndef _BSD_RUNE_T_DEFINED_   /* Darwin */
+#ifndef _WCHAR_T_DECLARED /* FreeBSD 5 */
+#ifndef _WCHAR_T_DEFINED_
+#ifndef _WCHAR_T_DEFINED
+#ifndef _WCHAR_T_H
+#ifndef ___int_wchar_t_h
+#ifndef __INT_WCHAR_T_H
+#ifndef _GCC_WCHAR_T
+#define __wchar_t__    /* BeOS */
+#define __WCHAR_T__    /* Cray Unicos/Mk */
+#define _WCHAR_T
+#define _T_WCHAR_
+#define _T_WCHAR
+#define __WCHAR_T
+#define _WCHAR_T_
+#define _BSD_WCHAR_T_
+#define _WCHAR_T_DEFINED_
+#define _WCHAR_T_DEFINED
+#define _WCHAR_T_H
+#define ___int_wchar_t_h
+#define __INT_WCHAR_T_H
+#define _GCC_WCHAR_T
+#define _WCHAR_T_DECLARED
+
+/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
+   instead of _WCHAR_T_, and _BSD_RUNE_T_ (which, unlike the other
+   symbols in the _FOO_T_ family, stays defined even after its
+   corresponding type is defined).  If we define wchar_t, then we
+   must undef _WCHAR_T_; for BSD/386 1.1 (and perhaps others), if
+   we undef _WCHAR_T_, then we must also define rune_t, since 
+   headers like runetype.h assume that if machine/ansi.h is included,
+   and _BSD_WCHAR_T_ is not defined, then rune_t is available.
+   machine/ansi.h says, "Note that _WCHAR_T_ and _RUNE_T_ must be of
+   the same type." */
+#ifdef _BSD_WCHAR_T_
+#undef _BSD_WCHAR_T_
+#ifdef _BSD_RUNE_T_
+#if !defined (_ANSI_SOURCE) && !defined (_POSIX_SOURCE)
+typedef _BSD_RUNE_T_ rune_t;
+#define _BSD_WCHAR_T_DEFINED_
+#define _BSD_RUNE_T_DEFINED_   /* Darwin */
+#if defined (__FreeBSD__) && (__FreeBSD__ < 5)
+/* Why is this file so hard to maintain properly?  In contrast to
+   the comment above regarding BSD/386 1.1, on FreeBSD for as long
+   as the symbol has existed, _BSD_RUNE_T_ must not stay defined or
+   redundant typedefs will occur when stdlib.h is included after this file. */
+#undef _BSD_RUNE_T_
+#endif
+#endif
+#endif
+#endif
+/* FreeBSD 5 can't be handled well using "traditional" logic above
+   since it no longer defines _BSD_RUNE_T_ yet still desires to export
+   rune_t in some cases... */
+#if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
+#if !defined (_ANSI_SOURCE) && !defined (_POSIX_SOURCE)
+#if __BSD_VISIBLE
+#ifndef _RUNE_T_DECLARED
+typedef __rune_t        rune_t;
+#define _RUNE_T_DECLARED
+#endif
+#endif
+#endif
+#endif
+
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ int
+#endif
+#ifndef __cplusplus
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif /* _WCHAR_T_DECLARED */
+#endif /* _BSD_RUNE_T_DEFINED_ */
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif /* __WCHAR_T__ */
+#endif /* __wchar_t__ */
+#undef __need_wchar_t
+#endif /* _STDDEF_H or __need_wchar_t.  */
+
+#if defined (__need_wint_t)
+#ifndef _WINT_T
+#define _WINT_T
+
+#ifndef __WINT_TYPE__
+#define __WINT_TYPE__ unsigned int
+#endif
+typedef __WINT_TYPE__ wint_t;
+#endif
+#undef __need_wint_t
+#endif
+
+/*  In 4.3bsd-net2, leave these undefined to indicate that size_t, etc.
+    are already defined.  */
+/*  BSD/OS 3.1 and FreeBSD [23].x require the MACHINE_ANSI_H check here.  */
+#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_)
+/*  The references to _GCC_PTRDIFF_T_, _GCC_SIZE_T_, and _GCC_WCHAR_T_
+    are probably typos and should be removed before 2.8 is released.  */
+#ifdef _GCC_PTRDIFF_T_
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#ifdef _GCC_SIZE_T_
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#ifdef _GCC_WCHAR_T_
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+/*  The following ones are the real ones.  */
+#ifdef _GCC_PTRDIFF_T
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#ifdef _GCC_SIZE_T
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#ifdef _GCC_WCHAR_T
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+#endif /* _ANSI_H_ || _MACHINE_ANSI_H_ */
+
+#endif /* __sys_stdtypes_h */
+
+/* A null pointer constant.  */
+
+#if defined (_STDDEF_H) || defined (__need_NULL)
+#undef NULL            /* in case <stdio.h> has defined it. */
+#ifdef __GNUG__
+#define NULL __null
+#else   /* G++ */
+#ifndef __cplusplus
+#define NULL ((void *)0)
+#else   /* C++ */
+#define NULL 0
+#endif  /* C++ */
+#endif  /* G++ */
+#endif /* NULL not defined and <stddef.h> or need NULL.  */
+#undef __need_NULL
+
+#ifdef _STDDEF_H
+
+/* Offset of member MEMBER in a struct of type TYPE. */
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#endif
+
+#endif /* _STDDEF_H was defined this time */
+
+#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__
+         || __need_XXX was not defined before */
diff --git a/gccinclude/sparc/stdfix.h b/gccinclude/sparc/stdfix.h
new file mode 100644 (file)
index 0000000..5e7cb2e
--- /dev/null
@@ -0,0 +1,207 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/* ISO/IEC JTC1 SC22 WG14 N1169
+ * Date: 2006-04-04
+ * ISO/IEC TR 18037
+ * Programming languages - C - Extensions to support embedded processors
+ */
+
+#ifndef _STDFIX_H
+#define _STDFIX_H
+
+/* 7.18a.1 Introduction.  */
+
+#undef fract
+#undef accum
+#undef sat
+#define fract          _Fract
+#define accum          _Accum
+#define sat            _Sat
+
+/* 7.18a.3 Precision macros.  */
+
+#undef SFRACT_FBIT
+#undef SFRACT_MIN
+#undef SFRACT_MAX
+#undef SFRACT_EPSILON
+#define SFRACT_FBIT    __SFRACT_FBIT__
+#define SFRACT_MIN     __SFRACT_MIN__
+#define SFRACT_MAX     __SFRACT_MAX__
+#define SFRACT_EPSILON __SFRACT_EPSILON__
+
+#undef USFRACT_FBIT
+#undef USFRACT_MIN
+#undef USFRACT_MAX
+#undef USFRACT_EPSILON
+#define USFRACT_FBIT   __USFRACT_FBIT__
+#define USFRACT_MIN    __USFRACT_MIN__         /* GCC extension.  */
+#define USFRACT_MAX    __USFRACT_MAX__
+#define USFRACT_EPSILON        __USFRACT_EPSILON__
+
+#undef FRACT_FBIT
+#undef FRACT_MIN
+#undef FRACT_MAX
+#undef FRACT_EPSILON
+#define FRACT_FBIT     __FRACT_FBIT__
+#define FRACT_MIN      __FRACT_MIN__
+#define FRACT_MAX      __FRACT_MAX__
+#define FRACT_EPSILON  __FRACT_EPSILON__
+
+#undef UFRACT_FBIT
+#undef UFRACT_MIN
+#undef UFRACT_MAX
+#undef UFRACT_EPSILON
+#define UFRACT_FBIT    __UFRACT_FBIT__
+#define UFRACT_MIN     __UFRACT_MIN__          /* GCC extension.  */
+#define UFRACT_MAX     __UFRACT_MAX__
+#define UFRACT_EPSILON __UFRACT_EPSILON__
+
+#undef LFRACT_FBIT
+#undef LFRACT_MIN
+#undef LFRACT_MAX
+#undef LFRACT_EPSILON
+#define LFRACT_FBIT    __LFRACT_FBIT__
+#define LFRACT_MIN     __LFRACT_MIN__
+#define LFRACT_MAX     __LFRACT_MAX__
+#define LFRACT_EPSILON __LFRACT_EPSILON__
+
+#undef ULFRACT_FBIT
+#undef ULFRACT_MIN
+#undef ULFRACT_MAX
+#undef ULFRACT_EPSILON
+#define ULFRACT_FBIT   __ULFRACT_FBIT__
+#define ULFRACT_MIN    __ULFRACT_MIN__         /* GCC extension.  */
+#define ULFRACT_MAX    __ULFRACT_MAX__
+#define ULFRACT_EPSILON        __ULFRACT_EPSILON__
+
+#undef LLFRACT_FBIT
+#undef LLFRACT_MIN
+#undef LLFRACT_MAX
+#undef LLFRACT_EPSILON
+#define LLFRACT_FBIT   __LLFRACT_FBIT__        /* GCC extension.  */
+#define LLFRACT_MIN    __LLFRACT_MIN__         /* GCC extension.  */
+#define LLFRACT_MAX    __LLFRACT_MAX__         /* GCC extension.  */
+#define LLFRACT_EPSILON        __LLFRACT_EPSILON__     /* GCC extension.  */
+
+#undef ULLFRACT_FBIT
+#undef ULLFRACT_MIN
+#undef ULLFRACT_MAX
+#undef ULLFRACT_EPSILON
+#define ULLFRACT_FBIT  __ULLFRACT_FBIT__       /* GCC extension.  */
+#define ULLFRACT_MIN   __ULLFRACT_MIN__        /* GCC extension.  */
+#define ULLFRACT_MAX   __ULLFRACT_MAX__        /* GCC extension.  */
+#define ULLFRACT_EPSILON       __ULLFRACT_EPSILON__    /* GCC extension.  */
+
+#undef SACCUM_FBIT
+#undef SACCUM_IBIT
+#undef SACCUM_MIN
+#undef SACCUM_MAX
+#undef SACCUM_EPSILON
+#define SACCUM_FBIT    __SACCUM_FBIT__
+#define SACCUM_IBIT    __SACCUM_IBIT__
+#define SACCUM_MIN     __SACCUM_MIN__
+#define SACCUM_MAX     __SACCUM_MAX__
+#define SACCUM_EPSILON __SACCUM_EPSILON__
+
+#undef USACCUM_FBIT
+#undef USACCUM_IBIT
+#undef USACCUM_MIN
+#undef USACCUM_MAX
+#undef USACCUM_EPSILON
+#define USACCUM_FBIT   __USACCUM_FBIT__
+#define USACCUM_IBIT   __USACCUM_IBIT__
+#define USACCUM_MIN    __USACCUM_MIN__         /* GCC extension.  */
+#define USACCUM_MAX    __USACCUM_MAX__
+#define USACCUM_EPSILON        __USACCUM_EPSILON__
+
+#undef ACCUM_FBIT
+#undef ACCUM_IBIT
+#undef ACCUM_MIN
+#undef ACCUM_MAX
+#undef ACCUM_EPSILON
+#define ACCUM_FBIT     __ACCUM_FBIT__
+#define ACCUM_IBIT     __ACCUM_IBIT__
+#define ACCUM_MIN      __ACCUM_MIN__
+#define ACCUM_MAX      __ACCUM_MAX__
+#define ACCUM_EPSILON  __ACCUM_EPSILON__
+
+#undef UACCUM_FBIT
+#undef UACCUM_IBIT
+#undef UACCUM_MIN
+#undef UACCUM_MAX
+#undef UACCUM_EPSILON
+#define UACCUM_FBIT    __UACCUM_FBIT__
+#define UACCUM_IBIT    __UACCUM_IBIT__
+#define UACCUM_MIN     __UACCUM_MIN__          /* GCC extension.  */
+#define UACCUM_MAX     __UACCUM_MAX__
+#define UACCUM_EPSILON __UACCUM_EPSILON__
+
+#undef LACCUM_FBIT
+#undef LACCUM_IBIT
+#undef LACCUM_MIN
+#undef LACCUM_MAX
+#undef LACCUM_EPSILON
+#define LACCUM_FBIT    __LACCUM_FBIT__
+#define LACCUM_IBIT    __LACCUM_IBIT__
+#define LACCUM_MIN     __LACCUM_MIN__
+#define LACCUM_MAX     __LACCUM_MAX__
+#define LACCUM_EPSILON __LACCUM_EPSILON__
+
+#undef ULACCUM_FBIT
+#undef ULACCUM_IBIT
+#undef ULACCUM_MIN
+#undef ULACCUM_MAX
+#undef ULACCUM_EPSILON
+#define ULACCUM_FBIT   __ULACCUM_FBIT__
+#define ULACCUM_IBIT   __ULACCUM_IBIT__
+#define ULACCUM_MIN    __ULACCUM_MIN__         /* GCC extension.  */
+#define ULACCUM_MAX    __ULACCUM_MAX__
+#define ULACCUM_EPSILON        __ULACCUM_EPSILON__
+
+#undef LLACCUM_FBIT
+#undef LLACCUM_IBIT
+#undef LLACCUM_MIN
+#undef LLACCUM_MAX
+#undef LLACCUM_EPSILON
+#define LLACCUM_FBIT   __LLACCUM_FBIT__        /* GCC extension.  */
+#define LLACCUM_IBIT   __LLACCUM_IBIT__        /* GCC extension.  */
+#define LLACCUM_MIN    __LLACCUM_MIN__         /* GCC extension.  */
+#define LLACCUM_MAX    __LLACCUM_MAX__         /* GCC extension.  */
+#define LLACCUM_EPSILON        __LLACCUM_EPSILON__     /* GCC extension.  */
+
+#undef ULLACCUM_FBIT
+#undef ULLACCUM_IBIT
+#undef ULLACCUM_MIN
+#undef ULLACCUM_MAX
+#undef ULLACCUM_EPSILON
+#define ULLACCUM_FBIT  __ULLACCUM_FBIT__       /* GCC extension.  */
+#define ULLACCUM_IBIT  __ULLACCUM_IBIT__       /* GCC extension.  */
+#define ULLACCUM_MIN   __ULLACCUM_MIN__        /* GCC extension.  */
+#define ULLACCUM_MAX   __ULLACCUM_MAX__        /* GCC extension.  */
+#define ULLACCUM_EPSILON       __ULLACCUM_EPSILON__    /* GCC extension.  */
+
+#endif /* _STDFIX_H */
diff --git a/gccinclude/sparc/tgmath.h b/gccinclude/sparc/tgmath.h
new file mode 100644 (file)
index 0000000..1c0fb37
--- /dev/null
@@ -0,0 +1,174 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Contributed by Apple, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/*
+ * ISO C Standard:  7.22  Type-generic math <tgmath.h>
+ */
+
+#ifndef _TGMATH_H
+#define _TGMATH_H
+
+#include <math.h>
+
+#ifndef __cplusplus
+#include <complex.h>
+
+/* Naming convention: generic macros are defining using
+   __TGMATH_CPLX*, __TGMATH_REAL*, and __TGMATH_CPLX_ONLY.  _CPLX
+   means the generic argument(s) may be real or complex, _REAL means
+   real only, _CPLX means complex only.  If there is no suffix, we are
+   defining a function of one generic argument.  If the suffix is _n
+   it is a function of n generic arguments.  If the suffix is _m_n it
+   is a function of n arguments, the first m of which are generic.  We
+   only define these macros for values of n and/or m that are needed. */
+
+/* The general rules for generic macros are given in 7.22 paragraphs 1 and 2.
+   If any generic parameter is complex, we use a complex version.  Otherwise
+   we use a real version.  If the real part of any generic parameter is long
+   double, we use the long double version.  Otherwise if the real part of any
+   generic parameter is double or of integer type, we use the double version.
+   Otherwise we use the float version. */
+
+#define __tg_cplx(expr) \
+  __builtin_classify_type(expr) == 9
+
+#define __tg_ldbl(expr) \
+  __builtin_types_compatible_p(__typeof__(expr), long double)
+
+#define __tg_dbl(expr)                                       \
+  (__builtin_types_compatible_p(__typeof__(expr), double)    \
+   || __builtin_classify_type(expr) == 1)
+
+#define __tg_choose(x,f,d,l)                                  \
+  __builtin_choose_expr(__tg_ldbl(x), l,                      \
+                        __builtin_choose_expr(__tg_dbl(x), d, \
+                                              f))
+
+#define __tg_choose_2(x,y,f,d,l)                                             \
+  __builtin_choose_expr(__tg_ldbl(x) || __tg_ldbl(y), l,                     \
+                        __builtin_choose_expr(__tg_dbl(x) || __tg_dbl(y), d, \
+                                              f))
+
+#define __tg_choose_3(x,y,z,f,d,l)                                        \
+   __builtin_choose_expr(__tg_ldbl(x) || __tg_ldbl(y) || __tg_ldbl(z), l, \
+                        __builtin_choose_expr(__tg_dbl(x) || __tg_dbl(y)  \
+                                              || __tg_dbl(z), d,          \
+                                              f))
+
+#define __TGMATH_CPLX(z,R,C)                                                  \
+  __builtin_choose_expr (__tg_cplx(z),                                        \
+                         __tg_choose (__real__(z), C##f(z), (C)(z), C##l(z)), \
+                         __tg_choose (z, R##f(z), (R)(z), R##l(z)))
+
+#define __TGMATH_CPLX_2(z1,z2,R,C)                                             \
+  __builtin_choose_expr (__tg_cplx(z1) || __tg_cplx(z2),                       \
+                         __tg_choose_2 (__real__(z1), __real__(z2),            \
+                                        C##f(z1,z2), (C)(z1,z2), C##l(z1,z2)), \
+                         __tg_choose_2 (z1, z2,                                \
+                                        R##f(z1,z2), (R)(z1,z2), R##l(z1,z2)))
+
+#define __TGMATH_REAL(x,R) \
+  __tg_choose (x, R##f(x), (R)(x), R##l(x))
+#define __TGMATH_REAL_2(x,y,R) \
+  __tg_choose_2 (x, y, R##f(x,y), (R)(x,y), R##l(x,y))
+#define __TGMATH_REAL_3(x,y,z,R) \
+  __tg_choose_3 (x, y, z, R##f(x,y,z), (R)(x,y,z), R##l(x,y,z))
+#define __TGMATH_REAL_1_2(x,y,R) \
+  __tg_choose (x, R##f(x,y), (R)(x,y), R##l(x,y))
+#define __TGMATH_REAL_2_3(x,y,z,R) \
+  __tg_choose_2 (x, y, R##f(x,y,z), (R)(x,y,z), R##l(x,y,z))
+#define __TGMATH_CPLX_ONLY(z,C) \
+  __tg_choose (__real__(z), C##f(z), (C)(z), C##l(z))
+
+/* Functions defined in both <math.h> and <complex.h> (7.22p4) */
+#define acos(z)          __TGMATH_CPLX(z, acos, cacos)
+#define asin(z)          __TGMATH_CPLX(z, asin, casin)
+#define atan(z)          __TGMATH_CPLX(z, atan, catan)
+#define acosh(z)         __TGMATH_CPLX(z, acosh, cacosh)
+#define asinh(z)         __TGMATH_CPLX(z, asinh, casinh)
+#define atanh(z)         __TGMATH_CPLX(z, atanh, catanh)
+#define cos(z)           __TGMATH_CPLX(z, cos, ccos)
+#define sin(z)           __TGMATH_CPLX(z, sin, csin)
+#define tan(z)           __TGMATH_CPLX(z, tan, ctan)
+#define cosh(z)          __TGMATH_CPLX(z, cosh, ccosh)
+#define sinh(z)          __TGMATH_CPLX(z, sinh, csinh)
+#define tanh(z)          __TGMATH_CPLX(z, tanh, ctanh)
+#define exp(z)           __TGMATH_CPLX(z, exp, cexp)
+#define log(z)           __TGMATH_CPLX(z, log, clog)
+#define pow(z1,z2)       __TGMATH_CPLX_2(z1, z2, pow, cpow)
+#define sqrt(z)          __TGMATH_CPLX(z, sqrt, csqrt)
+#define fabs(z)          __TGMATH_CPLX(z, fabs, cabs)
+
+/* Functions defined in <math.h> only (7.22p5) */
+#define atan2(x,y)       __TGMATH_REAL_2(x, y, atan2)
+#define cbrt(x)          __TGMATH_REAL(x, cbrt)
+#define ceil(x)          __TGMATH_REAL(x, ceil)
+#define copysign(x,y)    __TGMATH_REAL_2(x, y, copysign)
+#define erf(x)           __TGMATH_REAL(x, erf)
+#define erfc(x)          __TGMATH_REAL(x, erfc)
+#define exp2(x)          __TGMATH_REAL(x, exp2)
+#define expm1(x)         __TGMATH_REAL(x, expm1)
+#define fdim(x,y)        __TGMATH_REAL_2(x, y, fdim)
+#define floor(x)         __TGMATH_REAL(x, floor)
+#define fma(x,y,z)       __TGMATH_REAL_3(x, y, z, fma)
+#define fmax(x,y)        __TGMATH_REAL_2(x, y, fmax)
+#define fmin(x,y)        __TGMATH_REAL_2(x, y, fmin)
+#define fmod(x,y)        __TGMATH_REAL_2(x, y, fmod)
+#define frexp(x,y)       __TGMATH_REAL_1_2(x, y, frexp)
+#define hypot(x,y)       __TGMATH_REAL_2(x, y, hypot)
+#define ilogb(x)         __TGMATH_REAL(x, ilogb)
+#define ldexp(x,y)       __TGMATH_REAL_1_2(x, y, ldexp)
+#define lgamma(x)        __TGMATH_REAL(x, lgamma)
+#define llrint(x)        __TGMATH_REAL(x, llrint)
+#define llround(x)       __TGMATH_REAL(x, llround)
+#define log10(x)         __TGMATH_REAL(x, log10)
+#define log1p(x)         __TGMATH_REAL(x, log1p)
+#define log2(x)          __TGMATH_REAL(x, log2)
+#define logb(x)          __TGMATH_REAL(x, logb)
+#define lrint(x)         __TGMATH_REAL(x, lrint)
+#define lround(x)        __TGMATH_REAL(x, lround)
+#define nearbyint(x)     __TGMATH_REAL(x, nearbyint)
+#define nextafter(x,y)   __TGMATH_REAL_2(x, y, nextafter)
+#define nexttoward(x,y)  __TGMATH_REAL_1_2(x, y, nexttoward)
+#define remainder(x,y)   __TGMATH_REAL_2(x, y, remainder)
+#define remquo(x,y,z)    __TGMATH_REAL_2_3(x, y, z, remquo)
+#define rint(x)          __TGMATH_REAL(x, rint)
+#define round(x)         __TGMATH_REAL(x, round)
+#define scalbn(x,y)      __TGMATH_REAL_1_2(x, y, scalbn)
+#define scalbln(x,y)     __TGMATH_REAL_1_2(x, y, scalbln)
+#define tgamma(x)        __TGMATH_REAL(x, tgamma)
+#define trunc(x)         __TGMATH_REAL(x, trunc)
+
+/* Functions defined in <complex.h> only (7.22p6) */
+#define carg(z)          __TGMATH_CPLX_ONLY(z, carg)
+#define cimag(z)         __TGMATH_CPLX_ONLY(z, cimag)
+#define conj(z)          __TGMATH_CPLX_ONLY(z, conj)
+#define cproj(z)         __TGMATH_CPLX_ONLY(z, cproj)
+#define creal(z)         __TGMATH_CPLX_ONLY(z, creal)
+
+#endif /* __cplusplus */
+#endif /* _TGMATH_H */
diff --git a/gccinclude/sparc/unwind.h b/gccinclude/sparc/unwind.h
new file mode 100644 (file)
index 0000000..5e0f608
--- /dev/null
@@ -0,0 +1,279 @@
+/* Exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC 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.
+
+   GCC 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 GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
+
+/* This is derived from the C++ ABI for IA-64.  Where we diverge
+   for cross-architecture compatibility are noted with "@@@".  */
+
+#ifndef _UNWIND_H
+#define _UNWIND_H
+
+#ifndef HIDE_EXPORTS
+#pragma GCC visibility push(default)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Level 1: Base ABI  */
+
+/* @@@ The IA-64 ABI uses uint64 throughout.  Most places this is
+   inefficient for 32-bit and smaller machines.  */
+typedef unsigned _Unwind_Word __attribute__((__mode__(__unwind_word__)));
+typedef signed _Unwind_Sword __attribute__((__mode__(__unwind_word__)));
+#if defined(__ia64__) && defined(__hpux__)
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
+#else
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
+#endif
+typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
+
+/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
+   consumer of an exception.  We'll go along with this for now even on
+   32-bit machines.  We'll need to provide some other option for
+   16-bit machines and for machines with > 8 bits per byte.  */
+typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
+
+/* The unwind interface uses reason codes in several contexts to
+   identify the reasons for failures or other actions.  */
+typedef enum
+{
+  _URC_NO_REASON = 0,
+  _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+  _URC_FATAL_PHASE2_ERROR = 2,
+  _URC_FATAL_PHASE1_ERROR = 3,
+  _URC_NORMAL_STOP = 4,
+  _URC_END_OF_STACK = 5,
+  _URC_HANDLER_FOUND = 6,
+  _URC_INSTALL_CONTEXT = 7,
+  _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+
+/* The unwind interface uses a pointer to an exception header object
+   as its representation of an exception being thrown. In general, the
+   full representation of an exception object is language- and
+   implementation-specific, but it will be prefixed by a header
+   understood by the unwind interface.  */
+
+struct _Unwind_Exception;
+
+typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
+                                             struct _Unwind_Exception *);
+
+struct _Unwind_Exception
+{
+  _Unwind_Exception_Class exception_class;
+  _Unwind_Exception_Cleanup_Fn exception_cleanup;
+  _Unwind_Word private_1;
+  _Unwind_Word private_2;
+
+  /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
+     Taking that literally does not make much sense generically.  Instead we
+     provide the maximum alignment required by any type for the machine.  */
+} __attribute__((__aligned__));
+
+
+/* The ACTIONS argument to the personality routine is a bitwise OR of one
+   or more of the following constants.  */
+typedef int _Unwind_Action;
+
+#define _UA_SEARCH_PHASE       1
+#define _UA_CLEANUP_PHASE      2
+#define _UA_HANDLER_FRAME      4
+#define _UA_FORCE_UNWIND       8
+#define _UA_END_OF_STACK       16
+
+/* The target can override this macro to define any back-end-specific
+   attributes required for the lowest-level stack frame.  */
+#ifndef LIBGCC2_UNWIND_ATTRIBUTE
+#define LIBGCC2_UNWIND_ATTRIBUTE
+#endif
+
+/* This is an opaque type used to refer to a system-specific data
+   structure used by the system unwinder. This context is created and
+   destroyed by the system, and passed to the personality routine
+   during unwinding.  */
+struct _Unwind_Context;
+
+/* Raise an exception, passing along the given exception object.  */
+extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_RaiseException (struct _Unwind_Exception *);
+
+/* Raise an exception for forced unwinding.  */
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
+     (int, _Unwind_Action, _Unwind_Exception_Class,
+      struct _Unwind_Exception *, struct _Unwind_Context *, void *);
+
+extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_ForcedUnwind (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+
+/* Helper to invoke the exception_cleanup routine.  */
+extern void _Unwind_DeleteException (struct _Unwind_Exception *);
+
+/* Resume propagation of an existing exception.  This is used after
+   e.g. executing cleanup code, and not to implement rethrowing.  */
+extern void LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_Resume (struct _Unwind_Exception *);
+
+/* @@@ Resume propagation of a FORCE_UNWIND exception, or to rethrow
+   a normal exception that was handled.  */
+extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
+
+/* @@@ Use unwind data to perform a stack backtrace.  The trace callback
+   is called for every stack frame in the call chain, but no cleanup
+   actions are performed.  */
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
+     (struct _Unwind_Context *, void *);
+
+extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_Backtrace (_Unwind_Trace_Fn, void *);
+
+/* These functions are used for communicating information about the unwind
+   context (i.e. the unwind descriptors and the user register state) between
+   the unwind library and the personality routine and landing pad.  Only
+   selected registers may be manipulated.  */
+
+extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
+extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
+
+extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
+extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
+extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
+
+/* @@@ Retrieve the CFA of the given context.  */
+extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
+
+extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
+
+extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
+
+
+/* The personality routine is the function in the C++ (or other language)
+   runtime library which serves as an interface between the system unwind
+   library and language-specific exception handling semantics.  It is
+   specific to the code fragment described by an unwind info block, and
+   it is always referenced via the pointer in the unwind info block, and
+   hence it has no ABI-specified name.
+
+   Note that this implies that two different C++ implementations can
+   use different names, and have different contents in the language
+   specific data area.  Moreover, that the language specific data
+   area contains no version info because name of the function invoked
+   provides more effective versioning by detecting at link time the
+   lack of code to handle the different data format.  */
+
+typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
+     (int, _Unwind_Action, _Unwind_Exception_Class,
+      struct _Unwind_Exception *, struct _Unwind_Context *);
+
+/* @@@ The following alternate entry points are for setjmp/longjmp
+   based unwinding.  */
+
+struct SjLj_Function_Context;
+extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
+extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
+
+extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_SjLj_RaiseException (struct _Unwind_Exception *);
+extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_SjLj_ForcedUnwind (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+extern void LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_SjLj_Resume (struct _Unwind_Exception *);
+extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
+_Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *);
+
+/* @@@ The following provide access to the base addresses for text
+   and data-relative addressing in the LDSA.  In order to stay link
+   compatible with the standard ABI for IA-64, we inline these.  */
+
+#ifdef __ia64__
+#include <stdlib.h>
+
+static inline _Unwind_Ptr
+_Unwind_GetDataRelBase (struct _Unwind_Context *_C)
+{
+  /* The GP is stored in R1.  */
+  return _Unwind_GetGR (_C, 1);
+}
+
+static inline _Unwind_Ptr
+_Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__)))
+{
+  abort ();
+  return 0;
+}
+
+/* @@@ Retrieve the Backing Store Pointer of the given context.  */
+extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *);
+#else
+extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *);
+extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
+#endif
+
+/* @@@ Given an address, return the entry point of the function that
+   contains it.  */
+extern void * _Unwind_FindEnclosingFunction (void *pc);
+
+#ifndef __SIZEOF_LONG__
+  #error "__SIZEOF_LONG__ macro not defined"
+#endif
+
+#ifndef __SIZEOF_POINTER__
+  #error "__SIZEOF_POINTER__ macro not defined"
+#endif
+
+
+/* leb128 type numbers have a potentially unlimited size.
+   The target of the following definitions of _sleb128_t and _uleb128_t
+   is to have efficient data types large enough to hold the leb128 type
+   numbers used in the unwind code.
+   Mostly these types will simply be defined to long and unsigned long
+   except when a unsigned long data type on the target machine is not
+   capable of storing a pointer.  */
+
+#if __SIZEOF_LONG__ >= __SIZEOF_POINTER__
+  typedef long _sleb128_t;
+  typedef unsigned long _uleb128_t;
+#elif __SIZEOF_LONG_LONG__ >= __SIZEOF_POINTER__
+  typedef long long _sleb128_t;
+  typedef unsigned long long _uleb128_t;
+#else
+# error "What type shall we use for _sleb128_t?"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef HIDE_EXPORTS
+#pragma GCC visibility pop
+#endif
+
+#endif /* unwind.h */
diff --git a/gccinclude/sparc/varargs.h b/gccinclude/sparc/varargs.h
new file mode 100644 (file)
index 0000000..4b9803e
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _VARARGS_H
+#define _VARARGS_H
+
+#error "GCC no longer implements <varargs.h>."
+#error "Revise your code to use <stdarg.h>."
+
+#endif
index 4f95bba..0df458c 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <arch/types.h>
 #include <arch/trap.h>
+#include <arch/frontend.h>
 
 static __inline uint32_t read_psr(void) __attribute__((always_inline));
 static __inline uint32_t read_wim(void) __attribute__((always_inline));
index 15a02a9..f170dd6 100644 (file)
@@ -36,7 +36,7 @@ timer_init(void)
 
        while(ticks == timer_ticks) ;
 
-       system_timing.tsc_freq = read_tsc() - tsc_ticks;
+       system_timing.tsc_freq = (read_tsc() - tsc_ticks)*INTERRUPT_TIMER_HZ;
 
        cprintf("TSC Frequency: %llu\n", system_timing.tsc_freq);
 }
index b0696cd..732d39b 100644 (file)
@@ -24,6 +24,7 @@ enum
        SYS_yield,
        SYS_proc_create,
        SYS_proc_run,
+       SYS_frontend,           // forward a syscall to front-end machine
 
        SYS_endofcalls //Should always be last
 };
index 724d6bf..9cd4637 100644 (file)
@@ -40,17 +40,13 @@ KERN_APPFILES := \
                  $(USER_APPS_ROSLIB_DIR)/fptest \
                  $(USER_APPS_ROSLIB_DIR)/null \
                  $(USER_APPS_ROSLIB_DIR)/spawn \
-                 $(USER_APPS_ROSLIB_DIR)/hello
-
-ifeq ($(TARGET_ARCH),i386)
-       KERN_APPFILES += \
-                        $(USER_APPS_PARLIB_DIR)/channel_test_client \
-                        $(USER_APPS_PARLIB_DIR)/channel_test_server \
-                        $(USER_APPS_ROSLIB_DIR)/measurements
-#                       $(USER_APPS_PARLIB_DIR)/draw_nanwan \
-#                       $(USER_APPS_PARLIB_DIR)/open_read \
-#                       $(USER_APPS_PARLIB_DIR)/hello
-endif
+                 $(USER_APPS_ROSLIB_DIR)/hello \
+                 $(USER_APPS_PARLIB_DIR)/channel_test_client \
+                 $(USER_APPS_PARLIB_DIR)/channel_test_server \
+                 $(USER_APPS_ROSLIB_DIR)/measurements \
+                 $(USER_APPS_PARLIB_DIR)/hello \
+                 $(USER_APPS_PARLIB_DIR)/matrix \
+#                 $(USER_APPS_PARLIB_DIR)/open_read
 
 KERN_LDFLAGS   := $(KERN_LDFLAGS) -L$(OBJDIR)/$(KERN_DIR) \
                   -T $(ARCH_DIR)/$(TARGET_ARCH)/kernel.ld
index df853fb..58997ad 100644 (file)
@@ -23,12 +23,11 @@ DECL_PROG(roslib_fptest);
 DECL_PROG(roslib_null);
 DECL_PROG(roslib_spawn);
 DECL_PROG(roslib_hello);
-
-#ifdef __i386__
+DECL_PROG(roslib_measurements);
 DECL_PROG(parlib_channel_test_client);
 DECL_PROG(parlib_channel_test_server);
-DECL_PROG(roslib_measurements);
-#endif
+DECL_PROG(parlib_matrix);
+DECL_PROG(parlib_hello);
 
 struct kfs_entry kfs[MAX_KFS_FILES] = {
        KFS_ENTRY(roslib_proctests)
@@ -36,11 +35,11 @@ struct kfs_entry kfs[MAX_KFS_FILES] = {
        KFS_ENTRY(roslib_null)
        KFS_ENTRY(roslib_spawn)
        KFS_ENTRY(roslib_hello)
-       #ifdef __i386__
+       KFS_ENTRY(roslib_measurements)
        KFS_ENTRY(parlib_channel_test_client)
        KFS_ENTRY(parlib_channel_test_server)
-       KFS_ENTRY(roslib_measurements)
-       #endif
+       KFS_ENTRY(parlib_matrix)
+       KFS_ENTRY(parlib_hello)
 };
 
 ssize_t kfs_lookup_path(char* path)
index 537e42c..92a5efc 100644 (file)
@@ -338,10 +338,6 @@ intreg_t syscall(env_t* e, uint32_t syscallno, uint32_t a1, uint32_t a2,
                        return sys_cgetc(e);
                case SYS_getcpuid:
                        return sys_getcpuid();
-               case SYS_serial_write:
-                       return sys_serial_write(e, (char *DANGEROUS)a1, (size_t)a2);
-               case SYS_serial_read:
-                       return sys_serial_read(e, (char *DANGEROUS)a1, (size_t)a2);
                case SYS_getpid:
                        return sys_getenvid(e);
                case SYS_proc_destroy:
@@ -353,6 +349,19 @@ intreg_t syscall(env_t* e, uint32_t syscallno, uint32_t a1, uint32_t a2,
                        return sys_proc_create(e, (char *DANGEROUS)a1);
                case SYS_proc_run:
                        return sys_proc_run(e, (size_t)a1);
+
+       #ifdef __i386__
+               case SYS_serial_write:
+                       return sys_serial_write(e, (char *DANGEROUS)a1, (size_t)a2);
+               case SYS_serial_read:
+                       return sys_serial_read(e, (char *DANGEROUS)a1, (size_t)a2);
+       #endif
+
+       #ifdef __sparc_v8__
+               case SYS_frontend:
+                       return frontend_syscall(a1,a2,a3,a4);
+       #endif
+
                default:
                        // or just return -EINVAL
                        panic("Invalid syscall number %d for env %x!", syscallno, *e);
index 57a7397..0596f5e 100644 (file)
@@ -4,9 +4,5 @@ USER_CFLAGS  := $(CFLAGS) -DROS_USER
 USER_LDFLAGS := $(LDFLAGS)
 
 include $(USER_DIR)/roslib/Makefrag
-
-ifeq ($(TARGET_ARCH),i386)
-       include $(USER_DIR)/parlib/Makefrag
-endif
-
+include $(USER_DIR)/parlib/Makefrag
 include $(USER_DIR)/apps/Makefrag
index 43e95fc..d456971 100644 (file)
@@ -6,14 +6,14 @@ USER_APPS_PARLIB_CFLAGS    := $(USER_CFLAGS) --nodeputy --nopatch \
                               -I$(USER_PARLIB_DIR)/inc
 
 USER_APPS_PARLIB_LDFLAGS   := $(USER_LDFLAGS) -static \
-                              -T $(USER_APPS_PARLIB_DIR)/apps.ld
+                              -T $(USER_APPS_PARLIB_DIR)/apps_$(TARGET_ARCH).ld
 
 USER_APPS_PARLIB_LDDIRS    := -L$(OBJDIR)/$(USER_PARLIB_DIR) \
                               -L$(USER_PARLIB_NEWLIB_DIR)/lib/$(TARGET_ARCH)
 
 USER_APPS_PARLIB_LDLIBS    := --start-group -lc -lm -lg -lparlib -livyparlib --end-group
 
-USER_APPS_PARLIB_LDOBJS    := $(OBJDIR)/$(USER_PARLIB_DIR)/entry_$(TARGET_ARCH).o \
+USER_APPS_PARLIB_LDOBJS    := $(OBJDIR)/$(USER_PARLIB_DIR)/$(TARGET_ARCH)/entry.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/readline.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/file_io.o \
                               $(OBJDIR)/$(USER_APPS_PARLIB_DIR)/file_error.o \
diff --git a/user/apps/parlib/apps.ld b/user/apps/parlib/apps.ld
deleted file mode 100644 (file)
index 3f64202..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Simple linker script for ROS user-level programs.
-   See the GNU ld 'info' manual ("info ld") to learn the syntax. */
-
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(_start)
-
-SECTIONS
-{
-       /* Load programs at this address: "." means the current address */
-       . = 0x800020;
-
-       .text : {
-               *(.text .stub .text.* .gnu.linkonce.t.*)
-       }
-
-       PROVIDE(_etext = .);    /* Define the 'etext' symbol to this value */
-
-       .rodata : {
-               *(.rodata .rodata.* .gnu.linkonce.r.*)
-       }
-
-       /* Adjust the address for the data segment to the next page */
-       . = ALIGN(0x1000);
-
-       .data : {
-               *(.data)
-       }
-
-       PROVIDE(_edata = .);
-
-       .bss : {
-               *(.bss)
-       }
-
-       PROVIDE(_end = .);
-
-
-       /* Place debugging symbols so that they can be found by
-        * the kernel debugger.
-        * Specifically, the four words at 0x200000 mark the beginning of
-        * the stabs, the end of the stabs, the beginning of the stabs
-        * string table, and the end of the stabs string table, respectively.
-        */
-
-       .stab_info 0x200000 : {
-               LONG(__STAB_BEGIN__);
-               LONG(__STAB_END__);
-               LONG(__STABSTR_BEGIN__);
-               LONG(__STABSTR_END__);
-       }
-
-       .stab : {
-               __STAB_BEGIN__ = DEFINED(__STAB_BEGIN__) ? __STAB_BEGIN__ : .;
-               *(.stab);
-               __STAB_END__ = DEFINED(__STAB_END__) ? __STAB_END__ : .;
-               BYTE(0)         /* Force the linker to allocate space
-                                  for this section */
-       }
-
-       .stabstr : {
-               __STABSTR_BEGIN__ = DEFINED(__STABSTR_BEGIN__) ? __STABSTR_BEGIN__ : .;
-               *(.stabstr);
-               __STABSTR_END__ = DEFINED(__STABSTR_END__) ? __STABSTR_END__ : .;
-               BYTE(0)         /* Force the linker to allocate space
-                                  for this section */
-       }
-
-       /DISCARD/ : {
-               *(.eh_frame .note.GNU-stack)
-       }
-}
diff --git a/user/apps/parlib/apps_i386.ld b/user/apps/parlib/apps_i386.ld
new file mode 100644 (file)
index 0000000..3f64202
--- /dev/null
@@ -0,0 +1,72 @@
+/* Simple linker script for ROS user-level programs.
+   See the GNU ld 'info' manual ("info ld") to learn the syntax. */
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+
+SECTIONS
+{
+       /* Load programs at this address: "." means the current address */
+       . = 0x800020;
+
+       .text : {
+               *(.text .stub .text.* .gnu.linkonce.t.*)
+       }
+
+       PROVIDE(_etext = .);    /* Define the 'etext' symbol to this value */
+
+       .rodata : {
+               *(.rodata .rodata.* .gnu.linkonce.r.*)
+       }
+
+       /* Adjust the address for the data segment to the next page */
+       . = ALIGN(0x1000);
+
+       .data : {
+               *(.data)
+       }
+
+       PROVIDE(_edata = .);
+
+       .bss : {
+               *(.bss)
+       }
+
+       PROVIDE(_end = .);
+
+
+       /* Place debugging symbols so that they can be found by
+        * the kernel debugger.
+        * Specifically, the four words at 0x200000 mark the beginning of
+        * the stabs, the end of the stabs, the beginning of the stabs
+        * string table, and the end of the stabs string table, respectively.
+        */
+
+       .stab_info 0x200000 : {
+               LONG(__STAB_BEGIN__);
+               LONG(__STAB_END__);
+               LONG(__STABSTR_BEGIN__);
+               LONG(__STABSTR_END__);
+       }
+
+       .stab : {
+               __STAB_BEGIN__ = DEFINED(__STAB_BEGIN__) ? __STAB_BEGIN__ : .;
+               *(.stab);
+               __STAB_END__ = DEFINED(__STAB_END__) ? __STAB_END__ : .;
+               BYTE(0)         /* Force the linker to allocate space
+                                  for this section */
+       }
+
+       .stabstr : {
+               __STABSTR_BEGIN__ = DEFINED(__STABSTR_BEGIN__) ? __STABSTR_BEGIN__ : .;
+               *(.stabstr);
+               __STABSTR_END__ = DEFINED(__STABSTR_END__) ? __STABSTR_END__ : .;
+               BYTE(0)         /* Force the linker to allocate space
+                                  for this section */
+       }
+
+       /DISCARD/ : {
+               *(.eh_frame .note.GNU-stack)
+       }
+}
diff --git a/user/apps/parlib/apps_sparc.ld b/user/apps/parlib/apps_sparc.ld
new file mode 100644 (file)
index 0000000..9142d7b
--- /dev/null
@@ -0,0 +1,72 @@
+/* Simple linker script for ROS user-level programs.
+   See the GNU ld 'info' manual ("info ld") to learn the syntax. */
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+
+SECTIONS
+{
+       /* Load programs at this address: "." means the current address */
+       . = 0x800020;
+
+       .text : {
+               *(.text .stub .text.* .gnu.linkonce.t.*)
+       }
+
+       PROVIDE(_etext = .);    /* Define the 'etext' symbol to this value */
+
+       .rodata : {
+               *(.rodata .rodata.* .gnu.linkonce.r.*)
+       }
+
+       /* Adjust the address for the data segment to the next page */
+       . = ALIGN(0x1000);
+
+       .data : {
+               *(.data)
+       }
+
+       PROVIDE(_edata = .);
+
+       .bss : {
+               *(.bss)
+       }
+
+       PROVIDE(_end = .);
+
+
+       /* Place debugging symbols so that they can be found by
+        * the kernel debugger.
+        * Specifically, the four words at 0x200000 mark the beginning of
+        * the stabs, the end of the stabs, the beginning of the stabs
+        * string table, and the end of the stabs string table, respectively.
+        */
+
+       .stab_info 0x200000 : {
+               LONG(__STAB_BEGIN__);
+               LONG(__STAB_END__);
+               LONG(__STABSTR_BEGIN__);
+               LONG(__STABSTR_END__);
+       }
+
+       .stab : {
+               __STAB_BEGIN__ = DEFINED(__STAB_BEGIN__) ? __STAB_BEGIN__ : .;
+               *(.stab);
+               __STAB_END__ = DEFINED(__STAB_END__) ? __STAB_END__ : .;
+               BYTE(0)         /* Force the linker to allocate space
+                                  for this section */
+       }
+
+       .stabstr : {
+               __STABSTR_BEGIN__ = DEFINED(__STABSTR_BEGIN__) ? __STABSTR_BEGIN__ : .;
+               *(.stabstr);
+               __STABSTR_END__ = DEFINED(__STABSTR_END__) ? __STABSTR_END__ : .;
+               BYTE(0)         /* Force the linker to allocate space
+                                  for this section */
+       }
+
+       /DISCARD/ : {
+               *(.eh_frame .note.GNU-stack)
+       }
+}
index 2ee6686..cbe98f2 100644 (file)
@@ -27,7 +27,7 @@ int main(int argc, char** argv)
 {      
        set_default_user();
        printf("Welcome to the Tessellation OS newlib test suite!\n");
-       printf("Enter at you're own risk....\n");
+       printf("Enter at your own risk....\n");
        clrscrn(2);
        while(1) {
                char* s = readline(prompt);
index b5120cc..f4c45b9 100644 (file)
@@ -5,14 +5,14 @@ USER_PARLIB_SRC_CFLAGS   := $(USER_CFLAGS) --nopatch \
                             -I$(USER_PARLIB_DIR)/inc \
                             -I$(USER_PARLIB_NEWLIB_DIR)/include
 
-USER_PARLIB_SRC_SRCFILES := $(USER_PARLIB_SRC_DIR)/newlib_backend.c \
-                            $(USER_PARLIB_SRC_DIR)/debug.c \
+USER_PARLIB_SRC_SRCFILES := $(USER_PARLIB_SRC_DIR)/debug.c \
                             $(USER_PARLIB_SRC_DIR)/debugfmt.c \
                             $(USER_PARLIB_SRC_DIR)/syscall.c \
-                            $(USER_PARLIB_SRC_DIR)/syscall_$(TARGET_ARCH).c \
                             $(USER_PARLIB_SRC_DIR)/parlibmain.c \
                             $(USER_PARLIB_SRC_DIR)/channel.c \
-                            $(USER_PARLIB_SRC_DIR)/entry_$(TARGET_ARCH).S  
+                            $(USER_PARLIB_SRC_DIR)/$(TARGET_ARCH)/syscall.c \
+                            $(USER_PARLIB_SRC_DIR)/$(TARGET_ARCH)/entry.S \
+                            $(USER_PARLIB_SRC_DIR)/$(TARGET_ARCH)/newlib_backend.c
 
 USER_PARLIB_SRC_OBJFILES := $(patsubst $(USER_PARLIB_SRC_DIR)/%.c, \
                             $(OBJDIR)/$(USER_PARLIB_DIR)/%.o, \
diff --git a/user/parlib/src/entry_i386.S b/user/parlib/src/entry_i386.S
deleted file mode 100644 (file)
index aa6e18e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <arch/mmu.h>
-#include <ros/memlayout.h>
-
-.data
-
-
-// Define the global symbols 'envs', 'pages', 'vpt', and 'vpd'
-// so that they can be used in C as if they were ordinary global arrays.
-       .globl procinfo
-       .set procinfo, UINFO
-       .globl procdata
-       .set procdata, USYSCALL
-       .globl pages
-       .set pages, UPAGES
-       .globl vpt
-       .set vpt, UVPT
-       .globl vpd
-       .set vpd, (UVPT+(UVPT>>12)*4)
-
-
-// Entrypoint - this is where the kernel (or our parent environment)
-// starts us running when we are initially loaded into a new environment.
-.text
-.globl _start
-_start:
-       // See if we were started with arguments on the stack
-       cmpl $USTACKTOP, %esp
-       jne args_exist
-
-       // If not, push dummy argc/argv arguments.
-       // This happens when we are loaded by the kernel,
-       // because the kernel does not know about passing arguments.
-       pushl $0
-       pushl $0
-
-args_exist:
-       call parlibmain
-1:      jmp 1b
-
diff --git a/user/parlib/src/entry_sparc.S b/user/parlib/src/entry_sparc.S
deleted file mode 100644 (file)
index 0ae2bcf..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#include <arch/mmu.h>
-#include <ros/memlayout.h>
-
-.data
-
-
-// Define the global symbols 'envs', 'pages', 'vpt', and 'vpd'
-// so that they can be used in C as if they were ordinary global arrays.
-       .globl procinfo
-       .set procinfo, UINFO
-       .globl procdata
-       .set procdata, USYSCALL
-       .globl pages
-       .set pages, UPAGES
-       .globl vpt
-       .set vpt, UVPT
-       .globl vpd
-       .set vpd, (UVPT+(UVPT>>12)*4)
-
-
-// Entrypoint - this is where the kernel (or our parent environment)
-// starts us running when we are initially loaded into a new environment.
-.text
-.globl _start
-_start:
-       // See if we were started with arguments on the stack
-       tst     %o0
-       bne     args_exist
-        nop
-
-       // If not, push dummy argc/argv arguments.
-       // This happens when we are loaded by the kernel,
-       // because the kernel does not know about passing arguments.
-       mov     0,%o0
-       mov     0,%o1
-
-args_exist:
-       call    parlibmain
-        nop
-
-1:     ba      1b
-        nop
-
diff --git a/user/parlib/src/i386/entry.S b/user/parlib/src/i386/entry.S
new file mode 100644 (file)
index 0000000..aa6e18e
--- /dev/null
@@ -0,0 +1,39 @@
+#include <arch/mmu.h>
+#include <ros/memlayout.h>
+
+.data
+
+
+// Define the global symbols 'envs', 'pages', 'vpt', and 'vpd'
+// so that they can be used in C as if they were ordinary global arrays.
+       .globl procinfo
+       .set procinfo, UINFO
+       .globl procdata
+       .set procdata, USYSCALL
+       .globl pages
+       .set pages, UPAGES
+       .globl vpt
+       .set vpt, UVPT
+       .globl vpd
+       .set vpd, (UVPT+(UVPT>>12)*4)
+
+
+// Entrypoint - this is where the kernel (or our parent environment)
+// starts us running when we are initially loaded into a new environment.
+.text
+.globl _start
+_start:
+       // See if we were started with arguments on the stack
+       cmpl $USTACKTOP, %esp
+       jne args_exist
+
+       // If not, push dummy argc/argv arguments.
+       // This happens when we are loaded by the kernel,
+       // because the kernel does not know about passing arguments.
+       pushl $0
+       pushl $0
+
+args_exist:
+       call parlibmain
+1:      jmp 1b
+
diff --git a/user/parlib/src/i386/newlib_backend.c b/user/parlib/src/i386/newlib_backend.c
new file mode 100644 (file)
index 0000000..1011086
--- /dev/null
@@ -0,0 +1,789 @@
+/* See COPYRIGHT for copyright information. */
+/* Kevin Klues <klueska@cs.berkeley.edu>       */
+
+#ifdef __DEPUTY__
+#pragma nodeputy
+#endif
+
+#include <parlib.h>
+#include <unistd.h>
+#include <newlib_backend.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <debug.h>
+
+#define debug_in_out(...) // debug(__VA_ARGS__)  
+#define debug_write_check(fmt, ...) // debug(fmt, __VA_ARGS__)
+
+/* environ
+ * A pointer to a list of environment variables and their values. 
+ * For a minimal environment, this empty list is adequate.
+ */
+char *__env[1] = { 0 };
+char **environ = __env;
+
+/* _exit()
+ * Exit a program without cleaning up files. 
+ * If your system doesn't provide this, it is best to avoid linking 
+ * with subroutines that require it (exit, system).
+ */
+void _exit(int __status) _ATTRIBUTE ((noreturn))
+{
+       sys_proc_destroy(sys_getpid()); // TODO: can run getpid and cache it
+       while(1); //Should never get here...
+}
+    
+/* close()
+ * Close a file. 
+ */
+int close(int file) {
+       debug_in_out("CLOSE\n");
+
+       // If trying to close stdin/out/err just return
+       if ((file == STDIN_FILENO) || (file == STDERR_FILENO) 
+                                   || (file == STDOUT_FILENO))
+               return 0;
+
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(CLOSE_MESSAGE_FIXED_SIZE);
+       if (out_msg == NULL)
+               return -1;
+
+       char *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = CLOSE_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+
+       // Send message
+       char *result = send_message(out_msg, CLOSE_MESSAGE_FIXED_SIZE);
+
+       free(out_msg);
+
+       int return_val;
+
+       if (result != NULL) {
+               // Read result
+               return_val = *((int *) result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+       
+       return return_val;
+}
+
+/* execve()
+ * Transfer control to a new process. 
+ * Minimal implementation (for a system without processes).
+ */
+
+int execve(char *name, char **argv, char **env) 
+{
+       debug_in_out("EXECVE\n");
+       errno = ENOMEM;
+       return -1;
+}
+
+/* fork()
+ * Create a new process. 
+ * Minimal implementation (for a system without processes).
+ */
+int fork(void) 
+{
+       debug_in_out("FORK\n");
+       errno = EAGAIN;
+    return -1;
+}
+
+/* fstat()
+ * Status of an open file. 
+ * For consistency with other minimal implementations in these stubs, 
+ * all files are regarded as character special devices. 
+ * The sys/stat.h header file required is distributed in the include 
+ * subdirectory for the newlib C library.
+ */
+int fstat(int file, struct stat *st) 
+{
+       debug_in_out("FSTAT\n");        
+
+       st->st_mode = S_IFCHR;
+       
+       // stdout hack
+       if (file == 1)
+               st->st_mode = 8592;
+       return 0;
+
+
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(FSTAT_MESSAGE_FIXED_SIZE);
+       if(out_msg == NULL)
+               return -1;
+       char *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = FSTAT_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+       // Send message
+       char *result = send_message(out_msg, FSTAT_MESSAGE_FIXED_SIZE);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               if (return_val == -1)
+                       errno = *(((char *)result) + 
+                                       sizeof(int) + sizeof(struct stat));
+               else
+                       memcpy(st, ((int *)result) + 1, sizeof(struct stat));
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* getpid()
+ * Process-ID; this is sometimes used to generate strings unlikely to 
+ * conflict with other processes. Minimal implementation, for a system 
+ * without processes.
+ */
+int getpid(void) 
+{
+       return sys_getpid(); // TODO: can run getpid and cache it
+}
+
+/* isatty()
+ * Query whether output stream is a terminal. 
+ * For consistency with the other minimal implementations, 
+ * which only support output to stdout, this minimal 
+ * implementation is suggested.
+ */
+int isatty(int file) 
+{
+       debug_in_out("ISATTY\n");
+
+       // Cheap hack to avoid sending serial comm for stuff we know
+       if ((STDIN_FILENO == file) || (STDOUT_FILENO == file) 
+                               || (STDERR_FILENO == file))
+               return 1;
+
+       
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(ISATTY_MESSAGE_FIXED_SIZE);
+       if(out_msg == NULL)
+               return -1;
+       char *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = ISATTY_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+       // Send message
+       char *result = send_message(out_msg, ISATTY_MESSAGE_FIXED_SIZE);
+
+       free(out_msg);
+
+       int return_val;
+
+       if (result != NULL) {
+               // Read result
+               return_val = *((int *) result);
+               if (return_val == 0) errno = *(((int *)result) + 1);
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = 0;
+       }
+       
+       return return_val;
+}
+
+/* kill()
+ * Send a signal. 
+ * Minimal implementation.
+ */
+int kill(int pid, int sig) 
+{
+       debug_in_out("KILL\n");
+       errno = EINVAL;
+    return -1;
+}
+
+/* link()
+ * Establish a new name for an existing file. 
+ * Minimal implementation.
+ */
+int link(char *old, char *new) 
+{
+       debug_in_out("LINK\n");
+       
+       int s_len_old = strlen(old) + 1; // Null terminator
+       int s_len_new = strlen(new) + 1; // Null terminator
+
+       int out_msg_len = LINK_MESSAGE_FIXED_SIZE + s_len_old + s_len_new;
+
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(out_msg_len);
+       char *out_msg_pos = out_msg;
+
+       if (out_msg == NULL)
+               return -1;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = LINK_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = s_len_old;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = s_len_new;
+       out_msg_pos += sizeof(int);
+
+       memcpy(out_msg_pos, old, s_len_old);
+       out_msg_pos += s_len_old;
+
+       memcpy(out_msg_pos, new, s_len_new);
+
+       // Send message
+       char *result = send_message(out_msg, out_msg_len);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* lseek()
+ * Set position in a file. 
+ * Minimal implementation.
+ */
+off_t lseek(int file, off_t ptr, int dir) 
+{
+       debug_in_out("LSEEK\n");        
+       
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(LSEEK_MESSAGE_FIXED_SIZE);
+       if(out_msg == NULL)
+               return -1;
+       char *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = LSEEK_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = ptr;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = dir;
+       out_msg_pos += sizeof(int);
+
+       // Send message
+       char *result = send_message(out_msg, LSEEK_MESSAGE_FIXED_SIZE);
+
+       free(out_msg);
+
+       int return_val;
+
+       if (result != NULL) {
+               // Read result
+               return_val = *((int *) result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* open()
+ * Open a file. 
+ */
+int open(const char *name, int flags, int mode) 
+{
+       debug_in_out("OPEN\n");
+
+       int s_len = strlen(name) + 1; // Null terminator
+       int out_msg_len = OPEN_MESSAGE_FIXED_SIZE + s_len;
+
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(out_msg_len);
+       char *out_msg_pos = out_msg;
+
+       if (out_msg == NULL)
+               return -1;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = OPEN_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = flags;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = mode;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = s_len;
+       out_msg_pos += sizeof(int);
+
+       memcpy(out_msg_pos, name, s_len);
+
+       // Send message
+       char *result = send_message(out_msg, out_msg_len);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* read()
+ * Read from a file. 
+ */
+ssize_t read(int file, void *ptr, size_t len) 
+{
+       debug_in_out("READ\n");
+
+       if (file == STDIN_FILENO) {
+               for(int i=0; i<len; i++)        
+                       ((uint8_t*)ptr)[i] = sys_cgetc();
+               return len;
+       }
+
+       // Allocate a new buffer of proper size
+       char *out_msg = (char*)malloc(READ_MESSAGE_FIXED_SIZE);
+       if (out_msg == NULL)
+               return -1;
+
+       char *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = READ_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int *)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+       *((int *)out_msg_pos) = len;
+       out_msg_pos += sizeof(int);
+
+       // Send message
+       char *result = send_message(out_msg, READ_MESSAGE_FIXED_SIZE);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               if (return_val > 0)
+                       memcpy(ptr, ((int *)result) + 1, return_val);
+               else 
+                       errno = *(((int *)result) + 1);
+
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* Read len bytes from the given channel to the buffer.
+ * If peek is NO_PEEK, will wait indefinitely until that much data is read.
+ * If peek is PEEK, if no data is available, will return immediately.
+ *             However once some data is available, 
+ *                      will block until the entire amount is available.
+ */
+int read_from_channel(char * buf, int len, int peek)
+{
+       // TODO: NEED TO IMPLIMENT A TIMEOUT
+       //                      Also, watch out for CONNECTION TERMINATED
+       int total_read = 0;
+
+       int just_read = sys_serial_read(buf, len);
+
+
+       if (just_read < 0) return just_read;
+       if (just_read == 0 && peek) return just_read;
+
+       total_read += just_read;
+
+       while (total_read != len) {
+               just_read = sys_serial_read(buf + total_read, len - total_read);
+
+               if (just_read == -1) return -1;
+               total_read += just_read;
+       }
+
+       return total_read;
+}
+
+/* sbrk()
+ * Increase program data space. 
+ * As malloc and related functions depend on this, it is 
+ * useful to have a working implementation. 
+ * The following suffices for a standalone system; it exploits the 
+ * symbol _end automatically defined by the GNU linker.
+ */
+void* sbrk(ptrdiff_t incr) 
+{
+       debug_in_out("SBRK\n");
+       debug_in_out("\tincr: %u\n", incr);     
+
+       #define HEAP_SIZE 8192
+       static uint8_t array[HEAP_SIZE];
+       static uint8_t* heap_end = array;
+       static uint8_t* stack_ptr = &(array[HEAP_SIZE-1]);
+
+       uint8_t* prev_heap_end; 
+
+       prev_heap_end = heap_end;
+       if (heap_end + incr > stack_ptr) {
+               errno = ENOMEM;
+               return (void*)-1;
+       }
+     
+       heap_end += incr;
+       debug_in_out("\treturning: %u\n", prev_heap_end);
+       return (caddr_t) prev_heap_end;
+}
+
+/* send_message()
+ * Write the message in buffer out on the channel, and wait for a response.
+ * Caller is responsible for management of buffer passed in and buffer returned.
+ */
+char *send_message(char *message, int len)
+{
+       syscall_id_t this_call_id = *((syscall_id_t*)message);
+
+       if (write_to_channel(message, len) != len)
+               return NULL;
+
+       int response_value;
+
+       // Pull the response from the server out of the channel.
+       if (read_from_channel( (char*)&response_value, 
+                               sizeof(int), 
+                               NO_PEEK) == -1) 
+               return NULL;
+
+       char* return_msg = NULL;
+       char* errno_pos = NULL;
+       int extra_space = (response_value == -1) ? sizeof(int) : 0;
+
+       // TODO: Make these sizes an array we index into, and only have this code once.
+       // TODO: Will have a flag that tells us we have a variable length response (right now only for read case)
+       // TODO: Default clause with error handling.
+       switch (this_call_id) {
+               case ISATTY_ID:
+                       // This case must be at the top! Else extra space will be wrong at times 
+                       // ISATTY is special, 0 signifies error, not -1. Annoying.
+                       extra_space = (response_value == 0) ? sizeof(int) : 0;
+               case OPEN_ID:           
+               case CLOSE_ID:
+               case WRITE_ID:  
+               case LSEEK_ID:
+               case UNLINK_ID:
+               case LINK_ID:
+                        return_msg = (char*)malloc(sizeof(int) + extra_space);
+                       if (return_msg == NULL)
+                                return NULL;
+
+                       errno_pos = return_msg + sizeof(int);
+                        if (extra_space && (-1 == read_from_channel(errno_pos,
+                                                                    sizeof(int), 
+                                                                    NO_PEEK))) {
+                               free(return_msg);
+                                return NULL;
+                       }
+
+                        break;
+
+                case STAT_ID:
+               case FSTAT_ID:
+                       return_msg = (char*)malloc(sizeof(int) 
+                                                    + sizeof(struct stat)
+                                                    + extra_space);
+                        if (return_msg == NULL)
+                                return NULL;
+
+                       if (-1 == read_from_channel(return_msg + sizeof(int),
+                                                    sizeof(struct stat), 
+                                                    NO_PEEK)) {
+                               free(return_msg);
+                                return NULL;
+                       }
+
+                        errno_pos = return_msg + sizeof(int) 
+                                               + sizeof(struct stat);
+
+                        if (extra_space && (-1 == read_from_channel(errno_pos,
+                                                                    sizeof(int), 
+                                                                    NO_PEEK))) {
+                               free(return_msg);
+                               return NULL;
+                       }
+
+                       break;
+               
+               case READ_ID:
+                       if (response_value > 0)
+                               extra_space = response_value;
+                       else
+                               extra_space = extra_space;
+
+                       return_msg = (char*)malloc(sizeof(int) + extra_space);
+
+                       if (return_msg == NULL)
+                               return NULL;
+
+                       if (-1 == read_from_channel(return_msg + sizeof(int),
+                                                    extra_space,
+                                                    NO_PEEK)) {
+                                free(return_msg);
+                                return NULL;
+                        }
+
+                       break;
+
+       }
+
+       // Copy response value in place
+       memcpy(return_msg, &response_value, sizeof(int));
+
+       return return_msg;
+}
+
+
+/* stat()
+ * Status of a file (by name). 
+ * Minimal implementation.
+ */
+int stat(char *file, struct stat *st) 
+{
+       debug_in_out("STAT\n");
+       
+       int s_len = strlen(file) + 1; // Null terminator
+       int out_msg_len = STAT_MESSAGE_FIXED_SIZE + s_len;
+
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(out_msg_len);
+       char *out_msg_pos = out_msg;
+
+       if (out_msg == NULL)
+               return -1;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = STAT_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = s_len;
+       out_msg_pos += sizeof(int);
+
+       memcpy(out_msg_pos, file, s_len);
+
+       // Send message
+       char *result = send_message(out_msg, out_msg_len);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+
+               if (return_val == -1)
+                       errno = *(((char *)result) + sizeof(int) 
+                                                   + sizeof(struct stat));
+               else
+                       memcpy(st, ((int *)result) + 1, sizeof(struct stat));
+
+               free(result);
+
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+/* times()
+ * Timing information for current process. 
+ * Minimal implementation.
+ */
+int times(struct tms *buf) 
+{
+       debug_in_out("TIMES");
+       return -1;
+}
+
+/* unlink()
+ * Remove a file's directory entry. 
+ * Minimal implementation.
+ */
+int unlink(char *name) 
+{
+       debug_in_out("UNLINK\n");
+       
+       int s_len = strlen(name) + 1; // Null terminator
+       int out_msg_len = UNLINK_MESSAGE_FIXED_SIZE + s_len;
+
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(out_msg_len);
+       char *out_msg_pos = out_msg;
+
+       if (out_msg == NULL)
+               return -1;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = UNLINK_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = s_len;
+       out_msg_pos += sizeof(int);
+
+       memcpy(out_msg_pos, name, s_len);
+
+       // Send message
+       char *result = send_message(out_msg, out_msg_len);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+       return return_val;
+}
+
+/* wait()
+ * Wait for a child process. 
+ * Minimal implementation.
+ */
+int wait(int *status) 
+{
+       debug_in_out("WAIT\n");
+       errno = ECHILD;
+       return -1;
+}
+
+/* write()
+ * Write to a file. 
+ */
+ssize_t write(int file, void *ptr, size_t len) {
+       
+       debug_in_out("WRITE\n");        
+       debug_in_out("\tFILE: %u\n", file);
+
+       debug_write_check("Writing len: %d\n", len);
+
+       if ((file == STDIN_FILENO) || (file == STDERR_FILENO) 
+                                   || (file == STDOUT_FILENO))
+               return sys_cputs(ptr, len);
+       
+       int out_msg_len = WRITE_MESSAGE_FIXED_SIZE + len;
+
+       // Allocate a new buffer of proper size
+       char *out_msg = malloc(out_msg_len);
+       char *out_msg_pos = out_msg;
+
+       // Fill the buffer
+       *((syscall_id_t *)out_msg_pos) = WRITE_ID;
+       out_msg_pos += sizeof(syscall_id_t);
+
+       *((int*)out_msg_pos) = file;
+       out_msg_pos += sizeof(int);
+
+       *((int*)out_msg_pos) = len;
+       out_msg_pos += sizeof(int);
+
+       memcpy(out_msg_pos, ptr, len);
+
+       // Send message
+       char *result = send_message(out_msg, out_msg_len);
+
+       free(out_msg);
+
+       // Read result
+       int return_val;
+
+       if (result != NULL) {
+               return_val = *((int *)result);
+               if (return_val == -1) errno = *(((int *)result) + 1);
+               free(result);
+       } else {
+               errno = ECHANNEL;
+               return_val = -1;
+       }
+
+       return return_val;
+}
+
+
+/* write_to_channel()
+ * Send a message out over the channel, defined by msg, of length len
+ */
+int write_to_channel(char * msg, int len)
+{
+       return sys_serial_write((char*)msg, len);
+}
+
diff --git a/user/parlib/src/i386/syscall.c b/user/parlib/src/i386/syscall.c
new file mode 100644 (file)
index 0000000..d4ef7ab
--- /dev/null
@@ -0,0 +1,73 @@
+// System call stubs.
+#ifdef __DEPUTY__
+#pragma nodeputy
+#endif
+
+#include <arch/types.h>
+#include <arch/arch.h>
+
+// TODO: fix sysenter to take all 5 params
+static inline intreg_t syscall_sysenter(uint16_t num, intreg_t a1,
+                                 intreg_t a2, intreg_t a3,
+                                 intreg_t a4, intreg_t a5)
+{
+       intreg_t ret;
+       asm volatile ("  pushl %%ebp;        "
+                     "  pushl %%esi;        "
+                     "  movl %%esp, %%ebp;  "
+                     "  leal 1f, %%esi;     "
+                     "  sysenter;           "
+                     "1:                    "
+                     "  popl %%esi;         "
+                     "  popl %%ebp;         "
+                     : "=a" (ret)
+                     : "a" (num),
+                       "d" (a1),
+                       "c" (a2),
+                       "b" (a3),
+                       "D" (a4)
+                     : "cc", "memory");
+       return ret;
+}
+
+static inline intreg_t syscall_trap(uint16_t num, intreg_t a1,
+                             intreg_t a2, intreg_t a3,
+                             intreg_t a4, intreg_t a5)
+{
+       uint32_t ret;
+
+       // Generic system call: pass system call number in AX,
+       // up to five parameters in DX, CX, BX, DI, SI.
+       // Interrupt kernel with T_SYSCALL.
+       //
+       // The "volatile" tells the assembler not to optimize
+       // this instruction away just because we don't use the
+       // return value.
+       //
+       // The last clause tells the assembler that this can
+       // potentially change the condition codes and arbitrary
+       // memory locations.
+
+       asm volatile("int %1"
+                    : "=a" (ret)
+                    : "i" (T_SYSCALL),
+                      "a" (num),
+                      "d" (a1),
+                      "c" (a2),
+                      "b" (a3),
+                      "D" (a4),
+                      "S" (a5)
+                    : "cc", "memory");
+       return ret;
+}
+
+intreg_t syscall(uint16_t num, intreg_t a1,
+                intreg_t a2, intreg_t a3,
+                intreg_t a4, intreg_t a5)
+{
+       #ifndef SYSCALL_TRAP
+               return syscall_sysenter(num, a1, a2, a3, a4, a5);
+       #else
+               return syscall_trap(num, a1, a2, a3, a4, a5);
+       #endif
+}
diff --git a/user/parlib/src/newlib_backend.c b/user/parlib/src/newlib_backend.c
deleted file mode 100644 (file)
index 1011086..0000000
+++ /dev/null
@@ -1,789 +0,0 @@
-/* See COPYRIGHT for copyright information. */
-/* Kevin Klues <klueska@cs.berkeley.edu>       */
-
-#ifdef __DEPUTY__
-#pragma nodeputy
-#endif
-
-#include <parlib.h>
-#include <unistd.h>
-#include <newlib_backend.h>
-#include <string.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <debug.h>
-
-#define debug_in_out(...) // debug(__VA_ARGS__)  
-#define debug_write_check(fmt, ...) // debug(fmt, __VA_ARGS__)
-
-/* environ
- * A pointer to a list of environment variables and their values. 
- * For a minimal environment, this empty list is adequate.
- */
-char *__env[1] = { 0 };
-char **environ = __env;
-
-/* _exit()
- * Exit a program without cleaning up files. 
- * If your system doesn't provide this, it is best to avoid linking 
- * with subroutines that require it (exit, system).
- */
-void _exit(int __status) _ATTRIBUTE ((noreturn))
-{
-       sys_proc_destroy(sys_getpid()); // TODO: can run getpid and cache it
-       while(1); //Should never get here...
-}
-    
-/* close()
- * Close a file. 
- */
-int close(int file) {
-       debug_in_out("CLOSE\n");
-
-       // If trying to close stdin/out/err just return
-       if ((file == STDIN_FILENO) || (file == STDERR_FILENO) 
-                                   || (file == STDOUT_FILENO))
-               return 0;
-
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(CLOSE_MESSAGE_FIXED_SIZE);
-       if (out_msg == NULL)
-               return -1;
-
-       char *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = CLOSE_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-
-       // Send message
-       char *result = send_message(out_msg, CLOSE_MESSAGE_FIXED_SIZE);
-
-       free(out_msg);
-
-       int return_val;
-
-       if (result != NULL) {
-               // Read result
-               return_val = *((int *) result);
-               if (return_val == -1) errno = *(((int *)result) + 1);
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-       
-       return return_val;
-}
-
-/* execve()
- * Transfer control to a new process. 
- * Minimal implementation (for a system without processes).
- */
-
-int execve(char *name, char **argv, char **env) 
-{
-       debug_in_out("EXECVE\n");
-       errno = ENOMEM;
-       return -1;
-}
-
-/* fork()
- * Create a new process. 
- * Minimal implementation (for a system without processes).
- */
-int fork(void) 
-{
-       debug_in_out("FORK\n");
-       errno = EAGAIN;
-    return -1;
-}
-
-/* fstat()
- * Status of an open file. 
- * For consistency with other minimal implementations in these stubs, 
- * all files are regarded as character special devices. 
- * The sys/stat.h header file required is distributed in the include 
- * subdirectory for the newlib C library.
- */
-int fstat(int file, struct stat *st) 
-{
-       debug_in_out("FSTAT\n");        
-
-       st->st_mode = S_IFCHR;
-       
-       // stdout hack
-       if (file == 1)
-               st->st_mode = 8592;
-       return 0;
-
-
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(FSTAT_MESSAGE_FIXED_SIZE);
-       if(out_msg == NULL)
-               return -1;
-       char *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = FSTAT_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-       // Send message
-       char *result = send_message(out_msg, FSTAT_MESSAGE_FIXED_SIZE);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               if (return_val == -1)
-                       errno = *(((char *)result) + 
-                                       sizeof(int) + sizeof(struct stat));
-               else
-                       memcpy(st, ((int *)result) + 1, sizeof(struct stat));
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* getpid()
- * Process-ID; this is sometimes used to generate strings unlikely to 
- * conflict with other processes. Minimal implementation, for a system 
- * without processes.
- */
-int getpid(void) 
-{
-       return sys_getpid(); // TODO: can run getpid and cache it
-}
-
-/* isatty()
- * Query whether output stream is a terminal. 
- * For consistency with the other minimal implementations, 
- * which only support output to stdout, this minimal 
- * implementation is suggested.
- */
-int isatty(int file) 
-{
-       debug_in_out("ISATTY\n");
-
-       // Cheap hack to avoid sending serial comm for stuff we know
-       if ((STDIN_FILENO == file) || (STDOUT_FILENO == file) 
-                               || (STDERR_FILENO == file))
-               return 1;
-
-       
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(ISATTY_MESSAGE_FIXED_SIZE);
-       if(out_msg == NULL)
-               return -1;
-       char *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = ISATTY_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-       // Send message
-       char *result = send_message(out_msg, ISATTY_MESSAGE_FIXED_SIZE);
-
-       free(out_msg);
-
-       int return_val;
-
-       if (result != NULL) {
-               // Read result
-               return_val = *((int *) result);
-               if (return_val == 0) errno = *(((int *)result) + 1);
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = 0;
-       }
-       
-       return return_val;
-}
-
-/* kill()
- * Send a signal. 
- * Minimal implementation.
- */
-int kill(int pid, int sig) 
-{
-       debug_in_out("KILL\n");
-       errno = EINVAL;
-    return -1;
-}
-
-/* link()
- * Establish a new name for an existing file. 
- * Minimal implementation.
- */
-int link(char *old, char *new) 
-{
-       debug_in_out("LINK\n");
-       
-       int s_len_old = strlen(old) + 1; // Null terminator
-       int s_len_new = strlen(new) + 1; // Null terminator
-
-       int out_msg_len = LINK_MESSAGE_FIXED_SIZE + s_len_old + s_len_new;
-
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(out_msg_len);
-       char *out_msg_pos = out_msg;
-
-       if (out_msg == NULL)
-               return -1;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = LINK_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = s_len_old;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = s_len_new;
-       out_msg_pos += sizeof(int);
-
-       memcpy(out_msg_pos, old, s_len_old);
-       out_msg_pos += s_len_old;
-
-       memcpy(out_msg_pos, new, s_len_new);
-
-       // Send message
-       char *result = send_message(out_msg, out_msg_len);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               if (return_val == -1) errno = *(((int *)result) + 1);
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* lseek()
- * Set position in a file. 
- * Minimal implementation.
- */
-off_t lseek(int file, off_t ptr, int dir) 
-{
-       debug_in_out("LSEEK\n");        
-       
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(LSEEK_MESSAGE_FIXED_SIZE);
-       if(out_msg == NULL)
-               return -1;
-       char *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = LSEEK_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = ptr;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = dir;
-       out_msg_pos += sizeof(int);
-
-       // Send message
-       char *result = send_message(out_msg, LSEEK_MESSAGE_FIXED_SIZE);
-
-       free(out_msg);
-
-       int return_val;
-
-       if (result != NULL) {
-               // Read result
-               return_val = *((int *) result);
-               if (return_val == -1) errno = *(((int *)result) + 1);
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* open()
- * Open a file. 
- */
-int open(const char *name, int flags, int mode) 
-{
-       debug_in_out("OPEN\n");
-
-       int s_len = strlen(name) + 1; // Null terminator
-       int out_msg_len = OPEN_MESSAGE_FIXED_SIZE + s_len;
-
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(out_msg_len);
-       char *out_msg_pos = out_msg;
-
-       if (out_msg == NULL)
-               return -1;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = OPEN_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = flags;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = mode;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = s_len;
-       out_msg_pos += sizeof(int);
-
-       memcpy(out_msg_pos, name, s_len);
-
-       // Send message
-       char *result = send_message(out_msg, out_msg_len);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               if (return_val == -1) errno = *(((int *)result) + 1);
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* read()
- * Read from a file. 
- */
-ssize_t read(int file, void *ptr, size_t len) 
-{
-       debug_in_out("READ\n");
-
-       if (file == STDIN_FILENO) {
-               for(int i=0; i<len; i++)        
-                       ((uint8_t*)ptr)[i] = sys_cgetc();
-               return len;
-       }
-
-       // Allocate a new buffer of proper size
-       char *out_msg = (char*)malloc(READ_MESSAGE_FIXED_SIZE);
-       if (out_msg == NULL)
-               return -1;
-
-       char *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = READ_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int *)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-       *((int *)out_msg_pos) = len;
-       out_msg_pos += sizeof(int);
-
-       // Send message
-       char *result = send_message(out_msg, READ_MESSAGE_FIXED_SIZE);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               if (return_val > 0)
-                       memcpy(ptr, ((int *)result) + 1, return_val);
-               else 
-                       errno = *(((int *)result) + 1);
-
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* Read len bytes from the given channel to the buffer.
- * If peek is NO_PEEK, will wait indefinitely until that much data is read.
- * If peek is PEEK, if no data is available, will return immediately.
- *             However once some data is available, 
- *                      will block until the entire amount is available.
- */
-int read_from_channel(char * buf, int len, int peek)
-{
-       // TODO: NEED TO IMPLIMENT A TIMEOUT
-       //                      Also, watch out for CONNECTION TERMINATED
-       int total_read = 0;
-
-       int just_read = sys_serial_read(buf, len);
-
-
-       if (just_read < 0) return just_read;
-       if (just_read == 0 && peek) return just_read;
-
-       total_read += just_read;
-
-       while (total_read != len) {
-               just_read = sys_serial_read(buf + total_read, len - total_read);
-
-               if (just_read == -1) return -1;
-               total_read += just_read;
-       }
-
-       return total_read;
-}
-
-/* sbrk()
- * Increase program data space. 
- * As malloc and related functions depend on this, it is 
- * useful to have a working implementation. 
- * The following suffices for a standalone system; it exploits the 
- * symbol _end automatically defined by the GNU linker.
- */
-void* sbrk(ptrdiff_t incr) 
-{
-       debug_in_out("SBRK\n");
-       debug_in_out("\tincr: %u\n", incr);     
-
-       #define HEAP_SIZE 8192
-       static uint8_t array[HEAP_SIZE];
-       static uint8_t* heap_end = array;
-       static uint8_t* stack_ptr = &(array[HEAP_SIZE-1]);
-
-       uint8_t* prev_heap_end; 
-
-       prev_heap_end = heap_end;
-       if (heap_end + incr > stack_ptr) {
-               errno = ENOMEM;
-               return (void*)-1;
-       }
-     
-       heap_end += incr;
-       debug_in_out("\treturning: %u\n", prev_heap_end);
-       return (caddr_t) prev_heap_end;
-}
-
-/* send_message()
- * Write the message in buffer out on the channel, and wait for a response.
- * Caller is responsible for management of buffer passed in and buffer returned.
- */
-char *send_message(char *message, int len)
-{
-       syscall_id_t this_call_id = *((syscall_id_t*)message);
-
-       if (write_to_channel(message, len) != len)
-               return NULL;
-
-       int response_value;
-
-       // Pull the response from the server out of the channel.
-       if (read_from_channel( (char*)&response_value, 
-                               sizeof(int), 
-                               NO_PEEK) == -1) 
-               return NULL;
-
-       char* return_msg = NULL;
-       char* errno_pos = NULL;
-       int extra_space = (response_value == -1) ? sizeof(int) : 0;
-
-       // TODO: Make these sizes an array we index into, and only have this code once.
-       // TODO: Will have a flag that tells us we have a variable length response (right now only for read case)
-       // TODO: Default clause with error handling.
-       switch (this_call_id) {
-               case ISATTY_ID:
-                       // This case must be at the top! Else extra space will be wrong at times 
-                       // ISATTY is special, 0 signifies error, not -1. Annoying.
-                       extra_space = (response_value == 0) ? sizeof(int) : 0;
-               case OPEN_ID:           
-               case CLOSE_ID:
-               case WRITE_ID:  
-               case LSEEK_ID:
-               case UNLINK_ID:
-               case LINK_ID:
-                        return_msg = (char*)malloc(sizeof(int) + extra_space);
-                       if (return_msg == NULL)
-                                return NULL;
-
-                       errno_pos = return_msg + sizeof(int);
-                        if (extra_space && (-1 == read_from_channel(errno_pos,
-                                                                    sizeof(int), 
-                                                                    NO_PEEK))) {
-                               free(return_msg);
-                                return NULL;
-                       }
-
-                        break;
-
-                case STAT_ID:
-               case FSTAT_ID:
-                       return_msg = (char*)malloc(sizeof(int) 
-                                                    + sizeof(struct stat)
-                                                    + extra_space);
-                        if (return_msg == NULL)
-                                return NULL;
-
-                       if (-1 == read_from_channel(return_msg + sizeof(int),
-                                                    sizeof(struct stat), 
-                                                    NO_PEEK)) {
-                               free(return_msg);
-                                return NULL;
-                       }
-
-                        errno_pos = return_msg + sizeof(int) 
-                                               + sizeof(struct stat);
-
-                        if (extra_space && (-1 == read_from_channel(errno_pos,
-                                                                    sizeof(int), 
-                                                                    NO_PEEK))) {
-                               free(return_msg);
-                               return NULL;
-                       }
-
-                       break;
-               
-               case READ_ID:
-                       if (response_value > 0)
-                               extra_space = response_value;
-                       else
-                               extra_space = extra_space;
-
-                       return_msg = (char*)malloc(sizeof(int) + extra_space);
-
-                       if (return_msg == NULL)
-                               return NULL;
-
-                       if (-1 == read_from_channel(return_msg + sizeof(int),
-                                                    extra_space,
-                                                    NO_PEEK)) {
-                                free(return_msg);
-                                return NULL;
-                        }
-
-                       break;
-
-       }
-
-       // Copy response value in place
-       memcpy(return_msg, &response_value, sizeof(int));
-
-       return return_msg;
-}
-
-
-/* stat()
- * Status of a file (by name). 
- * Minimal implementation.
- */
-int stat(char *file, struct stat *st) 
-{
-       debug_in_out("STAT\n");
-       
-       int s_len = strlen(file) + 1; // Null terminator
-       int out_msg_len = STAT_MESSAGE_FIXED_SIZE + s_len;
-
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(out_msg_len);
-       char *out_msg_pos = out_msg;
-
-       if (out_msg == NULL)
-               return -1;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = STAT_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = s_len;
-       out_msg_pos += sizeof(int);
-
-       memcpy(out_msg_pos, file, s_len);
-
-       // Send message
-       char *result = send_message(out_msg, out_msg_len);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-
-               if (return_val == -1)
-                       errno = *(((char *)result) + sizeof(int) 
-                                                   + sizeof(struct stat));
-               else
-                       memcpy(st, ((int *)result) + 1, sizeof(struct stat));
-
-               free(result);
-
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-/* times()
- * Timing information for current process. 
- * Minimal implementation.
- */
-int times(struct tms *buf) 
-{
-       debug_in_out("TIMES");
-       return -1;
-}
-
-/* unlink()
- * Remove a file's directory entry. 
- * Minimal implementation.
- */
-int unlink(char *name) 
-{
-       debug_in_out("UNLINK\n");
-       
-       int s_len = strlen(name) + 1; // Null terminator
-       int out_msg_len = UNLINK_MESSAGE_FIXED_SIZE + s_len;
-
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(out_msg_len);
-       char *out_msg_pos = out_msg;
-
-       if (out_msg == NULL)
-               return -1;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = UNLINK_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = s_len;
-       out_msg_pos += sizeof(int);
-
-       memcpy(out_msg_pos, name, s_len);
-
-       // Send message
-       char *result = send_message(out_msg, out_msg_len);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               if (return_val == -1) errno = *(((int *)result) + 1);
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-       return return_val;
-}
-
-/* wait()
- * Wait for a child process. 
- * Minimal implementation.
- */
-int wait(int *status) 
-{
-       debug_in_out("WAIT\n");
-       errno = ECHILD;
-       return -1;
-}
-
-/* write()
- * Write to a file. 
- */
-ssize_t write(int file, void *ptr, size_t len) {
-       
-       debug_in_out("WRITE\n");        
-       debug_in_out("\tFILE: %u\n", file);
-
-       debug_write_check("Writing len: %d\n", len);
-
-       if ((file == STDIN_FILENO) || (file == STDERR_FILENO) 
-                                   || (file == STDOUT_FILENO))
-               return sys_cputs(ptr, len);
-       
-       int out_msg_len = WRITE_MESSAGE_FIXED_SIZE + len;
-
-       // Allocate a new buffer of proper size
-       char *out_msg = malloc(out_msg_len);
-       char *out_msg_pos = out_msg;
-
-       // Fill the buffer
-       *((syscall_id_t *)out_msg_pos) = WRITE_ID;
-       out_msg_pos += sizeof(syscall_id_t);
-
-       *((int*)out_msg_pos) = file;
-       out_msg_pos += sizeof(int);
-
-       *((int*)out_msg_pos) = len;
-       out_msg_pos += sizeof(int);
-
-       memcpy(out_msg_pos, ptr, len);
-
-       // Send message
-       char *result = send_message(out_msg, out_msg_len);
-
-       free(out_msg);
-
-       // Read result
-       int return_val;
-
-       if (result != NULL) {
-               return_val = *((int *)result);
-               if (return_val == -1) errno = *(((int *)result) + 1);
-               free(result);
-       } else {
-               errno = ECHANNEL;
-               return_val = -1;
-       }
-
-       return return_val;
-}
-
-
-/* write_to_channel()
- * Send a message out over the channel, defined by msg, of length len
- */
-int write_to_channel(char * msg, int len)
-{
-       return sys_serial_write((char*)msg, len);
-}
-
diff --git a/user/parlib/src/sparc/entry.S b/user/parlib/src/sparc/entry.S
new file mode 100644 (file)
index 0000000..f55b083
--- /dev/null
@@ -0,0 +1,49 @@
+#include <arch/mmu.h>
+#include <arch/arch.h>
+#include <ros/memlayout.h>
+
+.data
+
+
+// Define the global symbols 'envs', 'pages', 'vpt', and 'vpd'
+// so that they can be used in C as if they were ordinary global arrays.
+       .globl procinfo
+       .set procinfo, UINFO
+       .globl procdata
+       .set procdata, USYSCALL
+       .globl pages
+       .set pages, UPAGES
+       .globl vpt
+       .set vpt, UVPT
+       .globl vpd
+       .set vpd, (UVPT+(UVPT>>12)*4)
+
+// Entrypoint - this is where the kernel (or our parent environment)
+// starts us running when we are initially loaded into a new environment.
+.text
+.globl _start
+_start:
+       // See if we were started with arguments on the stack
+       tst     %o0
+       bne     args_exist
+        nop
+
+       // If not, push dummy argc/argv arguments.
+       // This happens when we are loaded by the kernel,
+       // because the kernel does not know about passing arguments.
+       mov     0,%o0
+       mov     0,%o1
+
+args_exist:
+       call    parlibmain
+        nop
+
+1:     ba      1b
+        nop
+
+
+.globl hart_self
+hart_self:
+       retl
+       mov     CORE_ID_REG,%o0
+
diff --git a/user/parlib/src/sparc/newlib_backend.c b/user/parlib/src/sparc/newlib_backend.c
new file mode 100644 (file)
index 0000000..f714629
--- /dev/null
@@ -0,0 +1,146 @@
+/* See COPYRIGHT for copyright information. */
+/* Andrew Waterman <waterman@eecs.bekeley.edu> */
+
+#include <arch/frontend.h>
+#include <parlib.h>
+#include <sys/unistd.h>
+
+char *__env[1] = { 0 };
+char **environ = __env;
+
+#define IS_CONSOLE(fd) ((uint32_t)(fd) < 3)
+
+int
+getpid(void)
+{
+       static int pid = 0;
+       if(pid == 0)
+               return pid = sys_getpid();
+
+       return pid;
+}
+
+void
+_exit(int code)
+{
+       sys_proc_destroy(getpid());
+       while(1);
+}
+
+int
+isatty(int fd)
+{
+       return IS_CONSOLE(fd);
+}
+
+int
+fork(void)
+{
+       return -1;
+}
+
+int
+execve(char* name, char** argv, char** env)
+{
+       return -1;
+}
+
+int
+kill(int pid, int sig)
+{
+       return -1;
+}
+
+int
+wait(int* status)
+{
+       return -1;
+}
+
+int
+link(char* old, char* new)
+{
+       return -1;
+}
+
+int
+unlink(char* old)
+{
+       return syscall(SYS_frontend,RAMP_SYSCALL_unlink,(int)old,0,0,0);
+}
+
+int
+fstat(int fd, struct stat* st)
+{
+       return syscall(SYS_frontend,RAMP_SYSCALL_fstat,fd,(int)st,0,0);
+}
+
+int
+stat(char* name, struct stat* st)
+{
+       return syscall(SYS_frontend,RAMP_SYSCALL_stat,(int)name,(int)st,0,0);
+}
+
+off_t
+lseek(int fd, off_t ptr, int dir)
+{
+       return syscall(SYS_frontend,RAMP_SYSCALL_lseek,fd,ptr,dir,0);
+}
+
+size_t
+write(int fd, void* ptr, size_t len)
+{
+       return syscall(SYS_frontend,RAMP_SYSCALL_write,fd,(int)ptr,len,0);
+}
+
+size_t
+read(int fd, void* ptr, size_t len)
+{
+       return syscall(SYS_frontend,RAMP_SYSCALL_read,fd,(int)ptr,len,0);
+}
+
+int
+open(char* name, int flags, int mode)
+{
+       return syscall(SYS_frontend,RAMP_SYSCALL_open,(int)name,flags,mode,0);
+}
+
+int
+close(int fd)
+{
+       if(IS_CONSOLE(fd))
+               return 0;
+       return syscall(SYS_frontend,RAMP_SYSCALL_close,fd,0,0,0);
+}
+
+int
+times(struct tms* buf)
+{
+       return -1;
+}
+
+int
+gettimeofday(struct timeval* tp, void* tzp)
+{
+       return -1;
+}
+
+void*SNT
+sbrk(ptrdiff_t incr)
+{
+       #define HEAP_SIZE 8192
+       static uint8_t array[HEAP_SIZE];
+       static uint8_t*SNT heap_end = array;
+       static uint8_t*SNT stack_ptr = &(array[HEAP_SIZE-1]);
+
+       uint8_t*SNT prev_heap_end;
+
+       prev_heap_end = heap_end;
+       if (heap_end + incr > stack_ptr) {
+               errno = ENOMEM;
+               return (void*SNT)-1;
+       }
+
+       heap_end += incr;
+       return (caddr_t SNT) prev_heap_end;
+}
diff --git a/user/parlib/src/sparc/syscall.c b/user/parlib/src/sparc/syscall.c
new file mode 100644 (file)
index 0000000..2528869
--- /dev/null
@@ -0,0 +1,10 @@
+__asm__ (".global syscall              \n\t"
+         "syscall:                     \n\t"
+         "mov %o0,%g1          \n\t"
+         "mov %o1,%o0          \n\t"
+         "mov %o2,%o1          \n\t"
+         "mov %o3,%o2          \n\t"
+         "mov %o4,%o3          \n\t"
+         "mov %o5,%o4          \n\t"
+         "retl                 \n\t"
+         "ta 8                 \n\t");
diff --git a/user/parlib/src/syscall_i386.c b/user/parlib/src/syscall_i386.c
deleted file mode 100644 (file)
index d4ef7ab..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// System call stubs.
-#ifdef __DEPUTY__
-#pragma nodeputy
-#endif
-
-#include <arch/types.h>
-#include <arch/arch.h>
-
-// TODO: fix sysenter to take all 5 params
-static inline intreg_t syscall_sysenter(uint16_t num, intreg_t a1,
-                                 intreg_t a2, intreg_t a3,
-                                 intreg_t a4, intreg_t a5)
-{
-       intreg_t ret;
-       asm volatile ("  pushl %%ebp;        "
-                     "  pushl %%esi;        "
-                     "  movl %%esp, %%ebp;  "
-                     "  leal 1f, %%esi;     "
-                     "  sysenter;           "
-                     "1:                    "
-                     "  popl %%esi;         "
-                     "  popl %%ebp;         "
-                     : "=a" (ret)
-                     : "a" (num),
-                       "d" (a1),
-                       "c" (a2),
-                       "b" (a3),
-                       "D" (a4)
-                     : "cc", "memory");
-       return ret;
-}
-
-static inline intreg_t syscall_trap(uint16_t num, intreg_t a1,
-                             intreg_t a2, intreg_t a3,
-                             intreg_t a4, intreg_t a5)
-{
-       uint32_t ret;
-
-       // Generic system call: pass system call number in AX,
-       // up to five parameters in DX, CX, BX, DI, SI.
-       // Interrupt kernel with T_SYSCALL.
-       //
-       // The "volatile" tells the assembler not to optimize
-       // this instruction away just because we don't use the
-       // return value.
-       //
-       // The last clause tells the assembler that this can
-       // potentially change the condition codes and arbitrary
-       // memory locations.
-
-       asm volatile("int %1"
-                    : "=a" (ret)
-                    : "i" (T_SYSCALL),
-                      "a" (num),
-                      "d" (a1),
-                      "c" (a2),
-                      "b" (a3),
-                      "D" (a4),
-                      "S" (a5)
-                    : "cc", "memory");
-       return ret;
-}
-
-intreg_t syscall(uint16_t num, intreg_t a1,
-                intreg_t a2, intreg_t a3,
-                intreg_t a4, intreg_t a5)
-{
-       #ifndef SYSCALL_TRAP
-               return syscall_sysenter(num, a1, a2, a3, a4, a5);
-       #else
-               return syscall_trap(num, a1, a2, a3, a4, a5);
-       #endif
-}
diff --git a/user/parlib/src/syscall_sparc.c b/user/parlib/src/syscall_sparc.c
deleted file mode 100644 (file)
index 2528869..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-__asm__ (".global syscall              \n\t"
-         "syscall:                     \n\t"
-         "mov %o0,%g1          \n\t"
-         "mov %o1,%o0          \n\t"
-         "mov %o2,%o1          \n\t"
-         "mov %o3,%o2          \n\t"
-         "mov %o4,%o3          \n\t"
-         "mov %o5,%o4          \n\t"
-         "retl                 \n\t"
-         "ta 8                 \n\t");