]> git.saurik.com Git - apple/xnu.git/blob - bsd/dev/arm/munge.c
xnu-6153.61.1.tar.gz
[apple/xnu.git] / bsd / dev / arm / munge.c
1 /*
2 * Coyright (c) 2005-2015 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 /*
30 * For arm32 ABI where 64-bit types are aligned to even registers and
31 * 64-bits on stack, we need to unpack registers differently. So
32 * we use the mungers for that. Currently this is just ARMv7k.
33 *
34 * Since arm32 has no need for munging otherwise, we don't include
35 * any of this for other arm32 ABIs
36 */
37 #if __arm__ && (__BIGGEST_ALIGNMENT__ > 4)
38
39 #include <sys/munge.h>
40 #include <sys/param.h>
41 #include <mach/thread_status.h>
42 #include <libkern/libkern.h>
43 #include <stdint.h>
44
45
46 /*
47 * Userspace args are in r0-r6, then r8, then stack unless this is an
48 * indirect call in which case the syscall number is in r0 then args
49 * are in registers r1-r6, then r8, then stack. This is for mach and
50 * BSD style syscalls.
51 */
52
53
54 #define SS_TO_STYLE(ss) ((ss->r[12] != 0) ? kDirect : kIndirect)
55 #define REGS_TO_STYLE(regs) (SS_TO_STYLE(((const arm_saved_state_t *)regs)))
56
57 typedef enum {
58 kIndirect = 0,
59 kDirect
60 } style_t;
61
62 #define DECLARE_AND_CAST(regs, args, ss, uu_args) const arm_saved_state_t *ss = (const arm_saved_state_t *)regs; \
63 uint32_t *uu_args = (uint32_t *)args;
64
65 /*
66 * We start 32 bytes after sp since 4 registers are pushed onto the stack
67 * in the userspace syscall handler, and the first 4 stack argumnets are moved
68 * into registers already
69 */
70 #define ARG_SP_BYTE_OFFSET 32
71
72
73 /*
74 * Marshal in arguments from userspace where no padding exists
75 */
76
77 static int
78 marshal_no_pad(const arm_saved_state_t *ss, uint32_t *args, const uint32_t word_count)
79 {
80 int error = 0;
81 /* init assuming kDirect style */
82 uint32_t copy_count, contiguous_reg_count = 7, contiguous_reg_start = 0;
83 style_t style = SS_TO_STYLE(ss);
84
85 if (style == kIndirect) {
86 contiguous_reg_count--;
87 contiguous_reg_start++;
88 }
89
90 /* r0 through r6 */
91 copy_count = MIN(word_count, contiguous_reg_count);
92 memcpy(args, &(ss->r[contiguous_reg_start]), copy_count * sizeof(uint32_t));
93 args += copy_count;
94
95 if (word_count > copy_count) {
96 /* r8 */
97 *args = ss->r[8];
98 args++;
99 copy_count++;
100
101 /* stack */
102 if (word_count > copy_count) {
103 error = copyin(ss->sp + ARG_SP_BYTE_OFFSET,
104 args, (word_count - copy_count) * sizeof(uint32_t));
105 if (error) {
106 return error;
107 }
108 }
109 }
110 return error;
111 }
112
113 /*
114 * Define mungers to marshal userspace data into argument structs
115 */
116
117 int
118 munge_w(const void *regs, void *args)
119 {
120 return marshal_no_pad(regs, args, 1);
121 }
122
123 int
124 munge_ww(const void *regs, void *args)
125 {
126 return marshal_no_pad(regs, args, 2);
127 }
128
129 int
130 munge_www(const void *regs, void *args)
131 {
132 return marshal_no_pad(regs, args, 3);
133 }
134
135 int
136 munge_wwww(const void *regs, void *args)
137 {
138 return marshal_no_pad(regs, args, 4);
139 }
140
141 int
142 munge_wwwww(const void *regs, void *args)
143 {
144 return marshal_no_pad(regs, args, 5);
145 }
146
147 int
148 munge_wwwwww(const void *regs, void *args)
149 {
150 return marshal_no_pad(regs, args, 6);
151 }
152
153 int
154 munge_wwwwwww(const void *regs, void *args)
155 {
156 return marshal_no_pad(regs, args, 7);
157 }
158
159 int
160 munge_wwwwwwww(const void *regs, void *args)
161 {
162 return marshal_no_pad(regs, args, 8);
163 }
164
165 int
166 munge_wwl(const void *regs, void *args)
167 {
168 if (REGS_TO_STYLE(regs) == kDirect) {
169 return marshal_no_pad(regs, args, 4);
170 } else {
171 DECLARE_AND_CAST(regs, args, ss, uu_args);
172
173 uu_args[0] = ss->r[1]; // w
174 uu_args[1] = ss->r[2]; // w
175 uu_args[2] = ss->r[4]; // l (longs are aligned to even registers for armv7k, so skip r3)
176 uu_args[3] = ss->r[5]; //
177 return 0;
178 }
179 }
180
181 int
182 munge_wwlw(const void *regs, void *args)
183 {
184 if (REGS_TO_STYLE(regs) == kDirect) {
185 return marshal_no_pad(regs, args, 5);
186 } else {
187 DECLARE_AND_CAST(regs, args, ss, uu_args);
188
189 int error = munge_wwl(regs, args); // wwl
190 uu_args[4] = ss->r[6]; // w
191 return error;
192 }
193 }
194
195 int
196 munge_wwlww(const void *regs, void *args)
197 {
198 if (REGS_TO_STYLE(regs) == kDirect) {
199 // the long-long here is aligned on an even register
200 // so there shouldn't be any padding
201 return marshal_no_pad(regs, args, 6);
202 } else {
203 DECLARE_AND_CAST(regs, args, ss, uu_args);
204
205 int error = munge_wwlw(regs, args); // wwlw
206 uu_args[5] = ss->r[8]; // w
207 return error;
208 }
209 }
210
211 int
212 munge_wwlll(const void *regs, void *args)
213 {
214 if (REGS_TO_STYLE(regs) == kDirect) {
215 return marshal_no_pad(regs, args, 8);
216 } else {
217 DECLARE_AND_CAST(regs, args, ss, uu_args);
218
219 int error = munge_wwl(regs, args); // wwl
220 if (error) {
221 return error;
222 }
223 uu_args[4] = ss->r[6]; // l
224 uu_args[5] = ss->r[8]; //
225 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
226 &(uu_args[6]), 2 * sizeof(uint32_t));
227 }
228 }
229
230 int
231 munge_wwllww(const void *regs, void *args)
232 {
233 return munge_wwlll(regs, args);
234 }
235
236 int
237 munge_wl(const void *regs, void *args)
238 {
239 if (REGS_TO_STYLE(regs) == kDirect) {
240 memcpy(args, regs, 4 * sizeof(uint32_t));
241 } else {
242 DECLARE_AND_CAST(regs, args, ss, uu_args);
243
244 uu_args[0] = ss->r[1]; // w
245 uu_args[2] = ss->r[2]; // l
246 uu_args[3] = ss->r[3]; //
247 }
248 return 0;
249 }
250
251 int
252 munge_wlw(const void *regs, void *args)
253 {
254 if (REGS_TO_STYLE(regs) == kDirect) {
255 memcpy(args, regs, 5 * sizeof(uint32_t));
256 } else {
257 DECLARE_AND_CAST(regs, args, ss, uu_args);
258
259 uu_args[0] = ss->r[1]; // w
260 uu_args[2] = ss->r[2]; // l
261 uu_args[3] = ss->r[3]; //
262 uu_args[4] = ss->r[4]; // w
263 }
264 return 0;
265 }
266
267 int
268 munge_wlww(const void *regs, void *args)
269 {
270 if (REGS_TO_STYLE(regs) == kDirect) {
271 memcpy(args, regs, 6 * sizeof(uint32_t));
272 } else {
273 DECLARE_AND_CAST(regs, args, ss, uu_args);
274
275 uu_args[0] = ss->r[1]; // w
276 uu_args[2] = ss->r[2]; // l
277 uu_args[3] = ss->r[3]; //
278 uu_args[4] = ss->r[4]; // w
279 uu_args[5] = ss->r[5]; // w
280 }
281 return 0;
282 }
283
284 int
285 munge_wlwwwll(const void *regs, void *args)
286 {
287 DECLARE_AND_CAST(regs, args, ss, uu_args);
288
289 if (REGS_TO_STYLE(regs) == kDirect) {
290 memcpy(args, regs, 7 * sizeof(uint32_t)); // wlwww
291 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
292 uu_args + 8, 4 * sizeof(uint32_t));
293 } else {
294 uu_args[0] = ss->r[1]; // w
295 uu_args[2] = ss->r[2]; // l
296 uu_args[3] = ss->r[3]; //
297 uu_args[4] = ss->r[4]; // w
298 uu_args[5] = ss->r[5]; // w
299 uu_args[6] = ss->r[6]; // w
300 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
301 uu_args + 8, 4 * sizeof(uint32_t));
302 }
303 }
304
305 int
306 munge_wlwwwllw(const void *regs, void *args)
307 {
308 DECLARE_AND_CAST(regs, args, ss, uu_args);
309
310 if (REGS_TO_STYLE(regs) == kDirect) {
311 memcpy(args, regs, 7 * sizeof(uint32_t)); // wlwww
312 return copyin(ss->sp + ARG_SP_BYTE_OFFSET,
313 uu_args + 8, 5 * sizeof(uint32_t)); // ll
314 } else {
315 uu_args[0] = ss->r[1]; // w
316 uu_args[2] = ss->r[2]; // l
317 uu_args[3] = ss->r[3]; //
318 uu_args[4] = ss->r[4]; // w
319 uu_args[5] = ss->r[5]; // w
320 uu_args[6] = ss->r[6]; // w
321 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // llw
322 uu_args + 8, 5 * sizeof(uint32_t));
323 }
324 }
325
326 int
327 munge_wlwwlwlw(const void *regs, void *args)
328 {
329 DECLARE_AND_CAST(regs, args, ss, uu_args);
330
331 if (REGS_TO_STYLE(regs) == kDirect) {
332 uu_args[0] = ss->r[0]; // w
333 } else {
334 uu_args[0] = ss->r[1]; // w
335 }
336 uu_args[2] = ss->r[2]; // l
337 uu_args[3] = ss->r[3]; //
338 uu_args[4] = ss->r[4]; // w
339 uu_args[5] = ss->r[5]; // w
340 uu_args[6] = ss->r[6]; // l
341 uu_args[7] = ss->r[8]; //
342 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // wlw
343 uu_args + 8, 5 * sizeof(uint32_t));
344 }
345
346 int
347 munge_wll(const void *regs, void *args)
348 {
349 if (REGS_TO_STYLE(regs) == kDirect) {
350 memcpy(args, regs, 6 * sizeof(uint32_t));
351 } else {
352 DECLARE_AND_CAST(regs, args, ss, uu_args);
353
354 uu_args[0] = ss->r[1]; // w
355 uu_args[2] = ss->r[2]; // l
356 uu_args[3] = ss->r[3]; //
357 uu_args[4] = ss->r[4]; // l
358 uu_args[5] = ss->r[5]; //
359 }
360 return 0;
361 }
362
363 int
364 munge_wlll(const void *regs, void *args)
365 {
366 DECLARE_AND_CAST(regs, args, ss, uu_args);
367
368 int error = munge_wll(regs, args); // wll
369 uu_args[6] = ss->r[6]; // l
370 uu_args[7] = ss->r[8]; //
371 return error;
372 }
373
374 int
375 munge_wllll(const void *regs, void *args)
376 {
377 DECLARE_AND_CAST(regs, args, ss, uu_args);
378
379 munge_wlll(regs, args); // wlll
380 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
381 uu_args + 8, 2 * sizeof(uint32_t));
382 }
383
384 int
385 munge_wllww(const void *regs, void *args)
386 {
387 return munge_wlll(regs, args);
388 }
389
390 int
391 munge_wllwwll(const void *regs, void *args)
392 {
393 DECLARE_AND_CAST(regs, args, ss, uu_args);
394
395 int error = munge_wlll(regs, args); // wllww
396 if (error) {
397 return error;
398 }
399 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
400 uu_args + 8, 4 * sizeof(uint32_t));
401 }
402
403 int
404 munge_wwwlw(const void *regs, void *args)
405 {
406 if (REGS_TO_STYLE(regs) == kDirect) {
407 memcpy(args, regs, 7 * sizeof(uint32_t));
408 } else {
409 DECLARE_AND_CAST(regs, args, ss, uu_args);
410
411 uu_args[0] = ss->r[1]; // w
412 uu_args[1] = ss->r[2]; // w
413 uu_args[2] = ss->r[3]; // w
414 uu_args[4] = ss->r[4]; // l
415 uu_args[5] = ss->r[5]; //
416 uu_args[6] = ss->r[6]; // w
417 }
418 return 0;
419 }
420
421 int
422 munge_wwwlww(const void *regs, void *args)
423 {
424 if (REGS_TO_STYLE(regs) == kDirect) {
425 return munge_wlll(regs, args);
426 } else {
427 DECLARE_AND_CAST(regs, args, ss, uu_args);
428
429 uu_args[0] = ss->r[1]; // w
430 uu_args[1] = ss->r[2]; // w
431 uu_args[2] = ss->r[3]; // w
432 uu_args[4] = ss->r[4]; // l
433 uu_args[5] = ss->r[5]; //
434 uu_args[6] = ss->r[6]; // w
435 uu_args[7] = ss->r[8]; // w
436 return 0;
437 }
438 }
439
440 int
441 munge_wwwl(const void *regs, void *args)
442 {
443 if (REGS_TO_STYLE(regs) == kDirect) {
444 return munge_wll(regs, args);
445 } else {
446 DECLARE_AND_CAST(regs, args, ss, uu_args);
447
448 uu_args[0] = ss->r[1]; // w
449 uu_args[1] = ss->r[2]; // w
450 uu_args[2] = ss->r[3]; // w
451 uu_args[4] = ss->r[4]; // l
452 uu_args[5] = ss->r[5]; //
453 return 0;
454 }
455 }
456
457 int
458 munge_wwwwl(const void *regs, void *args)
459 {
460 if (REGS_TO_STYLE(regs) == kDirect) {
461 return marshal_no_pad(regs, args, 6);
462 } else {
463 DECLARE_AND_CAST(regs, args, ss, uu_args);
464
465 uu_args[0] = ss->r[1]; // w
466 uu_args[1] = ss->r[2]; // w
467 uu_args[2] = ss->r[3]; // w
468 uu_args[3] = ss->r[4]; // w
469 uu_args[4] = ss->r[6]; // l
470 uu_args[5] = ss->r[8]; //
471 return 0;
472 }
473 }
474
475 int
476 munge_wwwwlw(const void *regs, void *args)
477 {
478 if (REGS_TO_STYLE(regs) == kDirect) {
479 return marshal_no_pad(regs, args, 7);
480 } else {
481 DECLARE_AND_CAST(regs, args, ss, uu_args);
482
483 int error = munge_wwwwl(regs, args); // wwwwl
484 if (error) {
485 return error;
486 }
487 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // w
488 uu_args + 6, sizeof(uint32_t));
489 }
490 }
491
492 int
493 munge_wwwwwl(const void *regs, void *args)
494 {
495 if (REGS_TO_STYLE(regs) == kDirect) {
496 return munge_wlll(regs, args);
497 } else {
498 DECLARE_AND_CAST(regs, args, ss, uu_args);
499
500 uu_args[0] = ss->r[1]; // w
501 uu_args[1] = ss->r[2]; // w
502 uu_args[2] = ss->r[3]; // w
503 uu_args[3] = ss->r[4]; // w
504 uu_args[4] = ss->r[5]; // w
505 uu_args[6] = ss->r[6]; // l
506 uu_args[7] = ss->r[8]; //
507 return 0;
508 }
509 }
510
511 int
512 munge_wwwwwlww(const void *regs, void *args)
513 {
514 if (REGS_TO_STYLE(regs) == kDirect) {
515 return munge_wllll(regs, args);
516 } else {
517 DECLARE_AND_CAST(regs, args, ss, uu_args);
518
519 int error = munge_wwwwwl(regs, args); // wwwwwl
520 if (error) {
521 return error;
522 }
523 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ww
524 uu_args + 8, 2 * sizeof(uint32_t));
525 }
526 }
527
528 int
529 munge_wwwwwllw(const void *regs, void *args)
530 {
531 DECLARE_AND_CAST(regs, args, ss, uu_args);
532
533 int error = munge_wwwwwl(regs, args); // wwwwwl
534 if (error) {
535 return error;
536 }
537 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lw
538 uu_args + 8, 3 * sizeof(uint32_t));
539 }
540
541 int
542 munge_wwwwwlll(const void *regs, void *args)
543 {
544 DECLARE_AND_CAST(regs, args, ss, uu_args);
545 int error;
546
547 if (REGS_TO_STYLE(regs) == kDirect) {
548 error = munge_wlll(regs, args); // wlll
549 if (error) {
550 return error;
551 }
552 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
553 uu_args + 8, 4 * sizeof(uint32_t));
554 } else {
555 error = munge_wwwwwl(regs, args); // wwwwwl
556 if (error) {
557 return error;
558 }
559 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
560 uu_args + 8, 4 * sizeof(uint32_t));
561 }
562 }
563
564 int
565 munge_wwwwwwl(const void *regs, void *args)
566 {
567 munge_wwlll(regs, args);
568
569 if (REGS_TO_STYLE(regs) == kDirect) {
570 return marshal_no_pad(regs, args, 8);
571 } else {
572 DECLARE_AND_CAST(regs, args, ss, uu_args);
573
574 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
575 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
576 &(uu_args[6]), 2 * sizeof(uint32_t));
577 }
578 }
579
580 int
581 munge_wwwwwwlw(const void *regs, void *args)
582 {
583 if (REGS_TO_STYLE(regs) == kDirect) {
584 return marshal_no_pad(regs, args, 9);
585 } else {
586 DECLARE_AND_CAST(regs, args, ss, uu_args);
587
588 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
589 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lw
590 &(uu_args[6]), 3 * sizeof(uint32_t));
591 }
592 }
593
594 int
595 munge_wwwwwwll(const void *regs, void *args)
596 {
597 if (REGS_TO_STYLE(regs) == kDirect) {
598 return marshal_no_pad(regs, args, 10);
599 } else {
600 DECLARE_AND_CAST(regs, args, ss, uu_args);
601
602 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
603 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
604 &(uu_args[6]), 4 * sizeof(uint32_t));
605 }
606 }
607
608 int
609 munge_wsw(const void *regs, void *args)
610 {
611 return munge_wlw(regs, args);
612 }
613
614 int
615 munge_wws(const void *regs, void *args)
616 {
617 return munge_wwl(regs, args);
618 }
619
620 int
621 munge_wwws(const void *regs, void *args)
622 {
623 return munge_wwwl(regs, args);
624 }
625
626 int
627 munge_wwwsw(const void *regs, void *args)
628 {
629 return munge_wwwlw(regs, args);
630 }
631
632 int
633 munge_llllll(const void *regs, void *args)
634 {
635 if (REGS_TO_STYLE(regs) == kDirect) {
636 return marshal_no_pad(regs, args, 12);
637 } else {
638 DECLARE_AND_CAST(regs, args, ss, uu_args);
639
640 uu_args[0] = ss->r[2]; // l
641 uu_args[1] = ss->r[3]; //
642 uu_args[2] = ss->r[4]; // l
643 uu_args[3] = ss->r[5]; //
644 uu_args[4] = ss->r[6]; // l
645 uu_args[5] = ss->r[8]; //
646 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lll
647 uu_args + 6, 6 * sizeof(uint32_t));
648 }
649 }
650
651 int
652 munge_ll(const void *regs, void *args)
653 {
654 if (REGS_TO_STYLE(regs) == kDirect) {
655 return marshal_no_pad(regs, args, 4);
656 } else {
657 memcpy(args, (const uint32_t*)regs + 2, 4 * sizeof(uint32_t));
658 }
659 return 0;
660 }
661
662 int
663 munge_l(const void *regs, void *args)
664 {
665 if (REGS_TO_STYLE(regs) == kDirect) {
666 return marshal_no_pad(regs, args, 2);
667 } else {
668 memcpy(args, (const uint32_t*)regs + 2, 2 * sizeof(uint32_t));
669 }
670 return 0;
671 }
672
673 int
674 munge_lw(const void *regs, void *args)
675 {
676 if (REGS_TO_STYLE(regs) == kDirect) {
677 return marshal_no_pad(regs, args, 3);
678 } else {
679 memcpy(args, (const uint32_t*)regs + 2, 3 * sizeof(uint32_t));
680 }
681 return 0;
682 }
683
684 int
685 munge_lwww(const void *regs, void *args)
686 {
687 if (REGS_TO_STYLE(regs) == kDirect) {
688 return marshal_no_pad(regs, args, 5);
689 } else {
690 memcpy(args, (const uint32_t*)regs + 2, 5 * sizeof(uint32_t));
691 }
692 return 0;
693 }
694
695 int
696 munge_lwwwwwww(const void *regs, void *args)
697 {
698 if (REGS_TO_STYLE(regs) == kDirect) {
699 return marshal_no_pad(regs, args, 9);
700 } else {
701 DECLARE_AND_CAST(regs, args, ss, uu_args);
702
703 uu_args[0] = ss->r[2]; // l
704 uu_args[1] = ss->r[3]; //
705 uu_args[2] = ss->r[4]; // w
706 uu_args[3] = ss->r[5]; // w
707 uu_args[4] = ss->r[6]; // w
708 uu_args[5] = ss->r[8]; // w
709 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // www
710 uu_args + 6, 3 * sizeof(uint32_t));
711 }
712 }
713
714 int
715 munge_wwlwww(const void *regs, void *args)
716 {
717 if (REGS_TO_STYLE(regs) == kDirect) {
718 return marshal_no_pad(regs, args, 7);
719 } else {
720 DECLARE_AND_CAST(regs, args, ss, uu_args);
721
722 uu_args[0] = ss->r[1]; // w
723 uu_args[1] = ss->r[2]; // w
724 uu_args[2] = ss->r[4]; // l
725 uu_args[3] = ss->r[5]; //
726 uu_args[4] = ss->r[6]; // w
727 uu_args[5] = ss->r[8]; // w
728 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // w
729 uu_args + 6, sizeof(uint32_t));
730 }
731 }
732
733 int
734 munge_wlwwwl(const void *regs, void *args)
735 {
736 DECLARE_AND_CAST(regs, args, ss, uu_args);
737
738 if (REGS_TO_STYLE(regs) == kDirect) {
739 memcpy(args, regs, 7 * sizeof(uint32_t)); // wlwww
740 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
741 uu_args + 8, 2 * sizeof(uint32_t));
742 } else {
743 uu_args[0] = ss->r[1]; // w
744 uu_args[2] = ss->r[2]; // l
745 uu_args[3] = ss->r[3]; //
746 uu_args[4] = ss->r[4]; // w
747 uu_args[5] = ss->r[5]; // w
748 uu_args[6] = ss->r[6]; // w
749 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
750 uu_args + 8, 2 * sizeof(uint32_t));
751 }
752 }
753
754 int
755 munge_wwlwwwl(const void *regs, void *args)
756 {
757 DECLARE_AND_CAST(regs, args, ss, uu_args);
758
759 if (REGS_TO_STYLE(regs) == kDirect) {
760 memcpy(args, regs, 7 * sizeof(uint32_t)); // wwlwww
761 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
762 uu_args + 8, 2 * sizeof(uint32_t));
763 } else {
764 uu_args[0] = ss->r[1]; // w
765 uu_args[1] = ss->r[2]; // w
766 uu_args[2] = ss->r[4]; // l
767 uu_args[3] = ss->r[5]; //
768 uu_args[4] = ss->r[6]; // w
769 uu_args[5] = ss->r[8]; // w
770 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // wl
771 uu_args + 6, 4 * sizeof(uint32_t));
772 }
773 }
774
775 #endif // __arm__ && (__BIGGEST_ALIGNMENT__ > 4)