Rizin
unix-like reverse engineering framework and cli tools
parse_dalvik_pseudo.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include <rz_lib.h>
9 #include <rz_util.h>
10 #include <rz_flag.h>
11 #include <rz_analysis.h>
12 #include <rz_parse.h>
13 
14 #include "parse_common.c"
15 
16 static RzList *dalvik_tokenize(const char *assembly, size_t length);
17 
18 static const RzPseudoGrammar dalvik_lexicon[] = {
19  RZ_PSEUDO_DEFINE_GRAMMAR("+iget-wide-volatile", "1 = (wide-volatile) 2 [3]"),
20  RZ_PSEUDO_DEFINE_GRAMMAR("+invoke-interface/range", "call 2 1"),
21  RZ_PSEUDO_DEFINE_GRAMMAR("+invoke-virtual-quick", "call 2 1"),
22  RZ_PSEUDO_DEFINE_GRAMMAR("add-double", "1 = (double)(2 + 3)"),
23  RZ_PSEUDO_DEFINE_GRAMMAR("add-double", "1 = 2 + 3"),
24  RZ_PSEUDO_DEFINE_GRAMMAR("add-double/2addr", "1 += (double)2"),
25  RZ_PSEUDO_DEFINE_GRAMMAR("add-int", "1 = (int)(2 + 3)"),
26  RZ_PSEUDO_DEFINE_GRAMMAR("add-int/2addr", "1 += 2"),
27  RZ_PSEUDO_DEFINE_GRAMMAR("add-int/lit16", "1 = 2 + 3"),
28  RZ_PSEUDO_DEFINE_GRAMMAR("add-int/lit8", "1 = 2 + 3"),
29  RZ_PSEUDO_DEFINE_GRAMMAR("add-long", "1 = 2 + 3"),
30  RZ_PSEUDO_DEFINE_GRAMMAR("aget", "1 = 2[3]"),
31  RZ_PSEUDO_DEFINE_GRAMMAR("aget-boolean", "1 = (boolean) 2[3]"),
32  RZ_PSEUDO_DEFINE_GRAMMAR("aget-byte", "1 = (byte) 2[3]"),
33  RZ_PSEUDO_DEFINE_GRAMMAR("aget-char", "1 = (char) 2[3]"),
34  RZ_PSEUDO_DEFINE_GRAMMAR("aget-object", "1 = (object) 2[3]"),
35  RZ_PSEUDO_DEFINE_GRAMMAR("aget-short", "1 = (short) 2[3]"),
36  RZ_PSEUDO_DEFINE_GRAMMAR("aget-wide", "1 = (wide) 2[3]"),
37  RZ_PSEUDO_DEFINE_GRAMMAR("and-byte", "1 &= (byte) 2"),
38  RZ_PSEUDO_DEFINE_GRAMMAR("and-int", "1 &= (int) 2"),
39  RZ_PSEUDO_DEFINE_GRAMMAR("and-long/2addr", "1 &= (long) 2"),
40  RZ_PSEUDO_DEFINE_GRAMMAR("aput", "2[3] = 1"),
41  RZ_PSEUDO_DEFINE_GRAMMAR("aput-boolean", "2[3] = (bool) 1"),
42  RZ_PSEUDO_DEFINE_GRAMMAR("aput-byte", "2[3] = (byte) 1"),
43  RZ_PSEUDO_DEFINE_GRAMMAR("aput-char", "2[3] = (char) 1"),
44  RZ_PSEUDO_DEFINE_GRAMMAR("aput-object", "2[3] = (object) 1"),
45  RZ_PSEUDO_DEFINE_GRAMMAR("aput-short", "2[3] = (short) 1"),
46  RZ_PSEUDO_DEFINE_GRAMMAR("aput-wide", "2[3] = (wide) 1"),
47  RZ_PSEUDO_DEFINE_GRAMMAR("array-length", "1 = Array.length (2)"),
48  RZ_PSEUDO_DEFINE_GRAMMAR("check-cast", "if (1 instanceof 2)"),
49  RZ_PSEUDO_DEFINE_GRAMMAR("cmp-int", "1 = (2 == 3)"),
50  RZ_PSEUDO_DEFINE_GRAMMAR("cmp-long", "1 = (2 == 3)"),
51  RZ_PSEUDO_DEFINE_GRAMMAR("cmpg-double", "1 = (2 == 3)"),
52  RZ_PSEUDO_DEFINE_GRAMMAR("cmpg-float", "1 = (2 == 3)"),
53  RZ_PSEUDO_DEFINE_GRAMMAR("cmpl-double", "1 = (double)(2 == 3)"),
54  RZ_PSEUDO_DEFINE_GRAMMAR("cmpl-float", "1 = (float)(2 == 3)"),
55  RZ_PSEUDO_DEFINE_GRAMMAR("cmpl-int", "1 = (int)(2 == 3)"),
56  RZ_PSEUDO_DEFINE_GRAMMAR("const", "1 = 2"),
57  RZ_PSEUDO_DEFINE_GRAMMAR("const-class", "1 = (class) 2"),
58  RZ_PSEUDO_DEFINE_GRAMMAR("const-string", "1 = (string) 2"),
59  RZ_PSEUDO_DEFINE_GRAMMAR("const-string/jumbo", "1 = (jumbo-string) 2"),
60  RZ_PSEUDO_DEFINE_GRAMMAR("const-wide", "1 = (wide) 2"),
61  RZ_PSEUDO_DEFINE_GRAMMAR("const-wide/16", "1 = 2"),
62  RZ_PSEUDO_DEFINE_GRAMMAR("const-wide/32", "1 = 2"),
63  RZ_PSEUDO_DEFINE_GRAMMAR("const-wide/high16", "1 = 2"),
64  RZ_PSEUDO_DEFINE_GRAMMAR("const/16", "1 = 2"),
65  RZ_PSEUDO_DEFINE_GRAMMAR("const/4", "1 = (wide) 2"),
66  RZ_PSEUDO_DEFINE_GRAMMAR("const/high16", "1 = 2"),
67  RZ_PSEUDO_DEFINE_GRAMMAR("div-double", "1 = (double) 2 / 3"),
68  RZ_PSEUDO_DEFINE_GRAMMAR("div-double/2addr", "1 /= (double) 2"),
69  RZ_PSEUDO_DEFINE_GRAMMAR("div-float", "1 = 2 / 3"),
70  RZ_PSEUDO_DEFINE_GRAMMAR("div-float/2addr", "1 /= (float) 2"),
71  RZ_PSEUDO_DEFINE_GRAMMAR("div-int", "1 = (int)(2 / 3)"),
72  RZ_PSEUDO_DEFINE_GRAMMAR("div-int/2addr", "1 /= 2"),
73  RZ_PSEUDO_DEFINE_GRAMMAR("div-int/lit16", "1 = 2 / 3"),
74  RZ_PSEUDO_DEFINE_GRAMMAR("div-int/lit8", "1 = 2 / 3"),
75  RZ_PSEUDO_DEFINE_GRAMMAR("double-to-int", "1 = (int) 2"),
76  RZ_PSEUDO_DEFINE_GRAMMAR("double-to-long", "1 = (long) 2"),
77  RZ_PSEUDO_DEFINE_GRAMMAR("filled-new-array", "1 = new Array(2)"),
78  RZ_PSEUDO_DEFINE_GRAMMAR("float-to-double", "1 = (double)(float) 2"),
79  RZ_PSEUDO_DEFINE_GRAMMAR("float-to-int", "1 = (int)(float) 2"),
80  RZ_PSEUDO_DEFINE_GRAMMAR("float-to-long", "1 = (long)(float) 2"),
81  RZ_PSEUDO_DEFINE_GRAMMAR("goto/16", "goto 1"),
82  RZ_PSEUDO_DEFINE_GRAMMAR("goto/32", "goto 1"),
83  RZ_PSEUDO_DEFINE_GRAMMAR("if-eq", "if (1 == 2) goto 3"),
84  RZ_PSEUDO_DEFINE_GRAMMAR("if-eqz", "if (!1) goto 2"),
85  RZ_PSEUDO_DEFINE_GRAMMAR("if-ge", "if (1 > zero) goto 2"),
86  RZ_PSEUDO_DEFINE_GRAMMAR("if-gtz", "if (1 > 0) goto 2"),
87  RZ_PSEUDO_DEFINE_GRAMMAR("if-le", "if (1 <= 2) goto 3"),
88  RZ_PSEUDO_DEFINE_GRAMMAR("if-lt", "if (1 < 2) goto 3"),
89  RZ_PSEUDO_DEFINE_GRAMMAR("if-ltz", "if (1 <=) goto 2"),
90  RZ_PSEUDO_DEFINE_GRAMMAR("if-ne", "if (1 != 2) goto 3"),
91  RZ_PSEUDO_DEFINE_GRAMMAR("if-nez", "if (1) goto 2"),
92  RZ_PSEUDO_DEFINE_GRAMMAR("iget", "1 = 2[3]"),
93  RZ_PSEUDO_DEFINE_GRAMMAR("iget-boolean", "1 = (bool) 2 [3]"),
94  RZ_PSEUDO_DEFINE_GRAMMAR("iget-byte", "1 = (byte) 2 [3]"),
95  RZ_PSEUDO_DEFINE_GRAMMAR("iget-char", "1 = (char) 2 [3]"),
96  RZ_PSEUDO_DEFINE_GRAMMAR("iget-object", "1 = (2) 3"),
97  RZ_PSEUDO_DEFINE_GRAMMAR("iget-short", "1 = (short) 2 [3]"),
98  RZ_PSEUDO_DEFINE_GRAMMAR("iget-wide", "1 = (wide) 2 [3]"),
99  RZ_PSEUDO_DEFINE_GRAMMAR("instance-of", "1 = insteanceof (2) == 3"),
100  RZ_PSEUDO_DEFINE_GRAMMAR("int-to-byte", "1 = (byte) 2"),
101  RZ_PSEUDO_DEFINE_GRAMMAR("int-to-double", "1 = (double) 2"),
102  RZ_PSEUDO_DEFINE_GRAMMAR("int-to-long", "1 = (long) 2"),
103  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-direct", "call 2 1"),
104  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-direct/range", "call 2 1"),
105  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-interface", "call 2 1"),
106  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-interface/range", "call 2 1"),
107  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-polymorphic", "call polymorphic 2 1"),
108  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-static", "call 2 1"),
109  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-super", "call super 2 1"),
110  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-super/range", "call super 2 1"),
111  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-virtual", "call 2 1"),
112  RZ_PSEUDO_DEFINE_GRAMMAR("invoke-virtual/range", "call 2 1"),
113  RZ_PSEUDO_DEFINE_GRAMMAR("iput", "2[3] = 1"),
114  RZ_PSEUDO_DEFINE_GRAMMAR("iput-boolean", "2[3] = (bool) 1"),
115  RZ_PSEUDO_DEFINE_GRAMMAR("iput-byte", "2[3] = (byte) 1"),
116  RZ_PSEUDO_DEFINE_GRAMMAR("iput-char", "2[3] = (char) 1"),
117  RZ_PSEUDO_DEFINE_GRAMMAR("iput-int", "2[3] = (int) 1"),
118  RZ_PSEUDO_DEFINE_GRAMMAR("iput-object", "2[3] = (object) 1"),
119  RZ_PSEUDO_DEFINE_GRAMMAR("long-to-double", "1 = (double) 2"),
120  RZ_PSEUDO_DEFINE_GRAMMAR("long-to-float", "1 = (float)(long) 2"),
121  RZ_PSEUDO_DEFINE_GRAMMAR("long-to-int", "1 = (int)(long) 2"),
122  RZ_PSEUDO_DEFINE_GRAMMAR("move", "1 = 2"),
123  RZ_PSEUDO_DEFINE_GRAMMAR("move-exception", "1 = exception"),
124  RZ_PSEUDO_DEFINE_GRAMMAR("move-object", "1 = (object) 2"),
125  RZ_PSEUDO_DEFINE_GRAMMAR("move-object/16", "1 = (object) 2"),
126  RZ_PSEUDO_DEFINE_GRAMMAR("move-object/from16", "1 = (object) 2"),
127  RZ_PSEUDO_DEFINE_GRAMMAR("move-result", "1 = result"),
128  RZ_PSEUDO_DEFINE_GRAMMAR("move-result-object", "1 = (object) result"),
129  RZ_PSEUDO_DEFINE_GRAMMAR("move-result-wide", "1 = (wide) result"),
130  RZ_PSEUDO_DEFINE_GRAMMAR("move-wide", "1 = 2"),
131  RZ_PSEUDO_DEFINE_GRAMMAR("move-wide/16", "1 = 2"),
132  RZ_PSEUDO_DEFINE_GRAMMAR("move-wide/from16", "1 = (wide) 2"),
133  RZ_PSEUDO_DEFINE_GRAMMAR("move/16", "1 = 2"),
134  RZ_PSEUDO_DEFINE_GRAMMAR("move/from16", "1 = 2"),
135  RZ_PSEUDO_DEFINE_GRAMMAR("mul-double", "1 = 2 * 3"),
136  RZ_PSEUDO_DEFINE_GRAMMAR("mul-float", "1 = 2 * 3"),
137  RZ_PSEUDO_DEFINE_GRAMMAR("mul-float/2addr", "1 *= 2"),
138  RZ_PSEUDO_DEFINE_GRAMMAR("mul-int", "1 = (int)(2 * 3)"),
139  RZ_PSEUDO_DEFINE_GRAMMAR("mul-int/lit8", "1 = (2 * 3)"),
140  RZ_PSEUDO_DEFINE_GRAMMAR("mul-long", "1 = 2 * 3"),
141  RZ_PSEUDO_DEFINE_GRAMMAR("neg-double", "1 = -2"),
142  RZ_PSEUDO_DEFINE_GRAMMAR("neg-float", "1 = -2"),
143  RZ_PSEUDO_DEFINE_GRAMMAR("neg-long", "1 = -2"),
144  RZ_PSEUDO_DEFINE_GRAMMAR("new-array", "1 = new array (2, 3)"),
145  RZ_PSEUDO_DEFINE_GRAMMAR("new-instance", "1 = 2.new"),
146  RZ_PSEUDO_DEFINE_GRAMMAR("nop", ""),
147  RZ_PSEUDO_DEFINE_GRAMMAR("not-int", "1 = !2"),
148  RZ_PSEUDO_DEFINE_GRAMMAR("or-int", "1 = (int)(2 | 3)"),
149  RZ_PSEUDO_DEFINE_GRAMMAR("or-int/2addr", "1 |= 2"),
150  RZ_PSEUDO_DEFINE_GRAMMAR("or-long", "1 |= 2"),
151  RZ_PSEUDO_DEFINE_GRAMMAR("packed-switch", "switch 2"),
152  RZ_PSEUDO_DEFINE_GRAMMAR("rem-double", "1 = (double) 2 % 3"),
153  RZ_PSEUDO_DEFINE_GRAMMAR("rem-double/2addr", "1 %= (double) 2"),
154  RZ_PSEUDO_DEFINE_GRAMMAR("rem-float", "1 = (float) 2 % 3"),
155  RZ_PSEUDO_DEFINE_GRAMMAR("rem-float/2addr", "1 %= (float) 2"),
156  RZ_PSEUDO_DEFINE_GRAMMAR("rem-long", "1 = (long) 2 % 3"),
157  RZ_PSEUDO_DEFINE_GRAMMAR("rem-long/2addr", "1 %= 2"),
158  RZ_PSEUDO_DEFINE_GRAMMAR("return-object", "return (object) 1"),
159  RZ_PSEUDO_DEFINE_GRAMMAR("return-void", "return"),
160  RZ_PSEUDO_DEFINE_GRAMMAR("return-wide", "return (wide) 1"),
161  RZ_PSEUDO_DEFINE_GRAMMAR("rsub-int", "1 = 2 - 3"),
162  RZ_PSEUDO_DEFINE_GRAMMAR("sget", "1 = 2"),
163  RZ_PSEUDO_DEFINE_GRAMMAR("sget-boolean", "1 = (bool) 2"),
164  RZ_PSEUDO_DEFINE_GRAMMAR("sget-byte", "1 = (byte) 2 [3]"),
165  RZ_PSEUDO_DEFINE_GRAMMAR("sget-char", "1 = (char) 2"),
166  RZ_PSEUDO_DEFINE_GRAMMAR("sget-object", "1 = (object) 2"),
167  RZ_PSEUDO_DEFINE_GRAMMAR("sget-short", "1 = (short) 2"),
168  RZ_PSEUDO_DEFINE_GRAMMAR("shl-int", "1 = (int) 2 << 3"),
169  RZ_PSEUDO_DEFINE_GRAMMAR("shl-int/2addr", "1 <<<= 2"),
170  RZ_PSEUDO_DEFINE_GRAMMAR("shl-long", "1 = (long) 2 << 3"),
171  RZ_PSEUDO_DEFINE_GRAMMAR("shr-int", "1 = (int) 2 >> 3"),
172  RZ_PSEUDO_DEFINE_GRAMMAR("shr-long", "1 = (long) 2 >> 3"),
173  RZ_PSEUDO_DEFINE_GRAMMAR("shr-long/2addr", "1 >>= 2"),
174  RZ_PSEUDO_DEFINE_GRAMMAR("sparse-switch", "switch 2"),
175  RZ_PSEUDO_DEFINE_GRAMMAR("sput", "1 = 2 3"),
176  RZ_PSEUDO_DEFINE_GRAMMAR("sput-boolean", "2[3] = (bool) 1"),
177  RZ_PSEUDO_DEFINE_GRAMMAR("sput-char", "2[3] = (char) 1"),
178  RZ_PSEUDO_DEFINE_GRAMMAR("sput-object", "1 = 2"),
179  RZ_PSEUDO_DEFINE_GRAMMAR("sput-wide", "1 = 2"),
180  RZ_PSEUDO_DEFINE_GRAMMAR("sub-float", "1 = 2 - 3"),
181  RZ_PSEUDO_DEFINE_GRAMMAR("sub-float/2addr", "1 -= 2"),
182  RZ_PSEUDO_DEFINE_GRAMMAR("sub-int", "1 = (int) 2 - 3"),
183  RZ_PSEUDO_DEFINE_GRAMMAR("sub-int", "1 = (int)(2 - 3)"),
184  RZ_PSEUDO_DEFINE_GRAMMAR("sub-int/2addr", "1 -= 2"),
185  RZ_PSEUDO_DEFINE_GRAMMAR("sub-long", "1 = (long) 2 - 3"),
186  RZ_PSEUDO_DEFINE_GRAMMAR("sub-long/2addr", "1 -= (long) 2"),
187  RZ_PSEUDO_DEFINE_GRAMMAR("ushl-int/2addr", "1 <<<= 2"),
188  RZ_PSEUDO_DEFINE_GRAMMAR("ushr-int", "1 = (int) 2 >>> 3"),
189  RZ_PSEUDO_DEFINE_GRAMMAR("ushr-int/2addr", "1 >>>= 2"),
190  RZ_PSEUDO_DEFINE_GRAMMAR("ushr-long", "1 = (long) 2 >>> 3"),
191  RZ_PSEUDO_DEFINE_GRAMMAR("xor-byte", "1 = (byte)(2 ^ 3)"),
192  RZ_PSEUDO_DEFINE_GRAMMAR("xor-int", "1 = (int)(2 ^ 3)"),
193  RZ_PSEUDO_DEFINE_GRAMMAR("xor-int/2addr", "1 ^= 2"),
194  RZ_PSEUDO_DEFINE_GRAMMAR("xor-long", "1 = (long)(2 ^ 3)"),
195  RZ_PSEUDO_DEFINE_GRAMMAR("xor-short", "1 = (short)(2 ^ 3)"),
196 };
197 
198 static const RzPseudoReplace dalvik_replace[] = {
199  RZ_PSEUDO_DEFINE_REPLACE("{", "(", 1),
200  RZ_PSEUDO_DEFINE_REPLACE("}", ")", 1),
201  RZ_PSEUDO_DEFINE_REPLACE(";", "", 1),
202 };
203 
205 
206 RzList *dalvik_tokenize(const char *assembly, size_t length) {
207  size_t i, p;
208  char *buf = NULL;
209  RzList *tokens = NULL;
210  const char *comma_replace = NULL;
211  bool keep = false;
212 
213  buf = rz_str_ndup(assembly, length);
214  if (!buf) {
215  return NULL;
216  }
217 
218  for (i = 0, p = 0; p < length; ++i, ++p) {
219  if (buf[p] == ',') {
220  if (!keep) {
221  p++;
222  } else if (buf[p + 1] == ' ') {
223  buf[i] = buf[p];
224  p++;
225  continue;
226  }
227  } else if (buf[p] == '{') {
228  keep = true;
229  comma_replace = ", ";
230  } else if (buf[p] == '}') {
231  keep = false;
232  }
233  if (p > i) {
234  buf[i] = buf[p];
235  }
236  }
237  buf[i] = 0;
238 
239  tokens = rz_str_split_duplist(buf, " ", true);
240  free(buf);
241  if (!tokens) {
242  return NULL;
243  }
244 
245  if (comma_replace) {
246  RzListIter *it;
247  rz_list_foreach (tokens, it, buf) {
248  it->data = rz_str_replace(buf, ",", comma_replace, 1);
249  }
250  }
251 
252  return tokens;
253 }
254 
255 static bool parse(RzParse *parse, const char *assembly, RzStrBuf *sb) {
256  return rz_pseudo_convert(&dalvik_config, assembly, sb);
257 }
258 
260  .name = "dalvik.pseudo",
261  .desc = "DALVIK pseudo syntax",
262  .init = NULL,
263  .fini = NULL,
264  .parse = parse,
265 };
266 
267 #ifndef RZ_PLUGIN_INCORE
271  .version = RZ_VERSION
272 };
273 #endif
lzma_index ** i
Definition: index.h:629
static SblHeader sb
Definition: bin_mbn.c:26
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
void * p
Definition: libc.cpp:67
#define RZ_PSEUDO_DEFINE_REPLACE(x, y, f)
Definition: parse_common.c:64
static bool rz_pseudo_convert(const RzPseudoConfig *config, const char *assembly, RzStrBuf *sb)
Definition: parse_common.c:103
#define RZ_PSEUDO_DEFINE_CONFIG_NO_DIRECT(l, r, m, t)
Definition: parse_common.c:79
#define RZ_PSEUDO_DEFINE_GRAMMAR(x, y)
Definition: parse_common.c:58
static const RzPseudoConfig dalvik_config
RZ_API RzLibStruct rizin_plugin
RzParsePlugin rz_parse_plugin_dalvik_pseudo
static const RzPseudoReplace dalvik_replace[]
static const RzPseudoGrammar dalvik_lexicon[]
static bool parse(RzParse *parse, const char *assembly, RzStrBuf *sb)
static RzList * dalvik_tokenize(const char *assembly, size_t length)
@ RZ_LIB_TYPE_PARSE
Definition: rz_lib.h:74
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
RZ_API RzList * rz_str_split_duplist(const char *str, const char *c, bool trim)
Split the string str according to the substring c and returns a RzList with the result.
Definition: str.c:3464
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
#define RZ_VERSION
Definition: rz_version.h:8
Definition: regcomp.c:57
void * data
Definition: rz_list.h:14