Rizin
unix-like reverse engineering framework and cli tools
uleb128.c File Reference
#include "rz_util/rz_str.h"
#include <rz_util.h>

Go to the source code of this file.

Macros

#define BYTE_AT(type, i, shift)   (((type)(p[i]) & 0x7f) << (shift))
 
#define LEB128_1(type)   (BYTE_AT(type, 0, 0))
 
#define LEB128_2(type)   (BYTE_AT(type, 1, 7) | LEB128_1(type))
 
#define LEB128_3(type)   (BYTE_AT(type, 2, 14) | LEB128_2(type))
 
#define LEB128_4(type)   (BYTE_AT(type, 3, 21) | LEB128_3(type))
 
#define LEB128_5(type)   (BYTE_AT(type, 4, 28) | LEB128_4(type))
 
#define LEB128_6(type)   (BYTE_AT(type, 5, 35) | LEB128_5(type))
 
#define LEB128_7(type)   (BYTE_AT(type, 6, 42) | LEB128_6(type))
 
#define LEB128_8(type)   (BYTE_AT(type, 7, 49) | LEB128_7(type))
 
#define LEB128_9(type)   (BYTE_AT(type, 8, 56) | LEB128_8(type))
 
#define LEB128_10(type)   (BYTE_AT(type, 9, 63) | LEB128_9(type))
 
#define SHIFT_AMOUNT(type, sign_bit)   (sizeof(type) * 8 - 1 - (sign_bit))
 
#define SIGN_EXTEND(type, value, sign_bit)
 

Functions

RZ_API const ut8rz_uleb128 (const ut8 *data, int datalen, RZ_NULLABLE ut64 *v, const char **error)
 
RZ_API int rz_uleb128_len (const ut8 *data, int size)
 
RZ_API const ut8rz_uleb128_decode (const ut8 *data, int *datalen, ut64 *v)
 
RZ_API ut8rz_uleb128_encode (const ut64 s, int *len)
 
RZ_API const ut8rz_leb128 (const ut8 *data, int datalen, st64 *v)
 
RZ_API st64 rz_sleb128 (const ut8 **data, const ut8 *end)
 
RZ_API size_t read_u32_leb128 (const ut8 *p, const ut8 *max, ut32 *out_value)
 
RZ_API size_t read_i32_leb128 (const ut8 *p, const ut8 *max, st32 *out_value)
 
RZ_API size_t read_u64_leb128 (const ut8 *p, const ut8 *max, ut64 *out_value)
 
RZ_API size_t read_i64_leb128 (const ut8 *p, const ut8 *max, st64 *out_value)
 

Macro Definition Documentation

◆ BYTE_AT

#define BYTE_AT (   type,
  i,
  shift 
)    (((type)(p[i]) & 0x7f) << (shift))

Definition at line 168 of file uleb128.c.

◆ LEB128_1

#define LEB128_1 (   type)    (BYTE_AT(type, 0, 0))

Definition at line 170 of file uleb128.c.

◆ LEB128_10

#define LEB128_10 (   type)    (BYTE_AT(type, 9, 63) | LEB128_9(type))

Definition at line 179 of file uleb128.c.

◆ LEB128_2

#define LEB128_2 (   type)    (BYTE_AT(type, 1, 7) | LEB128_1(type))

Definition at line 171 of file uleb128.c.

◆ LEB128_3

#define LEB128_3 (   type)    (BYTE_AT(type, 2, 14) | LEB128_2(type))

Definition at line 172 of file uleb128.c.

◆ LEB128_4

#define LEB128_4 (   type)    (BYTE_AT(type, 3, 21) | LEB128_3(type))

Definition at line 173 of file uleb128.c.

◆ LEB128_5

#define LEB128_5 (   type)    (BYTE_AT(type, 4, 28) | LEB128_4(type))

Definition at line 174 of file uleb128.c.

◆ LEB128_6

#define LEB128_6 (   type)    (BYTE_AT(type, 5, 35) | LEB128_5(type))

Definition at line 175 of file uleb128.c.

◆ LEB128_7

