]> git.saurik.com Git - apple/xnu.git/blame - bsd/dev/arm/munge.c
xnu-7195.101.1.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@
0a7de745 5 *
5ba3f43e
A
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.
0a7de745 14 *
5ba3f43e
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
5ba3f43e
A
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.
0a7de745 25 *
5ba3f43e
A
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
0a7de745 29/*
5ba3f43e
A
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
0a7de745 46/*
5ba3f43e
A
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; \
0a7de745 63 uint32_t *uu_args = (uint32_t *)args;
5ba3f43e 64
0a7de745 65/*
5ba3f43e 66 * We start 32 bytes after sp since 4 registers are pushed onto the stack
c3c9b80d 67 * in the userspace syscall handler, and the first 4 stack arguments are moved
5ba3f43e
A
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,
0a7de745
A
104 args, (word_count - copy_count) * sizeof(uint32_t));
105 if (error) {
5ba3f43e 106 return error;
0a7de745 107 }
5ba3f43e
A
108 }
109 }
110 return error;
111}
112
113/*
114 * Define mungers to marshal userspace data into argument structs
115 */
116
117int
118munge_w(const void *regs, void *args)
119{
120 return marshal_no_pad(regs, args, 1);
121}
122
0a7de745 123int
5ba3f43e
A
124munge_ww(const void *regs, void *args)
125{
126 return marshal_no_pad(regs, args, 2);
127}
128
0a7de745 129int
5ba3f43e
A
130munge_www(const void *regs, void *args)
131{
132 return marshal_no_pad(regs, args, 3);
133}
134
0a7de745 135int
5ba3f43e
A
136munge_wwww(const void *regs, void *args)
137{
138 return marshal_no_pad(regs, args, 4);
139}
140
0a7de745 141int
5ba3f43e
A
142munge_wwwww(const void *regs, void *args)
143{
144 return marshal_no_pad(regs, args, 5);
145}
146
0a7de745 147int
5ba3f43e
A
148munge_wwwwww(const void *regs, void *args)
149{
150 return marshal_no_pad(regs, args, 6);
151}
152
0a7de745 153int
5ba3f43e
A
154munge_wwwwwww(const void *regs, void *args)
155{
156 return marshal_no_pad(regs, args, 7);
157}
158
0a7de745 159int
5ba3f43e
A
160munge_wwwwwwww(const void *regs, void *args)
161{
162 return marshal_no_pad(regs, args, 8);
163}
164
0a7de745 165int
5ba3f43e
A
166munge_wwl(const void *regs, void *args)
167{
0a7de745 168 if (REGS_TO_STYLE(regs) == kDirect) {
cb323159 169 return marshal_no_pad(regs, args, 4);
0a7de745 170 } else {
5ba3f43e
A
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)
0a7de745 176 uu_args[3] = ss->r[5]; //
5ba3f43e
A
177 return 0;
178 }
179}
180
0a7de745 181int
5ba3f43e
A
182munge_wwlw(const void *regs, void *args)
183{
0a7de745 184 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 185 return marshal_no_pad(regs, args, 5);
0a7de745 186 } else {
5ba3f43e
A
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
195int
196munge_wwlww(const void *regs, void *args)
197{
0a7de745 198 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e
A
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);
0a7de745 202 } else {
5ba3f43e
A
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
0a7de745 211int
5ba3f43e
A
212munge_wwlll(const void *regs, void *args)
213{
0a7de745 214 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 215 return marshal_no_pad(regs, args, 8);
0a7de745 216 } else {
5ba3f43e
A
217 DECLARE_AND_CAST(regs, args, ss, uu_args);
218
219 int error = munge_wwl(regs, args); // wwl
0a7de745 220 if (error) {
5ba3f43e 221 return error;
0a7de745 222 }
5ba3f43e
A
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
0a7de745 226 &(uu_args[6]), 2 * sizeof(uint32_t));
5ba3f43e
A
227 }
228}
229
230int
231munge_wwllww(const void *regs, void *args)
232{
233 return munge_wwlll(regs, args);
234}
235
236int
237munge_wl(const void *regs, void *args)
238{
0a7de745 239 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 240 memcpy(args, regs, 4 * sizeof(uint32_t));
0a7de745 241 } else {
5ba3f43e
A
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
251int
252munge_wlw(const void *regs, void *args)
253{
0a7de745
A
254 if (REGS_TO_STYLE(regs) == kDirect) {
255 memcpy(args, regs, 5 * sizeof(uint32_t));
256 } else {
5ba3f43e
A
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
267int
268munge_wlww(const void *regs, void *args)
269{
0a7de745 270 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 271 memcpy(args, regs, 6 * sizeof(uint32_t));
0a7de745 272 } else {
5ba3f43e
A
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
284int
285munge_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
0a7de745
A
292 uu_args + 8, 4 * sizeof(uint32_t));
293 } else {
5ba3f43e
A
294 uu_args[0] = ss->r[1]; // w
295 uu_args[2] = ss->r[2]; // l
0a7de745 296 uu_args[3] = ss->r[3]; //
5ba3f43e
A
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
0a7de745 301 uu_args + 8, 4 * sizeof(uint32_t));
5ba3f43e
A
302 }
303}
304
305int
306munge_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,
0a7de745
A
313 uu_args + 8, 5 * sizeof(uint32_t)); // ll
314 } else {
5ba3f43e
A
315 uu_args[0] = ss->r[1]; // w
316 uu_args[2] = ss->r[2]; // l
0a7de745 317 uu_args[3] = ss->r[3]; //
5ba3f43e
A
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
0a7de745 322 uu_args + 8, 5 * sizeof(uint32_t));
5ba3f43e
A
323 }
324}
325
0a7de745 326int
5ba3f43e
A
327munge_wlwwlwlw(const void *regs, void *args)
328{
329 DECLARE_AND_CAST(regs, args, ss, uu_args);
330
0a7de745 331 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 332 uu_args[0] = ss->r[0]; // w
0a7de745 333 } else {
5ba3f43e 334 uu_args[0] = ss->r[1]; // w
0a7de745 335 }
5ba3f43e
A
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
0a7de745 343 uu_args + 8, 5 * sizeof(uint32_t));
5ba3f43e
A
344}
345
0a7de745 346int
5ba3f43e
A
347munge_wll(const void *regs, void *args)
348{
0a7de745
A
349 if (REGS_TO_STYLE(regs) == kDirect) {
350 memcpy(args, regs, 6 * sizeof(uint32_t));
351 } else {
5ba3f43e
A
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
0a7de745 363int
5ba3f43e
A
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
f427ee49
A
374int
375munge_wlllww(const void *regs, void *args)
376{
377 return munge_wllll(regs, args);
378}
379
0a7de745 380int
5ba3f43e
A
381munge_wllll(const void *regs, void *args)
382{
383 DECLARE_AND_CAST(regs, args, ss, uu_args);
384
385 munge_wlll(regs, args); // wlll
386 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
0a7de745 387 uu_args + 8, 2 * sizeof(uint32_t));
5ba3f43e
A
388}
389
390int
391munge_wllww(const void *regs, void *args)
392{
393 return munge_wlll(regs, args);
394}
395
0a7de745 396int
5ba3f43e
A
397munge_wllwwll(const void *regs, void *args)
398{
399 DECLARE_AND_CAST(regs, args, ss, uu_args);
400
401 int error = munge_wlll(regs, args); // wllww
0a7de745 402 if (error) {
5ba3f43e 403 return error;
0a7de745 404 }
5ba3f43e 405 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
0a7de745 406 uu_args + 8, 4 * sizeof(uint32_t));
5ba3f43e
A
407}
408
0a7de745 409int
5ba3f43e
A
410munge_wwwlw(const void *regs, void *args)
411{
0a7de745 412 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 413 memcpy(args, regs, 7 * sizeof(uint32_t));
0a7de745 414 } else {
5ba3f43e
A
415 DECLARE_AND_CAST(regs, args, ss, uu_args);
416
417 uu_args[0] = ss->r[1]; // w
418 uu_args[1] = ss->r[2]; // w
419 uu_args[2] = ss->r[3]; // w
420 uu_args[4] = ss->r[4]; // l
421 uu_args[5] = ss->r[5]; //
422 uu_args[6] = ss->r[6]; // w
423 }
424 return 0;
425}
426
427int
428munge_wwwlww(const void *regs, void *args)
429{
0a7de745 430 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 431 return munge_wlll(regs, args);
0a7de745 432 } else {
5ba3f43e
A
433 DECLARE_AND_CAST(regs, args, ss, uu_args);
434
435 uu_args[0] = ss->r[1]; // w
436 uu_args[1] = ss->r[2]; // w
437 uu_args[2] = ss->r[3]; // w
438 uu_args[4] = ss->r[4]; // l
439 uu_args[5] = ss->r[5]; //
440 uu_args[6] = ss->r[6]; // w
441 uu_args[7] = ss->r[8]; // w
442 return 0;
443 }
444}
0a7de745 445
f427ee49
A
446int
447munge_wwwlwww(const void *regs, void *args)
448{
449 if (REGS_TO_STYLE(regs) == kDirect) {
450 memcpy(args, regs, 9 * sizeof(uint32_t));
451 } else {
452 DECLARE_AND_CAST(regs, args, ss, uu_args);
453
454 uu_args[0] = ss->r[1]; // w
455 uu_args[1] = ss->r[2]; // w
456 uu_args[2] = ss->r[3]; // w
457 uu_args[4] = ss->r[4]; // l
458 uu_args[5] = ss->r[5]; //
459 uu_args[6] = ss->r[6]; // w
460 uu_args[7] = ss->r[7]; // w
461 uu_args[8] = ss->r[8]; // w
462 }
463 return 0;
464}
465
0a7de745 466int
5ba3f43e
A
467munge_wwwl(const void *regs, void *args)
468{
0a7de745 469 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 470 return munge_wll(regs, args);
0a7de745 471 } else {
5ba3f43e
A
472 DECLARE_AND_CAST(regs, args, ss, uu_args);
473
474 uu_args[0] = ss->r[1]; // w
475 uu_args[1] = ss->r[2]; // w
476 uu_args[2] = ss->r[3]; // w
477 uu_args[4] = ss->r[4]; // l
478 uu_args[5] = ss->r[5]; //
479 return 0;
480 }
481}
482
0a7de745 483int
5ba3f43e
A
484munge_wwwwl(const void *regs, void *args)
485{
0a7de745 486 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 487 return marshal_no_pad(regs, args, 6);
0a7de745 488 } else {
5ba3f43e
A
489 DECLARE_AND_CAST(regs, args, ss, uu_args);
490
491 uu_args[0] = ss->r[1]; // w
492 uu_args[1] = ss->r[2]; // w
493 uu_args[2] = ss->r[3]; // w
494 uu_args[3] = ss->r[4]; // w
495 uu_args[4] = ss->r[6]; // l
496 uu_args[5] = ss->r[8]; //
497 return 0;
498 }
499}
500
501int
502munge_wwwwlw(const void *regs, void *args)
503{
0a7de745 504 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 505 return marshal_no_pad(regs, args, 7);
0a7de745 506 } else {
5ba3f43e
A
507 DECLARE_AND_CAST(regs, args, ss, uu_args);
508
509 int error = munge_wwwwl(regs, args); // wwwwl
0a7de745 510 if (error) {
5ba3f43e 511 return error;
0a7de745 512 }
5ba3f43e 513 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // w
0a7de745 514 uu_args + 6, sizeof(uint32_t));
5ba3f43e
A
515 }
516}
517
f427ee49
A
518int
519munge_wwwwllww(const void *regs, void *args)
520{
521 if (REGS_TO_STYLE(regs) == kDirect) {
522 return marshal_no_pad(regs, args, 10);
523 } else {
524 DECLARE_AND_CAST(regs, args, ss, uu_args);
525 int error = munge_wwwwl(regs, args); // wwwwl
526 if (error) {
527 return error;
528 }
529 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lww
530 uu_args + 6, 4 * sizeof(uint32_t));
531 }
532}
533
0a7de745 534int
5ba3f43e
A
535munge_wwwwwl(const void *regs, void *args)
536{
0a7de745 537 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 538 return munge_wlll(regs, args);
0a7de745 539 } else {
5ba3f43e
A
540 DECLARE_AND_CAST(regs, args, ss, uu_args);
541
542 uu_args[0] = ss->r[1]; // w
543 uu_args[1] = ss->r[2]; // w
544 uu_args[2] = ss->r[3]; // w
545 uu_args[3] = ss->r[4]; // w
546 uu_args[4] = ss->r[5]; // w
547 uu_args[6] = ss->r[6]; // l
548 uu_args[7] = ss->r[8]; //
549 return 0;
550 }
551}
552
0a7de745 553int
5ba3f43e
A
554munge_wwwwwlww(const void *regs, void *args)
555{
0a7de745 556 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 557 return munge_wllll(regs, args);
0a7de745 558 } else {
5ba3f43e
A
559 DECLARE_AND_CAST(regs, args, ss, uu_args);
560
561 int error = munge_wwwwwl(regs, args); // wwwwwl
0a7de745 562 if (error) {
5ba3f43e 563 return error;
0a7de745 564 }
5ba3f43e 565 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ww
0a7de745 566 uu_args + 8, 2 * sizeof(uint32_t));
5ba3f43e
A
567 }
568}
569
570int
571munge_wwwwwllw(const void *regs, void *args)
572{
573 DECLARE_AND_CAST(regs, args, ss, uu_args);
574
575 int error = munge_wwwwwl(regs, args); // wwwwwl
0a7de745 576 if (error) {
5ba3f43e 577 return error;
0a7de745 578 }
5ba3f43e 579 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lw
0a7de745 580 uu_args + 8, 3 * sizeof(uint32_t));
5ba3f43e
A
581}
582
583int
584munge_wwwwwlll(const void *regs, void *args)
585{
586 DECLARE_AND_CAST(regs, args, ss, uu_args);
587 int error;
588
589 if (REGS_TO_STYLE(regs) == kDirect) {
590 error = munge_wlll(regs, args); // wlll
0a7de745 591 if (error) {
5ba3f43e 592 return error;
0a7de745 593 }
5ba3f43e 594 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
0a7de745
A
595 uu_args + 8, 4 * sizeof(uint32_t));
596 } else {
5ba3f43e 597 error = munge_wwwwwl(regs, args); // wwwwwl
0a7de745 598 if (error) {
5ba3f43e 599 return error;
0a7de745 600 }
5ba3f43e 601 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
0a7de745 602 uu_args + 8, 4 * sizeof(uint32_t));
5ba3f43e
A
603 }
604}
605
606int
607munge_wwwwwwl(const void *regs, void *args)
608{
609 munge_wwlll(regs, args);
610
0a7de745 611 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 612 return marshal_no_pad(regs, args, 8);
0a7de745 613 } else {
5ba3f43e
A
614 DECLARE_AND_CAST(regs, args, ss, uu_args);
615
616 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
617 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
0a7de745 618 &(uu_args[6]), 2 * sizeof(uint32_t));
5ba3f43e
A
619 }
620}
621
0a7de745 622int
5ba3f43e
A
623munge_wwwwwwlw(const void *regs, void *args)
624{
0a7de745 625 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 626 return marshal_no_pad(regs, args, 9);
0a7de745 627 } else {
5ba3f43e
A
628 DECLARE_AND_CAST(regs, args, ss, uu_args);
629
630 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
631 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lw
0a7de745 632 &(uu_args[6]), 3 * sizeof(uint32_t));
5ba3f43e
A
633 }
634}
0a7de745
A
635
636int
5ba3f43e
A
637munge_wwwwwwll(const void *regs, void *args)
638{
0a7de745 639 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 640 return marshal_no_pad(regs, args, 10);
0a7de745 641 } else {
5ba3f43e
A
642 DECLARE_AND_CAST(regs, args, ss, uu_args);
643
644 memcpy(args, &(ss->r[1]), 6 * sizeof(uint32_t)); // wwwwww
645 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
0a7de745 646 &(uu_args[6]), 4 * sizeof(uint32_t));
5ba3f43e
A
647 }
648}
649
0a7de745 650int
5ba3f43e
A
651munge_wsw(const void *regs, void *args)
652{
653 return munge_wlw(regs, args);
654}
655
0a7de745 656int
5ba3f43e
A
657munge_wws(const void *regs, void *args)
658{
659 return munge_wwl(regs, args);
660}
661
662int
663munge_wwws(const void *regs, void *args)
664{
665 return munge_wwwl(regs, args);
666}
667
668int
669munge_wwwsw(const void *regs, void *args)
670{
671 return munge_wwwlw(regs, args);
672}
673
0a7de745 674int
5ba3f43e
A
675munge_llllll(const void *regs, void *args)
676{
0a7de745 677 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 678 return marshal_no_pad(regs, args, 12);
0a7de745 679 } else {
5ba3f43e
A
680 DECLARE_AND_CAST(regs, args, ss, uu_args);
681
682 uu_args[0] = ss->r[2]; // l
683 uu_args[1] = ss->r[3]; //
684 uu_args[2] = ss->r[4]; // l
685 uu_args[3] = ss->r[5]; //
686 uu_args[4] = ss->r[6]; // l
687 uu_args[5] = ss->r[8]; //
688 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lll
0a7de745 689 uu_args + 6, 6 * sizeof(uint32_t));
5ba3f43e
A
690 }
691}
692
0a7de745 693int
5ba3f43e
A
694munge_ll(const void *regs, void *args)
695{
0a7de745 696 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 697 return marshal_no_pad(regs, args, 4);
0a7de745 698 } else {
5ba3f43e 699 memcpy(args, (const uint32_t*)regs + 2, 4 * sizeof(uint32_t));
0a7de745 700 }
5ba3f43e
A
701 return 0;
702}
703
0a7de745 704int
5ba3f43e
A
705munge_l(const void *regs, void *args)
706{
0a7de745 707 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 708 return marshal_no_pad(regs, args, 2);
0a7de745 709 } else {
5ba3f43e 710 memcpy(args, (const uint32_t*)regs + 2, 2 * sizeof(uint32_t));
0a7de745 711 }
5ba3f43e
A
712 return 0;
713}
714
0a7de745 715int
5ba3f43e
A
716munge_lw(const void *regs, void *args)
717{
0a7de745 718 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 719 return marshal_no_pad(regs, args, 3);
0a7de745 720 } else {
5ba3f43e 721 memcpy(args, (const uint32_t*)regs + 2, 3 * sizeof(uint32_t));
0a7de745 722 }
5ba3f43e
A
723 return 0;
724}
725
726int
727munge_lwww(const void *regs, void *args)
728{
0a7de745 729 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 730 return marshal_no_pad(regs, args, 5);
0a7de745 731 } else {
5ba3f43e 732 memcpy(args, (const uint32_t*)regs + 2, 5 * sizeof(uint32_t));
0a7de745 733 }
5ba3f43e
A
734 return 0;
735}
736
0a7de745 737int
5ba3f43e
A
738munge_lwwwwwww(const void *regs, void *args)
739{
0a7de745 740 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 741 return marshal_no_pad(regs, args, 9);
0a7de745 742 } else {
5ba3f43e
A
743 DECLARE_AND_CAST(regs, args, ss, uu_args);
744
745 uu_args[0] = ss->r[2]; // l
0a7de745 746 uu_args[1] = ss->r[3]; //
5ba3f43e
A
747 uu_args[2] = ss->r[4]; // w
748 uu_args[3] = ss->r[5]; // w
749 uu_args[4] = ss->r[6]; // w
750 uu_args[5] = ss->r[8]; // w
751 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // www
0a7de745 752 uu_args + 6, 3 * sizeof(uint32_t));
5ba3f43e
A
753 }
754}
755
756int
757munge_wwlwww(const void *regs, void *args)
758{
0a7de745 759 if (REGS_TO_STYLE(regs) == kDirect) {
5ba3f43e 760 return marshal_no_pad(regs, args, 7);
0a7de745 761 } else {
5ba3f43e
A
762 DECLARE_AND_CAST(regs, args, ss, uu_args);
763
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, // w
0a7de745 771 uu_args + 6, sizeof(uint32_t));
5ba3f43e 772 }
5ba3f43e
A
773}
774
775int
776munge_wlwwwl(const void *regs, void *args)
777{
778 DECLARE_AND_CAST(regs, args, ss, uu_args);
779
780 if (REGS_TO_STYLE(regs) == kDirect) {
0a7de745 781 memcpy(args, regs, 7 * sizeof(uint32_t)); // wlwww
5ba3f43e 782 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
0a7de745 783 uu_args + 8, 2 * sizeof(uint32_t));
5ba3f43e
A
784 } else {
785 uu_args[0] = ss->r[1]; // w
786 uu_args[2] = ss->r[2]; // l
787 uu_args[3] = ss->r[3]; //
788 uu_args[4] = ss->r[4]; // w
789 uu_args[5] = ss->r[5]; // w
790 uu_args[6] = ss->r[6]; // w
791 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
0a7de745 792 uu_args + 8, 2 * sizeof(uint32_t));
5ba3f43e
A
793 }
794}
795
796int
797munge_wwlwwwl(const void *regs, void *args)
798{
0a7de745 799 DECLARE_AND_CAST(regs, args, ss, uu_args);
5ba3f43e
A
800
801 if (REGS_TO_STYLE(regs) == kDirect) {
0a7de745 802 memcpy(args, regs, 7 * sizeof(uint32_t)); // wwlwww
5ba3f43e 803 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // l
0a7de745 804 uu_args + 8, 2 * sizeof(uint32_t));
5ba3f43e
A
805 } else {
806 uu_args[0] = ss->r[1]; // w
807 uu_args[1] = ss->r[2]; // w
808 uu_args[2] = ss->r[4]; // l
809 uu_args[3] = ss->r[5]; //
810 uu_args[4] = ss->r[6]; // w
811 uu_args[5] = ss->r[8]; // w
812 return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // wl
0a7de745 813 uu_args + 6, 4 * sizeof(uint32_t));
5ba3f43e
A
814 }
815}
816
817#endif // __arm__ && (__BIGGEST_ALIGNMENT__ > 4)