浏览代码

all files compile again with new ast

Tobias Waldekranz.com 8 年之前
父节点
当前提交
ece12da963
共有 16 个文件被更改,包括 490 次插入312 次删除
  1. 8 4
      Makefile
  2. 12 15
      arch-x86_64.c
  3. 67 0
      arch-x86_64_test.c
  4. 10 10
      arch.h
  5. 91 26
      global.c
  6. 2 0
      ir.c
  7. 87 81
      kprobe.c
  8. 23 0
      node.c
  9. 4 7
      node.h
  10. 65 54
      ply.c
  11. 20 12
      ply.h
  12. 44 39
      sym.c
  13. 18 14
      sym.h
  14. 35 47
      type.c
  15. 2 2
      type.h
  16. 2 1
      type_test.c

+ 8 - 4
Makefile

1
 CFLAGS ?= -Wall -Wextra -Werror -Wno-unused -O0 -g
1
 CFLAGS ?= -Wall -Wextra -Werror -Wno-unused -O0 -g
2
 
2
 
3
-srcs := ply.c node.c type.c
4
-hdrs := node.h ply.h type.h
3
+csrcs  := $(wildcard *_test.c)
4
+cprogs := $(patsubst %.c,%,$(csrcs))
5
 
5
 
6
-#srcs := $(wildcard *.c)
7
-#hdrs := $(wildcard *.h)
6
+srcs := $(filter-out %_test.c,$(wildcard *.c))
7
+hdrs := $(wildcard *.h)
8
 objs := $(patsubst %.c,%.o,$(srcs))
8
 objs := $(patsubst %.c,%.o,$(srcs))
9
 deps := $(srcs) $(hdrs)
9
 deps := $(srcs) $(hdrs)
10
 
10
 
12
 
12
 
13
 ply: $(objs)
13
 ply: $(objs)
14
 
14
 
15
+arch-x86_64_test: arch-x86_64_test.o arch-x86_64.o type.o
15
 type_test: type_test.o type.o
16
 type_test: type_test.o type.o
17
+
18
+check: $(cprogs)
19
+	$(foreach prog,$(cprogs),./$(prog);)

+ 12 - 15
arch-x86_64.c

1
 #include <assert.h>
1
 #include <assert.h>
2
-#include <linux/ptrace.h>
3
 
2
 
4
 #include "type.h"
3
 #include "type.h"
5
 
4
 
6
 #define arch_typedef(_a, _t) {					\
5
 #define arch_typedef(_a, _t) {					\
7
 		.ttype = T_TYPEDEF,				\
6
 		.ttype = T_TYPEDEF,				\
