This is the mail archive of the
newlib@sources.redhat.com
mailing list for the newlib project.
Re: Compiling newlib natively [PATCH]
> Hmm, this was bound to happen with newlib using a combination of our headers and
> external headers.
>
> I get a problem because my Red Hat linux/time.h brings in linux/types.h. This
> causes the following:
[clip]
> to define a number of types. When newlib's sys/types.h gets included, there is
> a conflict among a number of the types.
It seems my linux/time.h has a Debian specific patch. If __KERNEL__ is
not defined it includes <time.h> (i.e. /usr/include/time.h) instead.
If __KERNEL__ is defined, my linux/time.h does bring in linux/types.h
as your does.
newlib's sys/types.h brings in linux/types.h explicitly. How about
including newlib's sys/types.h (which seems to work) before including
linux/time.h, so that linux/types.h is already included in a "safe"
manner.
> On all of my Red Hat Linux boxes (both old and new), the
> /usr/include/linux/stat.h does not include linux/time.h so I don't run into that
> particular problem with mktime.
My linux/stat.h defines struct kstat, which has a struct timespec
member, so it includes <linux/time.h> immediately before defining
struct timespec.
> I can only assume your linux/time.h isn't
> dragging in linux/types.h or doesn't have the clause above being invoked. Can
> you attach a copy of your linux/time.h and linux/stat.h so I can try and come up
> with some compromise (a.k.a kludge) that works for both. My first instinct is
> to try defining/undefining __KERNEL_STRICT_NAMES around the include but it would
> be good to see what your include files are.
It looks like defining/undefining __KERNEL_STRICT_NAMES would work for
me as well, though I haven't tested it. I've attached linux/time.h and
linux/stat.h, as well as linux/types.h.
I've noticed that my Linux kernel headers are provided by Debian and
are different than the kernel I'm running (2.6.8.1).
linux-kernel-headers 2.5.999-test7-bk-16
Cheers,
Shaun
#ifndef _LINUX_STAT_H
#define _LINUX_STAT_H
#ifdef __KERNEL__
#include <asm/stat.h>
#endif
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
#define S_IFMT 00170000
#define S_IFSOCK 0140000
#define S_IFLNK 0120000
#define S_IFREG 0100000
#define S_IFBLK 0060000
#define S_IFDIR 0040000
#define S_IFCHR 0020000
#define S_IFIFO 0010000
#define S_ISUID 0004000
#define S_ISGID 0002000
#define S_ISVTX 0001000
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
#endif
#ifdef __KERNEL__
#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
#include <linux/types.h>
#include <linux/time.h>
struct kstat {
unsigned long ino;
dev_t dev;
umode_t mode;
nlink_t nlink;
uid_t uid;
gid_t gid;
dev_t rdev;
loff_t size;
struct timespec atime;
struct timespec mtime;
struct timespec ctime;
unsigned long blksize;
unsigned long blocks;
};
#endif
#endif
#ifndef _LINUX_TIME_H
#define _LINUX_TIME_H
#ifndef __KERNEL__
#include <time.h>
#else
#include <asm/param.h>
#include <linux/types.h>
#ifndef _STRUCT_TIMESPEC
#define _STRUCT_TIMESPEC
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif /* _STRUCT_TIMESPEC */
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
#ifdef __KERNEL__
#include <linux/spinlock.h>
#include <linux/seqlock.h>
#include <linux/timex.h>
#include <asm/div64.h>
#ifndef div_long_long_rem
#define div_long_long_rem(dividend,divisor,remainder) ({ \
u64 result = dividend; \
*remainder = do_div(result,divisor); \
result; })
#endif
/*
* Have the 32 bit jiffies value wrap 5 minutes after boot
* so jiffies wrap bugs show up earlier.
*/
#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
/*
* Change timeval to jiffies, trying to avoid the
* most obvious overflows..
*
* And some not so obvious.
*
* Note that we don't want to return MAX_LONG, because
* for various timeout reasons we often end up having
* to wait "jiffies+1" in order to guarantee that we wait
* at _least_ "jiffies" - so "jiffies+1" had better still
* be positive.
*/
#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
/* Parameters used to convert the timespec values */
#ifndef USEC_PER_SEC
#define USEC_PER_SEC (1000000L)
#endif
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC (1000000000L)
#endif
#ifndef NSEC_PER_USEC
#define NSEC_PER_USEC (1000L)
#endif
/*
* We want to do realistic conversions of time so we need to use the same
* values the update wall clock code uses as the jiffies size. This value
* is: TICK_NSEC (which is defined in timex.h). This
* is a constant and is in nanoseconds. We will used scaled math
* with a set of scales defined here as SEC_JIFFIE_SC, USEC_JIFFIE_SC and
* NSEC_JIFFIE_SC. Note that these defines contain nothing but
* constants and so are computed at compile time. SHIFT_HZ (computed in
* timex.h) adjusts the scaling for different HZ values.
* Scaled math??? What is that?
*
* Scaled math is a way to do integer math on values that would,
* otherwise, either overflow, underflow, or cause undesired div
* instructions to appear in the execution path. In short, we "scale"
* up the operands so they take more bits (more precision, less
* underflow), do the desired operation and then "scale" the result back
* by the same amount. If we do the scaling by shifting we avoid the
* costly mpy and the dastardly div instructions.
* Suppose, for example, we want to convert from seconds to jiffies
* where jiffies is defined in nanoseconds as NSEC_PER_JIFFIE. The
* simple math is: jiff = (sec * NSEC_PER_SEC) / NSEC_PER_JIFFIE; We
* observe that (NSEC_PER_SEC / NSEC_PER_JIFFIE) is a constant which we
* might calculate at compile time, however, the result will only have
* about 3-4 bits of precision (less for smaller values of HZ).
*
* So, we scale as follows:
* jiff = (sec) * (NSEC_PER_SEC / NSEC_PER_JIFFIE);
* jiff = ((sec) * ((NSEC_PER_SEC * SCALE)/ NSEC_PER_JIFFIE)) / SCALE;
* Then we make SCALE a power of two so:
* jiff = ((sec) * ((NSEC_PER_SEC << SCALE)/ NSEC_PER_JIFFIE)) >> SCALE;
* Now we define:
* #define SEC_CONV = ((NSEC_PER_SEC << SCALE)/ NSEC_PER_JIFFIE))
* jiff = (sec * SEC_CONV) >> SCALE;
*
* Often the math we use will expand beyond 32-bits so we tell C how to
* do this and pass the 64-bit result of the mpy through the ">> SCALE"
* which should take the result back to 32-bits. We want this expansion
* to capture as much precision as possible. At the same time we don't
* want to overflow so we pick the SCALE to avoid this. In this file,
* that means using a different scale for each range of HZ values (as
* defined in timex.h).
*
* For those who want to know, gcc will give a 64-bit result from a "*"
* operator if the result is a long long AND at least one of the
* operands is cast to long long (usually just prior to the "*" so as
* not to confuse it into thinking it really has a 64-bit operand,
* which, buy the way, it can do, but it take more code and at least 2
* mpys).
* We also need to be aware that one second in nanoseconds is only a
* couple of bits away from overflowing a 32-bit word, so we MUST use
* 64-bits to get the full range time in nanoseconds.
*/
/*
* Here are the scales we will use. One for seconds, nanoseconds and
* microseconds.
*
* Within the limits of cpp we do a rough cut at the SEC_JIFFIE_SC and
* check if the sign bit is set. If not, we bump the shift count by 1.
* (Gets an extra bit of precision where we can use it.)
* We know it is set for HZ = 1024 and HZ = 100 not for 1000.
* Haven't tested others.
* Limits of cpp (for #if expressions) only long (no long long), but
* then we only need the most signicant bit.
*/
#define SEC_JIFFIE_SC (31 - SHIFT_HZ)
#if !((((NSEC_PER_SEC << 2) / TICK_NSEC) << (SEC_JIFFIE_SC - 2)) & 0x80000000)
#undef SEC_JIFFIE_SC
#define SEC_JIFFIE_SC (32 - SHIFT_HZ)
#endif
#define NSEC_JIFFIE_SC (SEC_JIFFIE_SC + 29)
#define USEC_JIFFIE_SC (SEC_JIFFIE_SC + 19)
#define SEC_CONVERSION ((unsigned long)((((u64)NSEC_PER_SEC << SEC_JIFFIE_SC))\
/ (u64)TICK_NSEC))
#define NSEC_CONVERSION ((unsigned long)((((u64)1 << NSEC_JIFFIE_SC))\
/ (u64)TICK_NSEC))
#define USEC_CONVERSION \
((unsigned long)((((u64)NSEC_PER_USEC << USEC_JIFFIE_SC)) \
/ (u64)TICK_NSEC))
/*
* USEC_ROUND is used in the timeval to jiffie conversion. See there
* for more details. It is the scaled resolution rounding value. Note
* that it is a 64-bit value. Since, when it is applied, we are already
* in jiffies (albit scaled), it is nothing but the bits we will shift
* off.
*/
#define USEC_ROUND (u64)(((u64)1 << USEC_JIFFIE_SC) - 1)
/*
* The maximum jiffie value is (MAX_INT >> 1). Here we translate that
* into seconds. The 64-bit case will overflow if we are not careful,
* so use the messy SH_DIV macro to do it. Still all constants.
*/
#if BITS_PER_LONG < 64
# define MAX_SEC_IN_JIFFIES \
(long)((u64)((u64)MAX_JIFFY_OFFSET * TICK_NSEC) / NSEC_PER_SEC)
#else /* take care of overflow on 64 bits machines */
# define MAX_SEC_IN_JIFFIES \
(SH_DIV((MAX_JIFFY_OFFSET >> SEC_JIFFIE_SC) * TICK_NSEC, NSEC_PER_SEC, 1) - 1)
#endif
/*
* The TICK_NSEC - 1 rounds up the value to the next resolution. Note
* that a remainder subtract here would not do the right thing as the
* resolution values don't fall on second boundries. I.e. the line:
* nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding.
*
* Rather, we just shift the bits off the right.
*
* The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
* value to a scaled second value.
*/
static __inline__ unsigned long
timespec_to_jiffies(struct timespec *value)
{
unsigned long sec = value->tv_sec;
long nsec = value->tv_nsec + TICK_NSEC - 1;
if (sec >= MAX_SEC_IN_JIFFIES){
sec = MAX_SEC_IN_JIFFIES;
nsec = 0;
}
return (((u64)sec * SEC_CONVERSION) +
(((u64)nsec * NSEC_CONVERSION) >>
(NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
}
static __inline__ void
jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
{
/*
* Convert jiffies to nanoseconds and separate with
* one divide.
*/
u64 nsec = (u64)jiffies * TICK_NSEC;
value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec);
}
/* Same for "timeval"
*
* Well, almost. The problem here is that the real system resolution is
* in nanoseconds and the value being converted is in micro seconds.
* Also for some machines (those that use HZ = 1024, in-particular),
* there is a LARGE error in the tick size in microseconds.
* The solution we use is to do the rounding AFTER we convert the
* microsecond part. Thus the USEC_ROUND, the bits to be shifted off.
* Instruction wise, this should cost only an additional add with carry
* instruction above the way it was done above.
*/
static __inline__ unsigned long
timeval_to_jiffies(struct timeval *value)
{
unsigned long sec = value->tv_sec;
long usec = value->tv_usec;
if (sec >= MAX_SEC_IN_JIFFIES){
sec = MAX_SEC_IN_JIFFIES;
usec = 0;
}
return (((u64)sec * SEC_CONVERSION) +
(((u64)usec * USEC_CONVERSION + USEC_ROUND) >>
(USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
}
static __inline__ void
jiffies_to_timeval(unsigned long jiffies, struct timeval *value)
{
/*
* Convert jiffies to nanoseconds and separate with
* one divide.
*/
u64 nsec = (u64)jiffies * TICK_NSEC;
value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec);
value->tv_usec /= NSEC_PER_USEC;
}
static __inline__ int timespec_equal(struct timespec *a, struct timespec *b)
{
return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
}
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
*
* [For the Julian calendar (which was used in Russia before 1917,
* Britain & colonies before 1752, anywhere else before 1582,
* and is still in use by some communities) leave out the
* -year/100+year/400 terms, and add 10.]
*
* This algorithm was first published by Gauss (I think).
*
* WARNING: this function will overflow on 2106-02-07 06:28:16 on
* machines were long is 32-bit! (However, as time_t is signed, we
* will already get problems at other places on 2038-01-19 03:14:08)
*/
static inline unsigned long
mktime (unsigned int year, unsigned int mon,
unsigned int day, unsigned int hour,
unsigned int min, unsigned int sec)
{
if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
mon += 12; /* Puts Feb last since it has leap day */
year -= 1;
}
return (((
(unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
year*365 - 719499
)*24 + hour /* now have hours */
)*60 + min /* now have minutes */
)*60 + sec; /* finally seconds */
}
extern struct timespec xtime;
extern struct timespec wall_to_monotonic;
extern seqlock_t xtime_lock;
static inline unsigned long get_seconds(void)
{
return xtime.tv_sec;
}
struct timespec current_kernel_time(void);
#define CURRENT_TIME (current_kernel_time())
#endif /* __KERNEL__ */
#define NFDBITS __NFDBITS
#ifdef __KERNEL__
extern void do_gettimeofday(struct timeval *tv);
extern int do_settimeofday(struct timespec *tv);
extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
extern void clock_was_set(void); // call when ever the clock is set
extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
extern long do_nanosleep(struct timespec *t);
extern long do_utimes(char __user * filename, struct timeval * times);
struct itimerval;
extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
extern int do_getitimer(int which, struct itimerval *value);
static inline void
set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
{
while (nsec > NSEC_PER_SEC) {
nsec -= NSEC_PER_SEC;
++sec;
}
while (nsec < 0) {
nsec += NSEC_PER_SEC;
--sec;
}
ts->tv_sec = sec;
ts->tv_nsec = nsec;
}
#endif
#define FD_SETSIZE __FD_SETSIZE
#define FD_SET(fd,fdsetp) __FD_SET(fd,fdsetp)
#define FD_CLR(fd,fdsetp) __FD_CLR(fd,fdsetp)
#define FD_ISSET(fd,fdsetp) __FD_ISSET(fd,fdsetp)
#define FD_ZERO(fdsetp) __FD_ZERO(fdsetp)
/*
* Names of the interval timers, and structure
* defining a timer setting.
*/
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
struct itimerspec {
struct timespec it_interval; /* timer period */
struct timespec it_value; /* timer expiration */
};
struct itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
/*
* The IDs of the various system clocks (for POSIX.1b interval timers).
*/
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
#define CLOCK_REALTIME_HR 4
#define CLOCK_MONOTONIC_HR 5
#define MAX_CLOCKS 6
#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC | \
CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR)
#define CLOCKS_MONO (CLOCK_MONOTONIC & CLOCK_MONOTONIC_HR)
/*
* The various flags for setting POSIX.1b interval timers.
*/
#define TIMER_ABSTIME 0x01
#endif /* __KERNEL__ DEBIAN */
#endif
#ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H
/* Debian: Use userland types instead. */
#ifndef __KERNEL__
# include <sys/types.h>
/* For other kernel headers. */
# include <linux/posix_types.h>
# include <asm/types.h>
/* For util-linux / cryptoloop. How lame. */
typedef __u32 __kernel_dev_t;
#else
#ifdef __KERNEL__
#include <linux/config.h>
#define BITS_TO_LONGS(bits) \
(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
#define CLEAR_BITMAP(name,bits) \
memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long))
#endif
#include <linux/posix_types.h>
#include <asm/types.h>
#ifndef __KERNEL_STRICT_NAMES
typedef __u32 __kernel_dev_t;
typedef __kernel_fd_set fd_set;
typedef __kernel_dev_t dev_t;
typedef __kernel_ino_t ino_t;
typedef __kernel_mode_t mode_t;
typedef __kernel_nlink_t nlink_t;
typedef __kernel_off_t off_t;
typedef __kernel_pid_t pid_t;
typedef __kernel_daddr_t daddr_t;
typedef __kernel_key_t key_t;
typedef __kernel_suseconds_t suseconds_t;
typedef __kernel_timer_t timer_t;
typedef __kernel_clockid_t clockid_t;
#ifdef __KERNEL__
typedef __kernel_uid32_t uid_t;
typedef __kernel_gid32_t gid_t;
typedef __kernel_uid16_t uid16_t;
typedef __kernel_gid16_t gid16_t;
#ifdef CONFIG_UID16
/* This is defined by include/asm-{arch}/posix_types.h */
typedef __kernel_old_uid_t old_uid_t;
typedef __kernel_old_gid_t old_gid_t;
#endif /* CONFIG_UID16 */
/* libc5 includes this file to define uid_t, thus uid_t can never change
* when it is included by non-kernel code
*/
#else
typedef __kernel_uid_t uid_t;
typedef __kernel_gid_t gid_t;
#endif /* __KERNEL__ */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
typedef __kernel_loff_t loff_t;
#endif
/*
* The following typedefs are also protected by individual ifdefs for
* historical reasons:
*/
#ifndef _SIZE_T
#define _SIZE_T
typedef __kernel_size_t size_t;
#endif
#ifndef _SSIZE_T
#define _SSIZE_T
typedef __kernel_ssize_t ssize_t;
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef __kernel_ptrdiff_t ptrdiff_t;
#endif
#ifndef _TIME_T
#define _TIME_T
typedef __kernel_time_t time_t;
#endif
#ifndef _CLOCK_T
#define _CLOCK_T
typedef __kernel_clock_t clock_t;
#endif
#ifndef _CADDR_T
#define _CADDR_T
typedef __kernel_caddr_t caddr_t;
#endif
/* bsd */
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
/* sysv */
typedef unsigned char unchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
#ifndef __BIT_TYPES_DEFINED__
#define __BIT_TYPES_DEFINED__
typedef __u8 u_int8_t;
typedef __s8 int8_t;
typedef __u16 u_int16_t;
typedef __s16 int16_t;
typedef __u32 u_int32_t;
typedef __s32 int32_t;
#endif /* !(__BIT_TYPES_DEFINED__) */
typedef __u8 uint8_t;
typedef __u16 uint16_t;
typedef __u32 uint32_t;
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
typedef __u64 uint64_t;
typedef __u64 u_int64_t;
typedef __s64 int64_t;
#endif
/*
* The type used for indexing onto a disc or disc partition.
* If required, asm/types.h can override it and define
* HAVE_SECTOR_T
*/
#ifndef HAVE_SECTOR_T
typedef unsigned long sector_t;
#endif
/*
* The type of an index into the pagecache. Use a #define so asm/types.h
* can override it.
*/
#ifndef pgoff_t
#define pgoff_t unsigned long
#endif
#endif /* __KERNEL_STRICT_NAMES */
/*
* Below are truly Linux-specific types that should never collide with
* any application/library that wants linux/types.h.
*/
#if 0
/* Debian: This is available from <sys/ustat.h>. */
struct ustat {
__kernel_daddr_t f_tfree;
__kernel_ino_t f_tinode;
char f_fname[6];
char f_fpack[6];
};
#endif
#endif /* __KERNEL__ DEBIAN */
#endif /* _LINUX_TYPES_H */