Index: libgloss/ChangeLog
===================================================================
RCS file: /cvs/src/src/libgloss/ChangeLog,v
retrieving revision 1.86
diff -u -p -r1.86 ChangeLog
--- libgloss/ChangeLog	3 Jun 2004 22:23:10 -0000	1.86
+++ libgloss/ChangeLog	7 Jun 2004 18:47:17 -0000
@@ -1,3 +1,17 @@
+2004-06-07  Toralf Lund  <toralf@procaptura.com>
+
+	* arm/crt0.S: Copied from newlib and it now also sets up stacks for 
+	FIQ and IRQ mode, plus calls hardware_init_hook() and 
+	software_init_hook() if present.
+	* arm/libcfunc.c, arm/swi.h, arm/syscalls.c: Copied
+	from newlib.
+	* arm/Makefile.in: Build crt0.o, rdpmon-crt0.o, rdimon-crt0.o,
+	librdpmon.a, librdimon.a - support file for "bare" setup, as well
+	as "RDP" and "RDI" monitors.
+	* arm/coff-rdpmon.specs, arm/elf-rdpmon.specs,
+	arm/coff-rdimon.specs, arm/elf-rdimon.specs: gcc specs files to go
+	with above mentioned support libs and startfiles.
+
 2004-06-03  Alexandre Oliva  <aoliva@redhat.com>
 
         * mn10300/sim.ld: Start at address 4, to avoid ambiguity with NULL
Index: libgloss/configure
===================================================================
RCS file: /cvs/src/src/libgloss/configure,v
retrieving revision 1.7
diff -u -p -r1.7 configure
--- libgloss/configure	25 Oct 2002 18:35:21 -0000	1.7
+++ libgloss/configure	7 Jun 2004 18:47:17 -0000
@@ -795,6 +795,9 @@ case "${target}" in
   arm*-*-elf | arm*-*-coff)
 	configdirs="${configdirs} arm testsuite";
 	;;
+  ep9312-*-elf | ep9312-*-coff)
+	configdirs="${configdirs} arm testsuite";
+	;;
   xscale-*-elf | xscale-*-coff)
 	configdirs="${configdirs} arm testsuite";
 	;;
@@ -818,7 +821,7 @@ subdirs="$configdirs"
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:822: checking for $ac_word" >&5
+echo "configure:825: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -848,7 +851,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:852: checking for $ac_word" >&5
+echo "configure:855: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -897,7 +900,7 @@ fi
 fi
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:901: checking whether we are using GNU C" >&5
+echo "configure:904: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -906,7 +909,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -921,7 +924,7 @@ if test $ac_cv_prog_gcc = yes; then
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=
   echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:925: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:928: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -953,7 +956,7 @@ AS=${AS-as}
 # Extract the first word of "ar", so it can be a program name with args.
 set dummy ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:957: checking for $ac_word" >&5
+echo "configure:960: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -987,7 +990,7 @@ LD=${LD-ld}
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:991: checking for $ac_word" >&5
+echo "configure:994: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
Index: libgloss/configure.in
===================================================================
RCS file: /cvs/src/src/libgloss/configure.in,v
retrieving revision 1.7
diff -u -p -r1.7 configure.in
--- libgloss/configure.in	25 Oct 2002 18:35:21 -0000	1.7
+++ libgloss/configure.in	7 Jun 2004 18:47:17 -0000
@@ -106,6 +106,9 @@ case "${target}" in
   arm*-*-elf | arm*-*-coff)
 	configdirs="${configdirs} arm testsuite";
 	;;
+  ep9312-*-elf | ep9312-*-coff)
+	configdirs="${configdirs} arm testsuite";
+	;;
   xscale-*-elf | xscale-*-coff)
 	configdirs="${configdirs} arm testsuite";
 	;;
Index: libgloss/arm/Makefile.in
===================================================================
RCS file: /cvs/src/src/libgloss/arm/Makefile.in,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile.in
--- libgloss/arm/Makefile.in	7 Nov 2002 00:25:57 -0000	1.2
+++ libgloss/arm/Makefile.in	7 Jun 2004 18:47:17 -0000
@@ -47,9 +47,26 @@ OBJCOPY = `if [ -f ${objroot}/../binutil
 	then echo ${objroot}/../binutils/objcopy ; \
 	else t='$(program_transform_name)'; echo objcopy | sed -e $$t ; fi`
 
-REDBOOT_OBJS	= redboot-crt0.o  redboot-syscalls.o
+CRT0		= crt0.o
+CRT0_INSTALL	= install-crt0
+
+REDBOOT_CRT0	= redboot-crt0.o 
+REDBOOT_OBJS	= redboot-syscalls.o
 REDBOOT_SCRIPTS	= redboot.ld redboot.specs
 REDBOOT_INSTALL	= install-redboot
+
+RDPMON_CRT0	= rdpmon-crt0.o
+RDPMON_BSP	= librdpmon.a
+RDPMON_OBJS	= syscalls.o libcfunc.o trap.o
+RDPMON_SCRIPTS	= rdpmon.specs
+RDPMON_INSTALL	= install-rdpmon
+
+RDIMON_CRT0	= rdimon-crt0.o
+RDIMON_BSP	= librdimon.a
+RDIMON_OBJS	= rdimon-syscalls.o rdimon-libcfunc.o rdimon-trap.o
+RDIMON_SCRIPTS	= rdimon.specs
+RDIMON_INSTALL	= install-rdimon
+
 CFLAGS		= -g
 
 # Here is all of the eval board stuff
@@ -67,7 +84,7 @@ IQ80310_INSTALL	= install-iq80310
 # build a test program for each target board. Just trying to get
 # it to link is a good test, so we ignore all the errors for now.
 #
-all: ${REDBOOT_OBJS}
+all: ${CRT0} ${REDBOOT_CRT0} ${REDBOOT_OBJS} ${RDPMON_CRT0} ${RDPMON_BSP} ${RDIMON_CRT0} ${RDIMON_BSP}
 
 #
 # here's where we build the test programs for each target
@@ -76,9 +93,33 @@ all: ${REDBOOT_OBJS}
 test:
 
 #
