Xtensa support for uClibc [7/9]

Chris Zankel chris at zankel.net
Thu Dec 6 20:50:04 UTC 2007


Add support for Xtensa to uClibc [7/9]: Syscalls and startup files, part 1.

---

diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/Makefile uClibc-0.9.29/libc/sysdeps/linux/xtensa/Makefile
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/Makefile	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,13 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2005 Erik Andersen <andersen at uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../
+top_builddir=../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/Makefile.arch uClibc-0.9.29/libc/sysdeps/linux/xtensa/Makefile.arch
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/Makefile.arch	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/Makefile.arch	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,14 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2007 Tensilica Inc.
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+CSRC := brk.c fork.c posix_fadvise.c posix_fadvise64.c pread_write.c \
+     	__syscall_error.c
+
+SSRC := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S \
+	syscall.S mmap.S windowspill.S __longjmp.S vfork.S
+
+include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/__longjmp.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/__longjmp.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/__longjmp.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/__longjmp.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,126 @@
+/* longjmp for Xtensa Processors.
+
+   Copyright (C) 2001, 2007 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., 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* This implementation relies heavily on the Xtensa register window
+   mechanism.  Setjmp flushes all the windows except its own to the
+   stack and then copies registers from the save areas on the stack
+   into the jmp_buf structure, along with the return address of the call
+   to setjmp.  Longjmp invalidates all the windows except its own, and
+   then sets things up so that it will return to the right place,
+   using a window underflow to automatically restore the registers.
+
+   Note that it would probably be sufficient to only copy the
+   registers from setjmp's caller into jmp_buf.  However, we also copy
+   the save area located at the stack pointer of setjmp's caller.
+   This save area will typically remain intact until the longjmp call.
+   The one exception is when there is an intervening alloca in
+   setjmp's caller.  This is certainly an unusual situation and is
+   likely to cause problems in any case (the storage allocated on the
+   stack cannot be safely accessed following the longjmp).  As bad as
+   it is, on most systems this situation would not necessarily lead to
+   a catastrophic failure.  If we did not preserve the extra save area
+   on Xtensa, however, it would.  When setjmp's caller returns after a
+   longjmp, there will be a window underflow; an invalid return
+   address or stack pointer in the save area will almost certainly
+   lead to a crash.  Keeping a copy of the extra save area in the
+   jmp_buf avoids this with only a small additional cost.  If setjmp
+   and longjmp are ever time-critical, this could be removed.  */
+
+
+#include "sysdep.h"
+
+
+ENTRY (__longjmp)
+
+	/* Invalidate all but the current window.  Reading and writing
+	   special registers WINDOWBASE and WINDOWSTART are
+	   privileged operations, so user processes must call the
+	   slower __window_spill() to do the job.  */
+
+	movi	a4, __window_spill
+	callx4	a4
+
+	/* Return to the return address of the setjmp, using the
+	   window size bits from the setjmp call so that the caller
+	   will be able to find the return value that we put in a2.  */
+
+	l32i	a0, a2, 64
+
+	/* Copy the first 4 saved registers from jmp_buf into the save area
+	   at the current sp so that the values will be restored to registers
+	   when longjmp returns. */
+
+	addi	a7, a1, -16
+	l32i	a4, a2, 0
+	l32i	a5, a2, 4
+	s32i	a4, a7, 0
+	s32i	a5, a7, 4
+	l32i	a4, a2, 8
+	l32i	a5, a2, 12
+	s32i	a4, a7, 8
+	s32i	a5, a7, 12
+
+	/* Copy the remaining 0-8 saved registers.  */
+	extui	a7, a0, 30, 2
+	blti	a7, 2, .Lendlj
+	l32i	a8, a2, 52
+	slli	a4, a7, 4
+	sub	a6, a8, a4
+	addi	a5, a2, 16
+	addi	a8, a8, -16		// a8 = end of register overflow area
+.Lljloop:
+	l32i	a7, a5, 0
+	l32i	a4, a5, 4
+	s32i	a7, a6, 0
+	s32i	a4, a6, 4
+	l32i	a7, a5, 8
+	l32i	a4, a5, 12
+	s32i	a7, a6, 8
+	s32i	a4, a6, 12
+	addi	a5, a5, 16
+	addi	a6, a6, 16
+	blt	a6, a8, .Lljloop
+.Lendlj:
+
+	/* The 4 words saved from the register save area at the target's
+	   sp are copied back to the target procedure's save area.  The
+	   only point of this is to prevent a catastrophic failure in
+	   case the contents were moved by an alloca after calling
+	   setjmp.  This is a bit paranoid but it doesn't cost much.  */
+
+	l32i	a7, a2, 4		// load the target stack pointer
+	addi	a7, a7, -16		// find the destination save area
+	l32i	a4, a2, 48
+	l32i	a5, a2, 52
+	s32i	a4, a7, 0
+	s32i	a5, a7, 4
+	l32i	a4, a2, 56
+	l32i	a5, a2, 60
+	s32i	a4, a7, 8
+	s32i	a5, a7, 12
+
+	/* Return v ? v : 1.  */
+	movi	a2, 1
+	movnez	a2, a3, a3
+
+	retw
+END (__longjmp)
+
+libc_hidden_def (__longjmp)
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/__syscall_error.c uClibc-0.9.29/libc/sysdeps/linux/xtensa/__syscall_error.c
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/__syscall_error.c	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/__syscall_error.c	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,18 @@
+/* Wrapper for setting errno.
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <errno.h>
+#include <features.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ * an error number into errno.  */
+int __syscall_error(int err_no) attribute_hidden;
+int __syscall_error(int err_no)
+{
+	__set_errno(-err_no);
+	return -1;
+}
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/brk.c uClibc-0.9.29/libc/sysdeps/linux/xtensa/brk.c
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/brk.c	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/brk.c	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,43 @@
+/* brk system call for Linux/Xtensa.
+   Copyright (C) 1996, 1997, 2005, 2007 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., 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+/* This must be initialized data because commons can't have aliases.  */
+void *__curbrk attribute_hidden = 0;
+
+libc_hidden_proto(brk)
+int
+brk (void *addr)
+{
+  void *newbrk;
+
+  __curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr);
+
+  if (newbrk < addr)
+    {
+      __set_errno (ENOMEM);
+      return -1;
+    }
+
+  return 0;
+}
+libc_hidden_def(brk)
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/bsd-_setjmp.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/bsd-_setjmp.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/bsd-_setjmp.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/bsd-_setjmp.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1 @@
+/* _setjmp is in setjmp.S  */
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/bsd-setjmp.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/bsd-setjmp.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/bsd-setjmp.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/bsd-setjmp.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1 @@
+/* setjmp is in setjmp.S  */
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/clone.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/clone.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/clone.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/clone.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,103 @@
+/* Copyright (C) 2001, 2005, 2007 Free Software Foundation, Inc.
+
+   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., 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* clone is even more special than fork as it mucks with stacks
+   and invokes a function in the right context after it's all over.  */
+
+#include "sysdep.h"
+#include <sys/syscall.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+/* int clone (a2 = int (*fn)(void *arg),
+	      a3 = void *child_stack,
+	      a4 = int flags,
+	      a5 = void *arg,
+              a6 = pid_t *ptid,
+	      a7 = struct user_desc *tls,
+	      16(sp) = pid_t *ctid) */
+
+        .text
+ENTRY (__clone)
+
+	/* Sanity check arguments.  */
+	beqz	a2, .Leinval	/* no NULL function pointers */
+	beqz	a3, .Leinval	/* no NULL stack pointers */
+
+	/* a2 and a3 are candidates for destruction by system-call return
+	   parameters.  We don't need the stack pointer after the system
+	   call.  We trust that the kernel will preserve a7, a9, and a6.  */
+
+	mov	a9, a5			/* save function argument */
+	mov	a5, a7
+	mov	a7, a2			/* save function pointer */
+	mov	a8, a6			/* use a8 as a temp */
+	mov	a6, a4
+	mov	a4, a8
+	l32i	a8, a1, 16		/* child_tid */
+	movi	a2, SYS_ify (clone)
+
+	/* syscall (a2 = NR_clone,
+		    a6 = clone_flags,
+		    a3 = usp,
+		    a4 = parent_tid,
+		    a5 = child_tls,
+		    a8 = child_tid) */
+	syscall
+	bltz	a2, SYSCALL_ERROR_LABEL
+	beqz	a2, .Lthread_start
+
+	/* Fall through for parent.  */
+.Lpseudo_end:
+	retw
+
+.Leinval:
+	movi	a2, -EINVAL
+	j	SYSCALL_ERROR_LABEL
+
+.Lthread_start:
+	/* Start child thread.  */
+	movi	a0, 0			/* terminate the stack frame */
+
+#ifdef RESET_PID
+	/* Check and see if we need to reset the PID.  */
+	bbsi.l	a6, 16, 1f		/* CLONE_THREAD = 0x00010000 */
+	movi	a2, -1
+	bbsi.l	a6, 8, 2f		/* CLONE_VM = 0x00000100 */
+	movi	a2, SYS_ify (getpid)
+	syscall
+2:	rur	a3, THREADPTR
+	movi	a4, PID_OFFSET
+	add	a4, a4, a3
+	s32i	a2, a4, 0
+	movi	a4, TID_OFFSET
+	add	a4, a4, a3
+	s32i	a2, a3, 0
+1:
+#endif /* RESET_PID */
+
+	mov	a6, a9			/* load up the 'arg' parameter */
+	callx4	a7			/* call the user's function */
+
+	/* Call _exit.  Note that any return parameter from the user's
+	   function in a6 is seen as inputs to _exit.  */
+	movi	a2, JUMPTARGET(_exit)
+	callx4	a2
+
+PSEUDO_END (__clone)
+
+weak_alias (__clone, clone)
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/crt1.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/crt1.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/crt1.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/crt1.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,119 @@
+/* Startup code compliant to the ELF Xtensa ABI.
+   Copyright (C) 2001, 2007 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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   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., 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include <features.h>
+
+#ifndef __UCLIBC_CTOR_DTOR__
+        .weak _init
+        .weak _fini
+#endif
+
+/* This is the canonical entry point, usually the first thing in the text
+   segment.  When the entry point runs, most register values are unspecified,
+   except for:
+
+	a2	Contains a function pointer to be registered with `atexit'.
+		This is how the dynamic linker arranges to have DT_FINI
+		functions called for shared libraries that have been loaded
+		before this code runs.
+
+	a1	The stack (i.e., a1+16) contains the arguments and environment:
+		a1+0			argc
+		a1+4			argv[0]
+		...
+		a1+(4*argc)		NULL
+		a1+(4*(argc+1))		envp[0]
+		...
+					NULL
+
+  Setup parameters accordingly (for a call4).  See function prototype
+  from sysdeps/generic/libc-start.c
+
+	a6 = *main
+	a7 = argc
+	a8 = ubp_av
+	a9 = *init
+	a10 = *fini
+	a11 = *rtld_fini
+	[sp+0] = stack_end
+ */
+
+	.text
+	.align	4
+	.literal_position
+	.global	_start
+	.type	_start, @function
+_start:
+	/* Clear a0 to obviously mark the outermost frame.  */
+	movi	a0, 0
+
+	/* Load up the user's main function.  */
+	movi	a6, main
+
+	/* Extract the arguments as encoded on the stack and set up
+	   the arguments for `main': argc, argv.  envp will be determined
+	   later in __uClibc_main.  */
+	l32i	a7, a1, 0	/* Load the argument count.  */
+	addi	a8, a1, 4	/* Compute the argv pointer.  */
+
+	/* Push address of our own entry points to .fini and .init.  */
+	movi	a9, _init
+	movi	a10, _fini
+
+	/* Setup the shared library termination function.  */
+	mov	a11, a2
+
+	/* Provide the highest stack address to the user code (for stacks
+	   which grow downwards).  Note that we destroy the stack version
+	   of argc here.  */
+	s32i	a1, a1, 0
+
+	/* Call the user's main function, and exit with its value.
+	   But let the libc call main.    */
+	movi	a4, __uClibc_main
+	callx4	a4
+
+	/* Crash if somehow `exit' does return.  */
+	ill
+
+	/* Define a symbol for the first piece of initialized data.  */
+	.data
+	.align	4
+	.global	__data_start
+__data_start:
+	.long	0
+	.weak	data_start
+	data_start = __data_start
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/crti.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/crti.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/crti.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/crti.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,16 @@
+/* glibc's sysdeps/xtensa/elf/initfini.c used for reference [PROLOG] */
+
+	.section .init
+	.align	4
+	.global	_init
+	.type	_init, @function
+_init:
+	entry	sp, 48
+
+
+	.section .fini
+	.align	4
+	.global	_fini
+	.type	_fini, @function
+_fini:
+	entry	sp, 48
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/crtn.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/crtn.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/crtn.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/crtn.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,8 @@
+/* glibc's sysdeps/xtensa/elf/initfini.c used for reference [EPILOG] */
+
+	.section .init
+	retw
+
+
+	.section .fini
+	retw
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/fork.c uClibc-0.9.29/libc/sysdeps/linux/xtensa/fork.c
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/fork.c	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/fork.c	2007-12-04 11:38:14.000000000 -0800
@@ -0,0 +1,25 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * fork() for Xtensa uClibc
+ *
+ * Copyright (C) 2007 Tensilica Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */ 
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+/* Xtensa doesn't provide a 'fork' system call, so we use 'clone'.  */
+
+extern __typeof(fork) __libc_fork;
+
+libc_hidden_proto (fork)
+pid_t __libc_fork (void)
+{
+  return (pid_t) INLINE_SYSCALL (clone, 2, SIGCHLD, 0);
+}
+weak_alias (__libc_fork, fork)
+libc_hidden_weak (fork)
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/mmap.S uClibc-0.9.29/libc/sysdeps/linux/xtensa/mmap.S
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/mmap.S	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/mmap.S	2007-12-04 11:38:00.000000000 -0800
@@ -0,0 +1,57 @@
+/* Copyright (C) 2005, 2007 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., 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include <sys/syscall.h>
+
+#define PAGE_SHIFT 12
+
+/* __ptr_t __mmap (a2 = __ptr_t addr,
+		   a3 = size_t len,
+		   a4 = int prot,
+		   a5 = int flags,
+		   a6 = int fd,
+		   a7 = off_t offset) */
+
+ENTRY (__mmap)
+
+	/* We only support mmap2 in the kernel, so shift offset by
+	   page - size.  */
+	mov	a8, a6
+	mov	a6, a2
+	movi	a2, SYS_ify (mmap2)
+	srli	a9, a7, PAGE_SHIFT
+
+	/* syscall (a2 = NR_mmap2,
+		    a6 = arg0,
+		    a3 = arg1,
+		    a4 = arg2,
+		    a5 = arg3,
+		    a8 = arg4,
+		    a9 = arg5) */
+
+	syscall
+	bltz	a2, SYSCALL_ERROR_LABEL
+
+.Lpseudo_end:
+	retw
+
+PSEUDO_END (__mmap)
+
+weak_alias (__mmap, mmap)
+libc_hidden_weak (mmap)
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/posix_fadvise.c uClibc-0.9.29/libc/sysdeps/linux/xtensa/posix_fadvise.c
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/posix_fadvise.c	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/posix_fadvise.c	2007-12-04 11:38:14.000000000 -0800
@@ -0,0 +1,29 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * posix_fadvise() for Xtensa uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
+ * Copyright (C) 2007 Tensilica Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+int posix_fadvise (int fd, off_t offset, off_t len, int advice)
+{
+#ifdef __NR_fadvise64_64
+	INTERNAL_SYSCALL_DECL (err);
+	int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd, advice,
+								__LONG_LONG_PAIR ((long) (offset >> 31),
+												  (long) offset),
+								__LONG_LONG_PAIR ((long) (len >> 31),
+												  (long) len));
+	if (!INTERNAL_SYSCALL_ERROR_P (ret, err))
+		return 0;
+	return INTERNAL_SYSCALL_ERRNO (ret, err);
+#else
+	return ENOSYS;
+#endif
+}
diff -Nurd uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/posix_fadvise64.c uClibc-0.9.29/libc/sysdeps/linux/xtensa/posix_fadvise64.c
--- uClibc-0.9.29.orig/libc/sysdeps/linux/xtensa/posix_fadvise64.c	1969-12-31 16:00:00.000000000 -0800
+++ uClibc-0.9.29/libc/sysdeps/linux/xtensa/posix_fadvise64.c	2007-12-04 11:38:14.000000000 -0800
@@ -0,0 +1,39 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * posix_fadvise64() for Xtensa uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
+ * Copyright (C) 2007 Tensilica Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#include <unistd.h>
+#include <errno.h>
+#include <endian.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+#ifdef __UCLIBC_HAS_LFS__
+
+int posix_fadvise64 (int fd, __off64_t offset, __off64_t len, int advice)
+{
+#ifdef __NR_fadvise64_64
+	INTERNAL_SYSCALL_DECL (err);
+	int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd, advice,
+								__LONG_LONG_PAIR ((long) (offset >> 32),
+												  (long) offset),
+								__LONG_LONG_PAIR ((long) (len >> 32),
+												  (long) len));
+	if (!INTERNAL_SYSCALL_ERROR_P (ret, err))
+		return 0;
+	return INTERNAL_SYSCALL_ERRNO (ret, err);
+#else
+	return ENOSYS;
+#endif
+}
+
+#endif /* __UCLIBC_HAS_LFS__ */



More information about the uClibc mailing list