1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012,2013 Petr Machata
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21#include "config.h"
22
23#include <sys/types.h>
24#include <assert.h>
25#include <gelf.h>
26#include <stddef.h>
27#include <stdint.h>
28#include <stdlib.h>
29#include <string.h>
30#include <stdio.h>
31
32#include "backend.h"
33#include "expr.h"
34#include "fetch.h"
35#include "proc.h"
36#include "ptrace.h"
37#include "type.h"
38#include "value.h"
39
40enum arg_class {
41	CLASS_INTEGER,
42	CLASS_SSE,
43	CLASS_NO,
44	CLASS_MEMORY,
45	CLASS_X87,
46};
47
48enum reg_pool {
49	POOL_FUNCALL,
50	POOL_SYSCALL,
51	/* A common pool for system call and function call return is
52	 * enough, the ABI is similar enough.  */
53	POOL_RETVAL,
54};
55
56struct fetch_context
57{
58	struct user_regs_struct iregs;
59	struct user_fpregs_struct fpregs;
60
61	arch_addr_t stack_pointer;
62	size_t ireg;	/* Used-up integer registers.  */
63	size_t freg;	/* Used-up floating registers.  */
64	int machine;
65
66	union {
67		struct {
68			/* Storage classes for return type.  We need
69			 * to compute them anyway, so let's keep them
70			 * around.  */
71			enum arg_class ret_classes[2];
72			ssize_t num_ret_classes;
73		} x86_64;
74		struct {
75			struct value retval;
76		} ix86;
77	} u;
78};
79
80#ifndef __x86_64__
81__attribute__((noreturn)) static void
82i386_unreachable(void)
83{
84	abort();
85}
86#endif
87
88static int
89contains_unaligned_fields(struct arg_type_info *info)
90{
91	/* XXX currently we don't support structure alignment.  */
92	return 0;
93}
94
95static int
96has_nontrivial_ctor_dtor(struct arg_type_info *info)
97{
98	/* XXX another unsupported aspect of type info.  We might call
99	 * these types "class" instead of "struct" in the config
100	 * file.  */
101	return 0;
102}
103
104static void
105copy_int_register(struct fetch_context *context,
106		  struct value *valuep, unsigned long val, size_t offset)
107{
108	if (valuep != NULL) {
109		unsigned char *buf = value_get_raw_data(valuep);
110		memcpy(buf + offset, &val, sizeof(val));
111	}
112	context->ireg++;
113}
114
115static void
116copy_sse_register(struct fetch_context *context, struct value *valuep,
117		  int half, size_t sz, size_t offset)
118{
119#ifdef __x86_64__
120	union {
121		uint32_t sse[4];
122		long halves[2];
123	} u;
124	size_t off = 4 * context->freg++;
125	memcpy(u.sse, context->fpregs.xmm_space + off, sizeof(u.sse));
126
127	if (valuep != NULL) {
128		unsigned char *buf = value_get_raw_data(valuep);
129		memcpy(buf + offset, u.halves + half, sz);
130	}
131#else
132	i386_unreachable();
133#endif
134}
135
136static void
137allocate_stack_slot(struct fetch_context *context,
138		    struct value *valuep, size_t sz, size_t offset,
139		    size_t archw)
140{
141	assert(valuep != NULL);
142	size_t a = type_alignof(valuep->inferior, valuep->type);
143	if (a < archw)
144		a = archw;
145	context->stack_pointer
146		= (void *)align((unsigned long)context->stack_pointer, a);
147
148	value_in_inferior(valuep, context->stack_pointer);
149	context->stack_pointer += sz;
150}
151
152static enum arg_class
153allocate_x87(struct fetch_context *context, struct value *valuep,
154	     size_t sz, size_t offset, enum reg_pool pool, size_t archw)
155{
156	/* Both i386 and x86_64 ABI only ever really use x87 registers
157	 * to return values.  Otherwise, the parameter is treated as
158	 * if it were CLASS_MEMORY.  On x86_64 x87 registers are only
159	 * used for returning long double values, which we currently
160	 * don't support.  */
161
162	if (pool != POOL_RETVAL) {
163		allocate_stack_slot(context, valuep, sz, offset, archw);
164		return CLASS_MEMORY;
165
166	}
167
168	/* If the class is X87, the value is returned on the X87 stack
169	 * in %st0 as 80-bit x87 number.
170	 *
171	 * If the class is X87UP, the value is returned together with
172	 * the previous X87 value in %st0.
173	 *
174	 * If the class is COMPLEX_X87, the real part of the value is
175	 * returned in %st0 and the imaginary part in %st1.  */
176
177	if (valuep != NULL) {
178		union {
179			long double ld;
180			double d;
181			float f;
182			char buf[0];
183		} u;
184
185		/* The x87 floating point value is in long double
186		 * format, so we need to convert in to the right type.
187		 * Alternatively we might just leave it as is and
188		 * smuggle the long double type into the value (via
189		 * value_set_type), but for that we first need to
190		 * support long double in the first place.  */
191
192#ifdef __x86_64__
193		unsigned int *reg;
194#else
195		long int *reg;
196#endif
197		reg = &context->fpregs.st_space[0];
198		memcpy(&u.ld, reg, sizeof(u));
199		if (valuep->type->type == ARGTYPE_FLOAT)
200			u.f = (float)u.ld;
201		else if (valuep->type->type == ARGTYPE_DOUBLE)
202			u.d = (double)u.ld;
203		else
204			assert(!"Unexpected floating type!"), abort();
205
206		unsigned char *buf = value_get_raw_data(valuep);
207		memcpy(buf + offset, u.buf, sz);
208	}
209	return CLASS_X87;
210}
211
212static enum arg_class
213allocate_integer(struct fetch_context *context, struct value *valuep,
214		 size_t sz, size_t offset, enum reg_pool pool)
215{
216#define HANDLE(NUM, WHICH)						\
217	case NUM:							\
218		copy_int_register(context, valuep,			\
219				  context->iregs.WHICH, offset);	\
220		return CLASS_INTEGER
221
222	switch (pool) {
223	case POOL_FUNCALL:
224#ifdef __x86_64__
225		switch (context->ireg) {
226			HANDLE(0, rdi);
227			HANDLE(1, rsi);
228			HANDLE(2, rdx);
229			HANDLE(3, rcx);
230			HANDLE(4, r8);
231			HANDLE(5, r9);
232		default:
233			allocate_stack_slot(context, valuep, sz, offset, 8);
234			return CLASS_MEMORY;
235		}
236#else
237		i386_unreachable();
238#endif
239
240	case POOL_SYSCALL:
241#ifdef __x86_64__
242		if (context->machine == EM_X86_64) {
243			switch (context->ireg) {
244				HANDLE(0, rdi);
245				HANDLE(1, rsi);
246				HANDLE(2, rdx);
247				HANDLE(3, r10);
248				HANDLE(4, r8);
249				HANDLE(5, r9);
250			default:
251				assert(!"More than six syscall arguments???");
252				abort();
253			}
254		}
255#endif
256		if (context->machine == EM_386) {
257
258#ifdef __x86_64__
259# define HANDLE32(NUM, WHICH) HANDLE(NUM, r##WHICH)
260#else
261# define HANDLE32(NUM, WHICH) HANDLE(NUM, e##WHICH)
262#endif
263
264			switch (context->ireg) {
265				HANDLE32(0, bx);
266				HANDLE32(1, cx);
267				HANDLE32(2, dx);
268				HANDLE32(3, si);
269				HANDLE32(4, di);
270				HANDLE32(5, bp);
271			default:
272				assert(!"More than six syscall arguments???");
273				abort();
274			}
275#undef HANDLE32
276		}
277
278	case POOL_RETVAL:
279		switch (context->ireg) {
280#ifdef __x86_64__
281			HANDLE(0, rax);
282			HANDLE(1, rdx);
283#else
284			HANDLE(0, eax);
285#endif
286		default:
287			assert(!"Too many return value classes.");
288			abort();
289		}
290	}
291
292	abort();
293
294#undef HANDLE
295}
296
297static enum arg_class
298allocate_sse(struct fetch_context *context, struct value *valuep,
299	     size_t sz, size_t offset, enum reg_pool pool)
300{
301	size_t num_regs = 0;
302	switch (pool) {
303	case POOL_FUNCALL:
304		num_regs = 8;
305	case POOL_SYSCALL:
306		break;
307	case POOL_RETVAL:
308		num_regs = 2;
309	}
310
311	if (context->freg >= num_regs) {
312		/* We shouldn't see overflow for RETVAL or SYSCALL
313		 * pool.  */
314		assert(pool == POOL_FUNCALL);
315		allocate_stack_slot(context, valuep, sz, offset, 8);
316		return CLASS_MEMORY;
317	} else {
318		copy_sse_register(context, valuep, 0, sz, offset);
319		return CLASS_SSE;
320	}
321}
322
323/* This allocates registers or stack space for another argument of the
324 * class CLS.  */
325static enum arg_class
326allocate_class(enum arg_class cls, struct fetch_context *context,
327	       struct value *valuep, size_t sz, size_t offset, enum reg_pool pool)
328{
329	switch (cls) {
330	case CLASS_MEMORY:
331		allocate_stack_slot(context, valuep, sz, offset, 8);
332	case CLASS_NO:
333		return cls;
334
335	case CLASS_INTEGER:
336		return allocate_integer(context, valuep, sz, offset, pool);
337
338	case CLASS_SSE:
339		return allocate_sse(context, valuep, sz, offset, pool);
340
341	case CLASS_X87:
342		return allocate_x87(context, valuep, sz, offset, pool, 8);
343	}
344	abort();
345}
346
347static ssize_t
348classify(struct process *proc, struct fetch_context *context,
349	 struct arg_type_info *info, enum arg_class classes[],
350	 size_t sz, size_t eightbytes);
351
352/* This classifies one eightbyte part of an array or struct.  */
353static ssize_t
354classify_eightbyte(struct process *proc, struct fetch_context *context,
355		   struct arg_type_info *info,
356		   enum arg_class *classp, size_t start, size_t end,
357		   struct arg_type_info *(*getter)(struct arg_type_info *,
358						   size_t))
359{
360	size_t i;
361	enum arg_class cls = CLASS_NO;
362	for (i = start; i < end; ++i) {
363		enum arg_class cls2;
364		struct arg_type_info *info2 = getter(info, i);
365		size_t sz = type_sizeof(proc, info2);
366		if (sz == (size_t)-1)
367			return -1;
368		if (classify(proc, context, info2, &cls2, sz, 1) < 0)
369			return -1;
370
371		if (cls == CLASS_NO)
372			cls = cls2;
373		else if (cls2 == CLASS_NO || cls == cls2)
374			;
375		else if (cls == CLASS_MEMORY || cls2 == CLASS_MEMORY)
376			cls = CLASS_MEMORY;
377		else if (cls == CLASS_INTEGER || cls2 == CLASS_INTEGER)
378			cls = CLASS_INTEGER;
379		else
380			cls = CLASS_SSE;
381	}
382
383	*classp = cls;
384	return 1;
385}
386
387/* This classifies small arrays and structs.  */
388static ssize_t
389classify_eightbytes(struct process *proc, struct fetch_context *context,
390		    struct arg_type_info *info,
391		    enum arg_class classes[], size_t elements,
392		    size_t eightbytes,
393		    struct arg_type_info *(*getter)(struct arg_type_info *,
394						    size_t))
395{
396	if (eightbytes > 1) {
397		/* Where the second eightbyte starts.  Number of the
398		 * first element in the structure that belongs to the
399		 * second eightbyte.  */
400		size_t start_2nd = 0;
401		size_t i;
402		for (i = 0; i < elements; ++i)
403			if (type_offsetof(proc, info, i) >= 8) {
404				start_2nd = i;
405				break;
406			}
407
408		enum arg_class cls1, cls2;
409		if (classify_eightbyte(proc, context, info, &cls1,
410				       0, start_2nd, getter) < 0
411		    || classify_eightbyte(proc, context, info, &cls2,
412					  start_2nd, elements, getter) < 0)
413			return -1;
414
415		if (cls1 == CLASS_MEMORY || cls2 == CLASS_MEMORY) {
416			classes[0] = CLASS_MEMORY;
417			return 1;
418		}
419
420		classes[0] = cls1;
421		classes[1] = cls2;
422		return 2;
423	}
424
425	return classify_eightbyte(proc, context, info, classes,
426				  0, elements, getter);
427}
428
429static struct arg_type_info *
430get_array_field(struct arg_type_info *info, size_t emt)
431{
432	return info->u.array_info.elt_type;
433}
434
435static int
436flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info)
437{
438	size_t i;
439	for (i = 0; i < type_struct_size(info); ++i) {
440		struct arg_type_info *field = type_struct_get(info, i);
441		assert(field != NULL);
442		switch (field->type) {
443		case ARGTYPE_STRUCT:
444			if (flatten_structure(flattened, field) < 0)
445				return -1;
446			break;
447
448		default:
449			if (type_struct_add(flattened, field, 0) < 0)
450				return -1;
451		}
452	}
453	return 0;
454}
455
456static ssize_t
457classify(struct process *proc, struct fetch_context *context,
458	 struct arg_type_info *info, enum arg_class classes[],
459	 size_t sz, size_t eightbytes)
460{
461	switch (info->type) {
462		struct arg_type_info flattened;
463	case ARGTYPE_VOID:
464		return 0;
465
466	case ARGTYPE_CHAR:
467	case ARGTYPE_SHORT:
468	case ARGTYPE_USHORT:
469	case ARGTYPE_INT:
470	case ARGTYPE_UINT:
471	case ARGTYPE_LONG:
472	case ARGTYPE_ULONG:
473
474	case ARGTYPE_POINTER:
475		/* and LONGLONG */
476		/* CLASS_INTEGER */
477		classes[0] = CLASS_INTEGER;
478		return 1;
479
480	case ARGTYPE_FLOAT:
481	case ARGTYPE_DOUBLE:
482		/* and DECIMAL, and _m64 */
483		classes[0] = CLASS_SSE;
484		return 1;
485
486	case ARGTYPE_ARRAY:
487		/* N.B. this cannot be top-level array, those decay to
488		 * pointers.  Therefore, it must be inside structure
489		 * that's at most 2 eightbytes long.  */
490
491		/* Structures with flexible array members can't be
492		 * passed by value.  */
493		assert(expr_is_compile_constant(info->u.array_info.length));
494
495		long l;
496		if (expr_eval_constant(info->u.array_info.length, &l) < 0)
497			return -1;
498
499		return classify_eightbytes(proc, context, info, classes,
500					   (size_t)l, eightbytes,
501					   get_array_field);
502
503	case ARGTYPE_STRUCT:
504		/* N.B. "big" structs are dealt with in the caller.
505		 *
506		 * First, we need to flatten the structure.  In
507		 * struct(float,struct(float,float)), first two floats
508		 * both belong to the same eightbyte.  */
509		type_init_struct(&flattened);
510
511		ssize_t ret;
512		if (flatten_structure(&flattened, info) < 0) {
513			ret = -1;
514			goto done;
515		}
516		ret = classify_eightbytes(proc, context, &flattened,
517					  classes,
518					  type_struct_size(&flattened),
519					  eightbytes, type_struct_get);
520	done:
521		type_destroy(&flattened);
522		return ret;
523
524	default:
525		/* Unsupported type.  */
526		assert(info->type != info->type);
527		abort();
528	}
529	abort();
530}
531
532static ssize_t
533pass_by_reference(struct value *valuep, enum arg_class classes[])
534{
535	if (valuep != NULL && value_pass_by_reference(valuep) < 0)
536		return -1;
537	classes[0] = CLASS_INTEGER;
538	return 1;
539}
540
541static ssize_t
542classify_argument(struct process *proc, struct fetch_context *context,
543		  struct arg_type_info *info, struct value *valuep,
544		  enum arg_class classes[], size_t *sizep)
545{
546	size_t sz = type_sizeof(proc, info);
547	if (sz == (size_t)-1)
548		return -1;
549	*sizep = sz;
550
551	size_t eightbytes = (sz + 7) / 8;  /* Round up.  */
552
553	/* Arrays decay into pointers.  */
554	assert(info->type != ARGTYPE_ARRAY);
555
556	if (info->type == ARGTYPE_STRUCT) {
557		if (eightbytes > 2 || contains_unaligned_fields(info)) {
558			classes[0] = CLASS_MEMORY;
559			return 1;
560		}
561
562		if (has_nontrivial_ctor_dtor(info))
563			return pass_by_reference(valuep, classes);
564	}
565
566	return classify(proc, context, info, classes, sz, eightbytes);
567}
568
569static int
570fetch_register_banks(struct process *proc, struct fetch_context *context,
571		     int floating)
572{
573	if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->iregs) < 0)
574		return -1;
575	context->ireg = 0;
576
577	if (floating) {
578		if (ptrace(PTRACE_GETFPREGS, proc->pid,
579			   0, &context->fpregs) < 0)
580			return -1;
581		context->freg = 0;
582	} else {
583		context->freg = -1;
584	}
585
586	return 0;
587}
588
589static int
590arch_fetch_arg_next_32(struct fetch_context *context, enum tof type,
591		       struct process *proc, struct arg_type_info *info,
592		       struct value *valuep)
593{
594	size_t sz = type_sizeof(proc, info);
595	if (sz == (size_t)-1)
596		return -1;
597	if (value_reserve(valuep, sz) == NULL)
598		return -1;
599
600	if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
601		int cls = allocate_integer(context, valuep,
602					   sz, 0, POOL_SYSCALL);
603		assert(cls == CLASS_INTEGER);
604		return 0;
605	}
606
607	allocate_stack_slot(context, valuep, sz, 0, 4);
608
609	return 0;
610}
611
612static int
613arch_fetch_retval_32(struct fetch_context *context, enum tof type,
614		     struct process *proc, struct arg_type_info *info,
615		     struct value *valuep)
616{
617	if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0)
618		return -1;
619
620	struct value *retval = &context->u.ix86.retval;
621	if (retval->type != NULL) {
622		/* Struct return value was extracted when in fetch
623		 * init.  */
624		memcpy(valuep, &context->u.ix86.retval, sizeof(*valuep));
625		return 0;
626	}
627
628	size_t sz = type_sizeof(proc, info);
629	if (sz == (size_t)-1)
630		return -1;
631	if (value_reserve(valuep, sz) == NULL)
632		return -1;
633
634	switch (info->type) {
635		enum arg_class cls;
636	case ARGTYPE_VOID:
637		return 0;
638
639	case ARGTYPE_INT:
640	case ARGTYPE_UINT:
641	case ARGTYPE_LONG:
642	case ARGTYPE_ULONG:
643	case ARGTYPE_CHAR:
644	case ARGTYPE_SHORT:
645	case ARGTYPE_USHORT:
646	case ARGTYPE_POINTER:
647		cls = allocate_integer(context, valuep, sz, 0, POOL_RETVAL);
648		assert(cls == CLASS_INTEGER);
649		return 0;
650
651	case ARGTYPE_FLOAT:
652	case ARGTYPE_DOUBLE:
653		cls = allocate_x87(context, valuep, sz, 0, POOL_RETVAL, 4);
654		assert(cls == CLASS_X87);
655		return 0;
656
657	case ARGTYPE_STRUCT: /* Handled above.  */
658	default:
659		assert(!"Unexpected i386 retval type!");
660		abort();
661	}
662
663	abort();
664}
665
666static arch_addr_t
667fetch_stack_pointer(struct fetch_context *context)
668{
669	arch_addr_t sp;
670#ifdef __x86_64__
671	sp = (arch_addr_t)context->iregs.rsp;
672#else
673	sp = (arch_addr_t)context->iregs.esp;
674#endif
675	return sp;
676}
677
678struct fetch_context *
679arch_fetch_arg_init_32(struct fetch_context *context,
680		       enum tof type, struct process *proc,
681		       struct arg_type_info *ret_info)
682{
683	context->stack_pointer = fetch_stack_pointer(context) + 4;
684
685	size_t sz = type_sizeof(proc, ret_info);
686	if (sz == (size_t)-1)
687		return NULL;
688
689	struct value *retval = &context->u.ix86.retval;
690	if (ret_info->type == ARGTYPE_STRUCT) {
691		value_init(retval, proc, NULL, ret_info, 0);
692
693		enum arg_class dummy[2];
694		if (pass_by_reference(retval, dummy) < 0)
695			return NULL;
696		allocate_stack_slot(context, retval, 4, 0, 4);
697
698	} else {
699		value_init_detached(retval, NULL, NULL, 0);
700	}
701
702	return context;
703}
704
705struct fetch_context *
706arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type,
707		       struct process *proc, struct arg_type_info *ret_info)
708{
709	/* The first stack slot holds a return address.  */
710	ctx->stack_pointer = fetch_stack_pointer(ctx) + 8;
711
712	size_t size;
713	ctx->u.x86_64.num_ret_classes
714		= classify_argument(proc, ctx, ret_info, NULL,
715				    ctx->u.x86_64.ret_classes, &size);
716	if (ctx->u.x86_64.num_ret_classes == -1)
717		return NULL;
718
719	/* If the class is MEMORY, then the first argument is a hidden
720	 * pointer to the allocated storage.  */
721	if (ctx->u.x86_64.num_ret_classes > 0
722	    && ctx->u.x86_64.ret_classes[0] == CLASS_MEMORY) {
723		/* MEMORY should be the sole class.  */
724		assert(ctx->u.x86_64.num_ret_classes == 1);
725		allocate_integer(ctx, NULL, size, 0, POOL_FUNCALL);
726	}
727
728	return ctx;
729}
730
731struct fetch_context *
732arch_fetch_arg_init(enum tof type, struct process *proc,
733		    struct arg_type_info *ret_info)
734{
735	struct fetch_context *ctx = malloc(sizeof(*ctx));
736	if (ctx == NULL)
737		return NULL;
738	ctx->machine = proc->e_machine;
739
740	assert(type != LT_TOF_FUNCTIONR
741	       && type != LT_TOF_SYSCALLR);
742	if (fetch_register_banks(proc, ctx, type == LT_TOF_FUNCTION) < 0) {
743	fail:
744		free(ctx);
745		return NULL;
746	}
747
748	struct fetch_context *ret;
749	if (proc->e_machine == EM_386)
750		ret = arch_fetch_arg_init_32(ctx, type, proc, ret_info);
751	else
752		ret = arch_fetch_arg_init_64(ctx, type, proc, ret_info);
753	if (ret == NULL)
754		goto fail;
755	return ret;
756}
757
758struct fetch_context *
759arch_fetch_arg_clone(struct process *proc, struct fetch_context *context)
760{
761	struct fetch_context *ret = malloc(sizeof(*ret));
762	if (ret == NULL)
763		return NULL;
764	return memcpy(ret, context, sizeof(*ret));
765}
766
767static int
768arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type,
769			 struct process *proc, struct arg_type_info *info,
770			 struct value *valuep, enum reg_pool pool)
771{
772	enum arg_class classes[2];
773	size_t sz, sz1;
774	ssize_t i;
775	ssize_t nclasses = classify_argument(proc, context, info, valuep,
776					     classes, &sz);
777	if (nclasses == -1)
778		return -1;
779	if (value_reserve(valuep, sz) == NULL)
780		return -1;
781
782	/* If there are no registers available for any eightbyte of an
783	 * argument, the whole argument is passed on the stack.  If
784	 * registers have already been assigned for some eightbytes of
785	 * such an argument, the assignments get reverted.  */
786	struct fetch_context tmp_context = *context;
787	int revert;
788	if (nclasses == 1) {
789		revert = allocate_class(classes[0], &tmp_context,
790					valuep, sz, 0, pool) != classes[0];
791	} else {
792		revert = 0;
793		for (i = 0; i < nclasses; ++i) {
794			sz1 = (size_t)(8 * (i + 1)) > sz ? sz - 8 * i : 8;
795			if (allocate_class(classes[i], &tmp_context, valuep,
796					   sz1, 8 * i, pool) != classes[i])
797				revert = 1;
798		}
799	}
800
801	if (nclasses > 1 && revert)
802		allocate_class(CLASS_MEMORY, context, valuep, sz, 0, pool);
803	else
804		*context = tmp_context; /* Commit.  */
805
806	return 0;
807}
808
809int
810arch_fetch_fun_retval(struct fetch_context *context, enum tof type,
811		      struct process *proc, struct arg_type_info *info,
812		      struct value *valuep)
813{
814	assert(type != LT_TOF_FUNCTION
815	       && type != LT_TOF_SYSCALL);
816	if (value_reserve(valuep, 8 * context->u.x86_64.num_ret_classes) == NULL
817	    || fetch_register_banks(proc, context,
818				    type == LT_TOF_FUNCTIONR) < 0)
819		return -1;
820
821	if (context->u.x86_64.num_ret_classes == 1
822	    && context->u.x86_64.ret_classes[0] == CLASS_MEMORY)
823		pass_by_reference(valuep, context->u.x86_64.ret_classes);
824
825	size_t sz = type_sizeof(proc, valuep->type);
826	if (sz == (size_t)-1)
827		return -1;
828
829	ssize_t i;
830	size_t sz1 = context->u.x86_64.num_ret_classes == 1 ? sz : 8;
831	for (i = 0; i < context->u.x86_64.num_ret_classes; ++i) {
832		enum arg_class cls
833			= allocate_class(context->u.x86_64.ret_classes[i],
834					 context, valuep, sz1,
835					 8 * i, POOL_RETVAL);
836		assert(cls == context->u.x86_64.ret_classes[i]);
837	}
838	return 0;
839}
840
841int
842arch_fetch_arg_next(struct fetch_context *context, enum tof type,
843		    struct process *proc, struct arg_type_info *info,
844		    struct value *valuep)
845{
846	if (proc->e_machine == EM_386)
847		return arch_fetch_arg_next_32(context, type, proc,
848					      info, valuep);
849
850	switch (type) {
851	case LT_TOF_FUNCTION:
852	case LT_TOF_FUNCTIONR:
853		return arch_fetch_pool_arg_next(context, type, proc,
854						info, valuep, POOL_FUNCALL);
855
856	case LT_TOF_SYSCALL:
857	case LT_TOF_SYSCALLR:
858		return arch_fetch_pool_arg_next(context, type, proc,
859						info, valuep, POOL_SYSCALL);
860	}
861
862	abort();
863}
864
865int
866arch_fetch_retval(struct fetch_context *context, enum tof type,
867		  struct process *proc, struct arg_type_info *info,
868		  struct value *valuep)
869{
870	if (proc->e_machine == EM_386)
871		return arch_fetch_retval_32(context, type, proc, info, valuep);
872
873	return arch_fetch_fun_retval(context, type, proc, info, valuep);
874}
875
876void
877arch_fetch_arg_done(struct fetch_context *context)
878{
879	if (context != NULL)
880		free(context);
881}
882