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