]>
git.saurik.com Git - apple/xnu.git/blob - bsd/dev/arm/munge.c
2 * Coyright (c) 2005-2015 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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.
34 * Since arm32 has no need for munging otherwise, we don't include
35 * any of this for other arm32 ABIs
37 #if __arm__ && (__BIGGEST_ALIGNMENT__ > 4)
39 #include <sys/munge.h>
40 #include <sys/param.h>
41 #include <mach/thread_status.h>
42 #include <libkern/libkern.h>
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
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)))
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;
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
70 #define ARG_SP_BYTE_OFFSET 32
74 * Marshal in arguments from userspace where no padding exists
78 marshal_no_pad(const arm_saved_state_t
*ss
, uint32_t *args
, const uint32_t word_count
)
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
);
85 if (style
== kIndirect
) {
86 contiguous_reg_count
--;
87 contiguous_reg_start
++;
91 copy_count
= MIN(word_count
, contiguous_reg_count
);
92 memcpy(args
, &(ss
->r
[contiguous_reg_start
]), copy_count
* sizeof(uint32_t));
95 if (word_count
> copy_count
) {
102 if (word_count
> copy_count
) {
103 error
= copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
,
104 args
, (word_count
- copy_count
) * sizeof(uint32_t));
114 * Define mungers to marshal userspace data into argument structs
118 munge_w(const void *regs
, void *args
)
120 return marshal_no_pad(regs
, args
, 1);
124 munge_ww(const void *regs
, void *args
)
126 return marshal_no_pad(regs
, args
, 2);
130 munge_www(const void *regs
, void *args
)
132 return marshal_no_pad(regs
, args
, 3);
136 munge_wwww(const void *regs
, void *args
)
138 return marshal_no_pad(regs
, args
, 4);
142 munge_wwwww(const void *regs
, void *args
)
144 return marshal_no_pad(regs
, args
, 5);
148 munge_wwwwww(const void *regs
, void *args
)
150 return marshal_no_pad(regs
, args
, 6);
154 munge_wwwwwww(const void *regs
, void *args
)
156 return marshal_no_pad(regs
, args
, 7);
160 munge_wwwwwwww(const void *regs
, void *args
)
162 return marshal_no_pad(regs
, args
, 8);
166 munge_wwl(const void *regs
, void *args
)
168 if (REGS_TO_STYLE(regs
) == kDirect
) {
169 return marshal_no_pad(regs
, args
, 4);
171 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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]; //
182 munge_wwlw(const void *regs
, void *args
)
184 if (REGS_TO_STYLE(regs
) == kDirect
) {
185 return marshal_no_pad(regs
, args
, 5);
187 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
189 int error
= munge_wwl(regs
, args
); // wwl
190 uu_args
[4] = ss
->r
[6]; // w
196 munge_wwlww(const void *regs
, void *args
)
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);
203 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
205 int error
= munge_wwlw(regs
, args
); // wwlw
206 uu_args
[5] = ss
->r
[8]; // w
212 munge_wwlll(const void *regs
, void *args
)
214 if (REGS_TO_STYLE(regs
) == kDirect
) {
215 return marshal_no_pad(regs
, args
, 8);
217 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
219 int error
= munge_wwl(regs
, args
); // wwl
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));
231 munge_wwllww(const void *regs
, void *args
)
233 return munge_wwlll(regs
, args
);
237 munge_wl(const void *regs
, void *args
)
239 if (REGS_TO_STYLE(regs
) == kDirect
) {
240 memcpy(args
, regs
, 4 * sizeof(uint32_t));
242 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
244 uu_args
[0] = ss
->r
[1]; // w
245 uu_args
[2] = ss
->r
[2]; // l
246 uu_args
[3] = ss
->r
[3]; //
252 munge_wlw(const void *regs
, void *args
)
254 if (REGS_TO_STYLE(regs
) == kDirect
) {
255 memcpy(args
, regs
, 5 * sizeof(uint32_t));
257 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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
268 munge_wlww(const void *regs
, void *args
)
270 if (REGS_TO_STYLE(regs
) == kDirect
) {
271 memcpy(args
, regs
, 6 * sizeof(uint32_t));
273 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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
285 munge_wlwwwll(const void *regs
, void *args
)
287 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
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));
306 munge_wlwwwllw(const void *regs
, void *args
)
308 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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
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));
327 munge_wlwwlwlw(const void *regs
, void *args
)
329 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
331 if (REGS_TO_STYLE(regs
) == kDirect
) {
332 uu_args
[0] = ss
->r
[0]; // w
334 uu_args
[0] = ss
->r
[1]; // w
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));
347 munge_wll(const void *regs
, void *args
)
349 if (REGS_TO_STYLE(regs
) == kDirect
) {
350 memcpy(args
, regs
, 6 * sizeof(uint32_t));
352 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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]; //
364 munge_wlll(const void *regs
, void *args
)
366 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
368 int error
= munge_wll(regs
, args
); // wll
369 uu_args
[6] = ss
->r
[6]; // l
370 uu_args
[7] = ss
->r
[8]; //
375 munge_wllll(const void *regs
, void *args
)
377 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
379 munge_wlll(regs
, args
); // wlll
380 return copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
, // l
381 uu_args
+ 8, 2 * sizeof(uint32_t));
385 munge_wllww(const void *regs
, void *args
)
387 return munge_wlll(regs
, args
);
391 munge_wllwwll(const void *regs
, void *args
)
393 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
395 int error
= munge_wlll(regs
, args
); // wllww
399 return copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
, // ll
400 uu_args
+ 8, 4 * sizeof(uint32_t));
404 munge_wwwlw(const void *regs
, void *args
)
406 if (REGS_TO_STYLE(regs
) == kDirect
) {
407 memcpy(args
, regs
, 7 * sizeof(uint32_t));
409 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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
422 munge_wwwlww(const void *regs
, void *args
)
424 if (REGS_TO_STYLE(regs
) == kDirect
) {
425 return munge_wlll(regs
, args
);
427 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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
441 munge_wwwl(const void *regs
, void *args
)
443 if (REGS_TO_STYLE(regs
) == kDirect
) {
444 return munge_wll(regs
, args
);
446 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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]; //
458 munge_wwwwl(const void *regs
, void *args
)
460 if (REGS_TO_STYLE(regs
) == kDirect
) {
461 return marshal_no_pad(regs
, args
, 6);
463 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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]; //
476 munge_wwwwlw(const void *regs
, void *args
)
478 if (REGS_TO_STYLE(regs
) == kDirect
) {
479 return marshal_no_pad(regs
, args
, 7);
481 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
483 int error
= munge_wwwwl(regs
, args
); // wwwwl
487 return copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
, // w
488 uu_args
+ 6, sizeof(uint32_t));
493 munge_wwwwwl(const void *regs
, void *args
)
495 if (REGS_TO_STYLE(regs
) == kDirect
) {
496 return munge_wlll(regs
, args
);
498 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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]; //
512 munge_wwwwwlww(const void *regs
, void *args
)
514 if (REGS_TO_STYLE(regs
) == kDirect
) {
515 return munge_wllll(regs
, args
);
517 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
519 int error
= munge_wwwwwl(regs
, args
); // wwwwwl
523 return copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
, // ww
524 uu_args
+ 8, 2 * sizeof(uint32_t));
529 munge_wwwwwllw(const void *regs
, void *args
)
531 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
533 int error
= munge_wwwwwl(regs
, args
); // wwwwwl
537 return copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
, // lw
538 uu_args
+ 8, 3 * sizeof(uint32_t));
542 munge_wwwwwlll(const void *regs
, void *args
)
544 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
547 if (REGS_TO_STYLE(regs
) == kDirect
) {
548 error
= munge_wlll(regs
, args
); // wlll
552 return copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
, // ll
553 uu_args
+ 8, 4 * sizeof(uint32_t));
555 error
= munge_wwwwwl(regs
, args
); // wwwwwl
559 return copyin(ss
->sp
+ ARG_SP_BYTE_OFFSET
, // ll
560 uu_args
+ 8, 4 * sizeof(uint32_t));
565 munge_wwwwwwl(const void *regs
, void *args
)
567 munge_wwlll(regs
, args
);
569 if (REGS_TO_STYLE(regs
) == kDirect
) {
570 return marshal_no_pad(regs
, args
, 8);
572 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
581 munge_wwwwwwlw(const void *regs
, void *args
)
583 if (REGS_TO_STYLE(regs
) == kDirect
) {
584 return marshal_no_pad(regs
, args
, 9);
586 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
595 munge_wwwwwwll(const void *regs
, void *args
)
597 if (REGS_TO_STYLE(regs
) == kDirect
) {
598 return marshal_no_pad(regs
, args
, 10);
600 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
609 munge_wsw(const void *regs
, void *args
)
611 return munge_wlw(regs
, args
);
615 munge_wws(const void *regs
, void *args
)
617 return munge_wwl(regs
, args
);
621 munge_wwws(const void *regs
, void *args
)
623 return munge_wwwl(regs
, args
);
627 munge_wwwsw(const void *regs
, void *args
)
629 return munge_wwwlw(regs
, args
);
633 munge_llllll(const void *regs
, void *args
)
635 if (REGS_TO_STYLE(regs
) == kDirect
) {
636 return marshal_no_pad(regs
, args
, 12);
638 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
652 munge_ll(const void *regs
, void *args
)
654 if (REGS_TO_STYLE(regs
) == kDirect
) {
655 return marshal_no_pad(regs
, args
, 4);
657 memcpy(args
, (const uint32_t*)regs
+ 2, 4 * sizeof(uint32_t));
663 munge_l(const void *regs
, void *args
)
665 if (REGS_TO_STYLE(regs
) == kDirect
) {
666 return marshal_no_pad(regs
, args
, 2);
668 memcpy(args
, (const uint32_t*)regs
+ 2, 2 * sizeof(uint32_t));
674 munge_lw(const void *regs
, void *args
)
676 if (REGS_TO_STYLE(regs
) == kDirect
) {
677 return marshal_no_pad(regs
, args
, 3);
679 memcpy(args
, (const uint32_t*)regs
+ 2, 3 * sizeof(uint32_t));
685 munge_lwww(const void *regs
, void *args
)
687 if (REGS_TO_STYLE(regs
) == kDirect
) {
688 return marshal_no_pad(regs
, args
, 5);
690 memcpy(args
, (const uint32_t*)regs
+ 2, 5 * sizeof(uint32_t));
696 munge_lwwwwwww(const void *regs
, void *args
)
698 if (REGS_TO_STYLE(regs
) == kDirect
) {
699 return marshal_no_pad(regs
, args
, 9);
701 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
715 munge_wwlwww(const void *regs
, void *args
)
717 if (REGS_TO_STYLE(regs
) == kDirect
) {
718 return marshal_no_pad(regs
, args
, 7);
720 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
734 munge_wlwwwl(const void *regs
, void *args
)
736 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
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));
755 munge_wwlwwwl(const void *regs
, void *args
)
757 DECLARE_AND_CAST(regs
, args
, ss
, uu_args
);
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));
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));
775 #endif // __arm__ && (__BIGGEST_ALIGNMENT__ > 4)