fetch.c revision 8d30fd9f26ccd15f0fa27e09d1fd99deddb17d36
1ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata/* 2ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * This file is part of ltrace. 3ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * Copyright (C) 2012 Petr Machata, Red Hat Inc. 4ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * 5ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * This program is free software; you can redistribute it and/or 6ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * modify it under the terms of the GNU General Public License as 7ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * published by the Free Software Foundation; either version 2 of the 8ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * License, or (at your option) any later version. 9ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * 10ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * This program is distributed in the hope that it will be useful, but 11ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 12ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * General Public License for more details. 14ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * 15ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * You should have received a copy of the GNU General Public License 16ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * along with this program; if not, write to the Free Software 17ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata * 02110-1301 USA 19ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata */ 20ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 21ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <asm/ptrace.h> 22ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <sys/ptrace.h> 23ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <sys/ucontext.h> 24ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <assert.h> 25ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <errno.h> 26ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <stdio.h> 27ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <stdlib.h> 28ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <string.h> 29ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 30ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "backend.h" 31ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "fetch.h" 32ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "type.h" 33ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "proc.h" 34ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "value.h" 35ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 36ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context { 37ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct user_regs_struct regs; 38ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata arch_addr_t stack_pointer; 39ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata int greg; 40ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata int freg; 41ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}; 42ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 43ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 4482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machatas390x(struct fetch_context *ctx) 4582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata{ 468d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata /* +--------+--------+--------+ 478d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata * | PSW.31 | PSW.32 | mode | 488d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata * +--------+--------+--------+ 498d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata * | 0 | 0 | 24-bit | Not supported in Linux 508d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata * | 0 | 1 | 31-bit | s390 compatible mode 518d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata * | 1 | 1 | 64-bit | z/Architecture, "s390x" 528d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata * +--------+--------+--------+ 538d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata * (Note: The leftmost bit is PSW.0, rightmost PSW.63.) 548d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata */ 558d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata 5682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata#ifdef __s390x__ 5782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata if ((ctx->regs.psw.mask & 0x180000000UL) == 0x180000000UL) 5882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata return 1; 5982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata#endif 6082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata return 0; 6182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata} 6282b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 6382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machatastatic int 64ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatafp_equivalent(struct arg_type_info *info) 65ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 66ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata switch (info->type) { 67ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_VOID: 68ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_INT: 69ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_UINT: 70ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_LONG: 71ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_ULONG: 72ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_CHAR: 73ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_SHORT: 74ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_USHORT: 75ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_ARRAY: 76ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_POINTER: 77ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 78ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 79ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_FLOAT: 80ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_DOUBLE: 81ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 1; 82ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 83ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_STRUCT: 84ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (type_struct_size(info) != 1) 85ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 86ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return fp_equivalent(type_element(info, 0)); 87ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 88ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata assert(info->type != info->type); 89ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata abort(); 90ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 91ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 92ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 93ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatafetch_register_banks(struct Process *proc, struct fetch_context *ctx) 94ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 95ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata ptrace_area parea; 96ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata parea.len = sizeof(ctx->regs); 97ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata parea.process_addr = (uintptr_t)&ctx->regs; 98ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata parea.kernel_addr = 0; 99ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (ptrace(PTRACE_PEEKUSR_AREA, proc->pid, &parea, NULL) < 0) { 100ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata fprintf(stderr, "fetch_register_banks GPR: %s\n", 101ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata strerror(errno)); 102ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 103ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 104ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 105ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 106ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 107ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 108ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatafetch_context_init(struct Process *proc, struct fetch_context *context) 109ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 110ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata context->greg = 2; 111ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata context->freg = 0; 112ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return fetch_register_banks(proc, context); 113ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 114ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 115ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context * 116ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_init(enum tof type, struct Process *proc, 117ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *ret_info) 118ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 119ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct fetch_context *context = malloc(sizeof(*context)); 120ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (context == NULL 121ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata || fetch_context_init(proc, context) < 0) { 122ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata fprintf(stderr, "arch_fetch_arg_init: %s\n", 123ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata strerror(errno)); 124ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata free(context); 125ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return NULL; 126ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 127ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 12882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata context->stack_pointer = get_stack_pointer(proc) 12982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata + (s390x(context) ? 160 : 96); 130ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (ret_info->type == ARGTYPE_STRUCT) 131ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata ++context->greg; 132ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 133ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return context; 134ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 135ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 136ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context * 137ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_clone(struct Process *proc, 138ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct fetch_context *context) 139ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 140ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct fetch_context *clone = malloc(sizeof(*context)); 141ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (clone == NULL) 142ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return NULL; 143ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata *clone = *context; 144ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return clone; 145ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 146ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 147ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 148ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataallocate_stack_slot(struct fetch_context *ctx, struct Process *proc, 149ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *info, struct value *valuep) 150ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 15182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata /* Note: when here, we shouldn't see composite types, those 15282b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata * are passed by reference, which is handled below. Here we 15382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata * only deal with integers, floats, etc. */ 15482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 155ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata size_t sz = type_sizeof(proc, info); 156ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (sz == (size_t)-1) 157ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 15882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 15982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata size_t a; 16082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata if (s390x(ctx)) { 16182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata assert(sz <= 8); 162ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata a = 8; 16382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata } else { 16482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata /* Note: double is 8 bytes. */ 16582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata assert(sz <= 8); 16682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata a = 4; 16782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata } 168ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 16982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata size_t off = sz < a ? a - sz : 0; 170ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 171ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata valuep->where = VAL_LOC_INFERIOR; 172ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata valuep->u.address = ctx->stack_pointer + off; 173ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 17482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata ctx->stack_pointer += sz > a ? sz : a; 175ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 176ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 177ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 178ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic void 179ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatacopy_gpr(struct fetch_context *ctx, struct value *valuep, int regno) 180ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 181ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata value_set_word(valuep, ctx->regs.gprs[regno]); 182ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 183ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 184ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 185ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataallocate_gpr(struct fetch_context *ctx, struct Process *proc, 186ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *info, struct value *valuep) 187ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 188ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (ctx->greg > 6) 189ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return allocate_stack_slot(ctx, proc, info, valuep); 190ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 191ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata copy_gpr(ctx, valuep, ctx->greg++); 192ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 193ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 194ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 195ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 196ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataallocate_fpr(struct fetch_context *ctx, struct Process *proc, 197ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *info, struct value *valuep) 198ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 19982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 20082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata int pool = s390x(ctx) ? 6 : 2; 20182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 20282b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata if (ctx->freg > pool) 203ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return allocate_stack_slot(ctx, proc, info, valuep); 204ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 205ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata size_t sz = type_sizeof(proc, info); 206ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (sz == (size_t)-1) 207ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 208ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 209ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_reserve(valuep, sz) == NULL) 210ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 211ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 212ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata memcpy(value_get_raw_data(valuep), 213ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata &ctx->regs.fp_regs.fprs[ctx->freg], sz); 214ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata ctx->freg += 2; 215ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 216ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 217ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 218ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 219ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint 220ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 221ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct Process *proc, 222ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *info, struct value *valuep) 223ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 22482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata /* XXX structures<4 bytes on s390 and structures<8 bytes on 22582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata * s390x are passed in register. On s390, long long and 22682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata * structures<8 bytes are passed in two consecutive 22782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata * registers (if two are available). */ 22882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 229ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata switch (info->type) { 230ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_VOID: 231ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata value_set_word(valuep, 0); 232ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 233ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 234ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_STRUCT: 235ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (fp_equivalent(info)) 236ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata /* fall through */ 237ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 238ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_FLOAT: 239ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_DOUBLE: 240ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return allocate_fpr(ctx, proc, info, valuep); 241ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 242ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (type_sizeof(proc, info) < 8) 243ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return allocate_gpr(ctx, proc, info,valuep); 244ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata /* fall through */ 245ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 246ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_ARRAY: 247ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_pass_by_reference(valuep) < 0) 248ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 249ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata /* fall through */ 250ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 251ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_INT: 252ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_UINT: 253ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_LONG: 254ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_ULONG: 255ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_CHAR: 256ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_SHORT: 257ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_USHORT: 258ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_POINTER: 259ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return allocate_gpr(ctx, proc, info, valuep); 260ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 261ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 262ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 263ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 264ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint 265ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_retval(struct fetch_context *ctx, enum tof type, 266ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct Process *proc, struct arg_type_info *info, 267ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct value *valuep) 268ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 269ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (info->type == ARGTYPE_STRUCT) { 270ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_pass_by_reference(valuep) < 0) 271ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 272ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata copy_gpr(ctx, valuep, 2); 273ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 274ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 275ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 276ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (fetch_context_init(proc, ctx) < 0) 277ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 278ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return arch_fetch_arg_next(ctx, type, proc, info, valuep); 279ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 280ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 281ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatavoid 282ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_done(struct fetch_context *context) 283ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 284ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata free(context); 285ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 286