Skip to content

Commit a9d3f60

Browse files
authored
Move the tinycc code as a plugin ##types
1 parent 90b7525 commit a9d3f60

File tree

7 files changed

+277
-175
lines changed

7 files changed

+277
-175
lines changed

dist/plugins-cfg/plugins.def.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
STATIC="
22
anal.null
3+
anal.tcc
34
anal.a2f
45
arch.6502
56
arch.cosmac

libr/anal/cparse.c

Lines changed: 43 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,190 +1,66 @@
11
/* radare - LGPL - Copyright 2013-2025 - pancake */
22

3-
#include <r_asm.h>
4-
#include "c/tcc.h"
5-
#include "c/tccgen.c"
6-
#include "c/tccpp.c"
7-
#include "c/libtcc.c"
8-
#define USE_R2 1
9-
#include <spp/spp.h>
3+
#include <r_anal.h>
104

11-
// used to pass anal and s1 to loader
12-
typedef struct {
13-
RAnal *anal;
14-
TCCState *s1;
15-
} LoadContext;
16-
17-
extern int tcc_sym_push(TCCState *s1, char *typename, int typesize, int meta);
18-
19-
/* parse C code and return it in key-value form */
20-
21-
static void __appendString(const char *msg, char **s) {
22-
if (!s) {
23-
printf ("%s\n", msg);
24-
} else if (*s) {
25-
char *p = malloc (strlen (msg) + strlen (*s) + 1);
26-
if (p) {
27-
strcpy (p, *s);
28-
free (*s);
29-
*s = p;
30-
strcpy (p + strlen (p), msg);
31-
}
32-
} else {
33-
*s = strdup (msg);
34-
}
35-
}
5+
R_IPI char* kvc_parse(const char* header_content, char **errmsg);
366

