1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2009 by Franck Hereson *
12 * franck.hereson@secad.fr *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
28 ***************************************************************************/
36 #include <helper/log.h>
38 /* convert ELF header field to host endianness */
39 #define field16(elf, field) \
40 ((elf->endianness == ELFDATA2LSB) ? \
41 le_to_h_u16((uint8_t *)&field) : be_to_h_u16((uint8_t *)&field))
43 #define field32(elf, field) \
44 ((elf->endianness == ELFDATA2LSB) ? \
45 le_to_h_u32((uint8_t *)&field) : be_to_h_u32((uint8_t *)&field))
47 static int autodetect_image_type(struct image
*image
, const char *url
)
54 /* read the first 4 bytes of image */
55 retval
= fileio_open(&fileio
, url
, FILEIO_READ
, FILEIO_BINARY
);
56 if (retval
!= ERROR_OK
)
58 retval
= fileio_read(&fileio
, 9, buffer
, &read_bytes
);
60 if (retval
== ERROR_OK
) {
62 retval
= ERROR_FILEIO_OPERATION_FAILED
;
64 fileio_close(&fileio
);
66 if (retval
!= ERROR_OK
)
69 /* check header against known signatures */
70 if (strncmp((char *)buffer
, ELFMAG
, SELFMAG
) == 0) {
71 LOG_DEBUG("ELF image detected.");
72 image
->type
= IMAGE_ELF
;
73 } else if ((buffer
[0] == ':') /* record start byte */
74 && (isxdigit(buffer
[1]))
75 && (isxdigit(buffer
[2]))
76 && (isxdigit(buffer
[3]))
77 && (isxdigit(buffer
[4]))
78 && (isxdigit(buffer
[5]))
79 && (isxdigit(buffer
[6]))
80 && (buffer
[7] == '0') /* record type : 00 -> 05 */
81 && (buffer
[8] >= '0') && (buffer
[8] < '6')) {
82 LOG_DEBUG("IHEX image detected.");
83 image
->type
= IMAGE_IHEX
;
84 } else if ((buffer
[0] == 'S') /* record start byte */
85 && (isxdigit(buffer
[1]))
86 && (isxdigit(buffer
[2]))
87 && (isxdigit(buffer
[3]))
88 && (buffer
[1] >= '0') && (buffer
[1] < '9')) {
89 LOG_DEBUG("S19 image detected.");
90 image
->type
= IMAGE_SRECORD
;
92 image
->type
= IMAGE_BINARY
;
97 static int identify_image_type(struct image
*image
, const char *type_string
, const char *url
)
100 if (!strcmp(type_string
, "bin"))
101 image
->type
= IMAGE_BINARY
;
102 else if (!strcmp(type_string
, "ihex"))
103 image
->type
= IMAGE_IHEX
;
104 else if (!strcmp(type_string
, "elf"))
105 image
->type
= IMAGE_ELF
;
106 else if (!strcmp(type_string
, "mem"))
107 image
->type
= IMAGE_MEMORY
;
108 else if (!strcmp(type_string
, "s19"))
109 image
->type
= IMAGE_SRECORD
;
110 else if (!strcmp(type_string
, "build"))
111 image
->type
= IMAGE_BUILDER
;
113 return ERROR_IMAGE_TYPE_UNKNOWN
;
115 return autodetect_image_type(image
, url
);
120 static int image_ihex_buffer_complete_inner(struct image
*image
,
122 struct imagesection
*section
)
124 struct image_ihex
*ihex
= image
->type_private
;
125 struct fileio
*fileio
= &ihex
->fileio
;
126 uint32_t full_address
= 0x0;
127 uint32_t cooked_bytes
;
130 /* we can't determine the number of sections that we'll have to create ahead of time,
131 * so we locally hold them until parsing is finished */
135 retval
= fileio_size(fileio
, &filesize
);
136 if (retval
!= ERROR_OK
)
139 ihex
->buffer
= malloc(filesize
>> 1);
141 image
->num_sections
= 0;
142 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
143 section
[image
->num_sections
].base_address
= 0x0;
144 section
[image
->num_sections
].size
= 0x0;
145 section
[image
->num_sections
].flags
= 0;
147 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
) {
150 uint32_t record_type
;
152 uint8_t cal_checksum
= 0;
153 size_t bytes_read
= 0;
155 if (lpszLine
[0] == '#')
158 if (sscanf(&lpszLine
[bytes_read
], ":%2" SCNx32
"%4" SCNx32
"%2" SCNx32
, &count
,
159 &address
, &record_type
) != 3)
160 return ERROR_IMAGE_FORMAT_ERROR
;
163 cal_checksum
+= (uint8_t)count
;
164 cal_checksum
+= (uint8_t)(address
>> 8);
165 cal_checksum
+= (uint8_t)address
;
166 cal_checksum
+= (uint8_t)record_type
;
168 if (record_type
== 0) { /* Data Record */
169 if ((full_address
& 0xffff) != address
) {
170 /* we encountered a nonconsecutive location, create a new section,
171 * unless the current section has zero size, in which case this specifies
172 * the current section's base address
174 if (section
[image
->num_sections
].size
!= 0) {
175 image
->num_sections
++;
176 if (image
->num_sections
>= IMAGE_MAX_SECTIONS
) {
177 /* too many sections */
178 LOG_ERROR("Too many sections found in IHEX file");
179 return ERROR_IMAGE_FORMAT_ERROR
;
181 section
[image
->num_sections
].size
= 0x0;
182 section
[image
->num_sections
].flags
= 0;
183 section
[image
->num_sections
].private =
184 &ihex
->buffer
[cooked_bytes
];
186 section
[image
->num_sections
].base_address
=
187 (full_address
& 0xffff0000) | address
;
188 full_address
= (full_address
& 0xffff0000) | address
;
191 while (count
-- > 0) {
193 sscanf(&lpszLine
[bytes_read
], "%2x", &value
);
194 ihex
->buffer
[cooked_bytes
] = (uint8_t)value
;
195 cal_checksum
+= (uint8_t)ihex
->buffer
[cooked_bytes
];
198 section
[image
->num_sections
].size
+= 1;
201 } else if (record_type
== 1) { /* End of File Record */
202 /* finish the current section */
203 image
->num_sections
++;
205 /* copy section information */
206 image
->sections
= malloc(sizeof(struct imagesection
) * image
->num_sections
);
207 for (i
= 0; i
< image
->num_sections
; i
++) {
208 image
->sections
[i
].private = section
[i
].private;
209 image
->sections
[i
].base_address
= section
[i
].base_address
;
210 image
->sections
[i
].size
= section
[i
].size
;
211 image
->sections
[i
].flags
= section
[i
].flags
;
215 } else if (record_type
== 2) { /* Linear Address Record */
216 uint16_t upper_address
;
218 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
219 cal_checksum
+= (uint8_t)(upper_address
>> 8);
220 cal_checksum
+= (uint8_t)upper_address
;
223 if ((full_address
>> 4) != upper_address
) {
224 /* we encountered a nonconsecutive location, create a new section,
225 * unless the current section has zero size, in which case this specifies
226 * the current section's base address
228 if (section
[image
->num_sections
].size
!= 0) {
229 image
->num_sections
++;
230 if (image
->num_sections
>= IMAGE_MAX_SECTIONS
) {
231 /* too many sections */
232 LOG_ERROR("Too many sections found in IHEX file");
233 return ERROR_IMAGE_FORMAT_ERROR
;
235 section
[image
->num_sections
].size
= 0x0;
236 section
[image
->num_sections
].flags
= 0;
237 section
[image
->num_sections
].private =
238 &ihex
->buffer
[cooked_bytes
];
240 section
[image
->num_sections
].base_address
=
241 (full_address
& 0xffff) | (upper_address
<< 4);
242 full_address
= (full_address
& 0xffff) | (upper_address
<< 4);
244 } else if (record_type
== 3) { /* Start Segment Address Record */
247 /* "Start Segment Address Record" will not be supported
248 * but we must consume it, and do not create an error. */
249 while (count
-- > 0) {
250 sscanf(&lpszLine
[bytes_read
], "%2" SCNx32
, &dummy
);
251 cal_checksum
+= (uint8_t)dummy
;
254 } else if (record_type
== 4) { /* Extended Linear Address Record */
255 uint16_t upper_address
;
257 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
258 cal_checksum
+= (uint8_t)(upper_address
>> 8);
259 cal_checksum
+= (uint8_t)upper_address
;
262 if ((full_address
>> 16) != upper_address
) {
263 /* we encountered a nonconsecutive location, create a new section,
264 * unless the current section has zero size, in which case this specifies
265 * the current section's base address
267 if (section
[image
->num_sections
].size
!= 0) {
268 image
->num_sections
++;
269 if (image
->num_sections
>= IMAGE_MAX_SECTIONS
) {
270 /* too many sections */
271 LOG_ERROR("Too many sections found in IHEX file");
272 return ERROR_IMAGE_FORMAT_ERROR
;
274 section
[image
->num_sections
].size
= 0x0;
275 section
[image
->num_sections
].flags
= 0;
276 section
[image
->num_sections
].private =
277 &ihex
->buffer
[cooked_bytes
];
279 section
[image
->num_sections
].base_address
=
280 (full_address
& 0xffff) | (upper_address
<< 16);
281 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
283 } else if (record_type
== 5) { /* Start Linear Address Record */
284 uint32_t start_address
;
286 sscanf(&lpszLine
[bytes_read
], "%8" SCNx32
, &start_address
);
287 cal_checksum
+= (uint8_t)(start_address
>> 24);
288 cal_checksum
+= (uint8_t)(start_address
>> 16);
289 cal_checksum
+= (uint8_t)(start_address
>> 8);
290 cal_checksum
+= (uint8_t)start_address
;
293 image
->start_address_set
= 1;
294 image
->start_address
= be_to_h_u32((uint8_t *)&start_address
);
296 LOG_ERROR("unhandled IHEX record type: %i", (int)record_type
);
297 return ERROR_IMAGE_FORMAT_ERROR
;
300 sscanf(&lpszLine
[bytes_read
], "%2" SCNx32
, &checksum
);
302 if ((uint8_t)checksum
!= (uint8_t)(~cal_checksum
+ 1)) {
303 /* checksum failed */
304 LOG_ERROR("incorrect record checksum found in IHEX file");
305 return ERROR_IMAGE_CHECKSUM
;
309 LOG_ERROR("premature end of IHEX file, no end-of-file record found");
310 return ERROR_IMAGE_FORMAT_ERROR
;
314 * Allocate memory dynamically instead of on the stack. This
315 * is important w/embedded hosts.
317 static int image_ihex_buffer_complete(struct image
*image
)
319 char *lpszLine
= malloc(1023);
320 if (lpszLine
== NULL
) {
321 LOG_ERROR("Out of memory");
324 struct imagesection
*section
= malloc(sizeof(struct imagesection
) * IMAGE_MAX_SECTIONS
);
325 if (section
== NULL
) {
327 LOG_ERROR("Out of memory");
332 retval
= image_ihex_buffer_complete_inner(image
, lpszLine
, section
);
340 static int image_elf_read_headers(struct image
*image
)
342 struct image_elf
*elf
= image
->type_private
;
346 uint32_t nload
, load_to_vaddr
= 0;
348 elf
->header
= malloc(sizeof(Elf32_Ehdr
));
350 if (elf
->header
== NULL
) {
351 LOG_ERROR("insufficient memory to perform operation ");
352 return ERROR_FILEIO_OPERATION_FAILED
;
355 retval
= fileio_read(&elf
->fileio
, sizeof(Elf32_Ehdr
), (uint8_t *)elf
->header
, &read_bytes
);
356 if (retval
!= ERROR_OK
) {
357 LOG_ERROR("cannot read ELF file header, read failed");
358 return ERROR_FILEIO_OPERATION_FAILED
;
360 if (read_bytes
!= sizeof(Elf32_Ehdr
)) {
361 LOG_ERROR("cannot read ELF file header, only partially read");
362 return ERROR_FILEIO_OPERATION_FAILED
;
365 if (strncmp((char *)elf
->header
->e_ident
, ELFMAG
, SELFMAG
) != 0) {
366 LOG_ERROR("invalid ELF file, bad magic number");
367 return ERROR_IMAGE_FORMAT_ERROR
;
369 if (elf
->header
->e_ident
[EI_CLASS
] != ELFCLASS32
) {
370 LOG_ERROR("invalid ELF file, only 32bits files are supported");
371 return ERROR_IMAGE_FORMAT_ERROR
;
374 elf
->endianness
= elf
->header
->e_ident
[EI_DATA
];
375 if ((elf
->endianness
!= ELFDATA2LSB
)
376 && (elf
->endianness
!= ELFDATA2MSB
)) {
377 LOG_ERROR("invalid ELF file, unknown endianness setting");
378 return ERROR_IMAGE_FORMAT_ERROR
;
381 elf
->segment_count
= field16(elf
, elf
->header
->e_phnum
);
382 if (elf
->segment_count
== 0) {
383 LOG_ERROR("invalid ELF file, no program headers");
384 return ERROR_IMAGE_FORMAT_ERROR
;
387 retval
= fileio_seek(&elf
->fileio
, field32(elf
, elf
->header
->e_phoff
));
388 if (retval
!= ERROR_OK
) {
389 LOG_ERROR("cannot seek to ELF program header table, read failed");
393 elf
->segments
= malloc(elf
->segment_count
*sizeof(Elf32_Phdr
));
394 if (elf
->segments
== NULL
) {
395 LOG_ERROR("insufficient memory to perform operation ");
396 return ERROR_FILEIO_OPERATION_FAILED
;
399 retval
= fileio_read(&elf
->fileio
, elf
->segment_count
*sizeof(Elf32_Phdr
),
400 (uint8_t *)elf
->segments
, &read_bytes
);
401 if (retval
!= ERROR_OK
) {
402 LOG_ERROR("cannot read ELF segment headers, read failed");
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
;
410 /* count useful segments (loadable), ignore BSS section */
411 image
->num_sections
= 0;
412 for (i
= 0; i
< elf
->segment_count
; i
++)
414 elf
->segments
[i
].p_type
) == PT_LOAD
) &&
415 (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
416 image
->num_sections
++;
418 assert(image
->num_sections
> 0);
421 * some ELF linkers produce binaries with *all* the program header
422 * p_paddr fields zero (there can be however one loadable segment
423 * that has valid physical address 0x0).
424 * If we have such a binary with more than
425 * one PT_LOAD header, then use p_vaddr instead of p_paddr
426 * (ARM ELF standard demands p_paddr = 0 anyway, and BFD
427 * library uses this approach to workaround zero-initialized p_paddrs
428 * when obtaining lma - look at elf.c of BDF)
430 for (nload
= 0, i
= 0; i
< elf
->segment_count
; i
++)
431 if (elf
->segments
[i
].p_paddr
!= 0)
433 else if ((field32(elf
,
434 elf
->segments
[i
].p_type
) == PT_LOAD
) &&
435 (field32(elf
, elf
->segments
[i
].p_memsz
) != 0))
438 if (i
>= elf
->segment_count
&& nload
> 1)
441 /* alloc and fill sections array with loadable segments */
442 image
->sections
= malloc(image
->num_sections
* sizeof(struct imagesection
));
443 for (i
= 0, j
= 0; i
< elf
->segment_count
; i
++) {
445 elf
->segments
[i
].p_type
) == PT_LOAD
) &&
446 (field32(elf
, elf
->segments
[i
].p_filesz
) != 0)) {
447 image
->sections
[j
].size
= field32(elf
, elf
->segments
[i
].p_filesz
);
449 image
->sections
[j
].base_address
= field32(elf
,
450 elf
->segments
[i
].p_vaddr
);
452 image
->sections
[j
].base_address
= field32(elf
,
453 elf
->segments
[i
].p_paddr
);
454 image
->sections
[j
].private = &elf
->segments
[i
];
455 image
->sections
[j
].flags
= field32(elf
, elf
->segments
[i
].p_flags
);
460 image
->start_address_set
= 1;
461 image
->start_address
= field32(elf
, elf
->header
->e_entry
);
466 static int image_elf_read_section(struct image
*image
,
473 struct image_elf
*elf
= image
->type_private
;
474 Elf32_Phdr
*segment
= (Elf32_Phdr
*)image
->sections
[section
].private;
475 size_t read_size
, really_read
;
480 LOG_DEBUG("load segment %d at 0x%" PRIx32
" (sz = 0x%" PRIx32
")", section
, offset
, size
);
482 /* read initialized data in current segment if any */
483 if (offset
< field32(elf
, segment
->p_filesz
)) {
484 /* maximal size present in file for the current segment */
485 read_size
= MIN(size
, field32(elf
, segment
->p_filesz
) - offset
);
486 LOG_DEBUG("read elf: size = 0x%zu at 0x%" PRIx32
"", read_size
,
487 field32(elf
, segment
->p_offset
) + offset
);
488 /* read initialized area of the segment */
489 retval
= fileio_seek(&elf
->fileio
, field32(elf
, segment
->p_offset
) + offset
);
490 if (retval
!= ERROR_OK
) {
491 LOG_ERROR("cannot find ELF segment content, seek failed");
494 retval
= fileio_read(&elf
->fileio
, read_size
, buffer
, &really_read
);
495 if (retval
!= ERROR_OK
) {
496 LOG_ERROR("cannot read ELF segment content, read failed");
500 *size_read
+= read_size
;
501 /* need more data ? */
509 static int image_mot_buffer_complete_inner(struct image
*image
,
511 struct imagesection
*section
)
513 struct image_mot
*mot
= image
->type_private
;
514 struct fileio
*fileio
= &mot
->fileio
;
515 uint32_t full_address
= 0x0;
516 uint32_t cooked_bytes
;
519 /* we can't determine the number of sections that we'll have to create ahead of time,
520 * so we locally hold them until parsing is finished */
524 retval
= fileio_size(fileio
, &filesize
);
525 if (retval
!= ERROR_OK
)
528 mot
->buffer
= malloc(filesize
>> 1);
530 image
->num_sections
= 0;
531 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
532 section
[image
->num_sections
].base_address
= 0x0;
533 section
[image
->num_sections
].size
= 0x0;
534 section
[image
->num_sections
].flags
= 0;
536 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
) {
539 uint32_t record_type
;
541 uint8_t cal_checksum
= 0;
542 uint32_t bytes_read
= 0;
544 /* get record type and record length */
545 if (sscanf(&lpszLine
[bytes_read
], "S%1" SCNx32
"%2" SCNx32
, &record_type
,
547 return ERROR_IMAGE_FORMAT_ERROR
;
550 cal_checksum
+= (uint8_t)count
;
552 /* skip checksum byte */
555 if (record_type
== 0) {
556 /* S0 - starting record (optional) */
559 while (count
-- > 0) {
560 sscanf(&lpszLine
[bytes_read
], "%2x", &iValue
);
561 cal_checksum
+= (uint8_t)iValue
;
564 } else if (record_type
>= 1 && record_type
<= 3) {
565 switch (record_type
) {
567 /* S1 - 16 bit address data record */
568 sscanf(&lpszLine
[bytes_read
], "%4" SCNx32
, &address
);
569 cal_checksum
+= (uint8_t)(address
>> 8);
570 cal_checksum
+= (uint8_t)address
;
576 /* S2 - 24 bit address data record */
577 sscanf(&lpszLine
[bytes_read
], "%6" SCNx32
, &address
);
578 cal_checksum
+= (uint8_t)(address
>> 16);
579 cal_checksum
+= (uint8_t)(address
>> 8);
580 cal_checksum
+= (uint8_t)address
;
586 /* S3 - 32 bit address data record */
587 sscanf(&lpszLine
[bytes_read
], "%8" SCNx32
, &address
);
588 cal_checksum
+= (uint8_t)(address
>> 24);
589 cal_checksum
+= (uint8_t)(address
>> 16);
590 cal_checksum
+= (uint8_t)(address
>> 8);
591 cal_checksum
+= (uint8_t)address
;
598 if (full_address
!= address
) {
599 /* we encountered a nonconsecutive location, create a new section,
600 * unless the current section has zero size, in which case this specifies
601 * the current section's base address
603 if (section
[image
->num_sections
].size
!= 0) {
604 image
->num_sections
++;
605 section
[image
->num_sections
].size
= 0x0;
606 section
[image
->num_sections
].flags
= 0;
607 section
[image
->num_sections
].private =
608 &mot
->buffer
[cooked_bytes
];
610 section
[image
->num_sections
].base_address
= address
;
611 full_address
= address
;
614 while (count
-- > 0) {
616 sscanf(&lpszLine
[bytes_read
], "%2x", &value
);
617 mot
->buffer
[cooked_bytes
] = (uint8_t)value
;
618 cal_checksum
+= (uint8_t)mot
->buffer
[cooked_bytes
];
621 section
[image
->num_sections
].size
+= 1;
624 } else if (record_type
== 5) {
625 /* S5 is the data count record, we ignore it */
628 while (count
-- > 0) {
629 sscanf(&lpszLine
[bytes_read
], "%2" SCNx32
, &dummy
);
630 cal_checksum
+= (uint8_t)dummy
;
633 } else if (record_type
>= 7 && record_type
<= 9) {
634 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
635 image
->num_sections
++;
637 /* copy section information */
638 image
->sections
= malloc(sizeof(struct imagesection
) * image
->num_sections
);
639 for (i
= 0; i
< image
->num_sections
; i
++) {
640 image
->sections
[i
].private = section
[i
].private;
641 image
->sections
[i
].base_address
= section
[i
].base_address
;
642 image
->sections
[i
].size
= section
[i
].size
;
643 image
->sections
[i
].flags
= section
[i
].flags
;
648 LOG_ERROR("unhandled S19 record type: %i", (int)(record_type
));
649 return ERROR_IMAGE_FORMAT_ERROR
;
652 /* account for checksum, will always be 0xFF */
653 sscanf(&lpszLine
[bytes_read
], "%2" SCNx32
, &checksum
);
654 cal_checksum
+= (uint8_t)checksum
;
656 if (cal_checksum
!= 0xFF) {
657 /* checksum failed */
658 LOG_ERROR("incorrect record checksum found in S19 file");
659 return ERROR_IMAGE_CHECKSUM
;
663 LOG_ERROR("premature end of S19 file, no end-of-file record found");
664 return ERROR_IMAGE_FORMAT_ERROR
;
668 * Allocate memory dynamically instead of on the stack. This
669 * is important w/embedded hosts.
671 static int image_mot_buffer_complete(struct image
*image
)
673 char *lpszLine
= malloc(1023);
674 if (lpszLine
== NULL
) {
675 LOG_ERROR("Out of memory");
678 struct imagesection
*section
= malloc(sizeof(struct imagesection
) * IMAGE_MAX_SECTIONS
);
679 if (section
== NULL
) {
681 LOG_ERROR("Out of memory");
686 retval
= image_mot_buffer_complete_inner(image
, lpszLine
, section
);
694 int image_open(struct image
*image
, const char *url
, const char *type_string
)
696 int retval
= ERROR_OK
;
698 retval
= identify_image_type(image
, type_string
, url
);
699 if (retval
!= ERROR_OK
)
702 if (image
->type
== IMAGE_BINARY
) {
703 struct image_binary
*image_binary
;
705 image_binary
= image
->type_private
= malloc(sizeof(struct image_binary
));
707 retval
= fileio_open(&image_binary
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
);
708 if (retval
!= ERROR_OK
)
711 retval
= fileio_size(&image_binary
->fileio
, &filesize
);
712 if (retval
!= ERROR_OK
) {
713 fileio_close(&image_binary
->fileio
);
717 image
->num_sections
= 1;
718 image
->sections
= malloc(sizeof(struct imagesection
));
719 image
->sections
[0].base_address
= 0x0;
720 image
->sections
[0].size
= filesize
;
721 image
->sections
[0].flags
= 0;
722 } else if (image
->type
== IMAGE_IHEX
) {
723 struct image_ihex
*image_ihex
;
725 image_ihex
= image
->type_private
= malloc(sizeof(struct image_ihex
));
727 retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
);
728 if (retval
!= ERROR_OK
)
731 retval
= image_ihex_buffer_complete(image
);
732 if (retval
!= ERROR_OK
) {
734 "failed buffering IHEX image, check daemon output for additional information");
735 fileio_close(&image_ihex
->fileio
);
738 } else if (image
->type
== IMAGE_ELF
) {
739 struct image_elf
*image_elf
;
741 image_elf
= image
->type_private
= malloc(sizeof(struct image_elf
));
743 retval
= fileio_open(&image_elf
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
);
744 if (retval
!= ERROR_OK
)
747 retval
= image_elf_read_headers(image
);
748 if (retval
!= ERROR_OK
) {
749 fileio_close(&image_elf
->fileio
);
752 } else if (image
->type
== IMAGE_MEMORY
) {
753 struct target
*target
= get_target(url
);
755 if (target
== NULL
) {
756 LOG_ERROR("target '%s' not defined", url
);
760 struct image_memory
*image_memory
;
762 image
->num_sections
= 1;
763 image
->sections
= malloc(sizeof(struct imagesection
));
764 image
->sections
[0].base_address
= 0x0;
765 image
->sections
[0].size
= 0xffffffff;
766 image
->sections
[0].flags
= 0;
768 image_memory
= image
->type_private
= malloc(sizeof(struct image_memory
));
770 image_memory
->target
= target
;
771 image_memory
->cache
= NULL
;
772 image_memory
->cache_address
= 0x0;
773 } else if (image
->type
== IMAGE_SRECORD
) {
774 struct image_mot
*image_mot
;
776 image_mot
= image
->type_private
= malloc(sizeof(struct image_mot
));
778 retval
= fileio_open(&image_mot
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
);
779 if (retval
!= ERROR_OK
)
782 retval
= image_mot_buffer_complete(image
);
783 if (retval
!= ERROR_OK
) {
785 "failed buffering S19 image, check daemon output for additional information");
786 fileio_close(&image_mot
->fileio
);
789 } else if (image
->type
== IMAGE_BUILDER
) {
790 image
->num_sections
= 0;
791 image
->sections
= NULL
;
792 image
->type_private
= NULL
;
795 if (image
->base_address_set
) {
798 for (section
= 0; section
< image
->num_sections
; section
++)
799 image
->sections
[section
].base_address
+= image
->base_address
;
800 /* we're done relocating. The two statements below are mainly
801 * for documenation purposes: stop anyone from empirically
802 * thinking they should use these values henceforth. */
803 image
->base_address
= 0;
804 image
->base_address_set
= 0;
810 int image_read_section(struct image
*image
,
819 /* don't read past the end of a section */
820 if (offset
+ size
> image
->sections
[section
].size
) {
822 "read past end of section: 0x%8.8" PRIx32
" + 0x%8.8" PRIx32
" > 0x%8.8" PRIx32
"",
825 image
->sections
[section
].size
);
826 return ERROR_COMMAND_SYNTAX_ERROR
;
829 if (image
->type
== IMAGE_BINARY
) {
830 struct image_binary
*image_binary
= image
->type_private
;
832 /* only one section in a plain binary */
834 return ERROR_COMMAND_SYNTAX_ERROR
;
837 retval
= fileio_seek(&image_binary
->fileio
, offset
);
838 if (retval
!= ERROR_OK
)
841 /* return requested bytes */
842 retval
= fileio_read(&image_binary
->fileio
, size
, buffer
, size_read
);
843 if (retval
!= ERROR_OK
)
845 } else if (image
->type
== IMAGE_IHEX
) {
846 memcpy(buffer
, (uint8_t *)image
->sections
[section
].private + offset
, size
);
850 } else if (image
->type
== IMAGE_ELF
)
851 return image_elf_read_section(image
, section
, offset
, size
, buffer
, size_read
);
852 else if (image
->type
== IMAGE_MEMORY
) {
853 struct image_memory
*image_memory
= image
->type_private
;
854 uint32_t address
= image
->sections
[section
].base_address
+ offset
;
858 while ((size
- *size_read
) > 0) {
859 uint32_t size_in_cache
;
861 if (!image_memory
->cache
862 || (address
< image_memory
->cache_address
)
864 (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
))) {
865 if (!image_memory
->cache
)
866 image_memory
->cache
= malloc(IMAGE_MEMORY_CACHE_SIZE
);
868 if (target_read_buffer(image_memory
->target
, address
&
869 ~(IMAGE_MEMORY_CACHE_SIZE
- 1),
870 IMAGE_MEMORY_CACHE_SIZE
, image_memory
->cache
) != ERROR_OK
) {
871 free(image_memory
->cache
);
872 image_memory
->cache
= NULL
;
873 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE
;
875 image_memory
->cache_address
= address
&
876 ~(IMAGE_MEMORY_CACHE_SIZE
- 1);
880 (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
) - address
;
882 memcpy(buffer
+ *size_read
,
883 image_memory
->cache
+ (address
- image_memory
->cache_address
),
884 (size_in_cache
> size
) ? size
: size_in_cache
887 *size_read
+= (size_in_cache
> size
) ? size
: size_in_cache
;
888 address
+= (size_in_cache
> size
) ? size
: size_in_cache
;
890 } else if (image
->type
== IMAGE_SRECORD
) {
891 memcpy(buffer
, (uint8_t *)image
->sections
[section
].private + offset
, size
);
895 } else if (image
->type
== IMAGE_BUILDER
) {
896 memcpy(buffer
, (uint8_t *)image
->sections
[section
].private + offset
, size
);
905 int image_add_section(struct image
*image
, uint32_t base
, uint32_t size
, int flags
, uint8_t const *data
)
907 struct imagesection
*section
;
909 /* only image builder supports adding sections */
910 if (image
->type
!= IMAGE_BUILDER
)
911 return ERROR_COMMAND_SYNTAX_ERROR
;
913 /* see if there's a previous section */
914 if (image
->num_sections
) {
915 section
= &image
->sections
[image
->num_sections
- 1];
917 /* see if it's enough to extend the last section,
918 * adding data to previous sections or merging is not supported */
919 if (((section
->base_address
+ section
->size
) == base
) &&
920 (section
->flags
== flags
)) {
921 section
->private = realloc(section
->private, section
->size
+ size
);
922 memcpy((uint8_t *)section
->private + section
->size
, data
, size
);
923 section
->size
+= size
;
928 /* allocate new section */
929 image
->num_sections
++;
931 realloc(image
->sections
, sizeof(struct imagesection
) * image
->num_sections
);
932 section
= &image
->sections
[image
->num_sections
- 1];
933 section
->base_address
= base
;
934 section
->size
= size
;
935 section
->flags
= flags
;
936 section
->private = malloc(sizeof(uint8_t) * size
);
937 memcpy((uint8_t *)section
->private, data
, size
);
942 void image_close(struct image
*image
)
944 if (image
->type
== IMAGE_BINARY
) {
945 struct image_binary
*image_binary
= image
->type_private
;
947 fileio_close(&image_binary
->fileio
);
948 } else if (image
->type
== IMAGE_IHEX
) {
949 struct image_ihex
*image_ihex
= image
->type_private
;
951 fileio_close(&image_ihex
->fileio
);
953 if (image_ihex
->buffer
) {
954 free(image_ihex
->buffer
);
955 image_ihex
->buffer
= NULL
;
957 } else if (image
->type
== IMAGE_ELF
) {
958 struct image_elf
*image_elf
= image
->type_private
;
960 fileio_close(&image_elf
->fileio
);
962 if (image_elf
->header
) {
963 free(image_elf
->header
);
964 image_elf
->header
= NULL
;
967 if (image_elf
->segments
) {
968 free(image_elf
->segments
);
969 image_elf
->segments
= NULL
;
971 } else if (image
->type
== IMAGE_MEMORY
) {
972 struct image_memory
*image_memory
= image
->type_private
;
974 if (image_memory
->cache
) {
975 free(image_memory
->cache
);
976 image_memory
->cache
= NULL
;
978 } else if (image
->type
== IMAGE_SRECORD
) {
979 struct image_mot
*image_mot
= image
->type_private
;
981 fileio_close(&image_mot
->fileio
);
983 if (image_mot
->buffer
) {
984 free(image_mot
->buffer
);
985 image_mot
->buffer
= NULL
;
987 } else if (image
->type
== IMAGE_BUILDER
) {
990 for (i
= 0; i
< image
->num_sections
; i
++) {
991 free(image
->sections
[i
].private);
992 image
->sections
[i
].private = NULL
;
996 if (image
->type_private
) {
997 free(image
->type_private
);
998 image
->type_private
= NULL
;
1001 if (image
->sections
) {
1002 free(image
->sections
);
1003 image
->sections
= NULL
;
1007 int image_calculate_checksum(uint8_t *buffer
, uint32_t nbytes
, uint32_t *checksum
)
1009 uint32_t crc
= 0xffffffff;
1010 LOG_DEBUG("Calculating checksum");
1012 static uint32_t crc32_table
[256];
1014 static bool first_init
;
1016 /* Initialize the CRC table and the decoding table. */
1019 for (i
= 0; i
< 256; i
++) {
1021 for (c
= i
<< 24, j
= 8; j
> 0; --j
)
1022 c
= c
& 0x80000000 ? (c
<< 1) ^ 0x04c11db7 : (c
<< 1);
1029 while (nbytes
> 0) {
1036 crc
= (crc
<< 8) ^ crc32_table
[((crc
>> 24) ^ *buffer
++) & 255];
1041 LOG_DEBUG("Calculating checksum done");
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)