~ubuntu-branches/ubuntu/utopic/eglibc/utopic

« back to all changes in this revision

Viewing changes to sysdeps/unix/sysv/linux/aarch64/sysdep.h

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2012-10-26 05:14:58 UTC
  • mfrom: (1.5.1) (4.4.22 experimental)
  • Revision ID: package-import@ubuntu.com-20121026051458-oryotr4i03ob5pab
Tags: 2.16-0ubuntu1
* Merge with unreleased 2.16 in Debian experimental, remaining changes:
  - Drop the Breaks line from libc6, which refers to a Debian transition
  - Remove the libc6 recommends on libc6-i686, which we don't build
  - Enable libc6{,-dev}-armel on armhf and libc6{-dev}-armhf on armel
  - Ship update-locale and validlocale in /usr/sbin in libc-bin
  - Don't build locales or locales-all in Ubuntu, we rely on langpacks
  - Heavily mangle the way we do service restarting on major upgrades
  - Use different MIN_KERNEL_SUPPORTED versions than Debian, due to
    buildd needs.  This should be universally bumped to 3.2.0 once all
    our buildds (including the PPA guests) are running precise kernels
  - Build i386 variants as -march=i686, build amd64 with -O3, and build
    ppc64 variants (both 64-bit and 32-bit) with -O3 -fno-tree-vectorize
  - Re-enable unsubmitted-ldconfig-cache-abi.diff and rebuild the cache
    on upgrades from previous versions that used a different constant
  - debian/patches/any/local-CVE-2012-3406.diff: switch to malloc when
    array grows too large to handle via alloca extension (CVE-2012-3406)
  - Build generic i386/i686 flavour with -mno-tls-direct-seg-refs
* Changes added/dropped with this merge while reducing our delta:
  - Stop building glibc docs from the eglibc source, and instead make
    the glibc-docs stub have a hard dependency on glibc-doc-reference
  - Remove outdated conflicts against ancient versions of ia32-libs
  - Drop the tzdata dependency from libc6, it's in required and minimal
  - Use gcc-4.7/g++-4.7 by default on all our supported architectures
  - Save our historical changelog as changelog.ubuntu in the source
  - Drop nscd's libaudit build-dep for now, as libaudit is in universe
  - Drop the unnecessary Breaks from libc6 to locales and locales-all
  - Ship xen's ld.so.conf.d snippet as /etc/ld.so.conf.d/libc6-xen.conf
* Disable hard failures on the test suite for the first upload to raring

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2005-2007, 2009-2012
 
2
   Free Software Foundation, Inc.
 
3
 
 
4
   This file is part of the GNU C Library.
 
5
 
 
6
   The GNU C Library is free software; you can redistribute it and/or
 
7
   modify it 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
   The GNU C Library is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   Lesser General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU Lesser General Public
 
17
   License along with the GNU C Library; if not, see
 
18
   <http://www.gnu.org/licenses/>.  */
 
19
 
 
20
#ifndef _LINUX_AARCH64_SYSDEP_H
 
21
#define _LINUX_AARCH64_SYSDEP_H 1
 
22
 
 
23
#include <sysdeps/unix/sysdep.h>
 
24
#include <sysdeps/aarch64/sysdep.h>
 
25
 
 
26
/* Don't use stime, even if the kernel headers define it.  We have
 
27
   settimeofday.  Similarly use setitimer to implement alarm.  */
 
28
#undef __NR_time
 
29
#undef __NR_umount
 
30
#undef __NR_stime
 
31
#undef __NR_alarm
 
32
#undef __NR_utime
 
33
#undef __NR_select
 
34
#undef __NR_readdir
 
35
#undef __NR_socketcall
 
36
#undef __NR_ipc
 
37
 
 
38
/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
 
39
#include <dl-sysdep.h>
 
40
 
 
41
#include <tls.h>
 
42
 
 
43
/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
 
44
#ifndef __ASSEMBLER__
 
45
#include <errno.h>
 
46
#endif
 
47
 
 
48
/* For Linux we can use the system call table in the header file
 
49
        /usr/include/asm/unistd.h
 
50
   of the kernel.  But these symbols do not follow the SYS_* syntax
 
51
   so we have to redefine the `SYS_ify' macro here.  */
 
52
#undef SYS_ify
 
53
#define SYS_ify(syscall_name)   (__NR_##syscall_name)
 
54
 
 
55
#ifdef __ASSEMBLER__
 
