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