8
-		.t = { .tdef = { .name = #_a, .type = _t } },	\
7
+		.tdef = { .name = #_a, .type = _t },		\
9
 	}
8
 	}
10
 
9
 
11
-type_t t_s8  = arch_typedef(s8,  &t_schar);
12
-type_t t_u8  = arch_typedef(u8,  &t_uchar);
13
-type_t t_s16 = arch_typedef(s16, &t_sshort);
14
-type_t t_u16 = arch_typedef(u16, &t_ushort);
15
-type_t t_s32 = arch_typedef(s32, &t_sint);
16
-type_t t_u32 = arch_typedef(u32, &t_uint);
17
-type_t t_s64 = arch_typedef(s64, &t_slong);
18
-type_t t_u64 = arch_typedef(u64, &t_ulong);
10
+struct type t_s8  = arch_typedef(s8,  &t_schar);
11
+struct type t_u8  = arch_typedef(u8,  &t_uchar);
12
+struct type t_s16 = arch_typedef(s16, &t_sshort);
13
+struct type t_u16 = arch_typedef(u16, &t_ushort);
14
+struct type t_s32 = arch_typedef(s32, &t_sint);
15
+struct type t_u32 = arch_typedef(u32, &t_uint);
16
+struct type t_s64 = arch_typedef(s64, &t_slong);
17
+struct type t_u64 = arch_typedef(u64, &t_ulong);
19
 
18
 
20
-field_t f_pt_regs_fields[] = {
19
+struct tfield f_pt_regs_fields[] = {
21
 	{ .name = "r15",      .type = &t_ulong },
20
 	{ .name = "r15",      .type = &t_ulong },
22
 	{ .name = "r14",      .type = &t_ulong },
21
 	{ .name = "r14",      .type = &t_ulong },
23
 	{ .name = "r13",      .type = &t_ulong },
22
 	{ .name = "r13",      .type = &t_ulong },
43
 	{ .type = &t_void }
42
 	{ .type = &t_void }
44
 };
43
 };
45
 
44
 
46
-type_t t_pt_regs = {
45
+struct type t_pt_regs = {
47
 	.ttype = T_STRUCT,
46
 	.ttype = T_STRUCT,
48
 
47
 
49
 	.sou = {
48
 	.sou = {
52
 	},
51
 	},
53
 };
52
 };
54
 
53
 
55
-type_t *arch_types[] = {
54
+struct type *arch_types[] = {
56
 	&t_s8, &t_u8,
55
 	&t_s8, &t_u8,
57
 	&t_s16, &t_u16,
56
 	&t_s16, &t_u16,
58
 	&t_s32, &t_u32,
57
 	&t_s32, &t_u32,
90
 static void arch_init(void)
89
 static void arch_init(void)
91
 {
90
 {
92
 	type_add_list(arch_types);
91
 	type_add_list(arch_types);
93
-
94
-	assert(t_pt_regs.size == sizeof(struct pt_regs));
95
 }
92
 }

+ 67 - 0
arch-x86_64_test.c

1
+#include <linux/ptrace.h>
2
+#include <stdint.h>
3
+
4
+#include "unittest.h"
5
+
6
+#include "arch.h"
7
+#include "type.h"
8
+
9
+static int arch_x86_64_sizeof(void *_null)
10
+{
11
+	unittest_eq(type_sizeof(&t_s8), sizeof(int8_t));
12
+	unittest_eq(type_sizeof(&t_u8), sizeof(uint8_t));
13
+
14
+	unittest_eq(type_sizeof(&t_s16), sizeof(int16_t));
15
+	unittest_eq(type_sizeof(&t_u16), sizeof(uint16_t));
16
+
17
+	unittest_eq(type_sizeof(&t_s32), sizeof(int32_t));
18
+	unittest_eq(type_sizeof(&t_u32), sizeof(uint32_t));
19
+
20
+	unittest_eq(type_sizeof(&t_s64), sizeof(int64_t));
21
+	unittest_eq(type_sizeof(&t_u64), sizeof(uint64_t));
22
+	return 0;
23
+}
24
+UNITTEST(arch_x86_64_sizeof);
25
+
26
+static int arch_x86_64_pt_regs(void *_null)
27
+{
28
+	unittest_eq(type_offsetof(&t_pt_regs, "r15"), offsetof(struct pt_regs, r15));
29
+	unittest_eq(type_offsetof(&t_pt_regs, "r14"), offsetof(struct pt_regs, r14));
30
+	unittest_eq(type_offsetof(&t_pt_regs, "r13"), offsetof(struct pt_regs, r13));
31
+	unittest_eq(type_offsetof(&t_pt_regs, "r12"), offsetof(struct pt_regs, r12));
32
+	unittest_eq(type_offsetof(&t_pt_regs, "rbp"), offsetof(struct pt_regs, rbp));
33
+	unittest_eq(type_offsetof(&t_pt_regs, "rbx"), offsetof(struct pt_regs, rbx));
34
+	unittest_eq(type_offsetof(&t_pt_regs, "r11"), offsetof(struct pt_regs, r11));
35
+	unittest_eq(type_offsetof(&t_pt_regs, "r10"), offsetof(struct pt_regs, r10));
36
+	unittest_eq(type_offsetof(&t_pt_regs, "r9"),  offsetof(struct pt_regs, r9));
37
+	unittest_eq(type_offsetof(&t_pt_regs, "r8"),  offsetof(struct pt_regs, r8));
38
+	unittest_eq(type_offsetof(&t_pt_regs, "rax"), offsetof(struct pt_regs, rax));
39
+	unittest_eq(type_offsetof(&t_pt_regs, "rcx"), offsetof(struct pt_regs, rcx));
40
+	unittest_eq(type_offsetof(&t_pt_regs, "rdx"), offsetof(struct pt_regs, rdx));
41
+	unittest_eq(type_offsetof(&t_pt_regs, "rsi"), offsetof(struct pt_regs, rsi));
42
+	unittest_eq(type_offsetof(&t_pt_regs, "rdi"), offsetof(struct pt_regs, rdi));
43
+	unittest_eq(type_offsetof(&t_pt_regs, "orig_rax"), offsetof(struct pt_regs, orig_rax));
44
+	unittest_eq(type_offsetof(&t_pt_regs, "rip"), offsetof(struct pt_regs, rip));
45
+	unittest_eq(type_offsetof(&t_pt_regs, "cs"),  offsetof(struct pt_regs, cs));
46
+	unittest_eq(type_offsetof(&t_pt_regs, "eflags"), offsetof(struct pt_regs, eflags));
47
+	unittest_eq(type_offsetof(&t_pt_regs, "rsp"), offsetof(struct pt_regs, rsp));
48
+	unittest_eq(type_offsetof(&t_pt_regs, "ss"),  offsetof(struct pt_regs, ss));
49
+
50
+	unittest_eq(type_alignof(&t_pt_regs),  __alignof__(struct pt_regs));
51
+	unittest_eq(type_sizeof(&t_pt_regs),  sizeof(struct pt_regs));	
52
+	return 0;
53
+}
54
+UNITTEST(arch_x86_64_pt_regs);
55
+
56
+
57
+int main(void)
58
+{
59
+	struct unittest_ctx ctx = {
60
+		.keep_going = 1,
61
+		.verbose = 1,
62
+
63
+		.ctx = NULL,
64
+	};
65
+
66
+	return unittests_run(&ctx) ? 1 : 0;
67
+}

+ 10 - 10
arch.h

1
 #ifndef _PLY_ARCH_H
1
 #ifndef _PLY_ARCH_H
2
 #define _PLY_ARCH_H
2
 #define _PLY_ARCH_H
3
 
3
 
4
-#include "type.h"
4
+struct type;
5
 
5
 
6
 /* fixed length integers */
6
 /* fixed length integers */
7
-extern type_t t_s8;
8
-extern type_t t_u8;
9
-extern type_t t_s16;
10
-extern type_t t_u16;
11
-extern type_t t_s32;
12
-extern type_t t_u32;
13
-extern type_t t_s64;
14
-extern type_t t_u64;
7
+extern struct type t_s8;
8
+extern struct type t_u8;
9
+extern struct type t_s16;
10
+extern struct type t_u16;
11
+extern struct type t_s32;
12
+extern struct type t_u32;
13
+extern struct type t_s64;
14
+extern struct type t_u64;
15
 
15
 
16
 /* layout of captured registers */
16
 /* layout of captured registers */
17
-extern type_t t_pt_regs;
17
+extern struct type t_pt_regs;
18
 
18
 
19
 /* ABI mapping of registers to arguments/return value */
19
 /* ABI mapping of registers to arguments/return value */
20
 const char *arch_register_argument(int num);
20
 const char *arch_register_argument(int num);

+ 91 - 26
global.c

1
 #include <errno.h>
1
 #include <errno.h>
2
 #include <string.h>
2
 #include <string.h>
3
 
3
 
4
+#include "func.h"
5
+#include "node.h"
4
 #include "ply.h"
6
 #include "ply.h"
7
+#include "sym.h"
5
 
8
 
9
+#if 0
6
 /* pid */
10
 /* pid */
7
 
11
 
8
 int pid_generate_ir(prog_t *prog, node_t *node)
12
 int pid_generate_ir(prog_t *prog, node_t *node)
111
 
115
 
112
 type_t *ts_time[] = { &t_time_t, &t_time_func, NULL };
116
 type_t *ts_time[] = { &t_time_t, &t_time_func, NULL };
113
 
117
 
118
+#endif
119
+
120
+/* int global_resolve(prog_t *prog, node_t *n) */
121
+/* { */
122
+/* 	type_t **ts = NULL; */
123
+/* 	type_t *t; */
124
+/* 	int err; */
125
+
126
+/* 	if (!strcmp(n->ident, "pid")) { */
127
+/* 		ts = ts_pid; */
128
+/* 		t = &t_pid_func; */
129
+/* 	} else if (!strcmp(n->ident, "quantize")) { */
130
+/* 		ts = ts_quantize; */
131
+/* 		t = &t_quantize_func; */
132
+/* 	} else if (!strcmp(n->ident, "time")) { */
133
+/* 		ts = ts_time; */
134
+/* 		t = &t_time_func; */
135
+/* 	} else { */
136
+/* 		return -ENOENT; */
137
+/* 	} */
138
+
139
+/* 	if (ts) { */
140
+/* 		err = type_add_list(ts); */
141
+/* 		if (err) */
142
+/* 			return err; */
143
+/* 	} */
144
+
145
+/* 	n->type = t; */
146
+/* 	return sym_add(prog->locals, n->ident, t, &n->sym); */
147
+/* } */
148
+
149
+static const struct func global_funcs[] = {
150
+
151
+	/* block */
152
+	{ .name = "{}", },
153
+
154
+	{ .name = "+", },
155
+	{ .name = "-", },
156
+	
157
+	{ .name = "=", },
158
+	{ .name = "[]", },
159
+
160
+	{ .name = "pid", },
161
+	{ .name = "time", },
162
+
163
+	{ .name = "quantize", },
164
+	
165
+	{ .name = NULL }
166
+};
167
+
168
+static const struct func global_num_func = {
169
+	.name = ":num",
170
+};
171
+
172
+static const struct func global_string_func = {
173
+	.name = ":string",
174
+};
175
+
176
+static const struct func global_ident_func = {
177
+	.name = ":ident",
178
+};
114
 
179
 
115
-int global_resolve(prog_t *prog, node_t *n)
180
+int global_sym_alloc(struct prog *prog, struct node *n)
116
 {
181
 {
117
-	type_t **ts = NULL;
118
-	type_t *t;
119
-	int err;
120
-
121
-	if (!strcmp(n->ident, "pid")) {
122
-		ts = ts_pid;
123
-		t = &t_pid_func;
124
-	} else if (!strcmp(n->ident, "quantize")) {
125
-		ts = ts_quantize;
126
-		t = &t_quantize_func;
127
-	} else if (!strcmp(n->ident, "time")) {
128
-		ts = ts_time;
129
-		t = &t_time_func;
130
-	} else {
131
-		return -ENOENT;
132
-	}
182
+	const struct func *func;
133
 
183
 
134
-	if (ts) {
135
-		err = type_add_list(ts);
136
-		if (err)
137
-			return err;
184
+	switch (n->ntype) {
185
+	case N_EXPR:
186
+		for (func = global_funcs; func->name; func++) {
187
+			if (strcmp(func->name, n->expr.func))
188
+				continue;
189
+
190
+			n->sym = sym_alloc(prog->locals, n, func);
191
+			return 0;
192
+		}
193
+
194
+		return -ENOENT;
195
+	case N_IDENT:
196
+		n->sym = sym_alloc(prog->globals, n, &global_ident_func);
197
+		return 0;
198
+	case N_NUM:
199
+		n->sym = sym_alloc(prog->locals, n, &global_num_func);
200
+		return 0;
201
+	case N_STRING:
202
+		n->sym = sym_alloc(prog->locals, n, &global_string_func);
203
+		return 0;
138
 	}
204
 	}
139
 
205
 
140
-	n->type = t;
141
-	return sym_add(prog->locals, n->ident, t, &n->sym);
206
+	return -ENOENT;
142
 }
207
 }
143
 
208
 
144
-int global_probe(prog_t *prog)
209
+int global_probe(struct prog *prog)
145
 {
210
 {
146
 	return 0;
211
 	return 0;
147
 }
212
 }
148
 
213
 
149
-provider_t global = {
214
+struct provider global = {
150
 	.name = ":",
215
 	.name = ":",
151
 
216
 
152
-	.resolve = global_resolve,
217
+	.sym_alloc = global_sym_alloc,
153
 	.probe = global_probe,
218
 	.probe = global_probe,
154
 };
219
 };
155
 
220
 

+ 2 - 0
ir.c

1
+#if 0
1
 #include <assert.h>
2
 #include <assert.h>
2
 #include <inttypes.h>
3
 #include <inttypes.h>
3
 #include <stdio.h>
4
 #include <stdio.h>
352
 	ir->next_label = -1;
353
 	ir->next_label = -1;
353
 	return ir;
354
 	return ir;
354
 }
355
 }
356
+#endif

+ 87 - 81
kprobe.c

10
 struct kprobe {
10
 struct kprobe {
11
 };
11
 };
12
 
12
 
13
-static int kprobe_ir_prologue(prog_t *prog)
13
+/* static int kprobe_ir_prologue(prog_t *prog) */
14
+/* { */
15
+/* 	sym_t *ctx = sym_get(prog->locals, "ctx"); */
16
+
17
+/* 	if (!ctx) */
18
+/* 		return 0; */
19
+
20
+/* 	irs_alloc_reg(&ctx->irs, prog->ir); */
21
+
22
+/* 	/\* kernel sets r1 to the address of the context *\/ */
23
+/* 	ir_emit_insn(prog->ir, MOV(0, 0), ctx->irs.reg, BPF_REG_1); */
24
+/* 	return 0; */
25
+/* } */
26
+
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
+/* } */
33
+
34
+/* static int kprobe_rewrite_arg(prog_t *prog, node_t *n) */
35
+/* { */
36
+/* 	const char *reg; */
37
+/* 	int arg = n->ident[3] - '0'; */
38
+/* 	node_t *new, *ctx; */
39
+
40
+/* 	reg = arch_register_argument(arg); */
41
+/* 	if (!reg) { */
42
+/* 		node_print(n, stderr); */
43
+/* 		fputs(": the location of this argument is unknown\n", stderr); */
44
+/* 		/\* TODO: add ABI mappings for specifying arguments */
45
+/* 		 * passed on the stack. *\/ */
46
+/* 		return -EINVAL; */
47
+/* 	} */
48
+
49
+/* 	ctx = node_ident("ctx"); */
50
+
51
+/* 	/\* argN => (*ctx).REG *\/ */
52
+/* 	new = node_vlist(node_keyword('.', 0), */
53
+/* 			 node_vlist(node_keyword('*', 0), */
54
+/* 				    ctx, */
55
+/* 				    NULL), */
56
+/* 			 node_string(reg), */
57
+/* 			 NULL); */
58
+
59
+/* 	ctx->type = type_ptr_of(&t_pt_regs); */
60
+/* 	new->type = n->type; */
61
+/* 	new->list->type = &t_void; */
62
+/* 	new->list->next->type = &t_pt_regs; */
63
+/* 	new->list->next->list->type = &t_void; */
64
+/* 	node_replace(n, new); */
65
+
66
+/* 	return sym_add(prog->locals, ctx->ident, ctx->type, &ctx->sym); */
67
+/* } */
68
+
69
+/* static int kprobe_rewrite_node(prog_t *prog, node_t *n) */
70
+/* { */
71
+/* 	if ((n->ntype == N_IDENT) && is_arg(n->ident)) */
72
+/* 		return kprobe_rewrite_arg(prog, n); */
73
+
74
+/* 	return 0; */
75
+/* } */
76
+
77
+/* static int kprobe_resolve(prog_t *prog, node_t *n) */
78
+/* { */
79
+/* 	type_t *t; */
80
+
81
+/* 	if (is_arg(n->ident)) */
82
+/* 		t = &t_ulong; */
83
+/* 	else if (!strcmp(n->ident, "ctx")) */
84
+/* 		t = type_ptr_of(&t_pt_regs); */
85
+/* 	else */
86
+/* 		return -ENOENT; */
87
+
88
+/* 	n->type = t; */
89
+/* 	return sym_add(prog->locals, n->ident, t, &n->sym); */
90
+/* } */
91
+
92
+static int kprobe_sym_alloc(struct prog *prog, struct node *n)
14
 {
93
 {
15
-	sym_t *ctx = sym_get(prog->locals, "ctx");
16
-
17
-	if (!ctx)
18
-		return 0;
19
-
20
-	irs_alloc_reg(&ctx->irs, prog->ir);
21
-
22
-	/* kernel sets r1 to the address of the context */
23
-	ir_emit_insn(prog->ir, MOV(0, 0), ctx->irs.reg, BPF_REG_1);
24
-	return 0;
25
-}
26
-
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
-}
33
-
34
-static int kprobe_rewrite_arg(prog_t *prog, node_t *n)
35
-{
36
-	const char *reg;
37
-	int arg = n->ident[3] - '0';
38
-	node_t *new, *ctx;
39
-
40
-	reg = arch_register_argument(arg);
41
-	if (!reg) {
42
-		node_print(n, stderr);
43
-		fputs(": the location of this argument is unknown\n", stderr);
44
-		/* TODO: add ABI mappings for specifying arguments
45
-		 * passed on the stack. */
46
-		return -EINVAL;
47
-	}
48
-
49
-	ctx = node_ident("ctx");
50
-
51
-	/* argN => (*ctx).REG */
52
-	new = node_vlist(node_keyword('.', 0),
53
-			 node_vlist(node_keyword('*', 0),
54
-				    ctx,
55
-				    NULL),
56
-			 node_string(reg),
57
-			 NULL);
58
-
59
-	ctx->type = type_ptr_of(&t_pt_regs);
60
-	new->type = n->type;
61
-	new->list->type = &t_void;
62
-	new->list->next->type = &t_pt_regs;
63
-	new->list->next->list->type = &t_void;
64
-	node_replace(n, new);
65
-
66
-	return sym_add(prog->locals, ctx->ident, ctx->type, &ctx->sym);
67
-}
68
-
69
-static int kprobe_rewrite_node(prog_t *prog, node_t *n)
70
-{
71
-	if ((n->ntype == N_IDENT) && is_arg(n->ident))
72
-		return kprobe_rewrite_arg(prog, n);
73
-
74
-	return 0;
75
-}
76
-
77
-static int kprobe_resolve(prog_t *prog, node_t *n)
78
-{
79
-	type_t *t;
80
-
81
-	if (is_arg(n->ident))
82
-		t = &t_ulong;
83
-	else if (!strcmp(n->ident, "ctx"))
84
-		t = type_ptr_of(&t_pt_regs);
85
-	else
86
-		return -ENOENT;
87
-
88
-	n->type = t;
89
-	return sym_add(prog->locals, n->ident, t, &n->sym);
94
+	return -ENOENT;
90
 }
95
 }
