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
s390x(struct fetch_context * ctx)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
fetch_register_banks(struct process * proc,struct fetch_context * ctx,bool syscall_enter)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
fetch_context_init(struct process * proc,struct fetch_context * context,bool syscall_enter)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 *
arch_fetch_arg_init(enum tof type,struct process * proc,struct arg_type_info * ret_info)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 *
arch_fetch_arg_clone(struct process * proc,struct fetch_context * 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
allocate_stack_slot(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep,size_t sz)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
copy_gpr(struct fetch_context * ctx,struct value * valuep,int regno)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
allocate_gpr(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep,size_t sz)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
allocate_gpr_pair(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep,size_t sz)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
allocate_fpr(struct fetch_context * ctx,struct process * proc,struct arg_type_info * info,struct value * valuep,size_t sz)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
arch_fetch_arg_next(struct fetch_context * ctx,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)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
arch_fetch_retval(struct fetch_context * ctx,enum tof type,struct process * proc,struct arg_type_info * info,struct value * valuep)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
arch_fetch_arg_done(struct fetch_context * context)293 arch_fetch_arg_done(struct fetch_context *context)
294 {
295 free(context);
296 }
297