image: log error when unknown image type is specified
[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 return retval;
972 size_t filesize;
973 retval = fileio_size(image_binary->fileio, &filesize);
974 if (retval != ERROR_OK) {
975 fileio_close(image_binary->fileio);
976 return retval;
977 }
978
979 image->num_sections = 1;
980 image->sections = malloc(sizeof(struct imagesection));
981 image->sections[0].base_address = 0x0;
982 image->sections[0].size = filesize;
983 image->sections[0].flags = 0;
984 } else if (image->type == IMAGE_IHEX) {
985 struct image_ihex *image_ihex;
986
987 image_ihex = image->type_private = malloc(sizeof(struct image_ihex));
988
989 retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT);
990 if (retval != ERROR_OK)
991 return retval;
992
993 retval = image_ihex_buffer_complete(image);
994 if (retval != ERROR_OK) {
995 LOG_ERROR(
996 "failed buffering IHEX image, check server output for additional information");
997 fileio_close(image_ihex->fileio);
998 return retval;
999 }
1000 } else if (image->type == IMAGE_ELF) {
1001 struct image_elf *image_elf;
1002
1003 image_elf = image->type_private = malloc(sizeof(struct image_elf));
1004
1005 retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY);
1006 if (retval != ERROR_OK)
1007 return retval;
1008
1009 retval = image_elf_read_headers(image);
1010 if (retval != ERROR_OK) {
1011 fileio_close(image_elf->fileio);
1012 return retval;
1013 }
1014 } else if (image->type == IMAGE_MEMORY) {
1015 struct target *target = get_target(url);
1016
1017 if (!target) {
1018 LOG_ERROR("target '%s' not defined", url);
1019 return ERROR_FAIL;
1020 }
1021
1022 struct image_memory *image_memory;
1023
1024 image->num_sections = 1;
1025 image->sections = malloc(sizeof(struct imagesection));
1026 image->sections[0].base_address = 0x0;
1027 image->sections[0].size = 0xffffffff;
1028 image->sections[0].flags = 0;
1029
1030 image_memory = image->type_private = malloc(sizeof(struct image_memory));
1031
1032 image_memory->target = target;
1033 image_memory->cache = NULL;
1034 image_memory->cache_address = 0x0;
1035 } else if (image->type == IMAGE_SRECORD) {
1036 struct image_mot *image_mot;
1037
1038 image_mot = image->type_private = malloc(sizeof(struct image_mot));
1039
1040 retval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT);
1041 if (retval != ERROR_OK)
1042 return retval;
1043
1044 retval = image_mot_buffer_complete(image);
1045 if (retval != ERROR_OK) {
1046 LOG_ERROR(
1047 "failed buffering S19 image, check server output for additional information");
1048 fileio_close(image_mot->fileio);
1049 return retval;
1050 }
1051 } else if (image->type == IMAGE_BUILDER) {
1052 image->num_sections = 0;
1053 image->base_address_set = false;
1054 image->sections = NULL;
1055 image->type_private = NULL;
1056 }
1057
1058 if (image->base_address_set) {
1059 /* relocate */
1060 for (unsigned int section = 0; section < image->num_sections; section++)
1061 image->sections[section].base_address += image->base_address;
1062 /* we're done relocating. The two statements below are mainly
1063 * for documentation purposes: stop anyone from empirically
1064 * thinking they should use these values henceforth. */
1065 image->base_address = 0;
1066 image->base_address_set = false;
1067 }
1068
1069 return retval;
1070 };
1071
1072 int image_read_section(struct image *image,
1073 int section,
1074 target_addr_t offset,
1075 uint32_t size,
1076 uint8_t *buffer,
1077 size_t *size_read)
1078 {
1079 int retval;
1080
1081 /* don't read past the end of a section */
1082 if (offset + size > image->sections[section].size) {
1083 LOG_DEBUG(
1084 "read past end of section: 0x%8.8" TARGET_PRIxADDR " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "",
1085 offset,
1086 size,
1087 image->sections[section].size);
1088 return ERROR_COMMAND_SYNTAX_ERROR;
1089 }
1090
1091 if (image->type == IMAGE_BINARY) {
1092 struct image_binary *image_binary = image->type_private;
1093
1094 /* only one section in a plain binary */
1095 if (section != 0)
1096 return ERROR_COMMAND_SYNTAX_ERROR;
1097
1098 /* seek to offset */
1099 retval = fileio_seek(image_binary->fileio, offset);
1100 if (retval != ERROR_OK)
1101 return retval;
1102
1103 /* return requested bytes */
1104 retval = fileio_read(image_binary->fileio, size, buffer, size_read);
1105 if (retval != ERROR_OK)
1106 return retval;
1107 } else if (image->type == IMAGE_IHEX) {
1108 memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);
1109 *size_read = size;
1110
1111 return ERROR_OK;
1112 } else if (image->type == IMAGE_ELF) {
1113 return image_elf_read_section(image, section, offset, size, buffer, size_read);
1114 } else if (image->type == IMAGE_MEMORY) {
1115 struct image_memory *image_memory = image->type_private;
1116 uint32_t address = image->sections[section].base_address + offset;
1117
1118 *size_read = 0;
1119
1120 while ((size - *size_read) > 0) {
1121 uint32_t size_in_cache;
1122
1123 if (!image_memory->cache
1124 || (address < image_memory->cache_address)
1125 || (address >=
1126 (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE))) {
1127 if (!image_memory->cache)
1128 image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);
1129
1130 if (target_read_buffer(image_memory->target, address &
1131 ~(IMAGE_MEMORY_CACHE_SIZE - 1),
1132 IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK) {
1133 free(image_memory->cache);
1134 image_memory->cache = NULL;
1135 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
1136 }
1137 image_memory->cache_address = address &
1138 ~(IMAGE_MEMORY_CACHE_SIZE - 1);
1139 }
1140
1141 size_in_cache =
1142 (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;
1143
1144 memcpy(buffer + *size_read,
1145 image_memory->cache + (address - image_memory->cache_address),
1146 (size_in_cache > size) ? size : size_in_cache
1147 );
1148
1149 *size_read += (size_in_cache > size) ? size : size_in_cache;
1150 address += (size_in_cache > size) ? size : size_in_cache;
1151 }
1152 } else if (image->type == IMAGE_SRECORD) {
1153 memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);
1154 *size_read = size;
1155
1156 return ERROR_OK;
1157 } else if (image->type == IMAGE_BUILDER) {
1158 memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);
1159 *size_read = size;
1160
1161 return ERROR_OK;
1162 }
1163
1164 return ERROR_OK;
1165 }
1166
1167 int image_add_section(struct image *image, target_addr_t base, uint32_t size, uint64_t flags, uint8_t const *data)
1168 {
1169 struct imagesection *section;
1170
1171 /* only image builder supports adding sections */
1172 if (image->type != IMAGE_BUILDER)
1173 return ERROR_COMMAND_SYNTAX_ERROR;
1174
1175 /* see if there's a previous section */
1176 if (image->num_sections) {
1177 section = &image->sections[image->num_sections - 1];
1178
1179 /* see if it's enough to extend the last section,
1180 * adding data to previous sections or merging is not supported */
1181 if (((section->base_address + section->size) == base) &&
1182 (section->flags == flags)) {
1183 section->private = realloc(section->private, section->size + size);
1184 memcpy((uint8_t *)section->private + section->size, data, size);
1185 section->size += size;
1186 return ERROR_OK;
1187 }
1188 }
1189
1190 /* allocate new section */
1191 image->num_sections++;
1192 image->sections =
1193 realloc(image->sections, sizeof(struct imagesection) * image->num_sections);
1194 section = &image->sections[image->num_sections - 1];
1195 section->base_address = base;
1196 section->size = size;
1197 section->flags = flags;
1198 section->private = malloc(sizeof(uint8_t) * size);
1199 memcpy((uint8_t *)section->private, data, size);
1200
1201 return ERROR_OK;
1202 }
1203
1204 void image_close(struct image *image)
1205 {
1206 if (image->type == IMAGE_BINARY) {
1207 struct image_binary *image_binary = image->type_private;
1208
1209 fileio_close(image_binary->fileio);
1210 } else if (image->type == IMAGE_IHEX) {
1211 struct image_ihex *image_ihex = image->type_private;
1212
1213 fileio_close(image_ihex->fileio);
1214
1215 free(image_ihex->buffer);
1216 image_ihex->buffer = NULL;
1217 } else if (image->type == IMAGE_ELF) {
1218 struct image_elf *image_elf = image->type_private;
1219
1220 fileio_close(image_elf->fileio);
1221
1222 if (image_elf->is_64_bit) {
1223 free(image_elf->header64);
1224 image_elf->header64 = NULL;
1225
1226 free(image_elf->segments64);
1227 image_elf->segments64 = NULL;
1228 } else {
1229 free(image_elf->header32);
1230 image_elf->header32 = NULL;
1231
1232 free(image_elf->segments32);
1233 image_elf->segments32 = NULL;
1234 }
1235 } else if (image->type == IMAGE_MEMORY) {
1236 struct image_memory *image_memory = image->type_private;
1237
1238 free(image_memory->cache);
1239 image_memory->cache = NULL;
1240 } else if (image->type == IMAGE_SRECORD) {
1241 struct image_mot *image_mot = image->type_private;
1242
1243 fileio_close(image_mot->fileio);
1244
1245 free(image_mot->buffer);
1246 image_mot->buffer = NULL;
1247 } else if (image->type == IMAGE_BUILDER) {
1248 for (unsigned int i = 0; i < image->num_sections; i++) {
1249 free(image->sections[i].private);
1250 image->sections[i].private = NULL;
1251 }
1252 }
1253
1254 free(image->type_private);
1255 image->type_private = NULL;
1256
1257 free(image->sections);
1258 image->sections = NULL;
1259 }
1260
1261 int image_calculate_checksum(const uint8_t *buffer, uint32_t nbytes, uint32_t *checksum)
1262 {
1263 uint32_t crc = 0xffffffff;
1264 LOG_DEBUG("Calculating checksum");
1265
1266 static uint32_t crc32_table[256];
1267
1268 static bool first_init;
1269 if (!first_init) {
1270 /* Initialize the CRC table and the decoding table. */
1271 unsigned int i, j, c;
1272 for (i = 0; i < 256; i++) {
1273 /* as per gdb */
1274 for (c = i << 24, j = 8; j > 0; --j)
1275 c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
1276 crc32_table[i] = c;
1277 }
1278
1279 first_init = true;
1280 }
1281
1282 while (nbytes > 0) {
1283 int run = nbytes;
1284 if (run > 32768)
1285 run = 32768;
1286 nbytes -= run;
1287 while (run--) {
1288 /* as per gdb */
1289 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
1290 }
1291 keep_alive();
1292 }
1293
1294 LOG_DEBUG("Calculating checksum done; checksum=0x%" PRIx32, crc);
1295
1296 *checksum = crc;
1297 return ERROR_OK;
1298 }

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)