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