summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/frv
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-02-18 08:04:51 +0000
committerEric Andersen <andersen@codepoet.org>2004-02-18 08:04:51 +0000
commitbaa67289df42b1b994092b8312148a6f9e172274 (patch)
tree9a6a60a10a0db9879671cd923e7307c993cfbd40 /libc/sysdeps/linux/frv
parent377c7157a8802c289c5560f1a2ecd1030d571e7d (diff)
Alexandre Oliva writes:
This patch adds code to uClibc to support a new ABI designed for the FR-V architecture, that enables text segments of executables and shared libraries to be shared by multiple processes on an OS such as uClinux, that can run on FR-V processors without an MMU. Patches for binutils and GCC have just been posted in the corresponding mailing lists. The binutils patch was approved, but there's one additional patch pending review, that I posted this week. An updated GCC patch will be posted to gcc-patches@gcc.gnu.org as soon as I complete testing (I used a known-good compiler to test the uClibc patch below). Since the existing dynamic loader code didn't support independent relocation of segments, it required changes that were somewhat extensive. I've added a number of new machine-specific macros to try to keep the platform and ABI-specific details outside the generic code. I hope this is not a problem.
Diffstat (limited to 'libc/sysdeps/linux/frv')
-rw-r--r--libc/sysdeps/linux/frv/Makefile89
-rw-r--r--libc/sysdeps/linux/frv/__init_brk.c25
-rw-r--r--libc/sysdeps/linux/frv/__longjmp.S75
-rw-r--r--libc/sysdeps/linux/frv/_mmap.c48
-rw-r--r--libc/sysdeps/linux/frv/bits/elf-fdpic.h104
-rw-r--r--libc/sysdeps/linux/frv/bits/endian.h7
-rw-r--r--libc/sysdeps/linux/frv/bits/fcntl.h156
-rw-r--r--libc/sysdeps/linux/frv/bits/kernel_stat.h57
-rw-r--r--libc/sysdeps/linux/frv/bits/kernel_types.h43
-rw-r--r--libc/sysdeps/linux/frv/bits/mman.h75
-rw-r--r--libc/sysdeps/linux/frv/bits/setjmp.h53
-rw-r--r--libc/sysdeps/linux/frv/bits/stackinfo.h28
-rw-r--r--libc/sysdeps/linux/frv/bits/syscalls.h129
-rw-r--r--libc/sysdeps/linux/frv/bits/wordsize.h19
-rw-r--r--libc/sysdeps/linux/frv/brk.c22
-rw-r--r--libc/sysdeps/linux/frv/clone.S83
-rw-r--r--libc/sysdeps/linux/frv/crt0.S110
-rw-r--r--libc/sysdeps/linux/frv/crti.S41
-rw-r--r--libc/sysdeps/linux/frv/crtn.S35
-rw-r--r--libc/sysdeps/linux/frv/crtreloc.c118
-rw-r--r--libc/sysdeps/linux/frv/dl-iterate-phdr.c43
-rw-r--r--libc/sysdeps/linux/frv/sbrk.c25
-rw-r--r--libc/sysdeps/linux/frv/setjmp.S95
-rw-r--r--libc/sysdeps/linux/frv/sys/procfs.h125
-rw-r--r--libc/sysdeps/linux/frv/sys/ptrace.h139
-rw-r--r--libc/sysdeps/linux/frv/sys/ucontext.h451
-rw-r--r--libc/sysdeps/linux/frv/sysdep.c27
-rw-r--r--libc/sysdeps/linux/frv/vfork.S44
28 files changed, 2266 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/frv/Makefile b/libc/sysdeps/linux/frv/Makefile
new file mode 100644
index 000000000..77d1326d5
--- /dev/null
+++ b/libc/sysdeps/linux/frv/Makefile
@@ -0,0 +1,89 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
+#
+# This program 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.
+#
+# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+TOPDIR=../../../../
+include $(TOPDIR)Rules.mak
+ASFLAGS=$(CFLAGS)
+
+CRT0_SRC = crt0.S
+CRT0_OBJ = crt0.o crt1.o # gcrt1.o
+SCRT0_OBJ = $(patsubst %,S%, $(CRT0_OBJ))
+CRT0_DEPS=gmon-start.S
+
+CTOR_TARGETS = crti.o crtn.o
+
+SSRC=__longjmp.S setjmp.S clone.S vfork.S
+ifeq ($(strip $(UCLIBC_PROFILING)),y)
+SSRC+=mcount.S
+endif
+SOBJS=$(patsubst %.S,%.o, $(SSRC))
+
+CSRC=_mmap.c sysdep.c brk.c sbrk.c __init_brk.c dl-iterate-phdr.c
+COBJS=$(patsubst %.c,%.o, $(CSRC))
+
+OBJS=$(SOBJS) $(COBJS)
+
+all: $(OBJS) $(LIBC)
+
+$(LIBC): ar-target
+
+ar-target: $(OBJS) $(CRT0_OBJ) $(SCRT0_OBJ) $(CTOR_TARGETS)
+ $(AR) $(ARFLAGS) $(LIBC) $(OBJS)
+ $(INSTALL) -d $(TOPDIR)lib
+ cp $(CRT0_OBJ) $(SCRT0_OBJ) $(CTOR_TARGETS) $(TOPDIR)lib/
+
+$(CRT0_OBJ): $(CRT0_SRC) crtreloc.o
+ $(CC) $(CFLAGS) -DL_$* -r -nostdlib $< crtreloc.o -o $*.o
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+crtreloc.o: crtreloc.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(SCRT0_OBJ): $(CRT0_SRC) Scrtreloc.o
+ $(CC) $(CFLAGS) -fPIE -DL_$* -r -nostdlib $< Scrtreloc.o -o $*.o
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+Scrtreloc.o: crtreloc.c
+ $(CC) $(CFLAGS) -fPIE -c $< -o $@
+
+$(CTOR_TARGETS): %.o : %.S
+ $(CC) $(CFLAGS) -c $< -o $@
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+$(SOBJS): %.o : %.S
+ $(CC) $(CFLAGS) -c $< -o $@
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+$(COBJS): %.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+ $(STRIPTOOL) -x -R .note -R .comment $*.o
+
+ifeq ($(strip $(UCLIBC_PROFILING)),y)
+SAFECFLAGS := $(filter-out -g,$(CFLAGS))
+gmon-start.S: ../common/gmon-start.c
+ $(CC) $(SAFECFLAGS) -c $< -S -o $*.S
+gcrt1.o: $(CRT0_DEPS)
+endif
+
+headers:
+
+
+clean:
+ rm -f *.[oa] *~ core
+ rm -f bits/sysnum.h
+
diff --git a/libc/sysdeps/linux/frv/__init_brk.c b/libc/sysdeps/linux/frv/__init_brk.c
new file mode 100644
index 000000000..7f9cd3c31
--- /dev/null
+++ b/libc/sysdeps/linux/frv/__init_brk.c
@@ -0,0 +1,25 @@
+/* From libc-5.3.12 */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+void * ___brk_addr = 0;
+
+#define __NR__brk __NR_brk
+_syscall1(void *, _brk, void *, ptr);
+
+int
+__init_brk (void)
+{
+ if (___brk_addr == 0)
+ {
+ ___brk_addr = _brk(0);
+ if (___brk_addr == 0)
+ {
+ __set_errno(ENOMEM);
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/libc/sysdeps/linux/frv/__longjmp.S b/libc/sysdeps/linux/frv/__longjmp.S
new file mode 100644
index 000000000..a61f8d4e0
--- /dev/null
+++ b/libc/sysdeps/linux/frv/__longjmp.S
@@ -0,0 +1,75 @@
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+
+# setjmp/longjmp for Frv. The jmpbuf looks like this:
+#
+# Register jmpbuf offset
+# R16-R31 0x0-0x03c
+# R48-R63 0x40-0x7c
+# FR16-FR31 0x80-0xbc
+# FR48-FR63 0xc0-0xfc
+# LR 0x100
+# SP 0x104
+# FP 0x108
+#
+# R8 contains the pointer to jmpbuf
+
+ .text
+ .global __longjmp
+ .type __longjmp,@function
+__longjmp:
+ lddi @(gr8,0), gr16
+ lddi @(gr8,8), gr18
+ lddi @(gr8,16), gr20
+ lddi @(gr8,24), gr22
+ lddi @(gr8,32), gr24
+ lddi @(gr8,40), gr26
+ lddi @(gr8,48), gr28
+ lddi @(gr8,56), gr30
+#if __FRV_GPR__ != 32
+ lddi @(gr8,64), gr48
+ lddi @(gr8,72), gr50
+ lddi @(gr8,80), gr52
+ lddi @(gr8,88), gr54
+ lddi @(gr8,96), gr56
+ lddi @(gr8,104), gr58
+ lddi @(gr8,112), gr60
+ lddi @(gr8,120), gr62
+#endif
+
+#if __FRV_FPR__ != 0
+ lddfi @(gr8,128), fr16
+ lddfi @(gr8,136), fr18
+ lddfi @(gr8,144), fr20
+ lddfi @(gr8,152), fr22
+ lddfi @(gr8,160), fr24
+ lddfi @(gr8,168), fr26
+ lddfi @(gr8,176), fr28
+ lddfi @(gr8,184), fr30
+#if __FRV_FPR__ != 32
+ lddfi @(gr8,192), fr48
+ lddfi @(gr8,200), fr50
+ lddfi @(gr8,208), fr52
+ lddfi @(gr8,216), fr54
+ lddfi @(gr8,224), fr56
+ lddfi @(gr8,232), fr58
+ lddfi @(gr8,240), fr60
+ lddfi @(gr8,248), fr62
+#endif
+#endif
+
+ ldi @(gr8,256), gr4
+ movgs gr4,lr
+
+ ldi @(gr8,260), sp
+ ldi @(gr8,264), fp
+
+# Value to return is in r9. If zero, return 1
+ cmp gr9, gr0, icc0
+ setlos #1, gr8
+ ckne icc0, cc4
+ cmov gr9, gr8, cc4, 1
+ ret
+.Lend2:
+ .size __longjmp,.Lend2-__longjmp
diff --git a/libc/sysdeps/linux/frv/_mmap.c b/libc/sysdeps/linux/frv/_mmap.c
new file mode 100644
index 000000000..b3fd7c3d8
--- /dev/null
+++ b/libc/sysdeps/linux/frv/_mmap.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Daniel Jacobowitz <dan@debian.org>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Massivly hacked up for uClibc by Erik Andersen */
+
+/* Extracted from ../common/mmap64.c by Alexandre Oliva <aoliva@redhat.com>
+
+ We don't want to use the old mmap interface. */
+
+#include <features.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+
+#define __NR___syscall_mmap2 __NR_mmap2
+static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
+ size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+
+/* This is always 12, even on architectures where PAGE_SHIFT != 12. */
+# ifndef MMAP2_PAGE_SHIFT
+# define MMAP2_PAGE_SHIFT 12
+# endif
+
+__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
+{
+ if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) {
+ __set_errno (EINVAL);
+ return MAP_FAILED;
+ }
+ return(__syscall_mmap2(addr, len, prot, flags, fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)));
+}
diff --git a/libc/sysdeps/linux/frv/bits/elf-fdpic.h b/libc/sysdeps/linux/frv/bits/elf-fdpic.h
new file mode 100644
index 000000000..f47d9493c
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/elf-fdpic.h
@@ -0,0 +1,104 @@
+/* Copyright 2003 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 Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 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 Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#ifndef _BITS_ELF_FDPIC_H
+#define _BITS_ELF_FDPIC_H
+
+/* These data structures are described in the FDPIC ABI extension.
+ The kernel passes a process a memory map, such that for every LOAD
+ segment there is an elf32_fdpic_loadseg entry. A pointer to an
+ elf32_fdpic_loadmap is passed in GR8 at start-up, and a pointer to
+ an additional such map is passed in GR9 for the interpreter, when
+ there is one. */
+
+#include <elf.h>
+
+/* This data structure represents a PT_LOAD segment. */
+struct elf32_fdpic_loadseg
+{
+ /* Core address to which the segment is mapped. */
+ Elf32_Addr addr;
+ /* VMA recorded in the program header. */
+ Elf32_Addr p_vaddr;
+ /* Size of this segment in memory. */
+ Elf32_Word p_memsz;
+};
+
+struct elf32_fdpic_loadmap {
+ /* Protocol version number, must be zero. */
+ Elf32_Half version;
+ /* Number of segments in this map. */
+ Elf32_Half nsegs;
+ /* The actual memory map. */
+ struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
+struct elf32_fdpic_loadaddr {
+ struct elf32_fdpic_loadmap *map;
+ void *got_value;
+};
+
+/* Map a pointer's VMA to its corresponding address according to the
+ load map. */
+inline static void *
+__reloc_pointer (void *p,
+ const struct elf32_fdpic_loadmap *map)
+{
+ int c;
+
+#if 0
+ if (map->version != 0)
+ /* Crash. */
+ ((void(*)())0)();
+#endif
+
+ /* No special provision is made for NULL. We don't want NULL
+ addresses to go through relocation, so they shouldn't be in
+ .rofixup sections, and, if they're present in dynamic
+ relocations, they shall be mapped to the NULL address without
+ undergoing relocations. */
+
+ for (c = 0;
+ /* Take advantage of the fact that the loadmap is ordered by
+ virtual addresses. In general there will only be 2 entries,
+ so it's not profitable to do a binary search. */
+ c < map->nsegs && p >= (void*)map->segs[c].p_vaddr;
+ c++)
+ {
+ /* This should be computed as part of the pointer comparison
+ above, but we want to use the carry in the comparison, so we
+ can't convert it to an integer type beforehand. */
+ unsigned long offset = p - (void*)map->segs[c].p_vaddr;
+ /* We explicitly refrain from checking for one-past-the-end.
+ Zero-sized objects aren't legal, and it's expected that array
+ addresses will be relocated before the addend that would make
+ it one-past-the-end is added. This gives us a reasonable speed
+ up, and we couldn't possibly disambiguate all cases anyway. */
+ if (offset < map->segs[c].p_memsz)
+ return (char*)map->segs[c].addr + offset;
+ }
+
+ /* We might want to crash instead. */
+ return (void*)-1;
+}
+
+# define __RELOC_POINTER(ptr, loadaddr) \
+ (__reloc_pointer ((void*)(ptr), \
+ (loadaddr).map))
+
+#endif /* _BITS_ELF_FDPIC_H */
diff --git a/libc/sysdeps/linux/frv/bits/endian.h b/libc/sysdeps/linux/frv/bits/endian.h
new file mode 100644
index 000000000..0564c5921
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/endian.h
@@ -0,0 +1,7 @@
+/* frv is little-endian. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __BIG_ENDIAN
diff --git a/libc/sysdeps/linux/frv/bits/fcntl.h b/libc/sysdeps/linux/frv/bits/fcntl.h
new file mode 100644
index 000000000..69a20966d
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/fcntl.h
@@ -0,0 +1,156 @@
+/* O_*, F_*, FD_* bit values for Linux.
+ Copyright (C) 1995, 1996, 1997, 1998, 2000 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+#include <sys/types.h>
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_CREAT 0100 /* not fcntl */
+#define O_EXCL 0200 /* not fcntl */
+#define O_NOCTTY 0400 /* not fcntl */
+#define O_TRUNC 01000 /* not fcntl */
+#define O_APPEND 02000
+#define O_NONBLOCK 04000
+#define O_NDELAY O_NONBLOCK
+#define O_SYNC 010000
+#define O_FSYNC O_SYNC
+#define O_ASYNC 020000
+
+#ifdef __USE_GNU
+# define O_DIRECT 040000 /* Direct disk access. */
+# define O_DIRECTORY 0200000 /* Must be a directory. */
+# define O_NOFOLLOW 0400000 /* Do not follow links. */
+# define O_STREAMING 04000000/* streaming access */
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define O_LARGEFILE 0100000
+#endif
+
+/* Values for the second argument to `fcntl'. */
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK 5 /* Get record locking info. */
+# define F_SETLK 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW 7 /* Set record locking info (blocking). */
+#else
+# define F_GETLK F_GETLK64 /* Get record locking info. */
+# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
+# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
+#endif
+#define F_GETLK64 12 /* Get record locking info. */
+#define F_SETLK64 13 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 14 /* Set record locking info (blocking). */
+
+#if defined __USE_BSD || defined __USE_XOPEN2K
+# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
+# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG 10 /* Set number of signal to be sent. */
+# define F_GETSIG 11 /* Get number of signal to be sent. */
+#endif
+
+/* For F_[GET|SET]FL. */
+#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 0 /* Read lock. */
+#define F_WRLCK 1 /* Write lock. */
+#define F_UNLCK 2 /* Remove lock. */
+
+/* For old implementation of bsd flock(). */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation. */
+# define LOCK_SH 1 /* shared lock */
+# define LOCK_EX 2 /* exclusive lock */
+# define LOCK_NB 4 /* or'd with one of the above to prevent
+ blocking */
+# define LOCK_UN 8 /* remove lock */
+#endif
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+ BSD systems which did not managed to hide these kernel macros. */
+#ifdef __USE_BSD
+# define FAPPEND O_APPEND
+# define FFSYNC O_FSYNC
+# define FASYNC O_ASYNC
+# define FNONBLOCK O_NONBLOCK
+# define FNDELAY O_NDELAY
+#endif /* Use BSD. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
diff --git a/libc/sysdeps/linux/frv/bits/kernel_stat.h b/libc/sysdeps/linux/frv/bits/kernel_stat.h
new file mode 100644
index 000000000..c6fc95328
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/kernel_stat.h
@@ -0,0 +1,57 @@
+#ifndef _BITS_STAT_STRUCT_H
+#define _BITS_STAT_STRUCT_H
+
+/* This file provides whatever this particular arch's kernel thinks
+ * struct kernel_stat should look like... It turns out each arch has a
+ * different opinion on the subject... */
+
+struct kernel_stat {
+ unsigned short st_dev;
+ unsigned short __pad1;
+ unsigned long st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ unsigned short __pad2;
+ unsigned long st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long __unused1;
+ unsigned long st_mtime;
+ unsigned long __unused2;
+ unsigned long st_ctime;
+ unsigned long __unused3;
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct kernel_stat64 {
+ unsigned char __pad0[6];
+ unsigned short st_dev;
+ unsigned char __pad1[2];
+#define _HAVE_STAT64___ST_INO
+ unsigned long __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned long st_uid;
+ unsigned long st_gid;
+ unsigned char __pad2[6];
+ unsigned short st_rdev;
+ unsigned char __pad3[2];
+ long long st_size;
+ unsigned long st_blksize;
+ unsigned long __pad4; /* future possible st_blocks high bits */
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+ unsigned long st_atime;
+ unsigned long __pad5;
+ unsigned long st_mtime;
+ unsigned long __pad6;
+ unsigned long st_ctime;
+ unsigned long __pad7; /* will be high 32 bits of ctime someday */
+ unsigned long long st_ino;
+};
+
+#endif /* _BITS_STAT_STRUCT_H */
diff --git a/libc/sysdeps/linux/frv/bits/kernel_types.h b/libc/sysdeps/linux/frv/bits/kernel_types.h
new file mode 100644
index 000000000..3d3f6304c
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/kernel_types.h
@@ -0,0 +1,43 @@
+/* Note that we use the exact same include guard #define names
+ * as asm/posix_types.h. This will avoid gratuitous conflicts
+ * with the posix_types.h kernel header, and will ensure that
+ * our private content, and not the kernel header, will win.
+ * -Erik
+ */
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
+
+typedef unsigned short __kernel_dev_t;
+typedef unsigned long __kernel_ino_t;
+typedef unsigned short __kernel_mode_t;
+typedef unsigned short __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_daddr_t;
+typedef char * __kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef long long __kernel_loff_t;
+
+typedef struct {
+#ifdef __USE_ALL
+ int val[2];
+#else
+ int __val[2];
+#endif
+} __kernel_fsid_t;
+
+#endif /* _ASM_POSIX_TYPES_H */
diff --git a/libc/sysdeps/linux/frv/bits/mman.h b/libc/sysdeps/linux/frv/bits/mman.h
new file mode 100644
index 000000000..9e87f804c
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/mman.h
@@ -0,0 +1,75 @@
+/* Definitions for POSIX memory map interface. Linux/frv version.
+ Copyright (C) 1997 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* The following definitions basically come from the kernel headers.
+ But the kernel header is not namespace clean. */
+
+
+/* Protections are chosen from these bits, OR'd together. The
+ implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ without PROT_READ. The only guarantees are that no writing will be
+ allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
+
+#define PROT_READ 0x1 /* Page can be read. */
+#define PROT_WRITE 0x2 /* Page can be written. */
+#define PROT_EXEC 0x4 /* Page can be executed. */
+#define PROT_NONE 0x0 /* Page can not be accessed. */
+
+/* Sharing types (must choose one and only one of these). */
+#define MAP_SHARED 0x01 /* Share changes. */
+#define MAP_PRIVATE 0x02 /* Changes are private. */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x0f /* Mask for type of mapping. */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x10 /* Interpret addr exactly. */
+#ifdef __USE_MISC
+# define MAP_FILE 0
+# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_GROWSDOWN 0x0100 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */
+# define MAP_LOCKED 0x2000 /* Lock the mapping. */
+# define MAP_NORESERVE 0x4000 /* Don't check for reservations. */
+#endif
+
+/* Flags to `msync'. */
+#define MS_ASYNC 1 /* Sync memory asynchronously. */
+#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
+
+/* Flags for `mlockall'. */
+#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 2 /* Lock all additions to address
+ space. */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+#endif
diff --git a/libc/sysdeps/linux/frv/bits/setjmp.h b/libc/sysdeps/linux/frv/bits/setjmp.h
new file mode 100644
index 000000000..5c20c4f54
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/setjmp.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 1999, 2000, 2003, 2004 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. */
+
+/* Define the machine-dependent type `jmp_buf'. FRV version. */
+
+#ifndef _SETJMP_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#define __SETJMP_NUM_INT 32 /* number of integer registers to save */
+#define __SETJMP_NUM_DBL 32 /* number of double registers to save */
+
+#define __SETJMP_INT(x) (x)
+#define __SETJMP_DBL(x) (__SETJMP_NUM_INT+(x))
+#define __SETJMP_LR (__SETJMP_NUM_INT+__SETJMP_NUM_DBL)
+#define __SETJMP_SP (__SETJMP_LR+1)
+#define __SETJMP_FP (__SETJMP_SP+1)
+
+
+#ifndef _ASM
+typedef struct
+/* Demand 64-bit alignment such that we can use std/ldd in
+ setjmp/longjmp. */
+__attribute__((__aligned__(8)))
+ {
+ /* Callee-saved registers. */
+ unsigned long __ints[__SETJMP_NUM_INT]; /* integer registers */
+ unsigned long __dbls[__SETJMP_NUM_DBL]; /* double registers */
+ unsigned long __lr; /* linkage register */
+ unsigned long __sp; /* stack pointer */
+ unsigned long __fp; /* frame pointer */
+ } __jmp_buf[1];
+#endif
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address) \
+ ((unsigned long) (address) < (jmpbuf)->__sp)
diff --git a/libc/sysdeps/linux/frv/bits/stackinfo.h b/libc/sysdeps/linux/frv/bits/stackinfo.h
new file mode 100644
index 000000000..03412e009
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2001 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+/* On FRV the stack grows down. */
+#define _STACK_GROWS_DOWN 1
+
+#endif /* stackinfo.h */
diff --git a/libc/sysdeps/linux/frv/bits/syscalls.h b/libc/sysdeps/linux/frv/bits/syscalls.h
new file mode 100644
index 000000000..552f7e7c4
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/syscalls.h
@@ -0,0 +1,129 @@
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
+#endif
+
+/* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
+ * header files. It also defines the traditional `SYS_<name>' macros for older
+ * programs. */
+#include <bits/sysnum.h>
+
+#ifndef __set_errno
+# define __set_errno(val) ((*__errno_location ()) = (val))
+#endif
+#ifndef SYS_ify
+# define SYS_ify(syscall_name) (__NR_##syscall_name)
+#endif
+
+#ifndef __ASSEMBLER__
+
+/* user-visible error numbers are in the range -1 - -4095: see <asm-frv/errno.h> */
+#define __syscall_return(type, res) \
+do { \
+ unsigned long __sr2 = (res); \
+ if ((unsigned long)(__sr2) >= (unsigned long)(-4095)) { \
+ __set_errno (-(__sr2)); \
+ __sr2 = -1; \
+ } \
+ return (type) (__sr2); \
+} while (0)
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
+register unsigned long __sc0 __asm__ ("gr8"); \
+__asm__ __volatile__ ("tra gr0,gr0" \
+ : "=r" (__sc0) \
+ : "r" (__scnum)); \
+__syscall_return(type,__sc0); \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
+register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
+__asm__ __volatile__ ("tra gr0,gr0" \
+ : "+r" (__sc0) \
+ : "r" (__scnum)); \
+__syscall_return(type,__sc0); \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
+register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
+register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
+__asm__ __volatile__ ("tra gr0,gr0" \
+ : "+r" (__sc0) \
+ : "r" (__scnum), "r" (__sc1)); \
+__syscall_return(type,__sc0); \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
+register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
+register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
+register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
+__asm__ __volatile__ ("tra gr0,gr0" \
+ : "+r" (__sc0) \
+ : "r" (__scnum), "r" (__sc1), "r" (__sc2)); \
+__syscall_return(type,__sc0); \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
+register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
+register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
+register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
+register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \
+__asm__ __volatile__ ("tra gr0,gr0" \
+ : "+r" (__sc0) \
+ : "r" (__scnum), "r" (__sc1), "r" (__sc2), "r" (__sc3)); \
+__syscall_return(type,__sc0); \
+}
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
+{ \
+register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
+register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
+register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
+register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
+register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \
+register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \
+__asm__ __volatile__ ("tra gr0,gr0" \
+ : "+r" (__sc0) \
+ : "r" (__scnum), "r" (__sc1), "r" (__sc2), \
+ "r" (__sc3), "r" (__sc4)); \
+__syscall_return(type,__sc0); \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
+{ \
+register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
+register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
+register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
+register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
+register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \
+register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \
+register unsigned long __sc5 __asm__ ("gr13") = (unsigned long) arg6; \
+__asm__ __volatile__ ("tra gr0,gr0" \
+ : "+r" (__sc0) \
+ : "r" (__scnum), "r" (__sc1), "r" (__sc2), \
+ "r" (__sc3), "r" (__sc4), "r" (__sc5)); \
+__syscall_return(type,__sc0); \
+}
+
+#endif /* __ASSEMBLER__ */
+#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/frv/bits/wordsize.h b/libc/sysdeps/linux/frv/bits/wordsize.h
new file mode 100644
index 000000000..ba643b60a
--- /dev/null
+++ b/libc/sysdeps/linux/frv/bits/wordsize.h
@@ -0,0 +1,19 @@
+/* Copyright (C) 1999 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __WORDSIZE 32
diff --git a/libc/sysdeps/linux/frv/brk.c b/libc/sysdeps/linux/frv/brk.c
new file mode 100644
index 000000000..4f97fb084
--- /dev/null
+++ b/libc/sysdeps/linux/frv/brk.c
@@ -0,0 +1,22 @@
+/* From libc-5.3.12 */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk (void);
+extern void *_brk(void *ptr);
+
+int brk(void * end_data_seg)
+{
+ if (__init_brk () == 0)
+ {
+ ___brk_addr = _brk(end_data_seg);
+ if (___brk_addr == end_data_seg)
+ return 0;
+ __set_errno(ENOMEM);
+ }
+ return -1;
+}
diff --git a/libc/sysdeps/linux/frv/clone.S b/libc/sysdeps/linux/frv/clone.S
new file mode 100644
index 000000000..2e3c6b742
--- /dev/null
+++ b/libc/sysdeps/linux/frv/clone.S
@@ -0,0 +1,83 @@
+/* Copyright (C) 2003 Free Software Foudnation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Alexandre Oliva <aoliva@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <asm/unistd.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+ .text
+ .globl __clone
+ .type __clone,@function
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
+__clone:
+ /* Sanity check arguments. */
+ cmp.p gr8, gr0, icc0
+ cmp gr9, gr0, icc1
+ mov.p gr8, gr4
+ beq icc0, #0, .Lerror
+ mov.p gr11, gr5
+ beq icc1, #0, .Lerror
+
+ mov.p gr10, gr8
+ setlos #__NR_clone, gr7
+ tra gr0,gr0
+
+ cmp gr8, gr0, icc0
+ bgtlr icc0, #1
+ beq icc0, #0, .Lthread_start
+
+.Lsys_error:
+ sethi.p #gotofffuncdeschi(__syscall_error), gr14
+ setlo #gotofffuncdesclo(__syscall_error), gr14
+ ldd @(gr14, gr15), gr14
+ jmpl @(gr14, gr0)
+
+.Lerror:
+ setlos.p #-EINVAL, gr7
+ bra .Lsys_error
+
+###############################################################################
+#
+# come here as the new thread [GR4 is fn, GR5 is arg]
+#
+###############################################################################
+.Lthread_start:
+ /* Save the PIC register. */
+ mov gr15, gr17
+
+ /* Call the user's function. */
+ ldd.p @(gr4, gr0), gr14
+ mov gr5, gr8
+ calll @(gr14, gr0)
+
+ /* Call _exit, rather simply inlining the syscall, such that
+ breakpoints work.*/
+
+ mov.p gr17, gr15
+ call _exit
+
+ /* Should never get here. */
+ jmpl @(gr0, gr0)
+ .size __clone,.-__clone
+
+.weak clone
+ clone = __clone
diff --git a/libc/sysdeps/linux/frv/crt0.S b/libc/sysdeps/linux/frv/crt0.S
new file mode 100644
index 000000000..8a425158f
--- /dev/null
+++ b/libc/sysdeps/linux/frv/crt0.S
@@ -0,0 +1,110 @@
+/* Copyright (C) 1991, 1992, 2003 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 Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 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 Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+
+/* Based on ../i386/crt0.S and newlib's libgloss/frv/crt0.S */
+
+/*
+ When we enter this piece of code, the program stack looks like this:
+ argc argument counter (integer)
+ argv[0] program name (pointer)
+ argv[1...N] program args (pointers)
+ argv[argc-1] end of args (integer)
+ NULL
+ env[0...N] environment variables (pointers)
+ NULL
+
+ Also, GR16 holds a pointer to a memory map. */
+
+#include <features.h>
+
+ .text
+ .global _start
+ .type _start,%function
+#if defined L_crt0 || defined L_Scrt0 || ! defined __UCLIBC_CTOR_DTOR__
+ .type __uClibc_main,%function
+#else
+ .weak _init
+ .weak _fini
+ .type __uClibc_start_main,%function
+#endif
+/* Stick in a dummy reference to main(), so that if an application
+ * is linking when the main() function is in a static library (.a)
+ * we can be sure that main() actually gets linked in */
+ .type main,%function
+_start:
+ /* At program start-up, gr16 contains a pointer to a memory
+ map, that we use to relocate addresses. */
+ call .Lcall
+.Lcall:
+ movsg lr, gr4
+ sethi.p #gprelhi(.Lcall), gr5
+ setlo #gprello(.Lcall), gr5
+ sub.p gr4, gr5, gr4
+ /* gr4 now holds the _gp address. */
+
+ mov gr16, gr8
+ sethi.p #gprelhi(__ROFIXUP_LIST__), gr9
+ sethi #gprelhi(__ROFIXUP_END__), gr10
+ setlo.p #gprello(__ROFIXUP_LIST__), gr9
+ setlo #gprello(__ROFIXUP_END__), gr10
+ add.p gr9, gr4, gr9
+ add gr10, gr4, gr10
+ call __self_reloc
+ mov.p gr8, gr17
+ mov gr8, gr15
+ /* gr17 now holds the self-relocated _GLOBAL_OFFSET_TABLE_
+ address, because the linker added its unrelocated address as
+ the last entry in the ROFIXUP list, and __self_reloc returns
+ the last entry, relocated. */
+
+ /* Prepare arguments for uClibc main. */
+ ld @(sp, gr0), gr8
+ slli gr8, #2, gr10
+ add sp, gr10, gr10
+ addi.p sp, #4, gr9
+ addi gr10, #8, gr10
+
+ /* Set up an invalid (NULL return address, NULL frame pointer)
+ callers stack frame so anybody unrolling the stack knows where
+ to stop */
+ mov gr0, fp
+ movgs gr0, lr
+
+#if (defined L_crt1 || defined L_gcrt1 || defined L_Scrt1) && defined __UCLIBC_CTOR_DTOR__
+ /* Pass .init and .fini arguments to __uClibc_start_main(). */
+ sethi.p #gotfuncdeschi(_init), gr11
+ sethi #gotfuncdeschi(_fini), gr12
+ setlo.p #gotfuncdesclo(_init), gr11
+ setlo #gotfuncdesclo(_fini), gr12
+ ld.p @(gr11, gr17), gr11
+ mov gr17, gr15
+ ld.p @(gr12, gr17), gr12
+ call __uClibc_start_main
+#else
+ mov.p gr17, gr15
+ call __uClibc_main
+#endif
+
+ /* Crash if somehow `exit' returns anyways. */
+ jmpl @(gr0,gr0)
+.size _start,.-_start
+
+#if defined L_gcrt1 && defined __UCLIBC_PROFILING__
+# include "./gmon-start.S"
+#endif
diff --git a/libc/sysdeps/linux/frv/crti.S b/libc/sysdeps/linux/frv/crti.S
new file mode 100644
index 000000000..715ce4a89
--- /dev/null
+++ b/libc/sysdeps/linux/frv/crti.S
@@ -0,0 +1,41 @@
+/* Copyright (C) 2003 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 Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 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 Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+ .section .init,"x"
+ .p2align 2
+ .globl _init
+ .type _init, @function
+_init:
+ addi sp,#-16,sp
+ st.p fp, @(sp,gr0)
+ mov sp, fp
+ movsg lr, gr5
+ sti gr15, @(fp,4)
+ sti gr5, @(fp,8)
+
+ .section .fini,"x"
+ .p2align 2
+ .globl _fini
+ .type _fini, @function
+_fini:
+ addi sp,#-16,sp
+ st.p fp, @(sp,gr0)
+ mov sp, fp
+ movsg lr, gr5
+ sti gr15, @(fp,4)
+ sti gr5, @(fp,8)
diff --git a/libc/sysdeps/linux/frv/crtn.S b/libc/sysdeps/linux/frv/crtn.S
new file mode 100644
index 000000000..b495bbeb2
--- /dev/null
+++ b/libc/sysdeps/linux/frv/crtn.S
@@ -0,0 +1,35 @@
+/* Copyright (C) 2003 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 Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 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 Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+ .section .init,"x"
+ .globl _init
+ .type _init, @function
+ ldi @(fp,8), gr5
+ ld @(sp,gr0), fp
+ addi sp,#16,sp
+ jmpl @(gr5,gr0)
+ .size _init, .-_init
+
+ .section .fini,"x"
+ .globl _fini
+ .type _fini, @function
+ ldi @(fp,8), gr5
+ ld @(sp,gr0), fp
+ addi sp,#16,sp
+ jmpl @(gr5,gr0)
+ .size _fini, .-_fini
diff --git a/libc/sysdeps/linux/frv/crtreloc.c b/libc/sysdeps/linux/frv/crtreloc.c
new file mode 100644
index 000000000..38af68c7b
--- /dev/null
+++ b/libc/sysdeps/linux/frv/crtreloc.c
@@ -0,0 +1,118 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ written by Alexandre Oliva <aoliva@redhat.com>
+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 Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 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 Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#define _GNU_SOURCE
+#include <link.h>
+
+#include <sys/types.h>
+
+#include <elf.h>
+#include <bits/elf-fdpic.h>
+
+/* This file is to be compiled into crt object files, to enable
+ executables to easily self-relocate. */
+
+#define hidden __attribute__((__visibility__("hidden")))
+
+/* Compute the runtime address of pointer in the range [p,e), and then
+ map the pointer pointed by it. */
+inline static void ***
+reloc_range_indirect (void ***p, void ***e,
+ const struct elf32_fdpic_loadmap *map)
+{
+ while (p < e)
+ {
+ void *ptr = __reloc_pointer (*p, map);
+ if (ptr)
+ {
+ void *pt;
+ if ((long)ptr & 3)
+ __builtin_memcpy(&pt, ptr, sizeof(pt));
+ else
+ pt = *(void**)ptr;
+ pt = __reloc_pointer (pt, map);
+ if ((long)ptr & 3)
+ __builtin_memcpy(ptr, &pt, sizeof(pt));
+ else
+ *(void**)ptr = pt;
+ }
+ p++;
+ }
+ return p;
+}
+
+/* Call __reloc_range_indirect for the given range except for the last
+ entry, whose contents are only relocated. It's expected to hold
+ the GOT value. */
+void* hidden
+__self_reloc (const struct elf32_fdpic_loadmap *map,
+ void ***p, void ***e)
+{
+ p = reloc_range_indirect (p, e-1, map);
+
+ if (p >= e)
+ return (void*)-1;
+
+ return __reloc_pointer (*p, map);
+}
+
+#if 0
+/* These are other functions that might be useful, but that we don't
+ need. */
+
+/* Remap pointers in [p,e). */
+inline static void**
+reloc_range (void **p, void **e,
+ const struct elf32_fdpic_loadmap *map)
+{
+ while (p < e)
+ {
+ *p = __reloc_pointer (*p, map);
+ p++;
+ }
+ return p;
+}
+
+/* Remap p, adjust e by the same offset, then map the pointers in the
+ range determined by them. */
+void hidden
+__reloc_range (const struct elf32_fdpic_loadmap *map,
+ void **p, void **e)
+{
+ void **old = p;
+
+ p = __reloc_pointer (p, map);
+ e += p - old;
+ reloc_range (p, e, map);
+}
+
+/* Remap p, adjust e by the same offset, then map pointers referenced
+ by the (unadjusted) pointers in the range. Return the relocated
+ value of the last pointer in the range. */
+void* hidden
+__reloc_range_indirect (const struct elf32_fdpic_loadmap *map,
+ void ***p, void ***e)
+{
+ void ***old = p;
+
+ p = __reloc_pointer (p, map);
+ e += p - old;
+ return reloc_range_indirect (p, e, map);
+}
+#endif
diff --git a/libc/sysdeps/linux/frv/dl-iterate-phdr.c b/libc/sysdeps/linux/frv/dl-iterate-phdr.c
new file mode 100644
index 000000000..ebb3b9c4a
--- /dev/null
+++ b/libc/sysdeps/linux/frv/dl-iterate-phdr.c
@@ -0,0 +1,43 @@
+/* Copyright 2003 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 Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 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 Lesser General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#define _GNU_SOURCE
+#include <link.h>
+
+extern int __attribute__((__weak__))
+__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
+ size_t size, void *data),
+ void *data);
+
+/* Define it as a pointer, such that we get a pointer to the global
+ function descriptor, that won't be optimized away by the
+ linker. */
+static int (*ptr) (int (*callback) (struct dl_phdr_info *info,
+ size_t size, void *data),
+ void *data) = __dl_iterate_phdr;
+
+int
+dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
+ size_t size, void *data),
+ void *data)
+{
+ if (ptr)
+ return ptr (callback, data);
+
+ return 0;
+}
diff --git a/libc/sysdeps/linux/frv/sbrk.c b/libc/sysdeps/linux/frv/sbrk.c
new file mode 100644
index 000000000..c39d60063
--- /dev/null
+++ b/libc/sysdeps/linux/frv/sbrk.c
@@ -0,0 +1,25 @@
+/* From libc-5.3.12 */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk (void);
+extern void *_brk(void *ptr);
+
+void *
+sbrk(intptr_t increment)
+{
+ if (__init_brk () == 0)
+ {
+ char * tmp = (char*)___brk_addr+increment;
+ ___brk_addr = _brk(tmp);
+ if (___brk_addr == tmp)
+ return tmp-increment;
+ __set_errno(ENOMEM);
+ return ((void *) -1);
+ }
+ return ((void *) -1);
+}
diff --git a/libc/sysdeps/linux/frv/setjmp.S b/libc/sysdeps/linux/frv/setjmp.S
new file mode 100644
index 000000000..455e61178
--- /dev/null
+++ b/libc/sysdeps/linux/frv/setjmp.S
@@ -0,0 +1,95 @@
+#include <features.h>
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+
+ .text
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+ .global _setjmp
+ .type _setjmp,@function
+_setjmp:
+ setlos #0, gr9
+ bra .Lsigsetjmp_intern
+ .size _setjmp,.-_setjmp
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+ .align 4
+ .type setjmp,@function
+ .globl setjmp
+setjmp:
+ setlos #1, gr9
+ bra .Lsigsetjmp_intern
+ .size setjmp,.-setjmp
+
+# setjmp/longjmp for Frv. The jmpbuf looks like this:
+#
+# Register jmpbuf offset
+# R16-R31 0x0-0x03c
+# R48-R63 0x40-0x7c
+# FR16-FR31 0x80-0xbc
+# FR48-FR63 0xc0-0xfc
+# LR 0x100
+# SP 0x104
+# FP 0x108
+
+ .global __sigsetjmp
+ .type __sigsetjmp,@function
+__sigsetjmp:
+.Lsigsetjmp_intern:
+ stdi gr16, @(gr8,0)
+ stdi gr18, @(gr8,8)
+ stdi gr20, @(gr8,16)
+ stdi gr22, @(gr8,24)
+ stdi gr24, @(gr8,32)
+ stdi gr26, @(gr8,40)
+ stdi gr28, @(gr8,48)
+ stdi gr30, @(gr8,56)
+#if __FRV_GPR__ != 32
+ stdi gr48, @(gr8,64)
+ stdi gr50, @(gr8,72)
+ stdi gr52, @(gr8,80)
+ stdi gr54, @(gr8,88)
+ stdi gr56, @(gr8,96)
+ stdi gr58, @(gr8,104)
+ stdi gr60, @(gr8,112)
+ stdi gr62, @(gr8,120)
+#endif
+
+#if __FRV_FPR__ != 0
+ stdfi fr16, @(gr8,128)
+ stdfi fr18, @(gr8,136)
+ stdfi fr20, @(gr8,144)
+ stdfi fr22, @(gr8,152)
+ stdfi fr24, @(gr8,160)
+ stdfi fr26, @(gr8,168)
+ stdfi fr28, @(gr8,176)
+ stdfi fr30, @(gr8,184)
+#if __FRV_FPR__ != 32
+ stdfi fr48, @(gr8,192)
+ stdfi fr50, @(gr8,200)
+ stdfi fr52, @(gr8,208)
+ stdfi fr54, @(gr8,216)
+ stdfi fr56, @(gr8,224)
+ stdfi fr58, @(gr8,232)
+ stdfi fr60, @(gr8,240)
+ stdfi fr62, @(gr8,248)
+#endif
+#endif
+
+ movsg lr, gr4
+ sti gr4, @(gr8,256)
+ sti sp, @(gr8,260)
+ sti fp, @(gr8,264)
+
+ sethi.p #gotofffuncdeschi(__sigjmp_save), gr4
+ setlo #gotofffuncdesclo(__sigjmp_save), gr4
+ ldd @(gr15, gr4), gr14
+ jmpl @(gr14, gr0)
+ .size __sigsetjmp,.-__sigsetjmp
diff --git a/libc/sysdeps/linux/frv/sys/procfs.h b/libc/sysdeps/linux/frv/sys/procfs.h
new file mode 100644
index 000000000..f07523342
--- /dev/null
+++ b/libc/sysdeps/linux/frv/sys/procfs.h
@@ -0,0 +1,125 @@
+/* Copyright (C) 1996, 1997, 1999, 2000, 2003 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. It doesn't have anything to do with the /proc file
+ system, even though Linux has one.
+
+ Anyway, the whole purpose of this file is for GDB and GDB only.
+ Don't read too much into it. Don't use it for anything other than
+ GDB unless you know what you are doing. */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+/* Type for a general-purpose register. */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them. We could have used `struct
+ user_regs_struct' directly in the typedef, but tradition says that
+ the register set is an array, which does have some peculiar
+ semantics, so leave it that way. */
+#define ELF_NGREG (sizeof (struct user_int_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Register set for the floating-point registers. */
+typedef struct user_fpmedia_regs elf_fpregset_t;
+
+/* Signal info. */
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with Linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ GDB doesn't really use excluded. */
+
+struct elf_prstatus
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args. */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+
+/* The rest of this file provides the types for emulation of the
+ Solaris <proc_service.h> interfaces that should be implemented by
+ users of libthread_db. */
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore have only one PID type. */
+typedef __pid_t lwpid_t;
+
+/* Process status and info. In the end we do provide typedefs for them. */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/linux/frv/sys/ptrace.h b/libc/sysdeps/linux/frv/sys/ptrace.h
new file mode 100644
index 000000000..6b0eca7b0
--- /dev/null
+++ b/libc/sysdeps/linux/frv/sys/ptrace.h
@@ -0,0 +1,139 @@
+/* `ptrace' debugger support interface. FRV-Linux version.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004
+ 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Type of the REQUEST argument to `ptrace.' */
+enum __ptrace_request
+{
+ /* Indicate that the process making this request should be traced.
+ All signals received by this process can be intercepted by its
+ parent, and its parent can use the other `ptrace' requests. */
+ PTRACE_TRACEME = 0,
+#define PT_TRACE_ME PTRACE_TRACEME
+
+ /* Return the word in the process's text space at address ADDR. */
+ PTRACE_PEEKTEXT = 1,
+#define PT_READ_I PTRACE_PEEKTEXT
+
+ /* Return the word in the process's data space at address ADDR. */
+ PTRACE_PEEKDATA = 2,
+#define PT_READ_D PTRACE_PEEKDATA
+
+ /* Return the word in the process's user area at offset ADDR. */
+ PTRACE_PEEKUSER = 3,
+#define PT_READ_U PTRACE_PEEKUSER
+
+ /* Write the word DATA into the process's text space at address ADDR. */
+ PTRACE_POKETEXT = 4,
+#define PT_WRITE_I PTRACE_POKETEXT
+
+ /* Write the word DATA into the process's data space at address ADDR. */
+ PTRACE_POKEDATA = 5,
+#define PT_WRITE_D PTRACE_POKEDATA
+
+ /* Write the word DATA into the process's user area at offset ADDR. */
+ PTRACE_POKEUSER = 6,
+#define PT_WRITE_U PTRACE_POKEUSER
+
+ /* Continue the process. */
+ PTRACE_CONT = 7,
+#define PT_CONTINUE PTRACE_CONT
+
+ /* Kill the process. */
+ PTRACE_KILL = 8,
+#define PT_KILL PTRACE_KILL
+
+ /* Single step the process.
+ This is not supported on all machines. */
+ PTRACE_SINGLESTEP = 9,
+#define PT_STEP PTRACE_SINGLESTEP
+
+ /* Get all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETREGS = 12,
+#define PT_GETREGS PTRACE_GETREGS
+
+ /* Set all general purpose registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETREGS = 13,
+#define PT_SETREGS PTRACE_SETREGS
+
+ /* Get all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETFPREGS = 14,
+#define PT_GETFPREGS PTRACE_GETFPREGS
+
+ /* Set all floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETFPREGS = 15,
+#define PT_SETFPREGS PTRACE_SETFPREGS
+
+ /* Attach to a process that is already running. */
+ PTRACE_ATTACH = 16,
+#define PT_ATTACH PTRACE_ATTACH
+
+ /* Detach from a process attached to with PTRACE_ATTACH. */
+ PTRACE_DETACH = 17,
+#define PT_DETACH PTRACE_DETACH
+
+ /* Get all extended floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_GETFPXREGS = 18,
+#define PT_GETFPXREGS PTRACE_GETFPXREGS
+
+ /* Set all extended floating point registers used by a processes.
+ This is not supported on all machines. */
+ PTRACE_SETFPXREGS = 19,
+#define PT_SETFPXREGS PTRACE_SETFPXREGS
+
+ /* Continue and stop at the next (return from) syscall. */
+ PTRACE_SYSCALL = 24,
+#define PT_SYSCALL PTRACE_SYSCALL
+
+ /* Obtain the load map of the main program or the interpreter of the
+ ptraced process, depending on whether the addr argument is
+ (void*)0 or (void*)1, respectively. */
+ PTRACE_GETFDPIC = 31
+#define PT_GETFDPIC PTRACE_GETFDPIC
+};
+
+#define PTRACE_GETFDPIC_EXEC ((void*)0) /* [addr] request the executable loadmap */
+#define PTRACE_GETFDPIC_INTERP ((void*)1) /* [addr] request the interpreter loadmap */
+
+/* Perform process tracing functions. REQUEST is one of the values
+ above, and determines the action to be taken.
+ For all requests except PTRACE_TRACEME, PID specifies the process to be
+ traced.
+
+ PID and the other arguments described above for the various requests should
+ appear (those that are used for the particular request) as:
+ pid_t PID, void *ADDR, int DATA, void *ADDR2
+ after REQUEST. */
+extern long int ptrace (enum __ptrace_request __request, ...) __THROW;
+
+__END_DECLS
+
+#endif /* _SYS_PTRACE_H */
diff --git a/libc/sysdeps/linux/frv/sys/ucontext.h b/libc/sysdeps/linux/frv/sys/ucontext.h
new file mode 100644
index 000000000..2385a072e
--- /dev/null
+++ b/libc/sysdeps/linux/frv/sys/ucontext.h
@@ -0,0 +1,451 @@
+/* Copyright (C) 1999, 2000, 2001, 2003 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. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+
+typedef unsigned long greg_t;
+
+/* Number of general registers. */
+#define NGREG (10+2+64)
+
+/* Container for all general registers. */
+typedef greg_t gregset_t[NGREG];
+
+#ifdef __USE_GNU
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ PSR = 0,
+#define PSR PSR
+ ISR = 1,
+#define ISR ISR
+ CCR = 2,
+#define CCR CCR
+ CCCR = 3,
+#define CCCR CCCR
+ LR = 4,
+#define LR LR
+ LCR = 5,
+#define LCR LCR
+ PC = 6,
+#define PC PC
+ __STATUS = 7,
+#define __STATUS __STATUS
+ SYSCALLNO = 8,
+#define SYSCALLNO SYSCALLNO
+ ORIG_GR8 = 9,
+#define ORIG_GR8 ORIG_GR8
+ GNER0 = 10,
+#define GNER0 GNER0
+ GNER1 = 11,
+#define GNER1 GNER1
+ GR0 = 12,
+#define GR0 GR0
+ GR1 = 13,
+#define GR1 GR1
+ GR2 = 14,
+#define GR2 GR2
+ GR3 = 15,
+#define GR3 GR3
+ GR4 = 16,
+#define GR4 GR4
+ GR5 = 17,
+#define GR5 GR5
+ GR6 = 18,
+#define GR6 GR6
+ GR7 = 19,
+#define GR7 GR7
+ GR8 = 20,
+#define GR8 GR8
+ GR9 = 21,
+#define GR9 GR9
+ GR10 = 22,
+#define GR10 GR10
+ GR11 = 23,
+#define GR11 GR11
+ GR12 = 24,
+#define GR12 GR12
+ GR13 = 25,
+#define GR13 GR13
+ GR14 = 26,
+#define GR14 GR14
+ GR15 = 27,
+#define GR15 GR15
+ GR16 = 28,
+#define GR16 GR16
+ GR17 = 29,
+#define GR17 GR17
+ GR18 = 30,
+#define GR18 GR18
+ GR19 = 31,
+#define GR19 GR19
+ GR20 = 32,
+#define GR20 GR20
+ GR21 = 33,
+#define GR21 GR21
+ GR22 = 34,
+#define GR22 GR22
+ GR23 = 35,
+#define GR23 GR23
+ GR24 = 36,
+#define GR24 GR24
+ GR25 = 37,
+#define GR25 GR25
+ GR26 = 38,
+#define GR26 GR26
+ GR27 = 39,
+#define GR27 GR27
+ GR28 = 40,
+#define GR28 GR28
+ GR29 = 41,
+#define GR29 GR29
+ GR30 = 42,
+#define GR30 GR30
+ GR31 = 43,
+#define GR31 GR31
+ GR32 = 44,
+#define GR32 GR32
+ GR33 = 45,
+#define GR33 GR33
+ GR34 = 46,
+#define GR34 GR34
+ GR35 = 47,
+#define GR35 GR35
+ GR36 = 48,
+#define GR36 GR36
+ GR37 = 49,
+#define GR37 GR37
+ GR38 = 50,
+#define GR38 GR38
+ GR39 = 51,
+#define GR39 GR39
+ GR40 = 52,
+#define GR40 GR40
+ GR41 = 53,
+#define GR41 GR41
+ GR42 = 54,
+#define GR42 GR42
+ GR43 = 55,
+#define GR43 GR43
+ GR44 = 56,
+#define GR44 GR44
+ GR45 = 57,
+#define GR45 GR45
+ GR46 = 58,
+#define GR46 GR46
+ GR47 = 59,
+#define GR47 GR47
+ GR48 = 60,
+#define GR48 GR48
+ GR49 = 61,
+#define GR49 GR49
+ GR50 = 62,
+#define GR50 GR50
+ GR51 = 63,
+#define GR51 GR51
+ GR52 = 64,
+#define GR52 GR52
+ GR53 = 65,
+#define GR53 GR53
+ GR54 = 66,
+#define GR54 GR54
+ GR55 = 67,
+#define GR55 GR55
+ GR56 = 68,
+#define GR56 GR56
+ GR57 = 69,
+#define GR57 GR57
+ GR58 = 70,
+#define GR58 GR58
+ GR59 = 71,
+#define GR59 GR59
+ GR60 = 72,
+#define GR60 GR60
+ GR61 = 73,
+#define GR61 GR61
+ GR62 = 74,
+#define GR62 GR62
+ GR63 = 75,
+#define GR63 GR63
+};
+#endif
+
+typedef unsigned long freg_t;
+
+/* Number of FPU registers. */
+#define NFPREG (64+2+2+8+2+1)
+
+#ifdef __USE_GNU
+/* Number of each register is the `gregset_t' array. */
+enum
+{
+ FR0 = 0,
+#define FR0 FR0
+ FR1 = 1,
+#define FR1 FR1
+ FR2 = 2,
+#define FR2 FR2
+ FR3 = 3,
+#define FR3 FR3
+ FR4 = 4,
+#define FR4 FR4
+ FR5 = 5,
+#define FR5 FR5
+ FR6 = 6,
+#define FR6 FR6
+ FR7 = 7,
+#define FR7 FR7
+ FR8 = 8,
+#define FR8 FR8
+ FR9 = 9,
+#define FR9 FR9
+ FR10 = 10,
+#define FR10 FR10
+ FR11 = 11,
+#define FR11 FR11
+ FR12 = 12,
+#define FR12 FR12
+ FR13 = 13,
+#define FR13 FR13
+ FR14 = 14,
+#define FR14 FR14
+ FR15 = 15,
+#define FR15 FR15
+ FR16 = 16,
+#define FR16 FR16
+ FR17 = 17,
+#define FR17 FR17
+ FR18 = 18,
+#define FR18 FR18
+ FR19 = 19,
+#define FR19 FR19
+ FR20 = 20,
+#define FR20 FR20
+ FR21 = 21,
+#define FR21 FR21
+ FR22 = 22,
+#define FR22 FR22
+ FR23 = 23,
+#define FR23 FR23
+ FR24 = 24,
+#define FR24 FR24
+ FR25 = 25,
+#define FR25 FR25
+ FR26 = 26,
+#define FR26 FR26
+ FR27 = 27,
+#define FR27 FR27
+ FR28 = 28,
+#define FR28 FR28
+ FR29 = 29,
+#define FR29 FR29
+ FR30 = 30,
+#define FR30 FR30
+ FR31 = 31,
+#define FR31 FR31
+ FR32 = 32,
+#define FR32 FR32
+ FR33 = 33,
+#define FR33 FR33
+ FR34 = 34,
+#define FR34 FR34
+ FR35 = 35,
+#define FR35 FR35
+ FR36 = 36,
+#define FR36 FR36
+ FR37 = 37,
+#define FR37 FR37
+ FR38 = 38,
+#define FR38 FR38
+ FR39 = 39,
+#define FR39 FR39
+ FR40 = 40,
+#define FR40 FR40
+ FR41 = 41,
+#define FR41 FR41
+ FR42 = 42,
+#define FR42 FR42
+ FR43 = 43,
+#define FR43 FR43
+ FR44 = 44,
+#define FR44 FR44
+ FR45 = 45,
+#define FR45 FR45
+ FR46 = 46,
+#define FR46 FR46
+ FR47 = 47,
+#define FR47 FR47
+ FR48 = 48,
+#define FR48 FR48
+ FR49 = 49,
+#define FR49 FR49
+ FR50 = 50,
+#define FR50 FR50
+ FR51 = 51,
+#define FR51 FR51
+ FR52 = 52,
+#define FR52 FR52
+ FR53 = 53,
+#define FR53 FR53
+ FR54 = 54,
+#define FR54 FR54
+ FR55 = 55,
+#define FR55 FR55
+ FR56 = 56,
+#define FR56 FR56
+ FR57 = 57,
+#define FR57 FR57
+ FR58 = 58,
+#define FR58 FR58
+ FR59 = 59,
+#define FR59 FR59
+ FR60 = 60,
+#define FR60 FR60
+ FR61 = 61,
+#define FR61 FR61
+ FR62 = 62,
+#define FR62 FR62
+ FR63 = 63,
+#define FR63 FR63
+ FNER0 = 64,
+#define FNER0 FNER0
+ FNER1 = 65,
+#define FNER1 FNER1
+ MSR0 = 66,
+#define MSR0 MSR0
+ MSR1 = 67,
+#define MSR1 MSR1
+ ACC0 = 68,
+#define ACC0 ACC0
+ ACC1 = 69,
+#define ACC1 ACC1
+ ACC2 = 70,
+#define ACC2 ACC2
+ ACC3 = 71,
+#define ACC3 ACC3
+ ACC4 = 72,
+#define ACC4 ACC4
+ ACC5 = 73,
+#define ACC5 ACC5
+ ACC6 = 74,
+#define ACC6 ACC6
+ ACC7 = 75,
+#define ACC7 ACC7
+ ACCG0123 = 76,
+#define ACCG0123 ACCG0123
+ ACCG4567 = 77,
+#define ACCG4567 ACCG4567
+ FSR0 = 78,
+#define FSR0 FSR0
+};
+#endif
+
+/* Structure to describe FPU registers. */
+typedef freg_t fpregset_t[NFPREG];
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ gregset_t gregs;
+ fpregset_t fpregs;
+ void *extension;
+ unsigned long sc_oldmask; /* old sigmask */
+ } __attribute__((aligned(8))) mcontext_t;
+
+#ifdef __USE_GNU
+struct kernel_user_int_regs
+{
+ /* integer registers
+ * - up to gr[31] mirror pt_regs in the kernel
+ */
+ unsigned long psr; /* Processor Status Register */
+ unsigned long isr; /* Integer Status Register */
+ unsigned long ccr; /* Condition Code Register */
+ unsigned long cccr; /* Condition Code for Conditional Insns Register */
+ unsigned long lr; /* Link Register */
+ unsigned long lcr; /* Loop Count Register */
+ unsigned long pc; /* Program Counter Register */
+ unsigned long __status; /* exception status */
+ unsigned long syscallno; /* syscall number or -1 */
+ unsigned long orig_gr8; /* original syscall arg #1 */
+ unsigned long gner[2];
+
+ union {
+ unsigned long tbr;
+ unsigned long gr[64];
+ };
+};
+
+struct kernel_user_fpmedia_regs
+{
+ /* FP/Media registers */
+ unsigned long fr[64];
+ unsigned long fner[2];
+ unsigned long msr[2];
+ unsigned long acc[8];
+ unsigned char accg[8];
+ unsigned long fsr[1];
+};
+
+struct kernel_user_context
+{
+ struct kernel_user_int_regs i;
+ struct kernel_user_fpmedia_regs f;
+
+ /* we provide a context extension so that we can save the regs for CPUs that
+ * implement many more of Fujitsu's lavish register spec
+ */
+ void *extension;
+
+ /* This is not part of the kernel's struct user_context, but
+ rather of the enclosing struct sigcontext, but we add it
+ here to parallel mcontext_t, just for completeness. */
+ unsigned long sc_oldmask; /* old sigmask */
+} __attribute__((aligned(8)));
+
+/* This union enables alias-safe casts from mcontext_t* to the union
+ type, that can then be dereferenced as_aliases. */
+union kmcontext_t
+{
+ mcontext_t as_regsets;
+ /* as_aliases is actually missing sc_oldmask, that is present in
+ mcontext_t. */
+ struct kernel_user_context as_aliases;
+};
+#endif
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/linux/frv/sysdep.c b/libc/sysdeps/linux/frv/sysdep.c
new file mode 100644
index 000000000..17260f72f
--- /dev/null
+++ b/libc/sysdeps/linux/frv/sysdep.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ an error number into errno. */
+int __syscall_error (int err_no)
+{
+ __set_errno (err_no);
+ return -1;
+}
diff --git a/libc/sysdeps/linux/frv/vfork.S b/libc/sysdeps/linux/frv/vfork.S
new file mode 100644
index 000000000..2f97b2a47
--- /dev/null
+++ b/libc/sysdeps/linux/frv/vfork.S
@@ -0,0 +1,44 @@
+/* Copyright (C) 2003 Free Software Foudnation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Howells <dhowells@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <asm/unistd.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+ .text
+ .globl __libc_vfork
+ .type __libc_vfork,@function
+/* int vfork(void) */
+__libc_vfork:
+ setlos #__NR_vfork, gr7
+ tira gr0, #0
+
+ cmp gr8, gr0, icc0
+ bplr icc0, #2
+
+ sethi.p #gotofffuncdeschi(__syscall_error), gr14
+ setlo #gotofffuncdesclo(__syscall_error), gr14
+ ldd @(gr14, gr15), gr14
+ jmpl @(gr14, gr0)
+
+ .size vfork,.-vfork
+
+.weak vfork
+.global vfork
+.set vfork, __libc_vfork