56
 
 
57
/* Linux uses a negative return value to indicate syscall errors,
 
58
   unlike most Unices, which use the condition codes' carry flag.
 
59
 
 
60
   Since version 2.1 the return value of a system call might be
 
61
   negative even if the call succeeded.  E.g., the `lseek' system call
 
62
   might return a large offset.  Therefore we must not anymore test
 
63
   for < 0, but test for a real error by making sure the value in R0
 
64
   is a real error number.  Linus said he will make sure the no syscall
 
65
   returns a value in -1 .. -4095 as a valid result so we can safely
 
66
   test with -4095.  */
 
67
 
 
68
#undef  PSEUDO
 
69
#define PSEUDO(name, syscall_name, args)                                      \
 
70
  .text;                                                                      \
 
71
  ENTRY (name);                                                               \
 
72
    DO_CALL (syscall_name, args);                                             \
 
73
    cmn x0, #4095;
 
74
 
 
75
/* Notice the use of 'RET' instead of 'ret' the assembler is case
 
76
   insensitive and eglibc already uses the preprocessor symbol 'ret'
 
77
   so we use the upper case 'RET' to force through a ret instruction
 
78
   to the assembler */
 
79
#define PSEUDO_RET                                                            \
 
80
    b.cs 1f;                                                                  \
 
81
    RET;                                                                      \
 
82
    1:                                                                        \
 
83
    b PLTJMP(SYSCALL_ERROR)
 
84
#undef ret
 
85
#define ret PSEUDO_RET
 
86
 
 
87
#undef  PSEUDO_END
 
88
#define PSEUDO_END(name)                                                      \
 
89
  SYSCALL_ERROR_HANDLER                                                       \
 
90
  END (name)
 
91
 
 
92
#undef  PSEUDO_NOERRNO
 
93
#define PSEUDO_NOERRNO(name, syscall_name, args)                              \
 
94
  .text;                                                                      \
 
95
  ENTRY (name);                                                               \
 
96
    DO_CALL (syscall_name, args);
 
97
 
 
98
/* Notice the use of 'RET' instead of 'ret' the assembler is case
 
99
   insensitive and eglibc already uses the preprocessor symbol 'ret'
 
100
   so we use the upper case 'RET' to force through a ret instruction
 
101
   to the assembler */
 
102
#define PSEUDO_RET_NOERRNO                                                    \
 
103
    RET;
 
104
 
 
105
#undef ret_NOERRNO
 
106
#define ret_NOERRNO PSEUDO_RET_NOERRNO
 
107
 
 
108
#undef  PSEUDO_END_NOERRNO
 
109
#define PSEUDO_END_NOERRNO(name)                                              \
 
110
  END (name)
 
111
 
 
112
/* The function has to return the error code.  */
 
113
#undef  PSEUDO_ERRVAL
 
114
#define PSEUDO_ERRVAL(name, syscall_name, args) \
 
115
  .text;                                                                      \
 
116
  ENTRY (name)                                                                \
 
117
    DO_CALL (syscall_name, args);                                             \
 
118
    neg x0, x0
 
119
 
 
120
#undef  PSEUDO_END_ERRVAL
 
121
#define PSEUDO_END_ERRVAL(name) \
 
122
  END (name)
 
123
 
 
124
#define ret_ERRVAL PSEUDO_RET_NOERRNO
 
125
 
 
126
#if NOT_IN_libc
 
127
# define SYSCALL_ERROR __local_syscall_error
 
128
# if RTLD_PRIVATE_ERRNO
 
129
#  define SYSCALL_ERROR_HANDLER                                 \
 
130
__local_syscall_error:                                          \
 
131
        adrp    x1, C_SYMBOL_NAME(rtld_errno);                  \
 
132
        add     x1, x1, #:lo12:C_SYMBOL_NAME(rtld_errno);       \
 
133
        neg     w0, w0;                                         \
 
134
        str     w0, [x1];                                       \
 
135
        mov     x0, -1;                                         \
 
136
        RET;
 
137
# else
 
138
 
 
139
#  define SYSCALL_ERROR_HANDLER                                 \
 
140
__local_syscall_error:                                          \
 
141
        stp     x29, x30, [sp, -32]!;                           \
 
142
        cfi_adjust_cfa_offset (32);                             \
 
143
        cfi_rel_offset (x29, 0);                                \
 
