From 8c29d069db1898b519c6c610a91a25b5ffb8c9d0 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 1 Jan 2001 22:16:11 +0000 Subject: A bunch of updates, part from Manuel Novoa III (such as more long long support), and other updates by me (better cross platform, cross-compiler, etc, support. Now compiles with 2.0.x kernels for armnommu. --- Makefile | 10 +- Rules.mak | 10 +- include/stdlib.h | 3 + include/sys/mount.h | 107 +++++++++++++++++-- libc/stdlib/Makefile | 9 +- libc/stdlib/abort.c | 2 - libc/stdlib/malloc/alloc.c | 4 +- libc/stdlib/malloc/malloc.c | 4 +- libc/stdlib/strto_l.c | 4 +- libc/stdlib/strto_ll.c | 192 +++++++++++++++++++++++++++++++++++ libc/sysdeps/linux/Makefile | 2 +- libc/sysdeps/linux/common/statfix.h | 4 +- libc/sysdeps/linux/common/syscalls.c | 14 +++ 13 files changed, 337 insertions(+), 28 deletions(-) create mode 100644 libc/stdlib/strto_ll.c diff --git a/Makefile b/Makefile index 2fe3168e6..f2a7a44d8 100644 --- a/Makefile +++ b/Makefile @@ -42,16 +42,18 @@ halfclean: @rm -f libc.a headers: dummy - @if [ ! -L "include/asm" ]; then ln -s /usr/include/asm include/asm ; fi - @if [ ! -L "include/net" ]; then ln -s /usr/include/net include/net ; fi - @if [ ! -L "include/linux" ]; then ln -s /usr/include/linux include/linux ; fi - @if [ ! -L "include/bits" ]; then ln -s ../sysdeps/linux/$(ARCH)/bits include/bits ; fi + @rm -f include/asm include/net include/linux include/bits + @ln -s $(KERNEL_SOURCE)/include/asm-$(ARCH_DIR) include/asm + @ln -s $(KERNEL_SOURCE)/include/net include/net + @ln -s $(KERNEL_SOURCE)/include/linux include/linux + @ln -s ../sysdeps/linux/$(TARGET_ARCH)/bits include/bits tags: ctags -R clean: subdirs_clean rm -f libc.a + rm -f include/asm include/net include/linux include/bits subdirs: $(patsubst %, _dir_%, $(DIRS)) subdirs_clean: $(patsubst %, _dirclean_%, $(DIRS)) diff --git a/Rules.mak b/Rules.mak index 600ce5ea8..f081affe4 100644 --- a/Rules.mak +++ b/Rules.mak @@ -39,11 +39,11 @@ endif CFLAGS=$(ARCH_CFLAGS) $(CCFLAGS) $(DEFS) ifeq ($(DODEBUG),true) - CFLAGS += -Wall -g + CFLAGS += $(WARNINGS) -g LDFLAGS = -nostdlib -Wl,-warn-common STRIPTOOL = /bin/true -Since_we_are_debugging else - CFLAGS += -Wall #-fomit-frame-pointer + CFLAGS += $(WARNINGS) #-fomit-frame-pointer LDFLAGS = -s -nostdlib -Wl,-warn-common endif @@ -53,15 +53,15 @@ endif ifneq ($(HAS_MMU),true) CFLAGS += -D__HAS_NO_MMU__ + ARCH_DIR = $(shell echo $(TARGET_ARCH)nommu) +else + ARCH_DIR = $(TARGET_ARCH) endif ifneq ($(HAS_FLOATS),true) CFLAGS += -D__HAS_NO_FLOATS__ endif -ifneq ($(DO_FIXME_STUFF),true) - CFLAGS += -DFIXME -endif # Use '-ffunction-sections -fdata-sections' and '--gc-sections' if they work diff --git a/include/stdlib.h b/include/stdlib.h index 6ad53fc9a..18a32e62f 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -43,8 +43,11 @@ typedef __compar_fn_t comparison_fn_t; #define atof(x) strtod((x),(char**)0) #define atoi(x) (int)strtol((x),(char**)0,10) #define atol(x) strtol((x),(char**)0,10) +#define atoll(x) strtoll((x),(char**)0,10) extern long strtol __P ((const char * nptr, char ** endptr, int base)); extern unsigned long strtoul __P ((const char * nptr, char ** endptr, int base)); +extern long long strtoll __P ((const char * nptr, char ** endptr, int base)); +extern unsigned long long strtoull __P ((const char * nptr, char ** endptr, int base)); #ifndef __HAS_NO_FLOATS__ /*TODO: extern char * gcvt __P ((double number, size_t ndigit, char * buf)); */ extern double strtod __P ((const char * nptr, char ** endptr)); diff --git a/include/sys/mount.h b/include/sys/mount.h index a0765e2ee..862c1f040 100644 --- a/include/sys/mount.h +++ b/include/sys/mount.h @@ -1,17 +1,108 @@ +/* Header file for mounting/unmount Linux filesystems. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This is taken from /usr/include/linux/fs.h. */ + #ifndef _SYS_MOUNT_H -#define _SYS_MOUNT_H +#define _SYS_MOUNT_H 1 #include +#include + +#define BLOCK_SIZE 1024 +#define BLOCK_SIZE_BITS 10 + + +/* These are the fs-independent mount-flags: up to 16 flags are + supported */ +enum +{ + MS_RDONLY = 1, /* Mount read-only. */ +#define MS_RDONLY MS_RDONLY + MS_NOSUID = 2, /* Ignore suid and sgid bits. */ +#define MS_NOSUID MS_NOSUID + MS_NODEV = 4, /* Disallow access to device special files. */ +#define MS_NODEV MS_NODEV + MS_NOEXEC = 8, /* Disallow program execution. */ +#define MS_NOEXEC MS_NOEXEC + MS_SYNCHRONOUS = 16, /* Writes are synced at once. */ +#define MS_SYNCHRONOUS MS_SYNCHRONOUS + MS_REMOUNT = 32, /* Alter flags of a mounted FS. */ +#define MS_REMOUNT MS_REMOUNT + MS_MANDLOCK = 64, /* Allow mandatory locks on an FS. */ +#define MS_MANDLOCK MS_MANDLOCK + S_WRITE = 128, /* Write on file/directory/symlink. */ +#define S_WRITE S_WRITE + S_APPEND = 256, /* Append-only file. */ +#define S_APPEND S_APPEND + S_IMMUTABLE = 512, /* Immutable file. */ +#define S_IMMUTABLE S_IMMUTABLE + MS_NOATIME = 1024, /* Do not update access times. */ +#define MS_NOATIME MS_NOATIME + MS_NODIRATIME = 2048 /* Do not update directory access times. */ +#define MS_NODIRATIME MS_NODIRATIME +}; + +/* Flags that can be altered by MS_REMOUNT */ +#define MS_RMT_MASK (MS_RDONLY | MS_MANDLOCK) + + +/* Magic mount flag number. Has to be or-ed to the flag values. */ + +#define MS_MGC_VAL 0xc0ed0000 /* Magic flag number to indicate "new" flags */ +#define MS_MGC_MSK 0xffff0000 /* Magic flag number mask */ + + +/* The read-only stuff doesn't really belong here, but any other place + is probably as bad and I don't want to create yet another include + file. */ + +#define BLKROSET _IO(0x12, 93) /* Set device read-only (0 = read-write). */ +#define BLKROGET _IO(0x12, 94) /* Get read-only status (0 = read_write). */ +#define BLKRRPART _IO(0x12, 95) /* Re-read partition table. */ +#define BLKGETSIZE _IO(0x12, 96) /* Return device size. */ +#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */ +#define BLKRASET _IO(0x12, 98) /* Set read ahead for block device. */ +#define BLKRAGET _IO(0x12, 99) /* Get current read ahead setting. */ + + +/* Possible value for FLAGS parameter of `umount2'. */ +enum +{ + MNT_FORCE = 1 /* Force unmounting. */ +#define MNT_FORCE MNT_FORCE +}; + __BEGIN_DECLS -extern int mount __P ((__const char* __specialfile, - __const char* __dir,__const char* __filesystemype, - unsigned long __rwflag,__const void *__data)); +/* Mount a filesystem. */ +extern int mount __P ((__const char *__special_file, __const char *__dir, + __const char *__fstype, unsigned long int __rwflag, + __const void *__data)); + +/* Unmount a filesystem. */ +extern int umount __P ((__const char *__special_file)); + +/* Unmount a filesystem. Force unmounting if FLAGS is set to MNT_FORCE. */ +extern int umount2 __P ((__const char *__special_file, int __flags)); -extern int umount __P ((__const char* __specialfile)); - - __END_DECLS -#endif +#endif /* _SYS_MOUNT_H */ diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile index 4d16a8585..e4b28979c 100644 --- a/libc/stdlib/Makefile +++ b/libc/stdlib/Makefile @@ -29,6 +29,9 @@ DIRS = $(MALLOC) MSRC=strto_l.c MOBJ=strtol.o strtoul.o strto_l.o +MSRC1=strto_ll.c +MOBJ1=strtoll.o strtoull.o strto_ll.o + MSRC2=atexit.c MOBJ2=on_exit.o atexit.o __do_exit.o exit.o @@ -38,7 +41,7 @@ CSRC = abort.c getenv.c mktemp.c qsort.c realpath.c strtod.c \ COBJS=$(patsubst %.c,%.o, $(CSRC)) -OBJS=$(MOBJ) $(MOBJ2) $(COBJS) +OBJS=$(MOBJ) $(MOBJ1) $(MOBJ2) $(COBJS) all: $(OBJS) $(LIBC) @@ -51,6 +54,10 @@ $(MOBJ): $(MSRC) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o +$(MOBJ1): $(MSRC1) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(STRIPTOOL) -x -R .note -R .comment $*.o + $(MOBJ2): $(MSRC2) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c index 6806a8b55..23510e913 100644 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -32,13 +32,11 @@ extern void _exit __P((int __status)) __attribute__ ((__noreturn__)); /* Cause an abnormal program termination with core-dump. */ void abort(void) { -#if FIXME sigset_t sigset; if (sigemptyset(&sigset) == 0 && sigaddset(&sigset, SIGABRT) == 0) { sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL); } -#endif if (__cleanup) __cleanup(); diff --git a/libc/stdlib/malloc/alloc.c b/libc/stdlib/malloc/alloc.c index b782f6dcf..22d508ca1 100644 --- a/libc/stdlib/malloc/alloc.c +++ b/libc/stdlib/malloc/alloc.c @@ -12,7 +12,7 @@ void * calloc_dbg(size_t num, size_t size, char * function, char * file, int line) { void * ptr; - fprintf(stderr, "calloc of %d bytes at %s @%s:%d = ", num*size, function, file, line); + fprintf(stderr, "calloc of %ld bytes at %s @%s:%d = ", (long)(num*size), function, file, line); ptr = calloc(num,size); fprintf(stderr, "%p\n", ptr); return ptr; @@ -26,7 +26,7 @@ void * malloc_dbg(size_t len, char * function, char * file, int line) { void * result; - fprintf(stderr, "malloc of %d bytes at %s @%s:%d = ", len, function, file, line); + fprintf(stderr, "malloc of %ld bytes at %s @%s:%d = ", (long)len, function, file, line); result = malloc(len); fprintf(stderr, "%p\n", result); return result; diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c index d7df5d243..a3f50fb3b 100644 --- a/libc/stdlib/malloc/malloc.c +++ b/libc/stdlib/malloc/malloc.c @@ -296,8 +296,8 @@ struct Block_s /* 32-bytes long control structure (if 4-byte aligned) */ /* packed 4-byte attributes */ /* { */ - char bal_free_mem : 8; /* balance of subtree */ - char bal_ptrs : 8; /* balance of subtree */ + signed char bal_free_mem : 8; /* balance of subtree */ + signed char bal_ptrs : 8; /* balance of subtree */ unsigned int used : 1; /* used/free state of the block */ unsigned int broken : 1; /* 1 if previous block can't be merged with it */ /* } */ diff --git a/libc/stdlib/strto_l.c b/libc/stdlib/strto_l.c index a83cf4095..16b29f5d6 100644 --- a/libc/stdlib/strto_l.c +++ b/libc/stdlib/strto_l.c @@ -15,7 +15,7 @@ /* OPTIONS */ /*****************************************************************************/ -/* Set if we want strtod to set errno appropriately. */ +/* Set if we want errno set appropriately. */ /* NOTE: Implies _STRTO_ENDPTR below */ #define _STRTO_ERRNO 0 @@ -107,8 +107,8 @@ unsigned long _strto_l(const char *str, char **endptr, int base, int uflag) goto DONE; } + cutoff_digit = ULONG_MAX % base; cutoff = ULONG_MAX / base; - cutoff_digit = ULONG_MAX - cutoff * base; while (1) { digit = 40; diff --git a/libc/stdlib/strto_ll.c b/libc/stdlib/strto_ll.c new file mode 100644 index 000000000..4b2854b8e --- /dev/null +++ b/libc/stdlib/strto_ll.c @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2000 Manuel Novoa III + * + * Notes: + * + * The primary objective of this implementation was minimal size. + * + * Note: Assumes char layout 0-9.*A-Z.*a-z for ordinals values. + * + * There are a couple of compile-time options below. + * + */ + +/*****************************************************************************/ +/* OPTIONS */ +/*****************************************************************************/ + +/* Set if we want errno set appropriately. */ +/* NOTE: Implies _STRTO_ENDPTR below */ +#define _STRTO_ERRNO 0 + +/* Set if we want support for the endptr arg. */ +/* Implied by _STRTO_ERRNO. */ +#define _STRTO_ENDPTR 1 + +/*****************************************************************************/ +/* Don't change anything that follows. */ +/*****************************************************************************/ + +#if _STRTO_ERRNO +#undef _STRTO_ENDPTR +#define _STRTO_ENDPTR 1 +#endif + +/*****************************************************************************/ + +/* Are there actually any machines where this might fail? */ +#if 'A' > 'a' +#error ordering assumption violated : 'A' > 'a' +#endif + +#include +#include +#include + +#if _STRTO_ERRNO +#include +#endif + +unsigned long long _strto_ll(const char *str, char **endptr, int base, int uflag); + +#if L_strto_ll + +/* + * This is the main work fuction which handles both strtol (uflag = 0) and + * strtoul (uflag = 1). + */ + +unsigned long long _strto_ll(const char *str, char **endptr, int base, int uflag) +{ + unsigned long long number = 0; + unsigned long long cutoff; + char *pos = (char *) str; +#if _STRTO_ENDPTR + char *fail_char = (char *) str; +#endif + int digit, cutoff_digit; + int negative; + + while (isspace(*pos)) { /* skip leading whitespace */ + ++pos; + } + + /* handle optional sign */ + negative = 0; + switch(*pos) { + case '-': negative = 1; /* fall through to increment pos */ + case '+': ++pos; + } + + if ((base == 16) && (*pos == '0')) { /* handle option prefix */ + ++pos; +#if _STRTO_ENDPTR + fail_char = pos; +#endif + if ((*pos == 'x') || (*pos == 'X')) { + ++pos; + } + } + + if (base == 0) { /* dynamic base */ + base = 10; /* default is 10 */ + if (*pos == '0') { + ++pos; + base -= 2; /* now base is 8 (or 16) */ +#if _STRTO_ENDPTR + fail_char = pos; +#endif + if ((*pos == 'x') || (*pos == 'X')) { + base += 8; /* base is 16 */ + ++pos; + } + } + } + + if ((base < 2) || (base > 36)) { /* illegal base */ + goto DONE; + } + + cutoff_digit = ULONG_LONG_MAX % base; + cutoff = ULONG_LONG_MAX / base; + + while (1) { + digit = 40; + if ((*pos >= '0') && (*pos <= '9')) { + digit = (*pos - '0'); + } else if (*pos >= 'a') { + digit = (*pos - 'a' + 10); + } else if (*pos >= 'A') { + digit = (*pos - 'A' + 10); + } else break; + + if (digit >= base) { + break; + } + + ++pos; +#if _STRTO_ENDPTR + fail_char = pos; +#endif + + /* adjust number, with overflow check */ + if ((number > cutoff) + || ((number == cutoff) && (digit > cutoff_digit))) { + number = ULONG_LONG_MAX; + if (uflag) { + negative = 0; /* since unsigned returns ULONG_LONG_MAX */ + } +#if _STRTO_ERRNO + errno = ERANGE; +#endif + } else { + number = number * base + digit; + } + + } + + DONE: +#if _STRTO_ENDPTR + if (endptr) { + *endptr = fail_char; + } +#endif + + if (negative) { + if (!uflag && (number > ((unsigned long long)(-(1+LONG_LONG_MIN)))+1)) { +#if _STRTO_ERRNO + errno = ERANGE; +#endif + return (unsigned long long) LONG_LONG_MIN; + } + return (unsigned long long)(-((long long)number)); + } else { + if (!uflag && (number > (unsigned long long) LONG_LONG_MAX)) { +#if _STRTO_ERRNO + errno = ERANGE; +#endif + return LONG_LONG_MAX; + } + return number; + } +} + +#endif + +#if L_strtoull + +unsigned long long strtoull(const char *str, char **endptr, int base) +{ + return _strto_ll(str, endptr, base, 1); +} + +#endif + +#if L_strtoll + +long long strtoll(const char *str, char **endptr, int base) +{ + return _strto_ll(str, endptr, base, 0); +} + +#endif diff --git a/libc/sysdeps/linux/Makefile b/libc/sysdeps/linux/Makefile index 2451e6383..fb7808913 100644 --- a/libc/sysdeps/linux/Makefile +++ b/libc/sysdeps/linux/Makefile @@ -23,7 +23,7 @@ TOPDIR=../../ include $(TOPDIR)Rules.mak -DIRS = $(ARCH) common +DIRS = $(TARGET_ARCH) common all: libc.a diff --git a/libc/sysdeps/linux/common/statfix.h b/libc/sysdeps/linux/common/statfix.h index 21a776c92..df85d84d4 100644 --- a/libc/sysdeps/linux/common/statfix.h +++ b/libc/sysdeps/linux/common/statfix.h @@ -3,9 +3,11 @@ /* Pull in whatever this particular arch's kernel thinks the kernel version of * struct stat should look like. It turn out that each arch has a different - * opinion on the subject... */ + * opinion on the subject, and different kernel revs use different names... */ #define stat kernel_stat +#define new_stat kernel_stat #include +#undef new_stat #undef stat /* Now pull in libc's version of stat */ diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c index c0630e1fd..a0bad06be 100644 --- a/libc/sysdeps/linux/common/syscalls.c +++ b/libc/sysdeps/linux/common/syscalls.c @@ -135,11 +135,19 @@ _syscall3(int, mknod, const char *, pathname, mode_t, mode, dev_t, dev); _syscall2(int, chmod, const char *, path, mode_t, mode); #endif +/* Old kernels don't have lchown -- do chown instead. This + * is sick and wrong, but at least things will compile. + * They may not follow links when they should though... */ +#ifndef __NR_lchown +#define __NR_lchown __NR_chown +#endif + //#define __NR_lchown 16 #ifdef L_lchown #include _syscall3(int, lchown, const char *, path, uid_t, owner, gid_t, group); #endif +#endif //#define __NR_break 17 @@ -325,11 +333,13 @@ gid_t getegid(void) //#define __NR_acct 51 +#ifdef __NR_umount2 /* Old kernels don't have umount2 */ //#define __NR_umount2 52 #ifdef L_umount2 #include _syscall2(int, umount2, const char *, special_file, int, flags); #endif +#endif //#define __NR_lock 53 @@ -639,6 +649,7 @@ _syscall2(int, statfs, const char *, path, struct statfs *, buf); _syscall2(int, fstatfs, int, fd, struct statfs *, buf); #endif +#ifndef __HAS_NO_MMU__ //#define __NR_ioperm 101 #ifdef L_ioperm #include @@ -646,6 +657,7 @@ syscall3(int, ioperm, unsigned, long, from, unsigned long, num, int, turn_on); #endif +#endif //#define __NR_socketcall 102 #ifdef L_socketcall @@ -737,11 +749,13 @@ int fstat(int fd, struct libc_stat *cstat) //#define __NR_olduname 109 +#ifndef __HAS_NO_MMU__ //#define __NR_iopl 110 #ifdef L_iopl #include _syscall1(int, iopl, int, level); #endif +#endif //#define __NR_vhangup 111 #ifdef L_vhangup -- cgit v1.2.3