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 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
39 #include "replacements.h"
45 /* convert ELF header field to host endianness */
46 #define field16(elf,field)\
47 ((elf->endianness==ELFDATA2LSB)? \
48 le_to_h_u16((u8*)&field):be_to_h_u16((u8*)&field))
50 #define field32(elf,field)\
51 ((elf->endianness==ELFDATA2LSB)? \
52 le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
54 static int autodetect_image_type(image_t
*image
, char *url
)
61 /* read the first 4 bytes of image */
62 if ((retval
= fileio_open(&fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
66 retval
= fileio_read(&fileio
, 9, buffer
, &read_bytes
);
72 retval
=ERROR_FILEIO_OPERATION_FAILED
;
75 fileio_close(&fileio
);
80 /* check header against known signatures */
81 if (strncmp((char*)buffer
,ELFMAG
,SELFMAG
)==0)
83 LOG_DEBUG("ELF image detected.");
84 image
->type
= IMAGE_ELF
;
86 else if ((buffer
[0]==':') /* record start byte */
87 &&(isxdigit(buffer
[1]))
88 &&(isxdigit(buffer
[2]))
89 &&(isxdigit(buffer
[3]))
90 &&(isxdigit(buffer
[4]))
91 &&(isxdigit(buffer
[5]))
92 &&(isxdigit(buffer
[6]))
93 &&(buffer
[7]=='0') /* record type : 00 -> 05 */
94 &&(buffer
[8]>='0')&&(buffer
[8]<'6'))
96 LOG_DEBUG("IHEX image detected.");
97 image
->type
= IMAGE_IHEX
;
99 else if ((buffer
[0] == 'S') /* record start byte */
100 &&(isxdigit(buffer
[1]))
101 &&(isxdigit(buffer
[2]))
102 &&(isxdigit(buffer
[3]))
103 &&(buffer
[1] >= '0') && (buffer
[1] < '9'))
105 LOG_DEBUG("S19 image detected.");
106 image
->type
= IMAGE_SRECORD
;
110 image
->type
= IMAGE_BINARY
;
116 int identify_image_type(image_t
*image
, char *type_string
, char *url
)
120 if (!strcmp(type_string
, "bin"))
122 image
->type
= IMAGE_BINARY
;
124 else if (!strcmp(type_string
, "ihex"))
126 image
->type
= IMAGE_IHEX
;
128 else if (!strcmp(type_string
, "elf"))
130 image
->type
= IMAGE_ELF
;
132 else if (!strcmp(type_string
, "mem"))
134 image
->type
= IMAGE_MEMORY
;
136 else if (!strcmp(type_string
, "s19"))
138 image
->type
= IMAGE_SRECORD
;
140 else if (!strcmp(type_string
, "build"))
142 image
->type
= IMAGE_BUILDER
;
146 return ERROR_IMAGE_TYPE_UNKNOWN
;
151 return autodetect_image_type(image
, url
);
157 int image_ihex_buffer_complete(image_t
*image
)
159 image_ihex_t
*ihex
= image
->type_private
;
160 fileio_t
*fileio
= &ihex
->fileio
;
161 u32 full_address
= 0x0;
166 /* we can't determine the number of sections that we'll have to create ahead of time,
167 * so we locally hold them until parsing is finished */
168 image_section_t section
[IMAGE_MAX_SECTIONS
];
170 ihex
->buffer
= malloc(fileio
->size
>> 1);
172 image
->num_sections
= 0;
173 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
174 section
[image
->num_sections
].base_address
= 0x0;
175 section
[image
->num_sections
].size
= 0x0;
176 section
[image
->num_sections
].flags
= 0;
178 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
187 if (sscanf(&lpszLine
[bytes_read
], ":%2x%4x%2x", &count
, &address
, &record_type
) != 3)
189 return ERROR_IMAGE_FORMAT_ERROR
;
193 cal_checksum
+= (u8
)count
;
194 cal_checksum
+= (u8
)(address
>> 8);
195 cal_checksum
+= (u8
)address
;
196 cal_checksum
+= (u8
)record_type
;
198 if (record_type
== 0) /* Data Record */
200 if ((full_address
& 0xffff) != address
)
202 /* we encountered a nonconsecutive location, create a new section,
203 * unless the current section has zero size, in which case this specifies
204 * the current section's base address
206 if (section
[image
->num_sections
].size
!= 0)
208 image
->num_sections
++;
209 section
[image
->num_sections
].size
= 0x0;
210 section
[image
->num_sections
].flags
= 0;
211 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
213 section
[image
->num_sections
].base_address
=
214 (full_address
& 0xffff0000) | address
;
215 full_address
= (full_address
& 0xffff0000) | address
;
220 sscanf(&lpszLine
[bytes_read
], "%2x", (u32
*)&ihex
->buffer
[cooked_bytes
]);
221 cal_checksum
+= (u8
)ihex
->buffer
[cooked_bytes
];
224 section
[image
->num_sections
].size
+= 1;
228 else if (record_type
== 1) /* End of File Record */
230 /* finish the current section */
231 image
->num_sections
++;
233 /* copy section information */
234 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
235 for (i
= 0; i
< image
->num_sections
; i
++)
237 image
->sections
[i
].private = section
[i
].private;
238 image
->sections
[i
].base_address
= section
[i
].base_address
;
239 image
->sections
[i
].size
= section
[i
].size
;
240 image
->sections
[i
].flags
= section
[i
].flags
;
245 else if (record_type
== 2) /* Linear Address Record */
249 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
250 cal_checksum
+= (u8
)(upper_address
>> 8);
251 cal_checksum
+= (u8
)upper_address
;
254 if ((full_address
>> 4) != upper_address
)
256 /* we encountered a nonconsecutive location, create a new section,
257 * unless the current section has zero size, in which case this specifies
258 * the current section's base address
260 if (section
[image
->num_sections
].size
!= 0)
262 image
->num_sections
++;
263 section
[image
->num_sections
].size
= 0x0;
264 section
[image
->num_sections
].flags
= 0;
265 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
267 section
[image
->num_sections
].base_address
=
268 (full_address
& 0xffff) | (upper_address
<< 4);
269 full_address
= (full_address
& 0xffff) | (upper_address
<< 4);
272 else if (record_type
== 3) /* Start Segment Address Record */
276 /* "Start Segment Address Record" will not be supported */
277 /* but we must consume it, and do not create an error. */
280 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
281 cal_checksum
+= (u8
)dummy
;
285 else if (record_type
== 4) /* Extended Linear Address Record */
289 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
290 cal_checksum
+= (u8
)(upper_address
>> 8);
291 cal_checksum
+= (u8
)upper_address
;
294 if ((full_address
>> 16) != upper_address
)
296 /* we encountered a nonconsecutive location, create a new section,
297 * unless the current section has zero size, in which case this specifies
298 * the current section's base address
300 if (section
[image
->num_sections
].size
!= 0)
302 image
->num_sections
++;
303 section
[image
->num_sections
].size
= 0x0;
304 section
[image
->num_sections
].flags
= 0;
305 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
307 section
[image
->num_sections
].base_address
=
308 (full_address
& 0xffff) | (upper_address
<< 16);
309 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
312 else if (record_type
== 5) /* Start Linear Address Record */
316 sscanf(&lpszLine
[bytes_read
], "%8x", &start_address
);
317 cal_checksum
+= (u8
)(start_address
>> 24);
318 cal_checksum
+= (u8
)(start_address
>> 16);
319 cal_checksum
+= (u8
)(start_address
>> 8);
320 cal_checksum
+= (u8
)start_address
;
323 image
->start_address_set
= 1;
324 image
->start_address
= be_to_h_u32((u8
*)&start_address
);
328 LOG_ERROR("unhandled IHEX record type: %i", record_type
);
329 return ERROR_IMAGE_FORMAT_ERROR
;
332 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
335 if ((u8
)checksum
!= (u8
)(~cal_checksum
+ 1))
337 /* checksum failed */
338 LOG_ERROR("incorrect record checksum found in IHEX file");
339 return ERROR_IMAGE_CHECKSUM
;
343 LOG_ERROR("premature end of IHEX file, no end-of-file record found");
344 return ERROR_IMAGE_FORMAT_ERROR
;
347 int image_elf_read_headers(image_t
*image
)
349 image_elf_t
*elf
= image
->type_private
;
354 elf
->header
= malloc(sizeof(Elf32_Ehdr
));
356 if(elf
->header
== NULL
)
358 LOG_ERROR("insufficient memory to perform operation ");
359 return ERROR_FILEIO_OPERATION_FAILED
;
362 if ((retval
= fileio_read(&elf
->fileio
, sizeof(Elf32_Ehdr
), (u8
*)elf
->header
, &read_bytes
)) != ERROR_OK
)
364 LOG_ERROR("cannot read ELF file header, read failed");
365 return ERROR_FILEIO_OPERATION_FAILED
;
367 if (read_bytes
!= sizeof(Elf32_Ehdr
))
369 LOG_ERROR("cannot read ELF file header, only partially read");
370 return ERROR_FILEIO_OPERATION_FAILED
;
373 if (strncmp((char*)elf
->header
->e_ident
,ELFMAG
,SELFMAG
)!=0)
375 LOG_ERROR("invalid ELF file, bad magic number");
376 return ERROR_IMAGE_FORMAT_ERROR
;
378 if (elf
->header
->e_ident
[EI_CLASS
]!=ELFCLASS32
)
380 LOG_ERROR("invalid ELF file, only 32bits files are supported");
381 return ERROR_IMAGE_FORMAT_ERROR
;
385 elf
->endianness
= elf
->header
->e_ident
[EI_DATA
];
386 if ((elf
->endianness
!=ELFDATA2LSB
)
387 &&(elf
->endianness
!=ELFDATA2MSB
))
389 LOG_ERROR("invalid ELF file, unknown endianess setting");
390 return ERROR_IMAGE_FORMAT_ERROR
;
393 elf
->segment_count
= field16(elf
,elf
->header
->e_phnum
);
394 if (elf
->segment_count
==0)
396 LOG_ERROR("invalid ELF file, no program headers");
397 return ERROR_IMAGE_FORMAT_ERROR
;
400 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,elf
->header
->e_phoff
))) != ERROR_OK
)
402 LOG_ERROR("cannot seek to ELF program header table, read failed");
406 elf
->segments
= malloc(elf
->segment_count
*sizeof(Elf32_Phdr
));
407 if(elf
->segments
== NULL
)
409 LOG_ERROR("insufficient memory to perform operation ");
410 return ERROR_FILEIO_OPERATION_FAILED
;
413 if ((retval
= fileio_read(&elf
->fileio
, elf
->segment_count
*sizeof(Elf32_Phdr
), (u8
*)elf
->segments
, &read_bytes
)) != ERROR_OK
)
415 LOG_ERROR("cannot read ELF segment headers, read failed");
418 if (read_bytes
!= elf
->segment_count
*sizeof(Elf32_Phdr
))
420 LOG_ERROR("cannot read ELF segment headers, only partially read");
421 return ERROR_FILEIO_OPERATION_FAILED
;
424 /* count useful segments (loadable), ignore BSS section */
425 image
->num_sections
= 0;
426 for (i
=0;i
<elf
->segment_count
;i
++)
427 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
428 image
->num_sections
++;
429 /* alloc and fill sections array with loadable segments */
430 image
->sections
= malloc(image
->num_sections
* sizeof(image_section_t
));
431 for (i
=0,j
=0;i
<elf
->segment_count
;i
++)
433 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
435 image
->sections
[j
].size
= field32(elf
,elf
->segments
[i
].p_filesz
);
436 image
->sections
[j
].base_address
= field32(elf
,elf
->segments
[i
].p_paddr
);
437 image
->sections
[j
].private = &elf
->segments
[i
];
438 image
->sections
[j
].flags
= field32(elf
,elf
->segments
[i
].p_flags
);
443 image
->start_address_set
= 1;
444 image
->start_address
= field32(elf
,elf
->header
->e_entry
);
449 int image_elf_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
451 image_elf_t
*elf
= image
->type_private
;
452 Elf32_Phdr
*segment
= (Elf32_Phdr
*)image
->sections
[section
].private;
453 u32 read_size
,really_read
;
458 LOG_DEBUG("load segment %d at 0x%x (sz=0x%x)",section
,offset
,size
);
460 /* read initialized data in current segment if any */
461 if (offset
<field32(elf
,segment
->p_filesz
))
463 /* maximal size present in file for the current segment */
464 read_size
= MIN(size
, field32(elf
,segment
->p_filesz
)-offset
);
465 LOG_DEBUG("read elf: size = 0x%x at 0x%x",read_size
,
466 field32(elf
,segment
->p_offset
)+offset
);
467 /* read initialized area of the segment */
468 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,segment
->p_offset
)+offset
)) != ERROR_OK
)
470 LOG_ERROR("cannot find ELF segment content, seek failed");
473 if ((retval
= fileio_read(&elf
->fileio
, read_size
, buffer
, &really_read
)) != ERROR_OK
)
475 LOG_ERROR("cannot read ELF segment content, read failed");
481 *size_read
+= read_size
;
482 /* need more data ? */
490 int image_mot_buffer_complete(image_t
*image
)
492 image_mot_t
*mot
= image
->type_private
;
493 fileio_t
*fileio
= &mot
->fileio
;
494 u32 full_address
= 0x0;
499 /* we can't determine the number of sections that we'll have to create ahead of time,
500 * so we locally hold them until parsing is finished */
501 image_section_t section
[IMAGE_MAX_SECTIONS
];
503 mot
->buffer
= malloc(fileio
->size
>> 1);
505 image
->num_sections
= 0;
506 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
507 section
[image
->num_sections
].base_address
= 0x0;
508 section
[image
->num_sections
].size
= 0x0;
509 section
[image
->num_sections
].flags
= 0;
511 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
520 /* get record type and record length */
521 if (sscanf(&lpszLine
[bytes_read
], "S%1x%2x", &record_type
, &count
) != 2)
523 return ERROR_IMAGE_FORMAT_ERROR
;
527 cal_checksum
+= (u8
)count
;
529 /* skip checksum byte */
532 if (record_type
== 0)
534 /* S0 - starting record (optional) */
537 while (count
-- > 0) {
538 sscanf(&lpszLine
[bytes_read
], "%2x", &iValue
);
539 cal_checksum
+= (u8
)iValue
;
543 else if (record_type
>= 1 && record_type
<= 3)
545 switch( record_type
)
548 /* S1 - 16 bit address data record */
549 sscanf(&lpszLine
[bytes_read
], "%4x", &address
);
550 cal_checksum
+= (u8
)(address
>> 8);
551 cal_checksum
+= (u8
)address
;
557 /* S2 - 24 bit address data record */
558 sscanf(&lpszLine
[bytes_read
], "%6x", &address
);
559 cal_checksum
+= (u8
)(address
>> 16);
560 cal_checksum
+= (u8
)(address
>> 8);
561 cal_checksum
+= (u8
)address
;
567 /* S3 - 32 bit address data record */
568 sscanf(&lpszLine
[bytes_read
], "%8x", &address
);
569 cal_checksum
+= (u8
)(address
>> 24);
570 cal_checksum
+= (u8
)(address
>> 16);
571 cal_checksum
+= (u8
)(address
>> 8);
572 cal_checksum
+= (u8
)address
;
579 if (full_address
!= address
)
581 /* we encountered a nonconsecutive location, create a new section,
582 * unless the current section has zero size, in which case this specifies
583 * the current section's base address
585 if (section
[image
->num_sections
].size
!= 0)
587 image
->num_sections
++;
588 section
[image
->num_sections
].size
= 0x0;
589 section
[image
->num_sections
].flags
= 0;
590 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
592 section
[image
->num_sections
].base_address
= address
;
593 full_address
= address
;
598 sscanf(&lpszLine
[bytes_read
], "%2x", (u32
*)&mot
->buffer
[cooked_bytes
]);
599 cal_checksum
+= (u8
)mot
->buffer
[cooked_bytes
];
602 section
[image
->num_sections
].size
+= 1;
606 else if (record_type
== 5)
608 /* S5 is the data count record, we ignore it */
613 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
614 cal_checksum
+= (u8
)dummy
;
618 else if (record_type
>= 7 && record_type
<= 9)
620 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
621 image
->num_sections
++;
623 /* copy section information */
624 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
625 for (i
= 0; i
< image
->num_sections
; i
++)
627 image
->sections
[i
].private = section
[i
].private;
628 image
->sections
[i
].base_address
= section
[i
].base_address
;
629 image
->sections
[i
].size
= section
[i
].size
;
630 image
->sections
[i
].flags
= section
[i
].flags
;
637 LOG_ERROR("unhandled S19 record type: %i", record_type
);
638 return ERROR_IMAGE_FORMAT_ERROR
;
641 /* account for checksum, will always be 0xFF */
642 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
643 cal_checksum
+= (u8
)checksum
;
646 if( cal_checksum
!= 0xFF )
648 /* checksum failed */
649 LOG_ERROR("incorrect record checksum found in S19 file");
650 return ERROR_IMAGE_CHECKSUM
;
654 LOG_ERROR("premature end of S19 file, no end-of-file record found");
655 return ERROR_IMAGE_FORMAT_ERROR
;
658 int image_open(image_t
*image
, char *url
, char *type_string
)
660 int retval
= ERROR_OK
;
662 if ((retval
= identify_image_type(image
, type_string
, url
)) != ERROR_OK
)
667 if (image
->type
== IMAGE_BINARY
)
669 image_binary_t
*image_binary
;
671 image_binary
= image
->type_private
= malloc(sizeof(image_binary_t
));
673 if ((retval
= fileio_open(&image_binary
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
678 image
->num_sections
= 1;
679 image
->sections
= malloc(sizeof(image_section_t
));
680 image
->sections
[0].base_address
= 0x0;
681 image
->sections
[0].size
= image_binary
->fileio
.size
;
682 image
->sections
[0].flags
= 0;
684 else if (image
->type
== IMAGE_IHEX
)
686 image_ihex_t
*image_ihex
;
688 image_ihex
= image
->type_private
= malloc(sizeof(image_ihex_t
));
690 if ((retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
695 if ((retval
= image_ihex_buffer_complete(image
)) != ERROR_OK
)
697 LOG_ERROR("failed buffering IHEX image, check daemon output for additional information");
698 fileio_close(&image_ihex
->fileio
);
702 else if (image
->type
== IMAGE_ELF
)
704 image_elf_t
*image_elf
;
706 image_elf
= image
->type_private
= malloc(sizeof(image_elf_t
));
708 if ((retval
= fileio_open(&image_elf
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
713 if ((retval
= image_elf_read_headers(image
)) != ERROR_OK
)
715 fileio_close(&image_elf
->fileio
);
719 else if (image
->type
== IMAGE_MEMORY
)
721 image_memory_t
*image_memory
;
723 image
->num_sections
= 1;
724 image
->sections
= malloc(sizeof(image_section_t
));
725 image
->sections
[0].base_address
= 0x0;
726 image
->sections
[0].size
= 0xffffffff;
727 image
->sections
[0].flags
= 0;
729 image_memory
= image
->type_private
= malloc(sizeof(image_memory_t
));
731 image_memory
->target
= get_target_by_num(strtoul(url
, NULL
, 0));;
732 image_memory
->cache
= NULL
;
733 image_memory
->cache_address
= 0x0;
735 else if (image
->type
== IMAGE_SRECORD
)
737 image_mot_t
*image_mot
;
739 image_mot
= image
->type_private
= malloc(sizeof(image_mot_t
));
741 if ((retval
= fileio_open(&image_mot
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
746 if ((retval
= image_mot_buffer_complete(image
)) != ERROR_OK
)
748 LOG_ERROR("failed buffering S19 image, check daemon output for additional information");
749 fileio_close(&image_mot
->fileio
);
753 else if (image
->type
== IMAGE_BUILDER
)
755 image
->num_sections
= 0;
756 image
->sections
= NULL
;
757 image
->type_private
= NULL
;
760 if (image
->base_address_set
)
764 for (section
=0; section
< image
->num_sections
; section
++)
766 image
->sections
[section
].base_address
+=image
->base_address
;
768 /* we're done relocating. The two statements below are mainly
769 * for documenation purposes: stop anyone from empirically
770 * thinking they should use these values henceforth. */
771 image
->base_address
=0;
772 image
->base_address_set
=0;
778 int image_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
782 /* don't read past the end of a section */
783 if (offset
+ size
> image
->sections
[section
].size
)
785 LOG_DEBUG("read past end of section: 0x%8.8x + 0x%8.8x > 0x%8.8x",
786 offset
, size
, image
->sections
[section
].size
);
787 return ERROR_INVALID_ARGUMENTS
;
790 if (image
->type
== IMAGE_BINARY
)
792 image_binary_t
*image_binary
= image
->type_private
;
794 /* only one section in a plain binary */
796 return ERROR_INVALID_ARGUMENTS
;
799 if ((retval
= fileio_seek(&image_binary
->fileio
, offset
)) != ERROR_OK
)
804 /* return requested bytes */
805 if ((retval
= fileio_read(&image_binary
->fileio
, size
, buffer
, size_read
)) != ERROR_OK
)
810 else if (image
->type
== IMAGE_IHEX
)
812 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
817 else if (image
->type
== IMAGE_ELF
)
819 return image_elf_read_section(image
, section
, offset
, size
, buffer
, size_read
);
821 else if (image
->type
== IMAGE_MEMORY
)
823 image_memory_t
*image_memory
= image
->type_private
;
824 u32 address
= image
->sections
[section
].base_address
+ offset
;
828 while ((size
- *size_read
) > 0)
832 if (!image_memory
->cache
833 || (address
< image_memory
->cache_address
)
834 || (address
>= (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
)))
836 if (!image_memory
->cache
)
837 image_memory
->cache
= malloc(IMAGE_MEMORY_CACHE_SIZE
);
839 if (target_read_buffer(image_memory
->target
, address
& ~(IMAGE_MEMORY_CACHE_SIZE
- 1),
840 IMAGE_MEMORY_CACHE_SIZE
, image_memory
->cache
) != ERROR_OK
)
842 free(image_memory
->cache
);
843 image_memory
->cache
= NULL
;
844 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE
;
846 image_memory
->cache_address
= address
& ~(IMAGE_MEMORY_CACHE_SIZE
- 1);
849 size_in_cache
= (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
) - address
;
851 memcpy(buffer
+ *size_read
,
852 image_memory
->cache
+ (address
- image_memory
->cache_address
),
853 (size_in_cache
> size
) ? size
: size_in_cache
856 *size_read
+= (size_in_cache
> size
) ? size
: size_in_cache
;
857 address
+= (size_in_cache
> size
) ? size
: size_in_cache
;
860 else if (image
->type
== IMAGE_SRECORD
)
862 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
867 else if (image
->type
== IMAGE_BUILDER
)
869 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
878 int image_add_section(image_t
*image
, u32 base
, u32 size
, int flags
, u8
*data
)
880 image_section_t
*section
;
882 /* only image builder supports adding sections */
883 if (image
->type
!= IMAGE_BUILDER
)
884 return ERROR_INVALID_ARGUMENTS
;
886 /* see if there's a previous section */
887 if (image
->num_sections
)
889 section
= &image
->sections
[image
->num_sections
- 1];
891 /* see if it's enough to extend the last section,
892 * adding data to previous sections or merging is not supported */
893 if (((section
->base_address
+ section
->size
) == base
) && (section
->flags
== flags
))
895 section
->private = realloc(section
->private, section
->size
+ size
);
896 memcpy((u8
*)section
->private + section
->size
, data
, size
);
897 section
->size
+= size
;
902 /* allocate new section */
903 image
->num_sections
++;
904 image
->sections
= realloc(image
->sections
, sizeof(image_section_t
) * image
->num_sections
);
905 section
= &image
->sections
[image
->num_sections
- 1];
906 section
->base_address
= base
;
907 section
->size
= size
;
908 section
->flags
= flags
;
909 section
->private = malloc(sizeof(u8
) * size
);
910 memcpy((u8
*)section
->private, data
, size
);
915 int image_close(image_t
*image
)
917 if (image
->type
== IMAGE_BINARY
)
919 image_binary_t
*image_binary
= image
->type_private
;
921 fileio_close(&image_binary
->fileio
);
923 else if (image
->type
== IMAGE_IHEX
)
925 image_ihex_t
*image_ihex
= image
->type_private
;
927 fileio_close(&image_ihex
->fileio
);
929 if (image_ihex
->buffer
)
931 free(image_ihex
->buffer
);
932 image_ihex
->buffer
= NULL
;
935 else if (image
->type
== IMAGE_ELF
)
937 image_elf_t
*image_elf
= image
->type_private
;
939 fileio_close(&image_elf
->fileio
);
941 if (image_elf
->header
)
943 free(image_elf
->header
);
944 image_elf
->header
= NULL
;
947 if (image_elf
->segments
)
949 free(image_elf
->segments
);
950 image_elf
->segments
= NULL
;
953 else if (image
->type
== IMAGE_MEMORY
)
955 image_memory_t
*image_memory
= image
->type_private
;
957 if (image_memory
->cache
)
959 free(image_memory
->cache
);
960 image_memory
->cache
= NULL
;
963 else if (image
->type
== IMAGE_SRECORD
)
965 image_mot_t
*image_mot
= image
->type_private
;
967 fileio_close(&image_mot
->fileio
);
969 if (image_mot
->buffer
)
971 free(image_mot
->buffer
);
972 image_mot
->buffer
= NULL
;
975 else if (image
->type
== IMAGE_BUILDER
)
979 for (i
= 0; i
< image
->num_sections
; i
++)
981 free(image
->sections
[i
].private);
982 image
->sections
[i
].private = NULL
;
986 if (image
->type_private
)
988 free(image
->type_private
);
989 image
->type_private
= NULL
;
994 free(image
->sections
);
995 image
->sections
= NULL
;
1001 int image_calculate_checksum(u8
* buffer
, u32 nbytes
, u32
* checksum
)
1003 u32 crc
= 0xffffffff;
1004 LOG_DEBUG("Calculating checksum");
1006 u32 crc32_table
[256];
1008 /* Initialize the CRC table and the decoding table. */
1011 for (i
= 0; i
< 256; i
++)
1014 for (c
= i
<< 24, j
= 8; j
> 0; --j
)
1015 c
= c
& 0x80000000 ? (c
<< 1) ^ 0x04c11db7 : (c
<< 1);
1030 crc
= (crc
<< 8) ^ crc32_table
[((crc
>> 24) ^ *buffer
++) & 255];
1035 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)