fetch.c revision 929bd57ca202fd2f2e8485ebf65d683e664f67b5
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 64929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_register_banks(struct process *proc, struct fetch_context *ctx) 65ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 66ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata ptrace_area parea; 67ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata parea.len = sizeof(ctx->regs); 68ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata parea.process_addr = (uintptr_t)&ctx->regs; 69ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata parea.kernel_addr = 0; 70ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (ptrace(PTRACE_PEEKUSR_AREA, proc->pid, &parea, NULL) < 0) { 71ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata fprintf(stderr, "fetch_register_banks GPR: %s\n", 72ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata strerror(errno)); 73ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 74ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 75ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 76ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 77ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 78ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 79929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_context_init(struct process *proc, struct fetch_context *context) 80ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 81ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata context->greg = 2; 82ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata context->freg = 0; 83ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return fetch_register_banks(proc, context); 84ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 85ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 86ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context * 87929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_init(enum tof type, struct process *proc, 88ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *ret_info) 89ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 90ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct fetch_context *context = malloc(sizeof(*context)); 91ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (context == NULL 92ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata || fetch_context_init(proc, context) < 0) { 93ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata fprintf(stderr, "arch_fetch_arg_init: %s\n", 94ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata strerror(errno)); 95ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata free(context); 96ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return NULL; 97ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 98ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 9982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata context->stack_pointer = get_stack_pointer(proc) 10082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata + (s390x(context) ? 160 : 96); 101ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (ret_info->type == ARGTYPE_STRUCT) 102ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata ++context->greg; 103ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 104ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return context; 105ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 106ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 107ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context * 108929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_clone(struct process *proc, 109ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct fetch_context *context) 110ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 111ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct fetch_context *clone = malloc(sizeof(*context)); 112ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (clone == NULL) 113ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return NULL; 114ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata *clone = *context; 115ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return clone; 116ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 117ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 118ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 119929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_stack_slot(struct fetch_context *ctx, struct process *proc, 1200b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata struct arg_type_info *info, struct value *valuep, 1210b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz) 122ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 123df59c75ee9fa70343c9af929403cd3d371443714Petr Machata /* Note: here we shouldn't see large composite types, those 12482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata * are passed by reference, which is handled below. Here we 125df59c75ee9fa70343c9af929403cd3d371443714Petr Machata * only deal with integers, floats, small structs, etc. */ 12682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 12782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata size_t a; 12882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata if (s390x(ctx)) { 12982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata assert(sz <= 8); 130ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata a = 8; 13182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata } else { 13282b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata /* Note: double is 8 bytes. */ 13382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata assert(sz <= 8); 13482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata a = 4; 13582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata } 136ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 13782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata size_t off = sz < a ? a - sz : 0; 1380ffa9f3f82febbcd475318ac282c456adb76c73cPetr Machata value_in_inferior(valuep, ctx->stack_pointer + off); 139ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 14082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata ctx->stack_pointer += sz > a ? sz : a; 141ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 142ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 143ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 144ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic void 145ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatacopy_gpr(struct fetch_context *ctx, struct value *valuep, int regno) 146ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 147ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata value_set_word(valuep, ctx->regs.gprs[regno]); 148ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 149ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 150ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 151929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_gpr(struct fetch_context *ctx, struct process *proc, 1520b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata struct arg_type_info *info, struct value *valuep, 1530b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz) 154ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 155ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (ctx->greg > 6) 1560b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_stack_slot(ctx, proc, info, valuep, sz); 157ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 158ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata copy_gpr(ctx, valuep, ctx->greg++); 159ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 160ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 161ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 162ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int 163929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_gpr_pair(struct fetch_context *ctx, struct process *proc, 164df59c75ee9fa70343c9af929403cd3d371443714Petr Machata struct arg_type_info *info, struct value *valuep, 165df59c75ee9fa70343c9af929403cd3d371443714Petr Machata size_t sz) 166df59c75ee9fa70343c9af929403cd3d371443714Petr Machata{ 167df59c75ee9fa70343c9af929403cd3d371443714Petr Machata assert(!s390x(ctx)); 168df59c75ee9fa70343c9af929403cd3d371443714Petr Machata assert(sz <= 8); 169df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 170df59c75ee9fa70343c9af929403cd3d371443714Petr Machata if (ctx->greg > 5) { 171df59c75ee9fa70343c9af929403cd3d371443714Petr Machata ctx->greg = 7; 172df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return allocate_stack_slot(ctx, proc, info, valuep, sz); 173df59c75ee9fa70343c9af929403cd3d371443714Petr Machata } 174df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 175df59c75ee9fa70343c9af929403cd3d371443714Petr Machata if (value_reserve(valuep, sz) == NULL) 176df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return -1; 177df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 178df59c75ee9fa70343c9af929403cd3d371443714Petr Machata unsigned char *ptr = value_get_raw_data(valuep); 179df59c75ee9fa70343c9af929403cd3d371443714Petr Machata union { 180df59c75ee9fa70343c9af929403cd3d371443714Petr Machata struct { 181df59c75ee9fa70343c9af929403cd3d371443714Petr Machata uint32_t a; 182df59c75ee9fa70343c9af929403cd3d371443714Petr Machata uint32_t b; 183df59c75ee9fa70343c9af929403cd3d371443714Petr Machata }; 184df59c75ee9fa70343c9af929403cd3d371443714Petr Machata unsigned char buf[8]; 185df59c75ee9fa70343c9af929403cd3d371443714Petr Machata } u; 186df59c75ee9fa70343c9af929403cd3d371443714Petr Machata u.a = ctx->regs.gprs[ctx->greg++]; 187df59c75ee9fa70343c9af929403cd3d371443714Petr Machata u.b = ctx->regs.gprs[ctx->greg++]; 188df59c75ee9fa70343c9af929403cd3d371443714Petr Machata memcpy(ptr, u.buf, sz); 189df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 190df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return 0; 191df59c75ee9fa70343c9af929403cd3d371443714Petr Machata} 192df59c75ee9fa70343c9af929403cd3d371443714Petr Machata 193df59c75ee9fa70343c9af929403cd3d371443714Petr Machatastatic int 194929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_fpr(struct fetch_context *ctx, struct process *proc, 1950b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata struct arg_type_info *info, struct value *valuep, 1960b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz) 197ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 19882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata int pool = s390x(ctx) ? 6 : 2; 19982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata 20082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata if (ctx->freg > pool) 2010b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_stack_slot(ctx, proc, info, valuep, sz); 202ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 203ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_reserve(valuep, sz) == NULL) 204ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 205ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 206ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata memcpy(value_get_raw_data(valuep), 207ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata &ctx->regs.fp_regs.fprs[ctx->freg], sz); 208ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata ctx->freg += 2; 209ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 210ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 211ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 212ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 213ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint 214ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 215929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct process *proc, 216ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct arg_type_info *info, struct value *valuep) 217ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 2180b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata size_t sz = type_sizeof(proc, info); 2190b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata if (sz == (size_t)-1) 2200b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return -1; 2210b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata 222ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata switch (info->type) { 223ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_VOID: 224ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata value_set_word(valuep, 0); 225ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 226ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 227ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_STRUCT: 228fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata if (type_get_fp_equivalent(info) != NULL) 229ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata /* fall through */ 230ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_FLOAT: 231ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata case ARGTYPE_DOUBLE: 2320b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_fpr(ctx, proc, info, valuep, sz); 233ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 23412d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata /* Structures<4 bytes on s390 and structures<8 bytes 23512d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata * on s390x are passed in register. On s390, long 23612d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata * long and structures<8 bytes are passed in two 23712d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata * consecutive registers (if two are available). */ 23812d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata 239df59c75ee9fa70343c9af929403cd3d371443714Petr Machata if (sz <= (s390x(ctx) ? 8 : 4)) 2400b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_gpr(ctx, proc, info, valuep, sz); 241df59c75ee9fa70343c9af929403cd3d371443714Petr Machata else if (sz <= 8) 242df59c75ee9fa70343c9af929403cd3d371443714Petr Machata return allocate_gpr_pair(ctx, proc, info, valuep, sz); 24312d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata 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: 2590b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata return allocate_gpr(ctx, proc, info, valuep, sz); 2605b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias 2615b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias default: 2625b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias assert(info->type != info->type); 2635b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias abort(); 264ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 265ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 266ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 267ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 268ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint 269ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_retval(struct fetch_context *ctx, enum tof type, 270929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct process *proc, struct arg_type_info *info, 271ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata struct value *valuep) 272ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 273ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (info->type == ARGTYPE_STRUCT) { 274ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (value_pass_by_reference(valuep) < 0) 275ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 276ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata copy_gpr(ctx, valuep, 2); 277ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return 0; 278ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata } 279ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 280ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata if (fetch_context_init(proc, ctx) < 0) 281ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return -1; 282ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata return arch_fetch_arg_next(ctx, type, proc, info, valuep); 283ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 284ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata 285ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatavoid 286ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_done(struct fetch_context *context) 287ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{ 288ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata free(context); 289ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata} 290