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

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)