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 
40 enum arg_class {
41 	CLASS_INTEGER,
42 	CLASS_SSE,
43 	CLASS_NO,
44 	CLASS_MEMORY,
45 	CLASS_X87,
46 };
47 
48 enum 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 
56 struct 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
i386_unreachable(void)82 i386_unreachable(void)
83 {
84 	abort();
85 }
86 #endif
87 
88 static int
contains_unaligned_fields(struct arg_type_info * info)89 contains_unaligned_fields(struct arg_type_info *info)
90 {
91 	/* XXX currently we don't support structure alignment.  */
92 	return 0;
93 }
94 
95 static int
has_nontrivial_ctor_dtor(struct arg_type_info * info)96 has_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 
104 static void
copy_int_register(struct fetch_context * context,struct value * valuep,unsigned long val,size_t offset)105 copy_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 
115 static void
copy_sse_register(struct fetch_context * context,struct value * valuep,int half,size_t sz,size_t offset)116 copy_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 
136 static void
allocate_stack_slot(struct fetch_context * context,struct value * valuep,size_t sz,size_t offset,size_t archw)137 allocate_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 
152 static enum arg_class
allocate_x87(struct fetch_context * context,struct value * valuep,size_t sz,size_t offset,enum reg_pool pool,size_t archw)153 allocate_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 
212 static enum arg_class
allocate_integer(struct fetch_context * context,struct value * valuep,size_t sz,size_t offset,enum reg_pool pool)213 allocate_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 
297 static enum arg_class
allocate_sse(struct fetch_context * context,struct value * valuep,size_t sz,size_t offset,enum reg_pool pool)298 allocate_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.  */
325 static enum arg_class
allocate_class(enum arg_class cls,struct fetch_context * context,struct value * valuep,size_t sz,size_t offset,enum reg_pool pool)326 allocate_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 
347 static ssize_t
348 classify(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.  */
353 static ssize_t
classify_eightbyte(struct process * proc,struct fetch_context * context,struct arg_type_info * info,enum arg_class * classp,size_t start,size_t end,struct arg_type_info * (* getter)(struct arg_type_info *,size_t))354 classify_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.  */
388 static ssize_t
classify_eightbytes(struct process * proc,struct fetch_context * context,struct arg_type_info * info,enum arg_class classes[],size_t elements,size_t eightbytes,struct arg_type_info * (* getter)(struct arg_type_info *,size_t))389 classify_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 
429 static struct arg_type_info *
get_array_field(struct arg_type_info * info,size_t emt)430 get_array_field(struct arg_type_info *info, size_t emt)
431 {
432 	return info->u.array_info.elt_type;
433 }
434 
435 static int
flatten_structure(struct arg_type_info * flattened,struct arg_type_info * info)436 flatten_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 
456 static ssize_t
classify(struct process * proc,struct fetch_context * context,struct arg_type_info * info,enum arg_class classes[],size_t sz,size_t eightbytes)457 classify(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 
532 static ssize_t
pass_by_reference(struct value * valuep,enum arg_class classes[])533 pass_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 
541 static ssize_t
classify_argument(struct process * proc,struct fetch_context * context,struct arg_type_info * info,struct value * valuep,enum arg_class classes[],size_t * sizep)542 classify_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 
569 static int
fetch_register_banks(struct process * proc,struct fetch_context * context,int floating)570 fetch_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 
589 static int
arch_fetch_arg_next_32(struct fetch_context * context,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)590 arch_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 
612 static int
arch_fetch_retval_32(struct fetch_context * context,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)613 arch_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 
666 static arch_addr_t
fetch_stack_pointer(struct fetch_context * context)667 fetch_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 
678 struct fetch_context *
arch_fetch_arg_init_32(struct fetch_context * context,enum tof type,struct process * proc,struct arg_type_info * ret_info)679 arch_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 
705 struct fetch_context *
arch_fetch_arg_init_64(struct fetch_context * ctx,enum tof type,struct process * proc,struct arg_type_info * ret_info)706 arch_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 
731 struct fetch_context *
arch_fetch_arg_init(enum tof type,struct process * proc,struct arg_type_info * ret_info)732 arch_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 
758 struct fetch_context *
arch_fetch_arg_clone(struct process * proc,struct fetch_context * context)759 arch_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 
767 static int
arch_fetch_pool_arg_next(struct fetch_context * context,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep,enum reg_pool pool)768 arch_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 
809 int
arch_fetch_fun_retval(struct fetch_context * context,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)810 arch_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 
841 int
arch_fetch_arg_next(struct fetch_context * context,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)842 arch_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 
865 int
arch_fetch_retval(struct fetch_context * context,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)866 arch_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 
876 void
arch_fetch_arg_done(struct fetch_context * context)877 arch_fetch_arg_done(struct fetch_context *context)
878 {
879 	if (context != NULL)
880 		free(context);
881 }
882