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

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)