OSDN Git Service

remove trailing ';' from _syscallX()
[uclinux-h8/uClibc.git] / ldso / ldso / bfin / dl-syscalls.h
1 /* Copyright (C) 2003, 2004 Red Hat, Inc.
2    Contributed by Alexandre Oliva <aoliva@redhat.com>
3
4 This file is part of uClibc.
5
6 uClibc is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 uClibc is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with uClibc; see the file COPYING.LIB.  If not, write to
18 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
19 USA.  */
20
21 /* We can't use the real errno in ldso, since it has not yet
22  * been dynamicly linked in yet. */
23 #include "sys/syscall.h"
24 extern int _dl_errno;
25 #undef __set_errno
26 #define __set_errno(X) {(_dl_errno) = (X);}
27 #include <sys/mman.h>
28
29 /* The code below is extracted from libc/sysdeps/linux/frv/_mmap.c */
30
31 #if DYNAMIC_LOADER_IN_SIMULATOR
32 #define __NR___syscall_mmap2        __NR_mmap2
33 static __inline__ _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
34         size_t, len, int, prot, int, flags, int, fd, off_t, offset)
35
36 /* Make sure we don't get another definition of _dl_mmap from the
37    machine-independent code.  */
38 #undef __NR_mmap
39 #undef __NR_mmap2
40
41 /* This is always 12, even on architectures where PAGE_SHIFT != 12.  */
42 # ifndef MMAP2_PAGE_SHIFT
43 #  define MMAP2_PAGE_SHIFT 12
44 # endif
45
46 #include <bits/uClibc_page.h> /* for PAGE_SIZE */
47 static __always_inline void *_dl_memset(void*,int,size_t);
48 static __always_inline ssize_t _dl_pread(int fd, void *buf, size_t count, off_t offset);
49
50 static __ptr_t
51 _dl_mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
52 {
53   size_t plen = (len + PAGE_SIZE - 1) & -PAGE_SIZE;
54
55 /* This is a hack to enable the dynamic loader to run within a
56    simulator that doesn't support mmap, with a number of very ugly
57    tricks.  Also, it's not as useful as it sounds, since only dynamic
58    executables without DT_NEEDED dependencies can be run.  AFAIK, they
59    can only be created with -pie.  This trick suffices to enable the
60    dynamic loader to obtain a blank page that it maps early in the
61    bootstrap. */
62   if ((flags & MAP_FIXED) == 0)
63     {
64       void *_dl_mmap_base = 0;
65       __ptr_t *ret = 0;
66
67       if (! _dl_mmap_base)
68         {
69           void *stack;
70           __asm__ ("mov sp, %0" : "=r" (stack));
71           _dl_mmap_base = (void *)(((long)stack + 2 * PAGE_SIZE) & -PAGE_SIZE);
72         retry:
73           if (((void **)_dl_mmap_base)[0] == _dl_mmap_base
74               && ((void **)_dl_mmap_base)[1023] == _dl_mmap_base
75               && (((void **)_dl_mmap_base)[177]
76                   == ((void **)_dl_mmap_base)[771]))
77             {
78               while (((void**)_dl_mmap_base)[177])
79                 {
80                   _dl_mmap_base = ((void**)_dl_mmap_base)[177];
81                   if (!(((void **)_dl_mmap_base)[0] == _dl_mmap_base
82                         && ((void **)_dl_mmap_base)[1023] == _dl_mmap_base
83                         && (((void **)_dl_mmap_base)[177]
84                             == ((void**)_dl_mmap_base)[771])))
85                     ((void(*)())0)();
86                 }
87             }
88           else
89             {
90               int i;
91               for (i = 0; i < (int)PAGE_SIZE; i++)
92                 if (*(char*)(_dl_mmap_base + i))
93                   break;
94               if (i != PAGE_SIZE)
95                 {
96                   _dl_mmap_base = (void*)((long)_dl_mmap_base + PAGE_SIZE);
97                   goto retry;
98                 }
99               ((void**)_dl_mmap_base)[-1] =
100                 ((void**)_dl_mmap_base)[0] =
101                 ((void**)_dl_mmap_base)[1023] =
102                 _dl_mmap_base;
103             }
104         }
105
106       if (_dl_mmap_base)
107         {
108           if (!(((void **)_dl_mmap_base)[0] == _dl_mmap_base
109                 && ((void **)_dl_mmap_base)[1023] == _dl_mmap_base
110                 && (((void **)_dl_mmap_base)[177]
111                     == ((void**)_dl_mmap_base)[771])))
112             ((void(*)())0)();
113           ret = (__ptr_t)((char*)_dl_mmap_base + PAGE_SIZE);
114           _dl_mmap_base =
115             ((void**)_dl_mmap_base)[177] =
116             ((void**)_dl_mmap_base)[771] =
117             (char*)_dl_mmap_base + plen + PAGE_SIZE;
118           ((void**)_dl_mmap_base)[0] =
119             ((void**)_dl_mmap_base)[1023] =
120             _dl_mmap_base;
121         }
122
123       if ((flags & MAP_ANONYMOUS) != 0)
124         {
125           _dl_memset (ret, 0, plen);
126           return ret;
127         }
128
129       flags |= MAP_FIXED;
130       addr = ret;
131     }
132     if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) {
133 #if 0
134         __set_errno (EINVAL);
135 #endif
136         return MAP_FAILED;
137     }
138     if ((flags & MAP_FIXED) != 0)
139       {
140         if (_dl_pread(fd, addr, len, offset) != (ssize_t)len)
141           return (void*)MAP_FAILED;
142         if (plen != len)
143           _dl_memset (addr + len, 0, plen - len);
144         return addr;
145       }
146     return(__syscall_mmap2(addr, len, prot, flags, fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)));
147 }
148 #endif
149
150 #ifdef __NR_pread
151 #ifdef DYNAMIC_LOADER_IN_SIMULATOR
152 #include <unistd.h>
153
154 #define __NR___syscall_lseek __NR_lseek
155 static __always_inline unsigned long _dl_read(int fd, const void *buf, unsigned long count);
156
157 static __always_inline _syscall3(__off_t, __syscall_lseek, int, fd, __off_t, offset,
158                         int, whence)
159 static __always_inline ssize_t
160 _dl_pread(int fd, void *buf, size_t count, off_t offset)
161 {
162   __off_t orig = __syscall_lseek (fd, 0, SEEK_CUR);
163   ssize_t ret;
164
165   if (orig == -1)
166     return -1;
167
168   if (__syscall_lseek (fd, offset, SEEK_SET) != offset)
169     return -1;
170
171   ret = _dl_read (fd, buf, count);
172
173   if (__syscall_lseek (fd, orig, SEEK_SET) != orig)
174     ((void(*)())0)();
175
176   return ret;
177 }
178 #else
179 #define __NR___syscall_pread __NR_pread
180 static __always_inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
181                         size_t, count, off_t, offset_hi, off_t, offset_lo)
182
183 static __always_inline ssize_t
184 _dl_pread(int fd, void *buf, size_t count, off_t offset)
185 {
186   return(__syscall_pread(fd,buf,count,__LONG_LONG_PAIR (offset >> 31, offset)));
187 }
188 #endif
189 #endif
190
191 #ifdef __NR_sram_alloc
192 #define __NR__dl_sram_alloc __NR_sram_alloc
193 static __always_inline _syscall2(__ptr_t, _dl_sram_alloc,
194                         size_t, len, unsigned long, flags)
195 #endif
196
197 #ifdef __NR_sram_free
198 #define __NR__dl_sram_free __NR_sram_free
199 static __always_inline _syscall1(int, _dl_sram_free, __ptr_t, addr)
200 #endif
201
202 #ifdef __NR_dma_memcpy
203 #define __NR__dl_dma_memcpy __NR_dma_memcpy
204 static __always_inline _syscall3(__ptr_t, _dl_dma_memcpy,
205                         __ptr_t, dest, __ptr_t, src, size_t, len)
206 #endif
207
208 #define __UCLIBC_MMAP_HAS_6_ARGS__