image: fix binary detection for small files
[openocd.git] / src / target / image.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2007 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 * *
7 * Copyright (C) 2007,2008 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
9 * *
10 * Copyright (C) 2008 by Spencer Oliver *
11 * spen@spen-soft.co.uk *
12 * *
13 * Copyright (C) 2009 by Franck Hereson *
14 * franck.hereson@secad.fr *
15 * *
16 * Copyright (C) 2018 by Advantest *
17 * florian.meister@advantest.com *
18 ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "image.h"
25 #include "target.h"
26 #include <helper/log.h>
27
28 /* convert ELF header field to host endianness */
29 #define field16(elf, field) \
30 ((elf->endianness == ELFDATA2LSB) ? \
31 le_to_h_u16((uint8_t *)&field) : be_to_h_u16((uint8_t *)&field))
32
33 #define field32(elf, field) \
34 ((elf->endianness == ELFDATA2LSB) ? \
35 le_to_h_u32((uint8_t *)&field) : be_to_h_u32((uint8_t *)&field))
36
37 #define field64(elf, field) \
38 ((elf->endianness == ELFDATA2LSB) ? \
39 le_to_h_u64((uint8_t *)&field) : be_to_h_u64((uint8_t *)&field))
40
41 static int autodetect_image_type(struct image *image, const char *url)
42 {
43 int retval;
44 struct fileio *fileio;
45 size_t read_bytes;
46 uint8_t buffer[9];
47
48 /* read the first 9 bytes of image */
49 retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY);
50 if (retval != ERROR_OK)
51 return retval;
52 retval = fileio_read(fileio, 9, buffer, &read_bytes);
53 fileio_close(fileio);
54
55 /* If the file is smaller than 9 bytes, it can only be bin */
56 if (retval == ERROR_OK && read_bytes != 9) {
57 LOG_DEBUG("Less than 9 bytes in the image file found.");
58 LOG_DEBUG("BIN image detected.");
59 image->type = IMAGE_BINARY;
60 return ERROR_OK;
61 }
62
63 if (retval != ERROR_OK)
64 return retval;
65
66 /* check header against known signatures */
67 if (strncmp((char *)buffer, ELFMAG, SELFMAG) == 0) {
68 LOG_DEBUG("ELF image detected.");
69 image->type = IMAGE_ELF;
70 } else if ((buffer[0] == ':') /* record start byte */
71 && (isxdigit(buffer[1]))
72 && (isxdigit(buffer[2]))
73 && (isxdigit(buffer[3]))
74 && (isxdigit(buffer[4]))
75 && (isxdigit(buffer[5]))
76 && (isxdigit(buffer[6]))
77 && (buffer[7] == '0') /* record type : 00 -> 05 */
78 && (buffer[8] >= '0') && (buffer[8] < '6')) {
79 LOG_DEBUG("IHEX image detected.");
80 image->type = IMAGE_IHEX;
81 } else if ((buffer[0] == 'S') /* record start byte */
82 && (isxdigit(buffer[1]))
83 && (isxdigit(buffer[2]))
84 && (isxdigit(buffer[3]))
85 && (buffer[1] >= '0') && (buffer[1] < '9')) {
86 LOG_DEBUG("S19 image detected.");
87 image->type = IMAGE_SRECORD;
88 } else {
89 LOG_DEBUG("BIN image detected.");
90 image->type = IMAGE_BINARY;
91 }
92
93 return ERROR_OK;
94 }
95
96 static int identify_image_type(struct image *image, const char *type_string, const char *url)
97 {
98 if (type_string) {
99 if (!strcmp(type_string, "bin"))
100 image->type = IMAGE_BINARY;
101 else if (!strcmp(type_string, "ihex"))
102 image->type = IMAGE_IHEX;
103 else if (!strcmp(type_string, "elf"))
104 image->type = IMAGE_ELF;
105 else if (!strcmp(type_string, "mem"))
106 image->type = IMAGE_MEMORY;
107 else if (!strcmp(type_string, "s19"))
108 image->type = IMAGE_SRECORD;
109 else if (!strcmp(type_string, "build"))
110 image->type = IMAGE_BUILDER;
111 else
112 return ERROR_IMAGE_TYPE_UNKNOWN;
113 } else
114 return autodetect_image_type(image, url);
115
116 return ERROR_OK;
117 }
118
119 static int image_ihex_buffer_complete_inner(struct image *image,
120 char *lpsz_line,
121 struct imagesection *section)
122 {
123 struct image_ihex *ihex = image->type_private;
124 struct fileio *fileio = ihex->fileio;
125 uint32_t full_address;
126 uint32_t cooked_bytes;
127 bool end_rec = false;
128
129 /* we can't determine the number of sections that we'll have to create ahead of time,
130 * so we locally hold them until parsing is finished */
131
132 size_t filesize;
133 int retval;
134 retval = fileio_size(fileio, &filesize);
135 if (retval != ERROR_OK)
136 return retval;
137
138 ihex->buffer = malloc(filesize >> 1);
139 cooked_bytes = 0x0;
140 image->num_sections = 0;
141
142 while (!fileio_feof(fileio)) {
143 full_address = 0x0;
144 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
145 section[image->num_sections].base_address = 0x0;
146 section[image->num_sections].size = 0x0;
147 section[image->num_sections].flags = 0;
148
149 while (fileio_fgets(fileio, 1023, lpsz_line) == ERROR_OK) {
150 uint32_t count;
151 uint32_t address;
152 uint32_t record_type;
153 uint32_t checksum;
154 uint8_t cal_checksum = 0;
155 size_t bytes_read = 0;
156
157 /* skip comments and blank lines */
158 if ((lpsz_line[0] == '#') || (strlen(lpsz_line + strspn(lpsz_line, "\n\t\r ")) == 0))
159 continue;
160
161 if (sscanf(&lpsz_line[bytes_read], ":%2" SCNx32 "%4" SCNx32 "%2" SCNx32, &count,
162 &address, &record_type) != 3)
163 return ERROR_IMAGE_FORMAT_ERROR;
164 bytes_read += 9;
165
166 cal_checksum += (uint8_t)count;
167 cal_checksum += (uint8_t)(address >> 8);
168 cal_checksum += (uint8_t)address;
169 cal_checksum += (uint8_t)record_type;
170
171 if (record_type == 0) { /* Data Record */
172 if ((full_address & 0xffff) != address) {
173 /* we encountered a nonconsecutive location, create a new section,
174 * unless the current section has zero size, in which case this specifies
175 * the current section's base address
176 */
177 if (section[image->num_sections].size != 0) {
178 image->num_sections++;
179 if (image->num_sections >= IMAGE_MAX_SECTIONS) {
180 /* too many sections */
181 LOG_ERROR("Too many sections found in IHEX file");
182 return ERROR_IMAGE_FORMAT_ERROR;
183 }
184 section[image->num_sections].size = 0x0;
185 section[image->num_sections].flags = 0;
186 section[image->num_sections].private =
187 &ihex->buffer[cooked_bytes];
188 }
189 section[image->num_sections].base_address =
190 (full_address & 0xffff0000) | address;
191 full_address = (full_address & 0xffff0000) | address;
192 }
193
194 while (count-- > 0) {
195 unsigned value;
196 sscanf(&lpsz_line[bytes_read], "%2x", &value);
197 ihex->buffer[cooked_bytes] = (uint8_t)value;
198 cal_checksum += (uint8_t)ihex->buffer[cooked_bytes];
199 bytes_read += 2;
200 cooked_bytes += 1;
201 section[image->num_sections].size += 1;
202 full_address++;
203 }
204 } else if (record_type == 1) { /* End of File Record */
205 /* finish the current section */
206 image->num_sections++;
207
208 /* copy section information */
209 image->sections = malloc(sizeof(struct imagesection) * image->num_sections);
210 for (unsigned int i = 0; i < image->num_sections; i++) {
211 image->sections[i].private = section[i].private;
212 image->sections[i].base_address = section[i].base_address;
213 image->sections[i].size = section[i].size;
214 image->sections[i].flags = section[i].flags;
215 }
216
217 end_rec = true;
218 break;
219 } else if (record_type == 2) { /* Linear Address Record */
220 uint16_t upper_address;
221
222 sscanf(&lpsz_line[bytes_read], "%4hx", &upper_address);
223 cal_checksum += (uint8_t)(upper_address >> 8);
224 cal_checksum += (uint8_t)upper_address;
225 bytes_read += 4;
226
227 if ((full_address >> 4) != upper_address) {
228 /* we encountered a nonconsecutive location, create a new section,
229 * unless the current section has zero size, in which case this specifies
230 * the current section's base address
231 */
232 if (section[image->num_sections].size != 0) {
233 image->num_sections++;
234 if (image->num_sections >= IMAGE_MAX_SECTIONS) {
235 /* too many sections */
236 LOG_ERROR("Too many sections found in IHEX file");
237 return ERROR_IMAGE_FORMAT_ERROR;
238 }
239 section[image->num_sections].size = 0x0;
240 section[image->num_sections].flags = 0;
241 section[image->num_sections].private =
242 &ihex->buffer[cooked_bytes];
243 }
244 section[image->num_sections].base_address =
245 (full_address & 0xffff) | (upper_address << 4);
246 full_address = (full_address & 0xffff) | (upper_address << 4);
247 }
248 } else if (record_type == 3) { /* Start Segment Address Record */
249 uint32_t dummy;
250
251 /* "Start Segment Address Record" will not be supported
252 * but we must consume it, and do not create an error. */
253 while (count-- > 0) {
254 sscanf(&lpsz_line[bytes_read], "%2" SCNx32, &dummy);
255 cal_checksum += (uint8_t)dummy;
256 bytes_read += 2;
257 }
258 } else if (record_type == 4) { /* Extended Linear Address Record */
259 uint16_t upper_address;
260
261 sscanf(&lpsz_line[bytes_read], "%4hx", &upper_address);
262 cal_checksum += (uint8_t)(upper_address >> 8);
263 cal_checksum += (uint8_t)upper_address;
264 bytes_read += 4;
265
266 if ((full_address >> 16) != upper_address) {
267 /* we encountered a nonconsecutive location, create a new section,
268 * unless the current section has zero size, in which case this specifies
269 * the current section's base address
270 */
271 if (section[image->num_sections].size != 0) {
272 image->num_sections++;
273 if (image->num_sections >= IMAGE_MAX_SECTIONS) {
274 /* too many sections */
275 LOG_ERROR("Too many sections found in IHEX file");
276 return ERROR_IMAGE_FORMAT_ERROR;
277 }
278 section[image->num_sections].size = 0x0;
279 section[image->num_sections].flags = 0;
280 section[image->num_sections].private =
281 &ihex->buffer[cooked_bytes];
282 }
283 section[image->num_sections].base_address =
284 (full_address & 0xffff) | (upper_address << 16);
285 full_address = (full_address & 0xffff) | (upper_address << 16);
286 }
287 } else if (record_type == 5) { /* Start Linear Address Record */
288 uint32_t start_address;
289
290 sscanf(&lpsz_line[bytes_read], "%8" SCNx32, &start_address);
291 cal_checksum += (uint8_t)(start_address >> 24);
292 cal_checksum += (uint8_t)(start_address >> 16);
293 cal_checksum += (uint8_t)(start_address >> 8);
294 cal_checksum += (uint8_t)start_address;
295 bytes_read += 8;
296
297 image->start_address_set = true;
298 image->start_address = be_to_h_u32((uint8_t *)&start_address);
299 } else {
300 LOG_ERROR("unhandled IHEX record type: %i", (int)record_type);
301 return ERROR_IMAGE_FORMAT_ERROR;
302 }
303
304 sscanf(&lpsz_line[bytes_read], "%2" SCNx32, &checksum);
305
306 if ((uint8_t)checksum != (uint8_t)(~cal_checksum + 1)) {
307 /* checksum failed */
308 LOG_ERROR("incorrect record checksum found in IHEX file");
309 return ERROR_IMAGE_CHECKSUM;
310 }
311
312 if (end_rec) {
313 end_rec = false;
314 LOG_WARNING("continuing after end-of-file record: %.40s", lpsz_line);
315 }
316 }
317 }
318
319 if (end_rec)
320 return ERROR_OK;
321 else {
322 LOG_ERROR("premature end of IHEX file, no matching end-of-file record found");
323 return ERROR_IMAGE_FORMAT_ERROR;
324 }
325 }
326
327 /**
328 * Allocate memory dynamically instead of on the stack. This
329 * is important w/embedded hosts.
330 */
331 static int image_ihex_buffer_complete(struct image *image)
332 {
333 char *lpsz_line = malloc(1023);
334 if (!lpsz_line) {
335 LOG_ERROR("Out of memory");
336 return ERROR_FAIL;
337 }
338 struct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS);
339 if (!section) {
340 free(lpsz_line);
341 LOG_ERROR("Out of memory");
342 return ERROR_FAIL;
343 }
344 int retval;
345
346 retval = image_ihex_buffer_complete_inner(image, lpsz_line, section);
347
348 free(section);
349 free(lpsz_line);
350
351 return retval;
352 }
353
354 static int image_elf32_read_headers(struct image *image)
355 {
356 struct image_elf *elf = image->type_private;
357 size_t read_bytes;
358 uint32_t i, j;
359 int retval;
360 uint32_t nload;
361 bool load_to_vaddr = false;
362
363 retval = fileio_seek(elf->fileio, 0);
364 if (retval != ERROR_OK) {
365 LOG_ERROR("cannot seek to ELF file header, read failed");
366 return retval;
367 }
368
369 elf->header32 = malloc(sizeof(Elf32_Ehdr));
370
371 if (!elf->header32) {
372 LOG_ERROR("insufficient memory to perform operation");
373 return ERROR_FILEIO_OPERATION_FAILED;
374 }
375
376 retval = fileio_read(elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header32, &read_bytes);
377 if (retval != ERROR_OK) {
378 LOG_ERROR("cannot read ELF file header, read failed");
379 return ERROR_FILEIO_OPERATION_FAILED;
380 }
381 if (read_bytes != sizeof(Elf32_Ehdr)) {
382 LOG_ERROR("cannot read ELF file header, only partially read");
383 return ERROR_FILEIO_OPERATION_FAILED;
384 }
385
386 elf->segment_count = field16(elf, elf->header32->e_phnum);
387 if (elf->segment_count == 0) {
388 LOG_ERROR("invalid ELF file, no program headers");
389 return ERROR_IMAGE_FORMAT_ERROR;
390 }
391
392 retval = fileio_seek(elf->fileio, field32(elf, elf->header32->e_phoff));
393 if (retval != ERROR_OK) {
394 LOG_ERROR("cannot seek to ELF program header table, read failed");
395 return retval;
396 }
397
398 elf->segments32 = malloc(elf->segment_count*sizeof(Elf32_Phdr));
399 if (!elf->segments32) {
400 LOG_ERROR("insufficient memory to perform operation");
401 return ERROR_FILEIO_OPERATION_FAILED;
402 }
403
404 retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf32_Phdr),
405 (uint8_t *)elf->segments32, &read_bytes);
406 if (retval != ERROR_OK) {
407 LOG_ERROR("cannot read ELF segment headers, read failed");
408 return retval;
409 }
410 if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr)) {
411 LOG_ERROR("cannot read ELF segment headers, only partially read");
412 return ERROR_FILEIO_OPERATION_FAILED;
413 }
414
415 /* count useful segments (loadable), ignore BSS section */
416 image->num_sections = 0;
417 for (i = 0; i < elf->segment_count; i++)
418 if ((field32(elf,
419 elf->segments32[i].p_type) == PT_LOAD) &&
420 (field32(elf, elf->segments32[i].p_filesz) != 0))
421 image->num_sections++;
422
423 if (image->num_sections == 0) {
424 LOG_ERROR("invalid ELF file, no loadable segments");
425 return ERROR_IMAGE_FORMAT_ERROR;
426 }
427
428 /**
429 * some ELF linkers produce binaries with *all* the program header
430 * p_paddr fields zero (there can be however one loadable segment
431 * that has valid physical address 0x0).
432 * If we have such a binary with more than
433 * one PT_LOAD header, then use p_vaddr instead of p_paddr
434 * (ARM ELF standard demands p_paddr = 0 anyway, and BFD
435 * library uses this approach to workaround zero-initialized p_paddrs
436 * when obtaining lma - look at elf.c of BDF)
437 */
438 for (nload = 0, i = 0; i < elf->segment_count; i++)
439 if (elf->segments32[i].p_paddr != 0)
440 break;
441 else if ((field32(elf,
442 elf->segments32[i].p_type) == PT_LOAD) &&
443 (field32(elf, elf->segments32[i].p_memsz) != 0))
444 ++nload;
445
446 if (i >= elf->segment_count && nload > 1)
447 load_to_vaddr = true;
448
449 /* alloc and fill sections array with loadable segments */
450 image->sections = malloc(image->num_sections * sizeof(struct imagesection));
451 if (!image->sections) {
452 LOG_ERROR("insufficient memory to perform operation");
453 return ERROR_FILEIO_OPERATION_FAILED;
454 }
455
456 for (i = 0, j = 0; i < elf->segment_count; i++) {
457 if ((field32(elf,
458 elf->segments32[i].p_type) == PT_LOAD) &&
459 (field32(elf, elf->segments32[i].p_filesz) != 0)) {
460 image->sections[j].size = field32(elf, elf->segments32[i].p_filesz);
461 if (load_to_vaddr)
462 image->sections[j].base_address = field32(elf,
463 elf->segments32[i].p_vaddr);
464 else
465 image->sections[j].base_address = field32(elf,
466 elf->segments32[i].p_paddr);
467 image->sections[j].private = &elf->segments32[i];
468 image->sections[j].flags = field32(elf, elf->segments32[i].p_flags);
469 j++;
470 }
471 }
472
473 image->start_address_set = true;
474 image->start_address = field32(elf, elf->header32->e_entry);
475
476 return ERROR_OK;
477 }
478
479 static int image_elf64_read_headers(struct image *image)
480 {
481 struct image_elf *elf = image->type_private;
482 size_t read_bytes;
483 uint32_t i, j;
484 int retval;
485 uint32_t nload;
486 bool load_to_vaddr = false;
487
488 retval = fileio_seek(elf->fileio, 0);
489 if (retval != ERROR_OK) {
490 LOG_ERROR("cannot seek to ELF file header, read failed");
491 return retval;
492 }
493
494 elf->header64 = malloc(sizeof(Elf64_Ehdr));
495
496 if (!elf->header64) {
497 LOG_ERROR("insufficient memory to perform operation");
498 return ERROR_FILEIO_OPERATION_FAILED;
499 }
500
501 retval = fileio_read(elf->fileio, sizeof(Elf64_Ehdr), (uint8_t *)elf->header64, &read_bytes);
502 if (retval != ERROR_OK) {
503 LOG_ERROR("cannot read ELF file header, read failed");
504 return ERROR_FILEIO_OPERATION_FAILED;
505 }
506 if (read_bytes != sizeof(Elf64_Ehdr)) {
507 LOG_ERROR("cannot read ELF file header, only partially read");
508 return ERROR_FILEIO_OPERATION_FAILED;
509 }
510
511 elf->segment_count = field16(elf, elf->header64->e_phnum);
512 if (elf->segment_count == 0) {
513 LOG_ERROR("invalid ELF file, no program headers");
514 return ERROR_IMAGE_FORMAT_ERROR;
515 }
516
517 retval = fileio_seek(elf->fileio, field64(elf, elf->header64->e_phoff));
518 if (retval != ERROR_OK) {
519 LOG_ERROR("cannot seek to ELF program header table, read failed");
520 return retval;
521 }
522
523 elf->segments64 = malloc(elf->segment_count*sizeof(Elf64_Phdr));
524 if (!elf->segments64) {
525 LOG_ERROR("insufficient memory to perform operation");
526 return ERROR_FILEIO_OPERATION_FAILED;
527 }
528
529 retval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf64_Phdr),
530 (uint8_t *)elf->segments64, &read_bytes);
531 if (retval != ERROR_OK) {
532 LOG_ERROR("cannot read ELF segment headers, read failed");
533 return retval;
534 }
535 if (read_bytes != elf->segment_count*sizeof(Elf64_Phdr)) {
536 LOG_ERROR("cannot read ELF segment headers, only partially read");
537 return ERROR_FILEIO_OPERATION_FAILED;
538 }
539
540 /* count useful segments (loadable), ignore BSS section */
541 image->num_sections = 0;
542 for (i = 0; i < elf->segment_count; i++)
543 if ((field32(elf,
544 elf->segments64[i].p_type) == PT_LOAD) &&
545 (field64(elf, elf->segments64[i].p_filesz) != 0))
546 image->num_sections++;
547
548 if (image->num_sections == 0) {
549 LOG_ERROR("invalid ELF file, no loadable segments");
550 return ERROR_IMAGE_FORMAT_ERROR;
551 }
552
553 /**
554 * some ELF linkers produce binaries with *all* the program header
555 * p_paddr fields zero (there can be however one loadable segment
556 * that has valid physical address 0x0).
557 * If we have such a binary with more than
558 * one PT_LOAD header, then use p_vaddr instead of p_paddr
559 * (ARM ELF standard demands p_paddr = 0 anyway, and BFD
560 * library uses this approach to workaround zero-initialized p_paddrs
561 * when obtaining lma - look at elf.c of BDF)
562 */
563 for (nload = 0, i = 0; i < elf->segment_count; i++)
564 if (elf->segments64[i].p_paddr != 0)
565 break;
566 else if ((field32(elf,
567 elf->segments64[i].p_type) == PT_LOAD) &&
568 (field64(elf, elf->segments64[i].p_memsz) != 0))
569 ++nload;
570
571 if (i >= elf->segment_count && nload > 1)
572 load_to_vaddr = true;
573
574 /* alloc and fill sections array with loadable segments */
575 image->sections = malloc(image->num_sections * sizeof(struct imagesection));
576 if (!image->sections) {
577 LOG_ERROR("insufficient memory to perform operation");
578 return ERROR_FILEIO_OPERATION_FAILED;
579 }
580
581 for (i = 0, j = 0; i < elf->segment_count; i++) {
582 if ((field32(elf,
583 elf->segments64[i].p_type) == PT_LOAD) &&
584 (field64(elf, elf->segments64[i].p_filesz) != 0)) {
585 image->sections[j].size = field64(elf, elf->segments64[i].p_filesz);
586 if (load_to_vaddr)
587 image->sections[j].base_address = field64(elf,
588 elf->segments64[i].p_vaddr);
589 else
590 image->sections[j].base_address = field64(elf,
591 elf->segments64[i].p_paddr);
592 image->sections[j].private = &elf->segments64[i];
593 image->sections[j].flags = field64(elf, elf->segments64[i].p_flags);
594 j++;
595 }
596 }
597
598 image->start_address_set = true;
599 image->start_address = field64(elf, elf->header64->e_entry);
600
601 return ERROR_OK;
602 }
603
604 static int image_elf_read_headers(struct image *image)
605 {
606 struct image_elf *elf = image->type_private;
607 size_t read_bytes;
608 unsigned char e_ident[EI_NIDENT];
609 int retval;
610
611 retval = fileio_read(elf->fileio, EI_NIDENT, e_ident, &read_bytes);
612 if (retval != ERROR_OK) {
613 LOG_ERROR("cannot read ELF file header, read failed");
614 return ERROR_FILEIO_OPERATION_FAILED;
615 }
616 if (read_bytes != EI_NIDENT) {
617 LOG_ERROR("cannot read ELF file header, only partially read");
618 return ERROR_FILEIO_OPERATION_FAILED;
619 }
620
621 if (strncmp((char *)e_ident, ELFMAG, SELFMAG) != 0) {
622 LOG_ERROR("invalid ELF file, bad magic number");
623 return ERROR_IMAGE_FORMAT_ERROR;
624 }
625
626 elf->endianness = e_ident[EI_DATA];
627 if ((elf->endianness != ELFDATA2LSB)
628 && (elf->endianness != ELFDATA2MSB)) {
629 LOG_ERROR("invalid ELF file, unknown endianness setting");
630 return ERROR_IMAGE_FORMAT_ERROR;
631 }
632
633 switch (e_ident[EI_CLASS]) {
634 case ELFCLASS32:
635 LOG_DEBUG("ELF32 image detected.");
636 elf->is_64_bit = false;
637 return image_elf32_read_headers(image);
638
639 case ELFCLASS64:
640 LOG_DEBUG("ELF64 image detected.");
641 elf->is_64_bit = true;
642 return image_elf64_read_headers(image);
643
644 default:
645 LOG_ERROR("invalid ELF file, only 32/64 bit ELF files are supported");
646 return ERROR_IMAGE_FORMAT_ERROR;
647 }
648 }
649
650 static int image_elf32_read_section(struct image *image,
651 int section,
652 target_addr_t offset,
653 uint32_t size,
654 uint8_t *buffer,
655 size_t *size_read)
656 {
657 struct image_elf *elf = image->type_private;
658 Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
659 size_t read_size, really_read;
660 int retval;
661
662 *size_read = 0;
663
664 LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size);
665
666 /* read initialized data in current segment if any */
667 if (offset < field32(elf, segment->p_filesz)) {
668 /* maximal size present in file for the current segment */
669 read_size = MIN(size, field32(elf, segment->p_filesz) - offset);
670 LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size,
671 field32(elf, segment->p_offset) + offset);
672 /* read initialized area of the segment */
673 retval = fileio_seek(elf->fileio, field32(elf, segment->p_offset) + offset);
674 if (retval != ERROR_OK) {
675 LOG_ERROR("cannot find ELF segment content, seek failed");
676 return retval;
677 }
678 retval = fileio_read(elf->fileio, read_size, buffer, &really_read);
679 if (retval != ERROR_OK) {
680 LOG_ERROR("cannot read ELF segment content, read failed");
681 return retval;
682 }
683 size -= read_size;
684 *size_read += read_size;
685 /* need more data ? */
686 if (!size)
687 return ERROR_OK;
688 }
689
690 return ERROR_OK;
691 }
692
693 static int image_elf64_read_section(struct image *image,
694 int section,
695 target_addr_t offset,
696 uint32_t size,
697 uint8_t *buffer,
698 size_t *size_read)
699 {
700 struct image_elf *elf = image->type_private;
701 Elf64_Phdr *segment = (Elf64_Phdr *)image->sections[section].private;
702 size_t read_size, really_read;
703 int retval;
704
705 *size_read = 0;
706
707 LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size);
708
709 /* read initialized data in current segment if any */
710 if (offset < field64(elf, segment->p_filesz)) {
711 /* maximal size present in file for the current segment */
712 read_size = MIN(size, field64(elf, segment->p_filesz) - offset);
713 LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size,
714 field64(elf, segment->p_offset) + offset);
715 /* read initialized area of the segment */
716 retval = fileio_seek(elf->fileio, field64(elf, segment->p_offset) + offset);
717 if (retval != ERROR_OK) {
718 LOG_ERROR("cannot find ELF segment content, seek failed");
719 return retval;
720 }
721 retval = fileio_read(elf->fileio, read_size, buffer, &really_read);
722 if (retval != ERROR_OK) {
723 LOG_ERROR("cannot read ELF segment content, read failed");
724 return retval;
725 }
726 size -= read_size;
727 *size_read += read_size;
728 /* need more data ? */
729 if (!size)
730 return ERROR_OK;
731 }
732
733 return ERROR_OK;
734 }
735
736 static int image_elf_read_section(struct image *image,
737 int section,
738 target_addr_t offset,
739 uint32_t size,
740 uint8_t *buffer,
741 size_t *size_read)
742 {
743 struct image_elf *elf = image->type_private;
744
745 if (elf->is_64_bit)
746 return image_elf64_read_section(image, section, offset, size, buffer, size_read);
747 else
748 return image_elf32_read_section(image, section, offset, size, buffer, size_read);
749 }
750
751 static int image_mot_buffer_complete_inner(struct image *image,
752 char *lpsz_line,
753 struct imagesection *section)
754 {
755 struct image_mot *mot = image->type_private;
756 struct fileio *fileio = mot->fileio;
757 uint32_t full_address;
758 uint32_t cooked_bytes;
759 bool end_rec = false;
760
761 /* we can't determine the number of sections that we'll have to create ahead of time,
762 * so we locally hold them until parsing is finished */
763
764 int retval;
765 size_t filesize;
766 retval = fileio_size(fileio, &filesize);
767 if (retval != ERROR_OK)
768 return retval;
769
770 mot->buffer = malloc(filesize >> 1);
771 cooked_bytes = 0x0;
772 image->num_sections = 0;
773
774 while (!fileio_feof(fileio)) {
775 full_address = 0x0;
776 section[image->num_sections].private = &mot->buffer[cooked_bytes];
777 section[image->num_sections].base_address = 0x0;
778 section[image->num_sections].size = 0x0;
779 section[image->num_sections].flags = 0;
780
781 while (fileio_fgets(fileio, 1023, lpsz_line) == ERROR_OK) {
782 uint32_t count;
783 uint32_t address;
784 uint32_t record_type;
785 uint32_t checksum;
786 uint8_t cal_checksum = 0;
787 uint32_t bytes_read = 0;
788
789 /* skip comments and blank lines */
790 if ((lpsz_line[0] == '#') || (strlen(lpsz_line + strspn(lpsz_line, "\n\t\r ")) == 0))
791 continue;
792
793 /* get record type and record length */
794 if (sscanf(&lpsz_line[bytes_read], "S%1" SCNx32 "%2" SCNx32, &record_type,
795 &count) != 2)
796 return ERROR_IMAGE_FORMAT_ERROR;
797
798 bytes_read += 4;
799 cal_checksum += (uint8_t)count;
800
801 /* skip checksum byte */
802 count -= 1;
803
804 if (record_type == 0) {
805 /* S0 - starting record (optional) */
806 int value;
807
808 while (count-- > 0) {
809 sscanf(&lpsz_line[bytes_read], "%2x", &value);
810 cal_checksum += (uint8_t)value;
811 bytes_read += 2;
812 }
813 } else if (record_type >= 1 && record_type <= 3) {
814 switch (record_type) {
815 case 1:
816 /* S1 - 16 bit address data record */
817 sscanf(&lpsz_line[bytes_read], "%4" SCNx32, &address);
818 cal_checksum += (uint8_t)(address >> 8);
819 cal_checksum += (uint8_t)address;
820 bytes_read += 4;
821 count -= 2;
822 break;
823
824 case 2:
825 /* S2 - 24 bit address data record */
826 sscanf(&lpsz_line[bytes_read], "%6" SCNx32, &address);
827 cal_checksum += (uint8_t)(address >> 16);
828 cal_checksum += (uint8_t)(address >> 8);
829 cal_checksum += (uint8_t)address;
830 bytes_read += 6;
831 count -= 3;
832 break;
833
834 case 3:
835 /* S3 - 32 bit address data record */
836 sscanf(&lpsz_line[bytes_read], "%8" SCNx32, &address);
837 cal_checksum += (uint8_t)(address >> 24);
838 cal_checksum += (uint8_t)(address >> 16);
839 cal_checksum += (uint8_t)(address >> 8);
840 cal_checksum += (uint8_t)address;
841 bytes_read += 8;
842 count -= 4;
843 break;
844
845 }
846
847 if (full_address != address) {
848 /* we encountered a nonconsecutive location, create a new section,
849 * unless the current section has zero size, in which case this specifies
850 * the current section's base address
851 */
852 if (section[image->num_sections].size != 0) {
853 image->num_sections++;
854 section[image->num_sections].size = 0x0;
855 section[image->num_sections].flags = 0;
856 section[image->num_sections].private =
857 &mot->buffer[cooked_bytes];
858 }
859 section[image->num_sections].base_address = address;
860 full_address = address;
861 }
862
863 while (count-- > 0) {
864 unsigned value;
865 sscanf(&lpsz_line[bytes_read], "%2x", &value);
866 mot->buffer[cooked_bytes] = (uint8_t)value;
867 cal_checksum += (uint8_t)mot->buffer[cooked_bytes];
868 bytes_read += 2;
869 cooked_bytes += 1;
870 section[image->num_sections].size += 1;
871 full_address++;
872 }
873 } else if (record_type == 5 || record_type == 6) {
874 /* S5 and S6 are the data count records, we ignore them */
875 uint32_t dummy;
876
877 while (count-- > 0) {
878 sscanf(&lpsz_line[bytes_read], "%2" SCNx32, &dummy);
879 cal_checksum += (uint8_t)dummy;
880 bytes_read += 2;
881 }
882 } else if (record_type >= 7 && record_type <= 9) {
883 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
884 image->num_sections++;
885
886 /* copy section information */
887 image->sections = malloc(sizeof(struct imagesection) * image->num_sections);
888 for (unsigned int i = 0; i < image->num_sections; i++) {
889 image->sections[i].private = section[i].private;
890 image->sections[i].base_address = section[i].base_address;
891 image->sections[i].size = section[i].size;
892 image->sections[i].flags = section[i].flags;
893 }
894
895 end_rec = true;
896 break;
897 } else {
898 LOG_ERROR("unhandled S19 record type: %i", (int)(record_type));
899 return ERROR_IMAGE_FORMAT_ERROR;
900 }
901
902 /* account for checksum, will always be 0xFF */
903 sscanf(&lpsz_line[bytes_read], "%2" SCNx32, &checksum);
904 cal_checksum += (uint8_t)checksum;
905
906 if (cal_checksum != 0xFF) {
907 /* checksum failed */
908 LOG_ERROR("incorrect record checksum found in S19 file");
909 return ERROR_IMAGE_CHECKSUM;
910 }
911
912 if (end_rec) {
913 end_rec = false;
914 LOG_WARNING("continuing after end-of-file record: %.40s", lpsz_line);
915 }
916 }
917 }
918
919 if (end_rec)
920 return ERROR_OK;
921 else {
922 LOG_ERROR("premature end of S19 file, no matching end-of-file record found");
923 return ERROR_IMAGE_FORMAT_ERROR;
924 }
925 }
926
927 /**
928 * Allocate memory dynamically instead of on the stack. This
929 * is important w/embedded hosts.
930 */
931 static int image_mot_buffer_complete(struct image *image)
932 {
933 char *lpsz_line = malloc(1023);
934 if (!lpsz_line) {
935 LOG_ERROR("Out of memory");
936 return ERROR_FAIL;
937 }
938 struct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS);
939 if (!section) {
940 free(lpsz_line);
941 LOG_ERROR("Out of memory");
942 return ERROR_FAIL;
943 }
944 int retval;
945
946 retval = image_mot_buffer_complete_inner(image, lpsz_line, section);
947
948 free(section);
949 free(lpsz_line);
950
951 return retval;
952 }
953
954 int image_open(struct image *image, const char *url, const char *type_string)
955 {
956 int retval = ERROR_OK;
957
958 retval = identify_image_type(image, type_string, url);
959 if (retval != ERROR_OK)
960 return retval;
961
962 if (image->type == IMAGE_BINARY) {
963 struct image_binary *image_binary;
964
965 image_binary = image->type_private = malloc(sizeof(struct image_binary));
966
967 retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY);
968 if (retval != ERROR_OK)
969 return retval;
970 size_t filesize;
971 retval = fileio_size(image_binary->fileio, &filesize);
972 if (retval != ERROR_OK) {
973 fileio_close(image_binary->fileio);
974 return retval;
975 }
976
977 image->num_sections = 1;
978 image->sections = malloc(sizeof(struct imagesection));
979 image->sections[0].base_address = 0x0;
980 image->sections[0].size = filesize;
981 image->sections[0].flags = 0;
982 } else if (image->type == IMAGE_IHEX) {
983 struct image_ihex *image_ihex;
984
985 image_ihex = image->type_private = malloc(sizeof(struct image_ihex));
986
987 retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT);
988 if (retval != ERROR_OK)
989 return retval;
990
991 retval = image_ihex_buffer_complete(image);
992 if (retval != ERROR_OK) {
993 LOG_ERROR(
994 "failed buffering IHEX image, check server output for additional information");
995 fileio_close(image_ihex->fileio);
996 return retval;
997 }
998 } else if (image->type == IMAGE_ELF) {
999 struct image_elf *image_elf;
1000
1001 image_elf = image->type_private = malloc(sizeof(struct image_elf));
1002
1003 retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY);
1004 if (retval != ERROR_OK)
1005 return retval;
1006
1007 retval = image_elf_read_headers(image);
1008 if (retval != ERROR_OK) {
1009 fileio_close(image_elf->fileio);
1010 return retval;
1011 }
1012 } else if (image->type == IMAGE_MEMORY) {
1013 struct target *target = get_target(url);
1014
1015 if (!target) {
1016 LOG_ERROR("target '%s' not defined", url);
1017 return ERROR_FAIL;
1018 }
1019
1020 struct image_memory *image_memory;
1021
1022 image->num_sections = 1;
1023 image->sections = malloc(sizeof(struct imagesection));
1024 image->sections[0].base_address = 0x0;
1025 image->sections[0].size = 0xffffffff;
1026 image->sections[0].flags = 0;
1027
1028 image_memory = image->type_private = malloc(sizeof(struct image_memory));
1029
1030 image_memory->target = target;
1031 image_memory->cache = NULL;
1032 image_memory->cache_address = 0x0;
1033 } else if (image->type == IMAGE_SRECORD) {
1034 struct image_mot *image_mot;
1035
1036 image_mot = image->type_private = malloc(sizeof(struct image_mot));
1037
1038 retval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT);
1039 if (retval != ERROR_OK)
1040 return retval;
1041
1042 retval = image_mot_buffer_complete(image);
1043 if (retval != ERROR_OK) {
1044 LOG_ERROR(
1045 "failed buffering S19 image, check server output for additional information");
1046 fileio_close(image_mot->fileio);
1047 return retval;
1048 }
1049 } else if (image->type == IMAGE_BUILDER) {
1050 image->num_sections = 0;
1051 image->base_address_set = false;
1052 image->sections = NULL;
1053 image->type_private = NULL;
1054 }
1055
1056 if (image->base_address_set) {
1057 /* relocate */
1058 for (unsigned int section = 0; section < image->num_sections; section++)
1059 image->sections[section].base_address += image->base_address;
1060 /* we're done relocating. The two statements below are mainly
1061 * for documentation purposes: stop anyone from empirically
1062 * thinking they should use these values henceforth. */
1063 image->base_address = 0;
1064 image->base_address_set = false;
1065 }
1066
1067 return retval;
1068 };
1069
1070 int image_read_section(struct image *image,
1071 int section,
1072 target_addr_t offset,
1073 uint32_t size,
1074 uint8_t *buffer,
1075 size_t *size_read)
1076 {
1077 int retval;
1078
1079 /* don't read past the end of a section */
1080 if (offset + size > image->sections[section].size) {
1081 LOG_DEBUG(
1082 "read past end of section: 0x%8.8" TARGET_PRIxADDR " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "",
1083 offset,
1084 size,
1085 image->sections[section].size);
1086 return ERROR_COMMAND_SYNTAX_ERROR;
1087 }
1088
1089 if (image->type == IMAGE_BINARY) {
1090 struct image_binary *image_binary = image->type_private;
1091
1092 /* only one section in a plain binary */
1093 if (section != 0)
1094 return ERROR_COMMAND_SYNTAX_ERROR;
1095
1096 /* seek to offset */
1097 retval = fileio_seek(image_binary->fileio, offset);
1098 if (retval != ERROR_OK)
1099 return retval;
1100
1101 /* return requested bytes */
1102 retval = fileio_read(image_binary->fileio, size, buffer, size_read);
1103 if (retval != ERROR_OK)
1104 return retval;
1105 } else if (image->type == IMAGE_IHEX) {
1106 memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);
1107 *size_read = size;
1108
1109 return ERROR_OK;
1110 } else if (image->type == IMAGE_ELF) {
1111 return image_elf_read_section(image, section, offset, size, buffer, size_read);
1112 } else if (image->type == IMAGE_MEMORY) {
1113 struct image_memory *image_memory = image->type_private;
1114 uint32_t address = image->sections[section].base_address + offset;
1115
1116 *size_read = 0;
1117
1118 while ((size - *size_read) > 0) {
1119 uint32_t size_in_cache;
1120
1121 if (!image_memory->cache
1122 || (address < image_memory->cache_address)
1123 || (address >=
1124 (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE))) {
1125 if (!image_memory->cache)
1126 image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);
1127
1128 if (target_read_buffer(image_memory->target, address &
1129 ~(IMAGE_MEMORY_CACHE_SIZE - 1),
1130 IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK) {
1131 free(image_memory->cache);
1132 image_memory->cache = NULL;
1133 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
1134 }
1135 image_memory->cache_address = address &
1136 ~(IMAGE_MEMORY_CACHE_SIZE - 1);
1137 }
1138
1139 size_in_cache =
1140 (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;
1141
1142 memcpy(buffer + *size_read,
1143 image_memory->cache + (address - image_memory->cache_address),
1144 (size_in_cache > size) ? size : size_in_cache
1145 );
1146
1147 *size_read += (size_in_cache > size) ? size : size_in_cache;
1148 address += (size_in_cache > size) ? size : size_in_cache;
1149 }
1150 } else if (image->type == IMAGE_SRECORD) {
1151 memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);
1152 *size_read = size;
1153
1154 return ERROR_OK;
1155 } else if (image->type == IMAGE_BUILDER) {
1156 memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);
1157 *size_read = size;
1158
1159 return ERROR_OK;
1160 }
1161
1162 return ERROR_OK;
1163 }
1164
1165 int image_add_section(struct image *image, target_addr_t base, uint32_t size, uint64_t flags, uint8_t const *data)
1166 {
1167 struct imagesection *section;
1168
1169 /* only image builder supports adding sections */
1170 if (image->type != IMAGE_BUILDER)
1171 return ERROR_COMMAND_SYNTAX_ERROR;
1172
1173 /* see if there's a previous section */
1174 if (image->num_sections) {
1175 section = &image->sections[image->num_sections - 1];
1176
1177 /* see if it's enough to extend the last section,
1178 * adding data to previous sections or merging is not supported */
1179 if (((section->base_address + section->size) == base) &&
1180 (section->flags == flags)) {
1181 section->private = realloc(section->private, section->size + size);
1182 memcpy((uint8_t *)section->private + section->size, data, size);
1183 section->size += size;
1184 return ERROR_OK;
1185 }
1186 }
1187
1188 /* allocate new section */
1189 image->num_sections++;
1190 image->sections =
1191 realloc(image->sections, sizeof(struct imagesection) * image->num_sections);
1192 section = &image->sections[image->num_sections - 1];
1193 section->base_address = base;
1194 section->size = size;
1195 section->flags = flags;
1196 section->private = malloc(sizeof(uint8_t) * size);
1197 memcpy((uint8_t *)section->private, data, size);
1198
1199 return ERROR_OK;
1200 }
1201
1202 void image_close(struct image *image)
1203 {
1204 if (image->type == IMAGE_BINARY) {
1205 struct image_binary *image_binary = image->type_private;
1206
1207 fileio_close(image_binary->fileio);
1208 } else if (image->type == IMAGE_IHEX) {
1209 struct image_ihex *image_ihex = image->type_private;
1210
1211 fileio_close(image_ihex->fileio);
1212
1213 free(image_ihex->buffer);
1214 image_ihex->buffer = NULL;
1215 } else if (image->type == IMAGE_ELF) {
1216 struct image_elf *image_elf = image->type_private;
1217
1218 fileio_close(image_elf->fileio);
1219
1220 if (image_elf->is_64_bit) {
1221 free(image_elf->header64);
1222 image_elf->header64 = NULL;
1223
1224 free(image_elf->segments64);
1225 image_elf->segments64 = NULL;
1226 } else {
1227 free(image_elf->header32);
1228 image_elf->header32 = NULL;
1229
1230 free(image_elf->segments32);
1231 image_elf->segments32 = NULL;
1232 }
1233 } else if (image->type == IMAGE_MEMORY) {
1234 struct image_memory *image_memory = image->type_private;
1235
1236 free(image_memory->cache);
1237 image_memory->cache = NULL;
1238 } else if (image->type == IMAGE_SRECORD) {
1239 struct image_mot *image_mot = image->type_private;
1240
1241 fileio_close(image_mot->fileio);
1242
1243 free(image_mot->buffer);
1244 image_mot->buffer = NULL;
1245 } else if (image->type == IMAGE_BUILDER) {
1246 for (unsigned int i = 0; i < image->num_sections; i++) {
1247 free(image->sections[i].private);
1248 image->sections[i].private = NULL;
1249 }
1250 }
1251
1252 free(image->type_private);
1253 image->type_private = NULL;
1254
1255 free(image->sections);
1256 image->sections = NULL;
1257 }
1258
1259 int image_calculate_checksum(const uint8_t *buffer, uint32_t nbytes, uint32_t *checksum)
1260 {
1261 uint32_t crc = 0xffffffff;
1262 LOG_DEBUG("Calculating checksum");
1263
1264 static uint32_t crc32_table[256];
1265
1266 static bool first_init;
1267 if (!first_init) {
1268 /* Initialize the CRC table and the decoding table. */
1269 unsigned int i, j, c;
1270 for (i = 0; i < 256; i++) {
1271 /* as per gdb */
1272 for (c = i << 24, j = 8; j > 0; --j)
1273 c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
1274 crc32_table[i] = c;
1275 }
1276
1277 first_init = true;
1278 }
1279
1280 while (nbytes > 0) {
1281 int run = nbytes;
1282 if (run > 32768)
1283 run = 32768;
1284 nbytes -= run;
1285 while (run--) {
1286 /* as per gdb */
1287 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
1288 }
1289 keep_alive();
1290 }
1291
1292 LOG_DEBUG("Calculating checksum done; checksum=0x%" PRIx32, crc);
1293
1294 *checksum = crc;
1295 return ERROR_OK;
1296 }

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)