fetch.c revision 0b926f68098c4dd0df922ba2c6214ed902cd4cd6
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 <asm/ptrace.h> 22#include <sys/ptrace.h> 23#include <sys/ucontext.h> 24#include <assert.h> 25#include <errno.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29 30#include "backend.h" 31#include "fetch.h" 32#include "type.h" 33#include "proc.h" 34#include "value.h" 35 36struct fetch_context { 37 struct user_regs_struct regs; 38 arch_addr_t stack_pointer; 39 int greg; 40 int freg; 41}; 42 43static int 44s390x(struct fetch_context *ctx) 45{ 46 /* +--------+--------+--------+ 47 * | PSW.31 | PSW.32 | mode | 48 * +--------+--------+--------+ 49 * | 0 | 0 | 24-bit | Not supported in Linux 50 * | 0 | 1 | 31-bit | s390 compatible mode 51 * | 1 | 1 | 64-bit | z/Architecture, "s390x" 52 * +--------+--------+--------+ 53 * (Note: The leftmost bit is PSW.0, rightmost PSW.63.) 54 */ 55 56#ifdef __s390x__ 57 if ((ctx->regs.psw.mask & 0x180000000UL) == 0x180000000UL) 58 return 1; 59#endif 60 return 0; 61} 62 63static int 64fp_equivalent(struct arg_type_info *info) 65{ 66 switch (info->type) { 67 case ARGTYPE_VOID: 68 case ARGTYPE_INT: 69 case ARGTYPE_UINT: 70 case ARGTYPE_LONG: 71 case ARGTYPE_ULONG: 72 case ARGTYPE_CHAR: 73 case ARGTYPE_SHORT: 74 case ARGTYPE_USHORT: 75 case ARGTYPE_ARRAY: 76 case ARGTYPE_POINTER: 77 return 0; 78 79 case ARGTYPE_FLOAT: 80 case ARGTYPE_DOUBLE: 81 return 1; 82 83 case ARGTYPE_STRUCT: 84 if (type_struct_size(info) != 1) 85 return 0; 86 return fp_equivalent(type_element(info, 0)); 87 } 88 assert(info->type != info->type); 89 abort(); 90} 91 92static int 93fetch_register_banks(struct Process *proc, struct fetch_context *ctx) 94{ 95 ptrace_area parea; 96 parea.len = sizeof(ctx->regs); 97 parea.process_addr = (uintptr_t)&ctx->regs; 98 parea.kernel_addr = 0; 99 if (ptrace(PTRACE_PEEKUSR_AREA, proc->pid, &parea, NULL) < 0) { 100 fprintf(stderr, "fetch_register_banks GPR: %s\n", 101 strerror(errno)); 102 return -1; 103 } 104 return 0; 105} 106 107static int 108fetch_context_init(struct Process *proc, struct fetch_context *context) 109{ 110 context->greg = 2; 111 context->freg = 0; 112 return fetch_register_banks(proc, context); 113} 114 115struct fetch_context * 116arch_fetch_arg_init(enum tof type, struct Process *proc, 117 struct arg_type_info *ret_info) 118{ 119 struct fetch_context *context = malloc(sizeof(*context)); 120 if (context == NULL 121 || fetch_context_init(proc, context) < 0) { 122 fprintf(stderr, "arch_fetch_arg_init: %s\n", 123 strerror(errno)); 124 free(context); 125 return NULL; 126 } 127 128 context->stack_pointer = get_stack_pointer(proc) 129 + (s390x(context) ? 160 : 96); 130 if (ret_info->type == ARGTYPE_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 size_t sz) 151{ 152 /* Note: when here, we shouldn't see composite types, those 153 * are passed by reference, which is handled below. Here we 154 * only deal with integers, floats, etc. */ 155 156 size_t a; 157 if (s390x(ctx)) { 158 assert(sz <= 8); 159 a = 8; 160 } else { 161 /* Note: double is 8 bytes. */ 162 assert(sz <= 8); 163 a = 4; 164 } 165 166 size_t off = sz < a ? a - sz : 0; 167 168 valuep->where = VAL_LOC_INFERIOR; 169 valuep->u.address = ctx->stack_pointer + off; 170 171 ctx->stack_pointer += sz > a ? sz : a; 172 return 0; 173} 174 175static void 176copy_gpr(struct fetch_context *ctx, struct value *valuep, int regno) 177{ 178 value_set_word(valuep, ctx->regs.gprs[regno]); 179} 180 181static int 182allocate_gpr(struct fetch_context *ctx, struct Process *proc, 183 struct arg_type_info *info, struct value *valuep, 184 size_t sz) 185{ 186 if (ctx->greg > 6) 187 return allocate_stack_slot(ctx, proc, info, valuep, sz); 188 189 copy_gpr(ctx, valuep, ctx->greg++); 190 return 0; 191} 192 193static int 194allocate_fpr(struct fetch_context *ctx, struct Process *proc, 195 struct arg_type_info *info, struct value *valuep, 196 size_t sz) 197{ 198 int pool = s390x(ctx) ? 6 : 2; 199 200 if (ctx->freg > pool) 201 return allocate_stack_slot(ctx, proc, info, valuep, sz); 202 203 if (value_reserve(valuep, sz) == NULL) 204 return -1; 205 206 memcpy(value_get_raw_data(valuep), 207 &ctx->regs.fp_regs.fprs[ctx->freg], sz); 208 ctx->freg += 2; 209 210 return 0; 211} 212 213int 214arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 215 struct Process *proc, 216 struct arg_type_info *info, struct value *valuep) 217{ 218 size_t sz = type_sizeof(proc, info); 219 if (sz == (size_t)-1) 220 return -1; 221 222 /* XXX structures<4 bytes on s390 and structures<8 bytes on 223 * s390x are passed in register. On s390, long long and 224 * structures<8 bytes are passed in two consecutive 225 * registers (if two are available). */ 226 227 switch (info->type) { 228 case ARGTYPE_VOID: 229 value_set_word(valuep, 0); 230 return 0; 231 232 case ARGTYPE_STRUCT: 233 if (fp_equivalent(info)) 234 /* fall through */ 235 236 case ARGTYPE_FLOAT: 237 case ARGTYPE_DOUBLE: 238 return allocate_fpr(ctx, proc, info, valuep, sz); 239 240 if (type_sizeof(proc, info) < 8) 241 return allocate_gpr(ctx, proc, info, valuep, sz); 242 /* fall through */ 243 244 case ARGTYPE_ARRAY: 245 if (value_pass_by_reference(valuep) < 0) 246 return -1; 247 /* fall through */ 248 249 case ARGTYPE_INT: 250 case ARGTYPE_UINT: 251 case ARGTYPE_LONG: 252 case ARGTYPE_ULONG: 253 case ARGTYPE_CHAR: 254 case ARGTYPE_SHORT: 255 case ARGTYPE_USHORT: 256 case ARGTYPE_POINTER: 257 return allocate_gpr(ctx, proc, info, valuep, sz); 258 } 259 return -1; 260} 261 262int 263arch_fetch_retval(struct fetch_context *ctx, enum tof type, 264 struct Process *proc, struct arg_type_info *info, 265 struct value *valuep) 266{ 267 if (info->type == ARGTYPE_STRUCT) { 268 if (value_pass_by_reference(valuep) < 0) 269 return -1; 270 copy_gpr(ctx, valuep, 2); 271 return 0; 272 } 273 274 if (fetch_context_init(proc, ctx) < 0) 275 return -1; 276 return arch_fetch_arg_next(ctx, type, proc, info, valuep); 277} 278 279void 280arch_fetch_arg_done(struct fetch_context *context) 281{ 282 free(context); 283} 284