91
 
96
 
92
-static int kprobe_probe(prog_t *prog)
97
+static int kprobe_probe(struct prog *prog)
93
 {
98
 {
94
 	struct kprobe *kp;
99
 	struct kprobe *kp;
95
 
100
 
100
 	return 0;
105
 	return 0;
101
 }
106
 }
102
 
107
 
103
-provider_t kprobe = {
108
+struct provider kprobe = {
104
 	.name = "kprobe",
109
 	.name = "kprobe",
105
 
110
 
106
-	.ir_prologue = kprobe_ir_prologue,
107
-	.rewrite_node = kprobe_rewrite_node,
108
-	.resolve = kprobe_resolve,
111
+	/* .ir_prologue = kprobe_ir_prologue, */
112
+	/* .rewrite_node = kprobe_rewrite_node, */
113
+	/* .resolve = kprobe_resolve, */
114
+	.sym_alloc = kprobe_sym_alloc,
109
 	.probe = kprobe_probe,
115
 	.probe = kprobe_probe,
110
 };
116
 };
111
 
117
 

+ 23 - 0
node.c

5
 #include <stdarg.h>
5
 #include <stdarg.h>
6
 #include <stdio.h>
6
 #include <stdio.h>
7
 #include <stdlib.h>
7
 #include <stdlib.h>