144
        cfi_rel_offset (x30, 8);                                \
 
145
        add     x29, sp, 0;                                     \
 
146
        str     x19, [sp,16];                                   \
 
147
        neg     x19, x0;                                        \
 
148
        bl      PLTJMP(C_SYMBOL_NAME(__errno_location));        \
 
149
        str     x19, [x0];                                      \
 
150
        mov     x0, -1;                                         \
 
151
        ldr     x19, [sp,16];                                   \
 
152
        ldp     x29, x30, [sp], 32;                             \
 
153
        cfi_adjust_cfa_offset (-32);                            \
 
154
        cfi_restore (x29);                                      \
 
155
        cfi_restore (x30);                                      \
 
156
        RET;
 
157
# endif
 
158
#else
 
159
# define SYSCALL_ERROR_HANDLER  /* Nothing here; code in sysdep.S is used.  */
 
160
# define SYSCALL_ERROR __syscall_error
 
161
#endif
 
162
 
 
163
/* Linux takes system call args in registers:
 
164
        syscall number  in the SVC instruction
 
165
        arg 1           x0
 
166
        arg 2           x1
 
167
        arg 3           x2
 
168
        arg 4           x3
 
169
        arg 5           x4
 
170
        arg 6           x5
 
171
        arg 7           x6
 
172
 
 
173
   The compiler is going to form a call by coming here, through PSEUDO, with
 
174
   arguments
 
175
        syscall number  in the DO_CALL macro
 
176
        arg 1           x0
 
177
        arg 2           x1
 
178
        arg 3           x2
 
179
        arg 4           x3
 
180
        arg 5           x4
 
181
        arg 6           x5
 
182
        arg 7           x6
 
183
 
 
184
   We need to shuffle values between R4..R6 and the stack so that the
 
185
   caller's v1..v3 and stack frame are not corrupted, and the kernel
 
186
   sees the right arguments.
 
187
 
 
188
*/
 
189
 
 
190
#undef  DO_CALL
 
191
#define DO_CALL(syscall_name, args)             \
 
192
    DOARGS_##args                               \
 
193
    mov x8, SYS_ify (syscall_name);             \
 
194
    svc 0;                                      \
 
195
    UNDOARGS_##args
 
196
 
 
197
#define DOARGS_0 /* nothing */
 
198
#define DOARGS_1 /* nothing */
 
199
#define DOARGS_2 /* nothing */
 
200
#define DOARGS_3 /* nothing */
 
201
#define DOARGS_4 /* nothing */
 
202
#define DOARGS_5 /* nothing */
 
203
#define DOARGS_6 /* nothing */
 
204
#define DOARGS_7 /* nothing */
 
205
 
 
206
#define UNDOARGS_0 /* nothing */
 
207
#define UNDOARGS_1 /* nothing */
 
208
#define UNDOARGS_2 /* nothing */
 
209
#define UNDOARGS_3 /* nothing */
 
210
#define UNDOARGS_4 /* nothing */
 
211
#define UNDOARGS_5 /* nothing */
 
212
#define UNDOARGS_6 /* nothing */
 
213
#define UNDOARGS_7 /* nothing */
 
214
 
 
215
#else /* not __ASSEMBLER__ */
 
216
 
 
217
#ifdef SHARED
 
218
# define INLINE_VSYSCALL(name, nr, args...)                                   \
 
219
  ({                                                                          \
 
220
    __label__ out;                                                            \
 
221
    __label__ iserr;                                                          \
 
222
    long sc_ret;                                                              \
 
223
    long sc_err;                                                              \
 
224
    INTERNAL_SYSCALL_DECL (sc_err);                                           \
 
225
                                                                              \
 
226
    if (__vdso_##name != NULL)                                                \
 
227
      {                                                                       \
 
228
        register long _x0 asm ("x0");                                         \
 
229
        sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args);   \
 
230
        if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                       \
 
231
          goto out;                                                           \
 
232
        if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS)                \
 
233
          goto iserr;                                                         \
 
234
      }                                                                       \
 
235
                                                                              \
 
236
    sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args);                     \
 
237
    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                            \
 
238
      {                                                                       \
 
239
      iserr:                                                                  \
 
240
        __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));                \
 
241
        sc_ret = -1L;                                                         \
 
242
      }                                                                       \
 
243
  out:                                                                        \
 
244
    sc_ret;                                                                   \
 
245
  })
 
246
#else
 
