]> git.saurik.com Git - apple/xnu.git/blob - bsd/dev/arm/munge.c
xnu-4570.1.46.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 return error;
110 }
111
112 /*
113 * Define mungers to marshal userspace data into argument structs
114 */
115
116 int
117 munge_w(const void *regs, void *args)
118 {
119 return marshal_no_pad(regs, args, 1);
120 }
121
122 int
123 munge_ww(const void *regs, void *args)
124 {
125 return marshal_no_pad(regs, args, 2);
126 }
127
128 int
129 munge_www(const void *regs, void *args)
130 {
131 return marshal_no_pad(regs, args, 3);
132 }
133
134 int
135 munge_wwww(const void *regs, void *args)
136 {
137 return marshal_no_pad(regs, args, 4);
138 }
139
140 int
141 munge_wwwww(const void *regs, void *args)
142 {
143 return marshal_no_pad(regs, args, 5);
144 }
145
146 int
147 munge_wwwwww(const void *regs, void *args)
148 {
149 return marshal_no_pad(regs, args, 6);
150 }
151
152 int
153 munge_wwwwwww(const void *regs, void *args)
154 {
155 return marshal_no_pad(regs, args, 7);
156 }
157
158 int
159 munge_wwwwwwww(const void *regs, void *args)
160 {
161 return marshal_no_pad(regs, args, 8);
162 }
163
164 int
165 munge_wwl(const void *regs, void *args)
166 {
167 if (REGS_TO_STYLE(regs) == kDirect)
168 return marshal_no_pad(regs, args, 3);
169 else {
170 DECLARE_AND_CAST(regs, args, ss, uu_args);
171
172 uu_args[0] = ss->r[1]; // w
173 uu_args[1] = ss->r[2]; // w
174 uu_args[2] = ss->r[4]; // l (longs are aligned to even registers for armv7k, so skip r3)
175 uu_args[3] = ss->r[5]; //
176 return 0;
177 }
178 }
179
180 int
181 munge_wwlw(const void *regs, void *args)
182 {
183 if (REGS_TO_STYLE(regs) == kDirect)
184 return marshal_no_pad(regs, args, 5);
185 else {
186 DECLARE_AND_CAST(regs, args, ss, uu_args);
187
188 int error = munge_wwl(regs, args); // wwl
189 uu_args[4] = ss->r[6]; // w
190 return error;
191 }
192 }
193
194 int
195 munge_wwlww(const void *regs, void *args)
196 {
197 if (REGS_TO_STYLE(regs) == kDirect)
198 // the long-long here is aligned on an even register
199 // so there shouldn't be any padding
200 return marshal_no_pad(regs, args, 6);
201 else {
202 DECLARE_AND_CAST(regs, args, ss, uu_args);
203
204 int error = munge_wwlw(regs, args); // wwlw
205 uu_args[5] = ss->r[8]; // w
206 return error;
207 }
208 }
209
210 int
211 munge_wwlll(const void *regs, void *args)
212 {
213 if (REGS_TO_STYLE(regs) == kDirect)
214 return marshal_no_pad(regs, args, 8);
215 else {
216 DECLARE_AND_CAST(regs, args, ss, uu_args);
217
218 int error = munge_wwl(regs, args); // wwl
219 if (error)
220 return error;
221 uu_args[4] = ss->r[6]; // l
222 uu_args[5] = ss->r[8]; //
223 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
224 &(uu_args[6]), 2 * sizeof(uint32_t));
225 }
226 }
227
228 int
229 munge_wwllww(const void *regs, void *args)
230 {
231 return munge_wwlll(regs, args);
232 }
233
234 int
235 munge_wl(const void *regs, void *args)
236 {
237 if (REGS_TO_STYLE(regs) == kDirect)
238 memcpy(args, regs, 4 * sizeof(uint32_t));
239 else {
240 DECLARE_AND_CAST(regs, args, ss, uu_args);
241
242 uu_args[0] = ss->r[1]; // w
243 uu_args[2] = ss->r[2]; // l
244 uu_args[3] = ss->r[3]; //
245 }
246 return 0;
247 }
248
249 int
250 munge_wlw(const void *regs, void *args)
251 {
252 if (REGS_TO_STYLE(regs) == kDirect)
253 memcpy(args, regs, 5 * sizeof(uint32_t));
254 else {
255 DECLARE_AND_CAST(regs, args, ss, uu_args);
256
257 uu_args[0] = ss->r[1]; // w
258 uu_args[2] = ss->r[2]; // l
259 uu_args[3] = ss->r[3]; //
260 uu_args[4] = ss->r[4]; // w
261 }
262 return 0;
263 }
264
265 int
266 munge_wlww(const void *regs, void *args)
267 {
268 if (REGS_TO_STYLE(regs) == kDirect)
269 memcpy(args, regs, 6 * sizeof(uint32_t));
270 else {
271 DECLARE_AND_CAST(regs, args, ss, uu_args);
272
273 uu_args[0] = ss->r[1]; // w
274 uu_args[2] = ss->r[2]; // l
275 uu_args[3] = ss->r[3]; //
276 uu_args[4] = ss->r[4]; // w
277 uu_args[5] = ss->r[5]; // w
278 }
279 return 0;
280 }
281
282 int
283 munge_wlwwwll(const void *regs, void *args)
284 {
285 DECLARE_AND_CAST(regs, args, ss, uu_args);
286
287 if (REGS_TO_STYLE(regs) == kDirect) {
288 memcpy(args, regs, 7 * sizeof(uint32_t)); // wlwww
289 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
290 uu_args + 8, 4 * sizeof(uint32_t));
291 }
292 else {
293 uu_args[0] = ss->r[1]; // w
294 uu_args[2] = ss->r[2]; // l
295 uu_args[3] = ss->r[3]; //
296 uu_args[4] = ss->r[4]; // w
297 uu_args[5] = ss->r[5]; // w
298 uu_args[6] = ss->r[6]; // w
299 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
300 uu_args + 8, 4 * sizeof(uint32_t));
301 }
302 }
303
304 int
305 munge_wlwwwllw(const void *regs, void *args)
306 {
307 DECLARE_AND_CAST(regs, args, ss, uu_args);
308
309 if (REGS_TO_STYLE(regs) == kDirect) {
310 memcpy(args, regs, 7 * sizeof(uint32_t)); // wlwww
311 return copyin(ss->sp + ARG_SP_BYTE_OFFSET,
312 uu_args + 8, 5 * sizeof(uint32_t)); // ll
313 }
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 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
399 uu_args + 8, 4 * sizeof(uint32_t));
400 }
401
402 int
403 munge_wwwlw(const void *regs, void *args)
404 {
405 if (REGS_TO_STYLE(regs) == kDirect)
406 memcpy(args, regs, 7 * sizeof(uint32_t));
407 else {
408 DECLARE_AND_CAST(regs, args, ss, uu_args);
409
410 uu_args[0] = ss->r[1]; // w
411 uu_args[1] = ss->r[2]; // w
412 uu_args[2] = ss->r[3]; // w
413 uu_args[4] = ss->r[4]; // l
414 uu_args[5] = ss->r[5]; //
415 uu_args[6] = ss->r[6]; // w
416 }
417 return 0;
418 }
419
420 int
421 munge_wwwlww(const void *regs, void *args)
422 {
423 if (REGS_TO_STYLE(regs) == kDirect)
424 return munge_wlll(regs, args);
425 else {
426 DECLARE_AND_CAST(regs, args, ss, uu_args);
427
428 uu_args[0] = ss->r[1]; // w
429 uu_args[1] = ss->r[2]; // w
430 uu_args[2] = ss->r[3]; // w
431 uu_args[4] = ss->r[4]; // l
432 uu_args[5] = ss->r[5]; //
433 uu_args[6] = ss->r[6]; // w
434 uu_args[7] = ss->r[8]; // w
435 return 0;
436 }
437 }
438
439 int
440 munge_wwwl(const void *regs, void *args)
441 {
442 if (REGS_TO_STYLE(regs) == kDirect)
443 return munge_wll(regs, args);
444 else {
445 DECLARE_AND_CAST(regs, args, ss, uu_args);
446
447 uu_args[0] = ss->r[1]; // w
448 uu_args[1] = ss->r[2]; // w
449 uu_args[2] = ss->r[3]; // w
450 uu_args[4] = ss->r[4]; // l
451 uu_args[5] = ss->r[5]; //
452 return 0;
453 }
454 }
455
456 int
457 munge_wwwwl(const void *regs, void *args)
458 {
459 if (REGS_TO_STYLE(regs) == kDirect)
460 return marshal_no_pad(regs, args, 6);
461 else {
462 DECLARE_AND_CAST(regs, args, ss, uu_args);
463
464 uu_args[0] = ss->r[1]; // w
465 uu_args[1] = ss->r[2]; // w
466 uu_args[2] = ss->r[3]; // w
467 uu_args[3] = ss->r[4]; // w
468 uu_args[4] = ss->r[6]; // l
469 uu_args[5] = ss->r[8]; //
470 return 0;
471 }
472 }
473
474 int
475 munge_wwwwlw(const void *regs, void *args)
476 {
477 if (REGS_TO_STYLE(regs) == kDirect)
478 return marshal_no_pad(regs, args, 7);
479 else {
480 DECLARE_AND_CAST(regs, args, ss, uu_args);
481
482 int error = munge_wwwwl(regs, args); // wwwwl
483 if (error)
484 return error;
485 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // w
486 uu_args + 6, sizeof(uint32_t));
487 }
488 }
489
490 int
491 munge_wwwwwl(const void *regs, void *args)
492 {
493 if (REGS_TO_STYLE(regs) == kDirect)
494 return munge_wlll(regs, args);
495 else {
496 DECLARE_AND_CAST(regs, args, ss, uu_args);
497
498 uu_args[0] = ss->r[1]; // w
499 uu_args[1] = ss->r[2]; // w
500 uu_args[2] = ss->r[3]; // w
501 uu_args[3] = ss->r[4]; // w
502 uu_args[4] = ss->r[5]; // w
503 uu_args[6] = ss->r[6]; // l
504 uu_args[7] = ss->r[8]; //
505 return 0;
506 }
507 }
508
509 int
510 munge_wwwwwlww(const void *regs, void *args)
511 {
512 if (REGS_TO_STYLE(regs) == kDirect)
513 return munge_wllll(regs, args);
514 else {
515 DECLARE_AND_CAST(regs, args, ss, uu_args);
516
517 int error = munge_wwwwwl(regs, args); // wwwwwl
518 if (error)
519 return error;
520 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ww
521 uu_args + 8, 2 * sizeof(uint32_t));
522 }
523 }
524
525 int
526 munge_wwwwwllw(const void *regs, void *args)
527 {
528 DECLARE_AND_CAST(regs, args, ss, uu_args);
529
530 int error = munge_wwwwwl(regs, args); // wwwwwl
531 if (error)
532 return error;
533 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lw
534 uu_args + 8, 3 * sizeof(uint32_t));
535 }
536
537 int
538 munge_wwwwwlll(const void *regs, void *args)
539 {
540 DECLARE_AND_CAST(regs, args, ss, uu_args);
541 int error;
542
543 if (REGS_TO_STYLE(regs) == kDirect) {
544 error = munge_wlll(regs, args); // wlll
545 if (error)
546 return error;
547 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
548 uu_args + 8, 4 * sizeof(uint32_t));
549 }
550 else {
551 error = munge_wwwwwl(regs, args); // wwwwwl
552 if (error)
553 return error;
554 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
555 uu_args + 8, 4 * sizeof(uint32_t));
556 }
557 }
558
559 int
560 munge_wwwwwwl(const void *regs, void *args)
561 {
562 munge_wwlll(regs, args);
563
564 if (REGS_TO_STYLE(regs) == kDirect)
565 return marshal_no_pad(regs, args, 8);
566 else {
567 DECLARE_AND_CAST(regs, args, ss, uu_args);
568
569 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
570 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
571 &(uu_args[6]), 2 * sizeof(uint32_t));
572 }
573 }
574
575 int
576 munge_wwwwwwlw(const void *regs, void *args)
577 {
578 if (REGS_TO_STYLE(regs) == kDirect)
579 return marshal_no_pad(regs, args, 9);
580 else {
581 DECLARE_AND_CAST(regs, args, ss, uu_args);
582
583 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
584 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lw
585 &(uu_args[6]), 3 * sizeof(uint32_t));
586 }
587 }
588
589 int
590 munge_wwwwwwll(const void *regs, void *args)
591 {
592 if (REGS_TO_STYLE(regs) == kDirect)
593 return marshal_no_pad(regs, args, 10);
594 else {
595 DECLARE_AND_CAST(regs, args, ss, uu_args);
596
597 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
598 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
599 &(uu_args[6]), 4 * sizeof(uint32_t));
600 }
601 }
602
603 int
604 munge_wsw(const void *regs, void *args)
605 {
606 return munge_wlw(regs, args);
607 }
608
609 int
610 munge_wws(const void *regs, void *args)
611 {
612 return munge_wwl(regs, args);
613 }
614
615 int
616 munge_wwws(const void *regs, void *args)
617 {
618 return munge_wwwl(regs, args);
619 }
620
621 int
622 munge_wwwsw(const void *regs, void *args)
623 {
624 return munge_wwwlw(regs, args);
625 }
626
627 int
628 munge_llllll(const void *regs, void *args)
629 {
630 if (REGS_TO_STYLE(regs) == kDirect)
631 return marshal_no_pad(regs, args, 12);
632 else {
633 DECLARE_AND_CAST(regs, args, ss, uu_args);
634
635 uu_args[0] = ss->r[2]; // l
636 uu_args[1] = ss->r[3]; //
637 uu_args[2] = ss->r[4]; // l
638 uu_args[3] = ss->r[5]; //
639 uu_args[4] = ss->r[6]; // l
640 uu_args[5] = ss->r[8]; //
641 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lll
642 uu_args + 6, 6 * sizeof(uint32_t));
643 }
644 }
645
646 int
647 munge_ll(const void *regs, void *args)
648 {
649 if (REGS_TO_STYLE(regs) == kDirect)
650 return marshal_no_pad(regs, args, 4);
651 else
652 memcpy(args, (const uint32_t*)regs + 2, 4 * sizeof(uint32_t));
653 return 0;
654 }
655
656 int
657 munge_l(const void *regs, void *args)
658 {
659 if (REGS_TO_STYLE(regs) == kDirect)
660 return marshal_no_pad(regs, args, 2);
661 else
662 memcpy(args, (const uint32_t*)regs + 2, 2 * sizeof(uint32_t));
663 return 0;
664 }
665
666 int
667 munge_lw(const void *regs, void *args)
668 {
669 if (REGS_TO_STYLE(regs) == kDirect)
670 return marshal_no_pad(regs, args, 3);
671 else
672 memcpy(args, (const uint32_t*)regs + 2, 3 * sizeof(uint32_t));
673 return 0;
674 }
675
676 int
677 munge_lwww(const void *regs, void *args)
678 {
679 if (REGS_TO_STYLE(regs) == kDirect)
680 return marshal_no_pad(regs, args, 5);
681 else
682 memcpy(args, (const uint32_t*)regs + 2, 5 * sizeof(uint32_t));
683 return 0;
684 }
685
686 int
687 munge_lwwwwwww(const void *regs, void *args)
688 {
689 if (REGS_TO_STYLE(regs) == kDirect)
690 return marshal_no_pad(regs, args, 9);
691 else {
692 DECLARE_AND_CAST(regs, args, ss, uu_args);
693
694 uu_args[0] = ss->r[2]; // l
695 uu_args[1] = ss->r[3]; //
696 uu_args[2] = ss->r[4]; // w
697 uu_args[3] = ss->r[5]; // w
698 uu_args[4] = ss->r[6]; // w
699 uu_args[5] = ss->r[8]; // w
700 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // www
701 uu_args + 6, 3 * sizeof(uint32_t));
702 }
703 }
704
705 int
706 munge_wwlwww(const void *regs, void *args)
707 {
708 if (REGS_TO_STYLE(regs) == kDirect)
709 return marshal_no_pad(regs, args, 7);
710 else {
711 DECLARE_AND_CAST(regs, args, ss, uu_args);
712
713 uu_args[0] = ss->r[1]; // w
714 uu_args[1] = ss->r[2]; // w
715 uu_args[2] = ss->r[4]; // l
716 uu_args[3] = ss->r[5]; //
717 uu_args[4] = ss->r[6]; // w
718 uu_args[5] = ss->r[8]; // w
719 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // w
720 uu_args + 6, sizeof(uint32_t));
721 }
722
723 }
724
725 int
726 munge_wlwwwl(const void *regs, void *args)
727 {
728 DECLARE_AND_CAST(regs, args, ss, uu_args);
729
730 if (REGS_TO_STYLE(regs) == kDirect) {
731 memcpy(args, regs, 7 * sizeof(uint32_t)); // wlwww
732 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
733 uu_args + 8, 2 * sizeof(uint32_t));
734 } else {
735 uu_args[0] = ss->r[1]; // w
736 uu_args[2] = ss->r[2]; // l
737 uu_args[3] = ss->r[3]; //
738 uu_args[4] = ss->r[4]; // w
739 uu_args[5] = ss->r[5]; // w
740 uu_args[6] = ss->r[6]; // w
741 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
742 uu_args + 8, 2 * sizeof(uint32_t));
743 }
744 }
745
746 int
747 munge_wwlwwwl(const void *regs, void *args)
748 {
749 DECLARE_AND_CAST(regs, args, ss, uu_args);
750
751 if (REGS_TO_STYLE(regs) == kDirect) {
752 memcpy(args, regs, 7 * sizeof(uint32_t)); // wwlwww
753 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
754 uu_args + 8, 2 * sizeof(uint32_t));
755 } else {
756 uu_args[0] = ss->r[1]; // w
757 uu_args[1] = ss->r[2]; // w
758 uu_args[2] = ss->r[4]; // l
759 uu_args[3] = ss->r[5]; //
760 uu_args[4] = ss->r[6]; // w
761 uu_args[5] = ss->r[8]; // w
762 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // wl
763 uu_args + 6, 4 * sizeof(uint32_t));
764 }
765 }
766
767 #endif // __arm__ && (__BIGGEST_ALIGNMENT__ > 4)