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

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)