fetch.c revision 929bd57ca202fd2f2e8485ebf65d683e664f67b5
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2012 Petr Machata, Red Hat Inc. 4 * Copyright (C) 2008,2009 Juan Cespedes 5 * Copyright (C) 2006 Steve Fink 6 * Copyright (C) 2006 Ian Wienand 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of the 11 * License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 */ 23 24#include <stdlib.h> 25#include <assert.h> 26#include <sys/rse.h> 27#include <ptrace.h> 28#include <string.h> 29#include <errno.h> 30 31#include "backend.h" 32#include "fetch.h" 33#include "type.h" 34#include "proc.h" 35#include "value.h" 36 37struct fetch_context { 38 arch_addr_t stack_pointer; 39 struct pt_all_user_regs regs; 40 enum param_pack_flavor ppflavor; 41 42 /* Return values larger than 256 bits (except HFAs of up to 8 43 * elements) are returned in a buffer allocated by the 44 * caller. A pointer to the buffer is passed to the called 45 * procedure in r8. This register is not guaranteed to be 46 * preserved by the called procedure. */ 47 unsigned long r8; 48 49 int slot_n; 50 int flt; 51}; 52 53union cfm_t { 54 struct { 55 unsigned long sof:7; 56 unsigned long sol:7; 57 unsigned long sor:4; 58 unsigned long rrb_gr:7; 59 unsigned long rrb_fr:7; 60 unsigned long rrb_pr:6; 61 } cfm; 62 unsigned long value; 63}; 64 65static int 66fetch_context_init(struct process *proc, struct fetch_context *context) 67{ 68 context->slot_n = 0; 69 context->flt = 8; 70 if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->regs) < 0) 71 return -1; 72 context->stack_pointer = (void *)(context->regs.gr[12] + 16); 73 context->ppflavor = PARAM_PACK_ARGS; 74 75 return 0; 76} 77 78struct fetch_context * 79arch_fetch_arg_init(enum tof type, struct process *proc, 80 struct arg_type_info *ret_info) 81{ 82 struct fetch_context *context = malloc(sizeof(*context)); 83 if (context == NULL 84 || fetch_context_init(proc, context) < 0) { 85 free(context); 86 return NULL; 87 } 88 context->r8 = context->regs.gr[8]; 89 90 return context; 91} 92 93struct fetch_context * 94arch_fetch_arg_clone(struct process *proc, 95 struct fetch_context *context) 96{ 97 struct fetch_context *clone = malloc(sizeof(*context)); 98 if (clone == NULL) 99 return NULL; 100 *clone = *context; 101 return clone; 102} 103 104int 105allocate_stack_slot(struct fetch_context *ctx, struct process *proc, 106 struct arg_type_info *info, struct value *valuep) 107{ 108 size_t al = type_alignof(proc, info); 109 size_t sz = type_sizeof(proc, info); 110 if (al == (size_t)-1 || sz == (size_t)-1) 111 return -1; 112 113 errno = 0; 114 long value = ptrace(PTRACE_PEEKDATA, proc->pid, ctx->stack_pointer, 0); 115 if (value == -1 && errno != 0) 116 return -1; 117 ctx->stack_pointer += 8; 118 value_set_word(valuep, value); 119 120 return 0; 121} 122 123static int 124allocate_reg(struct fetch_context *ctx, struct process *proc, 125 struct arg_type_info *info, struct value *valuep) 126{ 127 if (ctx->slot_n >= 8) 128 return allocate_stack_slot(ctx, proc, info, valuep); 129 130 int reg_num = ctx->slot_n++; 131 if (ctx->slot_n == 8) 132 ctx->flt = 16; 133 if (valuep == NULL) 134 return 0; 135 136 /* This would normally be brought over from asm/ptrace.h, but 137 * when we do, we get namespace conflicts between asm/fpu.h 138 * and libunwind. */ 139 enum { PT_AUR_BSP = 17 }; 140 141 union cfm_t cfm = { .value = ctx->regs.cfm }; 142 unsigned long *bsp = (unsigned long *)ctx->regs.ar[PT_AUR_BSP]; 143 unsigned long idx = -cfm.cfm.sof + reg_num; 144 unsigned long *ptr = ia64_rse_skip_regs(bsp, idx); 145 errno = 0; 146 long ret = ptrace(PTRACE_PEEKDATA, proc->pid, ptr, 0); 147 if (ret == -1 && errno != 0) 148 return -1; 149 150 value_set_word(valuep, ret); 151 return 0; 152} 153 154static int 155copy_aggregate_part(struct fetch_context *ctx, struct process *proc, 156 unsigned char *buf, size_t size) 157{ 158 size_t slots = (size + 7) / 8; 159 struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG); 160 while (slots-- > 0) { 161 size_t chunk_sz = size > 8 ? 8 : size; 162 size -= 8; 163 164 struct value tmp; 165 value_init(&tmp, proc, NULL, long_info, 0); 166 int rc = allocate_reg(ctx, proc, long_info, &tmp); 167 if (rc >= 0) { 168 memcpy(buf, value_get_data(&tmp, NULL), chunk_sz); 169 buf += 8; 170 } 171 value_destroy(&tmp); 172 if (rc < 0) 173 return -1; 174 } 175 return 0; 176} 177 178static int 179allocate_arg(struct fetch_context *ctx, struct process *proc, 180 struct arg_type_info *info, struct value *valuep) 181{ 182 size_t sz = type_sizeof(proc, info); 183 size_t align = type_alignof(proc, info); 184 if (sz == (size_t)-1 || align == (size_t)-1) 185 return -1; 186 187 unsigned char *buf = value_reserve(valuep, sz); 188 if (buf == NULL) 189 return -1; 190 191 assert(align == 0 || align == 1 || align == 2 || align == 4 192 || align == 8 || align == 16); 193 194 /* For aggregates with an external alignment of 16 bytes, the 195 * Next Even policy is used. 128-bit integers use the Next 196 * Even policy as well. */ 197 if (align == 16 && ctx->slot_n % 2 != 0) 198 allocate_reg(ctx, proc, info, NULL); 199 200 int rc= copy_aggregate_part(ctx, proc, buf, sz); 201 202 return rc; 203} 204 205/* Stolen from David Mosberger's utrace tool, which he released under 206 the GPL 207 (http://www.gelato.unsw.edu.au/archives/linux-ia64/0104/1405.html) */ 208static inline double 209fpreg_to_double (struct ia64_fpreg *fp) { 210 double result; 211 asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp)); 212 return result; 213} 214 215static int 216allocate_float(struct fetch_context *ctx, struct process *proc, 217 struct arg_type_info *info, struct value *valuep, 218 int take_slot) 219{ 220 /* The actual parameter is passed in the next available 221 * floating-point parameter register, if one is 222 * available. Floating-point parameter registers are allocated 223 * as needed from the range f8-f15, starting with f8. */ 224 /* Any register parameters corresponding to a 225 * variable-argument specification are passed in GRs. */ 226 if (ctx->flt > 15 || ctx->ppflavor == PARAM_PACK_VARARGS) 227 /* If all available floating-point parameter registers 228 * have been used, the actual parameter is passed in 229 * the appropriate general register(s). */ 230 return allocate_reg(ctx, proc, info, valuep); 231 232 union { 233 double d; 234 float f; 235 char buf[0]; 236 } u = { .d = fpreg_to_double(&ctx->regs.fr[ctx->flt++]) }; 237 if (take_slot) 238 allocate_reg(ctx, proc, info, NULL); 239 240 if (info->type == ARGTYPE_FLOAT) 241 u.f = u.d; 242 else 243 assert(info->type == ARGTYPE_DOUBLE); 244 245 if (value_reserve(valuep, sizeof(u)) == NULL) 246 return -1; 247 memmove(value_get_raw_data(valuep), u.buf, sizeof(u)); 248 249 return 0; 250} 251 252static enum arg_type 253get_hfa_type(struct arg_type_info *info, size_t *countp) 254{ 255 size_t n = type_aggregate_size(info); 256 if (n == (size_t)-1) 257 return ARGTYPE_VOID; 258 259 enum arg_type type = ARGTYPE_VOID; 260 *countp = 0; 261 262 while (n-- > 0) { 263 struct arg_type_info *emt = type_element(info, n); 264 265 enum arg_type emt_type = emt->type; 266 size_t emt_count = 1; 267 if (emt_type == ARGTYPE_STRUCT || emt_type == ARGTYPE_ARRAY) 268 emt_type = get_hfa_type(emt, &emt_count); 269 270 if (type == ARGTYPE_VOID) { 271 if (emt_type != ARGTYPE_FLOAT 272 && emt_type != ARGTYPE_DOUBLE) 273 return ARGTYPE_VOID; 274 type = emt_type; 275 } 276 if (emt_type != type) 277 return ARGTYPE_VOID; 278 *countp += emt_count; 279 } 280 return type; 281} 282 283static int 284allocate_hfa(struct fetch_context *ctx, struct process *proc, 285 struct arg_type_info *info, struct value *valuep, 286 enum arg_type hfa_type, size_t hfa_count) 287{ 288 size_t sz = type_sizeof(proc, info); 289 if (sz == (size_t)-1) 290 return -1; 291 292 /* If an actual parameter is known to correspond to an HFA 293 * formal parameter, each element is passed in the next 294 * available floating-point argument register, until the eight 295 * argument registers are exhausted. The remaining elements of 296 * the aggregate are passed in output GRs, according to the 297 * normal conventions. 298 * 299 * Because HFAs are mapped to parameter slots as aggregates, 300 * single-precision HFAs will be allocated with two 301 * floating-point values in each parameter slot, but only one 302 * value per register. 303 * 304 * It is possible for the first of two values in a parameter 305 * slot to occupy the last available floating- point parameter 306 * register. In this case, the second value is passed in its 307 * designated GR, but the half of the GR that would have 308 * contained the first value is undefined. */ 309 310 size_t slot_off = 0; 311 312 unsigned char *buf = value_reserve(valuep, sz); 313 if (buf == NULL) 314 return -1; 315 316 struct arg_type_info *hfa_info = type_get_simple(hfa_type); 317 size_t hfa_sz = type_sizeof(proc, hfa_info); 318 319 /* Pass in register the part that we can. */ 320 while (ctx->flt <= 15 && hfa_count > 0) { 321 struct value tmp; 322 value_init(&tmp, proc, NULL, hfa_info, 0); 323 int rc = allocate_float(ctx, proc, hfa_info, &tmp, 0); 324 if (rc >= 0) { 325 memcpy(buf, value_get_data(&tmp, NULL), hfa_sz); 326 slot_off += hfa_sz; 327 buf += hfa_sz; 328 hfa_count--; 329 330 /* Scratch each fully used slot. */ 331 while (slot_off >= 8) { 332 if (allocate_reg(ctx, proc, info, NULL) < 0) 333 rc = -1; 334 slot_off -= 8; 335 } 336 } 337 value_destroy(&tmp); 338 if (rc < 0) 339 return -1; 340 } 341 342 /* If we have half-slot opened (the case where odd 343 * ARGTYPE_FLOAT member fits into the last floating point 344 * register, and the following even member does not), finish 345 * it first. */ 346 struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG); 347 if (slot_off != 0 && hfa_count > 0) { 348 struct value tmp; 349 value_init(&tmp, proc, NULL, long_info, 0); 350 int rc = allocate_reg(ctx, proc, long_info, &tmp); 351 if (rc >= 0) { 352 unsigned char *data = value_get_data(&tmp, NULL); 353 memcpy(buf, data, 8 - slot_off); 354 buf += 8 - slot_off; 355 hfa_count--; 356 } 357 value_destroy(&tmp); 358 if (rc < 0) { 359 return -1; 360 } 361 } 362 363 /* The rest is passed in registers and on stack. */ 364 size_t rest = hfa_count * hfa_sz; 365 return copy_aggregate_part(ctx, proc, buf, rest); 366} 367 368static int 369allocate_ret(struct fetch_context *ctx, struct process *proc, 370 struct arg_type_info *info, struct value *valuep) 371{ 372 size_t sz = type_sizeof(proc, info); 373 if (sz == (size_t)-1) 374 return -1; 375 376 /* Homogeneous floating-point aggregates [...] are returned in 377 * floating-point registers, provided the array or structure 378 * contains no more than eight individual values. The 379 * elements of the aggregate are placed in successive 380 * floating-point registers, beginning with f8. */ 381 if (info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY) { 382 size_t hfa_size; 383 enum arg_type hfa_type = get_hfa_type(info, &hfa_size); 384 if (hfa_type != ARGTYPE_VOID && hfa_size <= 8) 385 return allocate_hfa(ctx, proc, info, valuep, 386 hfa_type, hfa_size); 387 } 388 389 /* Integers and pointers are passed in r8. 128-bit integers 390 * are passed in r8 and r9. Aggregates of up to 256 bits [32 391 * bytes] are passed in registers r8...r11. */ 392 if (sz <= 32) { 393 unsigned char *buf = value_reserve(valuep, sz); 394 if (buf == NULL) 395 return -1; 396 memcpy(buf, ctx->regs.gr + 8, sz); 397 return 0; 398 } 399 400 if (value_pass_by_reference(valuep) < 0) 401 return -1; 402 value_set_word(valuep, ctx->r8); 403 return 0; 404} 405 406int 407arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 408 struct process *proc, 409 struct arg_type_info *info, struct value *valuep) 410{ 411 switch (info->type) { 412 enum arg_type hfa_type; 413 size_t hfa_size; 414 415 case ARGTYPE_VOID: 416 value_set_word(valuep, 0); 417 return 0; 418 419 case ARGTYPE_FLOAT: 420 case ARGTYPE_DOUBLE: 421 return allocate_float(ctx, proc, info, valuep, 1); 422 423 case ARGTYPE_STRUCT: 424 hfa_type = get_hfa_type(info, &hfa_size); 425 if (hfa_type != ARGTYPE_VOID) 426 return allocate_hfa(ctx, proc, info, valuep, 427 hfa_type, hfa_size); 428 /* Fall through. */ 429 case ARGTYPE_CHAR: 430 case ARGTYPE_SHORT: 431 case ARGTYPE_USHORT: 432 case ARGTYPE_INT: 433 case ARGTYPE_UINT: 434 case ARGTYPE_LONG: 435 case ARGTYPE_ULONG: 436 case ARGTYPE_POINTER: 437 return allocate_arg(ctx, proc, info, valuep); 438 439 case ARGTYPE_ARRAY: 440 /* Arrays decay into pointers. XXX Fortran? */ 441 default: 442 assert(info->type != info->type); 443 abort(); 444 } 445} 446 447int 448arch_fetch_retval(struct fetch_context *ctx, enum tof type, 449 struct process *proc, struct arg_type_info *info, 450 struct value *valuep) 451{ 452 if (fetch_context_init(proc, ctx) < 0) 453 return -1; 454 455 switch (info->type) { 456 case ARGTYPE_VOID: 457 case ARGTYPE_FLOAT: 458 case ARGTYPE_DOUBLE: 459 /* The rules for returning those types are the same as 460 * for passing them in arguments. */ 461 return arch_fetch_arg_next(ctx, type, proc, info, valuep); 462 463 case ARGTYPE_CHAR: 464 case ARGTYPE_SHORT: 465 case ARGTYPE_USHORT: 466 case ARGTYPE_INT: 467 case ARGTYPE_UINT: 468 case ARGTYPE_LONG: 469 case ARGTYPE_ULONG: 470 case ARGTYPE_POINTER: 471 case ARGTYPE_STRUCT: 472 return allocate_ret(ctx, proc, info, valuep); 473 474 case ARGTYPE_ARRAY: 475 /* Arrays decay into pointers. XXX Fortran? */ 476 assert(info->type != ARGTYPE_ARRAY); 477 abort(); 478 } 479 assert("unhandled type"); 480 abort(); 481 return arch_fetch_arg_next(ctx, type, proc, info, valuep); 482} 483 484void 485arch_fetch_arg_done(struct fetch_context *context) 486{ 487 free(context); 488} 489 490int 491arch_fetch_param_pack_start(struct fetch_context *context, 492 enum param_pack_flavor ppflavor) 493{ 494 context->ppflavor = ppflavor; 495 return 0; 496} 497 498void 499arch_fetch_param_pack_end(struct fetch_context *context) 500{ 501 context->ppflavor = PARAM_PACK_ARGS; 502} 503