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

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)