Home | History | Annotate | Download | only in x86
      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
     82 i386_unreachable(void)
     83 {
     84 	abort();
     85 }
     86 #endif
     87 
     88 static int
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    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
    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
    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
    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
    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 *
    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 *
    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 *
    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 *
    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
    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
    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
    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
    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
    877 arch_fetch_arg_done(struct fetch_context *context)
    878 {
    879 	if (context != NULL)
    880 		free(context);
    881 }
    882