Cleanup of config/includes.
[openocd.git] / src / helper / binarybuffer.c
1 /***************************************************************************
2 * Copyright (C) 2004, 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
20 ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "helper/replacements.h"
27 #include "log.h"
28 #include "binarybuffer.h"
29
30 static const unsigned char bit_reverse_table256[] = {
31 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
32 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
33 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
34 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
35 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
36 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
37 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
38 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
39 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
40 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
41 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
42 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
43 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
44 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
45 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
46 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
47 };
48
49 static const char hex_digits[] = {
50 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
51 'a', 'b', 'c', 'd', 'e', 'f'
52 };
53
54 void *buf_cpy(const void *from, void *_to, unsigned size)
55 {
56 if (NULL == from || NULL == _to)
57 return NULL;
58
59 /* copy entire buffer */
60 memcpy(_to, from, DIV_ROUND_UP(size, 8));
61
62 /* mask out bits that don't belong to the buffer */
63 unsigned trailing_bits = size % 8;
64 if (trailing_bits) {
65 uint8_t *to = _to;
66 to[size / 8] &= (1 << trailing_bits) - 1;
67 }
68 return _to;
69 }
70
71 static bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m)
72 {
73 return (a & m) != (b & m);
74 }
75 static bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing)
76 {
77 uint8_t mask = (1 << trailing) - 1;
78 return buf_cmp_masked(a, b, mask & m);
79 }
80
81 bool buf_cmp(const void *_buf1, const void *_buf2, unsigned size)
82 {
83 if (!_buf1 || !_buf2)
84 return _buf1 != _buf2;
85
86 unsigned last = size / 8;
87 if (memcmp(_buf1, _buf2, last) != 0)
88 return false;
89
90 unsigned trailing = size % 8;
91 if (!trailing)
92 return false;
93
94 const uint8_t *buf1 = _buf1, *buf2 = _buf2;
95 return buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing);
96 }
97
98 bool buf_cmp_mask(const void *_buf1, const void *_buf2,
99 const void *_mask, unsigned size)
100 {
101 if (!_buf1 || !_buf2)
102 return _buf1 != _buf2 || _buf1 != _mask;
103
104 const uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask;
105 unsigned last = size / 8;
106 for (unsigned i = 0; i < last; i++) {
107 if (buf_cmp_masked(buf1[i], buf2[i], mask[i]))
108 return true;
109 }
110 unsigned trailing = size % 8;
111 if (!trailing)
112 return false;
113 return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);
114 }
115
116
117 void *buf_set_ones(void *_buf, unsigned size)
118 {
119 uint8_t *buf = _buf;
120 if (!buf)
121 return NULL;
122
123 memset(buf, 0xff, size / 8);
124
125 unsigned trailing_bits = size % 8;
126 if (trailing_bits)
127 buf[size / 8] = (1 << trailing_bits) - 1;
128
129 return buf;
130 }
131
132 void *buf_set_buf(const void *_src, unsigned src_start,
133 void *_dst, unsigned dst_start, unsigned len)
134 {
135 const uint8_t *src = _src;
136 uint8_t *dst = _dst;
137 unsigned i, sb, db, sq, dq, lb, lq;
138
139 sb = src_start / 8;
140 db = dst_start / 8;
141 sq = src_start % 8;
142 dq = dst_start % 8;
143 lb = len / 8;
144 lq = len % 8;
145
146 src += sb;
147 dst += db;
148
149 /* check if both buffers are on byte boundary and
150 * len is a multiple of 8bit so we can simple copy
151 * the buffer */
152 if ((sq == 0) && (dq == 0) && (lq == 0)) {
153 for (i = 0; i < lb; i++)
154 *dst++ = *src++;
155 return _dst;
156 }
157
158 /* fallback to slow bit copy */
159 for (i = 0; i < len; i++) {
160 if (((*src >> (sq&7)) & 1) == 1)
161 *dst |= 1 << (dq&7);
162 else
163 *dst &= ~(1 << (dq&7));
164 if (sq++ == 7) {
165 sq = 0;
166 src++;
167 }
168 if (dq++ == 7) {
169 dq = 0;
170 dst++;
171 }
172 }
173
174 return _dst;
175 }
176
177 uint32_t flip_u32(uint32_t value, unsigned int num)
178 {
179 uint32_t c = (bit_reverse_table256[value & 0xff] << 24) |
180 (bit_reverse_table256[(value >> 8) & 0xff] << 16) |
181 (bit_reverse_table256[(value >> 16) & 0xff] << 8) |
182 (bit_reverse_table256[(value >> 24) & 0xff]);
183
184 if (num < 32)
185 c = c >> (32 - num);
186
187 return c;
188 }
189
190 static int ceil_f_to_u32(float x)
191 {
192 if (x < 0) /* return zero for negative numbers */
193 return 0;
194
195 uint32_t y = x; /* cut off fraction */
196
197 if ((x - y) > 0.0) /* if there was a fractional part, increase by one */
198 y++;
199
200 return y;
201 }
202
203 char *buf_to_hex_str(const void *_buf, unsigned buf_len)
204 {
205 unsigned len_bytes = DIV_ROUND_UP(buf_len, 8);
206 char *str = calloc(len_bytes * 2 + 1, 1);
207
208 const uint8_t *buf = _buf;
209 for (unsigned i = 0; i < len_bytes; i++) {
210 uint8_t tmp = buf[len_bytes - i - 1];
211 if ((i == 0) && (buf_len % 8))
212 tmp &= (0xff >> (8 - (buf_len % 8)));
213 str[2 * i] = hex_digits[tmp >> 4];
214 str[2 * i + 1] = hex_digits[tmp & 0xf];
215 }
216
217 return str;
218 }
219
220 /** identify radix, and skip radix-prefix (0, 0x or 0X) */
221 static void str_radix_guess(const char **_str, unsigned *_str_len,
222 unsigned *_radix)
223 {
224 unsigned radix = *_radix;
225 if (0 != radix)
226 return;
227 const char *str = *_str;
228 unsigned str_len = *_str_len;
229 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
230 radix = 16;
231 str += 2;
232 str_len -= 2;
233 } else if ((str[0] == '0') && (str_len != 1)) {
234 radix = 8;
235 str += 1;
236 str_len -= 1;
237 } else
238 radix = 10;
239 *_str = str;
240 *_str_len = str_len;
241 *_radix = radix;
242 }
243
244 int str_to_buf(const char *str, unsigned str_len,
245 void *_buf, unsigned buf_len, unsigned radix)
246 {
247 str_radix_guess(&str, &str_len, &radix);
248
249 float factor;
250 if (radix == 16)
251 factor = 0.5; /* log(16) / log(256) = 0.5 */
252 else if (radix == 10)
253 factor = 0.41524; /* log(10) / log(256) = 0.41524 */
254 else if (radix == 8)
255 factor = 0.375; /* log(8) / log(256) = 0.375 */
256 else
257 return 0;
258
259 /* copy to zero-terminated buffer */
260 char *charbuf = strndup(str, str_len);
261
262 /* number of digits in base-256 notation */
263 unsigned b256_len = ceil_f_to_u32(str_len * factor);
264 uint8_t *b256_buf = calloc(b256_len, 1);
265
266 /* go through zero terminated buffer
267 * input digits (ASCII) */
268 unsigned i;
269 for (i = 0; charbuf[i]; i++) {
270 uint32_t tmp = charbuf[i];
271 if ((tmp >= '0') && (tmp <= '9'))
272 tmp = (tmp - '0');
273 else if ((tmp >= 'a') && (tmp <= 'f'))
274 tmp = (tmp - 'a' + 10);
275 else if ((tmp >= 'A') && (tmp <= 'F'))
276 tmp = (tmp - 'A' + 10);
277 else
278 continue; /* skip characters other than [0-9,a-f,A-F] */
279
280 if (tmp >= radix)
281 continue; /* skip digits invalid for the current radix */
282
283 /* base-256 digits */
284 for (unsigned j = 0; j < b256_len; j++) {
285 tmp += (uint32_t)b256_buf[j] * radix;
286 b256_buf[j] = (uint8_t)(tmp & 0xFF);
287 tmp >>= 8;
288 }
289
290 }
291
292 uint8_t *buf = _buf;
293 for (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++) {
294 if (j < b256_len)
295 buf[j] = b256_buf[j];
296 else
297 buf[j] = 0;
298 }
299
300 /* mask out bits that don't belong to the buffer */
301 if (buf_len % 8)
302 buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));
303
304 free(b256_buf);
305 free(charbuf);
306
307 return i;
308 }
309
310 void bit_copy_queue_init(struct bit_copy_queue *q)
311 {
312 INIT_LIST_HEAD(&q->list);
313 }
314
315 int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src,
316 unsigned src_offset, unsigned bit_count)
317 {
318 struct bit_copy_queue_entry *qe = malloc(sizeof(*qe));
319 if (!qe)
320 return ERROR_FAIL;
321
322 qe->dst = dst;
323 qe->dst_offset = dst_offset;
324 qe->src = src;
325 qe->src_offset = src_offset;
326 qe->bit_count = bit_count;
327 list_add_tail(&qe->list, &q->list);
328
329 return ERROR_OK;
330 }
331
332 void bit_copy_execute(struct bit_copy_queue *q)
333 {
334 struct bit_copy_queue_entry *qe;
335 struct bit_copy_queue_entry *tmp;
336 list_for_each_entry_safe(qe, tmp, &q->list, list) {
337 bit_copy(qe->dst, qe->dst_offset, qe->src, qe->src_offset, qe->bit_count);
338 list_del(&qe->list);
339 free(qe);
340 }
341 }
342
343 void bit_copy_discard(struct bit_copy_queue *q)
344 {
345 struct bit_copy_queue_entry *qe;
346 struct bit_copy_queue_entry *tmp;
347 list_for_each_entry_safe(qe, tmp, &q->list, list) {
348 list_del(&qe->list);
349 free(qe);
350 }
351 }
352
353 /**
354 * Convert a string of hexadecimal pairs into its binary
355 * representation.
356 *
357 * @param[out] bin Buffer to store binary representation. The buffer size must
358 * be at least @p count.
359 * @param[in] hex String with hexadecimal pairs to convert into its binary
360 * representation.
361 * @param[in] count Number of hexadecimal pairs to convert.
362 *
363 * @return The number of converted hexadecimal pairs.
364 */
365 size_t unhexify(uint8_t *bin, const char *hex, size_t count)
366 {
367 size_t i;
368 char tmp;
369
370 if (!bin || !hex)
371 return 0;
372
373 memset(bin, 0, count);
374
375 for (i = 0; i < 2 * count; i++) {
376 if (hex[i] >= 'a' && hex[i] <= 'f')
377 tmp = hex[i] - 'a' + 10;
378 else if (hex[i] >= 'A' && hex[i] <= 'F')
379 tmp = hex[i] - 'A' + 10;
380 else if (hex[i] >= '0' && hex[i] <= '9')
381 tmp = hex[i] - '0';
382 else
383 return i / 2;
384
385 bin[i / 2] |= tmp << (4 * ((i + 1) % 2));
386 }
387
388 return i / 2;
389 }
390
391 /**
392 * Convert binary data into a string of hexadecimal pairs.
393 *
394 * @param[out] hex Buffer to store string of hexadecimal pairs. The buffer size
395 * must be at least @p length.
396 * @param[in] bin Buffer with binary data to convert into hexadecimal pairs.
397 * @param[in] count Number of bytes to convert.
398 * @param[in] length Maximum number of characters, including null-terminator,
399 * to store into @p hex.
400 *
401 * @returns The length of the converted string excluding null-terminator.
402 */
403 size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
404 {
405 size_t i;
406 uint8_t tmp;
407
408 if (!length)
409 return 0;
410
411 for (i = 0; i < length - 1 && i < 2 * count; i++) {
412 tmp = (bin[i / 2] >> (4 * ((i + 1) % 2))) & 0x0f;
413 hex[i] = hex_digits[tmp];
414 }
415
416 hex[i] = 0;
417
418 return i;
419 }
420
421 void buffer_shr(void *_buf, unsigned buf_len, unsigned count)
422 {
423 unsigned i;
424 unsigned char *buf = _buf;
425 unsigned bytes_to_remove;
426 unsigned shift;
427
428 bytes_to_remove = count / 8;
429 shift = count - (bytes_to_remove * 8);
430
431 for (i = 0; i < (buf_len - 1); i++)
432 buf[i] = (buf[i] >> shift) | ((buf[i+1] << (8 - shift)) & 0xff);
433
434 buf[(buf_len - 1)] = buf[(buf_len - 1)] >> shift;
435
436 if (bytes_to_remove) {
437 memmove(buf, &buf[bytes_to_remove], buf_len - bytes_to_remove);
438 memset(&buf[buf_len - bytes_to_remove], 0, bytes_to_remove);
439 }
440 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)