xref: /xnu-8020.140.41/bsd/dev/arm/munge.c (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
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 arguments 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
marshal_no_pad(const arm_saved_state_t * ss,uint32_t * args,const uint32_t word_count)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
munge_w(const void * regs,void * args)118 munge_w(const void *regs, void *args)
119 {
120 	return marshal_no_pad(regs, args, 1);
121 }
122 
123 int
munge_ww(const void * regs,void * args)124 munge_ww(const void *regs, void *args)
125 {
126 	return marshal_no_pad(regs, args, 2);
127 }
128 
129 int
munge_www(const void * regs,void * args)130 munge_www(const void *regs, void *args)
131 {
132 	return marshal_no_pad(regs, args, 3);
133 }
134 
135 int
munge_wwww(const void * regs,void * args)136 munge_wwww(const void *regs, void *args)
137 {
138 	return marshal_no_pad(regs, args, 4);
139 }
140 
141 int
munge_wwwww(const void * regs,void * args)142 munge_wwwww(const void *regs, void *args)
143 {
144 	return marshal_no_pad(regs, args, 5);
145 }
146 
147 int
munge_wwwwww(const void * regs,void * args)148 munge_wwwwww(const void *regs, void *args)
149 {
150 	return marshal_no_pad(regs, args, 6);
151 }
152 
153 int
munge_wwwwwww(const void * regs,void * args)154 munge_wwwwwww(const void *regs, void *args)
155 {
156 	return marshal_no_pad(regs, args, 7);
157 }
158 
159 int
munge_wwwwwwww(const void * regs,void * args)160 munge_wwwwwwww(const void *regs, void *args)
161 {
162 	return marshal_no_pad(regs, args, 8);
163 }
164 
165 int
munge_wwl(const void * regs,void * args)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
munge_wwlw(const void * regs,void * args)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
munge_wwlww(const void * regs,void * args)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
munge_wwlll(const void * regs,void * args)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
munge_wwllww(const void * regs,void * args)231 munge_wwllww(const void *regs, void *args)
232 {
233 	return munge_wwlll(regs, args);
234 }
235 
236 int
munge_wl(const void * regs,void * args)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
munge_wlw(const void * regs,void * args)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
munge_wlww(const void * regs,void * args)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
munge_wlwwwll(const void * regs,void * args)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
munge_wlwwwllw(const void * regs,void * args)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
munge_wlwwlwlw(const void * regs,void * args)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
munge_wll(const void * regs,void * args)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
munge_wlll(const void * regs,void * args)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
munge_wlllww(const void * regs,void * args)375 munge_wlllww(const void *regs, void *args)
376 {
377 	return munge_wllll(regs, args);
378 }
379 
380 int
munge_wllll(const void * regs,void * args)381 munge_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
387 	           uu_args + 8, 2 * sizeof(uint32_t));
388 }
389 
390 int
munge_wllww(const void * regs,void * args)391 munge_wllww(const void *regs, void *args)
392 {
393 	return munge_wlll(regs, args);
394 }
395 
396 int
munge_wllwwll(const void * regs,void * args)397 munge_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
402 	if (error) {
403 		return error;
404 	}
405 	return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
406 	           uu_args + 8, 4 * sizeof(uint32_t));
407 }
408 
409 int
munge_wwwlw(const void * regs,void * args)410 munge_wwwlw(const void *regs, void *args)
411 {
412 	if (REGS_TO_STYLE(regs) == kDirect) {
413 		memcpy(args, regs, 7 * sizeof(uint32_t));
414 	} else {
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 
427 int
munge_wwwlww(const void * regs,void * args)428 munge_wwwlww(const void *regs, void *args)
429 {
430 	if (REGS_TO_STYLE(regs) == kDirect) {
431 		return munge_wlll(regs, args);
432 	} else {
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 }
445 
446 int
munge_wwwlwww(const void * regs,void * args)447 munge_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 
466 int
munge_wwwl(const void * regs,void * args)467 munge_wwwl(const void *regs, void *args)
468 {
469 	if (REGS_TO_STYLE(regs) == kDirect) {
470 		return munge_wll(regs, args);
471 	} else {
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 
483 int
munge_wwwwl(const void * regs,void * args)484 munge_wwwwl(const void *regs, void *args)
485 {
486 	if (REGS_TO_STYLE(regs) == kDirect) {
487 		return marshal_no_pad(regs, args, 6);
488 	} else {
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 
501 int
munge_wwwwlw(const void * regs,void * args)502 munge_wwwwlw(const void *regs, void *args)
503 {
504 	if (REGS_TO_STYLE(regs) == kDirect) {
505 		return marshal_no_pad(regs, args, 7);
506 	} else {
507 		DECLARE_AND_CAST(regs, args, ss, uu_args);
508 
509 		int error = munge_wwwwl(regs, args); // wwwwl
510 		if (error) {
511 			return error;
512 		}
513 		return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // w
514 		           uu_args + 6, sizeof(uint32_t));
515 	}
516 }
517 
518 int
munge_wwwwllww(const void * regs,void * args)519 munge_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 
534 int
munge_wwwwwl(const void * regs,void * args)535 munge_wwwwwl(const void *regs, void *args)
536 {
537 	if (REGS_TO_STYLE(regs) == kDirect) {
538 		return munge_wlll(regs, args);
539 	} else {
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 
553 int
munge_wwwwwlww(const void * regs,void * args)554 munge_wwwwwlww(const void *regs, void *args)
555 {
556 	if (REGS_TO_STYLE(regs) == kDirect) {
557 		return munge_wllll(regs, args);
558 	} else {
559 		DECLARE_AND_CAST(regs, args, ss, uu_args);
560 
561 		int error = munge_wwwwwl(regs, args); // wwwwwl
562 		if (error) {
563 			return error;
564 		}
565 		return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ww
566 		           uu_args + 8, 2 * sizeof(uint32_t));
567 	}
568 }
569 
570 int
munge_wwwwwllw(const void * regs,void * args)571 munge_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
576 	if (error) {
577 		return error;
578 	}
579 	return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // lw
580 	           uu_args + 8, 3 * sizeof(uint32_t));
581 }
582 
583 int
munge_wwwwwlll(const void * regs,void * args)584 munge_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
591 		if (error) {
592 			return error;
593 		}
594 		return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
595 		           uu_args + 8, 4 * sizeof(uint32_t));
596 	} else {
597 		error = munge_wwwwwl(regs, args);   // wwwwwl
598 		if (error) {
599 			return error;
600 		}
601 		return copyin(ss->sp + ARG_SP_BYTE_OFFSET, // ll
602 		           uu_args + 8, 4 * sizeof(uint32_t));
603 	}
604 }
605 
606 int
munge_wwwwwwl(const void * regs,void * args)607 munge_wwwwwwl(const void *regs, void *args)
608 {
609 	munge_wwlll(regs, args);
610 
611 	if (REGS_TO_STYLE(regs) == kDirect) {
612 		return marshal_no_pad(regs, args, 8);
613 	} else {
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
618 		           &(uu_args[6]), 2 * sizeof(uint32_t));
619 	}
620 }
621 
622 int
munge_wwwwwwlw(const void * regs,void * args)623 munge_wwwwwwlw(const void *regs, void *args)
624 {
625 	if (REGS_TO_STYLE(regs) == kDirect) {
626 		return marshal_no_pad(regs, args, 9);
627 	} else {
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
632 		           &(uu_args[6]), 3 * sizeof(uint32_t));
633 	}
634 }
635 
636 int
munge_wwwwwwll(const void * regs,void * args)637 munge_wwwwwwll(const void *regs, void *args)
638 {
639 	if (REGS_TO_STYLE(regs) == kDirect) {
640 		return marshal_no_pad(regs, args, 10);
641 	} else {
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
646 		           &(uu_args[6]), 4 * sizeof(uint32_t));
647 	}
648 }
649 
650 int
munge_wsw(const void * regs,void * args)651 munge_wsw(const void *regs, void *args)
652 {
653 	return munge_wlw(regs, args);
654 }
655 
656 int
munge_wws(const void * regs,void * args)657 munge_wws(const void *regs, void *args)
658 {
659 	return munge_wwl(regs, args);
660 }
661 
662 int
munge_wwws(const void * regs,void * args)663 munge_wwws(const void *regs, void *args)
664 {
665 	return munge_wwwl(regs, args);
666 }
667 
668 int
munge_wwwsw(const void * regs,void * args)669 munge_wwwsw(const void *regs, void *args)
670 {
671 	return munge_wwwlw(regs, args);
672 }
673 
674 int
munge_llllll(const void * regs,void * args)675 munge_llllll(const void *regs, void *args)
676 {
677 	if (REGS_TO_STYLE(regs) == kDirect) {
678 		return marshal_no_pad(regs, args, 12);
679 	} else {
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
689 		           uu_args + 6, 6 * sizeof(uint32_t));
690 	}
691 }
692 
693 int
munge_ll(const void * regs,void * args)694 munge_ll(const void *regs, void *args)
695 {
696 	if (REGS_TO_STYLE(regs) == kDirect) {
697 		return marshal_no_pad(regs, args, 4);
698 	} else {
699 		memcpy(args, (const uint32_t*)regs + 2, 4 * sizeof(uint32_t));
700 	}
701 	return 0;
702 }
703 
704 int
munge_l(const void * regs,void * args)705 munge_l(const void *regs, void *args)
706 {
707 	if (REGS_TO_STYLE(regs) == kDirect) {
708 		return marshal_no_pad(regs, args, 2);
709 	} else {
710 		memcpy(args, (const uint32_t*)regs + 2, 2 * sizeof(uint32_t));
711 	}
712 	return 0;
713 }
714 
715 int
munge_lw(const void * regs,void * args)716 munge_lw(const void *regs, void *args)
717 {
718 	if (REGS_TO_STYLE(regs) == kDirect) {
719 		return marshal_no_pad(regs, args, 3);
720 	} else {
721 		memcpy(args, (const uint32_t*)regs + 2, 3 * sizeof(uint32_t));
722 	}
723 	return 0;
724 }
725 
726 int
munge_lwww(const void * regs,void * args)727 munge_lwww(const void *regs, void *args)
728 {
729 	if (REGS_TO_STYLE(regs) == kDirect) {
730 		return marshal_no_pad(regs, args, 5);
731 	} else {
732 		memcpy(args, (const uint32_t*)regs + 2, 5 * sizeof(uint32_t));
733 	}
734 	return 0;
735 }
736 
737 int
munge_lwwwwwww(const void * regs,void * args)738 munge_lwwwwwww(const void *regs, void *args)
739 {
740 	if (REGS_TO_STYLE(regs) == kDirect) {
741 		return marshal_no_pad(regs, args, 9);
742 	} else {
743 		DECLARE_AND_CAST(regs, args, ss, uu_args);
744 
745 		uu_args[0]  = ss->r[2];             // l
746 		uu_args[1]  = ss->r[3];             //
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
752 		           uu_args + 6, 3 * sizeof(uint32_t));
753 	}
754 }
755 
756 int
munge_wwlwww(const void * regs,void * args)757 munge_wwlwww(const void *regs, void *args)
758 {
759 	if (REGS_TO_STYLE(regs) == kDirect) {
760 		return marshal_no_pad(regs, args, 7);
761 	} else {
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
771 		           uu_args + 6, sizeof(uint32_t));
772 	}
773 }
774 
775 int
munge_wlwwwl(const void * regs,void * args)776 munge_wlwwwl(const void *regs, void *args)
777 {
778 	DECLARE_AND_CAST(regs, args, ss, uu_args);
779 
780 	if (REGS_TO_STYLE(regs) == kDirect) {
781 		memcpy(args, regs, 7 * sizeof(uint32_t));  // wlwww
782 		return copyin(ss->sp + ARG_SP_BYTE_OFFSET, //  l
783 		           uu_args + 8, 2 * sizeof(uint32_t));
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
792 		           uu_args + 8, 2 * sizeof(uint32_t));
793 	}
794 }
795 
796 int
munge_wwlwwwl(const void * regs,void * args)797 munge_wwlwwwl(const void *regs, void *args)
798 {
799 	DECLARE_AND_CAST(regs, args, ss, uu_args);
800 
801 	if (REGS_TO_STYLE(regs) == kDirect) {
802 		memcpy(args, regs, 7 * sizeof(uint32_t));  // wwlwww
803 		return copyin(ss->sp + ARG_SP_BYTE_OFFSET, //  l
804 		           uu_args + 8, 2 * sizeof(uint32_t));
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
813 		           uu_args + 6, 4 * sizeof(uint32_t));
814 	}
815 }
816 
817 #endif // __arm__ && (__BIGGEST_ALIGNMENT__ > 4)
818