8
+#include <string.h>
8
 
9
 
9
 #include "node.h"
10
 #include "node.h"
10
 
11
 
85
 	fputc('\n', fp);		
86
 	fputc('\n', fp);		
86
 }
87
 }
87
 
88
 
89
+void node_error(struct node *n, FILE *fp, const char *fmt, ...)
90
+{
91
+	va_list ap;
92
+
93
+	node_print(n, fp);
94
+	fputs(": ", fp);
95
+
96
+	va_start(ap, fmt);
97
+	vfprintf(fp, fmt, ap);
98
+	va_end(ap);
99
+}
88
 
100
 
89
 int node_walk(struct node *n,
101
 int node_walk(struct node *n,
90
 	      int (*pre)(struct node *, void *),
102
 	      int (*pre)(struct node *, void *),
130
 	return 0;
142
 	return 0;
131
 }
143
 }
132
 
144
 
145
+/* helpers */
146
+
147
+int node_is_block(struct node *n)
148
+{
149
+	if (!n || (n->ntype != N_EXPR))
150
+		return 0;
151
+
152
+	return !strcmp(n->expr.func, "{}");
153
+}
154
+
155
+
133
 /* constructors */
156
 /* constructors */
134
 
157
 
135
 static struct node *node_new(enum ntype ntype)
158
 static struct node *node_new(enum ntype ntype)

+ 4 - 7
node.h