#define LEB128_7 (   type)    (BYTE_AT(type, 6, 42) | LEB128_6(type))

Definition at line 176 of file uleb128.c.

◆ LEB128_8

#define LEB128_8 (   type)    (BYTE_AT(type, 7, 49) | LEB128_7(type))

Definition at line 177 of file uleb128.c.

◆ LEB128_9

#define LEB128_9 (   type)    (BYTE_AT(type, 8, 56) | LEB128_8(type))

Definition at line 178 of file uleb128.c.

◆ SHIFT_AMOUNT

#define SHIFT_AMOUNT (   type,
  sign_bit 
)    (sizeof(type) * 8 - 1 - (sign_bit))

Definition at line 181 of file uleb128.c.

◆ SIGN_EXTEND

#define SIGN_EXTEND (   type,
  value,
  sign_bit 
)
Value:
((type)((value) << SHIFT_AMOUNT(type, sign_bit)) >> \
SHIFT_AMOUNT(type, sign_bit))
static int value
Definition: cmd_api.c:93
int type
Definition: mipsasm.c:17
#define SHIFT_AMOUNT(type, sign_bit)
Definition: uleb128.c:181

Definition at line 182 of file uleb128.c.

Function Documentation

◆ read_i32_leb128()

RZ_API size_t read_i32_leb128 ( const ut8 p,
const ut8 max,
st32 out_value 
)

Definition at line 211 of file uleb128.c.

211  {
212  if (p < max && !(p[0] & 0x80)) {
213  ut32 result = LEB128_1(ut32);
214  *out_value = SIGN_EXTEND(ut32, result, 6);
215  return 1;
216  } else if (p + 1 < max && !(p[1] & 0x80)) {
217  ut32 result = LEB128_2(ut32);
218  *out_value = SIGN_EXTEND(ut32, result, 13);
219  return 2;
220  } else if (p + 2 < max && !(p[2] & 0x80)) {
221  ut32 result = LEB128_3(ut32);
222  *out_value = SIGN_EXTEND(ut32, result, 20);
223  return 3;
224  } else if (p + 3 < max && !(p[3] & 0x80)) {
225  ut32 result = LEB128_4(ut32);
226  *out_value = SIGN_EXTEND(ut32, result, 27);
227  return 4;
228  } else if (p + 4 < max && !(p[4] & 0x80)) {
229  /* the top bits should be a sign-extension of the sign bit */
230  bool sign_bit_set = (p[4] & 0x8);
231  int top_bits = p[4] & 0xf0;
232  if ((sign_bit_set && top_bits != 0x70) || (!sign_bit_set && top_bits != 0)) {
233  return 0;
234  }
235  ut32 result = LEB128_5(ut32);
236  *out_value = result;
237  return 5;
238  } else {
239  /* past the end */
240  return 0;
241  }
242 }
uint32_t ut32
int max
Definition: enough.c:225
void * p
Definition: libc.cpp:67
#define SIGN_EXTEND(type, value, sign_bit)
Definition: uleb128.c:182
#define LEB128_3(type)
Definition: uleb128.c:172
#define LEB128_1(type)
Definition: uleb128.c:170
#define LEB128_5(type)
Definition: uleb128.c:174
#define LEB128_4(type)
Definition: uleb128.c:173
#define LEB128_2(type)
Definition: uleb128.c:171

References LEB128_1, LEB128_2, LEB128_3, LEB128_4, LEB128_5, max, p, and SIGN_EXTEND.

Referenced by consume_s7_r(), and wasm_dis().

◆ read_i64_leb128()

RZ_API size_t read_i64_leb128 ( const ut8 p,
const ut8 max,
st64 out_value 
)

Definition at line 282 of file uleb128.c.

