154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata/*
254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This file is part of ltrace.
354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * Copyright (C) 2012 Petr Machata, Red Hat Inc.
454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata *
554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This program is free software; you can redistribute it and/or
654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * modify it under the terms of the GNU General Public License as
754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * published by the Free Software Foundation; either version 2 of the
854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * License, or (at your option) any later version.
954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata *
1054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This program is distributed in the hope that it will be useful, but
1154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
1254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * General Public License for more details.
1454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata *
1554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * You should have received a copy of the GNU General Public License
1654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * along with this program; if not, write to the Free Software
1754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
1854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 02110-1301 USA
1954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata */
2054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
2154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <assert.h>
2254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <stdint.h>
2354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <stdlib.h>
2454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <string.h>
25b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#include <sys/ucontext.h>
2654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
2754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "backend.h"
2854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "fetch.h"
2954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "type.h"
3003f4b61154d2bfb87530bdc79f548c6374ba0db7Petr Machata#include "ptrace.h"
3154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "proc.h"
3254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "value.h"
3354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
34929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatastatic int allocate_gpr(struct fetch_context *ctx, struct process *proc,
3554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			struct arg_type_info *info, struct value *valuep);
3654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
3754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata/* Floating point registers have the same width on 32-bit as well as
3854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 64-bit PPC, but <ucontext.h> presents a different API depending on
3954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * whether ltrace is PPC32 or PPC64.
4054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata *
4154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This is PPC64 definition.  The PPC32 is simply an array of 33
4254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * doubles, and doesn't contain the terminating pad.  Both seem
4354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * compatible enough.  */
4454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fpregs_t
4554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
4654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	double fpregs[32];
4754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	double fpscr;
4854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	unsigned int _pad[2];
4954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata};
5054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
5154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatatypedef uint32_t gregs32_t[48];
5254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatatypedef uint64_t gregs64_t[48];
5354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
5454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fetch_context {
55bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t stack_pointer;
5654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	int greg;
5754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	int freg;
5854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	int ret_struct;
5954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
6054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	union {
6154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		gregs32_t r32;
6254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		gregs64_t r64;
6354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	} regs;
6454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	struct fpregs_t fpregs;
6554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
6654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata};
6754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
6854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int
69929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_context_init(struct process *proc, struct fetch_context *context)
7054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
7154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	context->greg = 3;
7254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	context->freg = 1;
7354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
747d1e7926b92403ce03d1c2002c80937b280fa415Petr Machata	if (proc->e_machine == EM_PPC)
7554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		context->stack_pointer = proc->stack_pointer + 8;
7654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	else
7754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		context->stack_pointer = proc->stack_pointer + 112;
7854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
7954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	/* When ltrace is 64-bit, we might use PTRACE_GETREGS to
8054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * obtain 64-bit as well as 32-bit registers.  But if we do it
8154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * this way, 32-bit ltrace can obtain 64-bit registers.
8254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 *
8354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * XXX this direction is not supported as of this writing, but
8454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * should be eventually.  */
8554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (proc->e_machine == EM_PPC64) {
8654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		if (ptrace(PTRACE_GETREGS64, proc->pid, 0,
8754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			   &context->regs.r64) < 0)
8854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			return -1;
89b52f89c1302256bae003edc44c6e3788833629f1Petr Machata	} else {
90b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#ifdef __powerpc64__
91b52f89c1302256bae003edc44c6e3788833629f1Petr Machata		if (ptrace(PTRACE_GETREGS, proc->pid, 0,
92b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			  &context->regs.r64) < 0)
93b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			return -1;
94b52f89c1302256bae003edc44c6e3788833629f1Petr Machata		unsigned i;
95b52f89c1302256bae003edc44c6e3788833629f1Petr Machata		for (i = 0; i < sizeof(context->regs.r64)/8; ++i)
96b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			context->regs.r32[i] = context->regs.r64[i];
97b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#else
98b52f89c1302256bae003edc44c6e3788833629f1Petr Machata		if (ptrace(PTRACE_GETREGS, proc->pid, 0,
99b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			  &context->regs.r32) < 0)
100b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			return -1;
101b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#endif
10254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	}
10354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
10454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (ptrace(PTRACE_GETFPREGS, proc->pid, 0, &context->fpregs) < 0)
10554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		return -1;
10654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
10754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	return 0;
10854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
10954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
11054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fetch_context *
111929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_init(enum tof type, struct process *proc,
11254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		    struct arg_type_info *ret_info)
11354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
11454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	struct fetch_context *context = malloc(sizeof(*context));
11554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (context == NULL
11654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	    || fetch_context_init(proc, context) < 0) {
11754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		free(context);
11854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		return NULL;
11954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	}
12054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
12154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	/* Aggregates or unions of any length, and character strings
12254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * of length longer than 8 bytes, will be returned in a
12354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * storage buffer allocated by the caller. The caller will
12454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * pass the address of this buffer as a hidden first argument
12554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * in r3, causing the first explicit argument to be passed in
12654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	 * r4.  */
12754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	context->ret_struct = ret_info->type == ARGTYPE_STRUCT;
12854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (context->ret_struct)
12954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		context->greg++;
13054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
13154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	return context;
13254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
13354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
13454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fetch_context *
135929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_clone(struct process *proc,
13654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		     struct fetch_context *context)
13754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
13854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	struct fetch_context *clone = malloc(sizeof(*context));
13954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (clone == NULL)
14054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		return NULL;
14154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	*clone = *context;
14254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	return clone;
14354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
14454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
14554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int
146929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_stack_slot(struct fetch_context *ctx, struct process *proc,
14754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		    struct arg_type_info *info, struct value *valuep)
14854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
149f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	size_t sz = type_sizeof(proc, info);
150f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	if (sz == (size_t)-1)
151f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		return -1;
152f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata
153d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	size_t a = type_alignof(proc, info);
154d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	size_t off = 0;
155f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	if (proc->e_machine == EM_PPC && a < 4)
156f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		a = 4;
157f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	else if (proc->e_machine == EM_PPC64 && a < 8)
158f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		a = 8;
159f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata
160bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	/* XXX Remove the two double casts when arch_addr_t
16136718b01e510ff3973e14b2bad0dbad3177b9943Petr Machata	 * becomes integral type.  */
16236718b01e510ff3973e14b2bad0dbad3177b9943Petr Machata	uintptr_t tmp = align((uint64_t)(uintptr_t)ctx->stack_pointer, a);
163bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	ctx->stack_pointer = (arch_addr_t)tmp;
164f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata
1650ffa9f3f82febbcd475318ac282c456adb76c73cPetr Machata	if (valuep != NULL)
1660ffa9f3f82febbcd475318ac282c456adb76c73cPetr Machata		value_in_inferior(valuep, ctx->stack_pointer + off);
167f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	ctx->stack_pointer += sz;
168f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata
169f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	return 0;
17054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
17154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
172d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machatastatic uint64_t
173929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataread_gpr(struct fetch_context *ctx, struct process *proc, int reg_num)
174d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata{
175d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	if (proc->e_machine == EM_PPC)
176d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return ctx->regs.r32[reg_num];
177d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	else
178d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return ctx->regs.r64[reg_num];
179d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata}
180d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
1812d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata/* The support for little endian PowerPC is in upstream Linux and BFD,
1822d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * and Unix-like Solaris, which we might well support at some point,
1832d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * runs PowerPC in little endian as well.  This code moves SZ-sized
1842d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * value to the beginning of W-sized BUF regardless of
1852d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * endian.  */
1862d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machatastatic void
1872d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machataalign_small_int(unsigned char *buf, size_t w, size_t sz)
1882d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata{
1892d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	assert(w == 4 || w == 8);
1902d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	union {
1912d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		uint64_t i64;
1922d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		uint32_t i32;
1932d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		uint16_t i16;
1942d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		uint8_t i8;
1952d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		char buf[0];
1962d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	} u;
1972d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	memcpy(u.buf, buf, w);
1982d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	if (w == 4)
1992d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		u.i64 = u.i32;
2002d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata
2012d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	switch (sz) {
2022d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	case 1:
2032d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		u.i8 = u.i64;
2042d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		break;
2052d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	case 2:
2062d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		u.i16 = u.i64;
2072d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		break;
2082d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	case 4:
2092d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		u.i32 = u.i64;
2102d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	case 8:
2112d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		break;
2122d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	}
2132d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata
2142d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata	memcpy(buf, u.buf, sz);
2152d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata}
216b52f89c1302256bae003edc44c6e3788833629f1Petr Machata
217d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machatastatic int
218929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_gpr(struct fetch_context *ctx, struct process *proc,
219d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	     struct arg_type_info *info, struct value *valuep)
220d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata{
221d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	if (ctx->greg > 10)
222d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return allocate_stack_slot(ctx, proc, info, valuep);
223d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
224d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	int reg_num = ctx->greg++;
225d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	if (valuep == NULL)
226d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return 0;
227d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
228d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	size_t sz = type_sizeof(proc, info);
229d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	if (sz == (size_t)-1)
230d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return -1;
231d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	assert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
232d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	if (value_reserve(valuep, sz) == NULL)
233d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return -1;
234d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
235d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	union {
236d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		uint64_t i64;
237b52f89c1302256bae003edc44c6e3788833629f1Petr Machata		unsigned char buf[0];
238d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	} u;
239d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
240d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	u.i64 = read_gpr(ctx, proc, reg_num);
241b52f89c1302256bae003edc44c6e3788833629f1Petr Machata	if (proc->e_machine == EM_PPC)
2422d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata		align_small_int(u.buf, 8, sz);
243d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	memcpy(value_get_raw_data(valuep), u.buf, sz);
244d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	return 0;
245d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata}
246d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
24754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int
248929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_float(struct fetch_context *ctx, struct process *proc,
24954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	       struct arg_type_info *info, struct value *valuep)
25054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
251b52f89c1302256bae003edc44c6e3788833629f1Petr Machata	int pool = proc->e_machine == EM_PPC64 ? 13 : 8;
25254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (ctx->freg <= pool) {
25354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		union {
25454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			double d;
25554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			float f;
25654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			char buf[0];
25754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		} u = { .d = ctx->fpregs.fpregs[ctx->freg] };
25854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
25954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		ctx->freg++;
260dbcb32a5ab5a1c9e2d8cb70b07320db1ae8c234bPetr Machata		if (proc->e_machine == EM_PPC64)
261dbcb32a5ab5a1c9e2d8cb70b07320db1ae8c234bPetr Machata			allocate_gpr(ctx, proc, info, NULL);
26254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
26354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		size_t sz = sizeof(double);
26454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		if (info->type == ARGTYPE_FLOAT) {
26554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			sz = sizeof(float);
26654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			u.f = (float)u.d;
26754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		}
26854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
26954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		if (value_reserve(valuep, sz) == NULL)
27054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata			return -1;
27154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
27254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		memcpy(value_get_raw_data(valuep), u.buf, sz);
27354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		return 0;
27454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	}
27554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	return allocate_stack_slot(ctx, proc, info, valuep);
27654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
27754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
27854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int
279929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_argument(struct fetch_context *ctx, struct process *proc,
280d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		  struct arg_type_info *info, struct value *valuep)
281f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata{
282d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	/* Floating point types and void are handled specially.  */
283d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	switch (info->type) {
284d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_VOID:
285d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		value_set_word(valuep, 0);
286d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return 0;
287d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
288d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_FLOAT:
289d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_DOUBLE:
290d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		return allocate_float(ctx, proc, info, valuep);
291d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
292d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_STRUCT:
293d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		if (proc->e_machine == EM_PPC) {
294d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			if (value_pass_by_reference(valuep) < 0)
295d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata				return -1;
296d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		} else {
297d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			/* PPC64: Fixed size aggregates and unions passed by
298d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			 * value are mapped to as many doublewords of the
299d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			 * parameter save area as the value uses in memory.
300d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			 * [...] The first eight doublewords mapped to the
301d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			 * parameter save area correspond to the registers r3
302d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			 * through r10.  */
303d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		}
304d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		/* fall through */
305d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_CHAR:
306d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_SHORT:
307d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_USHORT:
308d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_INT:
309d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_UINT:
310d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_LONG:
311d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_ULONG:
312d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_POINTER:
313d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		break;
314d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
315d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	case ARGTYPE_ARRAY:
316d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		/* Arrays decay into pointers.  XXX Fortran?  */
3175b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias	default:
3185b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias		assert(info->type != info->type);
319d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		abort();
320d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	}
321d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
322b52f89c1302256bae003edc44c6e3788833629f1Petr Machata	unsigned width = proc->e_machine == EM_PPC64 ? 8 : 4;
323b52f89c1302256bae003edc44c6e3788833629f1Petr Machata
324d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	/* For other cases (integral types and aggregates), read the
325d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	 * eightbytes comprising the data.  */
32695792af484c635071ed96107d34a3762c4ca2ef2Petr Machata	size_t sz = type_sizeof(proc, valuep->type);
327f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	if (sz == (size_t)-1)
328f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		return -1;
329b52f89c1302256bae003edc44c6e3788833629f1Petr Machata	size_t slots = (sz + width - 1) / width;  /* Round up.  */
330b52f89c1302256bae003edc44c6e3788833629f1Petr Machata	unsigned char *buf = value_reserve(valuep, slots * width);
331f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	if (buf == NULL)
332f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		return -1;
333d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG);
334f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata
335d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	unsigned char *ptr = buf;
336b52f89c1302256bae003edc44c6e3788833629f1Petr Machata	while (slots-- > 0) {
337f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		struct value val;
338d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		value_init(&val, proc, NULL, long_info, 0);
339fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata
340fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		/* Floating point registers [...] are used [...] to
341fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		   pass [...] one member aggregates passed by value
342fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		   containing a floating point value[.]  Note that for
343fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		   one member aggregates, "containing" extends to
344fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		   aggregates within aggregates ad infinitum.  */
345fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		int rc;
346fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		struct arg_type_info *fp_info
347fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata			= type_get_fp_equivalent(valuep->type);
348fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		if (fp_info != NULL)
349fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata			rc = allocate_float(ctx, proc, fp_info, &val);
350fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		else
351fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata			rc = allocate_gpr(ctx, proc, long_info, &val);
352fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata
353f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		if (rc >= 0) {
354b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			memcpy(ptr, value_get_data(&val, NULL), width);
355b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			ptr += width;
356f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		}
357f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata		value_destroy(&val);
358fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata
359fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		/* Bail out if we failed or if we are dealing with
360fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		 * FP-equivalent.  Those don't need the adjustments
361fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		 * made below.  */
362fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata		if (rc < 0 || fp_info != NULL)
363f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata			return rc;
364f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata	}
365f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata
366d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	/* Small values need post-processing.  */
367ebd9191418bd73796533d6e21a2536906459ec1fPetr Machata	if (sz < width) {
368d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		switch (info->type) {
3695b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias		default:
370d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			abort();
371d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
372d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		/* Simple integer types (char, short, int, long, enum)
373d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 * are mapped to a single doubleword. Values shorter
374d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 * than a doubleword are sign or zero extended as
375d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 * necessary.  */
376d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_CHAR:
377d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_SHORT:
378d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_INT:
379d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_USHORT:
380d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_UINT:
3812d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata			align_small_int(buf, width, sz);
382d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			break;
383d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata
384d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		/* Single precision floating point values are mapped
385d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 * to the second word in a single doubleword.
386d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 *
387d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 * An aggregate or union smaller than one doubleword
388d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 * in size is padded so that it appears in the least
389d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		 * significant bits of the doubleword.  */
390d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_FLOAT:
391d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_ARRAY:
392d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		case ARGTYPE_STRUCT:
393b52f89c1302256bae003edc44c6e3788833629f1Petr Machata			memmove(buf, buf + width - sz, sz);
394d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata			break;
395d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata		}
39654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	}
39754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
398d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata	return 0;
39954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
40054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
40154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataint
40254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataarch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
403929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata		    struct process *proc,
40454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		    struct arg_type_info *info, struct value *valuep)
40554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
40654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	return allocate_argument(ctx, proc, info, valuep);
40754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
40854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
40954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataint
41054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataarch_fetch_retval(struct fetch_context *ctx, enum tof type,
411929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata		  struct process *proc, struct arg_type_info *info,
41254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		  struct value *valuep)
41354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
41454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (ctx->ret_struct) {
41554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		assert(info->type == ARGTYPE_STRUCT);
41654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
41754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		uint64_t addr = read_gpr(ctx, proc, 3);
41854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		value_init(valuep, proc, NULL, info, 0);
41954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
42054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		valuep->where = VAL_LOC_INFERIOR;
421bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		/* XXX Remove the double cast when arch_addr_t
42236718b01e510ff3973e14b2bad0dbad3177b9943Petr Machata		 * becomes integral type. */
423bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		valuep->u.address = (arch_addr_t)(uintptr_t)addr;
42454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		return 0;
42554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	}
42654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
42754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	if (fetch_context_init(proc, ctx) < 0)
42854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata		return -1;
42954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	return allocate_argument(ctx, proc, info, valuep);
43054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
43154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata
43254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatavoid
43354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataarch_fetch_arg_done(struct fetch_context *context)
43454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{
43554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata	free(context);
43654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}
437