fetch.c revision 12d64f8bbae6245146900e8ee2292d854a22f26d
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, 1490b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata struct arg_type_info *info, struct value *valuep, 1500b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz) 151ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 152df59c75ee9fa70343c9af929403cd3d371443714Petr Machata /* Note: here we shouldn't see large composite types, those 15382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata * are passed by reference, which is handled below. Here we 154df59c75ee9fa70343c9af929403cd3d371443714Petr Machata * only deal with integers, floats, small structs, etc. */ 15582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 15682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata size_t a; 15782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata if (s390x(ctx)) { 15882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata assert(sz <= 8); 159ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata a = 8; 16082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata } else { 16182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata /* Note: double is 8 bytes. */ 16282b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata assert(sz <= 8); 16382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata a = 4; 16482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata } 165ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 16682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata size_t off = sz < a ? a - sz : 0; 167ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 168ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata valuep->where = VAL_LOC_INFERIOR; 169ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata valuep->u.address = ctx->stack_pointer + off; 170ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 17182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata ctx->stack_pointer += sz > a ? sz : a; 172ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 173ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 174ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 175ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic void 176ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatacopy_gpr(struct fetch_context *ctx, struct value *valuep, int regno) 177ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 178ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata value_set_word(valuep, ctx->regs.gprs[regno]); 179ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 180ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 181ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 182ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataallocate_gpr(struct fetch_context *ctx, struct Process *proc, 1830b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata struct arg_type_info *info, struct value *valuep, 1840b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz) 185ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 186ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (ctx->greg > 6) 1870b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_stack_slot(ctx, proc, info, valuep, sz); 188ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 189ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata copy_gpr(ctx, valuep, ctx->greg++); 190ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 191ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 192ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 193ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 194df59c75ee9fa70343c9af929403cd3d371443714Petr Machataallocate_gpr_pair(struct fetch_context *ctx, struct Process *proc, 195df59c75ee9fa70343c9af929403cd3d371443714Petr Machata struct arg_type_info *info, struct value *valuep, 196df59c75ee9fa70343c9af929403cd3d371443714Petr Machata size_t sz) 197df59c75ee9fa70343c9af929403cd3d371443714Petr Machata{ 198df59c75ee9fa70343c9af929403cd3d371443714Petr Machata assert(!s390x(ctx)); 199df59c75ee9fa70343c9af929403cd3d371443714Petr Machata assert(sz <= 8); 200df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 201df59c75ee9fa70343c9af929403cd3d371443714Petr Machata if (ctx->greg > 5) { 202df59c75ee9fa70343c9af929403cd3d371443714Petr Machata ctx->greg = 7; 203df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return allocate_stack_slot(ctx, proc, info, valuep, sz); 204df59c75ee9fa70343c9af929403cd3d371443714Petr Machata } 205df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 206df59c75ee9fa70343c9af929403cd3d371443714Petr Machata if (value_reserve(valuep, sz) == NULL) 207df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return -1; 208df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 209df59c75ee9fa70343c9af929403cd3d371443714Petr Machata unsigned char *ptr = value_get_raw_data(valuep); 210df59c75ee9fa70343c9af929403cd3d371443714Petr Machata union { 211df59c75ee9fa70343c9af929403cd3d371443714Petr Machata struct { 212df59c75ee9fa70343c9af929403cd3d371443714Petr Machata uint32_t a; 213df59c75ee9fa70343c9af929403cd3d371443714Petr Machata uint32_t b; 214df59c75ee9fa70343c9af929403cd3d371443714Petr Machata }; 215df59c75ee9fa70343c9af929403cd3d371443714Petr Machata unsigned char buf[8]; 216df59c75ee9fa70343c9af929403cd3d371443714Petr Machata } u; 217df59c75ee9fa70343c9af929403cd3d371443714Petr Machata u.a = ctx->regs.gprs[ctx->greg++]; 218df59c75ee9fa70343c9af929403cd3d371443714Petr Machata u.b = ctx->regs.gprs[ctx->greg++]; 219df59c75ee9fa70343c9af929403cd3d371443714Petr Machata memcpy(ptr, u.buf, sz); 220df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 221df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return 0; 222df59c75ee9fa70343c9af929403cd3d371443714Petr Machata} 223df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 224df59c75ee9fa70343c9af929403cd3d371443714Petr Machatastatic int 225ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataallocate_fpr(struct fetch_context *ctx, struct Process *proc, 2260b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata struct arg_type_info *info, struct value *valuep, 2270b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz) 228ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 22982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata int pool = s390x(ctx) ? 6 : 2; 23082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 23182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata if (ctx->freg > pool) 2320b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_stack_slot(ctx, proc, info, valuep, sz); 233ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 234ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_reserve(valuep, sz) == NULL) 235ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 236ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 237ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata memcpy(value_get_raw_data(valuep), 238ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata &ctx->regs.fp_regs.fprs[ctx->freg], sz); 239ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata ctx->freg += 2; 240ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 241ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 242ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 243ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 244ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint 245ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 246ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct Process *proc, 247ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *info, struct value *valuep) 248ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 2490b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz = type_sizeof(proc, info); 2500b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata if (sz == (size_t)-1) 2510b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return -1; 2520b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata 253ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata switch (info->type) { 254ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_VOID: 255ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata value_set_word(valuep, 0); 256ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 257ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 258ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_STRUCT: 259ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (fp_equivalent(info)) 260ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata /* fall through */ 261ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_FLOAT: 262ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_DOUBLE: 2630b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_fpr(ctx, proc, info, valuep, sz); 264ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 26512d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata /* Structures<4 bytes on s390 and structures<8 bytes 26612d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata * on s390x are passed in register. On s390, long 26712d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata * long and structures<8 bytes are passed in two 26812d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata * consecutive registers (if two are available). */ 26912d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata 270df59c75ee9fa70343c9af929403cd3d371443714Petr Machata if (sz <= (s390x(ctx) ? 8 : 4)) 2710b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_gpr(ctx, proc, info, valuep, sz); 272df59c75ee9fa70343c9af929403cd3d371443714Petr Machata else if (sz <= 8) 273df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return allocate_gpr_pair(ctx, proc, info, valuep, sz); 27412d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata 275ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata /* fall through */ 276ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 277ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_ARRAY: 278ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_pass_by_reference(valuep) < 0) 279ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 280ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata /* fall through */ 281ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 282ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_INT: 283ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_UINT: 284ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_LONG: 285ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_ULONG: 286ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_CHAR: 287ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_SHORT: 288ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_USHORT: 289ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_POINTER: 2900b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_gpr(ctx, proc, info, valuep, sz); 291ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 292ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 293ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 294ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 295ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint 296ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_retval(struct fetch_context *ctx, enum tof type, 297ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct Process *proc, struct arg_type_info *info, 298ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct value *valuep) 299ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 300ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (info->type == ARGTYPE_STRUCT) { 301ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_pass_by_reference(valuep) < 0) 302ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 303ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata copy_gpr(ctx, valuep, 2); 304ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 305ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 306ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 307ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (fetch_context_init(proc, ctx) < 0) 308ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 309ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return arch_fetch_arg_next(ctx, type, proc, info, valuep); 310ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 311ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 312ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatavoid 313ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_done(struct fetch_context *context) 314ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 315ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata free(context); 316ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 317