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