diff --git a/build-devkit.sh b/build-devkit.sh index a7ab5cc..f241564 100644 --- a/build-devkit.sh +++ b/build-devkit.sh @@ -10,8 +10,8 @@ BINUTILS_VER=2.16.1 GCC_VER=4.0.2 NEWLIB_VER=1.13.0 LIBOGC_VER=20050812 -LIBGBA_VER=20050914 -LIBNDS_VER=20050921 +LIBGBA_VER=20051018 +LIBNDS_VER=20051018 BINUTILS="binutils-$BINUTILS_VER.tar.bz2" GCC_CORE="gcc-core-$GCC_VER.tar.bz2" @@ -272,42 +272,42 @@ scriptdir=$(pwd)/$basedir/scripts BUILDSCRIPTDIR=$(pwd) echo "Extracting $BINUTILS" -#tar -xjvf $SRCDIR/$BINUTILS || { echo "Error extracting "$BINUTILS; exit; } +tar -xjvf $SRCDIR/$BINUTILS || { echo "Error extracting "$BINUTILS; exit; } echo "Extracting $GCC_CORE" -#tar -xjvf $SRCDIR/$GCC_CORE || { echo "Error extracting "$GCC_CORE; exit; } +tar -xjvf $SRCDIR/$GCC_CORE || { echo "Error extracting "$GCC_CORE; exit; } echo "Extracting $GCC_GPP" -#tar -xjvf $SRCDIR/$GCC_GPP || { echo "Error extracting "$GCC_GPP; exit; } +tar -xjvf $SRCDIR/$GCC_GPP || { echo "Error extracting "$GCC_GPP; exit; } echo "Extracting $NEWLIB" -#tar -xzvf $SRCDIR/$NEWLIB || { echo "Error extracting "$NEWLIB; exit; } +tar -xzvf $SRCDIR/$NEWLIB || { echo "Error extracting "$NEWLIB; exit; } if [ $VERSION -eq 2 ] then echo "Extracting $LIBOGC" -# mkdir -p $LIBOGC_SRCDIR -# bzip2 -cd $SRCDIR/$LIBOGC | tar -xv -C $LIBOGC_SRCDIR || { echo "Error extracting "$LIBOGC; exit; } + mkdir -p $LIBOGC_SRCDIR + bzip2 -cd $SRCDIR/$LIBOGC | tar -xv -C $LIBOGC_SRCDIR || { echo "Error extracting "$LIBOGC; exit; } fi if [ $VERSION -eq 1 ] then echo "Extracting $LIBNDS" -# mkdir -p $LIBNDS_SRCDIR -# bzip2 -cd $SRCDIR/$LIBNDS | tar -xv -C $LIBNDS_SRCDIR || { echo "Error extracting "$LIBNDS; exit; } + mkdir -p $LIBNDS_SRCDIR + bzip2 -cd $SRCDIR/$LIBNDS | tar -xv -C $LIBNDS_SRCDIR || { echo "Error extracting "$LIBNDS; exit; } echo "Extracting $LIBGBA" -# mkdir -p $LIBGBA_SRCDIR -# bzip2 -cd $SRCDIR/$LIBGBA | tar -xv -C $LIBGBA_SRCDIR || { echo "Error extracting "$LIBGBA; exit; } + mkdir -p $LIBGBA_SRCDIR + bzip2 -cd $SRCDIR/$LIBGBA | tar -xv -C $LIBGBA_SRCDIR || { echo "Error extracting "$LIBGBA; exit; } fi #--------------------------------------------------------------------------------- # apply patches #--------------------------------------------------------------------------------- -#patch -p1 -d $BINUTILS_SRCDIR -i $patchdir/binutils-$BINUTILS_VER.patch || { echo "Error patching binutils"; exit; } -#patch -p1 -d $GCC_SRCDIR -i $patchdir/gcc-$GCC_VER.patch || { echo "Error patching gcc"; exit; } -#patch -p1 -d $NEWLIB_SRCDIR -i $patchdir/newlib-$NEWLIB_VER.patch || { echo "Error patching newlib"; exit; } +patch -p1 -d $BINUTILS_SRCDIR -i $patchdir/binutils-$BINUTILS_VER.patch || { echo "Error patching binutils"; exit; } +patch -p1 -d $GCC_SRCDIR -i $patchdir/gcc-$GCC_VER.patch || { echo "Error patching gcc"; exit; } +patch -p1 -d $NEWLIB_SRCDIR -i $patchdir/newlib-$NEWLIB_VER.patch || { echo "Error patching newlib"; exit; } #--------------------------------------------------------------------------------- diff --git a/dkarm/crtls/ds_cart.specs b/dkarm/crtls/ds_cart.specs index f3a6ff4..8bd5778 100644 --- a/dkarm/crtls/ds_cart.specs +++ b/dkarm/crtls/ds_cart.specs @@ -1,4 +1,8 @@ %rename link old_link +%rename link_gcc_c_sequence old_gcc_c_sequence + +*link_gcc_c_sequence: +%(old_gcc_c_sequence) --start-group -lsysbase -lc --end-group *link: %(old_link) -T ds_cart.ld%s diff --git a/dkarm/patches/binutils-2.16.1.patch b/dkarm/patches/binutils-2.16.1.patch index a24d96c..71d0549 100644 --- a/dkarm/patches/binutils-2.16.1.patch +++ b/dkarm/patches/binutils-2.16.1.patch @@ -1,6 +1,6 @@ -diff -Nbaur --exclude=*.info* binutils-2.16.1/bfd/doc/chew.c binutils-2.16.1-new/bfd/doc/chew.c +diff -Nbaur --exclude=*.info* binutils-2.16.1/bfd/doc/chew.c binutils-2.16.1-arm/bfd/doc/chew.c --- binutils-2.16.1/bfd/doc/chew.c Thu Mar 3 11:41:02 2005 -+++ binutils-2.16.1-new/bfd/doc/chew.c Mon Jun 20 00:14:07 2005 ++++ binutils-2.16.1-arm/bfd/doc/chew.c Mon Sep 19 03:38:45 2005 @@ -91,6 +91,12 @@ #define DEF_SIZE 5000 #define STACK 50 @@ -14,3 +14,49 @@ diff -Nbaur --exclude=*.info* binutils-2.16.1/bfd/doc/chew.c binutils-2.16.1-new int internal_wanted; int internal_mode; +diff -Nbaur --exclude=*.info* binutils-2.16.1/configure binutils-2.16.1-arm/configure +--- binutils-2.16.1/configure Mon Feb 28 14:06:59 2005 ++++ binutils-2.16.1-arm/configure Wed Sep 21 12:33:11 2005 +@@ -1034,7 +1034,7 @@ + + # Some tools are only suitable for building in a "native" situation. + # Remove these if host!=target. +-native_only="autoconf automake libtool fileutils find gawk gettext gzip hello indent m4 rcs recode sed shellutils tar textutils uudecode wdiff gprof target-groff guile perl time ash bash bzip2 prms gnuserv target-gperf" ++native_only="autoconf automake libtool fileutils find gawk gettext gzip hello indent m4 rcs recode sed shellutils tar textutils uudecode wdiff target-groff guile perl time ash bash bzip2 prms gnuserv target-gperf" + + # Similarly, some are only suitable for cross toolchains. + # Remove these if host=target. +diff -Nbaur --exclude=*.info* binutils-2.16.1/configure.in binutils-2.16.1-arm/configure.in +--- binutils-2.16.1/configure.in Sun Jun 12 20:33:06 2005 ++++ binutils-2.16.1-arm/configure.in Wed Sep 21 12:34:18 2005 +@@ -242,7 +242,7 @@ + + # Some tools are only suitable for building in a "native" situation. + # Remove these if host!=target. +-native_only="autoconf automake libtool fileutils find gawk gettext gzip hello indent m4 rcs recode sed shellutils tar textutils uudecode wdiff gprof target-groff guile perl time ash bash bzip2 prms gnuserv target-gperf" ++native_only="autoconf automake libtool fileutils find gawk gettext gzip hello indent m4 rcs recode sed shellutils tar textutils uudecode wdiff target-groff guile perl time ash bash bzip2 prms gnuserv target-gperf" + + # Similarly, some are only suitable for cross toolchains. + # Remove these if host=target. +diff -Nbaur --exclude=*.info* binutils-2.16.1/gas/config/tc-arm.c binutils-2.16.1-arm/gas/config/tc-arm.c +--- binutils-2.16.1/gas/config/tc-arm.c Tue May 17 20:51:33 2005 ++++ binutils-2.16.1-arm/gas/config/tc-arm.c Fri Sep 23 03:58:13 2005 +@@ -12697,13 +12697,18 @@ + {"arm926ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2}, + {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2}, + {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, ++ {"arm946e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, + {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2}, + {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, ++ {"arm966e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, ++ {"arm968e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, + {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1}, ++ {"arm10tdmi", ARM_ARCH_V5T, FPU_ARCH_VFP_V1}, + {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, + {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, + {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1}, + {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, ++ {"arm1022e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2}, + {"arm1026ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2}, + {"arm1026ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2}, + {"arm1136js", ARM_ARCH_V6, FPU_NONE}, diff --git a/dkarm/patches/newlib-1.13.0.patch b/dkarm/patches/newlib-1.13.0.patch index b67c03c..4a39bca 100644 --- a/dkarm/patches/newlib-1.13.0.patch +++ b/dkarm/patches/newlib-1.13.0.patch @@ -2140,8 +2140,8 @@ diff -Nbaur newlib-1.13.0/libgloss/libsysbase/gettod.c newlib-1.13.0-new/libglos +stub_warning(_gettimeofday) diff -Nbaur newlib-1.13.0/libgloss/libsysbase/iosupport.c newlib-1.13.0-new/libgloss/libsysbase/iosupport.c --- newlib-1.13.0/libgloss/libsysbase/iosupport.c Thu Jan 1 00:00:00 1970 -+++ newlib-1.13.0-new/libgloss/libsysbase/iosupport.c Tue Aug 30 22:31:49 2005 -@@ -0,0 +1,50 @@ ++++ newlib-1.13.0-new/libgloss/libsysbase/iosupport.c Fri Sep 16 09:37:03 2005 +@@ -0,0 +1,91 @@ +#include +#include + @@ -2175,7 +2175,7 @@ diff -Nbaur newlib-1.13.0/libgloss/libsysbase/iosupport.c newlib-1.13.0-new/libg +//--------------------------------------------------------------------------------- +const devoptab_t dotab_stdnull = { +//--------------------------------------------------------------------------------- -+ "stdin", ++ "stdnull", + stdnull_open, + stdnull_close, + stdnull_write, @@ -2192,6 +2192,47 @@ diff -Nbaur newlib-1.13.0/libgloss/libsysbase/iosupport.c newlib-1.13.0-new/libg + &dotab_stdnull, &dotab_stdnull, &dotab_stdnull, &dotab_stdnull, + &dotab_stdnull, &dotab_stdnull, &dotab_stdnull, &dotab_stdnull +}; ++ ++ ++//--------------------------------------------------------------------------------- ++int FindDevice(char* name) { ++//--------------------------------------------------------------------------------- ++ int i, namelen, dev = -1; ++ ++ while(iname); ++ if(strncmp(devoptab_list[i]->name,file,namelen)==0 && file[namelen] == ':' ) { ++ dev = i; ++ break; ++ } ++ } ++ i++; ++ } ++ ++ return dev; ++} ++ ++//--------------------------------------------------------------------------------- ++int AddDevice( const devoptab_t* device) { ++//--------------------------------------------------------------------------------- ++ ++ int devnum; ++ ++ for ( devnum = 3;devnum name, device->name) || ++ strcmp(devoptab_list[devnum]->name, "stdnull") ) ++ break; ++ } ++ ++ if ( devnum == STD_MAX ) { ++ devnum = -1; ++ } else { ++ devoptab[devnum] = device; ++ } ++ return devnum; ++} diff -Nbaur newlib-1.13.0/libgloss/libsysbase/isatty.c newlib-1.13.0-new/libgloss/libsysbase/isatty.c --- newlib-1.13.0/libgloss/libsysbase/isatty.c Thu Jan 1 00:00:00 1970 +++ newlib-1.13.0-new/libgloss/libsysbase/isatty.c Tue Aug 30 01:02:43 2005 @@ -2295,8 +2336,8 @@ diff -Nbaur newlib-1.13.0/libgloss/libsysbase/malloc_vars.c newlib-1.13.0-new/li +char *fake_heap_start = (char*)0; diff -Nbaur newlib-1.13.0/libgloss/libsysbase/open.c newlib-1.13.0-new/libgloss/libsysbase/open.c --- newlib-1.13.0/libgloss/libsysbase/open.c Thu Jan 1 00:00:00 1970 -+++ newlib-1.13.0-new/libgloss/libsysbase/open.c Fri Sep 9 17:54:44 2005 -@@ -0,0 +1,57 @@ ++++ newlib-1.13.0-new/libgloss/libsysbase/open.c Fri Sep 16 03:21:31 2005 +@@ -0,0 +1,42 @@ +#include <_ansi.h> +#include <_syslist.h> +#include @@ -2325,30 +2366,15 @@ diff -Nbaur newlib-1.13.0/libgloss/libsysbase/open.c newlib-1.13.0-new/libgloss/ + struct _reent *r = _REENT; +#endif + int handle; -+ int i,dev,fd,namelen; -+ char lfile[256]; ++ int dev,fd; + -+ iprintf("%s\n",file); + -+ i = 0; -+ dev = -1; -+ while(iname); -+ if(strncmp(devoptab_list[i]->name,file,namelen)==0 && file[namelen] == ':' ) { -+ dev = i; -+ break; -+ } -+ } -+ i++; -+ } -+ -+ if(i>=STD_MAX) return -1; ++ dev = FindDevice(file); + + fd = -1; + handle = -1; + if(dev!=-1 && devoptab_list[dev]->open_r) { -+ fd = devoptab_list[dev]->open_r(r,lfile,flags,mode); ++ fd = devoptab_list[dev]->open_r(r,file,flags,mode); + if(fd!=-1) handle = _SHIFTL(dev,12,4)|(fd&0x0fff); + } + @@ -2642,9 +2668,295 @@ diff -Nbaur newlib-1.13.0/libgloss/libsysbase/write.c newlib-1.13.0-new/libgloss + } + return ret; +} +diff -Nbaur newlib-1.13.0/newlib/libc/include/stdint.h newlib-1.13.0-new/newlib/libc/include/stdint.h +--- newlib-1.13.0/newlib/libc/include/stdint.h Thu Jan 1 00:00:00 1970 ++++ newlib-1.13.0-new/newlib/libc/include/stdint.h Mon Sep 19 23:33:16 2005 +@@ -0,0 +1,282 @@ ++/* ++ * Copyright (c) 2004, 2005 by ++ * Ralf Corsepius, Ulm/Germany. All rights reserved. ++ * ++ * Permission to use, copy, modify, and distribute this software ++ * is freely granted, provided that this notice is preserved. ++ */ ++ ++/* ++ * @todo - Add fast_t types. ++ * @todo - Add support for wint_t types. ++ */ ++ ++#ifndef _STDINT_H ++#define _STDINT_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#if defined(__GNUC__) && (__GNUC__ >= 3 ) \ ++ && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2 ) ++#define __EXP(x) __##x##__ ++#else ++#define __EXP(x) x ++#include ++#endif ++ ++#if __EXP(SCHAR_MAX) == 0x7f ++typedef signed char int8_t ; ++typedef unsigned char uint8_t ; ++#define __int8_t_defined 1 ++#endif ++ ++#if __int8_t_defined ++typedef signed char int_least8_t; ++typedef unsigned char uint_least8_t; ++#define __int_least8_t_defined 1 ++#endif ++ ++#if __EXP(SHRT_MAX) == 0x7fff ++typedef signed short int16_t; ++typedef unsigned short uint16_t; ++#define __int16_t_defined 1 ++#elif __EXP(INT_MAX) == 0x7fff ++typedef signed int int16_t; ++typedef unsigned int uint16_t; ++#define __int16_t_defined 1 ++#elif __EXP(SCHAR_MAX) == 0x7fff ++typedef signed char int16_t; ++typedef unsigned char uint16_t; ++#define __int16_t_defined 1 ++#endif ++ ++#if __int16_t_defined ++typedef int16_t int_least16_t; ++typedef uint16_t uint_least16_t; ++#define __int_least16_t_defined 1 ++ ++#ifndef __int_least8_t_defined ++typedef int16_t int_least8_t; ++typedef uint16_t uint_least8_t; ++#define __int_least8_t_defined 1 ++#endif ++#endif ++ ++#if __EXP(INT_MAX) == 0x7fffffffL ++typedef signed int int32_t; ++typedef unsigned int uint32_t; ++#define __int32_t_defined 1 ++#elif __EXP(LONG_MAX) == 0x7fffffffL ++typedef signed long int32_t; ++typedef unsigned long uint32_t; ++#define __int32_t_defined 1 ++#define __have_long32 1 ++#elif __EXP(SHRT_MAX) == 0x7fffffffL ++typedef signed short int32_t; ++typedef unsigned short uint32_t; ++#define __int32_t_defined 1 ++#elif __EXP(SCHAR_MAX) == 0x7fffffffL ++typedef signed char int32_t; ++typedef unsigned char uint32_t; ++#define __int32_t_defined 1 ++#endif ++ ++#if __int32_t_defined ++typedef int32_t int_least32_t; ++typedef uint32_t uint_least32_t; ++#define __int_least32_t_defined 1 ++ ++#ifndef __int_least8_t_defined ++typedef int32_t int_least8_t; ++typedef uint32_t uint_least8_t; ++#define __int_least8_t_defined 1 ++#endif ++ ++#ifndef __int_least16_t_defined ++typedef int32_t int_least16_t; ++typedef uint32_t uint_least16_t; ++#define __int_least16_t_defined 1 ++#endif ++#endif ++ ++#if __EXP(LONG_MAX) > 0x7fffffff ++typedef signed long int64_t; ++typedef unsigned long uint64_t; ++#define __int64_t_defined 1 ++#define __have_long64 1 ++#elif defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ++typedef signed long long int64_t; ++typedef unsigned long long uint64_t; ++#define __int64_t_defined 1 ++#define __have_longlong64 1 ++#elif defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ++typedef signed long long int64_t; ++typedef unsigned long long uint64_t; ++#define __int64_t_defined 1 ++#define __have_longlong64 1 ++#elif __EXP(INT_MAX) > 0x7fffffff ++typedef signed int int64_t; ++typedef unsigned int uint64_t; ++#define __int64_t_defined 1 ++#endif ++ ++#if __int64_t_defined ++typedef int64_t int_least64_t; ++typedef uint64_t uint_least64_t; ++#define __int_least64_t_defined 1 ++ ++#ifndef __int_least8_t_defined ++typedef int64_t int_least8_t; ++typedef uint64_t uint_least8_t; ++#define __int_least8_t_defined 1 ++#endif ++ ++#ifndef __int_least16_t_defined ++typedef int64_t int_least16_t; ++typedef uint64_t uint_least16_t; ++#define __int_least16_t_defined 1 ++#endif ++ ++#ifndef __int_least32_t_defined ++typedef int64_t int_least32_t; ++typedef uint64_t uint_least32_t; ++#define __int_least32_t_defined 1 ++#endif ++#endif ++ ++#if __have_longlong64 ++typedef signed long long intmax_t; ++typedef unsigned long long uintmax_t; ++#else ++typedef signed long intmax_t; ++typedef unsigned long uintmax_t; ++#endif ++ ++/* ++ * GCC doesn't provide an propriate macro for [u]intptr_t ++ * For now, use __PTRDIFF_TYPE__ ++ */ ++#if defined(__PTRDIFF_TYPE__) ++typedef signed __PTRDIFF_TYPE__ intptr_t; ++typedef unsigned __PTRDIFF_TYPE__ uintptr_t; ++#else ++/* ++ * Fallback to hardcoded values, ++ * should be valid on cpu's with 32bit int/32bit void* ++ */ ++typedef signed long intptr_t; ++typedef unsigned long uintptr_t; ++#endif ++ ++/* Limits of Specified-Width Integer Types */ ++ ++#if __int8_t_defined ++#define INT8_MIN -128 ++#define INT8_MAX 127 ++#define UINT8_MAX 255 ++#endif ++ ++#if __int_least8_t_defined ++#define INTLEAST8_MIN -128 ++#define INTLEAST8_MAX 127 ++#define UINTLEAST8_MAX 255 ++#else ++#error required type int_least8_t missing ++#endif ++ ++#if __int16_t_defined ++#define INT16_MIN -32768 ++#define INT16_MAX 32767 ++#define UINT16_MAX 65535 ++#endif ++ ++#if __int_least16_t_defined ++#define INTLEAST16_MIN -32768 ++#define INTLEAST16_MAX 32767 ++#define UINTLEAST16_MAX 65535 ++#else ++#error required type int_least16_t missing ++#endif ++ ++#if __int32_t_defined ++#define INT32_MIN -2147483648 ++#define INT32_MAX 2147483647 ++#define UINT32_MAX 4294967295 ++#endif ++ ++#if __int_least32_t_defined ++#define INTLEAST32_MIN -2147483648 ++#define INTLEAST32_MAX 2147483647 ++#define UINTLEAST32_MAX 4294967295 ++#else ++#error required type int_least32_t missing ++#endif ++ ++#if __int64_t_defined ++#define INT64_MIN -9223372036854775808 ++#define INT64_MAX 9223372036854775807 ++#define UINT64_MAX 18446744073709551615 ++#endif ++ ++#if __int_least64_t_defined ++#define INTLEAST64_MIN -9223372036854775808 ++#define INTLEAST64_MAX 9223372036854775807 ++#define UINTLEAST64_MAX 18446744073709551615 ++#endif ++ ++/* This must match size_t in stddef.h, currently long unsigned int */ ++#define SIZE_MIN (-__EXP(LONG_MAX) - 1L) ++#define SIZE_MAX __EXP(LONG_MAX) ++ ++/* This must match sig_atomic_t in (currently int) */ ++#define SIG_ATOMIC_MIN (-__EXP(INT_MAX) - 1) ++#define SIG_ATOMIC_MAX __EXP(INT_MAX) ++ ++/* This must match ptrdiff_t in (currently long int) */ ++#define PTRDIFF_MIN (-__EXP(LONG_MAX) - 1L) ++#define PTHDIFF_MAX __EXT(LONG_MAX) ++ ++#undef __EXP ++ ++/** Macros for minimum-width integer constant expressions */ ++#define INT8_C(x) x ++#define UINT8_C(x) x##U ++ ++#define INT16_C(x) x ++#define UINT16_C(x) x##U ++ ++#if __have_long32 ++#define INT32_C(x) x##L ++#define UINT32_C(x) x##UL ++#else ++#define INT32_C(x) x ++#define UINT32_C(x) x##U ++#endif ++ ++#if __int64_t_defined ++#if __have_longlong64 ++#define INT64_C(x) x##LL ++#define UINT64_C(x) x##ULL ++#else ++#define INT64_C(x) x##L ++#define UINT64_C(x) x##UL ++#endif ++#endif ++ ++/** Macros for greatest-width integer constant expression */ ++#if __have_longlong64 ++#define INTMAX_C(x) x##LL ++#define UINTMAX_C(x) x##ULL ++#else ++#define INTMAX_C(x) x##L ++#define UINTMAX_C(x) x##UL ++#endif ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _STDINT_H */ diff -Nbaur newlib-1.13.0/newlib/libc/include/stdio.h newlib-1.13.0-new/newlib/libc/include/stdio.h --- newlib-1.13.0/newlib/libc/include/stdio.h Wed Nov 24 00:45:40 2004 -+++ newlib-1.13.0-new/newlib/libc/include/stdio.h Sat Sep 3 19:55:57 2005 ++++ newlib-1.13.0-new/newlib/libc/include/stdio.h Wed Sep 14 04:49:02 2005 @@ -244,6 +244,7 @@ int _EXFUN(vfiscanf, (FILE *, const char *, __VALIST)); int _EXFUN(vfscanf, (FILE *, const char *, __VALIST)); @@ -2655,8 +2967,8 @@ diff -Nbaur newlib-1.13.0/newlib/libc/include/stdio.h newlib-1.13.0-new/newlib/l int _EXFUN(vsscanf, (const char *, const char *, __VALIST)); diff -Nbaur newlib-1.13.0/newlib/libc/include/sys/iosupport.h newlib-1.13.0-new/newlib/libc/include/sys/iosupport.h --- newlib-1.13.0/newlib/libc/include/sys/iosupport.h Thu Jan 1 00:00:00 1970 -+++ newlib-1.13.0-new/newlib/libc/include/sys/iosupport.h Tue Aug 30 13:04:54 2005 -@@ -0,0 +1,32 @@ ++++ newlib-1.13.0-new/newlib/libc/include/sys/iosupport.h Fri Sep 16 03:20:57 2005 +@@ -0,0 +1,33 @@ +#ifndef __iosupp_h__ +#define __iosupp_h__ + @@ -2687,5 +2999,6 @@ diff -Nbaur newlib-1.13.0/newlib/libc/include/sys/iosupport.h newlib-1.13.0-new/ +extern const devoptab_t *devoptab_list[]; + +int AddDevice( const devoptab_t* device); ++int FindDevice(char* name); + +#endif diff --git a/dkpsp/patches/newlib-1.13.0.patch b/dkpsp/patches/newlib-1.13.0.patch index 1f08323..fbc8d83 100644 --- a/dkpsp/patches/newlib-1.13.0.patch +++ b/dkpsp/patches/newlib-1.13.0.patch @@ -1,5 +1,5 @@ ---- newlib-1.13.0.orig/config.sub 2004-11-15 17:18:39.000000000 -0800 -+++ newlib-psp/config.sub 2005-06-24 17:04:02.000000000 -0700 +--- newlib-1.13.0.orig/config.sub 2004-11-15 20:18:39.000000000 -0500 ++++ newlib-psp/config.sub 2005-07-06 22:53:22.000000000 -0400 @@ -253,6 +253,7 @@ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ @@ -27,8 +27,8 @@ mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; ---- newlib-1.13.0.orig/configure 2004-12-16 11:51:28.000000000 -0800 -+++ newlib-psp/configure 2005-06-19 18:09:12.000000000 -0700 +--- newlib-1.13.0.orig/configure 2004-12-16 14:51:28.000000000 -0500 ++++ newlib-psp/configure 2005-07-06 22:53:22.000000000 -0400 @@ -1507,6 +1507,9 @@ mips*-*-linux*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" @@ -39,8 +39,8 @@ mips*-*-*) noconfigdirs="$noconfigdirs gprof ${libgcj}" ;; ---- newlib-1.13.0.orig/configure.in 2004-12-16 11:51:28.000000000 -0800 -+++ newlib-psp/configure.in 2005-06-19 18:09:12.000000000 -0700 +--- newlib-1.13.0.orig/configure.in 2004-12-16 14:51:28.000000000 -0500 ++++ newlib-psp/configure.in 2005-07-06 22:53:22.000000000 -0400 @@ -716,6 +716,9 @@ mips*-*-linux*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" @@ -51,8 +51,41 @@ mips*-*-*) noconfigdirs="$noconfigdirs gprof ${libgcj}" ;; ---- newlib-1.13.0.orig/newlib/libc/sys/psp/Makefile.am 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/Makefile.am 2005-08-29 23:32:10.035769520 -0700 +--- newlib-1.13.0.orig/newlib/configure.host 2004-10-05 15:44:24.000000000 -0400 ++++ newlib-psp/newlib/configure.host 2005-07-28 15:42:00.000000000 -0400 +@@ -570,7 +570,14 @@ + ;; + mips*-*-elf*) + default_newlib_io_long_long="yes" +- newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES" ++ case "${host}" in ++ mipsallegrex*-psp-*) ++ sys_dir=psp ++ syscall_dir=syscalls ++ newlib_cflags="${newlib_cflags} -G0 -DPREFER_SIZE_OVER_SPEED -DCOMPACT_CTYPE -DCLOCK_PROVIDED -I${prefix}/psp/sdk/include" ;; ++ *) ++ newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES" ;; ++ esac + ;; + mmix-*) + syscall_dir=syscalls +--- newlib-1.13.0.orig/newlib/libc/include/sys/config.h 2004-06-22 17:54:51.000000000 -0400 ++++ newlib-psp/newlib/libc/include/sys/config.h 2005-08-16 16:40:10.000000000 -0400 +@@ -94,6 +94,12 @@ + #endif + #endif + ++/* We compile newlib with -G0 for PSP, but if we're compiling an app with $gp enabled, ++ then _impure_ptr is expected to live in .sdata. */ ++#if defined(__psp__) ++#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__section__(".sdata"))) ++#endif ++ + #ifdef __xstormy16__ + #define __SMALL_BITFIELDS + #undef INT_MAX +--- newlib-1.13.0.orig/newlib/libc/sys/psp/Makefile.am 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/Makefile.am 2005-10-02 20:55:44.000000000 -0400 @@ -0,0 +1,22 @@ +## Process this file with automake to generate Makefile.in + @@ -63,8 +96,8 @@ +noinst_LIBRARIES = lib.a + +LIBCGLUE_MULT_OBJS = _close.o _exit.o _fork.o _fstat.o _getpid.o _gettimeofday.o _kill.o _lseek.o \ -+ _open.o _read.o _sbrk.o _wait.o _write.o clock.o isatty.o time.o _link.o _unlink.o \ -+ _opendir.o _readdir.o _closedir.o getcwd.o chdir.o mkdir.o rmdir.o realpath.o _stat.o truncate.o access.o ++ _open.o _read.o _sbrk.o _wait.o _write.o clock.o isatty.o time.o _link.o _unlink.o sleep.o \ ++ opendir.o readdir.o closedir.o getcwd.o chdir.o mkdir.o rmdir.o realpath.o _stat.o truncate.o access.o + +lib_a_SOURCES = libcglue.c pspcwd.c +lib_a_LIBADD = $(LIBCGLUE_MULT_OBJS) @@ -76,23 +109,8 @@ + +ACLOCAL_AMFLAGS = -I ../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host ---- newlib-1.13.0.orig/newlib/libc/sys/psp/configure.in 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/configure.in 2005-07-23 22:43:33.000000000 -0700 -@@ -0,0 +1,12 @@ -+dnl This is the newlib/libc/sys/psp configure.in file. -+dnl Process this file with autoconf to produce a configure script. -+ -+AC_PREREQ(2.5) -+AC_INIT(libcglue.c) -+ -+dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. -+AC_CONFIG_AUX_DIR(../../../..) -+ -+NEWLIB_CONFIGURE(../../..) -+ -+AC_OUTPUT(Makefile) ---- newlib-1.13.0.orig/newlib/libc/sys/psp/Makefile.in 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/Makefile.in 2005-08-29 23:40:53.899130184 -0700 +--- newlib-1.13.0.orig/newlib/libc/sys/psp/Makefile.in 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/Makefile.in 2005-10-02 20:55:42.000000000 -0400 @@ -0,0 +1,344 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + @@ -188,7 +206,7 @@ + +noinst_LIBRARIES = lib.a + -+LIBCGLUE_MULT_OBJS = _close.o _exit.o _fork.o _fstat.o _getpid.o _gettimeofday.o _kill.o _lseek.o _open.o _read.o _sbrk.o _wait.o _write.o clock.o isatty.o time.o _link.o _unlink.o _opendir.o _readdir.o _closedir.o getcwd.o chdir.o mkdir.o rmdir.o realpath.o _stat.o truncate.o access.o ++LIBCGLUE_MULT_OBJS = _close.o _exit.o _fork.o _fstat.o _getpid.o _gettimeofday.o _kill.o _lseek.o _open.o _read.o _sbrk.o _wait.o _write.o clock.o isatty.o time.o _link.o _unlink.o sleep.o opendir.o readdir.o closedir.o getcwd.o chdir.o mkdir.o rmdir.o realpath.o _stat.o truncate.o access.o + + +lib_a_SOURCES = libcglue.c pspcwd.c @@ -207,8 +225,8 @@ +LIBS = @LIBS@ +lib_a_DEPENDENCIES = _close.o _exit.o _fork.o _fstat.o _getpid.o \ +_gettimeofday.o _kill.o _lseek.o _open.o _read.o _sbrk.o _wait.o \ -+_write.o clock.o isatty.o time.o _link.o _unlink.o _opendir.o \ -+_readdir.o _closedir.o getcwd.o chdir.o mkdir.o rmdir.o realpath.o \ ++_write.o clock.o isatty.o time.o _link.o _unlink.o sleep.o opendir.o \ ++readdir.o closedir.o getcwd.o chdir.o mkdir.o rmdir.o realpath.o \ +_stat.o truncate.o access.o +lib_a_OBJECTS = libcglue.o pspcwd.o +CFLAGS = @CFLAGS@ @@ -438,773 +456,8 @@ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: ---- newlib-1.13.0.orig/newlib/libc/sys/psp/libcglue.c 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/libcglue.c 2005-08-29 23:32:33.477205880 -0700 -@@ -0,0 +1,589 @@ -+/* -+ * PSP Software Development Kit - http://www.pspdev.org -+ * ----------------------------------------------------------------------- -+ * Licensed under the BSD license, see LICENSE in PSPSDK root for details. -+ * -+ * libcglue.c - Newlib-compatible system calls. -+ * -+ * Copyright (c) 2005 Marcus R. Brown -+ * Copyright (c) 2005 James Forshaw -+ * Copyright (c) 2005 John Kelley -+ * Copyright (c) 2005 Jim Paris -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* These functions aren't exposed in any public headers, and they probably don't need to be. */ -+int sceKernelStdin(void); -+int sceKernelStdout(void); -+int sceKernelStderr(void); -+ -+extern char * __psp_argv_0; -+extern int __psp_cwd_initialized; -+extern char __psp_cwd[MAXPATHLEN + 1]; -+extern void __psp_init_cwd(void); -+extern int __psp_path_absolute(const char *in, char *out, int len); -+ -+#ifdef F_getcwd -+char *getcwd(char *buf, size_t size) -+{ -+ if(!__psp_cwd_initialized) -+ __psp_init_cwd(); -+ -+ if(!buf) { -+ errno = EINVAL; -+ return NULL; -+ } -+ -+ if(strlen(__psp_cwd) >= size) { -+ errno = ERANGE; -+ return NULL; -+ } -+ -+ strcpy(buf, __psp_cwd); -+ return buf; -+} -+#endif -+ -+#ifdef F_chdir -+int chdir(const char *path) -+{ -+ char dest[MAXPATHLEN + 1]; -+ SceUID uid; -+ -+ if(!__psp_cwd_initialized) -+ __psp_init_cwd(); -+ -+ if(__psp_path_absolute(path, dest, MAXPATHLEN) < 0) { -+ errno = ENAMETOOLONG; -+ return -1; -+ } -+ -+ /* sceIoChdir doesn't give an indication of whether it worked, -+ so test for existance by attempting to open the dir */ -+ uid = sceIoDopen(dest); -+ if(uid < 0) { -+ errno = ENOTDIR; -+ return -1; -+ } -+ sceIoDclose(uid); -+ -+ sceIoChdir(dest); -+ strcpy(__psp_cwd, dest); -+ return 0; -+} -+#endif -+ -+#ifdef F_mkdir -+int mkdir(const char *pathname, mode_t mode) -+{ -+ /* Make sure the CWD has been set. */ -+ if (!__psp_cwd_initialized) { -+ __psp_init_cwd(); -+ } -+ -+ return sceIoMkdir(pathname, mode); -+} -+#endif -+ -+#ifdef F_rmdir -+int rmdir(const char *pathname) -+{ -+ /* Make sure the CWD has been set. */ -+ if (!__psp_cwd_initialized) { -+ __psp_init_cwd(); -+ } -+ -+ return sceIoRmdir(pathname); -+} -+#endif -+ -+#ifdef F_realpath -+char *realpath(const char *path, char *resolved_path) -+{ -+ if(!path || !resolved_path) { -+ errno = EINVAL; -+ return NULL; -+ } -+ if(__psp_path_absolute(path, resolved_path, MAXPATHLEN) < 0) { -+ errno = ENAMETOOLONG; -+ return NULL; -+ } -+ return resolved_path; -+} -+#endif -+ -+/* Wrappers of the standard open(), close(), read(), write(), unlink() and lseek() routines. */ -+#ifdef F__open -+int _open(const char *name, int flags, int mode) -+{ -+ int sce_flags; -+ -+ /* Make sure the CWD has been set. */ -+ if (!__psp_cwd_initialized) { -+ __psp_init_cwd(); -+ } -+ -+ /* O_RDONLY starts at 0, where PSP_O_RDONLY starts at 1, so remap the read/write -+ flags by adding 1. */ -+ sce_flags = (flags & O_ACCMODE) + 1; -+ -+ /* Translate standard open flags into the flags understood by the PSP kernel. */ -+ if (flags & O_APPEND) { -+ sce_flags |= PSP_O_APPEND; -+ } -+ if (flags & O_CREAT) { -+ sce_flags |= PSP_O_CREAT; -+ } -+ if (flags & O_TRUNC) { -+ sce_flags |= PSP_O_TRUNC; -+ } -+ if (flags & O_EXCL) { -+ sce_flags |= PSP_O_EXCL; -+ } -+ if (flags & O_NONBLOCK) { -+ sce_flags |= PSP_O_NBLOCK; -+ } -+ -+ return sceIoOpen(name, sce_flags, mode); -+} -+#endif -+ -+#ifdef F__close -+int _close(int fd) -+{ -+ int sce_fd = fd; -+ -+ if (fd == STDIN_FILENO) { -+ sce_fd = sceKernelStdin(); -+ } else if (fd == STDOUT_FILENO) { -+ sce_fd = sceKernelStdout(); -+ } else if (fd == STDERR_FILENO) { -+ sce_fd == sceKernelStderr(); -+ } -+ -+ if (sce_fd < 0) { -+ return -EBADF; -+ } -+ -+ return sceIoClose(sce_fd); -+} -+#endif -+ -+#ifdef F__read -+int _read(int fd, void *buf, size_t size) -+{ -+ int sce_fd = fd; -+ -+ if (fd == STDIN_FILENO) { -+ sce_fd = sceKernelStdin(); -+ } else if (fd == STDOUT_FILENO) { -+ sce_fd = sceKernelStdout(); -+ } else if (fd == STDERR_FILENO) { -+ sce_fd = sceKernelStderr(); -+ } -+ -+ if (sce_fd < 0) { -+ return -EBADF; -+ } -+ -+ return sceIoRead(sce_fd, buf, size); -+} -+#endif -+ -+#ifdef F__write -+int _write(int fd, const void *buf, size_t size) -+{ -+ int sce_fd = fd; -+ -+ if (fd == STDIN_FILENO) { -+ sce_fd = sceKernelStdin(); -+ } else if (fd == STDOUT_FILENO) { -+ sce_fd = sceKernelStdout(); -+ } else if (fd == STDERR_FILENO) { -+ sce_fd = sceKernelStderr(); -+ } -+ -+ if (sce_fd < 0) { -+ return -EBADF; -+ } -+ -+ return sceIoWrite(sce_fd, buf, size); -+} -+#endif -+ -+#ifdef F__lseek -+off_t _lseek(int fd, off_t offset, int whence) -+{ -+ int sce_fd = fd; -+ -+ if (fd == STDIN_FILENO) { -+ sce_fd = sceKernelStdin(); -+ } else if (fd == STDOUT_FILENO) { -+ sce_fd = sceKernelStdout(); -+ } else if (fd == STDERR_FILENO) { -+ sce_fd = sceKernelStderr(); -+ } -+ -+ if (sce_fd < 0) { -+ return -EBADF; -+ } -+ -+ /* We don't have to do anything with the whence argument because SEEK_* == PSP_SEEK_*. */ -+ return (off_t) sceIoLseek(sce_fd, offset, whence); -+} -+#endif -+ -+#ifdef F__unlink -+int _unlink(const char *path) -+{ -+ /* Make sure the CWD has been set. */ -+ if (!__psp_cwd_initialized) { -+ __psp_init_cwd(); -+ } -+ return sceIoRemove(path); -+} -+#endif -+ -+#ifdef F__link -+int _link(const char *name1, const char *name2) -+{ -+ return -1; -+} -+#endif -+ -+#ifdef F__opendir -+DIR *_opendir(const char *filename) -+{ -+ DIR *dirp; -+ SceUID uid; -+ -+ /* Make sure the CWD has been set. */ -+ if (!__psp_cwd_initialized) { -+ __psp_init_cwd(); -+ } -+ -+ dirp = (DIR *)malloc(sizeof(DIR)); -+ -+ uid = sceIoDopen(filename); -+ -+ if (uid < 0) -+ { -+ free(dirp); -+ return NULL; -+ } -+ -+ dirp->uid = uid; -+ -+ return dirp; -+} -+#endif -+ -+#ifdef F__readdir -+struct SceIoDirent *_readdir(DIR *dirp) -+{ -+ SceIoDirent *de; -+ -+ de = (SceIoDirent *)malloc(sizeof(SceIoDirent)); -+ -+ if (sceIoDread(dirp->uid, de) <= 0) -+ { -+ free(de); -+ return NULL; -+ } -+ -+ return de; -+} -+#endif -+ -+#ifdef F__closedir -+int _closedir(DIR *dirp) -+{ -+ if (dirp != NULL) -+ { -+ int uid; -+ uid = dirp->uid; -+ free (dirp); -+ return sceIoDclose(uid); -+ } -+ return -1; -+} -+#endif -+ -+/* Time routines. These wrap around the routines provided by the kernel. */ -+#ifdef F__gettimeofday -+int _gettimeofday(struct timeval *tp, struct timezone *tzp) -+{ -+ return sceKernelLibcGettimeofday(tp, tzp); -+} -+ -+#endif -+ -+/* If we're being built for PSPSDK's libc this function isn't defined. */ -+#ifdef F_glue_gettimeofday -+int gettimeofday(struct timeval *tp, struct timezone *tzp) -+{ -+ return sceKernelLibcGettimeofday(tp, tzp); -+} -+#endif -+ -+#if defined(F_clock) || defined(F_glue_clock) -+clock_t clock(void) -+{ -+ return sceKernelLibcClock(); -+} -+#endif -+ -+#if defined(F_time) || defined(F_glue_time) -+time_t time(time_t *t) -+{ -+ return sceKernelLibcTime(t); -+} -+#endif -+ -+/* PSP-compatible sbrk(). */ -+#if defined(F__sbrk) || defined(F_glue__sbrk) -+/* TODO: Currently our default heap is set to the maximum available block size -+ when sbrk() is first called. Sony seems to always use a default of 64KB, -+ with the expectation that user programs will override the default size with -+ their own desired size. The only reason I can think of them doing this is -+ to allow each PRX to have their own seperate heap. I think that their -+ method is overkill for most user programs. -+ -+ What I'd like to do instead is to use the default of 64KB for PRXes as Sony -+ does, but use the maximum available block size for executables. This avoids -+ the requirement of specifying the heap size manually in user programs. -+ However, we currently don't have a clean way to distinguish PRXes and normal -+ executables, so this code needs to be revisited once we do come up with a -+ way. */ -+#define DEFAULT_PRX_HEAP_SIZE_KB 64 -+ -+/* If defined it specifies the desired size of the heap, in KB. */ -+extern unsigned int sce_newlib_heap_kb_size __attribute__((weak)); -+ -+/* UID of the memory block that represents the heap. */ -+static SceUID __psp_heap_blockid; -+ -+void * _sbrk(ptrdiff_t incr) -+{ -+ static void * heap_bottom = NULL; -+ static void * heap_top = NULL; -+ static void * heap_ptr = NULL; -+ -+ /* Has our heap been initialized? */ -+ if (heap_bottom == NULL) { -+ /* No, initialize the heap. */ -+ SceSize heap_size; -+ -+ if (&sce_newlib_heap_kb_size != NULL) { -+ heap_size = sce_newlib_heap_kb_size * 1024; -+ } else { -+ /* TODO: Here we should distinguish between a PRX and a normal -+ executable. Right now we assume it's an executable. */ -+ if (0 /* is a prx */) { -+ heap_size = DEFAULT_PRX_HEAP_SIZE_KB * 1024; -+ } else { -+ heap_size = sceKernelMaxFreeMemSize(); -+ } -+ } -+ -+ __psp_heap_blockid = sceKernelAllocPartitionMemory(2, "block", PSP_SMEM_Low, heap_size, NULL); -+ if (__psp_heap_blockid > 0) { -+ heap_bottom = sceKernelGetBlockHeadAddr(__psp_heap_blockid); -+ heap_ptr = heap_bottom; -+ heap_top = (unsigned char *) heap_bottom + heap_size; -+ } -+ } -+ -+ void * heap_addr = (void *) -1; -+ void * next_heap_ptr = (void *) ((ptrdiff_t) heap_ptr + incr); -+ if ((heap_bottom != NULL) && (next_heap_ptr >= heap_bottom) && (next_heap_ptr < heap_top)) { -+ heap_addr = heap_ptr; -+ heap_ptr = next_heap_ptr; -+ } -+ -+ return heap_addr; -+} -+ -+/* Free the heap. */ -+int __psp_free_heap(void) -+{ -+ if (__psp_heap_blockid > 0) { -+ return sceKernelFreePartitionMemory(__psp_heap_blockid); -+ } -+ -+ return __psp_heap_blockid; -+} -+#endif -+ -+/* Other POSIX routines that must be defined. */ -+#ifdef F__fstat -+int _fstat(int fd, struct stat *sbuf) -+{ -+ sbuf->st_mode = S_IFCHR; -+ return 0; -+} -+#endif -+ -+#ifdef F_isatty -+int isatty(int fd) -+{ -+ return 1; -+} -+#endif -+ -+#ifdef F__stat -+static time_t psp_to_epoch_time(ScePspDateTime psp_time) -+{ -+ struct tm conv_time; -+ conv_time.tm_year = psp_time.year; -+ conv_time.tm_mon = psp_time.month; -+ conv_time.tm_mday = psp_time.day; -+ conv_time.tm_hour = psp_time.hour; -+ conv_time.tm_min = psp_time.minute; -+ conv_time.tm_sec = psp_time.second; -+ conv_time.tm_isdst = -1; -+ return mktime(&conv_time); -+} -+ -+int _stat(const char *filename, struct stat *buf) -+{ -+ SceIoStat psp_stat; -+ int ret; -+ -+ /* Make sure the CWD has been set. */ -+ if (!__psp_cwd_initialized) { -+ __psp_init_cwd(); -+ } -+ -+ memset(buf, '\0', sizeof(struct stat)); -+ if((ret = sceIoGetstat(filename, &psp_stat)) < 0) -+ return ret; -+ -+ buf->st_ctime = psp_to_epoch_time(psp_stat.st_ctime); -+ buf->st_atime = psp_to_epoch_time(psp_stat.st_atime); -+ buf->st_mtime = psp_to_epoch_time(psp_stat.st_mtime); -+ -+ buf->st_mode = (psp_stat.st_mode & 0xfff) | -+ ((FIO_S_ISLNK(psp_stat.st_mode))?(S_IFLNK):(0)) | -+ ((FIO_S_ISREG(psp_stat.st_mode))?(S_IFREG):(0)) | -+ ((FIO_S_ISDIR(psp_stat.st_mode))?(S_IFDIR):(0)); -+ buf->st_size = psp_stat.st_size; -+ return 0; -+} -+#endif -+ -+/* from stat.h in ps2sdk, this function may be correct */ -+#define FIO_CST_SIZE 0x0004 -+ -+#ifdef F_truncate -+int truncate(const char *filename, off_t length) -+{ -+ SceIoStat psp_stat; -+ -+ /* Make sure the CWD has been set. */ -+ if (!__psp_cwd_initialized) { -+ __psp_init_cwd(); -+ } -+ -+ psp_stat.st_size = length; -+ if(length < 0) -+ { -+ errno = EINVAL; -+ return -1; -+ } -+ return sceIoChstat(filename, &psp_stat, FIO_CST_SIZE); -+} -+#endif -+ -+/* Unsupported newlib system calls. */ -+#ifdef F__fork -+pid_t fork(void) -+{ -+ return (pid_t) -1; -+} -+#endif -+ -+#ifdef F__getpid -+pid_t _getpid(void) -+{ -+ return (pid_t) -1; -+} -+#endif -+ -+#ifdef F__kill -+int _kill(int unused, int unused2) -+{ -+ return -1; -+} -+#endif -+ -+#ifdef F__wait -+pid_t _wait(int *unused) -+{ -+ return (pid_t) -1; -+} -+#endif -+ -+#ifdef F_access -+int access(const char *pathname, int mode) -+{ -+ return 0; -+} -+#endif -+ -+/* Exit. */ -+#if defined(F__exit) || defined(F_glue__exit) -+extern int sce_newlib_nocreate_thread_in_start __attribute__((weak)); -+ -+extern int __psp_free_heap(void); -+ -+void _exit(int status) -+{ -+ if (&sce_newlib_nocreate_thread_in_start != NULL) { -+ /* Free the heap created by _sbrk(). */ -+ __psp_free_heap(); -+ -+ sceKernelSelfStopUnloadModule(1, 0, NULL); -+ } else { -+ if (status == 0) { -+ /* Free the heap created by _sbrk(). */ -+ __psp_free_heap(); -+ } -+ -+ sceKernelExitThread(status); -+ } -+ -+ while (1) ; -+} -+#endif -+ -+/* newlib's errno.h wants a function that returns a pointer to errno. */ -+#ifdef F_glue___errno -+#undef errno -+ -+int errno; -+ -+/* TODO: Should this be made reentrant (wrapping interrupt disable/enable -+ around it should do it)? */ -+int * __errno(void) -+{ -+ return &errno; -+} -+#endif ---- newlib-1.13.0.orig/newlib/libc/sys/psp/pspcwd.c 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/pspcwd.c 2005-07-23 21:49:44.000000000 -0700 -@@ -0,0 +1,170 @@ -+/* -+ * PSP Software Development Kit - http://www.pspdev.org -+ * ----------------------------------------------------------------------- -+ * Licensed under the BSD license, see LICENSE in PSPSDK root for details. -+ * -+ * pspcwd.c - Current working directory emulation helper functions -+ * -+ * Copyright (c) 2005 Marcus R. Brown -+ * Copyright (c) 2005 James Forshaw -+ * Copyright (c) 2005 John Kelley -+ * Copyright (c) 2005 Jim Paris -+ * -+ */ -+#include -+#include -+#include -+ -+#include -+#include -+ -+extern char * __psp_argv_0; -+int __psp_cwd_initialized = 0; -+char __psp_cwd[MAXPATHLEN + 1] = { 0 }; -+ -+/* Set the current working directory (CWD) to the path where the module was launched. */ -+void __psp_init_cwd(void) -+{ -+ if (!__psp_cwd_initialized && (__psp_argv_0 != NULL)) { -+ char base_path[MAXPATHLEN + 1]; -+ char *end; -+ -+ __psp_cwd_initialized = 1; -+ -+ strncpy(base_path, __psp_argv_0, sizeof(base_path) - 1); -+ base_path[sizeof(base_path) - 1] = '\0'; -+ end = strrchr(base_path, '/'); -+ if (end != NULL) { -+ *(end + 1) = '\0'; -+ chdir(base_path); -+ } -+ } -+} -+ -+/* Return the number of bytes taken up by the "drive:" prefix, -+ or -1 if it's not found */ -+int __psp_get_drive(const char *d) -+{ -+ int i; -+ for(i=0; d[i]; i++) { -+ if(! ((d[i] >= 'a' && d[i] <= 'z') || -+ (d[i] >= '0' && d[i] <= '9') )) -+ break; -+ } -+ if(d[i] == ':') return i+1; -+ return -1; -+} -+ -+/* Like strcpy, but returns 0 if the string doesn't fit */ -+int __psp_safe_strcpy(char *out, const char *in, int maxlen) -+{ -+ for( ; maxlen > 0 && *in ; maxlen-- ) -+ *(out++) = *(in++); -+ if(maxlen < 1) return 0; -+ *out = 0; -+ return 1; -+} -+ -+/* Like strcat, but returns 0 if the string doesn't fit */ -+int __psp_safe_strcat(char *out, const char *in, int maxlen) -+{ -+ for( ; *out ; out++,maxlen-- ) -+ continue; -+ return __psp_safe_strcpy(out, in, maxlen); -+} -+ -+/* Normalize a pathname (without leading "drive:") by removing -+ . and .. components, duplicated /, etc. */ -+int __psp_path_normalize(char *out, int len) -+{ -+ int i, j; -+ int first, next; -+ -+ /* First append "/" to make the rest easier */ -+ if(!__psp_safe_strcat(out,"/",len)) return -10; -+ -+ /* Convert "//" to "/" */ -+ for(i=0; out[i+1]; i++) { -+ if(out[i]=='/' && out[i+1]=='/') { -+ for(j=i+1; out[j]; j++) -+ out[j] = out[j+1]; -+ i--; -+ } -+ } -+ -+ /* Convert "/./" to "/" */ -+ for(i=0; out[i] && out[i+1] && out[i+2]; i++) { -+ if(out[i]=='/' && out[i+1]=='.' && out[i+2]=='/') { -+ for(j=i+1; out[j]; j++) -+ out[j] = out[j+2]; -+ i--; -+ } -+ } -+ -+ /* Convert "/asdf/../" to "/" until we can't anymore. Also -+ * convert leading "/../" to "/" */ -+ first = next = 0; -+ while(1) { -+ /* If a "../" follows, remove it and the parent */ -+ if(out[next+1] && out[next+1]=='.' && -+ out[next+2] && out[next+2]=='.' && -+ out[next+3] && out[next+3]=='/') { -+ for(j=0; out[first+j+1]; j++) -+ out[first+j+1] = out[next+j+4]; -+ first = next = 0; -+ continue; -+ } -+ -+ /* Find next slash */ -+ first = next; -+ for(next=first+1; out[next] && out[next] != '/'; next++) -+ continue; -+ if(!out[next]) break; -+ } -+ -+ /* Remove trailing "/" */ -+ for(i=1; out[i]; i++) -+ continue; -+ if(i > 1 && out[i-1] == '/') -+ out[i-1] = 0; -+ -+ return 0; -+} -+ -+/* Convert relative path to absolute path. */ -+int __psp_path_absolute(const char *in, char *out, int len) -+{ -+ int dr; -+ -+ /* See what the relative URL starts with */ -+ dr = __psp_get_drive(in); -+ if(dr > 0 && in[dr] == '/') { -+ /* It starts with "drive:/", so it's already absolute */ -+ if(!__psp_safe_strcpy(out, in, len)) -+ return -1; -+ } else if(in[0] == '/') { -+ /* It's absolute, but missing the drive, so use cwd's drive */ -+ if(strlen(__psp_cwd) >= len) -+ return -2; -+ strcpy(out, __psp_cwd); -+ dr = __psp_get_drive(out); -+ out[dr] = 0; -+ if(!__psp_safe_strcat(out, in, len)) -+ return -3; -+ } else { -+ /* It's not absolute, so append it to the current cwd */ -+ if(strlen(__psp_cwd) >= len) -+ return -4; -+ strcpy(out, __psp_cwd); -+ if(!__psp_safe_strcat(out, "/", len)) -+ return -6; -+ if(!__psp_safe_strcat(out, in, len)) -+ return -7; -+ } -+ -+ /* Now normalize the pathname portion */ -+ dr = __psp_get_drive(out); -+ if(dr < 0) dr = 0; -+ return __psp_path_normalize(out + dr, len - dr); -+} -+ ---- newlib-1.13.0.orig/newlib/libc/sys/psp/README 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/README 2005-07-23 23:25:55.000000000 -0700 +--- newlib-1.13.0.orig/newlib/libc/sys/psp/README 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/README 2005-07-28 15:42:00.000000000 -0400 @@ -0,0 +1,16 @@ +Newlib for PSP +-- @@ -1222,8 +475,8 @@ + +-- +Marcus R. Brown ---- newlib-1.13.0.orig/newlib/libc/sys/psp/aclocal.m4 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/aclocal.m4 2005-07-23 23:18:42.000000000 -0700 +--- newlib-1.13.0.orig/newlib/libc/sys/psp/aclocal.m4 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/aclocal.m4 2005-09-29 21:46:30.000000000 -0400 @@ -0,0 +1,1185 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p6 + @@ -2410,8 +1663,8 @@ +] +) + ---- newlib-1.13.0.orig/newlib/libc/sys/psp/configure 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/configure 2005-07-23 22:50:02.000000000 -0700 +--- newlib-1.13.0.orig/newlib/libc/sys/psp/configure 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/configure 2005-07-28 15:42:00.000000000 -0400 @@ -0,0 +1,1880 @@ +#! /bin/sh + @@ -4293,53 +3546,902 @@ +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + ---- newlib-1.13.0.orig/newlib/libc/sys/psp/crt0.c 1969-12-31 16:00:00.000000000 -0800 -+++ newlib-psp/newlib/libc/sys/psp/crt0.c 2005-07-23 23:27:06.000000000 -0700 +--- newlib-1.13.0.orig/newlib/libc/sys/psp/configure.in 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/configure.in 2005-07-28 15:42:00.000000000 -0400 +@@ -0,0 +1,12 @@ ++dnl This is the newlib/libc/sys/psp configure.in file. ++dnl Process this file with autoconf to produce a configure script. ++ ++AC_PREREQ(2.5) ++AC_INIT(libcglue.c) ++ ++dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. ++AC_CONFIG_AUX_DIR(../../../..) ++ ++NEWLIB_CONFIGURE(../../..) ++ ++AC_OUTPUT(Makefile) +--- newlib-1.13.0.orig/newlib/libc/sys/psp/crt0.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/crt0.c 2005-07-28 15:42:00.000000000 -0400 @@ -0,0 +1,3 @@ +/* The real crt0.c lives in PSPSDK. */ + +void _start() { } ---- newlib-1.13.0.orig/newlib/libc/include/sys/config.h 2004-06-22 14:54:51.000000000 -0700 -+++ newlib-psp/newlib/libc/include/sys/config.h 2005-08-15 14:11:50.000000000 -0700 -@@ -94,6 +94,12 @@ - #endif - #endif - -+/* We compile newlib with -G0 for PSP, but if we're compiling an app with $gp enabled, -+ then _impure_ptr is expected to live in .sdata. */ -+#if defined(__psp__) -+#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__section__(".sdata"))) +--- newlib-1.13.0.orig/newlib/libc/sys/psp/libcglue.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/libcglue.c 2005-10-17 17:53:39.000000000 -0400 +@@ -0,0 +1,667 @@ ++/* ++ * PSP Software Development Kit - http://www.pspdev.org ++ * ----------------------------------------------------------------------- ++ * Licensed under the BSD license, see LICENSE in PSPSDK root for details. ++ * ++ * libcglue.c - Newlib-compatible system calls. ++ * ++ * Copyright (c) 2005 Marcus R. Brown ++ * Copyright (c) 2005 James Forshaw ++ * Copyright (c) 2005 John Kelley ++ * Copyright (c) 2005 Jim Paris ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* These functions aren't exposed in any public headers, and they probably don't need to be. */ ++int sceKernelStdin(void); ++int sceKernelStdout(void); ++int sceKernelStderr(void); ++ ++extern char __psp_cwd[MAXPATHLEN + 1]; ++extern void __psp_init_cwd(char *argv_0); ++extern int __psp_path_absolute(const char *in, char *out, int len); ++ ++#define __PSP_FILENO_MAX 1024 ++extern char * __psp_filename_map[__PSP_FILENO_MAX]; ++ ++#ifdef F_getcwd ++char *getcwd(char *buf, size_t size) ++{ ++ if(!buf) { ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ if(strlen(__psp_cwd) >= size) { ++ errno = ERANGE; ++ return NULL; ++ } ++ ++ strcpy(buf, __psp_cwd); ++ return buf; ++} +#endif + - #ifdef __xstormy16__ - #define __SMALL_BITFIELDS - #undef INT_MAX ---- newlib-1.13.0.orig/newlib/configure.host 2004-10-05 12:44:24.000000000 -0700 -+++ newlib-psp/newlib/configure.host 2005-07-23 23:02:26.000000000 -0700 -@@ -570,7 +570,14 @@ - ;; - mips*-*-elf*) - default_newlib_io_long_long="yes" -- newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES" -+ case "${host}" in -+ mipsallegrex*-psp-*) -+ sys_dir=psp -+ syscall_dir=syscalls -+ newlib_cflags="${newlib_cflags} -G0 -DPREFER_SIZE_OVER_SPEED -DCOMPACT_CTYPE -DCLOCK_PROVIDED -I${prefix}/psp/sdk/include" ;; -+ *) -+ newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES" ;; -+ esac - ;; - mmix-*) - syscall_dir=syscalls ---- newlib-1.13.0.orig/newlib/libc/include/time.h 2004-02-09 22:56:46.000000000 +0000 -+++ newlib-psp/newlib/libc/include/time.h 2005-09-07 17:17:31.929445856 +0100 -@@ -18,7 +18,7 @@ - #include - - #ifndef _CLOCKS_PER_SEC_ --#define _CLOCKS_PER_SEC_ 1000 -+#define _CLOCKS_PER_SEC_ 1000000 - #endif - - #define CLOCKS_PER_SEC _CLOCKS_PER_SEC_ ++#ifdef F_chdir ++int chdir(const char *path) ++{ ++ char dest[MAXPATHLEN + 1]; ++ SceUID uid; ++ ++ if(__psp_path_absolute(path, dest, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ /* sceIoChdir doesn't give an indication of whether it worked, ++ so test for existence by attempting to open the dir */ ++ uid = sceIoDopen(dest); ++ if(uid < 0) { ++ errno = ENOTDIR; ++ return -1; ++ } ++ sceIoDclose(uid); ++ ++ sceIoChdir(dest); ++ strcpy(__psp_cwd, dest); ++ return 0; ++} ++#endif ++ ++#ifdef F_mkdir ++int mkdir(const char *pathname, mode_t mode) ++{ ++ char dest[MAXPATHLEN + 1]; ++ ++ if(__psp_path_absolute(pathname, dest, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ return sceIoMkdir(dest, mode); ++} ++#endif ++ ++#ifdef F_rmdir ++int rmdir(const char *pathname) ++{ ++ char dest[MAXPATHLEN + 1]; ++ ++ if(__psp_path_absolute(pathname, dest, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ return sceIoRmdir(dest); ++} ++#endif ++ ++#ifdef F_realpath ++char *realpath(const char *path, char *resolved_path) ++{ ++ if(!path || !resolved_path) { ++ errno = EINVAL; ++ return NULL; ++ } ++ if(__psp_path_absolute(path, resolved_path, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return NULL; ++ } ++ if(access(resolved_path, F_OK) < 0) { ++ errno = ENOENT; ++ return NULL; ++ } ++ return resolved_path; ++} ++#endif ++ ++/* Wrappers of the standard open(), close(), read(), write(), unlink() and lseek() routines. */ ++#ifdef F__open ++int _open(const char *name, int flags, int mode) ++{ ++ int fd; ++ int sce_flags; ++ char dest[MAXPATHLEN + 1]; ++ ++ if(__psp_path_absolute(name, dest, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ /* O_RDONLY starts at 0, where PSP_O_RDONLY starts at 1, so remap the read/write ++ flags by adding 1. */ ++ sce_flags = (flags & O_ACCMODE) + 1; ++ ++ /* Translate standard open flags into the flags understood by the PSP kernel. */ ++ if (flags & O_APPEND) { ++ sce_flags |= PSP_O_APPEND; ++ } ++ if (flags & O_CREAT) { ++ sce_flags |= PSP_O_CREAT; ++ } ++ if (flags & O_TRUNC) { ++ sce_flags |= PSP_O_TRUNC; ++ } ++ if (flags & O_EXCL) { ++ sce_flags |= PSP_O_EXCL; ++ } ++ if (flags & O_NONBLOCK) { ++ sce_flags |= PSP_O_NBLOCK; ++ } ++ ++ fd = sceIoOpen(dest, sce_flags, mode); ++ if ((fd >= 0) && (fd < __PSP_FILENO_MAX)) { ++ __psp_filename_map[fd] = strdup(dest); ++ } ++ return fd; ++} ++#endif ++ ++#ifdef F__close ++int _close(int fd) ++{ ++ if (fd < 0) { ++ return -EBADF; ++ } ++ ++ if ((fd >= 0) && (fd < __PSP_FILENO_MAX)) { ++ if (__psp_filename_map[fd] != NULL) { ++ free(__psp_filename_map[fd]); ++ __psp_filename_map[fd] = NULL; ++ } ++ } ++ ++ return sceIoClose(fd); ++} ++#endif ++ ++#ifdef F__read ++int _read(int fd, void *buf, size_t size) ++{ ++ if (fd < 0) { ++ return -EBADF; ++ } ++ ++ return sceIoRead(fd, buf, size); ++} ++#endif ++ ++#ifdef F__write ++int _write(int fd, const void *buf, size_t size) ++{ ++ if (fd < 0) { ++ return -EBADF; ++ } ++ ++ return sceIoWrite(fd, buf, size); ++} ++#endif ++ ++#ifdef F__lseek ++off_t _lseek(int fd, off_t offset, int whence) ++{ ++ if (fd < 0) { ++ return -EBADF; ++ } ++ ++ /* We don't have to do anything with the whence argument because SEEK_* == PSP_SEEK_*. */ ++ return (off_t) sceIoLseek(fd, offset, whence); ++} ++#endif ++ ++#ifdef F__unlink ++int _unlink(const char *path) ++{ ++ char dest[MAXPATHLEN + 1]; ++ ++ if(__psp_path_absolute(path, dest, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ return sceIoRemove(dest); ++} ++#endif ++ ++#ifdef F__link ++int _link(const char *name1, const char *name2) ++{ ++ return -1; /* not supported */ ++} ++#endif ++ ++#ifdef F_opendir ++DIR *opendir(const char *filename) ++{ ++ char dest[MAXPATHLEN + 1]; ++ DIR *dirp; ++ SceUID uid; ++ ++ /* Normalize pathname so that opendir(".") works */ ++ if(__psp_path_absolute(filename, dest, MAXPATHLEN) < 0) { ++ errno = ENOENT; ++ return NULL; ++ } ++ ++ dirp = (DIR *)malloc(sizeof(DIR)); ++ ++ uid = sceIoDopen(dest); ++ ++ if (uid < 0) ++ { ++ free(dirp); ++ return NULL; ++ } ++ ++ dirp->uid = uid; ++ ++ return dirp; ++} ++#endif ++ ++#ifdef F_readdir ++struct dirent *readdir(DIR *dirp) ++{ ++ SceIoDirent *de; ++ ++ de = (SceIoDirent *)malloc(sizeof(SceIoDirent)); ++ ++ if (sceIoDread(dirp->uid, de) <= 0) ++ { ++ free(de); ++ return NULL; ++ } ++ ++ return (struct dirent *)de; ++} ++#endif ++ ++#ifdef F_closedir ++int closedir(DIR *dirp) ++{ ++ if (dirp != NULL) ++ { ++ int uid; ++ uid = dirp->uid; ++ free (dirp); ++ return sceIoDclose(uid); ++ } ++ return -1; ++} ++#endif ++ ++/* Time routines. These wrap around the routines provided by the kernel. */ ++#ifdef F__gettimeofday ++int _gettimeofday(struct timeval *tp, struct timezone *tzp) ++{ ++ return sceKernelLibcGettimeofday(tp, tzp); ++} ++ ++#endif ++ ++/* If we're being built for PSPSDK's libc this function isn't defined. */ ++#ifdef F_glue_gettimeofday ++int gettimeofday(struct timeval *tp, struct timezone *tzp) ++{ ++ return sceKernelLibcGettimeofday(tp, tzp); ++} ++#endif ++ ++#if defined(F_clock) || defined(F_glue_clock) ++clock_t clock(void) ++{ ++ return sceKernelLibcClock(); ++} ++#endif ++ ++#if defined(F_time) || defined(F_glue_time) ++time_t time(time_t *t) ++{ ++ return sceKernelLibcTime(t); ++} ++#endif ++ ++#if defined(F_sleep) ++unsigned int sleep(unsigned int secs) { ++ while(secs--) { ++ sceKernelDelayThreadCB(1000000); ++ } ++ return 0; ++} ++#endif ++ ++/* PSP-compatible sbrk(). */ ++#if defined(F__sbrk) || defined(F_glue__sbrk) ++/* TODO: Currently our default heap is set to the maximum available block size ++ when sbrk() is first called. Sony seems to always use a default of 64KB, ++ with the expectation that user programs will override the default size with ++ their own desired size. The only reason I can think of them doing this is ++ to allow each PRX to have their own seperate heap. I think that their ++ method is overkill for most user programs. ++ ++ What I'd like to do instead is to use the default of 64KB for PRXes as Sony ++ does, but use the maximum available block size for executables. This avoids ++ the requirement of specifying the heap size manually in user programs. ++ However, we currently don't have a clean way to distinguish PRXes and normal ++ executables, so this code needs to be revisited once we do come up with a ++ way. */ ++#define DEFAULT_PRX_HEAP_SIZE_KB 64 ++ ++/* If defined it specifies the desired size of the heap, in KB. */ ++extern unsigned int sce_newlib_heap_kb_size __attribute__((weak)); ++ ++/* UID of the memory block that represents the heap. */ ++static SceUID __psp_heap_blockid; ++ ++void * _sbrk(ptrdiff_t incr) ++{ ++ static void * heap_bottom = NULL; ++ static void * heap_top = NULL; ++ static void * heap_ptr = NULL; ++ ++ /* Has our heap been initialized? */ ++ if (heap_bottom == NULL) { ++ /* No, initialize the heap. */ ++ SceSize heap_size; ++ ++ if (&sce_newlib_heap_kb_size != NULL) { ++ heap_size = sce_newlib_heap_kb_size * 1024; ++ } else { ++ /* TODO: Here we should distinguish between a PRX and a normal ++ executable. Right now we assume it's an executable. */ ++ if (0 /* is a prx */) { ++ heap_size = DEFAULT_PRX_HEAP_SIZE_KB * 1024; ++ } else { ++ heap_size = sceKernelMaxFreeMemSize(); ++ } ++ } ++ ++ __psp_heap_blockid = sceKernelAllocPartitionMemory(2, "block", PSP_SMEM_Low, heap_size, NULL); ++ if (__psp_heap_blockid > 0) { ++ heap_bottom = sceKernelGetBlockHeadAddr(__psp_heap_blockid); ++ heap_ptr = heap_bottom; ++ heap_top = (unsigned char *) heap_bottom + heap_size; ++ } ++ } ++ ++ void * heap_addr = (void *) -1; ++ void * next_heap_ptr = (void *) ((ptrdiff_t) heap_ptr + incr); ++ if ((heap_bottom != NULL) && (next_heap_ptr >= heap_bottom) && (next_heap_ptr < heap_top)) { ++ heap_addr = heap_ptr; ++ heap_ptr = next_heap_ptr; ++ } ++ ++ return heap_addr; ++} ++ ++/* Free the heap. */ ++int __psp_free_heap(void) ++{ ++ if (__psp_heap_blockid > 0) { ++ return sceKernelFreePartitionMemory(__psp_heap_blockid); ++ } ++ ++ return __psp_heap_blockid; ++} ++#endif ++ ++/* Other POSIX routines that must be defined. */ ++#ifdef F__fstat ++int _fstat(int fd, struct stat *sbuf) ++{ ++ int ret; ++ SceOff oldpos; ++ if ((fd >= 0) && (fd < __PSP_FILENO_MAX)) { ++ if (__psp_filename_map[fd] != NULL) { ++ if (strcmp(__psp_filename_map[fd], " __PSP_STDIO") == 0) { ++ memset(sbuf, '\0', sizeof(struct stat)); ++ sbuf->st_mode = S_IFCHR; ++ return 0; ++ } else { ++ ret = stat(__psp_filename_map[fd], sbuf); ++ /* Find true size of open file */ ++ oldpos = sceIoLseek(fd, 0, SEEK_CUR); ++ if (oldpos != (off_t) -1) { ++ sbuf->st_size = (off_t) sceIoLseek(fd, 0, SEEK_END); ++ sceIoLseek(fd, oldpos, SEEK_SET); ++ } ++ return ret; ++ } ++ } ++ } ++ errno = EBADF; ++ return -1; ++} ++#endif ++ ++#ifdef F_isatty ++int isatty(int fd) ++{ ++ if ((fd >= 0) && (fd < __PSP_FILENO_MAX)) { ++ if (__psp_filename_map[fd] != NULL) { ++ if (strcmp(__psp_filename_map[fd], " __PSP_STDIO") == 0) { ++ return 1; ++ } else { ++ return 0; ++ } ++ } ++ } ++ return 0; ++} ++#endif ++ ++#ifdef F__stat ++static time_t psp_to_epoch_time(ScePspDateTime psp_time) ++{ ++ struct tm conv_time; ++ conv_time.tm_year = psp_time.year; ++ conv_time.tm_mon = psp_time.month; ++ conv_time.tm_mday = psp_time.day; ++ conv_time.tm_hour = psp_time.hour; ++ conv_time.tm_min = psp_time.minute; ++ conv_time.tm_sec = psp_time.second; ++ conv_time.tm_isdst = -1; ++ return mktime(&conv_time); ++} ++ ++int _stat(const char *filename, struct stat *buf) ++{ ++ SceIoStat psp_stat; ++ char dest[MAXPATHLEN + 1]; ++ ++ if(__psp_path_absolute(filename, dest, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ memset(buf, '\0', sizeof(struct stat)); ++ if(sceIoGetstat(dest, &psp_stat) < 0) ++ return -1; ++ ++ buf->st_ctime = psp_to_epoch_time(psp_stat.st_ctime); ++ buf->st_atime = psp_to_epoch_time(psp_stat.st_atime); ++ buf->st_mtime = psp_to_epoch_time(psp_stat.st_mtime); ++ ++ buf->st_mode = (psp_stat.st_mode & 0xfff) | ++ ((FIO_S_ISLNK(psp_stat.st_mode))?(S_IFLNK):(0)) | ++ ((FIO_S_ISREG(psp_stat.st_mode))?(S_IFREG):(0)) | ++ ((FIO_S_ISDIR(psp_stat.st_mode))?(S_IFDIR):(0)); ++ buf->st_size = psp_stat.st_size; ++ return 0; ++} ++#endif ++ ++/* from stat.h in ps2sdk, this function may be correct */ ++#define FIO_CST_SIZE 0x0004 ++ ++#ifdef F_truncate ++int truncate(const char *filename, off_t length) ++{ ++ SceIoStat psp_stat; ++ char dest[MAXPATHLEN + 1]; ++ ++ if(__psp_path_absolute(filename, dest, MAXPATHLEN) < 0) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ psp_stat.st_size = length; ++ if(length < 0) ++ { ++ errno = EINVAL; ++ return -1; ++ } ++ return sceIoChstat(dest, &psp_stat, FIO_CST_SIZE); ++} ++#endif ++ ++/* Unsupported newlib system calls. */ ++#ifdef F__fork ++pid_t fork(void) ++{ ++ return (pid_t) -1; ++} ++#endif ++ ++#ifdef F__getpid ++pid_t _getpid(void) ++{ ++ return (pid_t) -1; ++} ++#endif ++ ++#ifdef F__kill ++int _kill(int unused, int unused2) ++{ ++ return -1; ++} ++#endif ++ ++#ifdef F__wait ++pid_t _wait(int *unused) ++{ ++ return (pid_t) -1; ++} ++#endif ++ ++#ifdef F_access ++int access(const char *fn, int flags) ++{ ++ struct stat s; ++ if (stat(fn, &s)) ++ return -1; ++ if (s.st_mode & S_IFDIR) ++ return 0; ++ if (flags & W_OK) ++ { ++ if (s.st_mode & S_IWRITE) ++ return 0; ++ return -1; ++ } ++ return 0; ++} ++#endif ++ ++/* Exit. */ ++#if defined(F__exit) || defined(F_glue__exit) ++extern int sce_newlib_nocreate_thread_in_start __attribute__((weak)); ++ ++extern int __psp_free_heap(void); ++ ++void _exit(int status) ++{ ++ if (&sce_newlib_nocreate_thread_in_start != NULL) { ++ /* Free the heap created by _sbrk(). */ ++ __psp_free_heap(); ++ ++ sceKernelSelfStopUnloadModule(1, 0, NULL); ++ } else { ++ if (status == 0) { ++ /* Free the heap created by _sbrk(). */ ++ __psp_free_heap(); ++ } ++ ++ sceKernelExitThread(status); ++ } ++ ++ while (1) ; ++} ++ ++/* Note: This function is being linked into _exit.o. ++ ++ Because __psp_libc_init is a weak import in crt0.c, the linker ++ chooses to ignore an object file in libc.a that contains just this ++ function, since it's not necessary for successful compilation. ++ ++ By putting it instead in _exit.o, which is already used by crt0.c, ++ the linker sees __psp_libc_init and resolves the symbol properly. ++*/ ++void __psp_libc_init(int argc, char *argv[]) ++{ ++ int fd; ++ (void) argc; ++ ++ /* Initialize cwd from this program's path */ ++ __psp_init_cwd(argv[0]); ++ ++ /* Initialize filenamap */ ++ memset(__psp_filename_map, '\0', sizeof(char *) * __PSP_FILENO_MAX); ++ fd = sceKernelStdin(); ++ if ((fd >= 0) && (fd < __PSP_FILENO_MAX)) { ++ __psp_filename_map[fd] = strdup(" __PSP_STDIO"); ++ } ++ fd = sceKernelStdout(); ++ if ((fd >= 0) && (fd < __PSP_FILENO_MAX)) { ++ __psp_filename_map[fd] = strdup(" __PSP_STDIO"); ++ } ++ fd = sceKernelStderr(); ++ if ((fd >= 0) && (fd < __PSP_FILENO_MAX)) { ++ __psp_filename_map[fd] = strdup(" __PSP_STDIO"); ++ } ++ ++ /* Initialize timezone from PSP configuration */ ++ int tzOffset = 0; ++ sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_TIMEZONE, &tzOffset); ++ int tzOffsetAbs = tzOffset < 0 ? -tzOffset : tzOffset; ++ int hours = tzOffsetAbs / 60; ++ int minutes = tzOffsetAbs - hours * 60; ++ static char tz[10]; ++ sprintf(tz, "GMT%s%02i:%02i", tzOffset < 0 ? "+" : "-", hours, minutes); ++ setenv("TZ", tz, 1); ++ tzset(); ++} ++ ++#endif /* F__exit */ ++ ++/* newlib's errno.h wants a function that returns a pointer to errno. */ ++#ifdef F_glue___errno ++#undef errno ++ ++int errno; ++ ++/* TODO: Should this be made reentrant (wrapping interrupt disable/enable ++ around it should do it)? */ ++int * __errno(void) ++{ ++ return &errno; ++} ++#endif +--- newlib-1.13.0.orig/newlib/libc/sys/psp/pspcwd.c 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/pspcwd.c 2005-10-06 05:24:40.000000000 -0400 +@@ -0,0 +1,167 @@ ++/* ++ * PSP Software Development Kit - http://www.pspdev.org ++ * ----------------------------------------------------------------------- ++ * Licensed under the BSD license, see LICENSE in PSPSDK root for details. ++ * ++ * pspcwd.c - Current working directory emulation helper functions ++ * ++ * Copyright (c) 2005 Marcus R. Brown ++ * Copyright (c) 2005 James Forshaw ++ * Copyright (c) 2005 John Kelley ++ * Copyright (c) 2005 Jim Paris ++ * ++ */ ++#include ++#include ++#include ++ ++#include ++#include ++ ++char __psp_cwd[MAXPATHLEN + 1] = { 0 }; ++char * __psp_filename_map[1024]; ++ ++/* Set the current working directory (CWD) to the path where the module was launched. */ ++void __psp_init_cwd(char *argv_0) ++{ ++ if (argv_0 != NULL) { ++ char base_path[MAXPATHLEN + 1]; ++ char *end; ++ ++ strncpy(base_path, argv_0, sizeof(base_path) - 1); ++ base_path[sizeof(base_path) - 1] = '\0'; ++ end = strrchr(base_path, '/'); ++ if (end != NULL) { ++ *(end + 1) = '\0'; ++ chdir(base_path); ++ } ++ } ++} ++ ++/* Return the number of bytes taken up by the "drive:" prefix, ++ or -1 if it's not found */ ++int __psp_get_drive(const char *d) ++{ ++ int i; ++ for(i=0; d[i]; i++) { ++ if(! ((d[i] >= 'a' && d[i] <= 'z') || ++ (d[i] >= '0' && d[i] <= '9') )) ++ break; ++ } ++ if(d[i] == ':') return i+1; ++ return -1; ++} ++ ++/* Like strcpy, but returns 0 if the string doesn't fit */ ++int __psp_safe_strcpy(char *out, const char *in, int maxlen) ++{ ++ for( ; maxlen > 0 && *in ; maxlen-- ) ++ *(out++) = *(in++); ++ if(maxlen < 1) return 0; ++ *out = 0; ++ return 1; ++} ++ ++/* Like strcat, but returns 0 if the string doesn't fit */ ++int __psp_safe_strcat(char *out, const char *in, int maxlen) ++{ ++ for( ; *out ; out++,maxlen-- ) ++ continue; ++ return __psp_safe_strcpy(out, in, maxlen); ++} ++ ++/* Normalize a pathname (without leading "drive:") by removing ++ . and .. components, duplicated /, etc. */ ++int __psp_path_normalize(char *out, int len) ++{ ++ int i, j; ++ int first, next; ++ ++ /* First append "/" to make the rest easier */ ++ if(!__psp_safe_strcat(out,"/",len)) return -10; ++ ++ /* Convert "//" to "/" */ ++ for(i=0; out[i+1]; i++) { ++ if(out[i]=='/' && out[i+1]=='/') { ++ for(j=i+1; out[j]; j++) ++ out[j] = out[j+1]; ++ i--; ++ } ++ } ++ ++ /* Convert "/./" to "/" */ ++ for(i=0; out[i] && out[i+1] && out[i+2]; i++) { ++ if(out[i]=='/' && out[i+1]=='.' && out[i+2]=='/') { ++ for(j=i+1; out[j]; j++) ++ out[j] = out[j+2]; ++ i--; ++ } ++ } ++ ++ /* Convert "/asdf/../" to "/" until we can't anymore. Also ++ * convert leading "/../" to "/" */ ++ first = next = 0; ++ while(1) { ++ /* If a "../" follows, remove it and the parent */ ++ if(out[next+1] && out[next+1]=='.' && ++ out[next+2] && out[next+2]=='.' && ++ out[next+3] && out[next+3]=='/') { ++ for(j=0; out[first+j+1]; j++) ++ out[first+j+1] = out[next+j+4]; ++ first = next = 0; ++ continue; ++ } ++ ++ /* Find next slash */ ++ first = next; ++ for(next=first+1; out[next] && out[next] != '/'; next++) ++ continue; ++ if(!out[next]) break; ++ } ++ ++ /* Remove trailing "/" */ ++ for(i=1; out[i]; i++) ++ continue; ++ if(i > 1 && out[i-1] == '/') ++ out[i-1] = 0; ++ ++ return 0; ++} ++ ++/* Convert relative path to absolute path. */ ++int __psp_path_absolute(const char *in, char *out, int len) ++{ ++ int dr; ++ ++ /* See what the relative URL starts with */ ++ dr = __psp_get_drive(in); ++ if(dr > 0 && in[dr] == '/') { ++ /* It starts with "drive:/", so it's already absolute */ ++ if(!__psp_safe_strcpy(out, in, len)) ++ return -1; ++ } else if(in[0] == '/') { ++ /* It's absolute, but missing the drive, so use cwd's drive */ ++ if(strlen(__psp_cwd) >= len) ++ return -2; ++ strcpy(out, __psp_cwd); ++ dr = __psp_get_drive(out); ++ out[dr] = 0; ++ if(!__psp_safe_strcat(out, in, len)) ++ return -3; ++ } else { ++ /* It's not absolute, so append it to the current cwd */ ++ if(strlen(__psp_cwd) >= len) ++ return -4; ++ strcpy(out, __psp_cwd); ++ if(!__psp_safe_strcat(out, "/", len)) ++ return -6; ++ if(!__psp_safe_strcat(out, in, len)) ++ return -7; ++ } ++ ++ /* Now normalize the pathname portion */ ++ dr = __psp_get_drive(out); ++ if(dr < 0) dr = 0; ++ return __psp_path_normalize(out + dr, len - dr); ++} ++ +--- newlib-1.13.0.orig/newlib/libc/sys/psp/sys/dirent.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-psp/newlib/libc/sys/psp/sys/dirent.h 2005-09-29 21:21:33.000000000 -0400 +@@ -0,0 +1,35 @@ ++#ifndef _SYS_DIRENT_H ++#define _SYS_DIRENT_H ++ ++/* PSP dirent.h, based on pspiofilemgr_dirent.h ++ by Jim Paris */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* Defines DIR */ ++#include ++ ++#define MAXNAMLEN 255 ++ ++/* Same as SceIoDirent, just with a different name. */ ++struct dirent { ++ /** File status. */ ++ SceIoStat d_stat; ++ /** File name. */ ++ char d_name[256]; ++ /** Device-specific data. */ ++ void * d_private; ++ int dummy; ++}; ++ ++DIR *opendir (const char *); ++struct dirent *readdir (DIR *); ++int closedir (DIR *); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif