fetch.c revision 78ed40f161c102a10c6033c28ad9a80e5ffe9550
194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata/* 294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This file is part of ltrace. 3cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata * Copyright (C) 2011,2012 Petr Machata 494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This program is free software; you can redistribute it and/or 694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * modify it under the terms of the GNU General Public License as 794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * published by the Free Software Foundation; either version 2 of the 894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * License, or (at your option) any later version. 994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 1094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This program is distributed in the hope that it will be useful, but 1194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 1294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * General Public License for more details. 1494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 1594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * You should have received a copy of the GNU General Public License 1694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * along with this program; if not, write to the Free Software 1794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 1894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 02110-1301 USA 1994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata */ 2094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 2194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "config.h" 2294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 2394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <sys/types.h> 2494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <assert.h> 2594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <gelf.h> 2694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <stddef.h> 2794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <stdint.h> 2894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <stdlib.h> 2994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <string.h> 3094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 3194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "backend.h" 3294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "expr.h" 3394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "fetch.h" 3494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "proc.h" 3594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "ptrace.h" 3694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "type.h" 3794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "value.h" 3894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 3994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataenum arg_class { 4094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata CLASS_INTEGER, 4194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata CLASS_SSE, 4294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata CLASS_NO, 4394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata CLASS_MEMORY, 4494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata CLASS_X87, 4594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}; 4694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 4794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataenum reg_pool { 4894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata POOL_FUNCALL, 4994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata POOL_SYSCALL, 5094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata /* A common pool for system call and function call return is 5194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * enough, the ABI is similar enough. */ 5294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata POOL_RETVAL, 5394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}; 5494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 5594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastruct fetch_context 5694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 5794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct user_regs_struct iregs; 5894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct user_fpregs_struct fpregs; 5994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 6094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata void *stack_pointer; 6194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t ireg; /* Used-up integer registers. */ 6294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t freg; /* Used-up floating registers. */ 6394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 6494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata union { 6594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct { 6694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata /* Storage classes for return type. We need 6794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * to compute them anyway, so let's keep them 6894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * around. */ 6994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata enum arg_class ret_classes[2]; 7094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata ssize_t num_ret_classes; 7194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } x86_64; 7294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct { 7394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct value retval; 7494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } ix86; 7594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } u; 7694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}; 7794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 7894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#ifndef __x86_64__ 7994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata__attribute__((noreturn)) static void 8094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatai386_unreachable(void) 8194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 8294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata abort(); 8394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 8494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#endif 8594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 8694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int 8794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatacontains_unaligned_fields(struct arg_type_info *info) 8894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 8994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata /* XXX currently we don't support structure alignment. */ 9094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return 0; 9194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 9294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 9394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int 9494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatahas_nontrivial_ctor_dtor(struct arg_type_info *info) 9594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 9694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata /* XXX another unsupported aspect of type info. We might call 9794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * these types "class" instead of "struct" in the config 9894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * file. */ 9994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return 0; 10094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 10194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 10294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic void 10394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatacopy_int_register(struct fetch_context *context, 10494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct value *valuep, unsigned long val, size_t offset) 10594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 10694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (valuep != NULL) { 10794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata unsigned char *buf = value_get_raw_data(valuep); 10894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata memcpy(buf + offset, &val, sizeof(val)); 10994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } 11094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata context->ireg++; 11194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 11294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 11394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic void 11494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatacopy_sse_register(struct fetch_context *context, struct value *valuep, 11594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata int half, size_t sz, size_t offset) 11694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 11794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#ifdef __x86_64__ 11894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata union { 11994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata uint32_t sse[4]; 12094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata long halves[2]; 12194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } u; 12294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t off = 4 * context->freg++; 12394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata memcpy(u.sse, context->fpregs.xmm_space + off, sizeof(u.sse)); 12494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 12594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (valuep != NULL) { 12694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata unsigned char *buf = value_get_raw_data(valuep); 12794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata memcpy(buf + offset, u.halves + half, sz); 128cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata } 129cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata#else 130cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata i386_unreachable(); 131cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata#endif 13294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 13394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 13494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic void 13594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataallocate_stack_slot(struct fetch_context *context, 13694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct value *valuep, size_t sz, size_t offset, 13794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t archw) 13894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 13994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t a = type_alignof(valuep->inferior, valuep->type); 14094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (a < archw) 14194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata a = archw; 14294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata context->stack_pointer 14394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata = (void *)align((unsigned long)context->stack_pointer, a); 14494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 14594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (valuep != NULL) { 14694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata valuep->where = VAL_LOC_INFERIOR; 14794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata valuep->u.address = context->stack_pointer; 14894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } 14994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata context->stack_pointer += sz; 15094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 15194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 15294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic enum arg_class 15394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataallocate_x87(struct fetch_context *context, struct value *valuep, 15494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t sz, size_t offset, enum reg_pool pool, size_t archw) 15594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 15694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata /* Both i386 and x86_64 ABI only ever really use x87 registers 15794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * to return values. Otherwise, the parameter is treated as 15894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * if it were CLASS_MEMORY. On x86_64 x87 registers are only 15994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * used for returning long double values, which we currently 16094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * don't support. */ 161 162 if (pool != POOL_RETVAL) { 163 allocate_stack_slot(context, valuep, sz, offset, archw); 164 return CLASS_MEMORY; 165 166 } 167 168 /* If the class is X87, the value is returned on the X87 stack 169 * in %st0 as 80-bit x87 number. 170 * 171 * If the class is X87UP, the value is returned together with 172 * the previous X87 value in %st0. 173 * 174 * If the class is COMPLEX_X87, the real part of the value is 175 * returned in %st0 and the imaginary part in %st1. */ 176 177 if (valuep != NULL) { 178 union { 179 long double ld; 180 double d; 181 float f; 182 char buf[0]; 183 } u; 184 185 /* The x87 floating point value is in long double 186 * format, so we need to convert in to the right type. 187 * Alternatively we might just leave it as is and 188 * smuggle the long double type into the value (via 189 * value_set_type), but for that we first need to 190 * support long double in the first place. */ 191 192#ifdef __x86_64__ 193 unsigned int *reg; 194#else 195 long int *reg; 196#endif 197 reg = &context->fpregs.st_space[0]; 198 memcpy(&u.ld, reg, sizeof(u)); 199 if (valuep->type->type == ARGTYPE_FLOAT) 200 u.f = (float)u.ld; 201 else if (valuep->type->type == ARGTYPE_DOUBLE) 202 u.d = (double)u.ld; 203 else 204 assert(!"Unexpected floating type!"), abort(); 205 206 unsigned char *buf = value_get_raw_data(valuep); 207 memcpy(buf + offset, u.buf, sz); 208 } 209 return CLASS_X87; 210} 211 212static enum arg_class 213allocate_integer(struct fetch_context *context, struct value *valuep, 214 size_t sz, size_t offset, enum reg_pool pool) 215{ 216#define HANDLE(NUM, WHICH) \ 217 case NUM: \ 218 copy_int_register(context, valuep, \ 219 context->iregs.WHICH, offset); \ 220 return CLASS_INTEGER 221 222 switch (pool) { 223 case POOL_FUNCALL: 224#ifdef __x86_64__ 225 switch (context->ireg) { 226 HANDLE(0, rdi); 227 HANDLE(1, rsi); 228 HANDLE(2, rdx); 229 HANDLE(3, rcx); 230 HANDLE(4, r8); 231 HANDLE(5, r9); 232 default: 233 allocate_stack_slot(context, valuep, sz, offset, 8); 234 return CLASS_MEMORY; 235 } 236#else 237 i386_unreachable(); 238#endif 239 240 case POOL_SYSCALL: 241#ifdef __x86_64__ 242 switch (context->ireg) { 243 HANDLE(0, rdi); 244 HANDLE(1, rsi); 245 HANDLE(2, rdx); 246 HANDLE(3, r10); 247 HANDLE(4, r8); 248 HANDLE(5, r9); 249 default: 250 assert(!"More than six syscall arguments???"); 251 abort(); 252 } 253#else 254 i386_unreachable(); 255#endif 256 257 case POOL_RETVAL: 258 switch (context->ireg) { 259#ifdef __x86_64__ 260 HANDLE(0, rax); 261 HANDLE(1, rdx); 262#else 263 HANDLE(0, eax); 264#endif 265 default: 266 assert(!"Too many return value classes."); 267 abort(); 268 } 269 } 270 271 abort(); 272 273#undef HANDLE 274} 275 276static enum arg_class 277allocate_sse(struct fetch_context *context, struct value *valuep, 278 size_t sz, size_t offset, enum reg_pool pool) 279{ 280 size_t num_regs = 0; 281 switch (pool) { 282 case POOL_FUNCALL: 283 num_regs = 8; 284 case POOL_SYSCALL: 285 break; 286 case POOL_RETVAL: 287 num_regs = 2; 288 } 289 290 if (context->freg >= num_regs) { 291 /* We shouldn't see overflow for RETVAL or SYSCALL 292 * pool. */ 293 assert(pool == POOL_FUNCALL); 294 allocate_stack_slot(context, valuep, sz, offset, 8); 295 return CLASS_MEMORY; 296 } else { 297 copy_sse_register(context, valuep, 0, sz, offset); 298 return CLASS_SSE; 299 } 300} 301 302/* This allocates registers or stack space for another argument of the 303 * class CLS. */ 304static enum arg_class 305allocate_class(enum arg_class cls, struct fetch_context *context, 306 struct value *valuep, size_t sz, size_t offset, enum reg_pool pool) 307{ 308 switch (cls) { 309 case CLASS_MEMORY: 310 allocate_stack_slot(context, valuep, sz, offset, 8); 311 case CLASS_NO: 312 return cls; 313 314 case CLASS_INTEGER: 315 return allocate_integer(context, valuep, sz, offset, pool); 316 317 case CLASS_SSE: 318 return allocate_sse(context, valuep, sz, offset, pool); 319 320 case CLASS_X87: 321 return allocate_x87(context, valuep, sz, offset, pool, 8); 322 } 323 abort(); 324} 325 326static ssize_t 327classify(struct Process *proc, struct fetch_context *context, 328 struct arg_type_info *info, struct value *valuep, enum arg_class classes[], 329 size_t sz, size_t eightbytes); 330 331/* This classifies one eightbyte part of an array or struct. */ 332static ssize_t 333classify_eightbyte(struct Process *proc, struct fetch_context *context, 334 struct arg_type_info *info, struct value *valuep, 335 enum arg_class *classp, size_t start, size_t end, 336 struct arg_type_info *(*getter)(struct arg_type_info *, 337 size_t)) 338{ 339 size_t i; 340 enum arg_class cls = CLASS_NO; 341 for (i = start; i < end; ++i) { 342 enum arg_class cls2; 343 struct arg_type_info *info2 = getter(info, i); 344 size_t sz = type_sizeof(proc, info2); 345 if (sz == (size_t)-1) 346 return -1; 347 if (classify(proc, context, info2, valuep, &cls2, sz, 1) < 0) 348 return -1; 349 350 if (cls == CLASS_NO) 351 cls = cls2; 352 else if (cls2 == CLASS_NO || cls == cls2) 353 ; 354 else if (cls == CLASS_MEMORY || cls2 == CLASS_MEMORY) 355 cls = CLASS_MEMORY; 356 else if (cls == CLASS_INTEGER || cls2 == CLASS_INTEGER) 357 cls = CLASS_INTEGER; 358 else 359 cls = CLASS_SSE; 360 } 361 362 *classp = cls; 363 return 1; 364} 365 366/* This classifies small arrays and structs. */ 367static ssize_t 368classify_eightbytes(struct Process *proc, struct fetch_context *context, 369 struct arg_type_info *info, struct value *valuep, 370 enum arg_class classes[], size_t elements, 371 size_t eightbytes, 372 struct arg_type_info *(*getter)(struct arg_type_info *, 373 size_t)) 374{ 375 if (eightbytes > 1) { 376 /* Where the second eightbyte starts. Number of the 377 * first element in the structure that belongs to the 378 * second eightbyte. */ 379 size_t start_2nd = 0; 380 size_t i; 381 for (i = 0; i < elements; ++i) 382 if (type_offsetof(proc, info, i) >= 8) { 383 start_2nd = i; 384 break; 385 } 386 387 enum arg_class cls1, cls2; 388 if (classify_eightbyte(proc, context, info, valuep, &cls1, 389 0, start_2nd, getter) < 0 390 || classify_eightbyte(proc, context, info, valuep, &cls2, 391 start_2nd, elements, getter) < 0) 392 return -1; 393 394 if (cls1 == CLASS_MEMORY || cls2 == CLASS_MEMORY) { 395 classes[0] = CLASS_MEMORY; 396 return 1; 397 } 398 399 classes[0] = cls1; 400 classes[1] = cls2; 401 return 2; 402 } 403 404 return classify_eightbyte(proc, context, info, valuep, classes, 405 0, elements, getter); 406} 407 408static struct arg_type_info * 409get_array_field(struct arg_type_info *info, size_t emt) 410{ 411 return info->u.array_info.elt_type; 412} 413 414static int 415flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info) 416{ 417 size_t i; 418 for (i = 0; i < type_struct_size(info); ++i) { 419 struct arg_type_info *field = type_struct_get(info, i); 420 assert(field != NULL); 421 switch (field->type) { 422 case ARGTYPE_STRUCT: 423 if (flatten_structure(flattened, field) < 0) 424 return -1; 425 break; 426 427 default: 428 if (type_struct_add(flattened, field, 0) < 0) 429 return -1; 430 } 431 } 432 return 0; 433} 434 435static ssize_t 436classify(struct Process *proc, struct fetch_context *context, 437 struct arg_type_info *info, struct value *valuep, enum arg_class classes[], 438 size_t sz, size_t eightbytes) 439{ 440 switch (info->type) { 441 struct arg_type_info flattened; 442 case ARGTYPE_VOID: 443 return 0; 444 445 case ARGTYPE_CHAR: 446 case ARGTYPE_SHORT: 447 case ARGTYPE_USHORT: 448 case ARGTYPE_INT: 449 case ARGTYPE_UINT: 450 case ARGTYPE_LONG: 451 case ARGTYPE_ULONG: 452 453 case ARGTYPE_POINTER: 454 /* and LONGLONG */ 455 /* CLASS_INTEGER */ 456 classes[0] = CLASS_INTEGER; 457 return 1; 458 459 case ARGTYPE_FLOAT: 460 case ARGTYPE_DOUBLE: 461 /* and DECIMAL, and _m64 */ 462 classes[0] = CLASS_SSE; 463 return 1; 464 465 case ARGTYPE_ARRAY: 466 /* N.B. this cannot be top-level array, those decay to 467 * pointers. Therefore, it must be inside structure 468 * that's at most 2 eightbytes long. */ 469 470 /* Structures with flexible array members can't be 471 * passed by value. */ 472 assert(expr_is_compile_constant(info->u.array_info.length)); 473 474 long l; 475 if (expr_eval_constant(info->u.array_info.length, &l) < 0) 476 return -1; 477 478 return classify_eightbytes(proc, context, info, valuep, classes, 479 (size_t)l, eightbytes, 480 get_array_field); 481 482 case ARGTYPE_STRUCT: 483 /* N.B. "big" structs are dealt with in the caller. 484 * 485 * First, we need to flatten the structure. In 486 * struct(float,struct(float,float)), first two floats 487 * both belong to the same eightbyte. */ 488 type_init_struct(&flattened); 489 490 ssize_t ret; 491 if (flatten_structure(&flattened, info) < 0) { 492 ret = -1; 493 goto done; 494 } 495 ret = classify_eightbytes(proc, context, &flattened, 496 valuep, classes, 497 type_struct_size(&flattened), 498 eightbytes, type_struct_get); 499 done: 500 type_destroy(&flattened); 501 return ret; 502 } 503 abort(); 504} 505 506static ssize_t 507pass_by_reference(struct value *valuep, enum arg_class classes[]) 508{ 509 if (valuep != NULL && value_pass_by_reference(valuep) < 0) 510 return -1; 511 classes[0] = CLASS_INTEGER; 512 return 1; 513} 514 515static ssize_t 516classify_argument(struct Process *proc, struct fetch_context *context, 517 struct arg_type_info *info, struct value *valuep, 518 enum arg_class classes[], size_t *sizep) 519{ 520 size_t sz = type_sizeof(proc, info); 521 if (sz == (size_t)-1) 522 return -1; 523 *sizep = sz; 524 525 size_t eightbytes = (sz + 7) / 8; /* Round up. */ 526 527 /* Arrays decay into pointers. */ 528 assert(info->type != ARGTYPE_ARRAY); 529 530 if (info->type == ARGTYPE_STRUCT) { 531 if (eightbytes > 2 || contains_unaligned_fields(info)) { 532 classes[0] = CLASS_MEMORY; 533 return 1; 534 } 535 536 if (has_nontrivial_ctor_dtor(info)) 537 return pass_by_reference(valuep, classes); 538 } 539 540 return classify(proc, context, info, valuep, classes, sz, eightbytes); 541} 542 543static int 544fetch_register_banks(struct Process *proc, struct fetch_context *context, 545 int floating) 546{ 547 if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->iregs) < 0) 548 return -1; 549 context->ireg = 0; 550 551 if (floating) { 552 if (ptrace(PTRACE_GETFPREGS, proc->pid, 553 0, &context->fpregs) < 0) 554 return -1; 555 context->freg = 0; 556 } else { 557 context->freg = -1; 558 } 559 560 return 0; 561} 562 563static int 564arch_fetch_arg_next_32(struct fetch_context *context, enum tof type, 565 struct Process *proc, struct arg_type_info *info, 566 struct value *valuep) 567{ 568 size_t sz = type_sizeof(proc, info); 569 if (sz == (size_t)-1) 570 return -1; 571 572 allocate_stack_slot(context, valuep, sz, 0, 4); 573 574 return 0; 575} 576 577static int 578arch_fetch_retval_32(struct fetch_context *context, enum tof type, 579 struct Process *proc, struct arg_type_info *info, 580 struct value *valuep) 581{ 582 if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0) 583 return -1; 584 585 struct value *retval = &context->u.ix86.retval; 586 if (retval->type != NULL) { 587 /* Struct return value was extracted when in fetch 588 * init. */ 589 memcpy(valuep, &context->u.ix86.retval, sizeof(*valuep)); 590 return 0; 591 } 592 593 size_t sz = type_sizeof(proc, info); 594 if (sz == (size_t)-1) 595 return -1; 596 if (value_reserve(valuep, sz) == NULL) 597 return -1; 598 599 switch (info->type) { 600 enum arg_class cls; 601 case ARGTYPE_VOID: 602 return 0; 603 604 case ARGTYPE_INT: 605 case ARGTYPE_UINT: 606 case ARGTYPE_LONG: 607 case ARGTYPE_ULONG: 608 case ARGTYPE_CHAR: 609 case ARGTYPE_SHORT: 610 case ARGTYPE_USHORT: 611 case ARGTYPE_POINTER: 612 cls = allocate_integer(context, valuep, sz, 0, POOL_RETVAL); 613 assert(cls == CLASS_INTEGER); 614 return 0; 615 616 case ARGTYPE_FLOAT: 617 case ARGTYPE_DOUBLE: 618 cls = allocate_x87(context, valuep, sz, 0, POOL_RETVAL, 4); 619 assert(cls == CLASS_X87); 620 return 0; 621 622 case ARGTYPE_ARRAY: 623 case ARGTYPE_STRUCT: /* Handled above. */ 624 assert(!"Unexpected i386 retval type!"); 625 abort(); 626 } 627 628 abort(); 629} 630 631static arch_addr_t 632fetch_stack_pointer(struct fetch_context *context) 633{ 634 arch_addr_t sp; 635#ifdef __x86_64__ 636 sp = (arch_addr_t)context->iregs.rsp; 637#else 638 sp = (arch_addr_t)context->iregs.esp; 639#endif 640 return sp; 641} 642 643struct fetch_context * 644arch_fetch_arg_init_32(struct fetch_context *context, 645 enum tof type, struct Process *proc, 646 struct arg_type_info *ret_info) 647{ 648 context->stack_pointer = fetch_stack_pointer(context) + 4; 649 650 size_t sz = type_sizeof(proc, ret_info); 651 if (sz == (size_t)-1) 652 return NULL; 653 654 struct value *retval = &context->u.ix86.retval; 655 if (ret_info->type == ARGTYPE_STRUCT) { 656 value_init(retval, proc, NULL, ret_info, 0); 657 658 enum arg_class dummy[2]; 659 if (pass_by_reference(retval, dummy) < 0) 660 return NULL; 661 allocate_stack_slot(context, retval, 4, 0, 4); 662 663 } else { 664 value_init_detached(retval, NULL, NULL, 0); 665 } 666 667 return context; 668} 669 670struct fetch_context * 671arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type, 672 struct Process *proc, struct arg_type_info *ret_info) 673{ 674 /* The first stack slot holds a return address. */ 675 ctx->stack_pointer = fetch_stack_pointer(ctx) + 8; 676 677 size_t size; 678 ctx->u.x86_64.num_ret_classes 679 = classify_argument(proc, ctx, ret_info, NULL, 680 ctx->u.x86_64.ret_classes, &size); 681 if (ctx->u.x86_64.num_ret_classes == -1) 682 return NULL; 683 684 /* If the class is MEMORY, then the first argument is a hidden 685 * pointer to the allocated storage. */ 686 if (ctx->u.x86_64.num_ret_classes > 0 687 && ctx->u.x86_64.ret_classes[0] == CLASS_MEMORY) { 688 /* MEMORY should be the sole class. */ 689 assert(ctx->u.x86_64.num_ret_classes == 1); 690 allocate_integer(ctx, NULL, size, 0, POOL_FUNCALL); 691 } 692 693 return ctx; 694} 695 696struct fetch_context * 697arch_fetch_arg_init(enum tof type, struct Process *proc, 698 struct arg_type_info *ret_info) 699{ 700 struct fetch_context *ctx = malloc(sizeof(*ctx)); 701 if (ctx == NULL) 702 return NULL; 703 704 assert(type != LT_TOF_FUNCTIONR 705 && type != LT_TOF_SYSCALLR); 706 if (fetch_register_banks(proc, ctx, type == LT_TOF_FUNCTION) < 0) { 707 fail: 708 free(ctx); 709 return NULL; 710 } 711 712 struct fetch_context *ret; 713 if (proc->e_machine == EM_386) 714 ret = arch_fetch_arg_init_32(ctx, type, proc, ret_info); 715 else 716 ret = arch_fetch_arg_init_64(ctx, type, proc, ret_info); 717 if (ret == NULL) 718 goto fail; 719 return ret; 720} 721 722struct fetch_context * 723arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) 724{ 725 struct fetch_context *ret = malloc(sizeof(*ret)); 726 if (ret == NULL) 727 return NULL; 728 return memcpy(ret, context, sizeof(*ret)); 729} 730 731static int 732arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type, 733 struct Process *proc, struct arg_type_info *info, 734 struct value *valuep, enum reg_pool pool) 735{ 736 enum arg_class classes[2]; 737 size_t sz, sz1; 738 ssize_t i; 739 ssize_t nclasses = classify_argument(proc, context, info, valuep, 740 classes, &sz); 741 if (nclasses == -1) 742 return -1; 743 if (value_reserve(valuep, sz) == NULL) 744 return -1; 745 746 /* If there are no registers available for any eightbyte of an 747 * argument, the whole argument is passed on the stack. If 748 * registers have already been assigned for some eightbytes of 749 * such an argument, the assignments get reverted. */ 750 struct fetch_context tmp_context = *context; 751 int revert; 752 if (nclasses == 1) { 753 revert = allocate_class(classes[0], &tmp_context, 754 valuep, sz, 0, pool) != classes[0]; 755 } else { 756 revert = 0; 757 for (i = 0; i < nclasses; ++i) { 758 sz1 = (size_t)(8 * (i + 1)) > sz ? sz - 8 * i : 8; 759 if (allocate_class(classes[i], &tmp_context, valuep, 760 sz1, 8 * i, pool) != classes[i]) 761 revert = 1; 762 } 763 } 764 765 if (nclasses > 1 && revert) 766 allocate_class(CLASS_MEMORY, context, valuep, sz, 0, pool); 767 else 768 *context = tmp_context; /* Commit. */ 769 770 return 0; 771} 772 773int 774arch_fetch_fun_retval(struct fetch_context *context, enum tof type, 775 struct Process *proc, struct arg_type_info *info, 776 struct value *valuep) 777{ 778 assert(type != LT_TOF_FUNCTION 779 && type != LT_TOF_SYSCALL); 780 if (value_reserve(valuep, 8 * context->u.x86_64.num_ret_classes) == NULL 781 || fetch_register_banks(proc, context, 782 type == LT_TOF_FUNCTIONR) < 0) 783 return -1; 784 785 if (context->u.x86_64.num_ret_classes == 1 786 && context->u.x86_64.ret_classes[0] == CLASS_MEMORY) 787 pass_by_reference(valuep, context->u.x86_64.ret_classes); 788 789 size_t sz = type_sizeof(proc, valuep->type); 790 if (sz == (size_t)-1) 791 return -1; 792 793 ssize_t i; 794 size_t sz1 = context->u.x86_64.num_ret_classes == 1 ? sz : 8; 795 for (i = 0; i < context->u.x86_64.num_ret_classes; ++i) { 796 enum arg_class cls 797 = allocate_class(context->u.x86_64.ret_classes[i], 798 context, valuep, sz1, 799 8 * i, POOL_RETVAL); 800 assert(cls == context->u.x86_64.ret_classes[i]); 801 } 802 return 0; 803} 804 805int 806arch_fetch_arg_next(struct fetch_context *context, enum tof type, 807 struct Process *proc, struct arg_type_info *info, 808 struct value *valuep) 809{ 810 if (proc->e_machine == EM_386) 811 return arch_fetch_arg_next_32(context, type, proc, 812 info, valuep); 813 814 switch (type) { 815 case LT_TOF_FUNCTION: 816 case LT_TOF_FUNCTIONR: 817 return arch_fetch_pool_arg_next(context, type, proc, 818 info, valuep, POOL_FUNCALL); 819 820 case LT_TOF_SYSCALL: 821 case LT_TOF_SYSCALLR: 822 return arch_fetch_pool_arg_next(context, type, proc, 823 info, valuep, POOL_SYSCALL); 824 } 825 826 abort(); 827} 828 829int 830arch_fetch_retval(struct fetch_context *context, enum tof type, 831 struct Process *proc, struct arg_type_info *info, 832 struct value *valuep) 833{ 834 if (proc->e_machine == EM_386) 835 return arch_fetch_retval_32(context, type, proc, info, valuep); 836 837 return arch_fetch_fun_retval(context, type, proc, info, valuep); 838} 839 840void 841arch_fetch_arg_done(struct fetch_context *context) 842{ 843 if (context != NULL) 844 free(context); 845} 846