- single core context used, removed debug context as thought unnecessary.
[openocd.git] / src / helper / binarybuffer.c
1 /***************************************************************************
2 * Copyright (C) 2004, 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "types.h"
28 #include "log.h"
29
30 #include "binarybuffer.h"
31
32 const unsigned char bit_reverse_table256[] =
33 {
34 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
35 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
36 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
37 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
38 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
39 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
40 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
41 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
42 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
43 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
44 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
45 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
46 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
47 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
48 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
49 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
50 };
51
52 int buf_set_u32(u8* buffer, unsigned int first, unsigned int num, u32 value)
53 {
54 unsigned int i;
55
56 if (!buffer)
57 return ERROR_INVALID_ARGUMENTS;
58
59 for (i=first; i<first+num; i++)
60 {
61 if (((value >> (i-first))&1) == 1)
62 buffer[i/8] |= 1 << (i%8);
63 else
64 buffer[i/8] &= ~(1 << (i%8));
65 }
66
67 return ERROR_OK;
68 }
69
70 u32 buf_get_u32(u8* buffer, unsigned int first, unsigned int num)
71 {
72 u32 result = 0;
73 unsigned int i;
74
75 if (!buffer)
76 {
77 LOG_ERROR("buffer not initialized");
78 return 0;
79 }
80
81 for (i=first; i<first+num; i++)
82 {
83 if (((buffer[i/8]>>(i%8))&1) == 1)
84 result |= 1 << (i-first);
85 }
86
87 return result;
88 }
89
90 u8* buf_cpy(u8 *from, u8 *to, int size)
91 {
92 int num_bytes = CEIL(size, 8);
93 unsigned int i;
94
95 if (from == NULL)
96 return NULL;
97
98 for (i = 0; i < num_bytes; i++)
99 to[i] = from[i];
100
101 /* mask out bits that don't belong to the buffer */
102 if (size % 8)
103 {
104 to[size / 8] &= (0xff >> (8 - (size % 8)));
105 }
106
107 return to;
108 }
109
110 int buf_cmp(u8 *buf1, u8 *buf2, int size)
111 {
112 int num_bytes = CEIL(size, 8);
113 int i;
114
115 if (!buf1 || !buf2)
116 return 1;
117
118 for (i = 0; i < num_bytes; i++)
119 {
120 /* last byte */
121 /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
122 if ((size % 8) && (i == num_bytes -1 ))
123 {
124 if ((buf1[i] & ((1 << (size % 8)) - 1)) != (buf2[i] & ((1 << (size % 8)) - 1)))
125 return 1;
126 }
127 else
128 {
129 if (buf1[i] != buf2[i])
130 return 1;
131 }
132 }
133
134 return 0;
135 }
136
137 int buf_cmp_mask(u8 *buf1, u8 *buf2, u8 *mask, int size)
138 {
139 int num_bytes = CEIL(size, 8);
140 int i;
141
142 for (i = 0; i < num_bytes; i++)
143 {
144 /* last byte */
145 /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
146 if ((size % 8) && (i == num_bytes -1 ))
147 {
148 if ((buf1[i] & ((1 << (size % 8)) - 1) & mask[i]) !=
149 (buf2[i] & ((1 << (size % 8)) - 1) & mask[i]))
150 return 1;
151 }
152 else
153 {
154 if ((buf1[i] & mask[i]) != (buf2[i] & mask[i]))
155 return 1;
156 }
157 }
158
159 return 0;
160 }
161
162 u8* buf_set_ones(u8 *buf, int count)
163 {
164 int num_bytes = CEIL(count, 8);
165 int i;
166
167 for (i = 0; i < num_bytes; i++)
168 {
169 if (count >= 8)
170 buf[i] = 0xff;
171 else
172 buf[i] = (1 << count) - 1;
173
174 count -= 8;
175 }
176
177 return buf;
178 }
179
180 u8* buf_set_buf(u8 *src, int src_start, u8 *dst, int dst_start, int len)
181 {
182 int src_idx = src_start, dst_idx = dst_start;
183 int i;
184
185 for (i = 0; i < len; i++)
186 {
187 if (((src[src_idx/8] >> (src_idx % 8)) & 1) == 1)
188 dst[dst_idx/8] |= 1 << (dst_idx%8);
189 else
190 dst[dst_idx/8] &= ~(1 << (dst_idx%8));
191 dst_idx++;
192 src_idx++;
193 }
194
195 return dst;
196 }
197
198 u32 flip_u32(u32 value, unsigned int num)
199 {
200 u32 c;
201
202 c = (bit_reverse_table256[value & 0xff] << 24) |
203 (bit_reverse_table256[(value >> 8) & 0xff] << 16) |
204 (bit_reverse_table256[(value >> 16) & 0xff] << 8) |
205 (bit_reverse_table256[(value >> 24) & 0xff]);
206
207 if (num < 32)
208 c = c >> (32 - num);
209
210 return c;
211 }
212
213 int ceil_f_to_u32(float x)
214 {
215 u32 y;
216
217 if (x < 0) /* return zero for negative numbers */
218 return 0;
219
220 y = x; /* cut off fraction */
221
222 if ((x - y) > 0.0) /* if there was a fractional part, increase by one */
223 y++;
224
225 return y;
226 }
227
228 char* buf_to_str(u8 *buf, int buf_len, int radix)
229 {
230 const char *DIGITS = "0123456789abcdef";
231 float factor;
232 char *str;
233 int str_len;
234 int b256_len = CEIL(buf_len, 8);
235 u32 tmp;
236
237 int j; /* base-256 digits */
238 int i; /* output digits (radix) */
239
240 if (radix == 16)
241 {
242 factor = 2.0; /* log(256) / log(16) = 2.0 */
243 }
244 else if (radix == 10)
245 {
246 factor = 2.40824; /* log(256) / log(10) = 2.40824 */
247 }
248 else if (radix == 8)
249 {
250 factor = 2.66667; /* log(256) / log(8) = 2.66667 */
251 }
252 else
253 return NULL;
254
255 str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor);
256 str = calloc(str_len + 1, 1);
257
258 for (i = b256_len - 1; i >= 0; i--)
259 {
260 tmp = buf[i];
261 if ((i == (buf_len / 8)) && (buf_len % 8))
262 tmp &= (0xff >> (8 - (buf_len % 8)));
263
264 for (j = str_len; j > 0; j--)
265 {
266 tmp += (u32)str[j-1] * 256;
267 str[j-1] = (u8)(tmp % radix);
268 tmp /= radix;
269 }
270 }
271
272 for (j = 0; j < str_len; j++)
273 str[j] = DIGITS[(int)str[j]];
274
275 return str;
276 }
277
278 int str_to_buf(char* str, int str_len, u8 *buf, int buf_len, int radix)
279 {
280 char *charbuf;
281 u32 tmp;
282 float factor;
283 u8 *b256_buf;
284 int b256_len;
285
286 int j; /* base-256 digits */
287 int i; /* input digits (ASCII) */
288
289 if (radix == 0)
290 {
291 /* identify radix, and skip radix-prefix (0, 0x or 0X) */
292 if ((str[0] == '0') && (str[1] && ((str[1] == 'x') || (str[1] == 'X'))))
293 {
294 radix = 16;
295 str += 2;
296 str_len -= 2;
297 }
298 else if ((str[0] == '0') && (str_len != 1))
299 {
300 radix = 8;
301 str += 1;
302 str_len -= 1;
303 }
304 else
305 {
306 radix = 10;
307 }
308 }
309
310 if (radix == 16)
311 factor = 0.5; /* log(16) / log(256) = 0.5 */
312 else if (radix == 10)
313 factor = 0.41524; /* log(10) / log(256) = 0.41524 */
314 else if (radix == 8)
315 factor = 0.375; /* log(8) / log(256) = 0.375 */
316 else
317 return 0;
318
319 /* copy to zero-terminated buffer */
320 charbuf = malloc(str_len + 1);
321 memcpy(charbuf, str, str_len);
322 charbuf[str_len] = '\0';
323
324 /* number of digits in base-256 notation */
325 b256_len = ceil_f_to_u32(str_len * factor);
326 b256_buf = calloc(b256_len, 1);
327
328 /* go through zero terminated buffer */
329 for (i = 0; charbuf[i]; i++)
330 {
331 tmp = charbuf[i];
332 if ((tmp >= '0') && (tmp <= '9'))
333 tmp = (tmp - '0');
334 else if ((tmp >= 'a') && (tmp <= 'f'))
335 tmp = (tmp - 'a' + 10);
336 else if ((tmp >= 'A') && (tmp <= 'F'))
337 tmp = (tmp - 'A' + 10);
338 else continue; /* skip characters other than [0-9,a-f,A-F] */
339
340 if (tmp >= radix)
341 continue; /* skip digits invalid for the current radix */
342
343 for (j = 0; j < b256_len; j++)
344 {
345 tmp += (u32)b256_buf[j] * radix;
346 b256_buf[j] = (u8)(tmp & 0xFF);
347 tmp >>= 8;
348 }
349
350 }
351
352 for (j = 0; j < CEIL(buf_len, 8); j++)
353 {
354 if (j < b256_len)
355 buf[j] = b256_buf[j];
356 else
357 buf[j] = 0;
358 }
359
360 /* mask out bits that don't belong to the buffer */
361 if (buf_len % 8)
362 buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));
363
364 free(b256_buf);
365 free(charbuf);
366
367 return i;
368 }
369
370 int buf_to_u32_handler(u8 *in_buf, void *priv, struct scan_field_s *field)
371 {
372 u32 *dest = priv;
373
374 *dest = buf_get_u32(in_buf, 0, 32);
375
376 return ERROR_OK;
377 }

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)