247
# define INLINE_VSYSCALL(name, nr, args...) \
 
248
  INLINE_SYSCALL (name, nr, ##args)
 
249
#endif
 
250
 
 
251
#ifdef SHARED
 
252
# define INTERNAL_VSYSCALL(name, err, nr, args...)                            \
 
253
  ({                                                                          \
 
254
    __label__ out;                                                            \
 
255
    long v_ret;                                                               \
 
256
                                                                              \
 
257
    if (__vdso_##name != NULL)                                                \
 
258
      {                                                                       \
 
259
        register long _x0 asm ("x0");                                         \
 
260
        v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args);       \
 
261
        if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err)                            \
 
262
            || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS)                 \
 
263
          goto out;                                                           \
 
264
      }                                                                       \
 
265
    v_ret = INTERNAL_SYSCALL (name, err, nr, ##args);                         \
 
266
  out:                                                                        \
 
267
    v_ret;                                                                    \
 
268
  })
 
269
#else
 
270
# define INTERNAL_VSYSCALL(name, err, nr, args...) \
 
271
  INTERNAL_SYSCALL (name, err, nr, ##args)
 
272
#endif
 
273
 
 
274
/* List of system calls which are supported as vsyscalls.  */
 
275
#define HAVE_CLOCK_GETRES_VSYSCALL      1
 
276
#define HAVE_CLOCK_GETTIME_VSYSCALL     1
 
277
 
 
278
#define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...)        \
 
279
  ({                                                            \
 
280
    LOAD_ARGS_##nr (args)                                       \
 
281
    asm volatile ("blr %1"                                      \
 
282
                  : "=r" (_x0)                                  \
 
283
                  : "r" (funcptr), ASM_ARGS_##nr                \
 
284
                  : "x30", "memory");                           \
 
285
    (long) _x0;                                                 \
 
286
  })
 
287
 
 
288
 
 
289
/* Define a macro which expands into the inline wrapper code for a system
 
290
   call.  */
 
291
#undef INLINE_SYSCALL
 
292
#define INLINE_SYSCALL(name, nr, args...)                               \
 
293
  ({ unsigned long _sys_result = INTERNAL_SYSCALL (name, , nr, args);   \
 
294
     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_sys_result, ), 0))\
 
295
       {                                                                \
 
296
         __set_errno (INTERNAL_SYSCALL_ERRNO (_sys_result, ));          \
 
297
         _sys_result = (unsigned long) -1;                              \
 
298
       }                                                                \
 
299
     (long) _sys_result; })
 
300
 
 
301
#undef INTERNAL_SYSCALL_DECL
 
302
#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
 
303
 
 
304
#undef INTERNAL_SYSCALL_RAW
 
305
#define INTERNAL_SYSCALL_RAW(name, err, nr, args...)            \
 
306
  ({ unsigned long _sys_result;                                 \
 
307
     {                                                          \
 
308
       LOAD_ARGS_##nr (args)                                    \
 
309
       register long _x8 asm ("x8") = (name);                   \
 
310
       asm volatile ("svc       0       // syscall " # name     \
 
311
                     : "+r" (_x0), "+r" (_x8)                   \
 
312
                     : ASM_ARGS_##nr                            \
 
313
                     : "memory", CLOBBER_ARGS_##nr);            \
 
314
       _sys_result = _x0;                                       \
 
315
     }                                                          \
 
316
     (long) _sys_result; })
 
317
 
 
318
#undef INTERNAL_SYSCALL
 
319
#define INTERNAL_SYSCALL(name, err, nr, args...)                \
 
320
        INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args)
 
321
 
 
322
#undef INTERNAL_SYSCALL_AARCH64
 
323
#define INTERNAL_SYSCALL_AARCH64(name, err, nr, args...)                \
 
