Rizin
unix-like reverse engineering framework and cli tools
options.c
Go to the documentation of this file.
1 //
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
10 //
12 
13 #include "private.h"
14 
15 
17 // Generic stuff //
19 
20 typedef struct {
21  const char *name;
23 } name_id_map;
24 
25 
26 typedef struct {
27  const char *name;
28  const name_id_map *map;
31 } option_map;
32 
33 
59 static void
60 parse_options(const char *str, const option_map *opts,
61  void (*set)(void *filter_options,
62  unsigned key, uint64_t value, const char *valuestr),
63  void *filter_options)
64 {
65  if (str == NULL || str[0] == '\0')
66  return;
67 
68  char *s = xstrdup(str);
69  char *name = s;
70 
71  while (*name != '\0') {
72  if (*name == ',') {
73  ++name;
74  continue;
75  }
76 
77  char *split = strchr(name, ',');
78  if (split != NULL)
79  *split = '\0';
80 
81  char *value = strchr(name, '=');
82  if (value != NULL)
83  *value++ = '\0';
84 
85  if (value == NULL || value[0] == '\0')
86  message_fatal(_("%s: Options must be `name=value' "
87  "pairs separated with commas"), str);
88 
89  // Look for the option name from the option map.
90  unsigned i = 0;
91  while (true) {
92  if (opts[i].name == NULL)
93  message_fatal(_("%s: Invalid option name"),
94  name);
95 
96  if (strcmp(name, opts[i].name) == 0)
97  break;
98 
99  ++i;
100  }
101 
102  // Option was found from the map. See how we should handle it.
103  if (opts[i].map != NULL) {
104  // value is a string which we should map
105  // to an integer.
106  unsigned j;
107  for (j = 0; opts[i].map[j].name != NULL; ++j) {
108  if (strcmp(opts[i].map[j].name, value) == 0)
109  break;
110  }
111 
112  if (opts[i].map[j].name == NULL)
113  message_fatal(_("%s: Invalid option value"),
114  value);
115 
116  set(filter_options, i, opts[i].map[j].id, value);
117 
118  } else if (opts[i].min == UINT64_MAX) {
119  // value is a special string that will be
120  // parsed by set().
121  set(filter_options, i, 0, value);
122 
123  } else {
124  // value is an integer.
125  const uint64_t v = str_to_uint64(name, value,
126  opts[i].min, opts[i].max);
127  set(filter_options, i, v, value);
128  }
129 
130  // Check if it was the last option.
131  if (split == NULL)
132  break;
133 
134  name = split + 1;
135  }
136 
137  free(s);
138  return;
139 }
140 
141 
143 // Delta //
145 
146 enum {
148 };
149 
150 
151 static void
152 set_delta(void *options, unsigned key, uint64_t value,
153  const char *valuestr lzma_attribute((__unused__)))
154 {
156  switch (key) {
157  case OPT_DIST:
158  opt->dist = value;
159  break;
160  }
161 }
162 
163 
164 extern lzma_options_delta *
165 options_delta(const char *str)
166 {
167  static const option_map opts[] = {
168  { "dist", NULL, LZMA_DELTA_DIST_MIN,
170  { NULL, NULL, 0, 0 }
171  };
172 
175  // It's hard to give a useful default for this.
176  .type = LZMA_DELTA_TYPE_BYTE,
177  .dist = LZMA_DELTA_DIST_MIN,
178  };
179 
181 
182  return options;
183 }
184 
185 
187 // BCJ //
189 
190 enum {
192 };
193 
194 
195 static void
196 set_bcj(void *options, unsigned key, uint64_t value,
197  const char *valuestr lzma_attribute((__unused__)))
198 {
199  lzma_options_bcj *opt = options;
200  switch (key) {
201  case OPT_START_OFFSET:
202  opt->start_offset = value;
203  break;
204  }
205 }
206 
207 
208 extern lzma_options_bcj *
209 options_bcj(const char *str)
210 {
211  static const option_map opts[] = {
212  { "start", NULL, 0, UINT32_MAX },
213  { NULL, NULL, 0, 0 }
214  };
215 
218  .start_offset = 0,
219  };
220 
221  parse_options(str, opts, &set_bcj, options);
222 
223  return options;
224 }
225 
226 
228 // LZMA //
230 
231 enum {
241 };
242 
243 
244 static void lzma_attribute((__noreturn__))
245 error_lzma_preset(const char *valuestr)
246 {
247  message_fatal(_("Unsupported LZMA1/LZMA2 preset: %s"), valuestr);
248 }
249 
250 
251 static void
252 set_lzma(void *options, unsigned key, uint64_t value, const char *valuestr)
253 {
254  lzma_options_lzma *opt = options;
255 
256  switch (key) {
257  case OPT_PRESET: {
258  if (valuestr[0] < '0' || valuestr[0] > '9')
259  error_lzma_preset(valuestr);
260 
261  uint32_t preset = (uint32_t)(valuestr[0] - '0');
262 
263  // Currently only "e" is supported as a modifier,
264  // so keep this simple for now.
265  if (valuestr[1] != '\0') {
266  if (valuestr[1] == 'e')
268  else
269  error_lzma_preset(valuestr);
270 
271  if (valuestr[2] != '\0')
272  error_lzma_preset(valuestr);
273  }
274 
275  if (lzma_lzma_preset(options, preset))
276  error_lzma_preset(valuestr);
277 
278  break;
279  }
280 
281  case OPT_DICT:
282  opt->dict_size = value;
283  break;
284 
285  case OPT_LC:
286  opt->lc = value;
287  break;
288 
289  case OPT_LP:
290  opt->lp = value;
291  break;
292 
293  case OPT_PB:
294  opt->pb = value;
295  break;
296 
297  case OPT_MODE:
298  opt->mode = value;
299  break;
300 
301  case OPT_NICE:
302  opt->nice_len = value;
303  break;
304 
305  case OPT_MF:
306  opt->mf = value;
307  break;
308 
309  case OPT_DEPTH:
310  opt->depth = value;
311  break;
312  }
313 }
314 
315 
316 extern lzma_options_lzma *
317 options_lzma(const char *str)
318 {
319  static const name_id_map modes[] = {
320  { "fast", LZMA_MODE_FAST },
321  { "normal", LZMA_MODE_NORMAL },
322  { NULL, 0 }
323  };
324 
325  static const name_id_map mfs[] = {
326  { "hc3", LZMA_MF_HC3 },
327  { "hc4", LZMA_MF_HC4 },
328  { "bt2", LZMA_MF_BT2 },
329  { "bt3", LZMA_MF_BT3 },
330  { "bt4", LZMA_MF_BT4 },
331  { NULL, 0 }
332  };
333 
334  static const option_map opts[] = {
335  { "preset", NULL, UINT64_MAX, 0 },
336  { "dict", NULL, LZMA_DICT_SIZE_MIN,
337  (UINT32_C(1) << 30) + (UINT32_C(1) << 29) },
338  { "lc", NULL, LZMA_LCLP_MIN, LZMA_LCLP_MAX },
339  { "lp", NULL, LZMA_LCLP_MIN, LZMA_LCLP_MAX },
340  { "pb", NULL, LZMA_PB_MIN, LZMA_PB_MAX },
341  { "mode", modes, 0, 0 },
342  { "nice", NULL, 2, 273 },
343  { "mf", mfs, 0, 0 },
344  { "depth", NULL, 0, UINT32_MAX },
345  { NULL, NULL, 0, 0 }
346  };
347 
349  if (lzma_lzma_preset(options, LZMA_PRESET_DEFAULT))
350  message_bug();
351 
352  parse_options(str, opts, &set_lzma, options);
353 
354  if (options->lc + options->lp > LZMA_LCLP_MAX)
355  message_fatal(_("The sum of lc and lp must not exceed 4"));
356 
357  const uint32_t nice_len_min = options->mf & 0x0F;
358  if (options->nice_len < nice_len_min)
359  message_fatal(_("The selected match finder requires at "
360  "least nice=%" PRIu32), nice_len_min);
361 
362  return options;
363 }
lzma_index ** i
Definition: index.h:629
static int value
Definition: cmd_api.c:93
uint32_t preset
Definition: container.h:259
#define LZMA_PRESET_DEFAULT
Default compression preset.
Definition: container.h:31
#define LZMA_PRESET_EXTREME
Extreme compression preset.
Definition: container.h:60
#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 key
Definition: sflib.h:118
@ LZMA_DELTA_TYPE_BYTE
Definition: delta.h:36
#define LZMA_DELTA_DIST_MIN
Definition: delta.h:60
#define LZMA_DELTA_DIST_MAX
Definition: delta.h:61
#define xmalloc
Definition: disas-asm.h:43
const char * v
Definition: dsignal.c:12
int max
Definition: enough.c:225
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define PRIu32
Definition: macros.h:20
char * xstrdup(const char *) ATTRIBUTE_MALLOC
Definition: util.c:48
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
@ LZMA_MODE_FAST
Fast compression.
Definition: lzma12.h:139
@ LZMA_MODE_NORMAL
Normal compression.
Definition: lzma12.h:147
#define LZMA_PB_MIN
Definition: lzma12.h:317
#define LZMA_DICT_SIZE_MIN
Definition: lzma12.h:218
#define LZMA_LCLP_MIN
Definition: lzma12.h:282
#define LZMA_PB_MAX
Definition: lzma12.h:318
#define LZMA_LCLP_MAX
Definition: lzma12.h:283
@ LZMA_MF_HC4
Hash Chain with 2-, 3-, and 4-byte hashing.
Definition: lzma12.h:70
@ LZMA_MF_BT4
Binary Tree with 2-, 3-, and 4-byte hashing.
Definition: lzma12.h:101
@ LZMA_MF_HC3
Hash Chain with 2- and 3-byte hashing.
Definition: lzma12.h:59
@ LZMA_MF_BT2
Binary Tree with 2-byte hashing.
Definition: lzma12.h:81
@ LZMA_MF_BT3
Binary Tree with 2- and 3-byte hashing.
Definition: lzma12.h:90
void message_bug(void)
Definition: message.c:789
void message_fatal(const char *fmt,...)
Definition: message.c:777
const char * name
Definition: op.c:541
#define _(String)
Definition: opintl.h:53
@ OPT_DIST
Definition: options.c:147
static void set_lzma(void *options, unsigned key, uint64_t value, const char *valuestr)
Definition: options.c:252
static void lzma_attribute((__noreturn__))
Definition: options.c:244
static void parse_options(const char *str, const option_map *opts, void(*set)(void *filter_options, unsigned key, uint64_t value, const char *valuestr), void *filter_options)
Definition: options.c:60
@ OPT_PRESET
Definition: options.c:232
@ OPT_LP
Definition: options.c:235
@ OPT_MODE
Definition: options.c:237
@ OPT_LC
Definition: options.c:234
@ OPT_DICT
Definition: options.c:233
@ OPT_NICE
Definition: options.c:238
@ OPT_DEPTH
Definition: options.c:240
@ OPT_PB
Definition: options.c:236
@ OPT_MF
Definition: options.c:239
lzma_options_lzma * options_lzma(const char *str)
Parser for LZMA options.
Definition: options.c:317
lzma_options_bcj * options_bcj(const char *str)
Parser for BCJ options.
Definition: options.c:209
static void set_delta(void *options, unsigned key, uint64_t value, const char *valuestr lzma_attribute((__unused__)))
Definition: options.c:152
lzma_options_delta * options_delta(const char *str)
Parser for Delta options.
Definition: options.c:165
@ OPT_START_OFFSET
Definition: options.c:191
static void set_bcj(void *options, unsigned key, uint64_t value, const char *valuestr lzma_attribute((__unused__)))
Definition: options.c:196
#define min(a, b)
Definition: qsort.h:83
static RzSocket * s
Definition: rtr.c:28
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
#define UINT32_C(val)
#define UINT64_MAX
#define UINT32_MAX
Options for BCJ filters.
Definition: bcj.h:73
uint32_t start_offset
Start offset for conversions.
Definition: bcj.h:88
Options for the Delta filter.
Definition: delta.h:45
uint32_t dist
Delta distance.
Definition: delta.h:59
Options specific to the LZMA1 and LZMA2 filters.
Definition: lzma12.h:185
uint32_t nice_len
Nice length of a match.
Definition: lzma12.h:342
uint32_t lp
Number of literal position bits.
Definition: lzma12.h:293
lzma_mode mode
Definition: lzma12.h:322
uint32_t depth
Maximum search depth in the match finder.
Definition: lzma12.h:375
uint32_t lc
Number of literal context bits.
Definition: lzma12.h:281
lzma_match_finder mf
Definition: lzma12.h:345
uint32_t pb
Number of position bits.
Definition: lzma12.h:316
uint32_t dict_size
Dictionary size in bytes.
Definition: lzma12.h:217
uint64_t id
Definition: options.c:22
const char * name
Definition: options.c:21
Definition: z80asm.h:102
uint64_t min
Definition: options.c:29
uint64_t max
Definition: options.c:30
const char * name
Definition: options.c:27
const name_id_map * map
Definition: options.c:28
Common includes, definitions, and prototypes.
uint64_t str_to_uint64(const char *name, const char *value, uint64_t min, uint64_t max)
Fancy version of strtoull()
Definition: util.c:58