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