fetch.c revision 8d30fd9f26ccd15f0fa27e09d1fd99deddb17d36
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{ 151 /* Note: when here, we shouldn't see composite types, those 152 * are passed by reference, which is handled below. Here we 153 * only deal with integers, floats, etc. */ 154 155 size_t sz = type_sizeof(proc, info); 156 if (sz == (size_t)-1) 157 return -1; 158 159 size_t a; 160 if (s390x(ctx)) { 161 assert(sz <= 8); 162 a = 8; 163 } else { 164 /* Note: double is 8 bytes. */ 165 assert(sz <= 8); 166 a = 4; 167 } 168 169 size_t off = sz < a ? a - sz : 0; 170 171 valuep->where = VAL_LOC_INFERIOR; 172 valuep->u.address = ctx->stack_pointer + off; 173 174 ctx->stack_pointer += sz > a ? sz : a; 175 return 0; 176} 177 178static void 179copy_gpr(struct fetch_context *ctx, struct value *valuep, int regno) 180{ 181 value_set_word(valuep, ctx->regs.gprs[regno]); 182} 183 184static int 185allocate_gpr(struct fetch_context *ctx, struct Process *proc, 186 struct arg_type_info *info, struct value *valuep) 187{ 188 if (ctx->greg > 6) 189 return allocate_stack_slot(ctx, proc, info, valuep); 190 191 copy_gpr(ctx, valuep, ctx->greg++); 192 return 0; 193} 194 195static int 196allocate_fpr(struct fetch_context *ctx, struct Process *proc, 197 struct arg_type_info *info, struct value *valuep) 198{ 199 200 int pool = s390x(ctx) ? 6 : 2; 201 202 if (ctx->freg > pool) 203 return allocate_stack_slot(ctx, proc, info, valuep); 204 205 size_t sz = type_sizeof(proc, info); 206 if (sz == (size_t)-1) 207 return -1; 208 209 if (value_reserve(valuep, sz) == NULL) 210 return -1; 211 212 memcpy(value_get_raw_data(valuep), 213 &ctx->regs.fp_regs.fprs[ctx->freg], sz); 214 ctx->freg += 2; 215 216 return 0; 217} 218 219int 220arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, 221 struct Process *proc, 222 struct arg_type_info *info, struct value *valuep) 223{ 224 /* XXX structures<4 bytes on s390 and structures<8 bytes on 225 * s390x are passed in register. On s390, long long and 226 * structures<8 bytes are passed in two consecutive 227 * registers (if two are available). */ 228 229 switch (info->type) { 230 case ARGTYPE_VOID: 231 value_set_word(valuep, 0); 232 return 0; 233 234 case ARGTYPE_STRUCT: 235 if (fp_equivalent(info)) 236 /* fall through */ 237 238 case ARGTYPE_FLOAT: 239 case ARGTYPE_DOUBLE: 240 return allocate_fpr(ctx, proc, info, valuep); 241 242 if (type_sizeof(proc, info) < 8) 243 return allocate_gpr(ctx, proc, info,valuep); 244 /* fall through */ 245 246 case ARGTYPE_ARRAY: 247 if (value_pass_by_reference(valuep) < 0) 248 return -1; 249 /* fall through */ 250 251 case ARGTYPE_INT: 252 case ARGTYPE_UINT: 253 case ARGTYPE_LONG: 254 case ARGTYPE_ULONG: 255 case ARGTYPE_CHAR: 256 case ARGTYPE_SHORT: 257 case ARGTYPE_USHORT: 258 case ARGTYPE_POINTER: 259 return allocate_gpr(ctx, proc, info, valuep); 260 } 261 return -1; 262} 263 264int 265arch_fetch_retval(struct fetch_context *ctx, enum tof type, 266 struct Process *proc, struct arg_type_info *info, 267 struct value *valuep) 268{ 269 if (info->type == ARGTYPE_STRUCT) { 270 if (value_pass_by_reference(valuep) < 0) 271 return -1; 272 copy_gpr(ctx, valuep, 2); 273 return 0; 274 } 275 276 if (fetch_context_init(proc, ctx) < 0) 277 return -1; 278 return arch_fetch_arg_next(ctx, type, proc, info, valuep); 279} 280 281void 282arch_fetch_arg_done(struct fetch_context *context) 283{ 284 free(context); 285} 286