282  {
283  if (p < max && !(p[0] & 0x80)) {
284  ut64 result = LEB128_1(ut64);
285  *out_value = SIGN_EXTEND(ut64, result, 6);
286  return 1;
287  } else if (p + 1 < max && !(p[1] & 0x80)) {
288  ut64 result = LEB128_2(ut64);
289  *out_value = SIGN_EXTEND(ut64, result, 13);
290  return 2;
291  } else if (p + 2 < max && !(p[2] & 0x80)) {
292  ut64 result = LEB128_3(ut64);
293  *out_value = SIGN_EXTEND(ut64, result, 20);
294  return 3;
295  } else if (p + 3 < max && !(p[3] & 0x80)) {
296  ut64 result = LEB128_4(ut64);
297  *out_value = SIGN_EXTEND(ut64, result, 27);
298  return 4;
299  } else if (p + 4 < max && !(p[4] & 0x80)) {
300  ut64 result = LEB128_5(ut64);
301  *out_value = SIGN_EXTEND(ut64, result, 34);
302  return 5;
303  } else if (p + 5 < max && !(p[5] & 0x80)) {
304  ut64 result = LEB128_6(ut64);
305  *out_value = SIGN_EXTEND(ut64, result, 41);
306  return 6;
307  } else if (p + 6 < max && !(p[6] & 0x80)) {
308  ut64 result = LEB128_7(ut64);
309  *out_value = SIGN_EXTEND(ut64, result, 48);
310  return 7;
311  } else if (p + 7 < max && !(p[7] & 0x80)) {
312  ut64 result = LEB128_8(ut64);
313  *out_value = SIGN_EXTEND(ut64, result, 55);
314  return 8;
315  } else if (p + 8 < max && !(p[8] & 0x80)) {
316  ut64 result = LEB128_9(ut64);
317  *out_value = SIGN_EXTEND(ut64, result, 62);
318  return 9;
319  } else if (p + 9 < max && !(p[9] & 0x80)) {
320  /* the top bits should be a sign-extension of the sign bit */
321  bool sign_bit_set = (p[9] & 0x1);
322  int top_bits = p[9] & 0xfe;
323  if ((sign_bit_set && top_bits != 0x7e) || (!sign_bit_set && top_bits != 0)) {
324  return 0;
325  }
326  ut64 result = LEB128_10(ut64);
327  *out_value = result;
328  return 10;
329  } else {
330  /* past the end */
331  return 0;
332  }
333 }
#define LEB128_10(type)
Definition: uleb128.c:179
#define LEB128_7(type)
Definition: uleb128.c:176
#define LEB128_6(type)
Definition: uleb128.c:175
#define LEB128_8(type)
Definition: uleb128.c:177
#define LEB128_9(type)
Definition: uleb128.c:178
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References LEB128_1, LEB128_10, LEB128_2, LEB128_3, LEB128_4, LEB128_5, LEB128_6, LEB128_7, LEB128_8, LEB128_9, max, p, SIGN_EXTEND, and ut64().

Referenced by wasm_dis().

◆ read_u32_leb128()

RZ_API size_t read_u32_leb128 ( const ut8 p,
const ut8 max,
ut32 out_value 
)

Definition at line 186 of file uleb128.c.

186  {
187  if (p < max && !(p[0] & 0x80)) {
188  *out_value = LEB128_1(ut32);
189  return 1;
190  } else if (p + 1 < max && !(p[1] & 0x80)) {
191  *out_value = LEB128_2(ut32);
192  return 2;
193  } else if (p + 2 < max && !(p[2] & 0x80)) {
194  *out_value = LEB128_3(ut32);
195  return 3;
196  } else if (p + 3 < max && !(p[3] & 0x80)) {
197  *out_value = LEB128_4(ut32);
198  return 4;
199  } else if (p + 4 < max && !(p[4] & 0x80)) {
200  /* the top bits set represent values > 32 bits */
201  // if (p[4] & 0xf0) {}
202  *out_value = LEB128_5(ut32);
203  return 5;
204  } else {
205  /* past the end */
206  *out_value = 0;
207  return 0;
208  }
209 }

References LEB128_1, LEB128_2, LEB128_3, LEB128_4, LEB128_5, max, and p.

Referenced by consume_u1_r(), consume_u32_r(), consume_u7_r(), decode_buffer(), get_cf_offset(), wasm_dis(), and wasm_op().

◆ read_u64_leb128()

RZ_API size_t read_u64_leb128 ( const ut8 p,
const ut8 max,
ut64 out_value 
)

