浏览代码

binop infer

Tobias Waldekranz.com 8 年之前
父节点
当前提交
1af238377e
共有 4 个文件被更改,包括 69 次插入8 次删除
  1. 22 0
      global.c
  2. 45 7
      kprobe.c
  3. 1 0
      ply.c
  4. 1 1
      sym.c

+ 22 - 0
global.c

133
 	return -EINVAL;
133
 	return -EINVAL;
134
 }
134
 }
135
 
135
 
136
+/* :binop */
137
+
138
+static int global_binop_type_infer(const struct func *func, struct node *n)
139
+{
140
+	struct node *lval, *rval;
141
+
142
+	lval = n->expr.args;
143
+	rval = lval->next;
144
+
145
+	if (n->sym->type || !lval->sym->type || !rval->sym->type)
146
+		return 0;
147
+
148
+	if (type_equal(lval->sym->type, rval->sym->type)) {
149
+		n->sym->type = lval->sym->type;
150
+		return 0;
151
+	}
152
+
153
+	/* TODO handle integer promotion */
154
+	return 0;
155
+}
136
 
156
 
137
 /* pid */
157
 /* pid */
138
 
158
 
204
 	{
224
 	{
205
 		.name = "+",
225
 		.name = "+",
206
 		.type = &t_2args_func,
226
 		.type = &t_2args_func,
227
+		.type_infer = global_binop_type_infer,
207
 	},
228
 	},
208
 	{
229
 	{
209
 		.name = "-",
230
 		.name = "-",
210
 		.type = &t_2args_func,
231
 		.type = &t_2args_func,
232
+		.type_infer = global_binop_type_infer,
211
 	},
233
 	},
212
 	
234
 	
213
 	{
235
 	{

+ 45 - 7
kprobe.c

5
 
5
 
6
 #include <linux/ptrace.h>
6
 #include <linux/ptrace.h>
7
 
7
 
8
+#include "func.h"
9
+#include "node.h"
8
 #include "ply.h"
10
 #include "ply.h"
11
+#include "sym.h"
12
+#include "type.h"
9
 
13
 
10
 struct kprobe {
14
 struct kprobe {
11
 };
15
 };
24
 /* 	return 0; */
28
 /* 	return 0; */
25
 /* } */
29
 /* } */
26
 
30
 
27
-/* static inline int is_arg(const char *name) */
28
-/* { */
29
-/* 	return (strstr(name, "arg") == name) */
30
-/* 		&& (strlen(name) == 4) */
31
-/* 		&& (name[3] >= '0' && name[3] <= '9'); */
32
-/* } */
31
+static inline int is_arg(const char *name)
32
+{
33
+	return (strstr(name, "arg") == name)
34
+		&& (strlen(name) == 4)
35
+		&& (name[3] >= '0' && name[3] <= '9');
36
+}
33
 
37
 
34
 /* static int kprobe_rewrite_arg(prog_t *prog, node_t *n) */
38
 /* static int kprobe_rewrite_arg(prog_t *prog, node_t *n) */
35
 /* { */
39
 /* { */
89
 /* 	return sym_add(prog->locals, n->ident, t, &n->sym); */
93
 /* 	return sym_add(prog->locals, n->ident, t, &n->sym); */
90
 /* } */
94
 /* } */
91
 
95
 
96
+static const struct func kprobe_arg_func = {
97
+	.name = "argN",
98
+
99
+	/* for now, in the future we could read dwarf symbols to
100
+	 * figure out the real type. */
101
+	.type = &t_ulong,
102
+	.static_ret = 1,
103
+};
104
+
92
 static int kprobe_sym_alloc(struct prog *prog, struct node *n)
105
 static int kprobe_sym_alloc(struct prog *prog, struct node *n)
93
 {
106
 {
94
-	return -ENOENT;
107
+	const struct func *func = NULL;
108
+	int err;
109
+
110
+	switch (n->ntype) {
111
+	case N_EXPR:
112
+		break;
113
+	case N_IDENT:
114
+		if (is_arg(n->ident.name))
115
+			func = &kprobe_arg_func;
116
+		break;
117
+	default:
118
+		break;
119
+	}
120
+
121
+	if (!func)
122
+		return -ENOENT;
123
+
124
+	err = func_static_validate(func, n);
125
+	if (err)
126
+		return err;
127
+
128
+	n->sym = sym_alloc(prog->locals, n, func);
129
+
130
+	if (func->static_ret)
131
+		n->sym->type = func_return_type(func);
132
+	return 0;
95
 }
133
 }
96
 
134
 
97
 static int kprobe_probe(struct prog *prog)
135
 static int kprobe_probe(struct prog *prog)

+ 1 - 0
ply.c

123
 					      node_expr("{}",
123
 					      node_expr("{}",
124
 							node_ident("t"),
124
 							node_ident("t"),
125
 							node_num("0"),
125
 							node_num("0"),
126
+							node_expr("time", NULL),
126
 							node_expr("pid", NULL),
127
 							node_expr("pid", NULL),
127
 							NULL),
128
 							NULL),
128
 					      NULL),
129
 					      NULL),

+ 1 - 1
sym.c

30
 	struct sym **sym;
30
 	struct sym **sym;
31
 
31
 
32
 	symtab_foreach(st, sym) {
32
 	symtab_foreach(st, sym) {
33
-		if (!strcmp((*sym)->name, n->ident.name))
33
+		if ((*sym)->name && !strcmp((*sym)->name, n->ident.name))
34
 			return *sym;
34
 			return *sym;
35
 	}
35
 	}
36
 
36