1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,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 <stdlib.h>
22#include <string.h>
23
24#include "fetch.h"
25#include "sysdep.h"
26#include "value.h"
27#include "type.h"
28
29#ifdef ARCH_HAVE_FETCH_ARG
30struct fetch_context *arch_fetch_arg_init(enum tof type, struct process *proc,
31					  struct arg_type_info *ret_info);
32
33struct fetch_context *arch_fetch_arg_clone(struct process *proc,
34					   struct fetch_context *context);
35
36int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
37			struct process *proc, struct arg_type_info *info,
38			struct value *valuep);
39
40int arch_fetch_retval(struct fetch_context *ctx, enum tof type,
41		      struct process *proc, struct arg_type_info *info,
42		      struct value *valuep);
43
44void arch_fetch_arg_done(struct fetch_context *context);
45
46# ifdef ARCH_HAVE_FETCH_PACK
47int arch_fetch_param_pack_start(struct fetch_context *context,
48				enum param_pack_flavor ppflavor);
49
50void arch_fetch_param_pack_end(struct fetch_context *context);
51# endif
52
53#else
54/* Fall back to gimme_arg.  */
55
56long gimme_arg(enum tof type, struct process *proc, int arg_num,
57	       struct arg_type_info *info);
58
59struct fetch_context {
60	int argnum;
61};
62
63struct fetch_context *
64arch_fetch_arg_init(enum tof type, struct process *proc,
65		    struct arg_type_info *ret_info)
66{
67	return calloc(sizeof(struct fetch_context), 1);
68}
69
70struct fetch_context *
71arch_fetch_arg_clone(struct process *proc, struct fetch_context *context)
72{
73	struct fetch_context *ret = malloc(sizeof(*ret));
74	if (ret == NULL)
75		return NULL;
76	return memcpy(ret, context, sizeof(*ret));
77}
78
79int
80arch_fetch_arg_next(struct fetch_context *context, enum tof type,
81		    struct process *proc,
82		    struct arg_type_info *info, struct value *valuep)
83{
84	long l = gimme_arg(type, proc, context->argnum++, info);
85	value_set_word(valuep, l);
86	return 0;
87}
88
89int
90arch_fetch_retval(struct fetch_context *context, enum tof type,
91		  struct process *proc,
92		  struct arg_type_info *info, struct value *valuep)
93{
94	long l = gimme_arg(type, proc, -1, info);
95	value_set_word(valuep, l);
96	return 0;
97}
98
99void
100arch_fetch_arg_done(struct fetch_context *context)
101{
102	free(context);
103}
104#endif
105
106#if !defined(ARCH_HAVE_FETCH_ARG) || !defined(ARCH_HAVE_FETCH_PACK)
107int
108arch_fetch_param_pack_start(struct fetch_context *context,
109			    enum param_pack_flavor ppflavor)
110{
111	return 0;
112}
113
114void
115arch_fetch_param_pack_end(struct fetch_context *context)
116{
117}
118#endif
119
120struct fetch_context *
121fetch_arg_init(enum tof type, struct process *proc,
122	       struct arg_type_info *ret_info)
123{
124	return arch_fetch_arg_init(type, proc, ret_info);
125}
126
127struct fetch_context *
128fetch_arg_clone(struct process *proc, struct fetch_context *context)
129{
130	return arch_fetch_arg_clone(proc, context);
131}
132
133int
134fetch_arg_next(struct fetch_context *context, enum tof type,
135	       struct process *proc,
136	       struct arg_type_info *info, struct value *valuep)
137{
138	return arch_fetch_arg_next(context, type, proc, info, valuep);
139}
140
141int
142fetch_retval(struct fetch_context *context, enum tof type,
143	     struct process *proc,
144	     struct arg_type_info *info, struct value *valuep)
145{
146	return arch_fetch_retval(context, type, proc, info, valuep);
147}
148
149void
150fetch_arg_done(struct fetch_context *context)
151{
152	return arch_fetch_arg_done(context);
153}
154
155int
156fetch_param_pack_start(struct fetch_context *context,
157		       enum param_pack_flavor ppflavor)
158{
159	return arch_fetch_param_pack_start(context, ppflavor);
160}
161
162void
163fetch_param_pack_end(struct fetch_context *context)
164{
165	return arch_fetch_param_pack_end(context);
166}
167