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