1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2012 Petr Machata, Red Hat Inc.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21#include <assert.h>
22#include <stdint.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/ucontext.h>
26
27#include "backend.h"
28#include "fetch.h"
29#include "type.h"
30#include "ptrace.h"
31#include "proc.h"
32#include "value.h"
33
34static int allocate_gpr(struct fetch_context *ctx, struct process *proc,
35			struct arg_type_info *info, struct value *valuep);
36
37/* Floating point registers have the same width on 32-bit as well as
38 * 64-bit PPC, but <ucontext.h> presents a different API depending on
39 * whether ltrace is PPC32 or PPC64.
40 *
41 * This is PPC64 definition.  The PPC32 is simply an array of 33
42 * doubles, and doesn't contain the terminating pad.  Both seem
43 * compatible enough.  */
44struct fpregs_t
45{
46	double fpregs[32];
47	double fpscr;
48	unsigned int _pad[2];
49};
50
51typedef uint32_t gregs32_t[48];
52typedef uint64_t gregs64_t[48];
53
54struct fetch_context {
55	arch_addr_t stack_pointer;
56	int greg;
57	int freg;
58	int ret_struct;
59
60	union {
61		gregs32_t r32;
62		gregs64_t r64;
63	} regs;
64	struct fpregs_t fpregs;
65
66};
67
68static int
69fetch_context_init(struct process *proc, struct fetch_context *context)
70{
71	context->greg = 3;
72	context->freg = 1;
73
74	if (proc->e_machine == EM_PPC)
75		context->stack_pointer = proc->stack_pointer + 8;
76	else
77		context->stack_pointer = proc->stack_pointer + 112;
78
79	/* When ltrace is 64-bit, we might use PTRACE_GETREGS to
80	 * obtain 64-bit as well as 32-bit registers.  But if we do it
81	 * this way, 32-bit ltrace can obtain 64-bit registers.
82	 *
83	 * XXX this direction is not supported as of this writing, but
84	 * should be eventually.  */
85	if (proc->e_machine == EM_PPC64) {
86		if (ptrace(PTRACE_GETREGS64, proc->pid, 0,
87			   &context->regs.r64) < 0)
88			return -1;
89	} else {
90#ifdef __powerpc64__
91		if (ptrace(PTRACE_GETREGS, proc->pid, 0,
92			  &context->regs.r64) < 0)
93			return -1;
94		unsigned i;
95		for (i = 0; i < sizeof(context->regs.r64)/8; ++i)
96			context->regs.r32[i] = context->regs.r64[i];
97#else
98		if (ptrace(PTRACE_GETREGS, proc->pid, 0,
99			  &context->regs.r32) < 0)
100			return -1;
101#endif
102	}
103
104	if (ptrace(PTRACE_GETFPREGS, proc->pid, 0, &context->fpregs) < 0)
105		return -1;
106
107	return 0;
108}
109
110struct fetch_context *
111arch_fetch_arg_init(enum tof type, struct process *proc,
112		    struct arg_type_info *ret_info)
113{
114	struct fetch_context *context = malloc(sizeof(*context));
115	if (context == NULL
116	    || fetch_context_init(proc, context) < 0) {
117		free(context);
118		return NULL;
119	}
120
121	/* Aggregates or unions of any length, and character strings
122	 * of length longer than 8 bytes, will be returned in a
123	 * storage buffer allocated by the caller. The caller will
124	 * pass the address of this buffer as a hidden first argument
125	 * in r3, causing the first explicit argument to be passed in
126	 * r4.  */
127	context->ret_struct = ret_info->type == ARGTYPE_STRUCT;
128	if (context->ret_struct)
129		context->greg++;
130
131	return context;
132}
133
134struct fetch_context *
135arch_fetch_arg_clone(struct process *proc,
136		     struct fetch_context *context)
137{
138	struct fetch_context *clone = malloc(sizeof(*context));
139	if (clone == NULL)
140		return NULL;
141	*clone = *context;
142	return clone;
143}
144
145static int
146allocate_stack_slot(struct fetch_context *ctx, struct process *proc,
147		    struct arg_type_info *info, struct value *valuep)
148{
149	size_t sz = type_sizeof(proc, info);
150	if (sz == (size_t)-1)
151		return -1;
152
153	size_t a = type_alignof(proc, info);
154	size_t off = 0;
155	if (proc->e_machine == EM_PPC && a < 4)
156		a = 4;
157	else if (proc->e_machine == EM_PPC64 && a < 8)
158		a = 8;
159
160	/* XXX Remove the two double casts when arch_addr_t
161	 * becomes integral type.  */
162	uintptr_t tmp = align((uint64_t)(uintptr_t)ctx->stack_pointer, a);
163	ctx->stack_pointer = (arch_addr_t)tmp;
164
165	if (valuep != NULL)
166		value_in_inferior(valuep, ctx->stack_pointer + off);
167	ctx->stack_pointer += sz;
168
169	return 0;
170}
171
172static uint64_t
173read_gpr(struct fetch_context *ctx, struct process *proc, int reg_num)
174{
175	if (proc->e_machine == EM_PPC)
176		return ctx->regs.r32[reg_num];
177	else
178		return ctx->regs.r64[reg_num];
179}
180
181/* The support for little endian PowerPC is in upstream Linux and BFD,
182 * and Unix-like Solaris, which we might well support at some point,
183 * runs PowerPC in little endian as well.  This code moves SZ-sized
184 * value to the beginning of W-sized BUF regardless of
185 * endian.  */
186static void
187align_small_int(unsigned char *buf, size_t w, size_t sz)
188{
189	assert(w == 4 || w == 8);
190	union {
191		uint64_t i64;
192		uint32_t i32;
193		uint16_t i16;
194		uint8_t i8;
195		char buf[0];
196	} u;
197	memcpy(u.buf, buf, w);
198	if (w == 4)
199		u.i64 = u.i32;
200
201	switch (sz) {
202	case 1:
203		u.i8 = u.i64;
204		break;
205	case 2:
206		u.i16 = u.i64;
207		break;
208	case 4:
209		u.i32 = u.i64;
210	case 8:
211		break;
212	}
213
214	memcpy(buf, u.buf, sz);
215}
216
217static int
218allocate_gpr(struct fetch_context *ctx, struct process *proc,
219	     struct arg_type_info *info, struct value *valuep)
220{
221	if (ctx->greg > 10)
222		return allocate_stack_slot(ctx, proc, info, valuep);
223
224	int reg_num = ctx->greg++;
225	if (valuep == NULL)
226		return 0;
227
228	size_t sz = type_sizeof(proc, info);
229	if (sz == (size_t)-1)
230		return -1;
231	assert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
232	if (value_reserve(valuep, sz) == NULL)
233		return -1;
234
235	union {
236		uint64_t i64;
237		unsigned char buf[0];
238	} u;
239
240	u.i64 = read_gpr(ctx, proc, reg_num);
241	if (proc->e_machine == EM_PPC)
242		align_small_int(u.buf, 8, sz);
243	memcpy(value_get_raw_data(valuep), u.buf, sz);
244	return 0;
245}
246
247static int
248allocate_float(struct fetch_context *ctx, struct process *proc,
249	       struct arg_type_info *info, struct value *valuep)
250{
251	int pool = proc->e_machine == EM_PPC64 ? 13 : 8;
252	if (ctx->freg <= pool) {
253		union {
254			double d;
255			float f;
256			char buf[0];
257		} u = { .d = ctx->fpregs.fpregs[ctx->freg] };
258
259		ctx->freg++;
260		if (proc->e_machine == EM_PPC64)
261			allocate_gpr(ctx, proc, info, NULL);
262
263		size_t sz = sizeof(double);
264		if (info->type == ARGTYPE_FLOAT) {
265			sz = sizeof(float);
266			u.f = (float)u.d;
267		}
268
269		if (value_reserve(valuep, sz) == NULL)
270			return -1;
271
272		memcpy(value_get_raw_data(valuep), u.buf, sz);
273		return 0;
274	}
275	return allocate_stack_slot(ctx, proc, info, valuep);
276}
277
278static int
279allocate_argument(struct fetch_context *ctx, struct process *proc,
280		  struct arg_type_info *info, struct value *valuep)
281{
282	/* Floating point types and void are handled specially.  */
283	switch (info->type) {
284	case ARGTYPE_VOID:
285		value_set_word(valuep, 0);
286		return 0;
287
288	case ARGTYPE_FLOAT:
289	case ARGTYPE_DOUBLE:
290		return allocate_float(ctx, proc, info, valuep);
291
292	case ARGTYPE_STRUCT:
293		if (proc->e_machine == EM_PPC) {
294			if (value_pass_by_reference(valuep) < 0)
295				return -1;
296		} else {
297			/* PPC64: Fixed size aggregates and unions passed by
298			 * value are mapped to as many doublewords of the
299			 * parameter save area as the value uses in memory.
300			 * [...] The first eight doublewords mapped to the
301			 * parameter save area correspond to the registers r3
302			 * through r10.  */
303		}
304		/* fall through */
305	case ARGTYPE_CHAR:
306	case ARGTYPE_SHORT:
307	case ARGTYPE_USHORT:
308	case ARGTYPE_INT:
309	case ARGTYPE_UINT:
310	case ARGTYPE_LONG:
311	case ARGTYPE_ULONG:
312	case ARGTYPE_POINTER:
313		break;
314
315	case ARGTYPE_ARRAY:
316		/* Arrays decay into pointers.  XXX Fortran?  */
317	default:
318		assert(info->type != info->type);
319		abort();
320	}
321
322	unsigned width = proc->e_machine == EM_PPC64 ? 8 : 4;
323
324	/* For other cases (integral types and aggregates), read the
325	 * eightbytes comprising the data.  */
326	size_t sz = type_sizeof(proc, valuep->type);
327	if (sz == (size_t)-1)
328		return -1;
329	size_t slots = (sz + width - 1) / width;  /* Round up.  */
330	unsigned char *buf = value_reserve(valuep, slots * width);
331	if (buf == NULL)
332		return -1;
333	struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG);
334
335	unsigned char *ptr = buf;
336	while (slots-- > 0) {
337		struct value val;
338		value_init(&val, proc, NULL, long_info, 0);
339
340		/* Floating point registers [...] are used [...] to
341		   pass [...] one member aggregates passed by value
342		   containing a floating point value[.]  Note that for
343		   one member aggregates, "containing" extends to
344		   aggregates within aggregates ad infinitum.  */
345		int rc;
346		struct arg_type_info *fp_info
347			= type_get_fp_equivalent(valuep->type);
348		if (fp_info != NULL)
349			rc = allocate_float(ctx, proc, fp_info, &val);
350		else
351			rc = allocate_gpr(ctx, proc, long_info, &val);
352
353		if (rc >= 0) {
354			memcpy(ptr, value_get_data(&val, NULL), width);
355			ptr += width;
356		}
357		value_destroy(&val);
358
359		/* Bail out if we failed or if we are dealing with
360		 * FP-equivalent.  Those don't need the adjustments
361		 * made below.  */
362		if (rc < 0 || fp_info != NULL)
363			return rc;
364	}
365
366	/* Small values need post-processing.  */
367	if (sz < width) {
368		switch (info->type) {
369		default:
370			abort();
371
372		/* Simple integer types (char, short, int, long, enum)
373		 * are mapped to a single doubleword. Values shorter
374		 * than a doubleword are sign or zero extended as
375		 * necessary.  */
376		case ARGTYPE_CHAR:
377		case ARGTYPE_SHORT:
378		case ARGTYPE_INT:
379		case ARGTYPE_USHORT:
380		case ARGTYPE_UINT:
381			align_small_int(buf, width, sz);
382			break;
383
384		/* Single precision floating point values are mapped
385		 * to the second word in a single doubleword.
386		 *
387		 * An aggregate or union smaller than one doubleword
388		 * in size is padded so that it appears in the least
389		 * significant bits of the doubleword.  */
390		case ARGTYPE_FLOAT:
391		case ARGTYPE_ARRAY:
392		case ARGTYPE_STRUCT:
393			memmove(buf, buf + width - sz, sz);
394			break;
395		}
396	}
397
398	return 0;
399}
400
401int
402arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
403		    struct process *proc,
404		    struct arg_type_info *info, struct value *valuep)
405{
406	return allocate_argument(ctx, proc, info, valuep);
407}
408
409int
410arch_fetch_retval(struct fetch_context *ctx, enum tof type,
411		  struct process *proc, struct arg_type_info *info,
412		  struct value *valuep)
413{
414	if (ctx->ret_struct) {
415		assert(info->type == ARGTYPE_STRUCT);
416
417		uint64_t addr = read_gpr(ctx, proc, 3);
418		value_init(valuep, proc, NULL, info, 0);
419
420		valuep->where = VAL_LOC_INFERIOR;
421		/* XXX Remove the double cast when arch_addr_t
422		 * becomes integral type. */
423		valuep->u.address = (arch_addr_t)(uintptr_t)addr;
424		return 0;
425	}
426
427	if (fetch_context_init(proc, ctx) < 0)
428		return -1;
429	return allocate_argument(ctx, proc, info, valuep);
430}
431
432void
433arch_fetch_arg_done(struct fetch_context *context)
434{
435	free(context);
436}
437