Fixes for mmix-knuth-mmixware
Hans-Peter Nilsson
hp@bitrange.com
Mon Feb 11 18:07:00 GMT 2002
Hi. A few patches (attached) for:
- Framework bugs, needs _link and should define _times, not times (a bug
in common with other targets, it seems).
- Trying to handle file append completely wrong (there's actually no
support for it in the simulator).
- Missing __volatile__ on the value-returning asms for simulator calls
made them disappear if the values weren't used. Bad if you expect some
side-effect from them. :-)
Can I please commit this? (Else please consider doing it for me.)
Can I commit changes to the mmixware files in the future, without explicit
approval?
2002-02-12 Hans-Peter Nilsson <hp@bitrange.com>
* libc/sys/mmixware/link.c: New.
* libc/sys/mmixware/sys/syscall.h (TRAP1i, I3f): Make asm
volatile.
* libc/sys/mmixware/times.c (_times): Renamed from times.
* libc/sys/mmixware/open.c (_open): Attempt to handle O_APPEND
properly by reading previous contents, not through BinaryReadWrite.
* libc/sys/mmixware/Makefile.am (lib_a_SOURCES): Add link.c
* libc/sys/mmixware/Makefile.in: Regenerate.
(Nag: don't forget to regenerate libc/sys/mmixware/Makefile.in. ;-)
brgds, H-P
-------------- next part --------------
*** /dev/null Tue Jan 1 05:00:00 1980
--- libc/sys/mmixware/link.c Mon Dec 31 04:20:30 2001
***************
*** 0 ****
--- 1,25 ----
+ /* link stub for MMIXware.
+
+ Copyright (C) 2002 Hans-Peter Nilsson
+
+ Permission to use, copy, modify, and distribute this software is
+ freely granted, provided that the above copyright notice, this notice
+ and the following disclaimer are preserved with no changes.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. */
+
+ #include <_ansi.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include "sys/syscall.h"
+ #include <errno.h>
+
+ int
+ _link ()
+ {
+ errno = EMLINK;
+ return -1;
+ }
Index: libc/sys/mmixware/Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/Makefile.am,v
retrieving revision 1.1
diff -p -c -r1.1 Makefile.am
*** libc/sys/mmixware/Makefile.am 2001/11/12 21:04:41 1.1
--- libc/sys/mmixware/Makefile.am 2002/02/12 01:39:58
*************** noinst_LIBRARIES = lib.a
*** 8,14 ****
lib_a_SOURCES = _exit.c access.c chmod.c chown.c close.c creat.c \
execv.c execve.c fork.c fstat.c getpid.c isatty.c \
! kill.c lseek.c open.c pipe.c read.c \
sbrk.c stat.c time.c unlink.c utime.c wait.c write.c \
times.c gettime.c setjmp.S
--- 8,14 ----
lib_a_SOURCES = _exit.c access.c chmod.c chown.c close.c creat.c \
execv.c execve.c fork.c fstat.c getpid.c isatty.c \
! kill.c link.c lseek.c open.c pipe.c read.c \
sbrk.c stat.c time.c unlink.c utime.c wait.c write.c \
times.c gettime.c setjmp.S
Index: libc/sys/mmixware/open.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/open.c,v
retrieving revision 1.3
diff -p -c -r1.3 open.c
*** libc/sys/mmixware/open.c 2001/11/18 23:47:59 1.3
--- libc/sys/mmixware/open.c 2002/02/12 01:39:58
***************
*** 1,6 ****
/* open for MMIXware.
! Copyright (C) 2001 Hans-Peter Nilsson
Permission to use, copy, modify, and distribute this software is
freely granted, provided that the above copyright notice, this notice
--- 1,6 ----
/* open for MMIXware.
! Copyright (C) 2001, 2002 Hans-Peter Nilsson
Permission to use, copy, modify, and distribute this software is
freely granted, provided that the above copyright notice, this notice
***************
*** 11,16 ****
--- 11,17 ----
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. */
+ #include <stdlib.h>
#include <fcntl.h>
#include <_ansi.h>
#include <sys/types.h>
*************** _open (const char *path,
*** 37,43 ****
{
long fileno;
unsigned char mode;
! long fffile = 0;
long ret;
for (fileno = 0;
--- 38,46 ----
{
long fileno;
unsigned char mode;
! long append_contents = 0;
! unsigned long prev_contents_size = 0;
! char *prev_contents = NULL;
long ret;
for (fileno = 0;
*************** _open (const char *path,
*** 55,61 ****
}
/* We map this to a fopen call. The flags parameter is stymied because
! we don't support more other than these flags. */
if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC))
{
UNIMPLEMENTED (("path: %s, flags: %d", path, flags));
--- 58,64 ----
}
/* We map this to a fopen call. The flags parameter is stymied because
! we don't support other than these flags. */
if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC))
{
UNIMPLEMENTED (("path: %s, flags: %d", path, flags));
*************** _open (const char *path,
*** 68,79 ****
else if ((flags & (O_WRONLY | O_APPEND)) == (O_WRONLY | O_APPEND))
{
mode = BinaryReadWrite;
! fffile = 1;
}
else if ((flags & (O_RDWR | O_APPEND)) == (O_RDWR | O_APPEND))
{
mode = BinaryReadWrite;
! fffile = 1;
}
else if ((flags & (O_WRONLY | O_CREAT)) == (O_WRONLY | O_CREAT)
|| (flags & (O_WRONLY | O_TRUNC)) == (O_WRONLY | O_TRUNC))
--- 71,82 ----
else if ((flags & (O_WRONLY | O_APPEND)) == (O_WRONLY | O_APPEND))
{
mode = BinaryReadWrite;
! append_contents = 1;
}
else if ((flags & (O_RDWR | O_APPEND)) == (O_RDWR | O_APPEND))
{
mode = BinaryReadWrite;
! append_contents = 1;
}
else if ((flags & (O_WRONLY | O_CREAT)) == (O_WRONLY | O_CREAT)
|| (flags & (O_WRONLY | O_TRUNC)) == (O_WRONLY | O_TRUNC))
*************** _open (const char *path,
*** 88,93 ****
--- 91,189 ----
return -1;
}
+ if (append_contents)
+ {
+ /* BinaryReadWrite is equal to "w+", so it truncates the file rather
+ than keeping the contents, as can be imagined if you're looking
+ for append functionality. The only way we can keep the contents
+ so we can append to it, is by first reading in and saving the
+ contents, then re-opening the file as BinaryReadWrite and write
+ the previous contents. This seems to work for the needs of
+ simple test-programs. */
+ long openexist = TRAP3f (SYS_Fopen, fileno, path, BinaryRead);
+ if (openexist == 0)
+ {
+ /* Yes, this file exists, now opened, so let's read it and keep
+ the contents. Better have the memory around for this to
+ work. */
+ long seekval = TRAP2f (SYS_Fseek, fileno, -1);
+
+ if (seekval == 0)
+ {
+ prev_contents_size = TRAP1f (SYS_Ftell, fileno);
+
+ /* If the file has non-zero size, we have something to
+ append to. */
+ if (prev_contents_size != 0)
+ {
+ /* Start reading from the beginning. Ignore the return
+ value from this call: we'll notice if we can't read
+ as much as we want. */
+ TRAP2f (SYS_Fseek, fileno, 0);
+
+ prev_contents = malloc (prev_contents_size);
+ if (prev_contents != 0)
+ {
+ /* I don't like the thought of trying to read the
+ whole file all at once, disregarding the size,
+ because the host system might not support that
+ and we'd get funky errors. Read in 32k at a
+ time. */
+ char *ptr = prev_contents;
+ unsigned long read_more = prev_contents_size;
+ unsigned long chunk_size = 1 << 15;
+
+ while (read_more >= chunk_size)
+ {
+ long readval
+ = TRAP3f (SYS_Fread, fileno, ptr, chunk_size);
+
+ if (readval != 0)
+ {
+ free (prev_contents);
+ TRAP1f (SYS_Fclose, fileno);
+ errno = EIO;
+ return -1;
+ }
+ read_more -= chunk_size;
+ ptr += chunk_size;
+ }
+
+ if (read_more != 0)
+ {
+ long readval
+ = TRAP3f (SYS_Fread, fileno, ptr, read_more);
+ if (readval != 0)
+ {
+ free (prev_contents);
+ TRAP1f (SYS_Fclose, fileno);
+ errno = EIO;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ /* Malloc of area to copy to failed. The glibc
+ manpage says its open can return ENOMEM due to
+ kernel memory failures, so let's do that too
+ here. */
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ /* Seek failed. Gotta be some I/O error. */
+ errno = EIO;
+ return -1;
+ }
+
+ TRAP1f (SYS_Fclose, fileno);
+ }
+ }
+
ret = TRAP3f (SYS_Fopen, fileno, path, mode);
if (ret < 0)
{
*************** _open (const char *path,
*** 97,108 ****
return -1;
}
! _MMIX_allocated_filehandle[fileno] = 1;
!
! if (fffile)
{
! TRAP2f (SYS_Fseek, fileno, -1);
}
return fileno;
}
--- 193,237 ----
return -1;
}
! if (prev_contents_size != 0)
{
! /* Write out the previous contents, a chunk at a time. Leave the
! file pointer at the end of the file. */
! unsigned long write_more = prev_contents_size;
! unsigned long chunk_size = 1 << 15;
! char *ptr = prev_contents;
!
! while (write_more >= chunk_size)
! {
! long writeval
! = TRAP3f (SYS_Fwrite, fileno, ptr, chunk_size);
! if (writeval != 0)
! {
! free (prev_contents);
! TRAP1f (SYS_Fclose, fileno);
! errno = EIO;
! return -1;
! }
! write_more -= chunk_size;
! ptr += chunk_size;
! }
! if (write_more != 0)
! {
! long writeval
! = TRAP3f (SYS_Fwrite, fileno, ptr, write_more);
! if (writeval != 0)
! {
! free (prev_contents);
! TRAP1f (SYS_Fclose, fileno);
! errno = EIO;
! return -1;
! }
! }
!
! free (prev_contents);
}
+
+ _MMIX_allocated_filehandle[fileno] = 1;
return fileno;
}
Index: libc/sys/mmixware/times.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/times.c,v
retrieving revision 1.3
diff -p -c -r1.3 times.c
*** libc/sys/mmixware/times.c 2001/11/18 23:47:59 1.3
--- libc/sys/mmixware/times.c 2002/02/12 01:39:58
***************
*** 1,6 ****
/* times stub for MMIXware.
! Copyright (C) 2001 Hans-Peter Nilsson
Permission to use, copy, modify, and distribute this software is
freely granted, provided that the above copyright notice, this notice
--- 1,6 ----
/* times stub for MMIXware.
! Copyright (C) 2001, 2002 Hans-Peter Nilsson
Permission to use, copy, modify, and distribute this software is
freely granted, provided that the above copyright notice, this notice
***************
*** 18,24 ****
#include "sys/times.h"
clock_t
! times (struct tms *buffer)
{
memset (buffer, 0, sizeof (*buffer));
return 0;
--- 18,24 ----
#include "sys/times.h"
clock_t
! _times (struct tms *buffer)
{
memset (buffer, 0, sizeof (*buffer));
return 0;
Index: libc/sys/mmixware/sys/syscall.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/sys/syscall.h,v
retrieving revision 1.2
diff -p -c -r1.2 syscall.h
*** libc/sys/mmixware/sys/syscall.h 2001/11/18 23:47:59 1.2
--- libc/sys/mmixware/sys/syscall.h 2002/02/12 01:39:58
***************
*** 1,6 ****
/* syscall defines for MMIXware.
! Copyright (C) 2001 Hans-Peter Nilsson
Permission to use, copy, modify, and distribute this software is
freely granted, provided that the above copyright notice, this notice
--- 1,6 ----
/* syscall defines for MMIXware.
! Copyright (C) 2001, 2002 Hans-Peter Nilsson
Permission to use, copy, modify, and distribute this software is
freely granted, provided that the above copyright notice, this notice
*************** extern unsigned char _MMIX_allocated_fil
*** 46,67 ****
#define TMPFNO 127
/* Simulator call with one argument. Also used for zero-argument calls;
! pass a zero as ARG1. */
! #define TRAP1i(FUN, ARG1) \
! ({ long ret_; \
! __asm__ ("TRAP 0,%1,%2\n\tSET %0,$255" \
! : "=r" (ret_) : "i" (FUN), "i" (ARG1) \
! : "memory"); \
! ret_; \
})
/* Helper macros to cope with the file-handle parameter to the simulator
! being *constant*. We support up to 32 simultaneously open files. */
! #define I3f(FUN, ARG1, N, ARGS) \
! if (ARG1 == N) \
! __asm__ ("SET $255,%3\n\tTRAP 0,%1,%2\n\tSET %0,$255" \
! : "=r" (ret_) : "i" (FUN), "i" (N), "r" (ARGS) \
! : "memory")
/* Using if:s rather than switches to help GCC optimize the rest away. */
#define DO32(FUN, ARG1, ARGS) \
--- 46,75 ----
#define TMPFNO 127
/* Simulator call with one argument. Also used for zero-argument calls;
! pass a zero as ARG1. Make the asm volatile so we can safely ignore the
! return-value and only get the benefit from the supposed side-effect
! without the asm being optimized away. */
! #define TRAP1i(FUN, ARG1) \
! ({ long ret_; \
! __asm__ __volatile__ \
! ("TRAP 0,%1,%2\n\tSET %0,$255" \
! : "=r" (ret_) : "i" (FUN), "i" (ARG1) \
! : "memory"); \
! ret_; \
})
/* Helper macros to cope with the file-handle parameter to the simulator
! being *constant*. We support up to 32 simultaneously open files. Make
! the asm volatile so we can safely ignore the return-value and get the
! benefit from the supposed side-effect without the asm being optimized
! away. */
!
! #define I3f(FUN, ARG1, N, ARGS) \
! if (ARG1 == N) \
! __asm__ __volatile__ \
! ("SET $255,%3\n\tTRAP 0,%1,%2\n\tSET %0,$255" \
! : "=r" (ret_) : "i" (FUN), "i" (N), "r" (ARGS) \
! : "memory")
/* Using if:s rather than switches to help GCC optimize the rest away. */
#define DO32(FUN, ARG1, ARGS) \
More information about the Newlib
mailing list