154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata/* 254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This file is part of ltrace. 354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * Copyright (C) 2012 Petr Machata, Red Hat Inc. 454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This program is free software; you can redistribute it and/or 654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * modify it under the terms of the GNU General Public License as 754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * published by the Free Software Foundation; either version 2 of the 854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * License, or (at your option) any later version. 954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 1054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This program is distributed in the hope that it will be useful, but 1154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 1254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * General Public License for more details. 1454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 1554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * You should have received a copy of the GNU General Public License 1654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * along with this program; if not, write to the Free Software 1754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 1854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 02110-1301 USA 1954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata */ 2054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 2154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <assert.h> 2254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <stdint.h> 2354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <stdlib.h> 2454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include <string.h> 25b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#include <sys/ucontext.h> 2654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 2754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "backend.h" 2854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "fetch.h" 2954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "type.h" 3003f4b61154d2bfb87530bdc79f548c6374ba0db7Petr Machata#include "ptrace.h" 3154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "proc.h" 3254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata#include "value.h" 3354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 34929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatastatic int allocate_gpr(struct fetch_context *ctx, struct process *proc, 3554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct arg_type_info *info, struct value *valuep); 3654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 3754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata/* Floating point registers have the same width on 32-bit as well as 3854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 64-bit PPC, but <ucontext.h> presents a different API depending on 3954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * whether ltrace is PPC32 or PPC64. 4054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 4154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * This is PPC64 definition. The PPC32 is simply an array of 33 4254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * doubles, and doesn't contain the terminating pad. Both seem 4354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * compatible enough. */ 4454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fpregs_t 4554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 4654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata double fpregs[32]; 4754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata double fpscr; 4854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata unsigned int _pad[2]; 4954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}; 5054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 5154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatatypedef uint32_t gregs32_t[48]; 5254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatatypedef uint64_t gregs64_t[48]; 5354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 5454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fetch_context { 55bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t stack_pointer; 5654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata int greg; 5754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata int freg; 5854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata int ret_struct; 5954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 6054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata union { 6154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata gregs32_t r32; 6254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata gregs64_t r64; 6354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } regs; 6454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct fpregs_t fpregs; 6554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 6654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata}; 6754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 6854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int 69929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_context_init(struct process *proc, struct fetch_context *context) 7054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 7154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata context->greg = 3; 7254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata context->freg = 1; 7354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 747d1e7926b92403ce03d1c2002c80937b280fa415Petr Machata if (proc->e_machine == EM_PPC) 7554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata context->stack_pointer = proc->stack_pointer + 8; 7654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata else 7754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata context->stack_pointer = proc->stack_pointer + 112; 7854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 7954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata /* When ltrace is 64-bit, we might use PTRACE_GETREGS to 8054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * obtain 64-bit as well as 32-bit registers. But if we do it 8154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * this way, 32-bit ltrace can obtain 64-bit registers. 8254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * 8354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * XXX this direction is not supported as of this writing, but 8454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * should be eventually. */ 8554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (proc->e_machine == EM_PPC64) { 8654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (ptrace(PTRACE_GETREGS64, proc->pid, 0, 8754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata &context->regs.r64) < 0) 8854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return -1; 89b52f89c1302256bae003edc44c6e3788833629f1Petr Machata } else { 90b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#ifdef __powerpc64__ 91b52f89c1302256bae003edc44c6e3788833629f1Petr Machata if (ptrace(PTRACE_GETREGS, proc->pid, 0, 92b52f89c1302256bae003edc44c6e3788833629f1Petr Machata &context->regs.r64) < 0) 93b52f89c1302256bae003edc44c6e3788833629f1Petr Machata return -1; 94b52f89c1302256bae003edc44c6e3788833629f1Petr Machata unsigned i; 95b52f89c1302256bae003edc44c6e3788833629f1Petr Machata for (i = 0; i < sizeof(context->regs.r64)/8; ++i) 96b52f89c1302256bae003edc44c6e3788833629f1Petr Machata context->regs.r32[i] = context->regs.r64[i]; 97b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#else 98b52f89c1302256bae003edc44c6e3788833629f1Petr Machata if (ptrace(PTRACE_GETREGS, proc->pid, 0, 99b52f89c1302256bae003edc44c6e3788833629f1Petr Machata &context->regs.r32) < 0) 100b52f89c1302256bae003edc44c6e3788833629f1Petr Machata return -1; 101b52f89c1302256bae003edc44c6e3788833629f1Petr Machata#endif 10254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } 10354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 10454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (ptrace(PTRACE_GETFPREGS, proc->pid, 0, &context->fpregs) < 0) 10554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return -1; 10654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 10754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return 0; 10854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 10954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 11054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fetch_context * 111929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_init(enum tof type, struct process *proc, 11254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct arg_type_info *ret_info) 11354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 11454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct fetch_context *context = malloc(sizeof(*context)); 11554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (context == NULL 11654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata || fetch_context_init(proc, context) < 0) { 11754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata free(context); 11854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return NULL; 11954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } 12054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 12154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata /* Aggregates or unions of any length, and character strings 12254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * of length longer than 8 bytes, will be returned in a 12354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * storage buffer allocated by the caller. The caller will 12454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * pass the address of this buffer as a hidden first argument 12554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * in r3, causing the first explicit argument to be passed in 12654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata * r4. */ 12754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata context->ret_struct = ret_info->type == ARGTYPE_STRUCT; 12854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (context->ret_struct) 12954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata context->greg++; 13054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 13154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return context; 13254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 13354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 13454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastruct fetch_context * 135929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_fetch_arg_clone(struct process *proc, 13654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct fetch_context *context) 13754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 13854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct fetch_context *clone = malloc(sizeof(*context)); 13954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (clone == NULL) 14054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return NULL; 14154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata *clone = *context; 14254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return clone; 14354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 14454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 14554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int 146929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_stack_slot(struct fetch_context *ctx, struct process *proc, 14754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct arg_type_info *info, struct value *valuep) 14854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 149f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata size_t sz = type_sizeof(proc, info); 150f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata if (sz == (size_t)-1) 151f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata return -1; 152f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata 153d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata size_t a = type_alignof(proc, info); 154d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata size_t off = 0; 155f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata if (proc->e_machine == EM_PPC && a < 4) 156f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata a = 4; 157f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata else if (proc->e_machine == EM_PPC64 && a < 8) 158f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata a = 8; 159f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata 160bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata /* XXX Remove the two double casts when arch_addr_t 16136718b01e510ff3973e14b2bad0dbad3177b9943Petr Machata * becomes integral type. */ 16236718b01e510ff3973e14b2bad0dbad3177b9943Petr Machata uintptr_t tmp = align((uint64_t)(uintptr_t)ctx->stack_pointer, a); 163bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata ctx->stack_pointer = (arch_addr_t)tmp; 164f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata 1650ffa9f3f82febbcd475318ac282c456adb76c73cPetr Machata if (valuep != NULL) 1660ffa9f3f82febbcd475318ac282c456adb76c73cPetr Machata value_in_inferior(valuep, ctx->stack_pointer + off); 167f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata ctx->stack_pointer += sz; 168f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata 169f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata return 0; 17054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 17154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 172d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machatastatic uint64_t 173929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataread_gpr(struct fetch_context *ctx, struct process *proc, int reg_num) 174d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata{ 175d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata if (proc->e_machine == EM_PPC) 176d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return ctx->regs.r32[reg_num]; 177d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata else 178d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return ctx->regs.r64[reg_num]; 179d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata} 180d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 1812d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata/* The support for little endian PowerPC is in upstream Linux and BFD, 1822d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * and Unix-like Solaris, which we might well support at some point, 1832d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * runs PowerPC in little endian as well. This code moves SZ-sized 1842d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * value to the beginning of W-sized BUF regardless of 1852d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata * endian. */ 1862d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machatastatic void 1872d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machataalign_small_int(unsigned char *buf, size_t w, size_t sz) 1882d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata{ 1892d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata assert(w == 4 || w == 8); 1902d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata union { 1912d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata uint64_t i64; 1922d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata uint32_t i32; 1932d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata uint16_t i16; 1942d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata uint8_t i8; 1952d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata char buf[0]; 1962d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata } u; 1972d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata memcpy(u.buf, buf, w); 1982d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata if (w == 4) 1992d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata u.i64 = u.i32; 2002d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata 2012d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata switch (sz) { 2022d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata case 1: 2032d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata u.i8 = u.i64; 2042d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata break; 2052d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata case 2: 2062d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata u.i16 = u.i64; 2072d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata break; 2082d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata case 4: 2092d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata u.i32 = u.i64; 2102d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata case 8: 2112d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata break; 2122d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata } 2132d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata 2142d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata memcpy(buf, u.buf, sz); 2152d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata} 216b52f89c1302256bae003edc44c6e3788833629f1Petr Machata 217d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machatastatic int 218929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_gpr(struct fetch_context *ctx, struct process *proc, 219d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata struct arg_type_info *info, struct value *valuep) 220d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata{ 221d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata if (ctx->greg > 10) 222d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return allocate_stack_slot(ctx, proc, info, valuep); 223d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 224d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata int reg_num = ctx->greg++; 225d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata if (valuep == NULL) 226d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return 0; 227d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 228d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata size_t sz = type_sizeof(proc, info); 229d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata if (sz == (size_t)-1) 230d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return -1; 231d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata assert(sz == 1 || sz == 2 || sz == 4 || sz == 8); 232d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata if (value_reserve(valuep, sz) == NULL) 233d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return -1; 234d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 235d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata union { 236d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata uint64_t i64; 237b52f89c1302256bae003edc44c6e3788833629f1Petr Machata unsigned char buf[0]; 238d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata } u; 239d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 240d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata u.i64 = read_gpr(ctx, proc, reg_num); 241b52f89c1302256bae003edc44c6e3788833629f1Petr Machata if (proc->e_machine == EM_PPC) 2422d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata align_small_int(u.buf, 8, sz); 243d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata memcpy(value_get_raw_data(valuep), u.buf, sz); 244d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return 0; 245d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata} 246d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 24754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int 248929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_float(struct fetch_context *ctx, struct process *proc, 24954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct arg_type_info *info, struct value *valuep) 25054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 251b52f89c1302256bae003edc44c6e3788833629f1Petr Machata int pool = proc->e_machine == EM_PPC64 ? 13 : 8; 25254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (ctx->freg <= pool) { 25354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata union { 25454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata double d; 25554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata float f; 25654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata char buf[0]; 25754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } u = { .d = ctx->fpregs.fpregs[ctx->freg] }; 25854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 25954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata ctx->freg++; 260dbcb32a5ab5a1c9e2d8cb70b07320db1ae8c234bPetr Machata if (proc->e_machine == EM_PPC64) 261dbcb32a5ab5a1c9e2d8cb70b07320db1ae8c234bPetr Machata allocate_gpr(ctx, proc, info, NULL); 26254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 26354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata size_t sz = sizeof(double); 26454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (info->type == ARGTYPE_FLOAT) { 26554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata sz = sizeof(float); 26654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata u.f = (float)u.d; 26754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } 26854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 26954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (value_reserve(valuep, sz) == NULL) 27054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return -1; 27154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 27254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata memcpy(value_get_raw_data(valuep), u.buf, sz); 27354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return 0; 27454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } 27554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return allocate_stack_slot(ctx, proc, info, valuep); 27654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 27754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 27854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatastatic int 279929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataallocate_argument(struct fetch_context *ctx, struct process *proc, 280d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata struct arg_type_info *info, struct value *valuep) 281f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata{ 282d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* Floating point types and void are handled specially. */ 283d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata switch (info->type) { 284d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_VOID: 285d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata value_set_word(valuep, 0); 286d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return 0; 287d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 288d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_FLOAT: 289d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_DOUBLE: 290d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return allocate_float(ctx, proc, info, valuep); 291d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 292d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_STRUCT: 293d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata if (proc->e_machine == EM_PPC) { 294d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata if (value_pass_by_reference(valuep) < 0) 295d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return -1; 296d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata } else { 297d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* PPC64: Fixed size aggregates and unions passed by 298d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * value are mapped to as many doublewords of the 299d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * parameter save area as the value uses in memory. 300d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * [...] The first eight doublewords mapped to the 301d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * parameter save area correspond to the registers r3 302d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * through r10. */ 303d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata } 304d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* fall through */ 305d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_CHAR: 306d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_SHORT: 307d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_USHORT: 308d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_INT: 309d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_UINT: 310d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_LONG: 311d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_ULONG: 312d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_POINTER: 313d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata break; 314d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 315d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_ARRAY: 316d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* Arrays decay into pointers. XXX Fortran? */ 3175b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias default: 3185b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias assert(info->type != info->type); 319d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata abort(); 320d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata } 321d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 322b52f89c1302256bae003edc44c6e3788833629f1Petr Machata unsigned width = proc->e_machine == EM_PPC64 ? 8 : 4; 323b52f89c1302256bae003edc44c6e3788833629f1Petr Machata 324d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* For other cases (integral types and aggregates), read the 325d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * eightbytes comprising the data. */ 32695792af484c635071ed96107d34a3762c4ca2ef2Petr Machata size_t sz = type_sizeof(proc, valuep->type); 327f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata if (sz == (size_t)-1) 328f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata return -1; 329b52f89c1302256bae003edc44c6e3788833629f1Petr Machata size_t slots = (sz + width - 1) / width; /* Round up. */ 330b52f89c1302256bae003edc44c6e3788833629f1Petr Machata unsigned char *buf = value_reserve(valuep, slots * width); 331f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata if (buf == NULL) 332f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata return -1; 333d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG); 334f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata 335d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata unsigned char *ptr = buf; 336b52f89c1302256bae003edc44c6e3788833629f1Petr Machata while (slots-- > 0) { 337f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata struct value val; 338d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata value_init(&val, proc, NULL, long_info, 0); 339fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata 340fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata /* Floating point registers [...] are used [...] to 341fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata pass [...] one member aggregates passed by value 342fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata containing a floating point value[.] Note that for 343fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata one member aggregates, "containing" extends to 344fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata aggregates within aggregates ad infinitum. */ 345fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata int rc; 346fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata struct arg_type_info *fp_info 347fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata = type_get_fp_equivalent(valuep->type); 348fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata if (fp_info != NULL) 349fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata rc = allocate_float(ctx, proc, fp_info, &val); 350fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata else 351fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata rc = allocate_gpr(ctx, proc, long_info, &val); 352fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata 353f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata if (rc >= 0) { 354b52f89c1302256bae003edc44c6e3788833629f1Petr Machata memcpy(ptr, value_get_data(&val, NULL), width); 355b52f89c1302256bae003edc44c6e3788833629f1Petr Machata ptr += width; 356f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata } 357f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata value_destroy(&val); 358fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata 359fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata /* Bail out if we failed or if we are dealing with 360fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata * FP-equivalent. Those don't need the adjustments 361fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata * made below. */ 362fcf256ceeab4b0b74cf1e18122e894aafce94fdcPetr Machata if (rc < 0 || fp_info != NULL) 363f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata return rc; 364f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata } 365f7537b62af3507de87d6fa645ef20fe61e3f3c09Petr Machata 366d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* Small values need post-processing. */ 367ebd9191418bd73796533d6e21a2536906459ec1fPetr Machata if (sz < width) { 368d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata switch (info->type) { 3695b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias default: 370d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata abort(); 371d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 372d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* Simple integer types (char, short, int, long, enum) 373d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * are mapped to a single doubleword. Values shorter 374d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * than a doubleword are sign or zero extended as 375d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * necessary. */ 376d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_CHAR: 377d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_SHORT: 378d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_INT: 379d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_USHORT: 380d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_UINT: 3812d9be647dd7402402ad3d2d2f114632aba21eacaPetr Machata align_small_int(buf, width, sz); 382d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata break; 383d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata 384d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata /* Single precision floating point values are mapped 385d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * to the second word in a single doubleword. 386d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * 387d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * An aggregate or union smaller than one doubleword 388d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * in size is padded so that it appears in the least 389d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata * significant bits of the doubleword. */ 390d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_FLOAT: 391d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_ARRAY: 392d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata case ARGTYPE_STRUCT: 393b52f89c1302256bae003edc44c6e3788833629f1Petr Machata memmove(buf, buf + width - sz, sz); 394d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata break; 395d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata } 39654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } 39754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 398d5d70af126d79150ba62a471af08119f9cd44ed0Petr Machata return 0; 39954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 40054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 40154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataint 40254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataarch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 403929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct process *proc, 40454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct arg_type_info *info, struct value *valuep) 40554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 40654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return allocate_argument(ctx, proc, info, valuep); 40754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 40854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 40954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataint 41054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataarch_fetch_retval(struct fetch_context *ctx, enum tof type, 411929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct process *proc, struct arg_type_info *info, 41254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata struct value *valuep) 41354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 41454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (ctx->ret_struct) { 41554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata assert(info->type == ARGTYPE_STRUCT); 41654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 41754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata uint64_t addr = read_gpr(ctx, proc, 3); 41854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata value_init(valuep, proc, NULL, info, 0); 41954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 42054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata valuep->where = VAL_LOC_INFERIOR; 421bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata /* XXX Remove the double cast when arch_addr_t 42236718b01e510ff3973e14b2bad0dbad3177b9943Petr Machata * becomes integral type. */ 423bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata valuep->u.address = (arch_addr_t)(uintptr_t)addr; 42454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return 0; 42554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata } 42654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 42754737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata if (fetch_context_init(proc, ctx) < 0) 42854737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return -1; 42954737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata return allocate_argument(ctx, proc, info, valuep); 43054737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 43154737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata 43254737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machatavoid 43354737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machataarch_fetch_arg_done(struct fetch_context *context) 43454737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata{ 43554737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata free(context); 43654737daf1c51ec826fcabc8189a7ff891f29d59bPetr Machata} 437