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
37 struct 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
53 union 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
65 static int
fetch_context_init(struct process * proc,struct fetch_context * context)66 fetch_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
78 struct fetch_context *
arch_fetch_arg_init(enum tof type,struct process * proc,struct arg_type_info * ret_info)79 arch_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
93 struct fetch_context *
arch_fetch_arg_clone(struct process * proc,struct fetch_context * context)94 arch_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
104 int
allocate_stack_slot(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)105 allocate_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
123 static int
allocate_reg(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)124 allocate_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
154 static int
copy_aggregate_part(struct fetch_context * ctx,struct process * proc,unsigned char * buf,size_t size)155 copy_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
178 static int
allocate_arg(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)179 allocate_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) */
208 static inline double
fpreg_to_double(struct ia64_fpreg * fp)209 fpreg_to_double (struct ia64_fpreg *fp) {
210 double result;
211 asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp));
212 return result;
213 }
214
215 static int
allocate_float(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep,int take_slot)216 allocate_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
252 static int
allocate_hfa(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep,enum arg_type hfa_type,size_t hfa_count)253 allocate_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
337 static int
allocate_ret(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep)338 allocate_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
376 int
arch_fetch_arg_next(struct fetch_context * ctx,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)377 arch_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
417 int
arch_fetch_retval(struct fetch_context * ctx,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)418 arch_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
454 void
arch_fetch_arg_done(struct fetch_context * context)455 arch_fetch_arg_done(struct fetch_context *context)
456 {
457 free(context);
458 }
459
460 int
arch_fetch_param_pack_start(struct fetch_context * context,enum param_pack_flavor ppflavor)461 arch_fetch_param_pack_start(struct fetch_context *context,
462 enum param_pack_flavor ppflavor)
463 {
464 context->ppflavor = ppflavor;
465 return 0;
466 }
467
468 void
arch_fetch_param_pack_end(struct fetch_context * context)469 arch_fetch_param_pack_end(struct fetch_context *context)
470 {
471 context->ppflavor = PARAM_PACK_ARGS;
472 }
473