324
        INTERNAL_SYSCALL_RAW(__ARM_NR_##name, err, nr, args)
 
325
 
 
326
#undef INTERNAL_SYSCALL_ERROR_P
 
327
#define INTERNAL_SYSCALL_ERROR_P(val, err) \
 
328
  ((unsigned long) (val) >= (unsigned long) -4095)
 
329
 
 
330
#undef INTERNAL_SYSCALL_ERRNO
 
331
#define INTERNAL_SYSCALL_ERRNO(val, err)        (-(val))
 
332
 
 
333
#define CLOBBER_ARGS_0       CLOBBER_ARGS_1
 
334
#define CLOBBER_ARGS_1 "x1", CLOBBER_ARGS_2
 
335
#define CLOBBER_ARGS_2 "x2", CLOBBER_ARGS_3
 
336
#define CLOBBER_ARGS_3 "x3", CLOBBER_ARGS_4
 
337
#define CLOBBER_ARGS_4 "x4", CLOBBER_ARGS_5
 
338
#define CLOBBER_ARGS_5 "x5", CLOBBER_ARGS_6
 
339
#define CLOBBER_ARGS_6 "x6", CLOBBER_ARGS_7
 
340
#define CLOBBER_ARGS_7 \
 
341
  "x7", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18"
 
342
 
 
343
#define LOAD_ARGS_0()                           \
 
344
  register long _x0 asm ("x0");
 
345
 
 
346
#define ASM_ARGS_0
 
347
#define LOAD_ARGS_1(x0)                         \
 
348
  long _x0tmp = (long) (x0);                    \
 
349
  LOAD_ARGS_0 ()                                \
 
350
  _x0 = _x0tmp;
 
351
#define ASM_ARGS_1      "r" (_x0)
 
352
#define LOAD_ARGS_2(x0, x1)                     \
 
353
  long _x1tmp = (long) (x1);                    \
 
354
  LOAD_ARGS_1 (x0)                              \
 
355
  register long _x1 asm ("x1") = _x1tmp;
 
356
#define ASM_ARGS_2      ASM_ARGS_1, "r" (_x1)
 
357
#define LOAD_ARGS_3(x0, x1, x2)                 \
 
358
  long _x2tmp = (long) (x2);                    \
 
359
  LOAD_ARGS_2 (x0, x1)                          \
 
360
  register long _x2 asm ("x2") = _x2tmp;
 
361
#define ASM_ARGS_3      ASM_ARGS_2, "r" (_x2)
 
362
#define LOAD_ARGS_4(x0, x1, x2, x3)             \
 
363
  long _x3tmp = (long) (x3);                    \
 
364
  LOAD_ARGS_3 (x0, x1, x2)                      \
 
365
  register long _x3 asm ("x3") = _x3tmp;
 
366
#define ASM_ARGS_4      ASM_ARGS_3, "r" (_x3)
 
367
#define LOAD_ARGS_5(x0, x1, x2, x3, x4)         \
 
368
  long _x4tmp = (long) (x4);                    \
 
369
  LOAD_ARGS_4 (x0, x1, x2, x3)                  \
 
370
  register long _x4 asm ("x4") = _x4tmp;
 
371
#define ASM_ARGS_5      ASM_ARGS_4, "r" (_x4)
 
372
#define LOAD_ARGS_6(x0, x1, x2, x3, x4, x5)     \
 
373
  long _x5tmp = (long) (x5);                    \
 
374
  LOAD_ARGS_5 (x0, x1, x2, x3, x4)              \
 
375
  register long _x5 asm ("x5") = _x5tmp;
 
376
#define ASM_ARGS_6      ASM_ARGS_5, "r" (_x5)
 
377
#define LOAD_ARGS_7(x0, x1, x2, x3, x4, x5, x6) \
 
378
  long _x6tmp = (long) (x6);                    \
 
379
  LOAD_ARGS_6 (x0, x1, x2, x3, x4, x5)          \
 
380
  register long _x6 asm ("x6") = _x6tmp;
 
381
#define ASM_ARGS_7      ASM_ARGS_6, "r" (_x6)
 
382
 
 
383
#undef INTERNAL_SYSCALL_NCS
 
384
#define INTERNAL_SYSCALL_NCS(number, err, nr, args...)          \
 
385
        INTERNAL_SYSCALL_RAW (number, err, nr, args)
 
386
 
 
387
#endif  /* __ASSEMBLER__ */
 
388
 
 
389
/* Pointer mangling is not yet supported for AArch64.  */
 
390
#define PTR_MANGLE(var) (void) (var)
 
391
#define PTR_DEMANGLE(var) (void) (var)
 
392
 
 
393
#if !defined __NR_pread && defined __NR_pread64
 
394
# define __NR_pread __NR_pread64
 
395
#endif
 
396
 
 
397
#if !defined __NR_pwrite && defined __NR_pwrite64
 
398
# define __NR_pwrite __NR_pwrite64
 
399
#endif
 
400
 
 
401
#endif /* linux/aarch64/sysdep.h */