1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
4 * Copyright (C) 2008,2009 Juan Cespedes
5 * Copyright (C) 2006 Steve Fink
6 * Copyright (C) 2006 Ian Wienand
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24#include <stdlib.h>
25#include <assert.h>
26#include <sys/rse.h>
27#include <ptrace.h>
28#include <string.h>
29#include <errno.h>
30
31#include "backend.h"
32#include "fetch.h"
33#include "type.h"
34#include "proc.h"
35#include "value.h"
36
37struct fetch_context {
38	arch_addr_t stack_pointer;
39	struct pt_all_user_regs regs;
40	enum param_pack_flavor ppflavor;
41
42	/* Return values larger than 256 bits (except HFAs of up to 8
43	 * elements) are returned in a buffer allocated by the
44	 * caller. A pointer to the buffer is passed to the called
45	 * procedure in r8. This register is not guaranteed to be
46	 * preserved by the called procedure.  */
47	unsigned long r8;
48
49	int slot_n;
50	int flt;
51};
52
53union cfm_t {
54	struct {
55		unsigned long sof:7;
56		unsigned long sol:7;
57		unsigned long sor:4;
58		unsigned long rrb_gr:7;
59		unsigned long rrb_fr:7;
60		unsigned long rrb_pr:6;
61	} cfm;
62	unsigned long value;
63};
64
65static int
66fetch_context_init(struct process *proc, struct fetch_context *context)
67{
68	context->slot_n = 0;
69	context->flt = 8;
70	if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->regs) < 0)
71		return -1;
72	context->stack_pointer = (void *)(context->regs.gr[12] + 16);
73	context->ppflavor = PARAM_PACK_ARGS;
74
75	return 0;
76}
77
78struct fetch_context *
79arch_fetch_arg_init(enum tof type, struct process *proc,
80		    struct arg_type_info *ret_info)
81{
82	struct fetch_context *context = malloc(sizeof(*context));
83	if (context == NULL
84	    || fetch_context_init(proc, context) < 0) {
85		free(context);
86		return NULL;
87	}
88	context->r8 = context->regs.gr[8];
89
90	return context;
91}
92
93struct fetch_context *
94arch_fetch_arg_clone(struct process *proc,
95		     struct fetch_context *context)
96{
97	struct fetch_context *clone = malloc(sizeof(*context));
98	if (clone == NULL)
99		return NULL;
100	*clone = *context;
101	return clone;
102}
103
104int
105allocate_stack_slot(struct fetch_context *ctx, struct process *proc,
106		    struct arg_type_info *info, struct value *valuep)
107{
108	size_t al = type_alignof(proc, info);
109	size_t sz = type_sizeof(proc, info);
110	if (al == (size_t)-1 || sz == (size_t)-1)
111		return -1;
112
113	errno = 0;
114	long value = ptrace(PTRACE_PEEKDATA, proc->pid, ctx->stack_pointer, 0);
115	if (value == -1 && errno != 0)
116		return -1;
117	ctx->stack_pointer += 8;
118	value_set_word(valuep, value);
119
120	return 0;
121}
122
123static int
124allocate_reg(struct fetch_context *ctx, struct process *proc,
125	     struct arg_type_info *info, struct value *valuep)
126{
127	if (ctx->slot_n >= 8)
128		return allocate_stack_slot(ctx, proc, info, valuep);
129
130	int reg_num = ctx->slot_n++;
131	if (ctx->slot_n == 8)
132		ctx->flt = 16;
133	if (valuep == NULL)
134		return 0;
135
136	/* This would normally be brought over from asm/ptrace.h, but
137	 * when we do, we get namespace conflicts between asm/fpu.h
138	 * and libunwind.  */
139	enum { PT_AUR_BSP = 17 };
140
141	union cfm_t cfm = { .value = ctx->regs.cfm };
142	unsigned long *bsp = (unsigned long *)ctx->regs.ar[PT_AUR_BSP];
143	unsigned long idx = -cfm.cfm.sof + reg_num;
144	unsigned long *ptr = ia64_rse_skip_regs(bsp, idx);
145	errno = 0;
146	long ret = ptrace(PTRACE_PEEKDATA, proc->pid, ptr, 0);
147	if (ret == -1 && errno != 0)
148		return -1;
149
150	value_set_word(valuep, ret);
151	return 0;
152}
153
154static int
155copy_aggregate_part(struct fetch_context *ctx, struct process *proc,
156		    unsigned char *buf, size_t size)
157{
158	size_t slots = (size + 7) / 8;
159	struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG);
160	while (slots-- > 0) {
161		size_t chunk_sz = size > 8 ? 8 : size;
162		size -= 8;
163
164		struct value tmp;
165		value_init(&tmp, proc, NULL, long_info, 0);
166		int rc = allocate_reg(ctx, proc, long_info, &tmp);
167		if (rc >= 0) {
168			memcpy(buf, value_get_data(&tmp, NULL), chunk_sz);
169			buf += 8;
170		}
171		value_destroy(&tmp);
172		if (rc < 0)
173			return -1;
174	}
175	return 0;
176}
177
178static int
179allocate_arg(struct fetch_context *ctx, struct process *proc,
180	     struct arg_type_info *info, struct value *valuep)
181{
182	size_t sz = type_sizeof(proc, info);
183	size_t align = type_alignof(proc, info);
184	if (sz == (size_t)-1 || align == (size_t)-1)
185		return -1;
186
187	unsigned char *buf = value_reserve(valuep, sz);
188	if (buf == NULL)
189		return -1;
190
191	assert(align == 0 || align == 1 || align == 2 || align == 4
192	       || align == 8 || align == 16);
193
194	/* For aggregates with an external alignment of 16 bytes, the
195	 * Next Even policy is used.  128-bit integers use the Next
196	 * Even policy as well.  */
197	if (align == 16 && ctx->slot_n % 2 != 0)
198		allocate_reg(ctx, proc, info, NULL);
199
200	int rc= copy_aggregate_part(ctx, proc, buf, sz);
201
202	return rc;
203}
204
205/* Stolen from David Mosberger's utrace tool, which he released under
206   the GPL
207   (http://www.gelato.unsw.edu.au/archives/linux-ia64/0104/1405.html) */
208static inline double
209fpreg_to_double (struct ia64_fpreg *fp) {
210	double result;
211	asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp));
212	return result;
213}
214
215static int
216allocate_float(struct fetch_context *ctx, struct process *proc,
217	       struct arg_type_info *info, struct value *valuep,
218	       int take_slot)
219{
220	/* The actual parameter is passed in the next available
221	 * floating-point parameter register, if one is
222	 * available. Floating-point parameter registers are allocated
223	 * as needed from the range f8-f15, starting with f8.  */
224	/* Any register parameters corresponding to a
225	 * variable-argument specification are passed in GRs.  */
226	if (ctx->flt > 15 || ctx->ppflavor == PARAM_PACK_VARARGS)
227		/* If all available floating-point parameter registers
228		 * have been used, the actual parameter is passed in
229		 * the appropriate general register(s).  */
230		return allocate_reg(ctx, proc, info, valuep);
231
232	union {
233		double d;
234		float f;
235		char buf[0];
236	} u = { .d = fpreg_to_double(&ctx->regs.fr[ctx->flt++]) };
237	if (take_slot)
238		allocate_reg(ctx, proc, info, NULL);
239
240	if (info->type == ARGTYPE_FLOAT)
241		u.f = u.d;
242	else
243		assert(info->type == ARGTYPE_DOUBLE);
244
245	if (value_reserve(valuep, sizeof(u)) == NULL)
246		return -1;
247	memmove(value_get_raw_data(valuep), u.buf, sizeof(u));
248
249	return 0;
250}
251
252static int
253allocate_hfa(struct fetch_context *ctx, struct process *proc,
254	     struct arg_type_info *info, struct value *valuep,
255	     enum arg_type hfa_type, size_t hfa_count)
256{
257	size_t sz = type_sizeof(proc, info);
258	if (sz == (size_t)-1)
259		return -1;
260
261	/* If an actual parameter is known to correspond to an HFA
262	 * formal parameter, each element is passed in the next
263	 * available floating-point argument register, until the eight
264	 * argument registers are exhausted. The remaining elements of
265	 * the aggregate are passed in output GRs, according to the
266	 * normal conventions.
267	 *
268	 * Because HFAs are mapped to parameter slots as aggregates,
269	 * single-precision HFAs will be allocated with two
270	 * floating-point values in each parameter slot, but only one
271	 * value per register.
272	 *
273	 * It is possible for the first of two values in a parameter
274	 * slot to occupy the last available floating- point parameter
275	 * register. In this case, the second value is passed in its
276	 * designated GR, but the half of the GR that would have
277	 * contained the first value is undefined.  */
278
279	size_t slot_off = 0;
280
281	unsigned char *buf = value_reserve(valuep, sz);
282	if (buf == NULL)
283		return -1;
284
285	struct arg_type_info *hfa_info = type_get_simple(hfa_type);
286	size_t hfa_sz = type_sizeof(proc, hfa_info);
287
288	/* Pass in register the part that we can.  */
289	while (ctx->flt <= 15 && hfa_count > 0) {
290		struct value tmp;
291		value_init(&tmp, proc, NULL, hfa_info, 0);
292		int rc = allocate_float(ctx, proc, hfa_info, &tmp, 0);
293		if (rc >= 0) {
294			memcpy(buf, value_get_data(&tmp, NULL), hfa_sz);
295			slot_off += hfa_sz;
296			buf += hfa_sz;
297			hfa_count--;
298
299			/* Scratch each fully used slot.  */
300			while (slot_off >= 8) {
301				if (allocate_reg(ctx, proc, info, NULL) < 0)
302					rc = -1;
303				slot_off -= 8;
304			}
305		}
306		value_destroy(&tmp);
307		if (rc < 0)
308			return -1;
309	}
310
311	/* If we have half-slot opened (the case where odd
312	 * ARGTYPE_FLOAT member fits into the last floating point
313	 * register, and the following even member does not), finish
314	 * it first.  */
315	struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG);
316	if (slot_off != 0 && hfa_count > 0) {
317		struct value tmp;
318		value_init(&tmp, proc, NULL, long_info, 0);
319		int rc = allocate_reg(ctx, proc, long_info, &tmp);
320		if (rc >= 0) {
321			unsigned char *data = value_get_data(&tmp, NULL);
322			memcpy(buf, data, 8 - slot_off);
323			buf += 8 - slot_off;
324			hfa_count--;
325		}
326		value_destroy(&tmp);
327		if (rc < 0) {
328			return -1;
329		}
330	}
331
332	/* The rest is passed in registers and on stack.  */
333	size_t rest = hfa_count * hfa_sz;
334	return copy_aggregate_part(ctx, proc, buf, rest);
335}
336
337static int
338allocate_ret(struct fetch_context *ctx, struct process *proc,
339	     struct arg_type_info *info, struct value *valuep)
340{
341	size_t sz = type_sizeof(proc, info);
342	if (sz == (size_t)-1)
343		return -1;
344
345	/* Homogeneous floating-point aggregates [...] are returned in
346	 * floating-point registers, provided the array or structure
347	 * contains no more than eight individual values.  The
348	 * elements of the aggregate are placed in successive
349	 * floating-point registers, beginning with f8.  */
350	if (info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY) {
351		size_t hfa_size;
352		struct arg_type_info *hfa_info
353			= type_get_hfa_type(info, &hfa_size);
354		if (hfa_info != NULL && hfa_size <= 8)
355			return allocate_hfa(ctx, proc, info, valuep,
356					    hfa_info->type, hfa_size);
357	}
358
359	/* Integers and pointers are passed in r8.  128-bit integers
360	 * are passed in r8 and r9.  Aggregates of up to 256 bits [32
361	 * bytes] are passed in registers r8...r11.  */
362	if (sz <= 32) {
363		unsigned char *buf = value_reserve(valuep, sz);
364		if (buf == NULL)
365			return -1;
366		memcpy(buf, ctx->regs.gr + 8, sz);
367		return 0;
368	}
369
370	if (value_pass_by_reference(valuep) < 0)
371		return -1;
372	value_set_word(valuep, ctx->r8);
373	return 0;
374}
375
376int
377arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
378		    struct process *proc,
379		    struct arg_type_info *info, struct value *valuep)
380{
381	switch (info->type) {
382		struct arg_type_info *hfa_info;
383		size_t hfa_size;
384
385	case ARGTYPE_VOID:
386		value_set_word(valuep, 0);
387		return 0;
388
389	case ARGTYPE_FLOAT:
390	case ARGTYPE_DOUBLE:
391		return allocate_float(ctx, proc, info, valuep, 1);
392
393	case ARGTYPE_STRUCT:
394		hfa_info = type_get_hfa_type(info, &hfa_size);
395		if (hfa_info != NULL)
396			return allocate_hfa(ctx, proc, info, valuep,
397					    hfa_info->type, hfa_size);
398		/* Fall through.  */
399	case ARGTYPE_CHAR:
400	case ARGTYPE_SHORT:
401	case ARGTYPE_USHORT:
402	case ARGTYPE_INT:
403	case ARGTYPE_UINT:
404	case ARGTYPE_LONG:
405	case ARGTYPE_ULONG:
406	case ARGTYPE_POINTER:
407		return allocate_arg(ctx, proc, info, valuep);
408
409	case ARGTYPE_ARRAY:
410		/* Arrays decay into pointers.  XXX Fortran?  */
411	default:
412		assert(info->type != info->type);
413		abort();
414	}
415}
416
417int
418arch_fetch_retval(struct fetch_context *ctx, enum tof type,
419		  struct process *proc, struct arg_type_info *info,
420		  struct value *valuep)
421{
422	if (fetch_context_init(proc, ctx) < 0)
423		return -1;
424
425	switch (info->type) {
426	case ARGTYPE_VOID:
427	case ARGTYPE_FLOAT:
428	case ARGTYPE_DOUBLE:
429		/* The rules for returning those types are the same as
430		 * for passing them in arguments.  */
431		return arch_fetch_arg_next(ctx, type, proc, info, valuep);
432
433	case ARGTYPE_CHAR:
434	case ARGTYPE_SHORT:
435	case ARGTYPE_USHORT:
436	case ARGTYPE_INT:
437	case ARGTYPE_UINT:
438	case ARGTYPE_LONG:
439	case ARGTYPE_ULONG:
440	case ARGTYPE_POINTER:
441	case ARGTYPE_STRUCT:
442		return allocate_ret(ctx, proc, info, valuep);
443
444	case ARGTYPE_ARRAY:
445		/* Arrays decay into pointers.  XXX Fortran?  */
446		assert(info->type != ARGTYPE_ARRAY);
447		abort();
448	}
449	assert("unhandled type");
450	abort();
451	return arch_fetch_arg_next(ctx, type, proc, info, valuep);
452}
453
454void
455arch_fetch_arg_done(struct fetch_context *context)
456{
457	free(context);
458}
459
460int
461arch_fetch_param_pack_start(struct fetch_context *context,
462			    enum param_pack_flavor ppflavor)
463{
464	context->ppflavor = ppflavor;
465	return 0;
466}
467
468void
469arch_fetch_param_pack_end(struct fetch_context *context)
470{
471	context->ppflavor = PARAM_PACK_ARGS;
472}
473