Definition at line 244 of file uleb128.c.

244  {
245  if (p < max && !(p[0] & 0x80)) {
246  *out_value = LEB128_1(ut64);
247  return 1;
248  } else if (p + 1 < max && !(p[1] & 0x80)) {
249  *out_value = LEB128_2(ut64);
250  return 2;
251  } else if (p + 2 < max && !(p[2] & 0x80)) {
252  *out_value = LEB128_3(ut64);
253  return 3;
254  } else if (p + 3 < max && !(p[3] & 0x80)) {
255  *out_value = LEB128_4(ut64);
256  return 4;
257  } else if (p + 4 < max && !(p[4] & 0x80)) {
258  *out_value = LEB128_5(ut64);
259  return 5;
260  } else if (p + 5 < max && !(p[5] & 0x80)) {
261  *out_value = LEB128_6(ut64);
262  return 6;
263  } else if (p + 6 < max && !(p[6] & 0x80)) {
264  *out_value = LEB128_7(ut64);
265  return 7;
266  } else if (p + 7 < max && !(p[7] & 0x80)) {
267  *out_value = LEB128_8(ut64);
268  return 8;
269  } else if (p + 8 < max && !(p[8] & 0x80)) {
270  *out_value = LEB128_9(ut64);
271  return 9;
272  } else if (p + 9 < max && !(p[9] & 0x80)) {
273  *out_value = LEB128_10(ut64);
274  return 10;
275  } else {
276  /* past the end */
277  *out_value = 0;
278  return 0;
279  }
280 }

References LEB128_1, LEB128_10, LEB128_2, LEB128_3, LEB128_4, LEB128_5, LEB128_6, LEB128_7, LEB128_8, LEB128_9, max, p, and ut64().

Referenced by decode_buffer().

◆ rz_leb128()

RZ_API const ut8* rz_leb128 ( const ut8 data,
int  datalen,
st64 v 
)

Definition at line 117 of file uleb128.c.

117  {
118  ut8 c = 0;
119  st64 s = 0, sum = 0;
120  const ut8 *data_end = data + datalen;
121  if (data && datalen > 0) {
122  if (!*data) {
123  data++;
124  goto beach;
125  }
126  while (data < data_end) {
127  c = *(data++) & 0x0ff;
128  sum |= ((st64)(c & 0x7f) << s);
129  s += 7;
130  if (!(c & 0x80)) {
131  break;
132  }
133  }
134  }
135  if ((s < (8 * sizeof(sum))) && (c & 0x40)) {
136  sum |= -((st64)1 << s);
137  }
138 beach:
139  if (v) {
140  *v = sum;
141  }
142  return data;
143 }
const char * v
Definition: dsignal.c:12
uint8_t ut8
Definition: lh5801.h:11
static RzSocket * s
Definition: rtr.c:28
#define st64
Definition: rz_types_base.h:10
#define c(i)
Definition: sha256.c:43

References c, s, st64, and v.

Referenced by parse_abbrev_raw(), parse_attr_value(), and parse_std_opcode().

◆ rz_sleb128()

RZ_API st64 rz_sleb128 ( const ut8 **  data,
const ut8 end 
)

Definition at line 145 of file uleb128.c.

145  {
146  const ut8 *p = *data;
147  st64 result = 0;
148  int offset = 0;
149  ut8 value;
150  bool cond;
151  do {
152  st64 chunk;
153  value = *p;
154  chunk = value & 0x7f;
155  result |= (chunk << offset);
156  offset += 7;
157  } while (cond = *p & 0x80 && p + 1 < end, p++, cond);
158 
159  if ((value & 0x40) != 0) {
160  result |= ~0ULL << offset;
161  }
162  *data = p;
163  return result;
164 }
voidpf uLong offset
Definition: ioapi.h:144
#define cond(bop, top, mask, flags)
Definition: malloc.c:21

References cond, test_evm::end, p, st64, and value.

Referenced by get_relocs(), parse_dwarf_location(), and reconstruct_chained_fixup().

◆ rz_uleb128()