+crt0.o: crt0.S
 redboot-crt0.o: redboot-crt0.S
 redboot-syscalls.o: redboot-syscalls.c $(srcdir)/../syscall.h
 
+rdpmon-crt0.o: crt0.S
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -DARM_RDP_MONITOR -o $@ -c $<
+
+rdimon-crt0.o: crt0.S
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -DARM_RDI_MONITOR -o $@ -c $<
+
+rdimon-trap.o: trap.S
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -DARM_RDI_MONITOR -o $@ -c $<
+
+rdimon-syscalls.o: syscalls.c
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -DARM_RDI_MONITOR -o $@ -c $<
+
+rdimon-libcfunc.o: libcfunc.c
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -DARM_RDI_MONITOR -o $@ -c $<
+
+$(RDPMON_BSP): $(RDPMON_OBJS)
+	${AR} ${ARFLAGS} $@ $(IDTOBJS)
+	${RANLIB} $@
+
+$(RDIMON_BSP): $(RDIMON_OBJS)
+	${AR} ${ARFLAGS} $@ $(IDTOBJS)
+	${RANLIB} $@
+
 clean mostlyclean:
 	rm -f a.out core *.i *.o *-test *.srec *.dis *.x $(SIM_BSP) $(IQ80310_BSP)
 
@@ -86,13 +127,24 @@ distclean maintainer-clean realclean: cl
 	rm -f Makefile config.status *~
 
 .PHONY: install info install-info clean-info
-install: ${REDBOOT_INSTALL} ${IQ80310_INSTALL}  ${PID_INSTALL}
+install: ${CRT0_INSTALL} ${REDBOOT_INSTALL} ${RDPMON_INSTALL} ${RDIMON_INSTALL} ${IQ80310_INSTALL}  ${PID_INSTALL}
 
+install-crt0:
+	${INSTALL_DATA} ${CRT0} ${tooldir}/lib${MULTISUBDIR}/$$x
 
 install-redboot:
-	set -e; for x in ${REDBOOT_OBJS}; do ${INSTALL_DATA} $$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
+	set -e; for x in ${REDBOOT_CRT0} ${REDBOOT_OBJS}; do ${INSTALL_DATA} $$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
 	set -e; for x in ${REDBOOT_SCRIPTS}; do ${INSTALL_DATA} ${srcdir}/${objtype}$$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
 
+install-rdpmon:
+	set -e; for x in ${RDPMON_CRT0} ${RDPMON_BSP}; do ${INSTALL_DATA} $$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
+	set -e; for x in ${RDPMON_SCRIPTS}; do ${INSTALL_DATA} ${srcdir}/${objtype}$$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
+
+install-rdimon:
+	set -e; for x in ${RDIMON_CRT0} ${RDIMON_BSP}; do ${INSTALL_DATA} $$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
+	set -e; for x in ${RDIMON_SCRIPTS}; do ${INSTALL_DATA} ${srcdir}/${objtype}$$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
+
+
 install-pid:
 	set -e; for x in ${PID_SCRIPTS}; do ${INSTALL_DATA} ${srcdir}/${objtype}$$x ${tooldir}/lib${MULTISUBDIR}/$$x; done
 
