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 34static 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. */ 44struct fpregs_t 45{ 46 double fpregs[32]; 47 double fpscr; 48 unsigned int _pad[2]; 49}; 50 51typedef uint32_t gregs32_t[48]; 52typedef uint64_t gregs64_t[48]; 53 54struct 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 68static int 69fetch_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 110struct fetch_context * 111arch_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 134struct fetch_context * 135arch_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 145static int 146allocate_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 172static uint64_t 173read_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. */ 186static void 187align_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 217static int 218allocate_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 247static int 248allocate_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 278static int 279allocate_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 401int 402arch_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 409int 410arch_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 432void 433arch_fetch_arg_done(struct fetch_context *context) 434{ 435 free(context); 436} 437