RZ_API const ut8* rz_uleb128 ( const ut8 data,
int  datalen,
RZ_NULLABLE ut64 v,
const char **  error 
)

Definition at line 9 of file uleb128.c.

9  {
10  ut8 c;
11  ut64 s, sum = 0;
12  const ut8 *data_end;
13  bool malformed_uleb = true;
14  if (v) {
15  *v = 0LL;
16  }
17  if (datalen == ST32_MAX) {
18  // WARNING; possible overflow
19  datalen = 0xffff;
20  }
21  if (datalen < 0) {
22  return NULL;
23  }
24  data_end = data + datalen;
25  if (data && datalen > 0) {
26  if (*data) {
27  for (s = 0; data < data_end; s += 7) {
28  c = *(data++) & 0xff;
29  if (s > 63) {
30  if (error) {
31  *error = rz_str_newf("rz_uleb128: undefined behaviour in %d shift on ut32\n", (int)s);
32  }
33  break;
34  } else {
35  sum |= ((ut64)(c & 0x7f) << s);
36  }
37  if (!(c & 0x80)) {
38  malformed_uleb = false;
39  break;
40  }
41  }
42  if (malformed_uleb) {
43  if (error) {
44  *error = rz_str_newf("malformed uleb128\n");
45  }
46  }
47  } else {
48  data++;
49  }
50  }
51  if (v) {
52  *v = sum;
53  }
54  return data;
55 }
#define NULL
Definition: cris-opc.c:27
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define ST32_MAX
Definition: rz_types_base.h:97
void error(const char *msg)
Definition: untgz.c:593

References c, error(), NULL, rz_str_newf(), s, ST32_MAX, ut64(), and v.

Referenced by parse_abbrev_raw(), parse_attr_value(), parse_comp_unit(), parse_dwarf_location(), parse_ext_opcode(), parse_line_header_source(), and parse_std_opcode().

◆ rz_uleb128_decode()

RZ_API const ut8* rz_uleb128_decode ( const ut8 data,
int datalen,
ut64 v 
)

Definition at line 71 of file uleb128.c.

71  {
72  ut8 c = 0xff;
73  ut64 s = 0, sum = 0, l = 0;
74  do {
75  c = *(data++) & 0xff;
76  sum |= ((ut64)(c & 0x7f) << s);
77  s += 7;
78  l++;
79  } while (c & 0x80);
80  if (v) {
81  *v = sum;
82  }
83  if (datalen) {
84  *datalen = l;
85  }
86  return data;
87 }

References c, s, ut64(), and v.

Referenced by rz_type_format_uleb(), and symbols().

◆ rz_uleb128_encode()

RZ_API ut8* rz_uleb128_encode ( const ut64  s,
int len 
)

Definition at line 89 of file uleb128.c.

89  {
90  ut8 c = 0;
91  int l = 0;
92  ut8 *otarget = NULL, *target = NULL, *tmptarget = NULL;
93  ut64 source = s;
94  do {
95  l++;
96  if (!(tmptarget = realloc(otarget, l))) {
97  l = 0;
98  free(otarget);
99  otarget = NULL;
100  break;
101  }
102  otarget = tmptarget;
103  target = otarget + l - 1;
104  c = source & 0x7f;
105  source >>= 7;
106  if (source) {
107  c |= 0x80;
108  }
109  *(target) = c;
110  } while (source);
111  if (len) {
112  *len = l;
113  }
114  return otarget;
115 }
size_t len
Definition: 6502dis.c:15
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
const char * source
Definition: lz4.h:699

References c, free(), len, NULL, realloc(), s, source, and ut64().

Referenced by rz_type_format_uleb().

◆ rz_uleb128_len()

RZ_API int rz_uleb128_len ( const ut8 data,
int  size 
)

Definition at line 57 of file uleb128.c.

57  {
58  int i = 1;
59  ut8 c = *(data++);
60  while (c > 0x7f && i < size) {
61  c = *(data++);
62  i++;
63  }
64  return i;
65 }
lzma_index ** i
Definition: index.h:629
voidpf void uLong size
Definition: ioapi.h:138

References c, and i.