1000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata/* 2000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * This file is part of ltrace. 37e3f650f22b7161f897532aad808d3b8f61fd6f4Petr Machata * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. 4000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * Copyright (C) 2007,2008 Juan Cespedes 5000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * 6000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * This program is free software; you can redistribute it and/or 7000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * modify it under the terms of the GNU General Public License as 8000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * published by the Free Software Foundation; either version 2 of the 9000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * License, or (at your option) any later version. 10000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * 11000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * This program is distributed in the hope that it will be useful, but 12000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 13000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * General Public License for more details. 15000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * 16000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * You should have received a copy of the GNU General Public License 17000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * along with this program; if not, write to the Free Software 18000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 19000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * 02110-1301 USA 20000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata */ 21000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 22000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#include <assert.h> 23000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#include <stdlib.h> 24c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata#include <limits.h> 25000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 26000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#include "type.h" 27000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#include "sysdep.h" 2894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "expr.h" 2931af32cfcd61671cbb5e567870103766b3231521Petr Machata#include "lens.h" 30000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 31000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastruct arg_type_info * 32000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_get_simple(enum arg_type type) 33000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 34000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#define HANDLE(T) { \ 35000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static struct arg_type_info t = { T }; \ 36000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case T: \ 37000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return &t; \ 38000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 39000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 40000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata switch (type) { 41000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_VOID) 42000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_INT) 43000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_UINT) 44000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_LONG) 45000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_ULONG) 46000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_CHAR) 47000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_SHORT) 48000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_USHORT) 49000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_FLOAT) 50000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata HANDLE(ARGTYPE_DOUBLE) 51000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 52000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#undef HANDLE 53000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 54000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ARRAY: 55000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_STRUCT: 56000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_POINTER: 57000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(!"Not a simple type!"); 58000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata }; 59000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata abort(); 60000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 61000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 62c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machatastruct arg_type_info * 63c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machatatype_get_voidptr(void) 64c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata{ 65c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata struct arg_type_info *void_info = type_get_simple(ARGTYPE_VOID); 66c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata static struct arg_type_info *ret; 67c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata if (ret == NULL) { 68c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata static struct arg_type_info ptr_info; 69c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata type_init_pointer(&ptr_info, void_info, 0); 70c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata ret = &ptr_info; 71c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata } 72c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata return ret; 73c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata} 74c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata 7531af32cfcd61671cbb5e567870103766b3231521Petr Machatastatic void 7631af32cfcd61671cbb5e567870103766b3231521Petr Machatatype_init_common(struct arg_type_info *info, enum arg_type type) 7731af32cfcd61671cbb5e567870103766b3231521Petr Machata{ 7831af32cfcd61671cbb5e567870103766b3231521Petr Machata info->type = type; 7931af32cfcd61671cbb5e567870103766b3231521Petr Machata info->lens = NULL; 8031af32cfcd61671cbb5e567870103766b3231521Petr Machata info->own_lens = 0; 8131af32cfcd61671cbb5e567870103766b3231521Petr Machata} 8231af32cfcd61671cbb5e567870103766b3231521Petr Machata 83000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastruct struct_field { 84000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct arg_type_info *info; 85000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata int own_info; 86000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata}; 87000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 88000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatavoid 89000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_init_struct(struct arg_type_info *info) 90000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 9131af32cfcd61671cbb5e567870103766b3231521Petr Machata type_init_common(info, ARGTYPE_STRUCT); 92000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata VECT_INIT(&info->u.entries, struct struct_field); 93000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 94000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 95000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machataint 96000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_struct_add(struct arg_type_info *info, 97000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct arg_type_info *field_info, int own) 98000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 99000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(info->type == ARGTYPE_STRUCT); 100000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct struct_field field = { field_info, own }; 101000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return VECT_PUSHBACK(&info->u.entries, &field); 102000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 103000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 104000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastruct arg_type_info * 105000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_struct_get(struct arg_type_info *info, size_t idx) 106000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 107000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(info->type == ARGTYPE_STRUCT); 1087e3f650f22b7161f897532aad808d3b8f61fd6f4Petr Machata return VECT_ELEMENT(&info->u.entries, struct struct_field, idx)->info; 109000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 110000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 111000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatasize_t 112000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_struct_size(struct arg_type_info *info) 113000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 114000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(info->type == ARGTYPE_STRUCT); 115000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return vect_size(&info->u.entries); 116000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 117000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 118000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastatic void 119000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastruct_field_dtor(struct struct_field *field, void *data) 120000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 121000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (field->own_info) { 122000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata type_destroy(field->info); 123000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata free(field->info); 124000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 125000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 126000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 127000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastatic void 128000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_struct_destroy(struct arg_type_info *info) 129000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 130000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata VECT_DESTROY(&info->u.entries, struct struct_field, 131000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct_field_dtor, NULL); 132000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 133000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 134000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastatic int 135929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatalayout_struct(struct process *proc, struct arg_type_info *info, 136000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t *sizep, size_t *alignmentp, size_t *offsetofp) 137000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 138000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t sz = 0; 139000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t max_alignment = 0; 140000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t i; 141000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t offsetof_field = (size_t)-1; 142000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (offsetofp != NULL) 143000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata offsetof_field = *offsetofp; 144000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 145000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(info->type == ARGTYPE_STRUCT); 146000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata for (i = 0; i < vect_size(&info->u.entries); ++i) { 147000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct struct_field *field 148000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata = VECT_ELEMENT(&info->u.entries, 149000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct struct_field, i); 150000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 151000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t alignment = type_alignof(proc, field->info); 152000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (alignment == (size_t)-1) 153000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return -1; 154000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 155000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata /* Add padding to SZ to align the next element. */ 156000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata sz = align(sz, alignment); 157000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (i == offsetof_field) { 158000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata *offsetofp = sz; 159000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (sizep == NULL && alignmentp == NULL) 160000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return 0; 161000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 162000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 163000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t size = type_sizeof(proc, field->info); 164000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (size == (size_t)-1) 165000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return -1; 166000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata sz += size; 167000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 168000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (alignment > max_alignment) 169000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata max_alignment = alignment; 170000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 171000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 172000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (max_alignment > 0) 173000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata sz = align(sz, max_alignment); 174000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 175000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (sizep != NULL) 176000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata *sizep = sz; 177000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 178000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (alignmentp != NULL) 179000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata *alignmentp = max_alignment; 180000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 181000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return 0; 182000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 183000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 184000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatavoid 185000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_init_array(struct arg_type_info *info, 186000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct arg_type_info *element_info, int own_info, 187940ec0650bfe0f1deda96d3561be3d0006df92fcPetr Machata struct expr_node *length_expr, int own_length) 188000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 18931af32cfcd61671cbb5e567870103766b3231521Petr Machata type_init_common(info, ARGTYPE_ARRAY); 190000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata info->u.array_info.elt_type = element_info; 191000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata info->u.array_info.own_info = own_info; 192940ec0650bfe0f1deda96d3561be3d0006df92fcPetr Machata info->u.array_info.length = length_expr; 19394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata info->u.array_info.own_length = own_length; 194000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 195000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 196000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastatic void 197000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_array_destroy(struct arg_type_info *info) 198000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 199000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (info->u.array_info.own_info) { 200000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata type_destroy(info->u.array_info.elt_type); 201000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata free(info->u.array_info.elt_type); 202000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 203000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (info->u.array_info.own_length) { 204000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata expr_destroy(info->u.array_info.length); 205000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata free(info->u.array_info.length); 206000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 20794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 20894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 209000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatavoid 210000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_init_pointer(struct arg_type_info *info, 211000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct arg_type_info *pointee_info, int own_info) 212000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 21331af32cfcd61671cbb5e567870103766b3231521Petr Machata type_init_common(info, ARGTYPE_POINTER); 214000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata info->u.ptr_info.info = pointee_info; 215000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata info->u.ptr_info.own_info = own_info; 216000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 217000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 218000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastatic void 219000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_pointer_destroy(struct arg_type_info *info) 220000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 221000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (info->u.ptr_info.own_info) { 222000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata type_destroy(info->u.ptr_info.info); 223000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata free(info->u.ptr_info.info); 224000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 225000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 226000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 227000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatavoid 228000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_destroy(struct arg_type_info *info) 229000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 230000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (info == NULL) 231000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return; 232000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 233000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata switch (info->type) { 234000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_STRUCT: 235000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata type_struct_destroy(info); 236000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata break; 237000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 238000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ARRAY: 239000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata type_array_destroy(info); 240000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata break; 241000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 242000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_POINTER: 243000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata type_pointer_destroy(info); 244000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata break; 245000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 246000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_VOID: 247000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_INT: 248000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_UINT: 249000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_LONG: 250000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ULONG: 251000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_CHAR: 252000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_SHORT: 253000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_USHORT: 254000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_FLOAT: 255000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_DOUBLE: 256000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata break; 257000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 25831af32cfcd61671cbb5e567870103766b3231521Petr Machata 25931af32cfcd61671cbb5e567870103766b3231521Petr Machata if (info->own_lens) { 26031af32cfcd61671cbb5e567870103766b3231521Petr Machata lens_destroy(info->lens); 26131af32cfcd61671cbb5e567870103766b3231521Petr Machata free(info->lens); 26231af32cfcd61671cbb5e567870103766b3231521Petr Machata } 263000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 264000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 265cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machatastatic int 266cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machatatype_alloc_and_clone(struct arg_type_info **retpp, 267cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata struct arg_type_info *info, int own) 268cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata{ 269cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata *retpp = info; 270cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (own) { 271cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata *retpp = malloc(sizeof **retpp); 272cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (*retpp == NULL || type_clone(*retpp, info) < 0) { 273cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata free(*retpp); 274cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return -1; 275cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata } 276cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata } 277cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return 0; 278cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata} 279cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 280cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machatastatic enum callback_status 281cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machataclone_struct_add_field(const struct struct_field *field, void *data) 282cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata{ 283cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata struct arg_type_info *retp = data; 284cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata struct arg_type_info *info; 285cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (type_alloc_and_clone(&info, field->info, field->own_info) < 0) { 286cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata fail: 287cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (info != field->info) 288cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata free(info); 289cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return CBS_STOP; 290cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata } 291cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 292cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (type_struct_add(retp, info, field->own_info) < 0) { 293cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (field->own_info) 294cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata type_destroy(info); 295cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata goto fail; 296cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata } 297cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 298cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return CBS_CONT; 299cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata} 300cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 301cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machataint 302cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machatatype_clone(struct arg_type_info *retp, const struct arg_type_info *info) 303cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata{ 304cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata switch (info->type) { 305cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_STRUCT: 306cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata type_init_struct(retp); 307cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (VECT_EACH_CST(&info->u.entries, struct struct_field, NULL, 308cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata clone_struct_add_field, retp) != NULL) { 309cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata type_destroy(retp); 310cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return -1; 311cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata } 312cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata break; 313cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 314cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_ARRAY:; 315cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata struct arg_type_info *elt_type; 316cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (type_alloc_and_clone(&elt_type, info->u.array_info.elt_type, 317cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata info->u.array_info.own_info) < 0) 318cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return -1; 319cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 320cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata assert(!info->u.array_info.own_length); // XXXXXXX 321cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata type_init_array(retp, elt_type, info->u.array_info.own_info, 322cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata info->u.array_info.length, 323cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata info->u.array_info.own_length); 324cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata break; 325cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 326cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_POINTER:; 327cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata struct arg_type_info *ninfo; 328cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata if (type_alloc_and_clone(&ninfo, info->u.ptr_info.info, 329cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata info->u.ptr_info.own_info) < 0) 330cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return -1; 331cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata type_init_pointer(retp, ninfo, info->u.ptr_info.own_info); 332cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata break; 333cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 334cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_VOID: 335cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_INT: 336cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_UINT: 337cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_LONG: 338cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_ULONG: 339cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_CHAR: 340cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_SHORT: 341cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_USHORT: 342cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_FLOAT: 343cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata case ARGTYPE_DOUBLE: 344cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata *retp = *info; 345cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata break; 346cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata } 347cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 348cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata assert(!info->own_lens); 349cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata retp->lens = info->lens; 350cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata retp->own_lens = info->own_lens; 351cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata return 0; 352cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata} 353cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata 354000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#ifdef ARCH_HAVE_SIZEOF 355929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatasize_t arch_type_sizeof(struct process *proc, struct arg_type_info *arg); 356000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#else 357000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatasize_t 358929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_type_sizeof(struct process *proc, struct arg_type_info *arg) 359000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 360000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata /* Use default value. */ 361000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-2; 362000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 363000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#endif 364000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 365000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#ifdef ARCH_HAVE_ALIGNOF 366929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatasize_t arch_type_alignof(struct process *proc, struct arg_type_info *arg); 367000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#else 368000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatasize_t 369929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_type_alignof(struct process *proc, struct arg_type_info *arg) 370000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 371000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata /* Use default value. */ 372000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-2; 373000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 374000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#endif 375000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 376000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata/* We need to support alignments that are not power of two. E.g. long 377000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * double on x86 has alignment of 12. */ 378000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatasize_t 379000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machataalign(size_t sz, size_t alignment) 380000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 381000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(alignment != 0); 382000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 383000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if ((sz % alignment) != 0) 384000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata sz = ((sz / alignment) + 1) * alignment; 385000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 386000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sz; 387000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 388000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 389000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatasize_t 390929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatatype_sizeof(struct process *proc, struct arg_type_info *type) 391000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 392000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t arch_size = arch_type_sizeof(proc, type); 393000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (arch_size != (size_t)-2) 394000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return arch_size; 395000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 396000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata switch (type->type) { 397000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t size; 398000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_CHAR: 399000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sizeof(char); 400000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 401000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_SHORT: 402000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_USHORT: 403000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sizeof(short); 404000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 405000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_INT: 406000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_UINT: 407000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sizeof(int); 408000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 409000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_LONG: 410000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ULONG: 411000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sizeof(long); 412000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 413000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_FLOAT: 414000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sizeof(float); 415000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 416000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_DOUBLE: 417000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sizeof(double); 418000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 419000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_STRUCT: 420000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (layout_struct(proc, type, &size, NULL, NULL) < 0) 421000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-1; 422000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return size; 423000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 424000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_POINTER: 425000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return sizeof(void *); 426000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 427000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ARRAY: 42894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (expr_is_compile_constant(type->u.array_info.length)) { 429000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata long l; 43094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (expr_eval_constant(type->u.array_info.length, 431000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata &l) < 0) 432000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return -1; 433000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 434000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct arg_type_info *elt_ti 435000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata = type->u.array_info.elt_type; 436000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 437000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t elt_size = type_sizeof(proc, elt_ti); 438000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (elt_size == (size_t)-1) 439000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-1; 440000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 441000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return ((size_t)l) * elt_size; 442000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 443000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } else { 444000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata /* Flexible arrays don't count into the 445000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata * sizeof. */ 446000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return 0; 447000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 448000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 449000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_VOID: 450000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return 0; 451000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 452000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 453000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata abort(); 454000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 455000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 456000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#undef alignof 457000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#define alignof(field,st) ((size_t) ((char*) &st.field - (char*) &st)) 458000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 459000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatasize_t 460929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatatype_alignof(struct process *proc, struct arg_type_info *type) 461000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 462000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t arch_alignment = arch_type_alignof(proc, type); 463000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (arch_alignment != (size_t)-2) 464000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return arch_alignment; 465000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 466000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct { char c; char C; } cC; 467000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct { char c; short s; } cs; 468000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct { char c; int i; } ci; 469000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct { char c; long l; } cl; 470000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct { char c; void* p; } cp; 471000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct { char c; float f; } cf; 472000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata struct { char c; double d; } cd; 473000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 474000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static size_t char_alignment = alignof(C, cC); 475000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static size_t short_alignment = alignof(s, cs); 476000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static size_t int_alignment = alignof(i, ci); 477000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static size_t long_alignment = alignof(l, cl); 478000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static size_t ptr_alignment = alignof(p, cp); 479000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static size_t float_alignment = alignof(f, cf); 480000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata static size_t double_alignment = alignof(d, cd); 481000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 482000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata switch (type->type) { 483000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t alignment; 484000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_LONG: 485000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ULONG: 486000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return long_alignment; 487000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_CHAR: 488000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return char_alignment; 489000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_SHORT: 490000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_USHORT: 491000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return short_alignment; 492000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_FLOAT: 493000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return float_alignment; 494000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_DOUBLE: 495000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return double_alignment; 496000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_POINTER: 497000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return ptr_alignment; 498000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 499000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ARRAY: 500000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return type_alignof(proc, type->u.array_info.elt_type); 501000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 502000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_STRUCT: 503000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (layout_struct(proc, type, NULL, &alignment, NULL) < 0) 504000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-1; 505000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return alignment; 506000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 507000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata default: 508000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return int_alignment; 509000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 510000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 511000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 512000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatasize_t 513929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatatype_offsetof(struct process *proc, struct arg_type_info *type, size_t emt) 514000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 515000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(type->type == ARGTYPE_STRUCT 516e3f4a984db115979e09414b7281da98399dd8949Petr Machata || type->type == ARGTYPE_ARRAY); 517000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 518000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata switch (type->type) { 519000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t alignment; 520000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size_t size; 521000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ARRAY: 522000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata alignment = type_alignof(proc, type->u.array_info.elt_type); 523000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (alignment == (size_t)-1) 524000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-1; 525000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 526000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata size = type_sizeof(proc, type->u.array_info.elt_type); 527000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (size == (size_t)-1) 528000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-1; 529000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 530000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return emt * align(size, alignment); 531000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 532000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_STRUCT: 533000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata if (layout_struct(proc, type, NULL, NULL, &emt) < 0) 534000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return (size_t)-1; 535000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return emt; 536000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 537000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata default: 538e3f4a984db115979e09414b7281da98399dd8949Petr Machata abort(); 539000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 540000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 541000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 542000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatastruct arg_type_info * 543000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machatatype_element(struct arg_type_info *info, size_t emt) 544000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 545000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(info->type == ARGTYPE_STRUCT 546e3f4a984db115979e09414b7281da98399dd8949Petr Machata || info->type == ARGTYPE_ARRAY); 547000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 548000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata switch (info->type) { 549000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_ARRAY: 550000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return info->u.array_info.elt_type; 551000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 552000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata case ARGTYPE_STRUCT: 553000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata assert(emt < type_struct_size(info)); 554000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata return type_struct_get(info, emt); 555000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata 556000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata default: 557e3f4a984db115979e09414b7281da98399dd8949Petr Machata abort(); 558000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata } 559000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata} 560c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata 56164d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machatasize_t 56264d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machatatype_aggregate_size(struct arg_type_info *info) 56364d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata{ 56464d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata assert(info->type == ARGTYPE_STRUCT 56564d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata || info->type == ARGTYPE_ARRAY); 56664d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata 56764d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata switch (info->type) { 56864d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata long ret; 56964d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata case ARGTYPE_ARRAY: 57064d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata if (expr_eval_constant(info->u.array_info.length, &ret) < 0) 57164d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata return (size_t)-1; 57264d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata return (size_t)ret; 57364d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata 57464d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata case ARGTYPE_STRUCT: 57564d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata return type_struct_size(info); 57664d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata 57764d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata default: 57864d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata abort(); 57964d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata } 58064d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata} 58164d6e060aa1d4607e766e40825bd9c9d13e8e1a4Petr Machata 582c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machataint 583c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machatatype_is_integral(enum arg_type type) 584c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata{ 585c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata switch (type) { 586c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_INT: 587c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_UINT: 588c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_LONG: 589c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_ULONG: 590c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_CHAR: 591c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_SHORT: 592c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_USHORT: 593c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata return 1; 594c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata 595c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_VOID: 596c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_FLOAT: 597c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_DOUBLE: 598c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_ARRAY: 599c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_STRUCT: 600c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_POINTER: 601c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata return 0; 602c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata } 603c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata abort(); 604c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata} 605c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata 606c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machataint 607c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machatatype_is_signed(enum arg_type type) 608c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata{ 609c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata assert(type_is_integral(type)); 610c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata 611c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata switch (type) { 612c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_CHAR: 613c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata return CHAR_MIN != 0; 614c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata 615c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_SHORT: 616c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_INT: 617c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_LONG: 618c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata return 1; 619c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata 620c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_UINT: 621c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_ULONG: 622c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_USHORT: 623c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata return 0; 624c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata 625c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_VOID: 626c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_FLOAT: 627c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_DOUBLE: 628c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_ARRAY: 629c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_STRUCT: 630c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata case ARGTYPE_POINTER: 631c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata abort(); 632c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata } 633c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata abort(); 634c07a26a8d0f86bc4137eb7b7fea8bbf9021275f1Petr Machata} 635fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata 636fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machatastruct arg_type_info * 637fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machatatype_get_fp_equivalent(struct arg_type_info *info) 638fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata{ 639fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata /* Extract innermost structure. Give up early if any 640fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata * component has more than one element. */ 641fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata while (info->type == ARGTYPE_STRUCT) { 642fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata if (type_struct_size(info) != 1) 643fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata return NULL; 644fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata info = type_element(info, 0); 645fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata } 646fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata 647fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata switch (info->type) { 648fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_CHAR: 649fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_SHORT: 650fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_INT: 651fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_LONG: 652fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_UINT: 653fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_ULONG: 654fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_USHORT: 655fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_VOID: 656fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_ARRAY: 657fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_POINTER: 658fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata return NULL; 659fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata 660fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_FLOAT: 661fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_DOUBLE: 662fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata return info; 663fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata 664fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata case ARGTYPE_STRUCT: 665fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata abort(); 666fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata } 667fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata abort(); 668fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata} 669982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata 670982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machatastruct arg_type_info * 671982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machatatype_get_hfa_type(struct arg_type_info *info, size_t *countp) 672982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata{ 673982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata assert(info != NULL); 674982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata if (info->type != ARGTYPE_STRUCT 675982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata && info->type != ARGTYPE_ARRAY) 676982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata return NULL; 677982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata 678982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata size_t n = type_aggregate_size(info); 679982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata if (n == (size_t)-1) 680982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata return NULL; 681982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata 682982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata struct arg_type_info *ret = NULL; 683982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata *countp = 0; 684982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata 685982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata while (n-- > 0) { 686982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata struct arg_type_info *emt = type_element(info, n); 687982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata 688982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata size_t emt_count = 1; 689982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata if (emt->type == ARGTYPE_STRUCT || emt->type == ARGTYPE_ARRAY) 690982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata emt = type_get_hfa_type(emt, &emt_count); 691982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata if (emt == NULL) 692982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata return NULL; 693982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata if (ret == NULL) { 694982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata if (emt->type != ARGTYPE_FLOAT 695982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata && emt->type != ARGTYPE_DOUBLE) 696982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata return NULL; 697982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata ret = emt; 698982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata } 699982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata if (emt->type != ret->type) 700982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata return NULL; 701982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata *countp += emt_count; 702982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata } 703982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata return ret; 704982cbca34b2b49a158086ff5f43eb9bba89edeadPetr Machata} 705