fetch.c revision f6ec08afb96292fd3c802c1f633d8de249664c72
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#include "fetch.h"
24#include "value.h"
25#include "arch.h"
26
27#ifdef ARCH_HAVE_FETCH_ARG
28struct fetch_context *arch_fetch_arg_init(enum tof type, struct Process *proc,
29					  struct arg_type_info *ret_info);
30
31struct fetch_context *arch_fetch_arg_clone(struct Process *proc,
32					   struct fetch_context *context);
33
34int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
35			struct Process *proc, struct arg_type_info *info,
36			struct value *valuep);
37
38int arch_fetch_retval(struct fetch_context *ctx, enum tof type,
39		      struct Process *proc, struct arg_type_info *info,
40		      struct value *valuep);
41
42void arch_fetch_arg_done(struct fetch_context *context);
43
44#else
45/* Fall back to gimme_arg.  */
46
47long gimme_arg(enum tof type, struct Process *proc, int arg_num,
48	       struct arg_type_info *info);
49
50struct fetch_context {
51	int argnum;
52};
53
54struct fetch_context *
55arch_fetch_arg_init(enum tof type, struct Process *proc,
56		    struct arg_type_info *ret_info)
57{
58	return calloc(sizeof(struct fetch_context), 1);
59}
60
61struct fetch_context *
62arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
63{
64	struct fetch_context *ret = malloc(sizeof(*ret));
65	if (ret == NULL)
66		return NULL;
67	return memcpy(ret, context, sizeof(*ret));
68}
69
70int
71arch_fetch_arg_next(struct fetch_context *context, enum tof type,
72		    struct Process *proc,
73		    struct arg_type_info *info, struct value *valuep)
74{
75	long l = gimme_arg(type, proc, context->argnum++, info);
76	value_set_long(valuep, l);
77	return 0;
78}
79
80int
81arch_fetch_retval(struct fetch_context *context, enum tof type,
82		  struct Process *proc,
83		  struct arg_type_info *info, struct value *valuep)
84{
85	long l = gimme_arg(type, proc, -1, info);
86	value_set_long(valuep, l);
87	return 0;
88}
89
90void
91arch_fetch_arg_done(struct fetch_context *context)
92{
93	free(context);
94}
95#endif
96
97struct fetch_context *
98fetch_arg_init(enum tof type, struct Process *proc,
99	       struct arg_type_info *ret_info)
100{
101	return arch_fetch_arg_init(type, proc, ret_info);
102}
103
104struct fetch_context *
105fetch_arg_clone(struct Process *proc, struct fetch_context *context)
106{
107	return arch_fetch_arg_clone(proc, context);
108}
109
110int
111fetch_arg_next(struct fetch_context *context, enum tof type,
112	       struct Process *proc,
113	       struct arg_type_info *info, struct value *valuep)
114{
115	return arch_fetch_arg_next(context, type, proc, info, valuep);
116}
117
118int
119fetch_retval(struct fetch_context *context, enum tof type,
120	     struct Process *proc,
121	     struct arg_type_info *info, struct value *valuep)
122{
123	return arch_fetch_retval(context, type, proc, info, valuep);
124}
125
126void
127fetch_arg_done(struct fetch_context *context)
128{
129	return arch_fetch_arg_done(context);
130}
131