Rizin
unix-like reverse engineering framework and cli tools
filter_encoder.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 "filter_encoder.h"
14 #include "filter_common.h"
15 #include "lzma_encoder.h"
16 #include "lzma2_encoder.h"
17 #include "simple_encoder.h"
18 #include "delta_encoder.h"
19 
20 
21 typedef struct {
24 
28 
31  uint64_t (*memusage)(const void *options);
32 
37  uint64_t (*block_size)(const void *options);
38 
42  lzma_ret (*props_size_get)(uint32_t *size, const void *options);
44 
51  lzma_ret (*props_encode)(const void *options, uint8_t *out);
52 
54 
55 
56 static const lzma_filter_encoder encoders[] = {
57 #ifdef HAVE_ENCODER_LZMA1
58  {
60  .init = &lzma_lzma_encoder_init,
61  .memusage = &lzma_lzma_encoder_memusage,
62  .block_size = NULL, // FIXME
63  .props_size_get = NULL,
64  .props_size_fixed = 5,
65  .props_encode = &lzma_lzma_props_encode,
66  },
67 #endif
68 #ifdef HAVE_ENCODER_LZMA2
69  {
70  .id = LZMA_FILTER_LZMA2,
71  .init = &lzma_lzma2_encoder_init,
72  .memusage = &lzma_lzma2_encoder_memusage,
73  .block_size = &lzma_lzma2_block_size, // FIXME
74  .props_size_get = NULL,
75  .props_size_fixed = 1,
76  .props_encode = &lzma_lzma2_props_encode,
77  },
78 #endif
79 #ifdef HAVE_ENCODER_X86
80  {
81  .id = LZMA_FILTER_X86,
83  .memusage = NULL,
84  .block_size = NULL,
85  .props_size_get = &lzma_simple_props_size,
86  .props_encode = &lzma_simple_props_encode,
87  },
88 #endif
89 #ifdef HAVE_ENCODER_POWERPC
90  {
91  .id = LZMA_FILTER_POWERPC,
93  .memusage = NULL,
94  .block_size = NULL,
95  .props_size_get = &lzma_simple_props_size,
96  .props_encode = &lzma_simple_props_encode,
97  },
98 #endif
99 #ifdef HAVE_ENCODER_IA64
100  {
101  .id = LZMA_FILTER_IA64,
103  .memusage = NULL,
104  .block_size = NULL,
105  .props_size_get = &lzma_simple_props_size,
106  .props_encode = &lzma_simple_props_encode,
107  },
108 #endif
109 #ifdef HAVE_ENCODER_ARM
110  {
111  .id = LZMA_FILTER_ARM,
113  .memusage = NULL,
114  .block_size = NULL,
115  .props_size_get = &lzma_simple_props_size,
116  .props_encode = &lzma_simple_props_encode,
117  },
118 #endif
119 #ifdef HAVE_ENCODER_ARMTHUMB
120  {
121  .id = LZMA_FILTER_ARMTHUMB,
123  .memusage = NULL,
124  .block_size = NULL,
125  .props_size_get = &lzma_simple_props_size,
126  .props_encode = &lzma_simple_props_encode,
127  },
128 #endif
129 #ifdef HAVE_ENCODER_SPARC
130  {
131  .id = LZMA_FILTER_SPARC,
133  .memusage = NULL,
134  .block_size = NULL,
135  .props_size_get = &lzma_simple_props_size,
136  .props_encode = &lzma_simple_props_encode,
137  },
138 #endif
139 #ifdef HAVE_ENCODER_DELTA
140  {
141  .id = LZMA_FILTER_DELTA,
142  .init = &lzma_delta_encoder_init,
143  .memusage = &lzma_delta_coder_memusage,
144  .block_size = NULL,
145  .props_size_get = NULL,
146  .props_size_fixed = 1,
147  .props_encode = &lzma_delta_props_encode,
148  },
149 #endif
150 };
151 
152 
153 static const lzma_filter_encoder *
155 {
156  for (size_t i = 0; i < ARRAY_SIZE(encoders); ++i)
157  if (encoders[i].id == id)
158  return encoders + i;
159 
160  return NULL;
161 }
162 
163 
165 lzma_filter_encoder_is_supported(lzma_vli id)
166 {
167  return encoder_find(id) != NULL;
168 }
169 
170 
172 lzma_filters_update(lzma_stream *strm, const lzma_filter *filters)
173 {
174  if (strm->internal->next.update == NULL)
175  return LZMA_PROG_ERROR;
176 
177  // Validate the filter chain.
178  if (lzma_raw_encoder_memusage(filters) == UINT64_MAX)
179  return LZMA_OPTIONS_ERROR;
180 
181  // The actual filter chain in the encoder is reversed. Some things
182  // still want the normal order chain, so we provide both.
183  size_t count = 1;
184  while (filters[count].id != LZMA_VLI_UNKNOWN)
185  ++count;
186 
187  lzma_filter reversed_filters[LZMA_FILTERS_MAX + 1];
188  for (size_t i = 0; i < count; ++i)
189  reversed_filters[count - i - 1] = filters[i];
190 
191  reversed_filters[count].id = LZMA_VLI_UNKNOWN;
192 
194  strm->allocator, filters, reversed_filters);
195 }
196 
197 
198 extern lzma_ret
200  const lzma_filter *options)
201 {
202  return lzma_raw_coder_init(next, allocator,
204 }
205 
206 
207 extern LZMA_API(lzma_ret)
208 lzma_raw_encoder(lzma_stream *strm, const lzma_filter *options)
209 {
211  (lzma_filter_find)(&encoder_find), true);
212 
216 
217  return LZMA_OK;
218 }
219 
220 
222 lzma_raw_encoder_memusage(const lzma_filter *filters)
223 {
226 }
227 
228 
229 extern uint64_t
231 {
232  uint64_t max = 0;
233 
234  for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
235  const lzma_filter_encoder *const fe
236  = encoder_find(filters[i].id);
237  if (fe->block_size != NULL) {
238  const uint64_t size
239  = fe->block_size(filters[i].options);
240  if (size == 0)
241  return 0;
242 
243  if (size > max)
244  max = size;
245  }
246  }
247 
248  return max;
249 }
250 
251 
252 extern LZMA_API(lzma_ret)
253 lzma_properties_size(uint32_t *size, const lzma_filter *filter)
254 {
255  const lzma_filter_encoder *const fe = encoder_find(filter->id);
256  if (fe == NULL) {
257  // Unknown filter - if the Filter ID is a proper VLI,
258  // return LZMA_OPTIONS_ERROR instead of LZMA_PROG_ERROR,
259  // because it's possible that we just don't have support
260  // compiled in for the requested filter.
261  return filter->id <= LZMA_VLI_MAX
263  }
264 
265  if (fe->props_size_get == NULL) {
266  // No props_size_get() function, use props_size_fixed.
267  *size = fe->props_size_fixed;
268  return LZMA_OK;
269  }
270 
271  return fe->props_size_get(size, filter->options);
272 }
273 
274 
275 extern LZMA_API(lzma_ret)
276 lzma_properties_encode(const lzma_filter *filter, uint8_t *props)
277 {
278  const lzma_filter_encoder *const fe = encoder_find(filter->id);
279  if (fe == NULL)
280  return LZMA_PROG_ERROR;
281 
282  if (fe->props_encode == NULL)
283  return LZMA_OK;
284 
285  return fe->props_encode(filter->options, props);
286 }
#define ARRAY_SIZE(a)
lzma_index ** i
Definition: index.h:629
lzma_ret lzma_simple_armthumb_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: armthumb.c:62
#define LZMA_FILTER_IA64
Definition: bcj.h:32
#define LZMA_FILTER_ARM
Definition: bcj.h:37
#define LZMA_FILTER_SPARC
Definition: bcj.h:47
#define LZMA_FILTER_ARMTHUMB
Definition: bcj.h:42
#define LZMA_FILTER_X86
Definition: bcj.h:22
#define LZMA_FILTER_POWERPC
Definition: bcj.h:27
const lzma_allocator * allocator
Definition: block.h:377
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
const lzma_filter * filters
Definition: container.h:315
#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 count
Definition: sflib.h:98
#define LZMA_FILTER_DELTA
Filter ID.
Definition: delta.h:25
uint64_t lzma_delta_coder_memusage(const void *options)
Definition: delta_common.c:63
lzma_ret lzma_delta_props_encode(const void *options, uint8_t *out)
lzma_ret lzma_delta_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Delta filter encoder.
int max
Definition: enough.c:225
const lzma_allocator const uint8_t * props
Definition: filter.h:362
#define LZMA_FILTERS_MAX
Maximum number of filters in a chain.
Definition: filter.h:26
uint64_t lzma_raw_coder_memusage(lzma_filter_find coder_find, const lzma_filter *filters)
lzma_ret lzma_raw_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *options, lzma_filter_find coder_find, bool is_encoder)
Filter-specific stuff common for both encoder and decoder.
const lzma_filter_coder *(* lzma_filter_find)(lzma_vli id)
Definition: filter_common.h:35
static const lzma_filter_encoder encoders[]
LZMA_API(lzma_bool)
uint64_t lzma_mt_block_size(const lzma_filter *filters)
static const lzma_filter_encoder * encoder_find(lzma_vli id)
lzma_ret lzma_raw_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *options)
static lzma_stream strm
Definition: full_flush.c:20
lzma_ret lzma_simple_ia64_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: ia64.c:98
voidpf void uLong size
Definition: ioapi.h:138
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
#define LZMA_FILTER_LZMA2
LZMA2 Filter ID.
Definition: lzma12.h:40
#define LZMA_FILTER_LZMA1
LZMA1 Filter ID.
Definition: lzma12.h:30
lzma_ret lzma_lzma2_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
uint64_t lzma_lzma2_block_size(const void *options)
lzma_ret lzma_lzma2_props_encode(const void *options, uint8_t *out)
uint64_t lzma_lzma2_encoder_memusage(const void *options)
LZMA2 encoder.
lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: lzma_encoder.c:619
uint64_t lzma_lzma_encoder_memusage(const void *options)
Definition: lzma_encoder.c:628
LZMA encoder API.
lzma_ret lzma_lzma_props_encode(const void *options, uint8_t *out)
lzma_ret lzma_simple_powerpc_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: powerpc.c:62
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
lzma_ret lzma_simple_sparc_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: sparc.c:69
lzma_ret lzma_simple_x86_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: x86.c:145
lzma_ret lzma_simple_props_encode(const void *options, uint8_t *out)
lzma_ret lzma_simple_props_size(uint32_t *size, const void *options)
#define UINT64_MAX
Custom functions for memory handling.
Definition: base.h:372
lzma_vli id
Filter ID.
lzma_ret(* props_size_get)(uint32_t *size, const void *options)
uint64_t(* block_size)(const void *options)
lzma_ret(* props_encode)(const void *options, uint8_t *out)
lzma_init_function init
Filter options.
Definition: filter.h:43
lzma_vli id
Filter ID.
Definition: filter.h:54
lzma_next_coder next
The actual coder that should do something useful.
Definition: common.h:198
bool supported_actions[LZMA_ACTION_MAX+1]
Indicates which lzma_action values are allowed by next.code.
Definition: common.h:220
Hold data and function pointers of the next filter in the chain.
Definition: common.h:135
void * coder
Pointer to coder-specific data.
Definition: common.h:137
lzma_ret(* update)(void *coder, const lzma_allocator *allocator, const lzma_filter *filters, const lzma_filter *reversed_filters)
Definition: common.h:173
Passing data to and from liblzma.
Definition: base.h:485
lzma_internal * internal
Definition: base.h:505
const lzma_allocator * allocator
Custom memory allocation functions.
Definition: base.h:502
#define lzma_next_strm_init(func, strm,...)
Definition: common.h:303
lzma_ret(* lzma_init_function)(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Type of a function used to initialize a filter encoder or decoder.
Definition: common.h:97
lzma_ret lzma_simple_arm_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: arm.c:57
uint64_t lzma_vli
Variable-length integer type.
Definition: vli.h:63
#define LZMA_VLI_UNKNOWN
VLI value to denote that the value is unknown.
Definition: vli.h:39
#define LZMA_VLI_MAX
Maximum supported value of a variable-length integer.
Definition: vli.h:34
lzma_ret
Return values used by several functions in liblzma.
Definition: base.h:57
@ LZMA_PROG_ERROR
Programming error.
Definition: base.h:218
@ LZMA_OPTIONS_ERROR
Invalid or unsupported options.
Definition: base.h:160
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58
@ LZMA_SYNC_FLUSH
Make all the input available at output.
Definition: base.h:265
@ LZMA_FINISH
Finish the coding operation.
Definition: base.h:328
@ LZMA_RUN
Continue coding.
Definition: base.h:251
unsigned char lzma_bool
Boolean.
Definition: base.h:29