17
 struct node {
17
 struct node {
18
 	struct node *next, *prev, *up;
18
 	struct node *next, *prev, *up;
19
 
19
 
20
+	struct sym *sym;
21
+
20
 	enum ntype ntype;
22
 	enum ntype ntype;
21
 
23
 
22
 	union {
24
 	union {
40
 void node_print(struct node *n, FILE *fp);
42
 void node_print(struct node *n, FILE *fp);
41
 void node_dump (struct node *n, FILE *fp);
43
 void node_dump (struct node *n, FILE *fp);
42
 
44
 
45
+void node_error(struct node *n, FILE *fp, const char *fmt, ...);
43
 
46
 
44
 typedef int (*nwalk_fn)(struct node *, void *);
47
 typedef int (*nwalk_fn)(struct node *, void *);
45
 int node_walk(struct node *n, nwalk_fn pre, nwalk_fn post, void *ctx);
48
 int node_walk(struct node *n, nwalk_fn pre, nwalk_fn post, void *ctx);
57
 
60
 
58
 /* helpers */
61
 /* helpers */
59
 
62
 
60
-static inline int node_is_block(struct node *n)
61
-{
62
-	if (!n || (n->ntype != N_EXPR))
63
-		return 0;
64
-
65
-	return n->expr.func[0] == '\0';
66
-}
63
+int node_is_block(struct node *n);
67
 
64
 
68
 #define node_expr_foreach(_expr, _arg) \
65
 #define node_expr_foreach(_expr, _arg) \
69
 	for ((_arg) = (_expr)->expr.args; (_arg); (_arg) = (_arg)->next)
66
 	for ((_arg) = (_expr)->expr.args; (_arg); (_arg) = (_arg)->next)

+ 65 - 54
ply.c

4
 #include <stdlib.h>
4
 #include <stdlib.h>
5
 #include <string.h>
5
 #include <string.h>
6
 
6
 
7
-#include "ply.h"
8
 #include "node.h"
7
 #include "node.h"
8
+#include "ply.h"
9
+#include "sym.h"
9
 
10
 
10
-/* struct providers { */
11
-/* 	provider_t **prov; */
12
-/* 	size_t len; */
13
-/* } providers; */
11
+struct providers {
12
+	struct provider **ps;
13
+	size_t len;
14
+} providers;
14
 
15
 
15
-/* provider_t *provider_get(const char *name) */
16
-/* { */
17
-/* 	size_t i; */
16
+#define providers_foreach(_ps, _p) \
17
+	for((_p) = (_ps)->ps; (_p) < &(_ps)->ps[(_ps)->len]; (_p)++)
18
 
18
 
19
-/* 	for (i = 0; i < providers.len; i++) { */
20
-/* 		if (strstr(providers.prov[i]->name, name) */
21
-/* 		    == providers.prov[i]->name) */
22
-/* 			return providers.prov[i]; */
23
-/* 	} */
19
+struct provider *provider_get(const char *name)
20
+{
21
+	struct provider **p;
24
 
22
 
25
-/* 	return NULL; */
26
-/* } */
23
+	providers_foreach(&providers, p) {
24
+		if (strstr((*p)->name, name) == (*p)->name)
25
+			return *p;
26
+	}
27
 
27
 
28
-/* void provider_register(provider_t *prov) */
29
-/* { */
30
-/* 	assert(prov); */
31
-/* 	assert(prov->probe); */
32
-/* 	assert(prov->resolve); */
28
+	return NULL;
29
+}
30
+
31
+void provider_register(struct provider *p)
32
+{
33
+	assert(p);
34
+	assert(p->probe);
35
+	assert(p->sym_alloc);
33
 
36
 
34
-/* 	providers.prov = realloc(providers.prov, */
35
-/* 				 ++providers.len * sizeof(*providers.prov)); */
37
+	providers.ps = realloc(providers.ps,
38
+				 ++providers.len * sizeof(*providers.ps));
36
 
39
 
37
-/* 	providers.prov[providers.len - 1] = prov; */
38
-/* } */
40
+	providers.ps[providers.len - 1] = p;
41
+}
39
 
42
 
40
 struct pass {
43
 struct pass {
41
 	int (*run)(struct pass *, struct ctx *);
44
 	int (*run)(struct pass *, struct ctx *);
44
 };
47
 };
45
 
48
 
46
 
49
 
47
-/* symtab_t globals = { .sym = NULL, .len = 0 }; */
50
+struct symtab syms = { .syms = NULL, .len = 0 };
48
 /* symtab_t locals = { .sym = NULL, .len = 0 }; */
51
 /* symtab_t locals = { .sym = NULL, .len = 0 }; */
49
 
52
 
50
 struct ctx *ctx_get(void)
53
 struct ctx *ctx_get(void)
53
 	struct prog *prog;
56
 	struct prog *prog;
54
 
57
 
55
 	ctx = calloc(1, sizeof(*ctx));
58
 	ctx = calloc(1, sizeof(*ctx));
56
-	/* ctx->globals = calloc(1, sizeof(*ctx->globals)); */
59
+	ctx->globals = calloc(1, sizeof(*ctx->globals));
57
 
60
 
58
 	ctx->progs = calloc(3, sizeof(*ctx->progs));
61
 	ctx->progs = calloc(3, sizeof(*ctx->progs));
59
 
62
 
60
 	/* PROBE0 */
63
 	/* PROBE0 */
61
 	prog = calloc(1, sizeof(*prog));
64
 	prog = calloc(1, sizeof(*prog));
62
-	/* prog->locals = calloc(1, sizeof(*prog->locals)); */
63
-	/* prog->globals = ctx->globals; */
65
+	prog->locals = calloc(1, sizeof(*prog->locals));
66
+	prog->globals = ctx->globals;
64
 
67
 
65
 	prog->probe = "k:SyS_read";
68
 	prog->probe = "k:SyS_read";
66
 
69
 
70
 	 * }
73
 	 * }
71
 	 */
74
 	 */
72
 	prog->ast =
75
 	prog->ast =
73
-		node_expr("",
76
+		node_expr("{}",
74
 			  node_expr("=",
77
 			  node_expr("=",
75
 				    node_expr("[]",
78
 				    node_expr("[]",
76
 					      node_ident("@t"),
79
 					      node_ident("@t"),
87
 				    NULL),
90
 				    NULL),
88
 			  NULL);
91
 			  NULL);
89
 
92
 
90
-	/* prog->provider = provider_get("k"); */
91
-	/* prog->provider->probe(prog); */
93
+	prog->provider = provider_get("k");
94
+	prog->provider->probe(prog);
92
 	/* prog->ir = ir_new(); */
95
 	/* prog->ir = ir_new(); */
93
 	ctx->progs[0] = prog;
96
 	ctx->progs[0] = prog;
94
 
97
 
95
 	/* PROBE1 */
98
 	/* PROBE1 */
96
 	prog = calloc(1, sizeof(*prog));
99
 	prog = calloc(1, sizeof(*prog));
97
-	/* prog->locals = calloc(1, sizeof(*prog->locals)); */
98
-	/* prog->globals = ctx->globals; */
100
+	prog->locals = calloc(1, sizeof(*prog->locals));
101
+	prog->globals = ctx->globals;
99
 
102
 
100
 	/* TODO: k -> kret */
103
 	/* TODO: k -> kret */
101
 	prog->probe = "k:SyS_read2"; 
104
 	prog->probe = "k:SyS_read2"; 
114
 				    NULL),
117
 				    NULL),
115
 			  NULL);
118
 			  NULL);
116
 
119
 
117
-	/* prog->provider = provider_get("k"); */
118
-	/* prog->provider->probe(prog); */
120
+	prog->provider = provider_get("k");
121
+	prog->provider->probe(prog);
119
 	/* prog->ir = ir_new(); */
122
 	/* prog->ir = ir_new(); */
120
 	ctx->progs[1] = prog;
123
 	ctx->progs[1] = prog;
121
 
124
 
123
 }
126
 }
124
 
127
 
125
 
128
 