37-
static bool __typeLoad(void *p, const char *k, const char *v) {
38-
r_strf_buffer (128);
39-
if (!p) {
40-
return false;
41-
}
42-
int btype = 0;
43-
LoadContext *loader = (LoadContext *)p;
44-
RAnal *anal = loader->anal;
45-
TCCState *s1 = loader->s1;
46-
// TCCState *s1 = NULL; // XXX THIS WILL MAKE IT CRASH
47-
//r_cons_printf (cons, "tk %s=%s\n", k, v);
48-
// TODO: Add unions support
49-
if (!strncmp (v, "struct", 6) && strncmp (k, "struct.", 7)) {
50-
// structure
51-
btype = VT_STRUCT;
52-
const char *typename = k;
53-
int typesize = 0;
54-
// TODO: Add typesize here
55-
char* query = r_strf ("struct.%s", k);
56-
char *members = sdb_get (anal->sdb_types, query, 0);
57-
char *next, *ptr = members;
58-
if (members) {
59-
do {
60-
char *name = sdb_anext (ptr, &next);
61-
if (!name) {
62-
break;
63-
}
64-
query = r_strf ("struct.%s.%s", k, name);
65-
char *subtype = sdb_get (anal->sdb_types, query, 0);
66-
if (!subtype) {
67-
break;
7+
static RAnalPlugin *resolve_plugin (RAnal *anal, int type) {
8+
RAnalPlugin *p;
9+
RListIter *iter;
10+
const char *tpp = anal->opt.tparser;
11+
r_list_foreach (anal->plugins, iter, p) {
12+
if (!strcmp (tpp, p->meta.name)) {
13+
switch (type) {
14+
case 0:
15+
if (p->tparse_text) {
16+
return p;
6817
}
69-
char *tmp = strchr (subtype, ',');
70-
if (tmp) {
71-
*tmp++ = 0;
72-
tmp = strchr (tmp, ',');
73-
if (tmp) {
74-
*tmp++ = 0;
75-
}
76-
char *subname = tmp;
77-
// TODO: Go recurse here
78-
query = r_strf ("struct.%s.%s.meta", subtype, subname);
79-
btype = sdb_num_get (anal->sdb_types, query, 0);
80-
tcc_sym_push (s1, subtype, 0, btype);
18+
break;
19+
case 1:
20+
if (p->tparse_file) {
21+
return p;
8122
}
82-
free (subtype);
83-
ptr = next;
84-
} while (next);
85-
free (members);
86-
}
87-
tcc_sym_push (s1, (char *)typename, typesize, btype);
88-
}
89-
return true;
90-
}
91-
92-
static void __errorFunc(void *opaque, const char *msg) {
93-
__appendString (msg, opaque);
94-
char **p = (char **)opaque;
95-
if (p && *p) {
96-
int n = strlen(*p);
97-
char *ptr = malloc (n + 2);
98-
if (!ptr) {
99-
return;
23+
break;
24+
}
10025
}
101-
strcpy (ptr, *p);
102-
ptr[n] = '\n';
103-
ptr[n + 1] = 0;
104-
free (*p);
105-
*p = ptr;
10626
}
27+
return NULL;
10728
}
10829

109-
R_IPI char* kvc_parse(const char* header_content, char **errmsg);
110-
11130
R_API char *r_anal_cparse2(RAnal *anal, const char *code, char **error_msg) {
11231
return kvc_parse (code, error_msg);
11332
}
11433

115-
static TCCState *new_tcc(RAnal *anal) {
116-
TCCState *ts = tcc_new (anal->config->arch, anal->config->bits, anal->config->os);
117-
if (!ts) {
118-
ts = tcc_new (R_SYS_ARCH, R_SYS_BITS, R_SYS_OS);
119-
if (!ts) {
120-
R_LOG_ERROR ("Cannot instantiate TCC for given arch (%s)", anal->config->arch);
121-
return NULL;
122-
}
123-
}
124-
return ts;
125-
}
126-
12734
R_API char *r_anal_cparse_file(RAnal *anal, const char *path, const char *dir, char **error_msg) {
128-
if (anal->opt.newcparser) {
129-
char *code = r_file_slurp (path, NULL);
130-
if (code) {
131-
char *res = r_anal_cparse2 (anal, code, error_msg);
132-
free (code);
133-
return res;
134-
}
135-
}
136-
char *str = NULL;
137-
TCCState *s1 = new_tcc (anal);
138-
if (!s1) {
139-
return NULL;
140-
}
141-
tcc_set_callback (s1, &__appendString, &str);
142-
tcc_set_error_func (s1, (void *)error_msg, __errorFunc);
143-
144-
// load saved types from sdb into the tcc context
145-
LoadContext ctx = {anal, s1};
146-
sdb_foreach (anal->sdb_types, __typeLoad, (void *)&ctx);
147-
148-
char *d = strdup (dir);
149-
RList *dirs = r_str_split_list (d, ":", 0);
150-
RListIter *iter;
151-
char *di;
152-
bool found = false;
153-
r_list_foreach (dirs, iter, di) {
154-
if (tcc_add_file (s1, path, di) != -1) {
155-
found = true;
156-
break;
35+
if (anal->opt.tparser) {
36+
RAnalPlugin *p = resolve_plugin (anal, 1);
37+
if (p) {
38+
return p->tparse_file (anal, path, dir);
39+
} else {
40+
RAnalPlugin *p = resolve_plugin (anal, 0);
41+
if (p) {
42+
char *text = r_file_slurp (path, NULL);
43+
char *res = p->tparse_text (anal, text);
44+
free (text);
45+
return res;
46+
}
15747
}
15848
}
159-
if (!found) {
160-
R_FREE (str);
49+
char *code = r_file_slurp (path, NULL);
50+
if (code) {
51+
char *res = r_anal_cparse2 (anal, code, error_msg);
52+
free (code);
53+
return res;
16154
}
162-
r_list_free (dirs);
163-
free (d);
164-
tcc_delete (s1);
165-
return str;
55+
return NULL;
16656
}
16757

16858
R_API char *r_anal_cparse(RAnal *anal, const char *code, char **error_msg) {
169-
if (anal->opt.newcparser) {
170-
return r_anal_cparse2 (anal, code, error_msg);
171-
}
172-
char *str = NULL;
173-
TCCState *s1 = new_tcc (anal);
174-
if (!s1) {
175-
R_LOG_ERROR ("Cannot instantiate TCC for given arch (%s)", anal->config->arch);
176-
return NULL;
177-
}
178-
tcc_set_callback (s1, &__appendString, &str);
179-
tcc_set_error_func (s1, (void *)error_msg, __errorFunc);
180-
181-
// load saved types from sdb into the tcc context
182-
LoadContext ctx = {anal, s1};
183-
sdb_foreach (anal->sdb_types, __typeLoad, (void *)&ctx);
184-
185-
if (tcc_compile_string (s1, code) != 0) {
186-
R_FREE (str);
59+
if (anal->opt.tparser) {
60+
RAnalPlugin *p = resolve_plugin (anal, 0);
61+
if (p) {
62+
return p->tparse_text(anal, code);
63+
}
18764
}
188-
tcc_delete (s1);
189-
return str;
65+
return r_anal_cparse2 (anal, code, error_msg);
19066
}

0 commit comments

Comments
 (0)