Committed, CRIS port: fix fallout from time_t defaulting to 64 bits

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Committed, CRIS port: fix fallout from time_t defaulting to 64 bits

Hans-Peter Nilsson
It's been a while...  I see the CRIS port broke with the
not-that-recent time_t-default-to-64-bit change, observable by a
few test-cases in the gcc fortran(!) tests failing, regressing
when trying a recent newlib.

This is a two-part belt-and-suspenders change: first, adjust the CRIS port
gettimeofday syscall (the only one in newlib/CRIS passing a time_t or
struct timeval) to handle a userspace 64-bit time_t and secondly default
time_t to 32-bit long anyway.  I considered making the local
kernel_timeval copy in _gettimeofday conditional on (userspace) time_t
being 64 bits, but thought it not worth bothering with the few move insns.

The effect of a 64-bit time_t is however observable as longer simulation
time when running the gcc testsuite and as bigger binaries without any
actual upside from the larger time_t size, so I thought better make the
default for this port go back to being a "long" again, meeting
expectations from earlier newlib versions.

Tested by running the gcc testsuite over the three combinations of two
parts of the patch and observing the expected changes.  Committed.
(No, the ChangeLog entry is not committed as such.)

libgloss:
        Adjust for syscall and userspace having different time_t or timeval.
        * cris/linunistd.h (kernel_time_t, kernel_suseconds_t, kernel_timeval):
        New types.
        (gettimeofday): Change the type of the first argument to be a
        pointer to a struct kernel_timeval.
        * cris/gensyscalls (_gettimeofday): Use an intermediate struct
        kernel_timeval for the syscall and initialize the result from
        that.

newlib:
        * configure.host (cris, crisv32): Default to "long" time_t.

Signed-off-by: Hans-Peter Nilsson <[hidden email]>

diff --git a/newlib/configure.host b/newlib/configure.host
index 7e9336a..c5b7734 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -135,6 +135,12 @@ case "${host_cpu}" in
  machine_dir=cr16
        ;;
   cris | crisv32)
+ # The size of the (kernel_)time_t passed from or to a
+ # simulator or a Linux kernel is mandated by the
+ # gettimeofday and time system calls and fixed to 32 bits, the
+ # size of a long.  Instead of churning as 64 bits what is anyway
+ # 32 bits, it makes more sense to default to long.
+ test -z "${enable_newlib_long_time_t}" && newlib_long_time_t=yes
  machine_dir=cris
  ;;
   crx*)
diff --git a/libgloss/cris/gensyscalls b/libgloss/cris/gensyscalls
index b885a20..3e2f9af 100644
--- a/libgloss/cris/gensyscalls
+++ b/libgloss/cris/gensyscalls
@@ -1,5 +1,5 @@
 #! /bin/sh
-#  Copyright (C) 2005 Axis Communications.
+#  Copyright (C) 2005, 2018 Axis Communications.
 #  All rights reserved.
 #
 #  Redistribution and use in source and binary forms, with or without
@@ -93,8 +93,16 @@ cat > gettod.c <<EOF
 $lu#include <sys/time.h>
 #include <sys/times.h>
 int
-_gettimeofday (struct timeval *tp, void *tzp
-${r}gettimeofday (tp, tzp))
+_gettimeofday (struct timeval *tp, void *tzp)
+{
+  struct kernel_timeval kt;
+  int retval = _Sys_gettimeofday(&kt, tzp);
+  if (retval == 0)
+  {
+    tp->tv_sec = kt.tv_sec;
+    tp->tv_usec = kt.tv_usec;
+  }
+  R (retval)
 EOF
 cat > isatty.c <<EOF
 $lu
diff --git a/libgloss/cris/linunistd.h b/libgloss/cris/linunistd.h
index 4d664a2..310e470 100644
--- a/libgloss/cris/linunistd.h
+++ b/libgloss/cris/linunistd.h
@@ -1,5 +1,5 @@
 /* Support for syscalls for cris*-axis-linux-gnu and simulators
-   Copyright (C) 1998-2005 Axis Communications.
+   Copyright (C) 1998-2005, 2018 Axis Communications.
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -402,6 +402,14 @@ struct new_stat {
  unsigned long  __unused5;
 };
 
+typedef long int kernel_time_t;
+typedef long int kernel_suseconds_t;
+
+struct kernel_timeval {
+  kernel_time_t      tv_sec;
+  kernel_suseconds_t tv_usec;
+};
+
 static inline _syscall2(int,stat,const char *,path,struct new_stat *,statbuf)
 static inline _syscall2(int,fstat,int,fd,struct new_stat *,statbuf)
 static inline _syscall0(int,getpid)
@@ -412,7 +420,7 @@ static inline _syscall1(long,times,struct tms *,tbuf)
 static inline _syscall1(long,mmap,long *, buf)
 struct timeval;
 struct timezone;
-static inline _syscall2(int,gettimeofday,struct timeval *,tp,
+static inline _syscall2(int,gettimeofday,struct kernel_timeval *,tp,
                         void *, tzp)
 static inline _syscall2(int,link,const char *,old,const char *,new)
 static inline _syscall1(int,unlink,const char *, f)

brgds, H-P