Index: libgloss/arm/coff-rdimon.specs
===================================================================
RCS file: libgloss/arm/coff-rdimon.specs
diff -N libgloss/arm/coff-rdimon.specs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/coff-rdimon.specs	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,8 @@
+%rename link                old_link
+
+*link:
+%(old_link) -lrdimon
+
+*startfile:
+rdimon-crt0%O%s
+
Index: libgloss/arm/coff-rdpmon.specs
===================================================================
RCS file: libgloss/arm/coff-rdpmon.specs
diff -N libgloss/arm/coff-rdpmon.specs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/coff-rdpmon.specs	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,8 @@
+%rename link                old_link
+
+*link:
+%(old_link) -lrdpmon
+
+*startfile:
+rdpmon-crt0%O%s
+
Index: libgloss/arm/crt0.S
===================================================================
RCS file: libgloss/arm/crt0.S
diff -N libgloss/arm/crt0.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/crt0.S	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,359 @@
+#include "swi.h"
+
+/* ANSI concatenation macros.  */
+#define CONCAT(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+#ifdef __USER_LABEL_PREFIX__
+#define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
+#else
+#error __USER_LABEL_PREFIX is not defined
+#endif
+
+/* .text is used instead of .section .text so it works with arm-aout too.  */
+	.text
+	.code 32
+	.align 	0
+
+	.global	_mainCRTStartup
+	.global	_start
+	.global	start
+start:
+_start:
+_mainCRTStartup:
+
+/* Start by setting up a stack */
+#ifdef ARM_RDP_MONITOR
+	/*  Issue Demon SWI to read stack info */
+	swi	SWI_GetEnv	/*  Returns command line in r0 */
+	mov	sp,r1		/*  and the highest memory address in r1 */
+	ldr	sl, .LC2	/*  stack limit is at end of data */
+	add	sl, sl, #256	/*  allow slop for stack overflow handling */
+				/*  and small frames */
+#else
+#ifdef ARM_RDI_MONITOR
+	/*  Issue Angel SWI to read stack info */
+	mov	r0, #AngelSWI_Reason_HeapInfo
+	adr	r1, .LC0	/*  point at ptr to 4 words to receive data */
+	swi	AngelSWI_ARM	/*  We are always in ARM mode for startup */
+	ldr	r0, .LC0	/*  point at values read */
+	ldr	sp, [r0, #8]
+	ldr	sl, [r0, #12]
+	add	sl, sl, #256	/*  allow slop for stack overflow handling */
+				/*  and small frames */
+#else
+	/*  Set up the stack pointer to a fixed value */
+	/*  Changes by toralf:
+	    - Allow linker script to provide stack via __stack symbol - see
+	      defintion of .Lstack
+	    - Provide "hooks" that may be used by the application to add
+	      custom init code - see .Lhwinit and .Lswinit	
+	    - Go through all execution modes and set up stack for each of them.
+	      Loosely based on init.s from ARM/Motorola example code.
+              Note: Mode switch via CPSR is not allowed once in non-privileged
+		    mode, so we take care not to enter "User" to set up its sp,
+		    and also skip most operations if already in that mode. */
+
+	ldr	r3, .Lstack
+	cmp	r3, #0
+	ldreq	r3, .LC0
+	/* Note: This 'mov' is essential when starting in User, and ensures we
+		 always get *some* sp value for the initial mode, even if we 
+		 have somehow missed it below (in which case it gets the same
+		 value as FIQ - not ideal, but better than nothing.) */
+	mov	sp, r3
+	mrs	r2, CPSR
+	tst	r2, #0x0F	/* Test mode bits - in User of all are 0 */
+	beq	.LC23		/* "eq" means r2 AND #0x0F is 0 */
+	msr     CPSR_c, #0xD1	/* FIRQ mode, interrupts disabled */
+	mov 	sp, r3
+	sub	sl, sp, #0x1000	/* This mode also has its own sl (see below) */
+	
+	mov	r3, sl	
+	msr     CPSR_c, #0xD7	/* Abort mode, interrupts disabled */
+	mov	sp, r3
+	sub	r3, r3, #0x1000
+
+	msr     CPSR_c, #0xDB	/* Undefined mode, interrupts disabled */
+	mov	sp, r3
+	sub	r3, r3, #0x1000
+
+	msr     CPSR_c, #0xD2	/* IRQ mode, interrupts disabled */
+	mov	sp, r3
+	sub	r3, r3, #0x2000
+		
+	msr     CPSR_c, #0xD3	/* Supervisory mode, interrupts disabled */
+	mov	sp, r3
+	sub	r3, r3, #0x8000	/* Min size 32k */
+	bic	r3, r3, #0x00FF	/* Align with current 64k block */
+	bic	r3, r3, #0xFF00
+
+	str	r3, [r3, #-4]	/* Move value into user mode sp without */ 
+	ldmdb	r3, {sp}^       /* changing modes, via '^' form of ldm */ 
+	
+	orr	r2, r2, #0xC0	/* Back to original mode, presumably SVC, */
+	msr	CPSR_c, r2	/* with FIQ/IRQ disable bits forced to 1 */
+.LC23:
+	/* Setup a default stack-limit in-case the code has been
+	   compiled with "-mapcs-stack-check".  Hard-wiring this value
+	   is not ideal, since there is currently no support for
+	   checking that the heap and stack have not collided, or that
+	   this default 64k is enough for the program being executed.
+	   However, it ensures that this simple crt0 world will not
+	   immediately cause an overflow event:  */
+	sub	sl, r3, #64 << 10	/* Still assumes 256bytes below sl */
+#endif
+#endif
+	/* Zero the memory in the .bss section.  */
+	mov 	a2, #0			/* Second arg: fill value */
+	mov	fp, a2			/* Null frame pointer */
+	mov	r7, a2			/* Null frame pointer for Thumb */
+	
+	ldr	a1, .LC1		/* First arg: start of memory block */
+	ldr	a3, .LC2	
+	sub	a3, a3, a1		/* Third arg: length of block */
+	
+
+#ifdef __thumb__		/* Enter Thumb mode.... */
+
+	add	a4, pc, #1	/* Get the address of the Thumb block */
+	bx	a4		/* Go there and start Thumb decoding  */
+
+	.code 16
+	.global __change_mode
+	.thumb_func
+__change_mode:	
+#endif
+	
+	bl	FUNCTION (memset)
+#if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)
+/* Changes by toralf: Taken from libgloss/m68k/crt0.S
+ * initialize target specific stuff. Only execute these
+ * functions it they exist.
+ */
+	ldr	r3, .Lhwinit
+	cmp	r3, #0
+	beq	.LC24
+	mov	lr, pc
+	mov	pc, r3
+.LC24:	
+	ldr	r3, .Lswinit
+	cmp	r3, #0
+	beq	.LC25
+	mov	lr, pc
+	mov	pc, r3
+.LC25:	
+	mov	r0, #0		/*  no arguments  */
+	mov	r1, #0		/*  no argv either */
+#else
+	/* Need to set up standard file handles */
+	bl	FUNCTION (initialise_monitor_handles)
+	
+#ifdef ARM_RDP_MONITOR
+	swi	SWI_GetEnv	/*  sets r0 to point to the command line */
+	mov	r1, r0
+#else
+	mov	r0, #AngelSWI_Reason_GetCmdLine
+	adr	r1, .LC30	/*  Space for command line */
+	swi	AngelSWI
+	ldr	r1, .LC30
+#endif
+	/*  Parse string at r1 */
+	mov	r0, #0		/*  count of arguments so far */
+	/* Push a NULL argument onto the end of the list.  */
+#ifdef __thumb__
+	push	{r0}
+#else
+	stmfd	sp!, {r0}
+#endif
+.LC10:
+/*  Skip leading blanks */
+#ifdef __thumb__
+	ldrb	r3, [r1]
+	add	r1, #1
+#else
+	ldrb	r3, [r1], #1
+#endif
+	cmp	r3, #0
+	beq	.LC12
+	cmp	r3, #' '
+	beq	.LC10
+
+/*  See whether we are scanning a string */
+	cmp	r3, #'"'
+#ifdef __thumb__
+	beq	.LC20
+	cmp	r3, #'\''
+	bne	.LC21
+.LC20:
+	mov	r2, r3
+	b	.LC22
+
+.LC21:
+	mov	r2, #' '	/*  terminator type */
+	sub	r1, r1, #1	/*  adjust back to point at start char */
+.LC22:
+#else
+	cmpne	r3, #'\''
+	moveq	r2, r3
+	movne	r2, #' '	/*  terminator type */
+	subne	r1, r1, #1	/*  adjust back to point at start char */
+#endif
+
+/*  Stack a pointer to the current argument */
+#ifdef __thumb__
+	push	{r1}
+#else
+	stmfd	sp!, {r1}
+#endif
+	add	r0, r0, #1
+.LC11:
+#ifdef __thumb__
+	ldrb	r3, [r1]
+	add	r1, #1
+#else
+	ldrb	r3, [r1], #1
+#endif
+	cmp	r3, #0
+	beq	.LC12
+	cmp	r2, r3		/*  reached terminator? */
+	bne	.LC11
+	mov	r2, #0
+	sub	r3, r1, #1
+	strb	r2, [r3]	/*  terminate the arg string */
+	b	.LC10
+
+.LC12:
+	mov	r1, sp		/*  point at stacked arg pointers */
+	/* We've now got the stacked args in order reverse the */
+#ifdef __thumb__
+	mov	r2, r0
+	lsl	r2, #2
+	add	r2, sp
+	mov	r3, sp
+.LC15:	cmp	r2, r3
+	bls	.LC14
+	sub	r2, #4
+	ldr	r4, [r2]
+	ldr	r5, [r3]
+	str	r5, [r2]
+	str	r4, [r3]
+	add	r3, #4
+	b	.LC15
+.LC14:	
+#else
+	add	r2, sp, r0, LSL #2	/* End of args */
+	mov	r3, sp			/* Start of args */
+.LC13:	cmp	r2, r3
+	ldrhi	r4,[r2, #-4]		/* Reverse ends of list */
+	ldrhi	r5, [r3]
+	strhi	r5, [r2, #-4]!
+	strhi	r4, [r3], #4
+	bhi	.LC13
+#endif
+#endif
+
+#ifdef __USES_INITFINI__
+	/* Some arm/elf targets use the .init and .fini sections
+	   to create constructors and destructors, and for these
+	   targets we need to call the _init function and arrange
+	   for _fini to be called at program exit.  */
+	mov	r4, r0
+	mov	r5, r1
+	ldr	r0, .Lfini
+	bl	FUNCTION (atexit)
+	bl	FUNCTION (_init)
+	mov	r0, r4
+	mov	r1, r5
+#endif	
+	bl	FUNCTION (main)
+
+	bl	FUNCTION (exit)		/* Should not return.  */
+
+#ifdef __thumb__
+	/* Come out of Thumb mode.  This code should be redundant.  */
+
+	mov	a4, pc
+	bx	a4
+
+	.code 32
+	.global change_back
+change_back:
+	/* Halt the execution.  This code should never be executed.  */
+	/* With no debug monitor, this probably aborts (eventually).
+	   With a Demon debug monitor, this halts cleanly.
+	   With an Angel debug monitor, this will report 'Unknown SWI'.	 */
+	swi	SWI_Exit
+#endif
+	
+	/* For Thumb, constants must be after the code since only 
+	   positive offsets are supported for PC relative addresses.  */
+	
+	.align 0
+.LC0:
+#ifdef ARM_RDI_MONITOR
+	.word	HeapBase
+#else
+#ifndef ARM_RDP_MONITOR
+	/* Changes by toralf: Provide alternative "stack" variable whose value
+	   may be defined externally; .Lstack will be used instead of .LC0 if
+	   it points to a non-0 value. Also set up references to "hooks" that
+           may be used by the application to provide additional init code. */
+	
+#ifdef __pe__
+	.word	0x800000
+#else
+	.word	0x80000			/* Top of RAM on the PIE board.  */
+#endif
+.Lstack:	
+	.word	__stack
+.Lhwinit:	
+	.word	FUNCTION (hardware_init_hook)
+.Lswinit:
+	.word	FUNCTION (software_init_hook)
+
+	/* Set up defaults for the above variables in the form of weak symbols
+	   - so that application will link correctly, and get value 0 in
+	   runtime (meaning "ignore setting") for the variables, when the user
+	   does not provide the symbols. (The linker uses a weak symbol if,
+	   and only if, a normal version of the same symbol isn't provided
+	   e.g. by a linker script or another object file.) */	
+
+	.set __stack, 0
+	.set FUNCTION (hardware_init_hook), 0
+	.set FUNCTION (software_init_hook), 0
+	
+	.weak __stack
+	.weak FUNCTION (hardware_init_hook) 
+	.weak FUNCTION (software_init_hook)
+#endif
+	
+#endif
+.LC1:
+	.word	__bss_start__
+.LC2:
+	.word	__bss_end__
+#ifdef __USES_INITFINI__
+.Lfini:
+	.word	FUNCTION(_fini)
+#endif
+#ifdef ARM_RDI_MONITOR
+.LC30:
+	.word	CommandLine
+	.word	255
+
+/*  Workspace for Angel calls.  */
+	.data
+/*  Data returned by monitor SWI.  */
+.global	__stack_base__
+HeapBase:	.word	0
+HeapLimit:	.word	0
+__stack_base__:	.word	0
+StackLimit:	.word	0
+CommandLine:	.space	256,0	/*  Maximum length of 255 chars handled.  */
+#endif
+	
+#ifdef __pe__
+	.section .idata$3
+	.long	0,0,0,0,0,0,0,0
+#endif
Index: libgloss/arm/elf-rdimon.specs
===================================================================
RCS file: libgloss/arm/elf-rdimon.specs
diff -N libgloss/arm/elf-rdimon.specs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/elf-rdimon.specs	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,8 @@
+%rename link                old_link
+
+*link:
+%(old_link) -lrdimon
+
+*startfile:
+crti%O%s crtbegin%O%s %{!pg:rdimon-crt0%O%s} %{pg:rdimon-crt0%O%s}
+
Index: libgloss/arm/elf-rdpmon.specs
===================================================================
RCS file: libgloss/arm/elf-rdpmon.specs
diff -N libgloss/arm/elf-rdpmon.specs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/elf-rdpmon.specs	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,8 @@
+%rename link                old_link
+
+*link:
+%(old_link) -lrdpmon
+
+*startfile:
+crti%O%s crtbegin%O%s %{!pg:rdpmon-crt0%O%s} %{pg:rdpmon-crt0%O%s}
+
Index: libgloss/arm/libcfunc.c
===================================================================
RCS file: libgloss/arm/libcfunc.c
diff -N libgloss/arm/libcfunc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/libcfunc.c	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,40 @@
+/* Support files for GNU libc.  Files in the C namespace go here.
+   Files in the system namespace (ie those that start with an underscore)
+   go in syscalls.c.
+   
+   Note: These functions are in a seperate file so that OS providers can
+   overrride the system call stubs (defined in syscalls.c) without having
+   to provide libc funcitons as well.  */
+#include "swi.h"
+
+#ifdef ARM_RDI_MONITOR
+
+static inline int
+do_AngelSWI (int reason, void * arg)
+{
+  int value;
+  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
+       : "=r" (value) /* Outputs */
+       : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
+       : "r0", "r1", "lr"
+		/* Clobbers r0 and r1, and lr if in supervisor mode */);
+  return value;
+}
+#endif /* ARM_RDI_MONITOR */
+
+
+void
+abort (void)
+{
+#ifdef ARM_RDI_MONITOR
+  do_AngelSWI (AngelSWI_Reason_ReportException,
+	      (void *) ADP_Stopped_RunTimeError);
+#else
+ asm ("mov r0,#17\nswi %a0" :: "i" (SWI_Exit));
+#endif
+}
+
+void
+alarm (void)
+{
+}
Index: libgloss/arm/swi.h
===================================================================
RCS file: libgloss/arm/swi.h
diff -N libgloss/arm/swi.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/swi.h	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,60 @@
+/* SWI numbers for RDP (Demon) monitor.  */
+#define SWI_WriteC                 0x0
+#define SWI_Write0                 0x2
+#define SWI_ReadC                  0x4
+#define SWI_CLI                    0x5
+#define SWI_GetEnv                 0x10
+#define SWI_Exit                   0x11
+#define SWI_EnterOS                0x16
+
+#define SWI_GetErrno               0x60
+#define SWI_Clock                  0x61
+#define SWI_Time                   0x63
+#define SWI_Remove                 0x64
+#define SWI_Rename                 0x65
+#define SWI_Open                   0x66
+
+#define SWI_Close                  0x68
+#define SWI_Write                  0x69
+#define SWI_Read                   0x6a
+#define SWI_Seek                   0x6b
+#define SWI_Flen                   0x6c
+
+#define SWI_IsTTY                  0x6e
+#define SWI_TmpNam                 0x6f
+#define SWI_InstallHandler         0x70
+#define SWI_GenerateError          0x71
+
+
+/* Now the SWI numbers and reason codes for RDI (Angel) monitors.  */
+#define AngelSWI_ARM 			0x123456
+#ifdef __thumb__
+#define AngelSWI 			0xAB
+#else
+#define AngelSWI 			AngelSWI_ARM
+#endif
+
+/* The reason codes:  */
+#define AngelSWI_Reason_Open		0x01
+#define AngelSWI_Reason_Close		0x02
+#define AngelSWI_Reason_WriteC		0x03
+#define AngelSWI_Reason_Write0		0x04
+#define AngelSWI_Reason_Write		0x05
+#define AngelSWI_Reason_Read		0x06
+#define AngelSWI_Reason_ReadC		0x07
+#define AngelSWI_Reason_IsTTY		0x09
+#define AngelSWI_Reason_Seek		0x0A
+#define AngelSWI_Reason_FLen		0x0C
+#define AngelSWI_Reason_TmpNam		0x0D
+#define AngelSWI_Reason_Remove		0x0E
+#define AngelSWI_Reason_Rename		0x0F
+#define AngelSWI_Reason_Clock		0x10
+#define AngelSWI_Reason_Time		0x11
+#define AngelSWI_Reason_System		0x12
+#define AngelSWI_Reason_Errno		0x13
+#define AngelSWI_Reason_GetCmdLine 	0x15
+#define AngelSWI_Reason_HeapInfo 	0x16
+#define AngelSWI_Reason_EnterSVC 	0x17
+#define AngelSWI_Reason_ReportException 0x18
+#define ADP_Stopped_ApplicationExit 	((2 << 16) + 38)
+#define ADP_Stopped_RunTimeError 	((2 << 16) + 35)
Index: libgloss/arm/syscalls.c
===================================================================
RCS file: libgloss/arm/syscalls.c
diff -N libgloss/arm/syscalls.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/syscalls.c	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,630 @@
+/* Support files for GNU libc.  Files in the system namespace go here.
+   Files in the C namespace (ie those that do not start with an
+   underscore) go in .c.  */
+
+#include <_ansi.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <errno.h>
+#include <reent.h>
+#include <unistd.h>
+#include "swi.h"
+
+/* Forward prototypes.  */
+int     _system     _PARAMS ((const char *));
+int     _rename     _PARAMS ((const char *, const char *));
+int     isatty		_PARAMS ((int));
+clock_t _times		_PARAMS ((struct tms *));
+int     _gettimeofday	_PARAMS ((struct timeval *, struct timezone *));
+void    _raise 		_PARAMS ((void));
+int     _unlink		_PARAMS ((void));
+int     _link 		_PARAMS ((void));
+int     _stat 		_PARAMS ((const char *, struct stat *));
+int     _fstat 		_PARAMS ((int, struct stat *));
+caddr_t _sbrk		_PARAMS ((int));
+int     _getpid		_PARAMS ((int));
+int     _kill		_PARAMS ((int, int));
+void    _exit		_PARAMS ((int));
+int     _close		_PARAMS ((int));
+int     _swiclose	_PARAMS ((int));
+int     _open		_PARAMS ((const char *, int, ...));
+int     _swiopen	_PARAMS ((const char *, int));
+int     _write 		_PARAMS ((int, char *, int));
+int     _swiwrite	_PARAMS ((int, char *, int));
+int     _lseek		_PARAMS ((int, int, int));
+int     _swilseek	_PARAMS ((int, int, int));
+int     _read		_PARAMS ((int, char *, int));
+int     _swiread	_PARAMS ((int, char *, int));
+void    initialise_monitor_handles _PARAMS ((void));
+
+static int	wrap		_PARAMS ((int));
+static int	error		_PARAMS ((int));
+static int	get_errno	_PARAMS ((void));
+static int	remap_handle	_PARAMS ((int));
+static int	do_AngelSWI	_PARAMS ((int, void *));
+static int 	findslot	_PARAMS ((int));
+
+/* Register name faking - works in collusion with the linker.  */
+register char * stack_ptr asm ("sp");
+
+
+/* following is copied from libc/stdio/local.h to check std streams */
+extern void   _EXFUN(__sinit,(struct _reent *));
+#define CHECK_INIT(fp) \
+  do                                    \
+    {                                   \
+      if ((fp)->_data == 0)             \
+        (fp)->_data = _REENT;           \
+      if (!(fp)->_data->__sdidinit)     \
+        __sinit ((fp)->_data);          \
+    }                                   \
+  while (0)
+
+/* Adjust our internal handles to stay away from std* handles.  */
+#define FILE_HANDLE_OFFSET (0x20)
+
+static int std_files_checked;
+static int monitor_stdin;
+static int monitor_stdout;
+static int monitor_stderr;
+
+/* Struct used to keep track of the file position, just so we
+   can implement fseek(fh,x,SEEK_CUR).  */
+typedef struct
+{
+  int handle;
+  int pos;
+}
+poslog;
+
+#define MAX_OPEN_FILES 20
+static poslog openfiles [MAX_OPEN_FILES];
+
+static int
+findslot (int fh)
+{
+  int i;
+  for (i = 0; i < MAX_OPEN_FILES; i ++)
+    if (openfiles[i].handle == fh)
+      break;
+  return i;
+}
+
+#ifdef ARM_RDI_MONITOR
+
+static inline int
+do_AngelSWI (int reason, void * arg)
+{
+  int value;
+  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
+       : "=r" (value) /* Outputs */
+       : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
+       : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
+		/* Clobbers r0 and r1, and lr if in supervisor mode */);
+                /* Accordingly to page 13-77 of ARM DUI 0040D other registers
+                   can also be clobbered.  Some memory positions may also be
+                   changed by a system call, so they should not be kept in
+                   registers. Note: we are assuming the manual is right and
+                   Angel is respecting the APCS.  */
+  return value;
+}
+#endif /* ARM_RDI_MONITOR */
+
+/* Function to convert std(in|out|err) handles to internal versions.  */
+static int
+remap_handle (int fh)
+{
+  if (!std_files_checked)
+    {
+       CHECK_INIT(stdin);
+       CHECK_INIT(stdout);
+       CHECK_INIT(stderr);
+       std_files_checked = 1;
+    }
+  if (fh == STDIN_FILENO)
+    return monitor_stdin;
+  if (fh == STDOUT_FILENO)
+    return monitor_stdout;
+  if (fh == STDERR_FILENO)
+    return monitor_stderr;
+
+  return fh - FILE_HANDLE_OFFSET;
+}
+
+void
+initialise_monitor_handles (void)
+{
+  int i;
+  
+#ifdef ARM_RDI_MONITOR
+  int volatile block[3];
+  
+  block[0] = (int) ":tt";
+  block[2] = 3;     /* length of filename */
+  block[1] = 0;     /* mode "r" */
+  monitor_stdin = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
+
+  block[0] = (int) ":tt";
+  block[2] = 3;     /* length of filename */
+  block[1] = 4;     /* mode "w" */
+  monitor_stdout = monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
+#else
+  int fh;
+  const char * name;
+
+  name = ":tt";
+  asm ("mov r0,%2; mov r1, #0; swi %a1; mov %0, r0"
+       : "=r"(fh)
+       : "i" (SWI_Open),"r"(name)
+       : "r0","r1");
+  monitor_stdin = fh;
+
+  name = ":tt";
+  asm ("mov r0,%2; mov r1, #4; swi %a1; mov %0, r0"
+       : "=r"(fh)
+       : "i" (SWI_Open),"r"(name)
+       : "r0","r1");
+  monitor_stdout = monitor_stderr = fh;
+#endif
+
+  for (i = 0; i < MAX_OPEN_FILES; i ++)
+    openfiles[i].handle = -1;
+
+  openfiles[0].handle = monitor_stdin;
+  openfiles[0].pos = 0;
+  openfiles[1].handle = monitor_stdout;
+  openfiles[1].pos = 0;
+}
+
+static int
+get_errno (void)
+{
+#ifdef ARM_RDI_MONITOR
+  return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
+#else
+  asm ("swi %a0" :: "i" (SWI_GetErrno));
+#endif
+}
+
+static int
+error (int result)
+{
+  errno = get_errno ();
+  return result;
+}
+
+static int
+wrap (int result)
+{
+  if (result == -1)
+    return error (-1);
+  return result;
+}
+
+/* Returns # chars not! written.  */
+int
+_swiread (int file,
+	  char * ptr,
+	  int len)
+{
+  int fh = remap_handle (file);
+#ifdef ARM_RDI_MONITOR
+  int block[3];
+  
+  block[0] = fh;
+  block[1] = (int) ptr;
+  block[2] = len;
+  
+  return do_AngelSWI (AngelSWI_Reason_Read, block);
+#else
+  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
+       : /* No outputs */
+       : "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)
+       : "r0","r1","r2");
+#endif
+}
+
+int
+_read (int file,
+       char * ptr,
+       int len)
+{
+  int slot = findslot (remap_handle (file));
+  int x = _swiread (file, ptr, len);
+
+  if (x < 0)
+    return error (-1);
+
+  if (slot != MAX_OPEN_FILES)
+    openfiles [slot].pos += len - x;
+
+  /* x == len is not an error, at least if we want feof() to work.  */
+  return len - x;
+}
+
+int
+_swilseek (int file,
+	   int ptr,
+	   int dir)
+{
+  int res;
+  int fh = remap_handle (file);
+  int slot = findslot (fh);
+#ifdef ARM_RDI_MONITOR
+  int block[2];
+#endif
+
+  if (dir == SEEK_CUR)
+    {
+      if (slot == MAX_OPEN_FILES)
+	return -1;
+      ptr = openfiles[slot].pos + ptr;
+      dir = SEEK_SET;
+    }
+  
+#ifdef ARM_RDI_MONITOR
+  if (dir == SEEK_END)
+    {
+      block[0] = fh;
+      ptr += do_AngelSWI (AngelSWI_Reason_FLen, block);
+    }
+  
+  /* This code only does absolute seeks.  */
+  block[0] = remap_handle (file);
+  block[1] = ptr;
+  res = do_AngelSWI (AngelSWI_Reason_Seek, block);
+#else
+  if (dir == SEEK_END)
+    {
+      asm ("mov r0, %2; swi %a1; mov %0, r0"
+	   : "=r" (res)
+	   : "i" (SWI_Flen), "r" (fh)
+	   : "r0");
+      ptr += res;
+    }
+
+  /* This code only does absolute seeks.  */
+  asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
+       : "=r" (res)
+       : "i" (SWI_Seek), "r" (fh), "r" (ptr)
+       : "r0", "r1");
+#endif
+
+  if (slot != MAX_OPEN_FILES && res == 0)
+    openfiles[slot].pos = ptr;
+
+  /* This is expected to return the position in the file.  */
+  return res == 0 ? ptr : -1;
+}
+
+int
+_lseek (int file,
+	int ptr,
+	int dir)
+{
+  return wrap (_swilseek (file, ptr, dir));
+}
+
+/* Returns #chars not! written.  */
+int
+_swiwrite (
+	   int    file,
+	   char * ptr,
+	   int    len)
+{
+  int fh = remap_handle (file);
+#ifdef ARM_RDI_MONITOR
+  int block[3];
+  
+  block[0] = fh;
+  block[1] = (int) ptr;
+  block[2] = len;
+  
+  return do_AngelSWI (AngelSWI_Reason_Write, block);
+#else
+  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
+       : /* No outputs */
+       : "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)
+       : "r0","r1","r2");
+#endif
+}
+
+int
+_write (int    file,
+	char * ptr,
+	int    len)
+{
+  int slot = findslot (remap_handle (file));
+  int x = _swiwrite (file, ptr,len);
+
+  if (x == -1 || x == len)
+    return error (-1);
+  
+  if (slot != MAX_OPEN_FILES)
+    openfiles[slot].pos += len - x;
+  
+  return len - x;
+}
+
+extern int strlen (const char *);
+
+int
+_swiopen (const char * path,
+	  int          flags)
+{
+  int aflags = 0, fh;
+#ifdef ARM_RDI_MONITOR
+  int block[3];
+#endif
+  
+  int i = findslot (-1);
+  
+  if (i == MAX_OPEN_FILES)
+    return -1;
+
+  /* The flags are Unix-style, so we need to convert them.  */
+#ifdef O_BINARY
+  if (flags & O_BINARY)
+    aflags |= 1;
+#endif
+
+  if (flags & O_RDWR)
+    aflags |= 2;
+
+  if (flags & O_CREAT)
+    aflags |= 4;
+
+  if (flags & O_TRUNC)
+    aflags |= 4;
+
+  if (flags & O_APPEND)
+    {
+      aflags &= ~4;     /* Can't ask for w AND a; means just 'a'.  */
+      aflags |= 8;
+    }
+  
+#ifdef ARM_RDI_MONITOR
+  block[0] = (int) path;
+  block[2] = strlen (path);
+  block[1] = aflags;
+  
+  fh = do_AngelSWI (AngelSWI_Reason_Open, block);
+  
+#else
+  asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"
+       : "=r"(fh)
+       : "i" (SWI_Open),"r"(path),"r"(aflags)
+       : "r0","r1");
+#endif
+  
+  if (fh >= 0)
+    {
+      openfiles[i].handle = fh;
+      openfiles[i].pos = 0;
+    }
+
+  return fh >= 0 ? fh + FILE_HANDLE_OFFSET : error (fh);
+}
+
+int
+_open (const char * path,
+       int          flags,
+       ...)
+{
+  return wrap (_swiopen (path, flags));
+}
+
+int
+_swiclose (int file)
+{
+  int myhan = remap_handle (file);
+  int slot = findslot (myhan);
+  
+  if (slot != MAX_OPEN_FILES)
+    openfiles[slot].handle = -1;
+
+#ifdef ARM_RDI_MONITOR
+  return do_AngelSWI (AngelSWI_Reason_Close, & myhan);
+#else
+  asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
+#endif
+}
+
+int
+_close (int file)
+{
+  return wrap (_swiclose (file));
+}
+
+void
+_exit (int n)
+{
+  /* FIXME: return code is thrown away.  */
+  
+#ifdef ARM_RDI_MONITOR
+  do_AngelSWI (AngelSWI_Reason_ReportException,
+	      (void *) ADP_Stopped_ApplicationExit);
+#else
+  asm ("swi %a0" :: "i" (SWI_Exit));
+#endif
+  n = n;
+}
+
+int
+_kill (int n, int m)
+{
+#ifdef ARM_RDI_MONITOR
+  return do_AngelSWI (AngelSWI_Reason_ReportException,
+		      (void *) ADP_Stopped_ApplicationExit);
+#else
+  asm ("swi %a0" :: "i" (SWI_Exit));
+#endif
+  n = n; m = m;
+}
+
+int
+_getpid (int n)
+{
+  return 1;
+  n = n;
+}
+
+caddr_t
+_sbrk (int incr)
+{
+  extern char   end asm ("end");	/* Defined by the linker.  */
+  static char * heap_end;
+  char *        prev_heap_end;
+
+  if (heap_end == NULL)
+    heap_end = & end;
+  
+  prev_heap_end = heap_end;
+  
+  if (heap_end + incr > stack_ptr)
+    {
+      /* Some of the libstdc++-v3 tests rely upon detecting
+	 out of memory errors, so do not abort here.  */
+#if 0
+      extern void abort (void);
+
+      _write (1, "_sbrk: Heap and stack collision\n", 32);
+      
+      abort ();
+#else
+      errno = ENOMEM;
+      return (caddr_t) -1;
+#endif
+    }
+  
+  heap_end += incr;
+
+  return (caddr_t) prev_heap_end;
+}
+
+extern void memset (struct stat *, int, unsigned int);
+
+int
+_fstat (int file, struct stat * st)
+{
+  memset (st, 0, sizeof (* st));
+  st->st_mode = S_IFCHR;
+  st->st_blksize = 1024;
+  return 0;
+  file = file;
+}
+
+int _stat (const char *fname, struct stat *st)
+{
+  int file;
+
+  /* The best we can do is try to open the file readonly.  If it exists,
+     then we can guess a few things about it.  */
+  if ((file = _open (fname, O_RDONLY)) < 0)
+    return -1;
+
+  memset (st, 0, sizeof (* st));
+  st->st_mode = S_IFREG | S_IREAD;
+  st->st_blksize = 1024;
+  _swiclose (file); /* Not interested in the error.  */
+  return 0;
+}
+
+int
+_link (void)
+{
+  return -1;
+}
+
+int
+_unlink (void)
+{
+  return -1;
+}
+
+void
+_raise (void)
+{
+  return;
+}
+
+int
+_gettimeofday (struct timeval * tp, struct timezone * tzp)
+{
+
+  if (tp)
+    {
+    /* Ask the host for the seconds since the Unix epoch.  */
+#ifdef ARM_RDI_MONITOR
+      tp->tv_sec = do_AngelSWI (AngelSWI_Reason_Time,NULL);
+#else
+      {
+        int value;
+        asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0");
+        tp->tv_sec = value;
+      }
+#endif
+      tp->tv_usec = 0;
+    }
+
+  /* Return fixed data for the timezone.  */
+  if (tzp)
+    {
+      tzp->tz_minuteswest = 0;
+      tzp->tz_dsttime = 0;
+    }
+
+  return 0;
+}
+
+/* Return a clock that ticks at 100Hz.  */
+clock_t 
+_times (struct tms * tp)
+{
+  clock_t timeval;
+
+#ifdef ARM_RDI_MONITOR
+  timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL);
+#else
+  asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");
+#endif
+
+  if (tp)
+    {
+      tp->tms_utime  = timeval;	/* user time */
+      tp->tms_stime  = 0;	/* system time */
+      tp->tms_cutime = 0;	/* user time, children */
+      tp->tms_cstime = 0;	/* system time, children */
+    }
+  
+  return timeval;
+};
+
+
+int
+isatty (int fd)
+{
+  return 1;
+  fd = fd;
+}
+
+int
+_system (const char *s)
+{
+  if (s == NULL)
+    return 0;
+  errno = ENOSYS;
+  return -1;
+}
+
+int
+_rename (const char * oldpath, const char * newpath)
+{
+  errno = ENOSYS;
+  return -1;
+}
Index: libgloss/arm/trap.S
===================================================================
RCS file: libgloss/arm/trap.S
diff -N libgloss/arm/trap.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgloss/arm/trap.S	7 Jun 2004 18:47:17 -0000
@@ -0,0 +1,93 @@
+        /* Run-time exception support */
+#include "swi.h"
+
+/* .text is used instead of .section .text so it works with arm-aout too.  */
+	.text
+        .align 0
+        .global __rt_stkovf_split_big
+        .global __rt_stkovf_split_small
+
+/* The following functions are provided for software stack checking.
+   If hardware stack-checking is being used then the code can be
+   compiled without the PCS entry checks, and simply rely on VM
+   management to extend the stack for a thread.
+
+   The stack extension event occurs when the PCS function entry code
+   would result in a stack-pointer beneath the stack-limit register
+   value.  The system relies on the following map:
+
+        +-----------------------------------+ <-- end of stack block
+        | ...                               |
+        | ...                               |
+        | active stack                      |
+        | ...                               | <-- sp (stack-pointer) somewhere in here
+        | ...                               |
+        +-----------------------------------+ <-- sl (stack-limit)
+        | stack-extension handler workspace |
+        +-----------------------------------+ <-- base of stack block
+
+   The "stack-extension handler workspace" is an amount of memory in
+   which the stack overflow support code must execute.  It must be
+   large enough to deal with the worst case path through the extension
+   code.  At the moment the compiler expects this to be AT LEAST
+   256bytes.  It uses this fact to code functions with small local
+   data usage within the overflow space.
+
+   In a true target environment We may need to increase the space
+   between sl and the true limit to allow for the stack extension
+   code, SWI handlers and for undefined instruction handlers of the
+   target environment.  */
+
+__rt_stkovf_split_small:
+        mov     ip,sp   @ Ensure we can calculate the stack required
+        @ and fall through to...
+__rt_stkovf_split_big:
+        @ in:   sp = current stack-pointer (beneath stack-limit)
+        @       sl = current stack-limit
+        @       ip = low stack point we require for the current function
+        @       lr = return address into the current function
+        @       fp = frame-pointer
+        @               original sp --> +----------------------------------+
+        @                               | pc (12 ahead of PCS entry store) |
+        @               current fp ---> +----------------------------------+
+        @                               | lr (on entry) pc (on exit)       |
+        @                               +----------------------------------+
+        @                               | sp ("original sp" on entry)      |
+        @                               +----------------------------------+
+        @                               | fp (on entry to function)        |
+        @                               +----------------------------------+
+        @                               |                                  |
+        @                               | ..argument and work registers..  |
+        @                               |                                  |
+        @               current sp ---> +----------------------------------+
+        @
+        @ The "current sl" is somewhere between "original sp" and "current sp"
+        @ but above "true sl". The "current sl" should be at least 256bytes
+        @ above the "true sl". The 256byte stack guard should be large enough
+        @ to deal with the worst case function entry stacking (160bytes) plus
+        @ the stack overflow handler stacking requirements, plus the stack
+        @ required for the memory allocation routines.
+        @
+        @ Normal PCS entry (before stack overflow check) can stack 16
+        @ standard registers (64bytes) and 8 floating point registers
+        @ (96bytes). This gives a minimum stack guard of 160bytes (excluding
+        @ the stack required for the code). (Actually only a maximum of
+        @ 14standard registers are ever stacked on entry to a function).
+        @
+        @ NOTE: Structure returns are performed by the caller allocating a
+        @       dummy space on the stack and passing in a "phantom" arg1 into
+        @       the function. This means that we do not need to worry about
+        @       preserving the stack under "sp" even on function return.
+        @ 
+        @        Code should never poke values beneath sp. The sp register
+        @        should always be "dropped" first to cover the data. This
+        @        protects the data against any events that may try and use
+        @        the stack.
+
+        SUB     ip, sp, ip      @ extra stack required for function
+        @ Add stack extension code here.  If desired a new stack chunk
+        @ can be allocated, and the register state updated suitably.
+
+        @ We now know how much extra stack the function requires.
+        @ Terminate the program for the moment:
+        swi     SWI_Exit
