blob: 7071541247e342e5b3c4bbad59875d452d870972 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* Copyright (C) 2000 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
18
19#include <features.h>
20#define _ERRNO_H
21#include <bits/errno.h>
22#include <sys/syscall.h>
23#include <bits/arm_asm.h>
24
25#if defined __UCLIBC_HAS_LFS__ && defined __NR_mmap2
26
27/* The mmap2 system call takes six arguments, all in registers. */
28.text
29.global mmap64
30.type mmap64,%function
31.align 2
32
33#ifdef __ARM_EABI__
34#if defined(THUMB1_ONLY)
35.thumb_func
36mmap64:
37#ifdef __ARMEB__
38/* Offsets are after pushing 3 words. */
39# define LOW_OFFSET 12 + 8 + 4
40# define HIGH_OFFSET 12 + 8 + 0
41#else
42# define LOW_OFFSET 12 + 8 + 0
43# define HIGH_OFFSET 12 + 8 + 4
44#endif
45 push {r4, r5, r6}
46 ldr r6, [sp, $LOW_OFFSET]
47 ldr r5, [sp, $HIGH_OFFSET]
48 lsl r4, r6, #20 @ check that offset is page-aligned
49 bne .Linval
50 lsr r4, r5, #12 @ check for overflow
51 bne .Linval
52 @ compose page offset
53 lsr r6, r6, #12
54 lsl r5, r5, #20
55 orr r5, r5, r6
56 ldr r4, [sp, #8] @ load fd
57 DO_CALL (mmap2)
58 ldr r1, =0xfffff000
59 cmp r0, r1
60 bcs .Lerror
61 bx lr
62.Linval:
63 ldr r0, =-EINVAL
64 pop {r4, r5, r6}
65.Lerror:
66 push {r3, lr}
67 bl __syscall_error
68 POP_RET
69.pool
70#else /* !THUMB1_ONLY */
71mmap64:
72#ifdef __ARMEB__
73# define LOW_OFFSET 8 + 4
74/* The initial + 4 is for the stack postdecrement. */
75# define HIGH_OFFSET 4 + 8 + 0
76#else
77# define LOW_OFFSET 8 + 0
78# define HIGH_OFFSET 4 + 8 + 4
79#endif
80 ldr ip, [sp, $LOW_OFFSET]
81 str r5, [sp, #-4]!
82 ldr r5, [sp, $HIGH_OFFSET]
83 str r4, [sp, #-4]!
84 movs r4, ip, lsl $20 @ check that offset is page-aligned
85 mov ip, ip, lsr $12
86 IT(t, eq)
87 moveqs r4, r5, lsr $12 @ check for overflow
88 bne .Linval
89 ldr r4, [sp, $8] @ load fd
90 orr r5, ip, r5, lsl $20 @ compose page offset
91 DO_CALL (mmap2)
92 cmn r0, $4096
93 ldmfd sp!, {r4, r5}
94 IT(t, cc)
95#if defined(__USE_BX__)
96 bxcc lr
97#else
98 movcc pc, lr
99#endif
100 b __syscall_error
101.Linval:
102 mov r0, $-EINVAL
103 ldmfd sp!, {r4, r5}
104 b __syscall_error
105#endif
106#else /* !__ARM_EABI__ */
107mmap64:
108 stmfd sp!, {r4, r5, lr}
109 ldr r5, [sp, $16]
110 ldr r4, [sp, $12]
111 movs ip, r5, lsl $20 @ check that offset is page-aligned
112 bne .Linval
113 ldr ip, [sp, $20]
114 mov r5, r5, lsr $12
115 orr r5, r5, ip, lsl $20 @ compose page offset
116 movs ip, ip, lsr $12
117 bne .Linval @ check for overflow
118 mov ip, r0
119 DO_CALL (mmap2)
120 cmn r0, $4096
121 ldmccfd sp!, {r4, r5, pc}
122 cmn r0, $ENOSYS
123 ldmnefd sp!, {r4, r5, lr}
124 bne __error
125 /* The current kernel does not support mmap2. Fall back to plain
126 mmap if the offset is small enough. */
127 ldr r5, [sp, $20]
128 mov r0, ip @ first arg was clobbered
129 teq r5, $0
130 ldmeqfd sp!, {r4, r5, lr}
131 beq HIDDEN_JUMPTARGET(mmap)
132.Linval:
133 mov r0, $-EINVAL
134 ldmfd sp!, {r4, r5, lr}
135 b __error
136
137__error:
138 b __syscall_error
139#endif
140.size mmap64,.-mmap64
141
142#endif