2 * This file is part of ltrace.
3 * Copyright (C) 2012 Petr Machata, Red Hat Inc.
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.
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.
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
25 #include <sys/ucontext.h>
33 #include "ltrace-elf.h"
35 static int allocate_gpr(struct fetch_context *ctx, struct process *proc,
36 struct arg_type_info *info, struct value *valuep,
37 size_t off, bool is_hfa_type);
39 /* Floating point registers have the same width on 32-bit as well as
40 * 64-bit PPC, but <ucontext.h> presents a different API depending on
41 * whether ltrace is PPC32 or PPC64.
43 * This is PPC64 definition. The PPC32 is simply an array of 33
44 * doubles, and doesn't contain the terminating pad. Both seem
45 * compatible enough. */
53 typedef uint32_t gregs32_t[48];
54 typedef uint64_t gregs64_t[48];
56 struct fetch_context {
57 arch_addr_t stack_pointer;
66 struct fpregs_t fpregs;
74 fetch_context_init(struct process *proc, struct fetch_context *context)
79 if (proc->e_machine == EM_PPC)
80 context->stack_pointer = proc->stack_pointer + 8;
82 context->stack_pointer = proc->stack_pointer
83 + STACK_FRAME_OVERHEAD;
85 /* When ltrace is 64-bit, we might use PTRACE_GETREGS to
86 * obtain 64-bit as well as 32-bit registers. But if we do it
87 * this way, 32-bit ltrace can obtain 64-bit registers.
89 * XXX this direction is not supported as of this writing, but
90 * should be eventually. */
91 if (proc->e_machine == EM_PPC64) {
92 if (ptrace(PTRACE_GETREGS64, proc->pid, 0,
93 &context->regs.r64) < 0)
97 if (ptrace(PTRACE_GETREGS, proc->pid, 0,
98 &context->regs.r64) < 0)
101 for (i = 0; i < sizeof(context->regs.r64)/8; ++i)
102 context->regs.r32[i] = context->regs.r64[i];
104 if (ptrace(PTRACE_GETREGS, proc->pid, 0,
105 &context->regs.r32) < 0)
110 if (ptrace(PTRACE_GETFPREGS, proc->pid, 0, &context->fpregs) < 0)
116 struct fetch_context *
117 arch_fetch_arg_init(enum tof type, struct process *proc,
118 struct arg_type_info *ret_info)
120 struct fetch_context *context = malloc(sizeof(*context));
122 || fetch_context_init(proc, context) < 0) {
127 context->vgreg = context->greg;
128 context->struct_size = 0;
129 context->struct_hfa_size = 0;
130 context->struct_hfa_count = 0;
132 /* Aggregates or unions of any length, and character strings
133 * of length longer than 8 bytes, will be returned in a
134 * storage buffer allocated by the caller. The caller will
135 * pass the address of this buffer as a hidden first argument
136 * in r3, causing the first explicit argument to be passed in
138 context->ret_struct = ret_info->type == ARGTYPE_STRUCT;
139 if (context->ret_struct) {
141 /* if R3 points to stack, parameters will be in R4. */
142 uint64_t pstack_end = ptrace(PTRACE_PEEKTEXT, proc->pid,
143 proc->stack_pointer, 0);
144 if (((arch_addr_t)context->regs.r64[3] > proc->stack_pointer)
145 && (context->regs.r64[3] < pstack_end)) {
147 context->stack_pointer += 8;
157 struct fetch_context *
158 arch_fetch_arg_clone(struct process *proc,
159 struct fetch_context *context)
161 struct fetch_context *clone = malloc(sizeof(*context));
169 allocate_stack_slot(struct fetch_context *ctx, struct process *proc,
170 struct arg_type_info *info, struct value *valuep,
173 size_t sz = type_sizeof(proc, info);
174 if (sz == (size_t)-1)
177 size_t a = type_alignof(proc, info);
179 if (proc->e_machine == EM_PPC && a < 4)
182 else if (proc->e_machine == EM_PPC64 && sz == 4 && is_hfa_type)
187 else if (proc->e_machine == EM_PPC64 && a < 8)
191 /* XXX Remove the two double casts when arch_addr_t
192 * becomes integral type. */
193 uintptr_t tmp = align((uint64_t)(uintptr_t)ctx->stack_pointer, a);
194 ctx->stack_pointer = (arch_addr_t)tmp;
197 value_in_inferior(valuep, ctx->stack_pointer + off);
198 ctx->stack_pointer += a;
204 read_gpr(struct fetch_context *ctx, struct process *proc, int reg_num)
206 if (proc->e_machine == EM_PPC)
207 return ctx->regs.r32[reg_num];
209 return ctx->regs.r64[reg_num];
212 /* The support for little endian PowerPC is in upstream Linux and BFD,
213 * and Unix-like Solaris, which we might well support at some point,
214 * runs PowerPC in little endian as well. This code moves SZ-sized
215 * value to the beginning of W-sized BUF regardless of
218 align_small_int(unsigned char *buf, size_t w, size_t sz)
220 assert(w == 4 || w == 8);
228 memcpy(u.buf, buf, w);
245 memcpy(buf, u.buf, sz);
249 allocate_gpr(struct fetch_context *ctx, struct process *proc,
250 struct arg_type_info *info, struct value *valuep,
251 size_t off, bool is_hfa_type)
254 return allocate_stack_slot(ctx, proc, info, valuep, is_hfa_type);
256 int reg_num = ctx->greg;
258 size_t sz = type_sizeof(proc, info);
259 if (sz == (size_t)-1)
261 assert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
263 /* Consume the stack slot corresponding to this arg. */
268 ctx->stack_pointer += sz;
270 ctx->stack_pointer += 8;
278 if (value_reserve(valuep, sz) == NULL)
283 unsigned char buf[0];
286 u.i64 = read_gpr(ctx, proc, reg_num);
287 if (proc->e_machine == EM_PPC)
288 align_small_int(u.buf, 8, sz);
289 memcpy(value_get_raw_data(valuep), u.buf + off, sz);
294 allocate_float(struct fetch_context *ctx, struct process *proc,
295 struct arg_type_info *info, struct value *valuep,
296 size_t off, bool is_hfa_type)
298 int pool = proc->e_machine == EM_PPC64 ? 13 : 8;
299 if (ctx->freg <= pool) {
304 } u = { .d = ctx->fpregs.fpregs[ctx->freg] };
311 if (proc->e_machine == EM_PPC64)
312 allocate_gpr(ctx, proc, info, NULL, off, is_hfa_type);
314 size_t sz = sizeof(double);
315 if (info->type == ARGTYPE_FLOAT) {
320 if (value_reserve(valuep, sz) == NULL)
323 memcpy(value_get_raw_data(valuep), u.buf, sz);
326 return allocate_stack_slot(ctx, proc, info, valuep, is_hfa_type);
331 allocate_hfa(struct fetch_context *ctx, struct process *proc,
332 struct arg_type_info *info, struct value *valuep,
333 enum arg_type hfa_type, size_t hfa_count)
335 size_t sz = type_sizeof(proc, info);
336 if (sz == (size_t)-1)
339 ctx->struct_hfa_size += sz;
341 /* There are two changes regarding structure return types:
342 * * heterogeneous float/vector structs are returned
343 * in (multiple) FP/vector registers,
344 * instead of via implicit reference.
345 * * small structs (up to 16 bytes) are return
346 * in one or two GPRs, instead of via implicit reference.
348 * Other structures (larger than 16 bytes, not heterogeneous)
349 * are still returned via implicit reference (i.e. a pointer
350 * to memory where to return the struct being passed in r3).
351 * Of course, whether or not an implicit reference pointer
352 * is present will shift the remaining arguments,
353 * so you need to get this right for ELFv2 in order
354 * to get the arguments correct.
355 * If an actual parameter is known to correspond to an HFA
356 * formal parameter, each element is passed in the next
357 * available floating-point argument register starting at fp1
358 * until the fp13. The remaining elements of the aggregate are
359 * passed on the stack. */
362 unsigned char *buf = value_reserve(valuep, sz);
366 struct arg_type_info *hfa_info = type_get_simple(hfa_type);
367 size_t hfa_sz = type_sizeof(proc, hfa_info);
370 ctx->struct_hfa_count += hfa_count;
372 while (hfa_count > 0 && ctx->freg <= 13) {
376 value_init(&tmp, proc, NULL, hfa_info, 0);
378 /* Hetereogeneous struct - get value on GPR or stack. */
379 if (((hfa_type == ARGTYPE_FLOAT
380 || hfa_type == ARGTYPE_DOUBLE)
382 rc = allocate_float(ctx, proc, hfa_info, &tmp,
385 rc = allocate_gpr(ctx, proc, hfa_info, &tmp,
388 memcpy(buf, value_get_data(&tmp, NULL), hfa_sz);
405 /* if no remaining FP, GPR corresponding to slot is used
406 * Mostly it is in part of r10. */
407 if (ctx->struct_hfa_size <= 64 && ctx->vgreg == 10) {
408 while (ctx->vgreg <= 10) {
410 value_init(&tmp, proc, NULL, hfa_info, 0);
413 unsigned char buf[0];
416 u.i64 = read_gpr(ctx, proc, ctx->vgreg);
418 memcpy(buf, u.buf + slot_off, hfa_sz);
422 ctx->stack_pointer += hfa_sz;
423 if (slot_off >= 8 ) {
434 /* Remaining values are on stack */
437 value_init(&tmp, proc, NULL, hfa_info, 0);
439 value_in_inferior(&tmp, ctx->stack_pointer);
440 memcpy(buf, value_get_data(&tmp, NULL), hfa_sz);
441 ctx->stack_pointer += hfa_sz;
450 allocate_argument(struct fetch_context *ctx, struct process *proc,
451 struct arg_type_info *info, struct value *valuep)
453 /* Floating point types and void are handled specially. */
454 switch (info->type) {
456 value_set_word(valuep, 0);
461 return allocate_float(ctx, proc, info, valuep,
462 8 - type_sizeof(proc,info), false);
465 if (proc->e_machine == EM_PPC) {
466 if (value_pass_by_reference(valuep) < 0)
470 struct arg_type_info *hfa_info;
472 hfa_info = type_get_hfa_type(info, &hfa_size);
473 if (hfa_info != NULL ) {
474 size_t sz = type_sizeof(proc, info);
475 ctx->struct_size += sz;
476 return allocate_hfa(ctx, proc, info, valuep,
477 hfa_info->type, hfa_size);
480 /* PPC64: Fixed size aggregates and unions passed by
481 * value are mapped to as many doublewords of the
482 * parameter save area as the value uses in memory.
483 * [...] The first eight doublewords mapped to the
484 * parameter save area correspond to the registers r3
495 case ARGTYPE_POINTER:
499 /* Arrays decay into pointers. XXX Fortran? */
501 assert(info->type != info->type);
505 unsigned width = proc->e_machine == EM_PPC64 ? 8 : 4;
507 /* For other cases (integral types and aggregates), read the
508 * eightbytes comprising the data. */
509 size_t sz = type_sizeof(proc, valuep->type);
510 if (sz == (size_t)-1)
514 ctx->struct_size += sz;
516 size_t slots = (sz + width - 1) / width; /* Round up. */
517 unsigned char *buf = value_reserve(valuep, slots * width);
520 struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG);
522 unsigned char *ptr = buf;
523 while (slots-- > 0) {
525 value_init(&val, proc, NULL, long_info, 0);
527 /* Floating point registers [...] are used [...] to
528 pass [...] one member aggregates passed by value
529 containing a floating point value[.] Note that for
530 one member aggregates, "containing" extends to
531 aggregates within aggregates ad infinitum. */
533 struct arg_type_info *fp_info
534 = type_get_fp_equivalent(valuep->type);
536 rc = allocate_float(ctx, proc, fp_info, &val,
537 8-type_sizeof(proc,info), false);
539 rc = allocate_gpr(ctx, proc, long_info, &val,
543 memcpy(ptr, value_get_data(&val, NULL), width);
548 /* Bail out if we failed or if we are dealing with
549 * FP-equivalent. Those don't need the adjustments
551 if (rc < 0 || fp_info != NULL)
555 #ifndef __LITTLE_ENDIAN__
556 /* Small values need post-processing. */
558 switch (info->type) {
562 /* Simple integer types (char, short, int, long, enum)
563 * are mapped to a single doubleword. Values shorter
564 * than a doubleword are sign or zero extended as
571 align_small_int(buf, width, sz);
574 /* Single precision floating point values are mapped
575 * to the second word in a single doubleword.
577 * An aggregate or union smaller than one doubleword
578 * in size is padded so that it appears in the least
579 * significant bits of the doubleword. */
583 memmove(buf, buf + width - sz, sz);
593 arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
594 struct process *proc,
595 struct arg_type_info *info, struct value *valuep)
597 return allocate_argument(ctx, proc, info, valuep);
601 arch_fetch_retval(struct fetch_context *ctx, enum tof type,
602 struct process *proc, struct arg_type_info *info,
603 struct value *valuep)
605 if (fetch_context_init(proc, ctx) < 0)
609 void *ptr = (void *)(ctx->regs.r64[1]+32);
610 uint64_t val = ptrace(PTRACE_PEEKTEXT, proc->pid, ptr, 0);
613 && ((ctx->struct_size > 64
614 || ctx->struct_hfa_count > 8
615 || (ctx->struct_hfa_size == 0 && ctx->struct_size > 56)
616 || (ctx->regs.r64[3] == ctx->regs.r64[1]+32)
617 || (ctx->regs.r64[3] == val )))) {
619 if (ctx->ret_struct) {
621 assert(info->type == ARGTYPE_STRUCT);
623 uint64_t addr = read_gpr(ctx, proc, 3);
624 value_init(valuep, proc, NULL, info, 0);
626 valuep->where = VAL_LOC_INFERIOR;
627 /* XXX Remove the double cast when arch_addr_t
628 * becomes integral type. */
629 valuep->u.address = (arch_addr_t)(uintptr_t)addr;
633 return allocate_argument(ctx, proc, info, valuep);
637 arch_fetch_arg_done(struct fetch_context *context)