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>
2642cccc91299718b95eecffa6941e29c33d5616b3Petr Machata#include <stdbool.h>
27ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <stdio.h>
28ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <stdlib.h>
29ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include <string.h>
30ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
31ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "backend.h"
32ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "fetch.h"
33ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "type.h"
34ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "proc.h"
35ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata#include "value.h"
36ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
37ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context {
38ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	struct user_regs_struct regs;
39ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	arch_addr_t stack_pointer;
40ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	int greg;
41ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	int freg;
42ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata};
43ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
44ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int
4582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machatas390x(struct fetch_context *ctx)
4682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata{
478d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	/* +--------+--------+--------+
488d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 * | PSW.31 | PSW.32 | mode   |
498d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 * +--------+--------+--------+
508d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 * | 0      | 0      | 24-bit | Not supported in Linux
518d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 * | 0      | 1      | 31-bit | s390 compatible mode
528d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 * | 1      | 1      | 64-bit | z/Architecture, "s390x"
538d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 * +--------+--------+--------+
548d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 * (Note: The leftmost bit is PSW.0, rightmost PSW.63.)
558d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata	 */
568d30fd9f26ccd15f0fa27e09d1fd99deddb17d36Petr Machata
5782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata#ifdef __s390x__
5882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	if ((ctx->regs.psw.mask & 0x180000000UL) == 0x180000000UL)
5982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata		return 1;
6082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata#endif
6182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	return 0;
6282b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata}
6382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata
6482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machatastatic int
6542cccc91299718b95eecffa6941e29c33d5616b3Petr Machatafetch_register_banks(struct process *proc, struct fetch_context *ctx,
6642cccc91299718b95eecffa6941e29c33d5616b3Petr Machata		     bool syscall_enter)
67ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
68ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	ptrace_area parea;
69ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	parea.len = sizeof(ctx->regs);
70ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	parea.process_addr = (uintptr_t)&ctx->regs;
71ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	parea.kernel_addr = 0;
72ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	if (ptrace(PTRACE_PEEKUSR_AREA, proc->pid, &parea, NULL) < 0) {
73ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		fprintf(stderr, "fetch_register_banks GPR: %s\n",
74ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata			strerror(errno));
75ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		return -1;
76ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	}
7742cccc91299718b95eecffa6941e29c33d5616b3Petr Machata
7842cccc91299718b95eecffa6941e29c33d5616b3Petr Machata	if (syscall_enter)
7942cccc91299718b95eecffa6941e29c33d5616b3Petr Machata		ctx->regs.gprs[2] = ctx->regs.orig_gpr2;
8042cccc91299718b95eecffa6941e29c33d5616b3Petr Machata
81ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return 0;
82ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
83ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
84ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int
8542cccc91299718b95eecffa6941e29c33d5616b3Petr Machatafetch_context_init(struct process *proc, struct fetch_context *context,
8642cccc91299718b95eecffa6941e29c33d5616b3Petr Machata		   bool syscall_enter)
87ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
88ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	context->greg = 2;
89ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	context->freg = 0;
9042cccc91299718b95eecffa6941e29c33d5616b3Petr Machata	return fetch_register_banks(proc, context, syscall_enter);
91ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
92ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
93ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context *
94929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_init(enum tof type, struct process *proc,
95ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		    struct arg_type_info *ret_info)
96ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
97ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	struct fetch_context *context = malloc(sizeof(*context));
98ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	if (context == NULL
9942cccc91299718b95eecffa6941e29c33d5616b3Petr Machata	    || fetch_context_init(proc, context, type == LT_TOF_SYSCALL) < 0) {
100ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		fprintf(stderr, "arch_fetch_arg_init: %s\n",
101ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata			strerror(errno));
102ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		free(context);
103ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		return NULL;
104ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	}
105ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
10682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	context->stack_pointer = get_stack_pointer(proc)
10782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata		+ (s390x(context) ? 160 : 96);
108ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	if (ret_info->type == ARGTYPE_STRUCT)
109ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		++context->greg;
110ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
111ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return context;
112ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
113ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
114ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastruct fetch_context *
115929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_clone(struct process *proc,
116ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		     struct fetch_context *context)
117ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
118ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	struct fetch_context *clone = malloc(sizeof(*context));
119ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	if (clone == NULL)
120ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		return NULL;
121ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	*clone = *context;
122ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return clone;
123ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
124ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
125ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int
126929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_stack_slot(struct fetch_context *ctx, struct process *proc,
1270b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata		    struct arg_type_info *info, struct value *valuep,
1280b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata		    size_t sz)
129ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
130df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	/* Note: here we shouldn't see large composite types, those
13182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	 * are passed by reference, which is handled below.  Here we
132df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	 * only deal with integers, floats, small structs, etc.  */
13382b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata
13482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	size_t a;
13582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	if (s390x(ctx)) {
13682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata		assert(sz <= 8);
137ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		a = 8;
13882b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	} else {
13982b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata		/* Note: double is 8 bytes.  */
14082b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata		assert(sz <= 8);
14182b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata		a = 4;
14282b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	}
143ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
14482b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	size_t off = sz < a ? a - sz : 0;
1450ffa9f3f82febbcd475318ac282c456adb76c73cPetr Machata	value_in_inferior(valuep, ctx->stack_pointer + off);
146ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
14782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	ctx->stack_pointer += sz > a ? sz : a;
148ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return 0;
149ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
150ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
151ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic void
152ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatacopy_gpr(struct fetch_context *ctx, struct value *valuep, int regno)
153ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
154ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	value_set_word(valuep, ctx->regs.gprs[regno]);
155ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
156ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
157ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int
158929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_gpr(struct fetch_context *ctx, struct process *proc,
1590b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata	     struct arg_type_info *info, struct value *valuep,
1600b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata	     size_t sz)
161ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
162ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	if (ctx->greg > 6)
1630b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata		return allocate_stack_slot(ctx, proc, info, valuep, sz);
164ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
165ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	copy_gpr(ctx, valuep, ctx->greg++);
166ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return 0;
167ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
168ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
169ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatastatic int
170929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_gpr_pair(struct fetch_context *ctx, struct process *proc,
171df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		  struct arg_type_info *info, struct value *valuep,
172df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		  size_t sz)
173df59c75ee9fa70343c9af929403cd3d371443714Petr Machata{
174df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	assert(!s390x(ctx));
175df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	assert(sz <= 8);
176df59c75ee9fa70343c9af929403cd3d371443714Petr Machata
177df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	if (ctx->greg > 5) {
178df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		ctx->greg = 7;
179df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		return allocate_stack_slot(ctx, proc, info, valuep, sz);
180df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	}
181df59c75ee9fa70343c9af929403cd3d371443714Petr Machata
182df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	if (value_reserve(valuep, sz) == NULL)
183df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		return -1;
184df59c75ee9fa70343c9af929403cd3d371443714Petr Machata
185df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	unsigned char *ptr = value_get_raw_data(valuep);
186df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	union {
187df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		struct {
188df59c75ee9fa70343c9af929403cd3d371443714Petr Machata			uint32_t a;
189df59c75ee9fa70343c9af929403cd3d371443714Petr Machata			uint32_t b;
190df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		};
191df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		unsigned char buf[8];
192df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	} u;
193df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	u.a = ctx->regs.gprs[ctx->greg++];
194df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	u.b = ctx->regs.gprs[ctx->greg++];
195df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	memcpy(ptr, u.buf, sz);
196df59c75ee9fa70343c9af929403cd3d371443714Petr Machata
197df59c75ee9fa70343c9af929403cd3d371443714Petr Machata	return 0;
198df59c75ee9fa70343c9af929403cd3d371443714Petr Machata}
199df59c75ee9fa70343c9af929403cd3d371443714Petr Machata
200df59c75ee9fa70343c9af929403cd3d371443714Petr Machatastatic int
201929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_fpr(struct fetch_context *ctx, struct process *proc,
2020b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata	     struct arg_type_info *info, struct value *valuep,
2030b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata	     size_t sz)
204ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
20582b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	int pool = s390x(ctx) ? 6 : 2;
20682b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata
20782b1977bfdc0c31be26454257db28a1cb497fbf2Petr Machata	if (ctx->freg > pool)
2080b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata		return allocate_stack_slot(ctx, proc, info, valuep, sz);
209ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
210ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	if (value_reserve(valuep, sz) == NULL)
211ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		return -1;
212ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
213ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	memcpy(value_get_raw_data(valuep),
214ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	       &ctx->regs.fp_regs.fprs[ctx->freg], sz);
215ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	ctx->freg += 2;
216ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
217ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return 0;
218ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
219ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
220ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint
221ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
222929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata		    struct process *proc,
223ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		    struct arg_type_info *info, struct value *valuep)
224ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
2250b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata	size_t sz = type_sizeof(proc, info);
2260b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata	if (sz == (size_t)-1)
2270b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata		return -1;
2280b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr 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:
235fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		if (type_get_fp_equivalent(info) != NULL)
236ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata			/* fall through */
237ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_FLOAT:
238ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_DOUBLE:
2390b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata			return allocate_fpr(ctx, proc, info, valuep, sz);
240ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
24112d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata		/* Structures<4 bytes on s390 and structures<8 bytes
24212d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata		 * on s390x are passed in register.  On s390, long
24312d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata		 * long and structures<8 bytes are passed in two
24412d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata		 * consecutive registers (if two are available).  */
24512d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata
246df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		if (sz <= (s390x(ctx) ? 8 : 4))
2470b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata			return allocate_gpr(ctx, proc, info, valuep, sz);
248df59c75ee9fa70343c9af929403cd3d371443714Petr Machata		else if (sz <= 8)
249df59c75ee9fa70343c9af929403cd3d371443714Petr Machata			return allocate_gpr_pair(ctx, proc, info, valuep, sz);
25012d64f8bbae6245146900e8ee2292d854a22f26dPetr Machata
251ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		/* fall through */
252ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
253ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_ARRAY:
254ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		if (value_pass_by_reference(valuep) < 0)
255ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata			return -1;
256ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		/* fall through */
257ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
258ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_INT:
259ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_UINT:
260ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_LONG:
261ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_ULONG:
262ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_CHAR:
263ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_SHORT:
264ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_USHORT:
265ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	case ARGTYPE_POINTER:
2660b926f68098c4dd0df922ba2c6214ed902cd4cd6Petr Machata		return allocate_gpr(ctx, proc, info, valuep, sz);
2675b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias
2685b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias	default:
2695b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias		assert(info->type != info->type);
2705b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias		abort();
271ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	}
272ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return -1;
273ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
274ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
275ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataint
276ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_retval(struct fetch_context *ctx, enum tof type,
277929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata		  struct process *proc, struct arg_type_info *info,
278ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		  struct value *valuep)
279ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
280ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	if (info->type == ARGTYPE_STRUCT) {
281ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		if (value_pass_by_reference(valuep) < 0)
282ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata			return -1;
283ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		copy_gpr(ctx, valuep, 2);
284ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		return 0;
285ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	}
286ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
28742cccc91299718b95eecffa6941e29c33d5616b3Petr Machata	if (fetch_context_init(proc, ctx, false) < 0)
288ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata		return -1;
289ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	return arch_fetch_arg_next(ctx, type, proc, info, valuep);
290ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
291ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata
292ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machatavoid
293ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machataarch_fetch_arg_done(struct fetch_context *context)
294ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata{
295ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata	free(context);
296ecb2e82fe81684fc10876db6b73de8cefad06d9aPetr Machata}
297