]> git.saurik.com Git - apple/xnu.git/blame - bsd/dev/arm/munge.c
xnu-4570.1.46.tar.gz
[apple/xnu.git] / bsd / dev / arm / munge.c
CommitLineData
5ba3f43e
A
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
57typedef 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
77static int
78marshal_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
116int
117munge_w(const void *regs, void *args)
118{
119 return marshal_no_pad(regs, args, 1);
120}
121
122int
123munge_ww(const void *regs, void *args)
124{
125 return marshal_no_pad(regs, args, 2);
126}
127
128int
129munge_www(const void *regs, void *args)
130{
131 return marshal_no_pad(regs, args, 3);
132}
133
134int
135munge_wwww(const void *regs, void *args)
136{
137 return marshal_no_pad(regs, args, 4);
138}
139
140int
141munge_wwwww(const void *regs, void *args)
142{
143 return marshal_no_pad(regs, args, 5);
144}
145
146int
147munge_wwwwww(const void *regs, void *args)
148{
149 return marshal_no_pad(regs, args, 6);
150}
151
152int
153munge_wwwwwww(const void *regs, void *args)
154{
155 return marshal_no_pad(regs, args, 7);
156}
157
158int
159munge_wwwwwwww(const void *regs, void *args)
160{
161 return marshal_no_pad(regs, args, 8);
162}
163
164int
165munge_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
180int
181munge_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
194int
195munge_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
210int
211munge_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
228int
229munge_wwllww(const void *regs, void *args)
230{
231 return munge_wwlll(regs, args);
232}
233
234int
235munge_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
249int
250munge_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
265int
266munge_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
282int
283munge_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
304int
305munge_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
326int
327munge_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
346int
347munge_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
363int
364munge_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
374int
375munge_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
384int
385munge_wllww(const void *regs, void *args)
386{
387 return munge_wlll(regs, args);
388}
389
390int
391munge_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
402int
403munge_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
420int
421munge_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
439int
440munge_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
456int
457munge_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
474int
475munge_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
490int
491munge_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
509int
510munge_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
525int
526munge_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
537int
538munge_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
559int
560munge_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
575int
576munge_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
589int
590munge_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
603int
604munge_wsw(const void *regs, void *args)
605{
606 return munge_wlw(regs, args);
607}
608
609int
610munge_wws(const void *regs, void *args)
611{
612 return munge_wwl(regs, args);
613}
614
615int
616munge_wwws(const void *regs, void *args)
617{
618 return munge_wwwl(regs, args);
619}
620
621int
622munge_wwwsw(const void *regs, void *args)
623{
624 return munge_wwwlw(regs, args);
625}
626
627int
628munge_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
646int
647munge_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
656int
657munge_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
666int
667munge_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
676int
677munge_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
686int
687munge_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
705int
706munge_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
725int
726munge_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
746int
747munge_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)