commit 5be672c3fecebef30d6f42006d321168de84054c
parent 88c6d1e058ed72d07da8e924fd5af15a2219901d
Author: Roberto Vargas <roberto.vargas@arm.com>
Date: Mon, 15 Oct 2018 14:59:58 +0100
[libc] Synchronize with scc libc
At this time, we get file related functions that are going to
be needed by libgcov.
Change-Id: Ie43777349dbe0090216d4cf6b25a51421d51619f
Diffstat:
21 files changed, 392 insertions(+), 52 deletions(-)
diff --git a/include/bits/bsd/sys.h b/include/bits/bsd/sys.h
@@ -0,0 +1,12 @@
+#define O_RDONLY 0x00000000
+#define O_WRONLY 0x00000001
+#define O_RDWR 0x00000002
+
+#define O_TRUNC 0x00000400
+#define O_APPEND 0x00000008
+#define O_CREAT 0x00000200
+
+typedef int pid_t;
+
+extern pid_t _getpid(void);
+extern int _kill(pid_t pid, int signum);
diff --git a/include/bits/linux/sys.h b/include/bits/linux/sys.h
@@ -0,0 +1,12 @@
+#define O_RDONLY 0x00000000
+#define O_WRONLY 0x00000001
+#define O_RDWR 0x00000002
+
+#define O_TRUNC 0x00000400
+#define O_APPEND 0x00000008
+#define O_CREAT 0x00000200
+
+typedef int pid_t;
+
+extern pid_t _getpid(void);
+extern int _kill(pid_t pid, int signum);
diff --git a/include/bits/none/sys.h b/include/bits/none/sys.h
@@ -0,0 +1,7 @@
+#define O_RDONLY 0x00000000
+#define O_WRONLY 0x00000001
+#define O_RDWR 0x00000002
+
+#define O_TRUNC 0x00000400
+#define O_APPEND 0x00000008
+#define O_CREAT 0x00000200
diff --git a/include/signal.h b/include/signal.h
@@ -0,0 +1,9 @@
+#ifndef _SIGNAL_H
+#define _SIGNAL_H
+
+#include <sys/signal.h>
+
+void ( *signal(int signum, void (*handler)(int)) ) (int);
+int raise(int sig);
+
+#endif
diff --git a/src/libc/Makefile b/src/libc/Makefile
@@ -1,7 +1,7 @@
PROJECTDIR =../..
-LIBCARCH = arch/$(ARCH)
include $(PROJECTDIR)/scripts/rules.mk
+LIBCARCH = arch/$(ARCH)
MORECFLAGS = -I.
OBJS = abort.o \
@@ -42,13 +42,23 @@ OBJS = abort.o \
errno.o \
atexit.o \
exit.o \
+ fopen.o \
+ _fpopen.o \
+ fclose.o \
+ feof.o \
+ setbuf.o \
+ setvbuf.o \
+ clearerr.o \
fputc.o \
fputs.o \
+ fseek.o \
+ ftell.o \
fprintf.o \
putchar.o \
puts.o \
rand.o \
raise.o \
+ malloc.o \
$(LIBCARCH)/setjmp.o \
$(LIBCARCH)/longjmp.o \
$(LIBCARCH)/_Exit-$(SYS).o \
diff --git a/src/libc/__putc.c b/src/libc/__putc.c
@@ -45,6 +45,14 @@ __putc(int ch, FILE *fp)
return EOF;
}
+ if (fp->buf == NULL) {
+ if ((fp->buf = malloc(BUFSIZ)) == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ fp->flags |= _IOALLOC;
+ }
+
if (first) {
if (atexit(cleanup)) {
fp->flags |= _IOERR;
diff --git a/src/libc/_flsbuf.c b/src/libc/_flsbuf.c
@@ -5,11 +5,10 @@
int
_flsbuf(FILE *fp)
{
- int lnbuf = fp->flags & _IOLBF;
unsigned char *p;
size_t cnt;
- p = (lnbuf) ? fp->lp : fp->wp;
+ p = (fp->flags & _IOLBF) ? fp->lp : fp->wp;
cnt = p - fp->buf;
if (_write(fp->fd, fp->buf, cnt) != cnt) {
diff --git a/src/libc/_fpopen.c b/src/libc/_fpopen.c
@@ -0,0 +1,75 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys.h>
+#include "syscall.h"
+#include "libc.h"
+#undef fopen
+
+FILE *
+_fpopen(const char * restrict fname,
+ const char * restrict mode,
+ FILE * restrict fp)
+{
+ int i, flags, fd, rw, bin;
+
+ flags = rw = bin = 0;
+
+ if (mode[0] == '\0')
+ goto einval;
+
+ for (i = 1; mode[i]; ++i) {
+ switch (mode[i]) {
+ case '+':
+ if (rw)
+ goto einval;
+ rw = 1;
+ break;
+ case 'b':
+ if (bin)
+ goto einval;
+ bin = 1;
+ break;
+ default:
+ goto einval;
+ }
+ }
+
+ switch (mode[0]) {
+ case 'a':
+ flags |= O_APPEND | O_CREAT;
+ goto wrflags;
+ case 'w':
+ flags |= O_TRUNC | O_CREAT;
+ wrflags:
+ flags |= (rw) ? O_RDWR : O_WRONLY;
+ break;
+ case 'r':
+ flags = (rw) ? O_RDWR : O_RDONLY;
+ break;
+ default:
+ einval:
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if ((fd = _open(fname, flags)) < 0)
+ return NULL;
+
+ fp->buf = NULL;
+ fp->fd = fd;
+
+ if (!bin)
+ fp->flags |= _IOTXT;
+
+ if (flags & O_RDWR)
+ fp->flags |= _IORW;
+ else if (flags & O_RDONLY)
+ fp->flags |= _IOREAD;
+ else
+ fp->flags |= _IOWRITE;
+
+ fp->lp = fp->rp = fp->wp = NULL;
+
+ return fp;
+}
diff --git a/src/libc/clearerr.c b/src/libc/clearerr.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#undef clearerr
+
+void
+clearerr(FILE *fp)
+{
+ fp->flags &= ~(_IOERR | _IOEOF);
+}
diff --git a/src/libc/fclose.c b/src/libc/fclose.c
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "syscall.h"
+#undef fclose
+
+extern int _flsbuf(FILE *fp);
+
+int
+fclose(FILE *fp)
+{
+ int r = EOF;
+
+ if ((fp->flags & _IOSTRG) == 0 &&
+ fp->flags & (_IOWRITE | _IOREAD | _IORW)) {
+ r = 0;
+ if (_flsbuf(fp) == EOF)
+ r = EOF;
+ if (_close(fp->fd) < 0)
+ r = EOF;
+ }
+
+ if (fp->flags & _IOALLOC) {
+ free(fp->buf);
+ fp->buf = NULL;
+ }
+
+ fp->flags &= ~(_IOWRITE | _IOREAD | _IORW |
+ _IOERR | _IOEOF |
+ _IOALLOC |
+ _IOTXT |
+ _IOSTRG);
+
+ return r;
+}
diff --git a/src/libc/feof.c b/src/libc/feof.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#undef feof
+
+int
+feof(FILE *fp)
+{
+ return fp->flags & _IOEOF;
+}
diff --git a/src/libc/fopen.c b/src/libc/fopen.c
@@ -0,0 +1,23 @@
+#include <errno.h>
+#include <stdio.h>
+
+#include "syscall.h"
+#include "libc.h"
+#undef fopen
+
+
+FILE *
+fopen(const char * restrict name, const char * restrict mode)
+{
+ FILE *fp;
+
+ for (fp = __iob; fp < &__iob[FOPEN_MAX]; ++fp) {
+ if ((fp->flags & (_IOREAD | _IOWRITE | _IORW)) == 0)
+ break;
+ }
+ if (fp == &__iob[FOPEN_MAX]) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return _fpopen(name, mode, fp);
+}
diff --git a/src/libc/fseek.c b/src/libc/fseek.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include "syscall.h"
+#undef fseek
+
+extern int _flsbuf(FILE *fp);
+
+int
+fseek(FILE *fp, long off, int whence)
+{
+ if (fp->flags & _IOERR)
+ return EOF;
+
+ if ((fp->flags & _IOWRITE) && _flsbuf(fp))
+ return -1;
+ else if (whence == SEEK_CUR && (fp->flags & _IOREAD))
+ off -= fp->wp - fp->rp;
+
+ if (_lseek(fp->fd, off, whence) < 0) {
+ fp->flags |= _IOERR;
+ return EOF;
+ }
+
+ if (fp->flags & _IORW)
+ fp->flags &= ~(_IOREAD | _IOWRITE);
+ fp->flags &= ~_IOEOF;
+
+ return 0;
+}
diff --git a/src/libc/ftell.c b/src/libc/ftell.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "syscall.h"
+#undef ftell
+
+long
+ftell(FILE *fp)
+{
+ long off;
+ unsigned char *p;
+
+ if (fp->flags & _IOERR)
+ return EOF;
+
+ if ((off = _lseek(fp->fd, 0, SEEK_CUR)) < 0) {
+ fp->flags |= _IOERR;
+ return EOF;
+ }
+
+ if (fp->flags & _IOREAD)
+ return off - (fp->wp - fp->rp);
+
+ if (fp->flags & _IOWRITE) {
+ p = (fp->flags & _IOLBF) ? fp->lp : fp->wp;
+ return off + (p - fp->buf);
+ }
+ return off;
+}
diff --git a/src/libc/libc.h b/src/libc/libc.h
@@ -0,0 +1,37 @@
+#define SUN 0
+#define MON 1
+#define TUE 2
+#define WED 3
+#define THU 4
+#define FRI 5
+#define SAT 6
+
+#define JAN 0
+#define FEB 1
+#define DEC 11
+
+#define EPOCH 1970
+#define FEBDAYS(y) ((_daysyear(y) == 366) ? 29 : 28)
+#define SECMIN 60
+#define SECHOUR (60 * SECMIN) /* 3600 */
+#define SECDAY (24 * SECHOUR) /* 86400 */
+
+#ifdef stdin
+extern FILE *_fpopen(const char * restrict fname,
+ const char * restrict mode,
+ FILE * restrict fp);
+#endif
+
+struct tzone {
+ char *name;
+ int gmtoff;
+ int isdst;
+};
+
+struct tm;
+
+extern struct tzone *_tzone(struct tm *tm);
+extern int _daysyear(int year);
+extern int _newyear(int year);
+
+extern int _daysmon[12];
diff --git a/src/libc/malloc.c b/src/libc/malloc.c
@@ -0,0 +1,37 @@
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+static int inuse[FOPEN_MAX];
+static char buffers[FOPEN_MAX][BUFSIZ];
+
+void *
+malloc(size_t siz)
+{
+ int i;
+
+ if (siz == BUFSIZ) {
+ for (i = 0; i < FOPEN_MAX && !inuse[i]; i++)
+ ;
+ if (i != FOPEN_MAX) {
+ inuse[i] = 1;
+ return buffers[i];
+ }
+ }
+
+ errno = ENOMEM;
+ return NULL;
+}
+
+void
+free(void *bp)
+{
+ int i;
+
+ for (i = 0; i < FOPEN_MAX && buffers[i] != bp; i++)
+ ;
+ if (i < FOPEN_MAX)
+ inuse[i] = 0;
+}
diff --git a/src/libc/memchr.c b/src/libc/memchr.c
@@ -4,7 +4,7 @@
void *
memchr(const void *s, int c, size_t n)
{
- unsigned char *bp = (unsigned char *) s;
+ const unsigned char *bp = s;
while (n > 0 && *bp++ != c)
--n;
diff --git a/src/libc/setbuf.c b/src/libc/setbuf.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#undef setbuf
+
+void
+setbuf(FILE * restrict fp, char * restrict buf)
+{
+ setvbuf(fp, buf, (buf) ? _IOFBF : _IONBF, BUFSIZ);
+}
diff --git a/src/libc/setvbuf.c b/src/libc/setvbuf.c
@@ -0,0 +1,46 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#undef setvbuf
+
+extern int _flsbuf(FILE *fp);
+
+int
+setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size)
+{
+ int flags;
+
+ if (_flsbuf(fp) == EOF)
+ return EOF;
+
+ switch (mode) {
+ case _IONBF:
+ size = sizeof(fp->unbuf);
+ buf = fp->unbuf;
+ break;
+ case _IOLBF:
+ case _IOFBF:
+ if (size == 0) {
+ if ((buf = malloc(BUFSIZ)) == NULL) {
+ errno = ENOMEM;
+ return EOF;
+ }
+ size = BUFSIZ;
+ }
+ break;
+ default:
+ errno = EINVAL;
+ return EOF;
+ }
+
+ flags = fp->flags;
+ if (flags & _IOALLOC)
+ free(fp->buf);
+ flags &= ~(_IONBF | _IOLBF | _IOFBF | _IOALLOC | _IOALLOC);
+ flags |= mode;
+ fp->flags = flags;
+ fp->buf = buf;
+ fp->len = size;
+
+ return 0;
+}
diff --git a/src/libc/signal.h b/src/libc/signal.h
@@ -1,35 +0,0 @@
-#ifndef _SIGNAL_H
-#define _SIGNAL_H
-
-typedef int sig_atomic_t;
-
-#define SIG_ERR ((void (*)(int))-1)
-#define SIG_DFL ((void (*)(int)) 0)
-#define SIG_IGN ((void (*)(int)) 1)
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGABRT 6
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGSSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-
-#define __NR_SIGNALS 23
-
-void ( *signal(int signum, void (*handler)(int)) ) (int);
-int raise(int sig);
-
-#endif
diff --git a/src/libc/stdio.c b/src/libc/stdio.c
@@ -1,26 +1,13 @@
#include <stdio.h>
-static unsigned char inbuf[BUFSIZ];
-static unsigned char outbuf[BUFSIZ];
-
FILE __iob[FOPEN_MAX] = {
{
.fd = 0,
- .buf = inbuf,
- .len = BUFSIZ,
.flags = _IOREAD,
- .lp = inbuf,
- .rp = inbuf,
- .wp = inbuf,
},
{
.fd = 1,
- .buf = outbuf,
- .len = BUFSIZ,
.flags = _IOWRITE | _IOLBF,
- .lp = outbuf,
- .rp = outbuf,
- .wp = outbuf,
},
{
.fd = 2,