126
-/* int pass_resolve_symbols(node_t *n, void *_prog) */
127
-/* { */
128
-/* 	struct prog *prog = _prog; */
129
-/* 	provider_t *global = provider_get(":"); */
130
-/* 	node_t *op; */
131
-/* 	int err; */
129
+int pass_sym_alloc(struct node *n, void *_prog)
130
+{
131
+	struct prog *prog = _prog;
132
+	struct provider *global = provider_get(":");
133
+	int err = 0;
132
 
134
 
133
-/* 	if (n->ntype != N_IDENT) */
134
-/* 		return 0; */
135
+	switch (n->ntype) {
136
+	case N_EXPR:
137
+	case N_IDENT:
138
+		err = prog->provider->sym_alloc(prog, n);
139
+		if (!err || (err != -ENOENT))
140
+			break;
135
 
141
 
136
-/* 	err = prog->provider->resolve(prog, n); */
137
-/* 	if (!err || (err != -ENOENT)) */
138
-/* 		return err; */
142
+		err = global->sym_alloc(prog, n);
143
+		break;
144
+	case N_NUM:
145
+	case N_STRING:
146
+		err = global->sym_alloc(prog, n);
147
+	}
139
 
148
 
140
-/* 	err = global->resolve(prog, n); */
141
-/* 	if (!err || (err != -ENOENT)) */
142
-/* 		return err; */
149
+	if (err) {
150
+		if (n->ntype == N_EXPR)
151
+			node_error(n, stderr, "unknown function '%s'",
152
+				   n->expr.func);
153
+		else
154
+			assert(0);
155
+	}
143
 
156
 
144
-/* 	/\* neither provider identifier nor global ditto => user */
145
-/* 	 * variable, add it as a global symbol of unknown type. *\/ */
146
-/* 	return sym_add(prog->globals, n->ident, NULL, &n->sym); */
147
-/* } */
157
+	return err;
158
+}
148
 
159
 
149
 /* int infer_type_list(struct prog *prog, node_t *n) */
160
 /* int infer_type_list(struct prog *prog, node_t *n) */
150
 /* { */
161
 /* { */
487
 }
498
 }
488
 
499
 
