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 
34 static 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.  */
44 struct fpregs_t
45 {
46 	double fpregs[32];
47 	double fpscr;
48 	unsigned int _pad[2];
49 };
50 
51 typedef uint32_t gregs32_t[48];
52 typedef uint64_t gregs64_t[48];
53 
54 struct 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 
68 static int
fetch_context_init(struct process * proc,struct fetch_context * context)69 fetch_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 
110 struct fetch_context *
arch_fetch_arg_init(enum tof type,struct process * proc,struct arg_type_info * ret_info)111 arch_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 
134 struct fetch_context *
arch_fetch_arg_clone(struct process * proc,struct fetch_context * context)135 arch_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 
145 static int
allocate_stack_slot(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)146 allocate_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 
172 static uint64_t
read_gpr(struct fetch_context * ctx,struct process * proc,int reg_num)173 read_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.  */
186 static void
align_small_int(unsigned char * buf,size_t w,size_t sz)187 align_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 
217 static int
allocate_gpr(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)218 allocate_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 
247 static int
allocate_float(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)248 allocate_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 
278 static int
allocate_argument(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)279 allocate_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 
401 int
arch_fetch_arg_next(struct fetch_context * ctx,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)402 arch_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 
409 int
arch_fetch_retval(struct fetch_context * ctx,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)410 arch_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 
432 void
arch_fetch_arg_done(struct fetch_context * context)433 arch_fetch_arg_done(struct fetch_context *context)
434 {
435 	free(context);
436 }
437