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

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)