489
 struct pass passes[] = {
500
 struct pass passes[] = {
490
-	/* { .run = run_walk, .post = pass_resolve_symbols }, */
501
+	{ .run = run_walk, .post = pass_sym_alloc },
491
 	/* { .run = run_walk, .post = pass_infer_types }, */
502
 	/* { .run = run_walk, .post = pass_infer_types }, */
492
 	/* { .run = run_walk, .post = pass_infer_types }, */
503
 	/* { .run = run_walk, .post = pass_infer_types }, */
493
 	/* { .run = run_walk, .post = pass_infer_types }, */
504
 	/* { .run = run_walk, .post = pass_infer_types }, */

+ 20 - 12
ply.h

2
 #define _PLY_H
2
 #define _PLY_H
3
 
3
 
4
 struct node;
4
 struct node;
5
+struct symtab;
5
 
6
 
6
 struct prog {
7
 struct prog {
7
 	const char *probe;
8
 	const char *probe;
8
 	struct node *ast;
9
 	struct node *ast;
9
 
10
 
11
+	struct symtab *locals;
12
+	struct symtab *globals;
13
+
10
 	/* symtab_t *locals; */
14
 	/* symtab_t *locals; */
11
 	/* symtab_t *globals; */
15
 	/* symtab_t *globals; */
12
 
16
 
13
-	/* provider_t *provider; */
14
-	/* void *provider_data; */
17
+	struct provider *provider;
18
+	void *provider_data;
15
 
19
 
16
 	/* ir_t *ir; */
20
 	/* ir_t *ir; */
17
 };
21
 };
19
 struct ctx {
23
 struct ctx {
20
 	struct prog **progs;
24
 	struct prog **progs;
21
 
25
 
22
-	/* symtab_t *globals; */
26
+	struct symtab *globals;
23
 };
27
 };
24
 
28
 
25
-/* struct provider { */
26
-/* 	const char *name; */
27
 
29
 
28
-/* 	int (*probe)(prog_t *); */
29
-/* 	int (*resolve)(prog_t *, node_t *); */
30
-/* 	int (*rewrite_node)(prog_t *, node_t *); */
31
-/* 	int (*ir_prologue)(prog_t *); */
32
-/* 	int (*ir_epilogue)(prog_t *); */
33
-/* }; */
30
+struct func;
31
+
32
+struct provider {
33
+	const char *name;
34
+
35
+	int (*probe)(struct prog *);
36
+	int (*sym_alloc)(struct prog *, struct node *);
37
+	/* int (*resolve)(struct prog *, struct node *); */
38
+	/* int (*rewrite_node)(struct prog *, struct node *); */
39
+	/* int (*ir_prologue)(struct prog *); */
40
+	/* int (*ir_epilogue)(struct prog *); */
41
+};
34
 
42
 
35
-/* void provider_register(provider_t *prov); */
43
+void provider_register(struct provider *p);
36
 
44
 
37
 #endif	/* _PLY_H */
45
 #endif	/* _PLY_H */

+ 44 - 39
sym.c

4
 #include <stdlib.h>
4
 #include <stdlib.h>
5
 #include <string.h>
5
 #include <string.h>
6
 
6
 
7
+#include "node.h"
7
 #include "sym.h"
8
 #include "sym.h"
9
+#include "type.h"
8
 
10
 
9
-sym_t *sym_get(symtab_t *st, const char *name)
11
+static struct sym *__sym_alloc(struct symtab *st, const char *name,
12
+			       const struct func *func)
10
 {
13
 {
11
-	size_t i;
14
+	struct sym *sym;
12
 
15
 
13
-	for (i = 0; i < st->len; i++) {
14
-		if (!strcmp(st->sym[i]->name, name))
15
-			return st->sym[i];
16
-	}
16
+	st->syms = realloc(st->syms, ++st->len * sizeof(*st->syms));
17
+	assert(st->syms);
17
 
18
 
18
-	return NULL;
19
+	st->syms[st->len - 1] = calloc(1, sizeof(struct sym));
20
+	sym = st->syms[st->len - 1];
21
+	sym->st   = st;
22
+	sym->name = name;
23
+	sym->func = func;
24
+	return 0;
19
 }
25
 }
20
 
26
 
21
-int sym_add(symtab_t *st, const char *name, type_t *type, sym_t **new)
27
+static struct sym *sym_alloc_ident(struct symtab *st, struct node *n,
28
+				   const struct func *func)
22
 {
29
 {
23
-	sym_t *sym;
24
-
25
-	sym = sym_get(st, name);
26
-	if (sym) {
27
-		/* if there is no type info, accept anything */
28
-		if (!sym->type)
29
-			sym->type = type;
30
-		/* otherwise, if specified, it must match */
31
-		else if (type && !type_equal(sym->type, type))
32
-			return -EINVAL;
30
+	struct sym **sym;
33
 
31
 
34
-		goto found;
32
+	symtab_foreach(st, sym) {
33
+		if (!strcmp((*sym)->name, n->ident.name))
34
+			return *sym;
35
 	}
35
 	}
36
 
36
 
37
-	st->sym = realloc(st->sym, ++st->len * sizeof(*st->sym));
38
-	assert(st->sym);
37
+	return __sym_alloc(st, n->ident.name, func);
38
+}
39
 
39
 
40
-	st->sym[st->len - 1] = calloc(1, sizeof(sym_t));
41
-	sym = st->sym[st->len - 1];
42
-	sym->st   = st;
43
-	sym->name = name;
44
-	sym->type = type;
45
-found:
46
-	if (new)
47
-		*new = sym;
48
-	return 0;
40
+struct sym *sym_alloc(struct symtab *st, struct node *n,
41
+		      const struct func *func)
42
+{
43
+	switch (n->ntype) {
44
+	case N_EXPR:
45
+	case N_NUM:
46
+	case N_STRING:
47
+		return __sym_alloc(st, NULL, func);
48
+	case N_IDENT:
49
+		return sym_alloc_ident(st, n, func);
50
+	}
51
+
52
+	assert(0);
53
+	return NULL;
49
 }
54
 }
50
 
55
 
51
-void sym_dump(sym_t *sym, FILE *fp)
56
+void sym_dump(struct sym *sym, FILE *fp)
52
 {
57
 {
53
-	fputs("\e[2m", fp);
54
-	type_dump(sym->type, fp);
55
-	fputs("\e[0m ", fp);
56
-	fputs(sym->name, fp);
58
+	type_dump(sym->type, sym->name, fp);
57
 }
59
 }
58
 
60
 
59
-void symtab_dump(symtab_t *st, FILE *fp)
61
+void symtab_dump(struct symtab *st, FILE *fp)
60
 {
62
 {
61
-	size_t i;
63
+	struct sym **sym;
64
+
65
+	symtab_foreach(st, sym) {
66
+		if (!(*sym)->name)
67
+			continue;
62
 
68
 
63
-	for (i = 0; i < st->len; i++) {
64
-		sym_dump(st->sym[i], fp);
69
+		sym_dump(*sym, fp);
65
 		fputc('\n', fp);
70
 		fputc('\n', fp);
66
 	}
71
 	}
67
 }
72
 }

+ 18 - 14
sym.h

3
 
3
 
4
 #include <stdint.h>
4
 #include <stdint.h>
5
 
5
 
6
-#include "ir.h"
7
-#include "type.h"
6
+struct symtab;
8
 
7
 
9
-typedef struct symtab symtab_t;
8
+struct type;
9
+struct func;
10
+
11
+struct sym {
12
+	struct symtab *st;
10
 
13
 
11
-typedef struct sym {
12
-	symtab_t *st;
13
 	const char *name;
14
 	const char *name;
14
-	type_t *type;
15
+	const struct func *func;
15
 
16
 
16
-	irstate_t irs;
17
-} sym_t;
17
+	struct type *type;
18
+	/* irstate_t irs; */
19
+};
18
 
20
 
19
 struct symtab {
21
 struct symtab {
20
-	sym_t **sym;
22
+	struct sym **syms;
21
 	size_t len;
23
 	size_t len;
22
 };
24
 };
23
 
25
 
24
-sym_t *sym_get(symtab_t *st, const char *name);
25
-int    sym_add(symtab_t *st, const char *name, type_t *type, sym_t **new);
26
+#define symtab_foreach(_st, _sym) \
27
+	for((_sym) = (_st)->syms; (_sym) < &(_st)->syms[(_st)->len]; (_sym)++)
28
+
29
+struct sym *sym_alloc(struct symtab *st, struct node *n,
30
+		      const struct func *func);
26
 
31
 
27
-void sym_dump(sym_t *sym, FILE *fp);
28
-void symtab_dump(symtab_t *st, FILE *fp);
32
+void sym_dump(struct sym *sym, FILE *fp);
33
+void symtab_dump(struct symtab *st, FILE *fp);
29
 
34
 
30
-//#define symtab_foreach(_st, _sym) for((_sym) = (_st)->sym; (_sym) < (_st)->sym[(_st)->len]; (_sym)++)
31
 
35
 
32
 #endif	/* _PLY_SYM_H */
36
 #endif	/* _PLY_SYM_H */

+ 35 - 47
type.c

6
 
6
 
7
 #include "type.h"
7
 #include "type.h"
8
 
8
 
9
-void type_dump_func(struct type *t, FILE *fp)
9
+static void type_dump_func(struct type *t, const char *name, FILE *fp)
10
 {
10
 {
11
 	struct tfield *arg;
11
 	struct tfield *arg;
12
 
12
 
13
-	type_dump(t->func.type, fp);
14
-	fputs(" (*)(", fp);
13
+	type_dump(t->func.type, NULL, fp);
14
+	fprintf(fp, " (*%s)(", name ? : "");
15
 
15
 
16
 	if (!t->func.args) {
16
 	if (!t->func.args) {
17
 		fputs("void)", fp);
17
 		fputs("void)", fp);
22
 		if (arg != t->func.args)
22
 		if (arg != t->func.args)
23
 			fputs(", ", fp);
23
 			fputs(", ", fp);
24
 
24
 
25
-		type_dump(arg->type, fp);
25
+		type_dump(arg->type, NULL, fp);
26
 	}
26
 	}
27
 
27
 
28
 	fputc(')', fp);
28
 	fputc(')', fp);
29
 }
29
 }
30
 
30
 
31
-void type_dump(struct type *t, FILE *fp)
31
+void type_dump(struct type *t, const char *name, FILE *fp)
32
 {
32
 {
33
 	if (!t) {
33
 	if (!t) {
34
 		fputs("<NONE>", fp);
34
 		fputs("<NONE>", fp);
37
 
37
 
38
 	switch (t->ttype){
38
 	switch (t->ttype){
39
 	case T_VOID:
39
 	case T_VOID:
40
-		fputs("void", fp);
40
+		fprintf(fp, "void%s%s", name? " " : "", name ? : "");
41
 		break;
41
 		break;
42
 	case T_TYPEDEF:
42
 	case T_TYPEDEF:
43
-		fputs(t->tdef.name, fp);
43
+		fprintf(fp, "%s%s%s", t->tdef.name, name? " " : "", name ? : "");
44
 		break;
44
 		break;
45
 	case T_SCALAR:
45
 	case T_SCALAR:
46
-		fputs(t->scalar.name, fp);
46
+		fprintf(fp, "%s%s%s", t->scalar.name, name? " " : "", name ? : "");
47
 		break;
47
 		break;
48
 	case T_POINTER:
48
 	case T_POINTER:
49
-		type_dump(t->ptr.type, fp);
50
-		fputs(" *", fp);
49
+		type_dump(t->ptr.type, NULL, fp);
50
+		fprintf(fp, " *%s", name ? : "");
51
 		break;
51
 		break;
52
 	case T_ARRAY:
52
 	case T_ARRAY:
53
-		type_dump(t->array.type, fp);
54
-		fprintf(fp, "[%zu]", t->array.len);
53
+		type_dump(t->array.type, NULL, fp);
54
+		fprintf(fp, "%s%s[%zu]", name ? " " : "", name? : "", t->array.len);
55
 		break;
55
 		break;
56
 	case T_STRUCT:
56
 	case T_STRUCT:
57
-		fputs("struct ", fp);
58
-		fputs(t->sou.name, fp);
57
+		fprintf(fp, "struct %s%s%s", t->sou.name, name? " " : "", name? : "");
59
 		break;
58
 		break;
60
-	/* case T_UNION: */
61
-	/* 	fputs("union ", fp); */
62
-	/* 	fputs(t->sou.name, fp); */
63
-	/* 	break; */
64
 	case T_FUNC:
59
 	case T_FUNC:
65
-		type_dump_func(t, fp);
60
+		type_dump_func(t, name, fp);
66
 		break;
61
 		break;
67
 	case T_MAP:
62
 	case T_MAP:
68
-		fputs("map [", fp);
69
-		type_dump(t->map.ktype, fp);
63
+		fprintf(fp, "map %s[", name ? : "");
64
+		type_dump(t->map.ktype, NULL, fp);
70
 		fputs("] ", fp);
65
 		fputs("] ", fp);
71
-		type_dump(t->map.vtype, fp);
66
+		type_dump(t->map.vtype, NULL, fp);
72
 		break;
67
 		break;
73
 	}
68
 	}
74
 }
69
 }
75
 
70
 
76
-void type_dump_cdecl_sou(struct type *t, FILE *fp)
71
+static void type_dump_decl_sou(struct type *t, FILE *fp)
77
 {
72
 {
78
 	struct tfield *f;
73
 	struct tfield *f;
79
 
74
 
80
-	type_dump(t, fp);
75
+	type_dump(t, NULL, fp);
81
 	fputs(" {\n", fp);
76
 	fputs(" {\n", fp);
82
 	for (f = t->sou.fields; f->type; f++) {
77
 	for (f = t->sou.fields; f->type; f++) {
83
 		fputc('\t', fp);
78
 		fputc('\t', fp);
84
-		type_dump(f->type, fp);
79
+		type_dump(f->type, NULL, fp);
85
 		fprintf(fp, " %s;\n", f->name);
80
 		fprintf(fp, " %s;\n", f->name);
86
 	}
81
 	}
87
 	fputs("}", fp);
82
 	fputs("}", fp);
88
 }
83
 }
89
 
84
 
90
-void type_dump_cdecl(struct type *t, FILE *fp)
85
+void type_dump_decl(struct type *t, FILE *fp)
91
 {
86
 {
92
 	switch (t->ttype) {
87
 	switch (t->ttype) {
93
 	case T_TYPEDEF:
88
 	case T_TYPEDEF:
94
 		fputs("typedef ", fp);
89
 		fputs("typedef ", fp);
95
-		type_dump(t->tdef.type, fp);
90
+		type_dump(t->tdef.type, NULL, fp);
96
 		fprintf(fp, " %s", t->tdef.name);
91
 		fprintf(fp, " %s", t->tdef.name);
97
 		break;
92
 		break;
98
 
93
 
99
 	case T_STRUCT:
94
 	case T_STRUCT:
100
-	/* case T_UNION: */
101
-		type_dump_cdecl_sou(t, fp);
95
+		type_dump_decl_sou(t, fp);
102
 		break;
96
 		break;
103
 
97
 
104
 	case T_VOID:
98
 	case T_VOID:
107
 	case T_ARRAY:
101
 	case T_ARRAY:
108
 	case T_MAP:
102
 	case T_MAP:
109
 	case T_FUNC:
103
 	case T_FUNC:
110
-		type_dump(t, fp);
104
+		type_dump(t, NULL, fp);
111
 		break;
105
 		break;
112
 	}
106
 	}
113
 }
107
 }
114
 
108
 
115
-/* void types_dump_cdecl(FILE *fp) */
116
-/* { */
117
-/* 	size_t i; */
118
-
119
-/* 	for (i = 0; i < types.len; i++) { */
120
-/* 		struct type *t = types.type[i]; */
121
-
122
-/* 		type_dump_cdecl(t, stdout); */
123
-/* 		printf(" <sz:0x%zx>\n", t->size); */
124
-/* 	} */
125
-/* } */
126
-
127
-
128
 
109
 
129
 struct type *type_normalize(struct type *t)
110
 struct type *type_normalize(struct type *t)
130
 {
111
 {
216
 	return -EINVAL;
197
 	return -EINVAL;
217
 }
198
 }
218
 
199
 
200
+static size_t __padding(size_t offset, size_t align)
201
+{
202
+	size_t pad = align - (offset & (align - 1));
203
+
204
+	return (pad == align) ? 0 : pad;
205
+}
206
+
219
 ssize_t type_offset_size_of(struct type *t, const char *field)
207
 ssize_t type_offset_size_of(struct type *t, const char *field)
220
 {
208
 {
221
 	struct tfield *f;
209
 	struct tfield *f;
236
 		if (falign < 0)
224
 		if (falign < 0)
237
 			return falign;
225
 			return falign;
238
 
226
 
239
-		if (!t->sou.packed && (falign > 1))
240
-			offset += falign - (offset % falign);
227
+		if (!t->sou.packed)
228
+			offset += __padding(offset, falign);
241
 
229
 
242
 		if (field && !strcmp(f->name, field))
230
 		if (field && !strcmp(f->name, field))
243
 			return offset;
231
 			return offset;
248
 	if (field)
236
 	if (field)
249
 		return -ENOENT;
237
 		return -ENOENT;
250
 
238
 
251
-	if (!t->sou.packed && offset && (falign > 1))
252
-		offset += falign - (offset % falign);
239
+	if (!t->sou.packed)
240
+		offset += __padding(offset, type_alignof(t));
253
 
241
 
254
 	return offset;
242
 	return offset;
255
 	
243
 	

+ 2 - 2
type.h

81
 int type_equal     (struct type *a, struct type *b);
81
 int type_equal     (struct type *a, struct type *b);
82
 int type_compatible(struct type *a, struct type *b);
82
 int type_compatible(struct type *a, struct type *b);
83
 
83
 
84
-void type_dump      (struct type *t, FILE *fp);
85
-void type_dump_cdecl(struct type *t, FILE *fp);
84
+void type_dump     (struct type *t, const char *name, FILE *fp);
85
+void type_dump_decl(struct type *t, FILE *fp);
86
 
86
 
87
 ssize_t type_alignof(struct type *t);
87
 ssize_t type_alignof(struct type *t);
88
 ssize_t type_offsetof(struct type *t, const char *field);
88
 ssize_t type_offsetof(struct type *t, const char *field);

+ 2 - 1
type_test.c

1
-#include "type.h"
2
 #include "unittest.h"
1
 #include "unittest.h"
3
 
2
 
3
+#include "type.h"
4
+
4
 static int sizeof_basic(void *_null)
5
 static int sizeof_basic(void *_null)
5
 {
6
 {
6
 	struct type *voidp, *map;
7
 	struct type *voidp, *map;