fetch.c revision 5b5c256d0e9076e745908a43acc46353265a5608
1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 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
31#include "backend.h"
32#include "expr.h"
33#include "fetch.h"
34#include "proc.h"
35#include "ptrace.h"
36#include "type.h"
37#include "value.h"
38
39enum arg_class {
40	CLASS_INTEGER,
41	CLASS_SSE,
42	CLASS_NO,
43	CLASS_MEMORY,
44	CLASS_X87,
45};
46
47enum reg_pool {
48	POOL_FUNCALL,
49	POOL_SYSCALL,
50	/* A common pool for system call and function call return is
51	 * enough, the ABI is similar enough.  */
52	POOL_RETVAL,
53};
54
55struct fetch_context
56{
57	struct user_regs_struct iregs;
58	struct user_fpregs_struct fpregs;
59
60	void *stack_pointer;
61	size_t ireg;	/* Used-up integer registers.  */
62	size_t freg;	/* Used-up floating registers.  */
63
64	union {
65		struct {
66			/* Storage classes for return type.  We need
67			 * to compute them anyway, so let's keep them
68			 * around.  */
69			enum arg_class ret_classes[2];
70			ssize_t num_ret_classes;
71		} x86_64;
72		struct {
73			struct value retval;
74		} ix86;
75	} u;
76};
77
78#ifndef __x86_64__
79__attribute__((noreturn)) static void
80i386_unreachable(void)
81{
82	abort();
83}
84#endif
85
86static int
87contains_unaligned_fields(struct arg_type_info *info)
88{
89	/* XXX currently we don't support structure alignment.  */
90	return 0;
91}
92
93static int
94has_nontrivial_ctor_dtor(struct arg_type_info *info)
95{
96	/* XXX another unsupported aspect of type info.  We might call
97	 * these types "class" instead of "struct" in the config
98	 * file.  */
99	return 0;
100}
101
102static void
103copy_int_register(struct fetch_context *context,
104		  struct value *valuep, unsigned long val, size_t offset)
105{
106	if (valuep != NULL) {
107		unsigned char *buf = value_get_raw_data(valuep);
108		memcpy(buf + offset, &val, sizeof(val));
109	}
110	context->ireg++;
111}
112
113static void
114copy_sse_register(struct fetch_context *context, struct value *valuep,
115		  int half, size_t sz, size_t offset)
116{
117#ifdef __x86_64__
118	union {
119		uint32_t sse[4];
120		long halves[2];
121	} u;
122	size_t off = 4 * context->freg++;
123	memcpy(u.sse, context->fpregs.xmm_space + off, sizeof(u.sse));
124
125	if (valuep != NULL) {
126		unsigned char *buf = value_get_raw_data(valuep);
127		memcpy(buf + offset, u.halves + half, sz);
128	}
129#else
130	i386_unreachable();
131#endif
132}
133
134static void
135allocate_stack_slot(struct fetch_context *context,
136		    struct value *valuep, size_t sz, size_t offset,
137		    size_t archw)
138{
139	size_t a = type_alignof(valuep->inferior, valuep->type);
140	if (a < archw)
141		a = archw;
142	context->stack_pointer
143		= (void *)align((unsigned long)context->stack_pointer, a);
144
145	if (valuep != NULL) {
146		valuep->where = VAL_LOC_INFERIOR;
147		valuep->u.address = context->stack_pointer;
148	}
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		switch (context->ireg) {
243			HANDLE(0, rdi);
244			HANDLE(1, rsi);
245			HANDLE(2, rdx);
246			HANDLE(3, r10);
247			HANDLE(4, r8);
248			HANDLE(5, r9);
249		default:
250			assert(!"More than six syscall arguments???");
251			abort();
252		}
253#else
254		i386_unreachable();
255#endif
256
257	case POOL_RETVAL:
258		switch (context->ireg) {
259#ifdef __x86_64__
260			HANDLE(0, rax);
261			HANDLE(1, rdx);
262#else
263			HANDLE(0, eax);
264#endif
265		default:
266			assert(!"Too many return value classes.");
267			abort();
268		}
269	}
270
271	abort();
272
273#undef HANDLE
274}
275
276static enum arg_class
277allocate_sse(struct fetch_context *context, struct value *valuep,
278	     size_t sz, size_t offset, enum reg_pool pool)
279{
280	size_t num_regs = 0;
281	switch (pool) {
282	case POOL_FUNCALL:
283		num_regs = 8;
284	case POOL_SYSCALL:
285		break;
286	case POOL_RETVAL:
287		num_regs = 2;
288	}
289
290	if (context->freg >= num_regs) {
291		/* We shouldn't see overflow for RETVAL or SYSCALL
292		 * pool.  */
293		assert(pool == POOL_FUNCALL);
294		allocate_stack_slot(context, valuep, sz, offset, 8);
295		return CLASS_MEMORY;
296	} else {
297		copy_sse_register(context, valuep, 0, sz, offset);
298		return CLASS_SSE;
299	}
300}
301
302/* This allocates registers or stack space for another argument of the
303 * class CLS.  */
304static enum arg_class
305allocate_class(enum arg_class cls, struct fetch_context *context,
306	       struct value *valuep, size_t sz, size_t offset, enum reg_pool pool)
307{
308	switch (cls) {
309	case CLASS_MEMORY:
310		allocate_stack_slot(context, valuep, sz, offset, 8);
311	case CLASS_NO:
312		return cls;
313
314	case CLASS_INTEGER:
315		return allocate_integer(context, valuep, sz, offset, pool);
316
317	case CLASS_SSE:
318		return allocate_sse(context, valuep, sz, offset, pool);
319
320	case CLASS_X87:
321		return allocate_x87(context, valuep, sz, offset, pool, 8);
322	}
323	abort();
324}
325
326static ssize_t
327classify(struct Process *proc, struct fetch_context *context,
328	 struct arg_type_info *info, struct value *valuep, enum arg_class classes[],
329	 size_t sz, size_t eightbytes);
330
331/* This classifies one eightbyte part of an array or struct.  */
332static ssize_t
333classify_eightbyte(struct Process *proc, struct fetch_context *context,
334		   struct arg_type_info *info, struct value *valuep,
335		   enum arg_class *classp, size_t start, size_t end,
336		   struct arg_type_info *(*getter)(struct arg_type_info *,
337						   size_t))
338{
339	size_t i;
340	enum arg_class cls = CLASS_NO;
341	for (i = start; i < end; ++i) {
342		enum arg_class cls2;
343		struct arg_type_info *info2 = getter(info, i);
344		size_t sz = type_sizeof(proc, info2);
345		if (sz == (size_t)-1)
346			return -1;
347		if (classify(proc, context, info2, valuep, &cls2, sz, 1) < 0)
348			return -1;
349
350		if (cls == CLASS_NO)
351			cls = cls2;
352		else if (cls2 == CLASS_NO || cls == cls2)
353			;
354		else if (cls == CLASS_MEMORY || cls2 == CLASS_MEMORY)
355			cls = CLASS_MEMORY;
356		else if (cls == CLASS_INTEGER || cls2 == CLASS_INTEGER)
357			cls = CLASS_INTEGER;
358		else
359			cls = CLASS_SSE;
360	}
361
362	*classp = cls;
363	return 1;
364}
365
366/* This classifies small arrays and structs.  */
367static ssize_t
368classify_eightbytes(struct Process *proc, struct fetch_context *context,
369		    struct arg_type_info *info, struct value *valuep,
370		    enum arg_class classes[], size_t elements,
371		    size_t eightbytes,
372		    struct arg_type_info *(*getter)(struct arg_type_info *,
373						    size_t))
374{
375	if (eightbytes > 1) {
376		/* Where the second eightbyte starts.  Number of the
377		 * first element in the structure that belongs to the
378		 * second eightbyte.  */
379		size_t start_2nd = 0;
380		size_t i;
381		for (i = 0; i < elements; ++i)
382			if (type_offsetof(proc, info, i) >= 8) {
383				start_2nd = i;
384				break;
385			}
386
387		enum arg_class cls1, cls2;
388		if (classify_eightbyte(proc, context, info, valuep, &cls1,
389				       0, start_2nd, getter) < 0
390		    || classify_eightbyte(proc, context, info, valuep, &cls2,
391					  start_2nd, elements, getter) < 0)
392			return -1;
393
394		if (cls1 == CLASS_MEMORY || cls2 == CLASS_MEMORY) {
395			classes[0] = CLASS_MEMORY;
396			return 1;
397		}
398
399		classes[0] = cls1;
400		classes[1] = cls2;
401		return 2;
402	}
403
404	return classify_eightbyte(proc, context, info, valuep, classes,
405				  0, elements, getter);
406}
407
408static struct arg_type_info *
409get_array_field(struct arg_type_info *info, size_t emt)
410{
411	return info->u.array_info.elt_type;
412}
413
414static int
415flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info)
416{
417	size_t i;
418	for (i = 0; i < type_struct_size(info); ++i) {
419		struct arg_type_info *field = type_struct_get(info, i);
420		assert(field != NULL);
421		switch (field->type) {
422		case ARGTYPE_STRUCT:
423			if (flatten_structure(flattened, field) < 0)
424				return -1;
425			break;
426
427		default:
428			if (type_struct_add(flattened, field, 0) < 0)
429				return -1;
430		}
431	}
432	return 0;
433}
434
435static ssize_t
436classify(struct Process *proc, struct fetch_context *context,
437	 struct arg_type_info *info, struct value *valuep, enum arg_class classes[],
438	 size_t sz, size_t eightbytes)
439{
440	switch (info->type) {
441		struct arg_type_info flattened;
442	case ARGTYPE_VOID:
443		return 0;
444
445	case ARGTYPE_CHAR:
446	case ARGTYPE_SHORT:
447	case ARGTYPE_USHORT:
448	case ARGTYPE_INT:
449	case ARGTYPE_UINT:
450	case ARGTYPE_LONG:
451	case ARGTYPE_ULONG:
452
453	case ARGTYPE_POINTER:
454		/* and LONGLONG */
455		/* CLASS_INTEGER */
456		classes[0] = CLASS_INTEGER;
457		return 1;
458
459	case ARGTYPE_FLOAT:
460	case ARGTYPE_DOUBLE:
461		/* and DECIMAL, and _m64 */
462		classes[0] = CLASS_SSE;
463		return 1;
464
465	case ARGTYPE_ARRAY:
466		/* N.B. this cannot be top-level array, those decay to
467		 * pointers.  Therefore, it must be inside structure
468		 * that's at most 2 eightbytes long.  */
469
470		/* Structures with flexible array members can't be
471		 * passed by value.  */
472		assert(expr_is_compile_constant(info->u.array_info.length));
473
474		long l;
475		if (expr_eval_constant(info->u.array_info.length, &l) < 0)
476			return -1;
477
478		return classify_eightbytes(proc, context, info, valuep, classes,
479					   (size_t)l, eightbytes,
480					   get_array_field);
481
482	case ARGTYPE_STRUCT:
483		/* N.B. "big" structs are dealt with in the caller.
484		 *
485		 * First, we need to flatten the structure.  In
486		 * struct(float,struct(float,float)), first two floats
487		 * both belong to the same eightbyte.  */
488		type_init_struct(&flattened);
489
490		ssize_t ret;
491		if (flatten_structure(&flattened, info) < 0) {
492			ret = -1;
493			goto done;
494		}
495		ret = classify_eightbytes(proc, context, &flattened,
496					  valuep, classes,
497					  type_struct_size(&flattened),
498					  eightbytes, type_struct_get);
499	done:
500		type_destroy(&flattened);
501		return ret;
502
503	default:
504		/* Unsupported type.  */
505		assert(info->type != info->type);
506		abort();
507	}
508	abort();
509}
510
511static ssize_t
512pass_by_reference(struct value *valuep, enum arg_class classes[])
513{
514	if (valuep != NULL && value_pass_by_reference(valuep) < 0)
515		return -1;
516	classes[0] = CLASS_INTEGER;
517	return 1;
518}
519
520static ssize_t
521classify_argument(struct Process *proc, struct fetch_context *context,
522		  struct arg_type_info *info, struct value *valuep,
523		  enum arg_class classes[], size_t *sizep)
524{
525	size_t sz = type_sizeof(proc, info);
526	if (sz == (size_t)-1)
527		return -1;
528	*sizep = sz;
529
530	size_t eightbytes = (sz + 7) / 8;  /* Round up.  */
531
532	/* Arrays decay into pointers.  */
533	assert(info->type != ARGTYPE_ARRAY);
534
535	if (info->type == ARGTYPE_STRUCT) {
536		if (eightbytes > 2 || contains_unaligned_fields(info)) {
537			classes[0] = CLASS_MEMORY;
538			return 1;
539		}
540
541		if (has_nontrivial_ctor_dtor(info))
542			return pass_by_reference(valuep, classes);
543	}
544
545	return classify(proc, context, info, valuep, classes, sz, eightbytes);
546}
547
548static int
549fetch_register_banks(struct Process *proc, struct fetch_context *context,
550		     int floating)
551{
552	if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->iregs) < 0)
553		return -1;
554	context->ireg = 0;
555
556	if (floating) {
557		if (ptrace(PTRACE_GETFPREGS, proc->pid,
558			   0, &context->fpregs) < 0)
559			return -1;
560		context->freg = 0;
561	} else {
562		context->freg = -1;
563	}
564
565	return 0;
566}
567
568static int
569arch_fetch_arg_next_32(struct fetch_context *context, enum tof type,
570		       struct Process *proc, struct arg_type_info *info,
571		       struct value *valuep)
572{
573	size_t sz = type_sizeof(proc, info);
574	if (sz == (size_t)-1)
575		return -1;
576
577	allocate_stack_slot(context, valuep, sz, 0, 4);
578
579	return 0;
580}
581
582static int
583arch_fetch_retval_32(struct fetch_context *context, enum tof type,
584		     struct Process *proc, struct arg_type_info *info,
585		     struct value *valuep)
586{
587	if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0)
588		return -1;
589
590	struct value *retval = &context->u.ix86.retval;
591	if (retval->type != NULL) {
592		/* Struct return value was extracted when in fetch
593		 * init.  */
594		memcpy(valuep, &context->u.ix86.retval, sizeof(*valuep));
595		return 0;
596	}
597
598	size_t sz = type_sizeof(proc, info);
599	if (sz == (size_t)-1)
600		return -1;
601	if (value_reserve(valuep, sz) == NULL)
602		return -1;
603
604	switch (info->type) {
605		enum arg_class cls;
606	case ARGTYPE_VOID:
607		return 0;
608
609	case ARGTYPE_INT:
610	case ARGTYPE_UINT:
611	case ARGTYPE_LONG:
612	case ARGTYPE_ULONG:
613	case ARGTYPE_CHAR:
614	case ARGTYPE_SHORT:
615	case ARGTYPE_USHORT:
616	case ARGTYPE_POINTER:
617		cls = allocate_integer(context, valuep, sz, 0, POOL_RETVAL);
618		assert(cls == CLASS_INTEGER);
619		return 0;
620
621	case ARGTYPE_FLOAT:
622	case ARGTYPE_DOUBLE:
623		cls = allocate_x87(context, valuep, sz, 0, POOL_RETVAL, 4);
624		assert(cls == CLASS_X87);
625		return 0;
626
627	case ARGTYPE_STRUCT: /* Handled above.  */
628	default:
629		assert(!"Unexpected i386 retval type!");
630		abort();
631	}
632
633	abort();
634}
635
636static arch_addr_t
637fetch_stack_pointer(struct fetch_context *context)
638{
639	arch_addr_t sp;
640#ifdef __x86_64__
641	sp = (arch_addr_t)context->iregs.rsp;
642#else
643	sp = (arch_addr_t)context->iregs.esp;
644#endif
645	return sp;
646}
647
648struct fetch_context *
649arch_fetch_arg_init_32(struct fetch_context *context,
650		       enum tof type, struct Process *proc,
651		       struct arg_type_info *ret_info)
652{
653	context->stack_pointer = fetch_stack_pointer(context) + 4;
654
655	size_t sz = type_sizeof(proc, ret_info);
656	if (sz == (size_t)-1)
657		return NULL;
658
659	struct value *retval = &context->u.ix86.retval;
660	if (ret_info->type == ARGTYPE_STRUCT) {
661		value_init(retval, proc, NULL, ret_info, 0);
662
663		enum arg_class dummy[2];
664		if (pass_by_reference(retval, dummy) < 0)
665			return NULL;
666		allocate_stack_slot(context, retval, 4, 0, 4);
667
668	} else {
669		value_init_detached(retval, NULL, NULL, 0);
670	}
671
672	return context;
673}
674
675struct fetch_context *
676arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type,
677		       struct Process *proc, struct arg_type_info *ret_info)
678{
679	/* The first stack slot holds a return address.  */
680	ctx->stack_pointer = fetch_stack_pointer(ctx) + 8;
681
682	size_t size;
683	ctx->u.x86_64.num_ret_classes
684		= classify_argument(proc, ctx, ret_info, NULL,
685				    ctx->u.x86_64.ret_classes, &size);
686	if (ctx->u.x86_64.num_ret_classes == -1)
687		return NULL;
688
689	/* If the class is MEMORY, then the first argument is a hidden
690	 * pointer to the allocated storage.  */
691	if (ctx->u.x86_64.num_ret_classes > 0
692	    && ctx->u.x86_64.ret_classes[0] == CLASS_MEMORY) {
693		/* MEMORY should be the sole class.  */
694		assert(ctx->u.x86_64.num_ret_classes == 1);
695		allocate_integer(ctx, NULL, size, 0, POOL_FUNCALL);
696	}
697
698	return ctx;
699}
700
701struct fetch_context *
702arch_fetch_arg_init(enum tof type, struct Process *proc,
703		    struct arg_type_info *ret_info)
704{
705	struct fetch_context *ctx = malloc(sizeof(*ctx));
706	if (ctx == NULL)
707		return NULL;
708
709	assert(type != LT_TOF_FUNCTIONR
710	       && type != LT_TOF_SYSCALLR);
711	if (fetch_register_banks(proc, ctx, type == LT_TOF_FUNCTION) < 0) {
712	fail:
713		free(ctx);
714		return NULL;
715	}
716
717	struct fetch_context *ret;
718	if (proc->e_machine == EM_386)
719		ret = arch_fetch_arg_init_32(ctx, type, proc, ret_info);
720	else
721		ret = arch_fetch_arg_init_64(ctx, type, proc, ret_info);
722	if (ret == NULL)
723		goto fail;
724	return ret;
725}
726
727struct fetch_context *
728arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
729{
730	struct fetch_context *ret = malloc(sizeof(*ret));
731	if (ret == NULL)
732		return NULL;
733	return memcpy(ret, context, sizeof(*ret));
734}
735
736static int
737arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type,
738			 struct Process *proc, struct arg_type_info *info,
739			 struct value *valuep, enum reg_pool pool)
740{
741	enum arg_class classes[2];
742	size_t sz, sz1;
743	ssize_t i;
744	ssize_t nclasses = classify_argument(proc, context, info, valuep,
745					     classes, &sz);
746	if (nclasses == -1)
747		return -1;
748	if (value_reserve(valuep, sz) == NULL)
749		return -1;
750
751	/* If there are no registers available for any eightbyte of an
752	 * argument, the whole argument is passed on the stack.  If
753	 * registers have already been assigned for some eightbytes of
754	 * such an argument, the assignments get reverted.  */
755	struct fetch_context tmp_context = *context;
756	int revert;
757	if (nclasses == 1) {
758		revert = allocate_class(classes[0], &tmp_context,
759					valuep, sz, 0, pool) != classes[0];
760	} else {
761		revert = 0;
762		for (i = 0; i < nclasses; ++i) {
763			sz1 = (size_t)(8 * (i + 1)) > sz ? sz - 8 * i : 8;
764			if (allocate_class(classes[i], &tmp_context, valuep,
765					   sz1, 8 * i, pool) != classes[i])
766				revert = 1;
767		}
768	}
769
770	if (nclasses > 1 && revert)
771		allocate_class(CLASS_MEMORY, context, valuep, sz, 0, pool);
772	else
773		*context = tmp_context; /* Commit.  */
774
775	return 0;
776}
777
778int
779arch_fetch_fun_retval(struct fetch_context *context, enum tof type,
780		      struct Process *proc, struct arg_type_info *info,
781		      struct value *valuep)
782{
783	assert(type != LT_TOF_FUNCTION
784	       && type != LT_TOF_SYSCALL);
785	if (value_reserve(valuep, 8 * context->u.x86_64.num_ret_classes) == NULL
786	    || fetch_register_banks(proc, context,
787				    type == LT_TOF_FUNCTIONR) < 0)
788		return -1;
789
790	if (context->u.x86_64.num_ret_classes == 1
791	    && context->u.x86_64.ret_classes[0] == CLASS_MEMORY)
792		pass_by_reference(valuep, context->u.x86_64.ret_classes);
793
794	size_t sz = type_sizeof(proc, valuep->type);
795	if (sz == (size_t)-1)
796		return -1;
797
798	ssize_t i;
799	size_t sz1 = context->u.x86_64.num_ret_classes == 1 ? sz : 8;
800	for (i = 0; i < context->u.x86_64.num_ret_classes; ++i) {
801		enum arg_class cls
802			= allocate_class(context->u.x86_64.ret_classes[i],
803					 context, valuep, sz1,
804					 8 * i, POOL_RETVAL);
805		assert(cls == context->u.x86_64.ret_classes[i]);
806	}
807	return 0;
808}
809
810int
811arch_fetch_arg_next(struct fetch_context *context, enum tof type,
812		    struct Process *proc, struct arg_type_info *info,
813		    struct value *valuep)
814{
815	if (proc->e_machine == EM_386)
816		return arch_fetch_arg_next_32(context, type, proc,
817					      info, valuep);
818
819	switch (type) {
820	case LT_TOF_FUNCTION:
821	case LT_TOF_FUNCTIONR:
822		return arch_fetch_pool_arg_next(context, type, proc,
823						info, valuep, POOL_FUNCALL);
824
825	case LT_TOF_SYSCALL:
826	case LT_TOF_SYSCALLR:
827		return arch_fetch_pool_arg_next(context, type, proc,
828						info, valuep, POOL_SYSCALL);
829	}
830
831	abort();
832}
833
834int
835arch_fetch_retval(struct fetch_context *context, enum tof type,
836		  struct Process *proc, struct arg_type_info *info,
837		  struct value *valuep)
838{
839	if (proc->e_machine == EM_386)
840		return arch_fetch_retval_32(context, type, proc, info, valuep);
841
842	return arch_fetch_fun_retval(context, type, proc, info, valuep);
843}
844
845void
846arch_fetch_arg_done(struct fetch_context *context)
847{
848	if (context != NULL)
849		free(context);
850}
851