1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2011,2012,2013 Petr Machata 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 * 02110-1301 USA 19 */ 20 21#include "config.h" 22 23#include <sys/types.h> 24#include <assert.h> 25#include <gelf.h> 26#include <stddef.h> 27#include <stdint.h> 28#include <stdlib.h> 29#include <string.h> 30#include <stdio.h> 31 32#include "backend.h" 33#include "expr.h" 34#include "fetch.h" 35#include "proc.h" 36#include "ptrace.h" 37#include "type.h" 38#include "value.h" 39 40enum arg_class { 41 CLASS_INTEGER, 42 CLASS_SSE, 43 CLASS_NO, 44 CLASS_MEMORY, 45 CLASS_X87, 46}; 47 48enum reg_pool { 49 POOL_FUNCALL, 50 POOL_SYSCALL, 51 /* A common pool for system call and function call return is 52 * enough, the ABI is similar enough. */ 53 POOL_RETVAL, 54}; 55 56struct fetch_context 57{ 58 struct user_regs_struct iregs; 59 struct user_fpregs_struct fpregs; 60 61 arch_addr_t stack_pointer; 62 size_t ireg; /* Used-up integer registers. */ 63 size_t freg; /* Used-up floating registers. */ 64 int machine; 65 66 union { 67 struct { 68 /* Storage classes for return type. We need 69 * to compute them anyway, so let's keep them 70 * around. */ 71 enum arg_class ret_classes[2]; 72 ssize_t num_ret_classes; 73 } x86_64; 74 struct { 75 struct value retval; 76 } ix86; 77 } u; 78}; 79 80#ifndef __x86_64__ 81__attribute__((noreturn)) static void 82i386_unreachable(void) 83{ 84 abort(); 85} 86#endif 87 88static int 89contains_unaligned_fields(struct arg_type_info *info) 90{ 91 /* XXX currently we don't support structure alignment. */ 92 return 0; 93} 94 95static int 96has_nontrivial_ctor_dtor(struct arg_type_info *info) 97{ 98 /* XXX another unsupported aspect of type info. We might call 99 * these types "class" instead of "struct" in the config 100 * file. */ 101 return 0; 102} 103 104static void 105copy_int_register(struct fetch_context *context, 106 struct value *valuep, unsigned long val, size_t offset) 107{ 108 if (valuep != NULL) { 109 unsigned char *buf = value_get_raw_data(valuep); 110 memcpy(buf + offset, &val, sizeof(val)); 111 } 112 context->ireg++; 113} 114 115static void 116copy_sse_register(struct fetch_context *context, struct value *valuep, 117 int half, size_t sz, size_t offset) 118{ 119#ifdef __x86_64__ 120 union { 121 uint32_t sse[4]; 122 long halves[2]; 123 } u; 124 size_t off = 4 * context->freg++; 125 memcpy(u.sse, context->fpregs.xmm_space + off, sizeof(u.sse)); 126 127 if (valuep != NULL) { 128 unsigned char *buf = value_get_raw_data(valuep); 129 memcpy(buf + offset, u.halves + half, sz); 130 } 131#else 132 i386_unreachable(); 133#endif 134} 135 136static void 137allocate_stack_slot(struct fetch_context *context, 138 struct value *valuep, size_t sz, size_t offset, 139 size_t archw) 140{ 141 assert(valuep != NULL); 142 size_t a = type_alignof(valuep->inferior, valuep->type); 143 if (a < archw) 144 a = archw; 145 context->stack_pointer 146 = (void *)align((unsigned long)context->stack_pointer, a); 147 148 value_in_inferior(valuep, context->stack_pointer); 149 context->stack_pointer += sz; 150} 151 152static enum arg_class 153allocate_x87(struct fetch_context *context, struct value *valuep, 154 size_t sz, size_t offset, enum reg_pool pool, size_t archw) 155{ 156 /* Both i386 and x86_64 ABI only ever really use x87 registers 157 * to return values. Otherwise, the parameter is treated as 158 * if it were CLASS_MEMORY. On x86_64 x87 registers are only 159 * used for returning long double values, which we currently 160 * don't support. */ 161 162 if (pool != POOL_RETVAL) { 163 allocate_stack_slot(context, valuep, sz, offset, archw); 164 return CLASS_MEMORY; 165 166 } 167 168 /* If the class is X87, the value is returned on the X87 stack 169 * in %st0 as 80-bit x87 number. 170 * 171 * If the class is X87UP, the value is returned together with 172 * the previous X87 value in %st0. 173 * 174 * If the class is COMPLEX_X87, the real part of the value is 175 * returned in %st0 and the imaginary part in %st1. */ 176 177 if (valuep != NULL) { 178 union { 179 long double ld; 180 double d; 181 float f; 182 char buf[0]; 183 } u; 184 185 /* The x87 floating point value is in long double 186 * format, so we need to convert in to the right type. 187 * Alternatively we might just leave it as is and 188 * smuggle the long double type into the value (via 189 * value_set_type), but for that we first need to 190 * support long double in the first place. */ 191 192#ifdef __x86_64__ 193 unsigned int *reg; 194#else 195 long int *reg; 196#endif 197 reg = &context->fpregs.st_space[0]; 198 memcpy(&u.ld, reg, sizeof(u)); 199 if (valuep->type->type == ARGTYPE_FLOAT) 200 u.f = (float)u.ld; 201 else if (valuep->type->type == ARGTYPE_DOUBLE) 202 u.d = (double)u.ld; 203 else 204 assert(!"Unexpected floating type!"), abort(); 205 206 unsigned char *buf = value_get_raw_data(valuep); 207 memcpy(buf + offset, u.buf, sz); 208 } 209 return CLASS_X87; 210} 211 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 if (context->machine == EM_X86_64) { 243 switch (context->ireg) { 244 HANDLE(0, rdi); 245 HANDLE(1, rsi); 246 HANDLE(2, rdx); 247 HANDLE(3, r10); 248 HANDLE(4, r8); 249 HANDLE(5, r9); 250 default: 251 assert(!"More than six syscall arguments???"); 252 abort(); 253 } 254 } 255#endif 256 if (context->machine == EM_386) { 257 258#ifdef __x86_64__ 259# define HANDLE32(NUM, WHICH) HANDLE(NUM, r##WHICH) 260#else 261# define HANDLE32(NUM, WHICH) HANDLE(NUM, e##WHICH) 262#endif 263 264 switch (context->ireg) { 265 HANDLE32(0, bx); 266 HANDLE32(1, cx); 267 HANDLE32(2, dx); 268 HANDLE32(3, si); 269 HANDLE32(4, di); 270 HANDLE32(5, bp); 271 default: 272 assert(!"More than six syscall arguments???"); 273 abort(); 274 } 275#undef HANDLE32 276 } 277 278 case POOL_RETVAL: 279 switch (context->ireg) { 280#ifdef __x86_64__ 281 HANDLE(0, rax); 282 HANDLE(1, rdx); 283#else 284 HANDLE(0, eax); 285#endif 286 default: 287 assert(!"Too many return value classes."); 288 abort(); 289 } 290 } 291 292 abort(); 293 294#undef HANDLE 295} 296 297static enum arg_class 298allocate_sse(struct fetch_context *context, struct value *valuep, 299 size_t sz, size_t offset, enum reg_pool pool) 300{ 301 size_t num_regs = 0; 302 switch (pool) { 303 case POOL_FUNCALL: 304 num_regs = 8; 305 case POOL_SYSCALL: 306 break; 307 case POOL_RETVAL: 308 num_regs = 2; 309 } 310 311 if (context->freg >= num_regs) { 312 /* We shouldn't see overflow for RETVAL or SYSCALL 313 * pool. */ 314 assert(pool == POOL_FUNCALL); 315 allocate_stack_slot(context, valuep, sz, offset, 8); 316 return CLASS_MEMORY; 317 } else { 318 copy_sse_register(context, valuep, 0, sz, offset); 319 return CLASS_SSE; 320 } 321} 322 323/* This allocates registers or stack space for another argument of the 324 * class CLS. */ 325static enum arg_class 326allocate_class(enum arg_class cls, struct fetch_context *context, 327 struct value *valuep, size_t sz, size_t offset, enum reg_pool pool) 328{ 329 switch (cls) { 330 case CLASS_MEMORY: 331 allocate_stack_slot(context, valuep, sz, offset, 8); 332 case CLASS_NO: 333 return cls; 334 335 case CLASS_INTEGER: 336 return allocate_integer(context, valuep, sz, offset, pool); 337 338 case CLASS_SSE: 339 return allocate_sse(context, valuep, sz, offset, pool); 340 341 case CLASS_X87: 342 return allocate_x87(context, valuep, sz, offset, pool, 8); 343 } 344 abort(); 345} 346 347static ssize_t 348classify(struct process *proc, struct fetch_context *context, 349 struct arg_type_info *info, enum arg_class classes[], 350 size_t sz, size_t eightbytes); 351 352/* This classifies one eightbyte part of an array or struct. */ 353static ssize_t 354classify_eightbyte(struct process *proc, struct fetch_context *context, 355 struct arg_type_info *info, 356 enum arg_class *classp, size_t start, size_t end, 357 struct arg_type_info *(*getter)(struct arg_type_info *, 358 size_t)) 359{ 360 size_t i; 361 enum arg_class cls = CLASS_NO; 362 for (i = start; i < end; ++i) { 363 enum arg_class cls2; 364 struct arg_type_info *info2 = getter(info, i); 365 size_t sz = type_sizeof(proc, info2); 366 if (sz == (size_t)-1) 367 return -1; 368 if (classify(proc, context, info2, &cls2, sz, 1) < 0) 369 return -1; 370 371 if (cls == CLASS_NO) 372 cls = cls2; 373 else if (cls2 == CLASS_NO || cls == cls2) 374 ; 375 else if (cls == CLASS_MEMORY || cls2 == CLASS_MEMORY) 376 cls = CLASS_MEMORY; 377 else if (cls == CLASS_INTEGER || cls2 == CLASS_INTEGER) 378 cls = CLASS_INTEGER; 379 else 380 cls = CLASS_SSE; 381 } 382 383 *classp = cls; 384 return 1; 385} 386 387/* This classifies small arrays and structs. */ 388static ssize_t 389classify_eightbytes(struct process *proc, struct fetch_context *context, 390 struct arg_type_info *info, 391 enum arg_class classes[], size_t elements, 392 size_t eightbytes, 393 struct arg_type_info *(*getter)(struct arg_type_info *, 394 size_t)) 395{ 396 if (eightbytes > 1) { 397 /* Where the second eightbyte starts. Number of the 398 * first element in the structure that belongs to the 399 * second eightbyte. */ 400 size_t start_2nd = 0; 401 size_t i; 402 for (i = 0; i < elements; ++i) 403 if (type_offsetof(proc, info, i) >= 8) { 404 start_2nd = i; 405 break; 406 } 407 408 enum arg_class cls1, cls2; 409 if (classify_eightbyte(proc, context, info, &cls1, 410 0, start_2nd, getter) < 0 411 || classify_eightbyte(proc, context, info, &cls2, 412 start_2nd, elements, getter) < 0) 413 return -1; 414 415 if (cls1 == CLASS_MEMORY || cls2 == CLASS_MEMORY) { 416 classes[0] = CLASS_MEMORY; 417 return 1; 418 } 419 420 classes[0] = cls1; 421 classes[1] = cls2; 422 return 2; 423 } 424 425 return classify_eightbyte(proc, context, info, classes, 426 0, elements, getter); 427} 428 429static struct arg_type_info * 430get_array_field(struct arg_type_info *info, size_t emt) 431{ 432 return info->u.array_info.elt_type; 433} 434 435static int 436flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info) 437{ 438 size_t i; 439 for (i = 0; i < type_struct_size(info); ++i) { 440 struct arg_type_info *field = type_struct_get(info, i); 441 assert(field != NULL); 442 switch (field->type) { 443 case ARGTYPE_STRUCT: 444 if (flatten_structure(flattened, field) < 0) 445 return -1; 446 break; 447 448 default: 449 if (type_struct_add(flattened, field, 0) < 0) 450 return -1; 451 } 452 } 453 return 0; 454} 455 456static ssize_t 457classify(struct process *proc, struct fetch_context *context, 458 struct arg_type_info *info, enum arg_class classes[], 459 size_t sz, size_t eightbytes) 460{ 461 switch (info->type) { 462 struct arg_type_info flattened; 463 case ARGTYPE_VOID: 464 return 0; 465 466 case ARGTYPE_CHAR: 467 case ARGTYPE_SHORT: 468 case ARGTYPE_USHORT: 469 case ARGTYPE_INT: 470 case ARGTYPE_UINT: 471 case ARGTYPE_LONG: 472 case ARGTYPE_ULONG: 473 474 case ARGTYPE_POINTER: 475 /* and LONGLONG */ 476 /* CLASS_INTEGER */ 477 classes[0] = CLASS_INTEGER; 478 return 1; 479 480 case ARGTYPE_FLOAT: 481 case ARGTYPE_DOUBLE: 482 /* and DECIMAL, and _m64 */ 483 classes[0] = CLASS_SSE; 484 return 1; 485 486 case ARGTYPE_ARRAY: 487 /* N.B. this cannot be top-level array, those decay to 488 * pointers. Therefore, it must be inside structure 489 * that's at most 2 eightbytes long. */ 490 491 /* Structures with flexible array members can't be 492 * passed by value. */ 493 assert(expr_is_compile_constant(info->u.array_info.length)); 494 495 long l; 496 if (expr_eval_constant(info->u.array_info.length, &l) < 0) 497 return -1; 498 499 return classify_eightbytes(proc, context, info, classes, 500 (size_t)l, eightbytes, 501 get_array_field); 502 503 case ARGTYPE_STRUCT: 504 /* N.B. "big" structs are dealt with in the caller. 505 * 506 * First, we need to flatten the structure. In 507 * struct(float,struct(float,float)), first two floats 508 * both belong to the same eightbyte. */ 509 type_init_struct(&flattened); 510 511 ssize_t ret; 512 if (flatten_structure(&flattened, info) < 0) { 513 ret = -1; 514 goto done; 515 } 516 ret = classify_eightbytes(proc, context, &flattened, 517 classes, 518 type_struct_size(&flattened), 519 eightbytes, type_struct_get); 520 done: 521 type_destroy(&flattened); 522 return ret; 523 524 default: 525 /* Unsupported type. */ 526 assert(info->type != info->type); 527 abort(); 528 } 529 abort(); 530} 531 532static ssize_t 533pass_by_reference(struct value *valuep, enum arg_class classes[]) 534{ 535 if (valuep != NULL && value_pass_by_reference(valuep) < 0) 536 return -1; 537 classes[0] = CLASS_INTEGER; 538 return 1; 539} 540 541static ssize_t 542classify_argument(struct process *proc, struct fetch_context *context, 543 struct arg_type_info *info, struct value *valuep, 544 enum arg_class classes[], size_t *sizep) 545{ 546 size_t sz = type_sizeof(proc, info); 547 if (sz == (size_t)-1) 548 return -1; 549 *sizep = sz; 550 551 size_t eightbytes = (sz + 7) / 8; /* Round up. */ 552 553 /* Arrays decay into pointers. */ 554 assert(info->type != ARGTYPE_ARRAY); 555 556 if (info->type == ARGTYPE_STRUCT) { 557 if (eightbytes > 2 || contains_unaligned_fields(info)) { 558 classes[0] = CLASS_MEMORY; 559 return 1; 560 } 561 562 if (has_nontrivial_ctor_dtor(info)) 563 return pass_by_reference(valuep, classes); 564 } 565 566 return classify(proc, context, info, classes, sz, eightbytes); 567} 568 569static int 570fetch_register_banks(struct process *proc, struct fetch_context *context, 571 int floating) 572{ 573 if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->iregs) < 0) 574 return -1; 575 context->ireg = 0; 576 577 if (floating) { 578 if (ptrace(PTRACE_GETFPREGS, proc->pid, 579 0, &context->fpregs) < 0) 580 return -1; 581 context->freg = 0; 582 } else { 583 context->freg = -1; 584 } 585 586 return 0; 587} 588 589static int 590arch_fetch_arg_next_32(struct fetch_context *context, enum tof type, 591 struct process *proc, struct arg_type_info *info, 592 struct value *valuep) 593{ 594 size_t sz = type_sizeof(proc, info); 595 if (sz == (size_t)-1) 596 return -1; 597 if (value_reserve(valuep, sz) == NULL) 598 return -1; 599 600 if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { 601 int cls = allocate_integer(context, valuep, 602 sz, 0, POOL_SYSCALL); 603 assert(cls == CLASS_INTEGER); 604 return 0; 605 } 606 607 allocate_stack_slot(context, valuep, sz, 0, 4); 608 609 return 0; 610} 611 612static int 613arch_fetch_retval_32(struct fetch_context *context, enum tof type, 614 struct process *proc, struct arg_type_info *info, 615 struct value *valuep) 616{ 617 if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0) 618 return -1; 619 620 struct value *retval = &context->u.ix86.retval; 621 if (retval->type != NULL) { 622 /* Struct return value was extracted when in fetch 623 * init. */ 624 memcpy(valuep, &context->u.ix86.retval, sizeof(*valuep)); 625 return 0; 626 } 627 628 size_t sz = type_sizeof(proc, info); 629 if (sz == (size_t)-1) 630 return -1; 631 if (value_reserve(valuep, sz) == NULL) 632 return -1; 633 634 switch (info->type) { 635 enum arg_class cls; 636 case ARGTYPE_VOID: 637 return 0; 638 639 case ARGTYPE_INT: 640 case ARGTYPE_UINT: 641 case ARGTYPE_LONG: 642 case ARGTYPE_ULONG: 643 case ARGTYPE_CHAR: 644 case ARGTYPE_SHORT: 645 case ARGTYPE_USHORT: 646 case ARGTYPE_POINTER: 647 cls = allocate_integer(context, valuep, sz, 0, POOL_RETVAL); 648 assert(cls == CLASS_INTEGER); 649 return 0; 650 651 case ARGTYPE_FLOAT: 652 case ARGTYPE_DOUBLE: 653 cls = allocate_x87(context, valuep, sz, 0, POOL_RETVAL, 4); 654 assert(cls == CLASS_X87); 655 return 0; 656 657 case ARGTYPE_STRUCT: /* Handled above. */ 658 default: 659 assert(!"Unexpected i386 retval type!"); 660 abort(); 661 } 662 663 abort(); 664} 665 666static arch_addr_t 667fetch_stack_pointer(struct fetch_context *context) 668{ 669 arch_addr_t sp; 670#ifdef __x86_64__ 671 sp = (arch_addr_t)context->iregs.rsp; 672#else 673 sp = (arch_addr_t)context->iregs.esp; 674#endif 675 return sp; 676} 677 678struct fetch_context * 679arch_fetch_arg_init_32(struct fetch_context *context, 680 enum tof type, struct process *proc, 681 struct arg_type_info *ret_info) 682{ 683 context->stack_pointer = fetch_stack_pointer(context) + 4; 684 685 size_t sz = type_sizeof(proc, ret_info); 686 if (sz == (size_t)-1) 687 return NULL; 688 689 struct value *retval = &context->u.ix86.retval; 690 if (ret_info->type == ARGTYPE_STRUCT) { 691 value_init(retval, proc, NULL, ret_info, 0); 692 693 enum arg_class dummy[2]; 694 if (pass_by_reference(retval, dummy) < 0) 695 return NULL; 696 allocate_stack_slot(context, retval, 4, 0, 4); 697 698 } else { 699 value_init_detached(retval, NULL, NULL, 0); 700 } 701 702 return context; 703} 704 705struct fetch_context * 706arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type, 707 struct process *proc, struct arg_type_info *ret_info) 708{ 709 /* The first stack slot holds a return address. */ 710 ctx->stack_pointer = fetch_stack_pointer(ctx) + 8; 711 712 size_t size; 713 ctx->u.x86_64.num_ret_classes 714 = classify_argument(proc, ctx, ret_info, NULL, 715 ctx->u.x86_64.ret_classes, &size); 716 if (ctx->u.x86_64.num_ret_classes == -1) 717 return NULL; 718 719 /* If the class is MEMORY, then the first argument is a hidden 720 * pointer to the allocated storage. */ 721 if (ctx->u.x86_64.num_ret_classes > 0 722 && ctx->u.x86_64.ret_classes[0] == CLASS_MEMORY) { 723 /* MEMORY should be the sole class. */ 724 assert(ctx->u.x86_64.num_ret_classes == 1); 725 allocate_integer(ctx, NULL, size, 0, POOL_FUNCALL); 726 } 727 728 return ctx; 729} 730 731struct fetch_context * 732arch_fetch_arg_init(enum tof type, struct process *proc, 733 struct arg_type_info *ret_info) 734{ 735 struct fetch_context *ctx = malloc(sizeof(*ctx)); 736 if (ctx == NULL) 737 return NULL; 738 ctx->machine = proc->e_machine; 739 740 assert(type != LT_TOF_FUNCTIONR 741 && type != LT_TOF_SYSCALLR); 742 if (fetch_register_banks(proc, ctx, type == LT_TOF_FUNCTION) < 0) { 743 fail: 744 free(ctx); 745 return NULL; 746 } 747 748 struct fetch_context *ret; 749 if (proc->e_machine == EM_386) 750 ret = arch_fetch_arg_init_32(ctx, type, proc, ret_info); 751 else 752 ret = arch_fetch_arg_init_64(ctx, type, proc, ret_info); 753 if (ret == NULL) 754 goto fail; 755 return ret; 756} 757 758struct fetch_context * 759arch_fetch_arg_clone(struct process *proc, struct fetch_context *context) 760{ 761 struct fetch_context *ret = malloc(sizeof(*ret)); 762 if (ret == NULL) 763 return NULL; 764 return memcpy(ret, context, sizeof(*ret)); 765} 766 767static int 768arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type, 769 struct process *proc, struct arg_type_info *info, 770 struct value *valuep, enum reg_pool pool) 771{ 772 enum arg_class classes[2]; 773 size_t sz, sz1; 774 ssize_t i; 775 ssize_t nclasses = classify_argument(proc, context, info, valuep, 776 classes, &sz); 777 if (nclasses == -1) 778 return -1; 779 if (value_reserve(valuep, sz) == NULL) 780 return -1; 781 782 /* If there are no registers available for any eightbyte of an 783 * argument, the whole argument is passed on the stack. If 784 * registers have already been assigned for some eightbytes of 785 * such an argument, the assignments get reverted. */ 786 struct fetch_context tmp_context = *context; 787 int revert; 788 if (nclasses == 1) { 789 revert = allocate_class(classes[0], &tmp_context, 790 valuep, sz, 0, pool) != classes[0]; 791 } else { 792 revert = 0; 793 for (i = 0; i < nclasses; ++i) { 794 sz1 = (size_t)(8 * (i + 1)) > sz ? sz - 8 * i : 8; 795 if (allocate_class(classes[i], &tmp_context, valuep, 796 sz1, 8 * i, pool) != classes[i]) 797 revert = 1; 798 } 799 } 800 801 if (nclasses > 1 && revert) 802 allocate_class(CLASS_MEMORY, context, valuep, sz, 0, pool); 803 else 804 *context = tmp_context; /* Commit. */ 805 806 return 0; 807} 808 809int 810arch_fetch_fun_retval(struct fetch_context *context, enum tof type, 811 struct process *proc, struct arg_type_info *info, 812 struct value *valuep) 813{ 814 assert(type != LT_TOF_FUNCTION 815 && type != LT_TOF_SYSCALL); 816 if (value_reserve(valuep, 8 * context->u.x86_64.num_ret_classes) == NULL 817 || fetch_register_banks(proc, context, 818 type == LT_TOF_FUNCTIONR) < 0) 819 return -1; 820 821 if (context->u.x86_64.num_ret_classes == 1 822 && context->u.x86_64.ret_classes[0] == CLASS_MEMORY) 823 pass_by_reference(valuep, context->u.x86_64.ret_classes); 824 825 size_t sz = type_sizeof(proc, valuep->type); 826 if (sz == (size_t)-1) 827 return -1; 828 829 ssize_t i; 830 size_t sz1 = context->u.x86_64.num_ret_classes == 1 ? sz : 8; 831 for (i = 0; i < context->u.x86_64.num_ret_classes; ++i) { 832 enum arg_class cls 833 = allocate_class(context->u.x86_64.ret_classes[i], 834 context, valuep, sz1, 835 8 * i, POOL_RETVAL); 836 assert(cls == context->u.x86_64.ret_classes[i]); 837 } 838 return 0; 839} 840 841int 842arch_fetch_arg_next(struct fetch_context *context, enum tof type, 843 struct process *proc, struct arg_type_info *info, 844 struct value *valuep) 845{ 846 if (proc->e_machine == EM_386) 847 return arch_fetch_arg_next_32(context, type, proc, 848 info, valuep); 849 850 switch (type) { 851 case LT_TOF_FUNCTION: 852 case LT_TOF_FUNCTIONR: 853 return arch_fetch_pool_arg_next(context, type, proc, 854 info, valuep, POOL_FUNCALL); 855 856 case LT_TOF_SYSCALL: 857 case LT_TOF_SYSCALLR: 858 return arch_fetch_pool_arg_next(context, type, proc, 859 info, valuep, POOL_SYSCALL); 860 } 861 862 abort(); 863} 864 865int 866arch_fetch_retval(struct fetch_context *context, enum tof type, 867 struct process *proc, struct arg_type_info *info, 868 struct value *valuep) 869{ 870 if (proc->e_machine == EM_386) 871 return arch_fetch_retval_32(context, type, proc, info, valuep); 872 873 return arch_fetch_fun_retval(context, type, proc, info, valuep); 874} 875 876void 877arch_fetch_arg_done(struct fetch_context *context) 878{ 879 if (context != NULL) 880 free(context); 881} 882