fetch.c revision 95792af484c635071ed96107d34a3762c4ca2ef2
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 <ptrace.h> 23#include <stdint.h> 24#include <stdlib.h> 25#include <string.h> 26#include <sys/ucontext.h> 27 28#include <stdio.h> 29 30#include "backend.h" 31#include "fetch.h" 32#include "type.h" 33#include "proc.h" 34#include "value.h" 35 36static int allocate_gpr(struct fetch_context *ctx, struct Process *proc, 37 struct arg_type_info *info, struct value *valuep); 38 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. 42 * 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. */ 46struct fpregs_t 47{ 48 double fpregs[32]; 49 double fpscr; 50 unsigned int _pad[2]; 51}; 52 53typedef uint32_t gregs32_t[48]; 54typedef uint64_t gregs64_t[48]; 55 56struct fetch_context { 57 target_address_t stack_pointer; 58 int greg; 59 int freg; 60 int ret_struct; 61 62 union { 63 gregs32_t r32; 64 gregs64_t r64; 65 } regs; 66 struct fpregs_t fpregs; 67 68}; 69 70static int 71fetch_context_init(struct Process *proc, struct fetch_context *context) 72{ 73 context->greg = 3; 74 context->freg = 1; 75 76 if (proc->e_machine == EM_PPC) 77 context->stack_pointer = proc->stack_pointer + 8; 78 else 79 context->stack_pointer = proc->stack_pointer + 112; 80 81 /* When ltrace is 64-bit, we might use PTRACE_GETREGS to 82 * obtain 64-bit as well as 32-bit registers. But if we do it 83 * this way, 32-bit ltrace can obtain 64-bit registers. 84 * 85 * XXX this direction is not supported as of this writing, but 86 * should be eventually. */ 87 if (proc->e_machine == EM_PPC64) { 88 if (ptrace(PTRACE_GETREGS64, proc->pid, 0, 89 &context->regs.r64) < 0) 90 return -1; 91 } else { 92#ifdef __powerpc64__ 93 if (ptrace(PTRACE_GETREGS, proc->pid, 0, 94 &context->regs.r64) < 0) 95 return -1; 96 unsigned i; 97 for (i = 0; i < sizeof(context->regs.r64)/8; ++i) 98 context->regs.r32[i] = context->regs.r64[i]; 99#else 100 if (ptrace(PTRACE_GETREGS, proc->pid, 0, 101 &context->regs.r32) < 0) 102 return -1; 103#endif 104 } 105 106 if (ptrace(PTRACE_GETFPREGS, proc->pid, 0, &context->fpregs) < 0) 107 return -1; 108 109 return 0; 110} 111 112struct fetch_context * 113arch_fetch_arg_init(enum tof type, struct Process *proc, 114 struct arg_type_info *ret_info) 115{ 116 struct fetch_context *context = malloc(sizeof(*context)); 117 if (context == NULL 118 || fetch_context_init(proc, context) < 0) { 119 free(context); 120 return NULL; 121 } 122 123 /* Aggregates or unions of any length, and character strings 124 * of length longer than 8 bytes, will be returned in a 125 * storage buffer allocated by the caller. The caller will 126 * pass the address of this buffer as a hidden first argument 127 * in r3, causing the first explicit argument to be passed in 128 * r4. */ 129 context->ret_struct = ret_info->type == ARGTYPE_STRUCT; 130 if (context->ret_struct) 131 context->greg++; 132 133 return context; 134} 135 136struct fetch_context * 137arch_fetch_arg_clone(struct Process *proc, 138 struct fetch_context *context) 139{ 140 struct fetch_context *clone = malloc(sizeof(*context)); 141 if (clone == NULL) 142 return NULL; 143 *clone = *context; 144 return clone; 145} 146 147static int 148allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, 149 struct arg_type_info *info, struct value *valuep) 150{ 151 size_t sz = type_sizeof(proc, info); 152 if (sz == (size_t)-1) 153 return -1; 154 155 size_t a = type_alignof(proc, info); 156 size_t off = 0; 157 if (proc->e_machine == EM_PPC && a < 4) 158 a = 4; 159 else if (proc->e_machine == EM_PPC64 && a < 8) 160 a = 8; 161 162 ctx->stack_pointer 163 = (target_address_t)align((uint64_t)ctx->stack_pointer, a); 164 165 if (valuep != NULL) { 166 valuep->where = VAL_LOC_INFERIOR; 167 valuep->u.address = ctx->stack_pointer + off; 168 } 169 170 ctx->stack_pointer += sz; 171 172 return 0; 173} 174 175static uint64_t 176read_gpr(struct fetch_context *ctx, struct Process *proc, int reg_num) 177{ 178 if (proc->e_machine == EM_PPC) 179 return ctx->regs.r32[reg_num]; 180 else 181 return ctx->regs.r64[reg_num]; 182} 183 184static void snip_small_int(unsigned char *buf, size_t w, size_t sz); 185 186static int 187allocate_gpr(struct fetch_context *ctx, struct Process *proc, 188 struct arg_type_info *info, struct value *valuep) 189{ 190 if (ctx->greg > 10) 191 return allocate_stack_slot(ctx, proc, info, valuep); 192 193 int reg_num = ctx->greg++; 194 if (valuep == NULL) 195 return 0; 196 197 size_t sz = type_sizeof(proc, info); 198 if (sz == (size_t)-1) 199 return -1; 200 assert(sz == 1 || sz == 2 || sz == 4 || sz == 8); 201 if (value_reserve(valuep, sz) == NULL) 202 return -1; 203 204 union { 205 uint64_t i64; 206 unsigned char buf[0]; 207 } u; 208 209 u.i64 = read_gpr(ctx, proc, reg_num); 210 if (proc->e_machine == EM_PPC) 211 snip_small_int(u.buf, 8, sz); 212 memcpy(value_get_raw_data(valuep), u.buf, sz); 213 return 0; 214} 215 216static int 217allocate_float(struct fetch_context *ctx, struct Process *proc, 218 struct arg_type_info *info, struct value *valuep) 219{ 220 int pool = proc->e_machine == EM_PPC64 ? 13 : 8; 221 if (ctx->freg <= pool) { 222 union { 223 double d; 224 float f; 225 char buf[0]; 226 } u = { .d = ctx->fpregs.fpregs[ctx->freg] }; 227 228 ctx->freg++; 229 allocate_gpr(ctx, proc, info, NULL); 230 231 size_t sz = sizeof(double); 232 if (info->type == ARGTYPE_FLOAT) { 233 sz = sizeof(float); 234 u.f = (float)u.d; 235 } 236 237 if (value_reserve(valuep, sz) == NULL) 238 return -1; 239 240 memcpy(value_get_raw_data(valuep), u.buf, sz); 241 return 0; 242 } 243 return allocate_stack_slot(ctx, proc, info, valuep); 244} 245 246/* The support for little endian PowerPC is in upstream Linux and BFD, 247 * and Unix-like Solaris, which we might well support at some point, 248 * runs PowerPC in little endian as well. This code moves SZ-sized 249 * value to the beginning of W-sized BUF regardless of 250 * endian. */ 251static void 252snip_small_int(unsigned char *buf, size_t w, size_t sz) 253{ 254 assert(w == 4 || w == 8); 255 union { 256 uint64_t i64; 257 uint32_t i32; 258 uint16_t i16; 259 uint8_t i8; 260 char buf[0]; 261 } u; 262 memcpy(u.buf, buf, w); 263 if (w == 4) 264 u.i64 = u.i32; 265 266 switch (sz) { 267 case 1: 268 u.i8 = u.i64; 269 break; 270 case 2: 271 u.i16 = u.i64; 272 break; 273 case 4: 274 u.i32 = u.i64; 275 case 8: 276 break; 277 } 278 279 memcpy(buf, u.buf, sz); 280} 281 282static int 283allocate_argument(struct fetch_context *ctx, struct Process *proc, 284 struct arg_type_info *info, struct value *valuep) 285{ 286 /* Floating point types and void are handled specially. */ 287 switch (info->type) { 288 case ARGTYPE_VOID: 289 value_set_word(valuep, 0); 290 return 0; 291 292 case ARGTYPE_FLOAT: 293 case ARGTYPE_DOUBLE: 294 return allocate_float(ctx, proc, info, valuep); 295 296 case ARGTYPE_STRUCT: 297 if (proc->e_machine == EM_PPC) { 298 if (value_pass_by_reference(valuep) < 0) 299 return -1; 300 } else { 301 /* PPC64: Fixed size aggregates and unions passed by 302 * value are mapped to as many doublewords of the 303 * parameter save area as the value uses in memory. 304 * [...] The first eight doublewords mapped to the 305 * parameter save area correspond to the registers r3 306 * through r10. */ 307 } 308 /* fall through */ 309 case ARGTYPE_CHAR: 310 case ARGTYPE_SHORT: 311 case ARGTYPE_USHORT: 312 case ARGTYPE_INT: 313 case ARGTYPE_UINT: 314 case ARGTYPE_LONG: 315 case ARGTYPE_ULONG: 316 case ARGTYPE_POINTER: 317 break; 318 319 case ARGTYPE_ARRAY: 320 /* Arrays decay into pointers. XXX Fortran? */ 321 assert(info->type != ARGTYPE_ARRAY); 322 abort(); 323 } 324 325 unsigned width = proc->e_machine == EM_PPC64 ? 8 : 4; 326 327 /* For other cases (integral types and aggregates), read the 328 * eightbytes comprising the data. */ 329 size_t sz = type_sizeof(proc, valuep->type); 330 if (sz == (size_t)-1) 331 return -1; 332 size_t slots = (sz + width - 1) / width; /* Round up. */ 333 unsigned char *buf = value_reserve(valuep, slots * width); 334 if (buf == NULL) 335 return -1; 336 struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG); 337 338 unsigned char *ptr = buf; 339 while (slots-- > 0) { 340 struct value val; 341 value_init(&val, proc, NULL, long_info, 0); 342 int rc = allocate_gpr(ctx, proc, long_info, &val); 343 if (rc >= 0) { 344 memcpy(ptr, value_get_data(&val, NULL), width); 345 ptr += width; 346 } 347 value_destroy(&val); 348 if (rc < 0) 349 return rc; 350 } 351 352 /* Small values need post-processing. */ 353 if (sz < width) { 354 switch (info->type) { 355 case ARGTYPE_LONG: 356 case ARGTYPE_ULONG: 357 case ARGTYPE_POINTER: 358 case ARGTYPE_DOUBLE: 359 case ARGTYPE_VOID: 360 abort(); 361 362 /* Simple integer types (char, short, int, long, enum) 363 * are mapped to a single doubleword. Values shorter 364 * than a doubleword are sign or zero extended as 365 * necessary. */ 366 case ARGTYPE_CHAR: 367 case ARGTYPE_SHORT: 368 case ARGTYPE_INT: 369 case ARGTYPE_USHORT: 370 case ARGTYPE_UINT: 371 snip_small_int(buf, width, sz); 372 break; 373 374 /* Single precision floating point values are mapped 375 * to the second word in a single doubleword. 376 * 377 * An aggregate or union smaller than one doubleword 378 * in size is padded so that it appears in the least 379 * significant bits of the doubleword. */ 380 case ARGTYPE_FLOAT: 381 case ARGTYPE_ARRAY: 382 case ARGTYPE_STRUCT: 383 memmove(buf, buf + width - sz, sz); 384 break; 385 } 386 } 387 388 return 0; 389} 390 391int 392arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 393 struct Process *proc, 394 struct arg_type_info *info, struct value *valuep) 395{ 396 return allocate_argument(ctx, proc, info, valuep); 397} 398 399int 400arch_fetch_retval(struct fetch_context *ctx, enum tof type, 401 struct Process *proc, struct arg_type_info *info, 402 struct value *valuep) 403{ 404 if (ctx->ret_struct) { 405 assert(info->type == ARGTYPE_STRUCT); 406 407 uint64_t addr = read_gpr(ctx, proc, 3); 408 value_init(valuep, proc, NULL, info, 0); 409 410 valuep->where = VAL_LOC_INFERIOR; 411 valuep->u.address = (target_address_t)addr; 412 return 0; 413 } 414 415 if (fetch_context_init(proc, ctx) < 0) 416 return -1; 417 return allocate_argument(ctx, proc, info, valuep); 418} 419 420void 421arch_fetch_arg_done(struct fetch_context *context) 422{ 423 free(context); 424} 425