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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
36 #include "replacements.h"
42 /* convert ELF header field to host endianness */
43 #define field16(elf,field)\
44 ((elf->endianness==ELFDATA2LSB)? \
45 le_to_h_u16((u8*)&field):be_to_h_u16((u8*)&field))
47 #define field32(elf,field)\
48 ((elf->endianness==ELFDATA2LSB)? \
49 le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
51 static int autodetect_image_type(image_t
*image
, char *url
)
58 /* read the first 4 bytes of image */
59 if ((retval
= fileio_open(&fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
63 retval
= fileio_read(&fileio
, 9, buffer
, &read_bytes
);
69 retval
=ERROR_FILEIO_OPERATION_FAILED
;
72 fileio_close(&fileio
);
77 /* check header against known signatures */
78 if (strncmp((char*)buffer
,ELFMAG
,SELFMAG
)==0)
80 LOG_DEBUG("ELF image detected.");
81 image
->type
= IMAGE_ELF
;
83 else if ((buffer
[0]==':') /* record start byte */
84 &&(isxdigit(buffer
[1]))
85 &&(isxdigit(buffer
[2]))
86 &&(isxdigit(buffer
[3]))
87 &&(isxdigit(buffer
[4]))
88 &&(isxdigit(buffer
[5]))
89 &&(isxdigit(buffer
[6]))
90 &&(buffer
[7]=='0') /* record type : 00 -> 05 */
91 &&(buffer
[8]>='0')&&(buffer
[8]<'6'))
93 LOG_DEBUG("IHEX image detected.");
94 image
->type
= IMAGE_IHEX
;
96 else if ((buffer
[0] == 'S') /* record start byte */
97 &&(isxdigit(buffer
[1]))
98 &&(isxdigit(buffer
[2]))
99 &&(isxdigit(buffer
[3]))
100 &&(buffer
[1] >= '0') && (buffer
[1] < '9'))
102 LOG_DEBUG("S19 image detected.");
103 image
->type
= IMAGE_SRECORD
;
107 image
->type
= IMAGE_BINARY
;
113 int identify_image_type(image_t
*image
, char *type_string
, char *url
)
117 if (!strcmp(type_string
, "bin"))
119 image
->type
= IMAGE_BINARY
;
121 else if (!strcmp(type_string
, "ihex"))
123 image
->type
= IMAGE_IHEX
;
125 else if (!strcmp(type_string
, "elf"))
127 image
->type
= IMAGE_ELF
;
129 else if (!strcmp(type_string
, "mem"))
131 image
->type
= IMAGE_MEMORY
;
133 else if (!strcmp(type_string
, "s19"))
135 image
->type
= IMAGE_SRECORD
;
137 else if (!strcmp(type_string
, "build"))
139 image
->type
= IMAGE_BUILDER
;
143 return ERROR_IMAGE_TYPE_UNKNOWN
;
148 return autodetect_image_type(image
, url
);
154 int image_ihex_buffer_complete(image_t
*image
)
156 image_ihex_t
*ihex
= image
->type_private
;
157 fileio_t
*fileio
= &ihex
->fileio
;
158 u32 full_address
= 0x0;
163 /* we can't determine the number of sections that we'll have to create ahead of time,
164 * so we locally hold them until parsing is finished */
165 image_section_t section
[IMAGE_MAX_SECTIONS
];
167 ihex
->buffer
= malloc(fileio
->size
>> 1);
169 image
->num_sections
= 0;
170 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
171 section
[image
->num_sections
].base_address
= 0x0;
172 section
[image
->num_sections
].size
= 0x0;
173 section
[image
->num_sections
].flags
= 0;
175 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
184 if (sscanf(&lpszLine
[bytes_read
], ":%2x%4x%2x", &count
, &address
, &record_type
) != 3)
186 return ERROR_IMAGE_FORMAT_ERROR
;
190 cal_checksum
+= (u8
)count
;
191 cal_checksum
+= (u8
)(address
>> 8);
192 cal_checksum
+= (u8
)address
;
193 cal_checksum
+= (u8
)record_type
;
195 if (record_type
== 0) /* Data Record */
197 if ((full_address
& 0xffff) != address
)
199 /* we encountered a nonconsecutive location, create a new section,
200 * unless the current section has zero size, in which case this specifies
201 * the current section's base address
203 if (section
[image
->num_sections
].size
!= 0)
205 image
->num_sections
++;
206 section
[image
->num_sections
].size
= 0x0;
207 section
[image
->num_sections
].flags
= 0;
208 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
210 section
[image
->num_sections
].base_address
=
211 (full_address
& 0xffff0000) | address
;
212 full_address
= (full_address
& 0xffff0000) | address
;
217 sscanf(&lpszLine
[bytes_read
], "%2x", (u32
*)&ihex
->buffer
[cooked_bytes
]);
218 cal_checksum
+= (u8
)ihex
->buffer
[cooked_bytes
];
221 section
[image
->num_sections
].size
+= 1;
225 else if (record_type
== 1) /* End of File Record */
227 /* finish the current section */
228 image
->num_sections
++;
230 /* copy section information */
231 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
232 for (i
= 0; i
< image
->num_sections
; i
++)
234 image
->sections
[i
].private = section
[i
].private;
235 image
->sections
[i
].base_address
= section
[i
].base_address
;
236 image
->sections
[i
].size
= section
[i
].size
;
237 image
->sections
[i
].flags
= section
[i
].flags
;
242 else if (record_type
== 2) /* Linear Address Record */
246 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
247 cal_checksum
+= (u8
)(upper_address
>> 8);
248 cal_checksum
+= (u8
)upper_address
;
251 if ((full_address
>> 4) != upper_address
)
253 /* we encountered a nonconsecutive location, create a new section,
254 * unless the current section has zero size, in which case this specifies
255 * the current section's base address
257 if (section
[image
->num_sections
].size
!= 0)
259 image
->num_sections
++;
260 section
[image
->num_sections
].size
= 0x0;
261 section
[image
->num_sections
].flags
= 0;
262 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
264 section
[image
->num_sections
].base_address
=
265 (full_address
& 0xffff) | (upper_address
<< 4);
266 full_address
= (full_address
& 0xffff) | (upper_address
<< 4);
269 else if (record_type
== 3) /* Start Segment Address Record */
273 /* "Start Segment Address Record" will not be supported */
274 /* but we must consume it, and do not create an error. */
277 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
278 cal_checksum
+= (u8
)dummy
;
282 else if (record_type
== 4) /* Extended Linear Address Record */
286 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
287 cal_checksum
+= (u8
)(upper_address
>> 8);
288 cal_checksum
+= (u8
)upper_address
;
291 if ((full_address
>> 16) != upper_address
)
293 /* we encountered a nonconsecutive location, create a new section,
294 * unless the current section has zero size, in which case this specifies
295 * the current section's base address
297 if (section
[image
->num_sections
].size
!= 0)
299 image
->num_sections
++;
300 section
[image
->num_sections
].size
= 0x0;
301 section
[image
->num_sections
].flags
= 0;
302 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
304 section
[image
->num_sections
].base_address
=
305 (full_address
& 0xffff) | (upper_address
<< 16);
306 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
309 else if (record_type
== 5) /* Start Linear Address Record */
313 sscanf(&lpszLine
[bytes_read
], "%8x", &start_address
);
314 cal_checksum
+= (u8
)(start_address
>> 24);
315 cal_checksum
+= (u8
)(start_address
>> 16);
316 cal_checksum
+= (u8
)(start_address
>> 8);
317 cal_checksum
+= (u8
)start_address
;
320 image
->start_address_set
= 1;
321 image
->start_address
= be_to_h_u32((u8
*)&start_address
);
325 LOG_ERROR("unhandled IHEX record type: %i", record_type
);
326 return ERROR_IMAGE_FORMAT_ERROR
;
329 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
332 if ((u8
)checksum
!= (u8
)(~cal_checksum
+ 1))
334 /* checksum failed */
335 LOG_ERROR("incorrect record checksum found in IHEX file");
336 return ERROR_IMAGE_CHECKSUM
;
340 LOG_ERROR("premature end of IHEX file, no end-of-file record found");
341 return ERROR_IMAGE_FORMAT_ERROR
;
344 int image_elf_read_headers(image_t
*image
)
346 image_elf_t
*elf
= image
->type_private
;
351 elf
->header
= malloc(sizeof(Elf32_Ehdr
));
353 if(elf
->header
== NULL
)
355 LOG_ERROR("insufficient memory to perform operation ");
356 return ERROR_FILEIO_OPERATION_FAILED
;
359 if ((retval
= fileio_read(&elf
->fileio
, sizeof(Elf32_Ehdr
), (u8
*)elf
->header
, &read_bytes
)) != ERROR_OK
)
361 LOG_ERROR("cannot read ELF file header, read failed");
362 return ERROR_FILEIO_OPERATION_FAILED
;
364 if (read_bytes
!= sizeof(Elf32_Ehdr
))
366 LOG_ERROR("cannot read ELF file header, only partially read");
367 return ERROR_FILEIO_OPERATION_FAILED
;
370 if (strncmp((char*)elf
->header
->e_ident
,ELFMAG
,SELFMAG
)!=0)
372 LOG_ERROR("invalid ELF file, bad magic number");
373 return ERROR_IMAGE_FORMAT_ERROR
;
375 if (elf
->header
->e_ident
[EI_CLASS
]!=ELFCLASS32
)
377 LOG_ERROR("invalid ELF file, only 32bits files are supported");
378 return ERROR_IMAGE_FORMAT_ERROR
;
382 elf
->endianness
= elf
->header
->e_ident
[EI_DATA
];
383 if ((elf
->endianness
!=ELFDATA2LSB
)
384 &&(elf
->endianness
!=ELFDATA2MSB
))
386 LOG_ERROR("invalid ELF file, unknown endianess setting");
387 return ERROR_IMAGE_FORMAT_ERROR
;
390 elf
->segment_count
= field16(elf
,elf
->header
->e_phnum
);
391 if (elf
->segment_count
==0)
393 LOG_ERROR("invalid ELF file, no program headers");
394 return ERROR_IMAGE_FORMAT_ERROR
;
397 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,elf
->header
->e_phoff
))) != ERROR_OK
)
399 LOG_ERROR("cannot seek to ELF program header table, read failed");
403 elf
->segments
= malloc(elf
->segment_count
*sizeof(Elf32_Phdr
));
404 if(elf
->segments
== NULL
)
406 LOG_ERROR("insufficient memory to perform operation ");
407 return ERROR_FILEIO_OPERATION_FAILED
;
410 if ((retval
= fileio_read(&elf
->fileio
, elf
->segment_count
*sizeof(Elf32_Phdr
), (u8
*)elf
->segments
, &read_bytes
)) != ERROR_OK
)
412 LOG_ERROR("cannot read ELF segment headers, read failed");
415 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
;
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
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
425 image
->num_sections
++;
426 /* alloc and fill sections array with loadable segments */
427 image
->sections
= malloc(image
->num_sections
* sizeof(image_section_t
));
428 for (i
=0,j
=0;i
<elf
->segment_count
;i
++)
430 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
432 image
->sections
[j
].size
= field32(elf
,elf
->segments
[i
].p_filesz
);
433 image
->sections
[j
].base_address
= field32(elf
,elf
->segments
[i
].p_paddr
);
434 image
->sections
[j
].private = &elf
->segments
[i
];
435 image
->sections
[j
].flags
= field32(elf
,elf
->segments
[i
].p_flags
);
440 image
->start_address_set
= 1;
441 image
->start_address
= field32(elf
,elf
->header
->e_entry
);
446 int image_elf_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
448 image_elf_t
*elf
= image
->type_private
;
449 Elf32_Phdr
*segment
= (Elf32_Phdr
*)image
->sections
[section
].private;
450 u32 read_size
,really_read
;
455 LOG_DEBUG("load segment %d at 0x%x (sz=0x%x)",section
,offset
,size
);
457 /* read initialized data in current segment if any */
458 if (offset
<field32(elf
,segment
->p_filesz
))
460 /* maximal size present in file for the current segment */
461 read_size
= MIN(size
, field32(elf
,segment
->p_filesz
)-offset
);
462 LOG_DEBUG("read elf: size = 0x%x at 0x%x",read_size
,
463 field32(elf
,segment
->p_offset
)+offset
);
464 /* read initialized area of the segment */
465 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,segment
->p_offset
)+offset
)) != ERROR_OK
)
467 LOG_ERROR("cannot find ELF segment content, seek failed");
470 if ((retval
= fileio_read(&elf
->fileio
, read_size
, buffer
, &really_read
)) != ERROR_OK
)
472 LOG_ERROR("cannot read ELF segment content, read failed");
478 *size_read
+= read_size
;
479 /* need more data ? */
487 int image_mot_buffer_complete(image_t
*image
)
489 image_mot_t
*mot
= image
->type_private
;
490 fileio_t
*fileio
= &mot
->fileio
;
491 u32 full_address
= 0x0;
496 /* we can't determine the number of sections that we'll have to create ahead of time,
497 * so we locally hold them until parsing is finished */
498 image_section_t section
[IMAGE_MAX_SECTIONS
];
500 mot
->buffer
= malloc(fileio
->size
>> 1);
502 image
->num_sections
= 0;
503 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
504 section
[image
->num_sections
].base_address
= 0x0;
505 section
[image
->num_sections
].size
= 0x0;
506 section
[image
->num_sections
].flags
= 0;
508 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
517 /* get record type and record length */
518 if (sscanf(&lpszLine
[bytes_read
], "S%1x%2x", &record_type
, &count
) != 2)
520 return ERROR_IMAGE_FORMAT_ERROR
;
524 cal_checksum
+= (u8
)count
;
526 /* skip checksum byte */
529 if (record_type
== 0)
531 /* S0 - starting record (optional) */
534 while (count
-- > 0) {
535 sscanf(&lpszLine
[bytes_read
], "%2x", &iValue
);
536 cal_checksum
+= (u8
)iValue
;
540 else if (record_type
>= 1 && record_type
<= 3)
542 switch( record_type
)
545 /* S1 - 16 bit address data record */
546 sscanf(&lpszLine
[bytes_read
], "%4x", &address
);
547 cal_checksum
+= (u8
)(address
>> 8);
548 cal_checksum
+= (u8
)address
;
554 /* S2 - 24 bit address data record */
555 sscanf(&lpszLine
[bytes_read
], "%6x", &address
);
556 cal_checksum
+= (u8
)(address
>> 16);
557 cal_checksum
+= (u8
)(address
>> 8);
558 cal_checksum
+= (u8
)address
;
564 /* S3 - 32 bit address data record */
565 sscanf(&lpszLine
[bytes_read
], "%8x", &address
);
566 cal_checksum
+= (u8
)(address
>> 24);
567 cal_checksum
+= (u8
)(address
>> 16);
568 cal_checksum
+= (u8
)(address
>> 8);
569 cal_checksum
+= (u8
)address
;
576 if (full_address
!= address
)
578 /* we encountered a nonconsecutive location, create a new section,
579 * unless the current section has zero size, in which case this specifies
580 * the current section's base address
582 if (section
[image
->num_sections
].size
!= 0)
584 image
->num_sections
++;
585 section
[image
->num_sections
].size
= 0x0;
586 section
[image
->num_sections
].flags
= 0;
587 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
589 section
[image
->num_sections
].base_address
= address
;
590 full_address
= address
;
595 sscanf(&lpszLine
[bytes_read
], "%2x", (u32
*)&mot
->buffer
[cooked_bytes
]);
596 cal_checksum
+= (u8
)mot
->buffer
[cooked_bytes
];
599 section
[image
->num_sections
].size
+= 1;
603 else if (record_type
== 5)
605 /* S5 is the data count record, we ignore it */
610 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
611 cal_checksum
+= (u8
)dummy
;
615 else if (record_type
>= 7 && record_type
<= 9)
617 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
618 image
->num_sections
++;
620 /* copy section information */
621 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
622 for (i
= 0; i
< image
->num_sections
; i
++)
624 image
->sections
[i
].private = section
[i
].private;
625 image
->sections
[i
].base_address
= section
[i
].base_address
;
626 image
->sections
[i
].size
= section
[i
].size
;
627 image
->sections
[i
].flags
= section
[i
].flags
;
634 LOG_ERROR("unhandled S19 record type: %i", record_type
);
635 return ERROR_IMAGE_FORMAT_ERROR
;
638 /* account for checksum, will always be 0xFF */
639 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
640 cal_checksum
+= (u8
)checksum
;
643 if( cal_checksum
!= 0xFF )
645 /* checksum failed */
646 LOG_ERROR("incorrect record checksum found in S19 file");
647 return ERROR_IMAGE_CHECKSUM
;
651 LOG_ERROR("premature end of S19 file, no end-of-file record found");
652 return ERROR_IMAGE_FORMAT_ERROR
;
655 int image_open(image_t
*image
, char *url
, char *type_string
)
657 int retval
= ERROR_OK
;
659 if ((retval
= identify_image_type(image
, type_string
, url
)) != ERROR_OK
)
664 if (image
->type
== IMAGE_BINARY
)
666 image_binary_t
*image_binary
;
668 image_binary
= image
->type_private
= malloc(sizeof(image_binary_t
));
670 if ((retval
= fileio_open(&image_binary
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
675 image
->num_sections
= 1;
676 image
->sections
= malloc(sizeof(image_section_t
));
677 image
->sections
[0].base_address
= 0x0;
678 image
->sections
[0].size
= image_binary
->fileio
.size
;
679 image
->sections
[0].flags
= 0;
681 else if (image
->type
== IMAGE_IHEX
)
683 image_ihex_t
*image_ihex
;
685 image_ihex
= image
->type_private
= malloc(sizeof(image_ihex_t
));
687 if ((retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
692 if ((retval
= image_ihex_buffer_complete(image
)) != ERROR_OK
)
694 LOG_ERROR("failed buffering IHEX image, check daemon output for additional information");
695 fileio_close(&image_ihex
->fileio
);
699 else if (image
->type
== IMAGE_ELF
)
701 image_elf_t
*image_elf
;
703 image_elf
= image
->type_private
= malloc(sizeof(image_elf_t
));
705 if ((retval
= fileio_open(&image_elf
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
710 if ((retval
= image_elf_read_headers(image
)) != ERROR_OK
)
712 fileio_close(&image_elf
->fileio
);
716 else if (image
->type
== IMAGE_MEMORY
)
718 image_memory_t
*image_memory
;
720 image
->num_sections
= 1;
721 image
->sections
= malloc(sizeof(image_section_t
));
722 image
->sections
[0].base_address
= 0x0;
723 image
->sections
[0].size
= 0xffffffff;
724 image
->sections
[0].flags
= 0;
726 image_memory
= image
->type_private
= malloc(sizeof(image_memory_t
));
728 image_memory
->target
= get_target_by_num(strtoul(url
, NULL
, 0));;
729 image_memory
->cache
= NULL
;
730 image_memory
->cache_address
= 0x0;
732 else if (image
->type
== IMAGE_SRECORD
)
734 image_mot_t
*image_mot
;
736 image_mot
= image
->type_private
= malloc(sizeof(image_mot_t
));
738 if ((retval
= fileio_open(&image_mot
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
743 if ((retval
= image_mot_buffer_complete(image
)) != ERROR_OK
)
745 LOG_ERROR("failed buffering S19 image, check daemon output for additional information");
746 fileio_close(&image_mot
->fileio
);
750 else if (image
->type
== IMAGE_BUILDER
)
752 image
->num_sections
= 0;
753 image
->sections
= NULL
;
754 image
->type_private
= NULL
;
757 if (image
->base_address_set
)
761 for (section
=0; section
< image
->num_sections
; section
++)
763 image
->sections
[section
].base_address
+=image
->base_address
;
765 /* we're done relocating. The two statements below are mainly
766 * for documenation purposes: stop anyone from empirically
767 * thinking they should use these values henceforth. */
768 image
->base_address
=0;
769 image
->base_address_set
=0;
775 int image_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
779 /* don't read past the end of a section */
780 if (offset
+ size
> image
->sections
[section
].size
)
782 LOG_DEBUG("read past end of section: 0x%8.8x + 0x%8.8x > 0x%8.8x",
783 offset
, size
, image
->sections
[section
].size
);
784 return ERROR_INVALID_ARGUMENTS
;
787 if (image
->type
== IMAGE_BINARY
)
789 image_binary_t
*image_binary
= image
->type_private
;
791 /* only one section in a plain binary */
793 return ERROR_INVALID_ARGUMENTS
;
796 if ((retval
= fileio_seek(&image_binary
->fileio
, offset
)) != ERROR_OK
)
801 /* return requested bytes */
802 if ((retval
= fileio_read(&image_binary
->fileio
, size
, buffer
, size_read
)) != ERROR_OK
)
807 else if (image
->type
== IMAGE_IHEX
)
809 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
814 else if (image
->type
== IMAGE_ELF
)
816 return image_elf_read_section(image
, section
, offset
, size
, buffer
, size_read
);
818 else if (image
->type
== IMAGE_MEMORY
)
820 image_memory_t
*image_memory
= image
->type_private
;
821 u32 address
= image
->sections
[section
].base_address
+ offset
;
825 while ((size
- *size_read
) > 0)
829 if (!image_memory
->cache
830 || (address
< image_memory
->cache_address
)
831 || (address
>= (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
)))
833 if (!image_memory
->cache
)
834 image_memory
->cache
= malloc(IMAGE_MEMORY_CACHE_SIZE
);
836 if (target_read_buffer(image_memory
->target
, address
& ~(IMAGE_MEMORY_CACHE_SIZE
- 1),
837 IMAGE_MEMORY_CACHE_SIZE
, image_memory
->cache
) != ERROR_OK
)
839 free(image_memory
->cache
);
840 image_memory
->cache
= NULL
;
841 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE
;
843 image_memory
->cache_address
= address
& ~(IMAGE_MEMORY_CACHE_SIZE
- 1);
846 size_in_cache
= (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
) - address
;
848 memcpy(buffer
+ *size_read
,
849 image_memory
->cache
+ (address
- image_memory
->cache_address
),
850 (size_in_cache
> size
) ? size
: size_in_cache
853 *size_read
+= (size_in_cache
> size
) ? size
: size_in_cache
;
854 address
+= (size_in_cache
> size
) ? size
: size_in_cache
;
857 else if (image
->type
== IMAGE_SRECORD
)
859 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
864 else if (image
->type
== IMAGE_BUILDER
)
866 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
875 int image_add_section(image_t
*image
, u32 base
, u32 size
, int flags
, u8
*data
)
877 image_section_t
*section
;
879 /* only image builder supports adding sections */
880 if (image
->type
!= IMAGE_BUILDER
)
881 return ERROR_INVALID_ARGUMENTS
;
883 /* see if there's a previous section */
884 if (image
->num_sections
)
886 section
= &image
->sections
[image
->num_sections
- 1];
888 /* see if it's enough to extend the last section,
889 * adding data to previous sections or merging is not supported */
890 if (((section
->base_address
+ section
->size
) == base
) && (section
->flags
== flags
))
892 section
->private = realloc(section
->private, section
->size
+ size
);
893 memcpy((u8
*)section
->private + section
->size
, data
, size
);
894 section
->size
+= size
;
899 /* allocate new section */
900 image
->num_sections
++;
901 image
->sections
= realloc(image
->sections
, sizeof(image_section_t
) * image
->num_sections
);
902 section
= &image
->sections
[image
->num_sections
- 1];
903 section
->base_address
= base
;
904 section
->size
= size
;
905 section
->flags
= flags
;
906 section
->private = malloc(sizeof(u8
) * size
);
907 memcpy((u8
*)section
->private, data
, size
);
912 int image_close(image_t
*image
)
914 if (image
->type
== IMAGE_BINARY
)
916 image_binary_t
*image_binary
= image
->type_private
;
918 fileio_close(&image_binary
->fileio
);
920 else if (image
->type
== IMAGE_IHEX
)
922 image_ihex_t
*image_ihex
= image
->type_private
;
924 fileio_close(&image_ihex
->fileio
);
926 if (image_ihex
->buffer
)
928 free(image_ihex
->buffer
);
929 image_ihex
->buffer
= NULL
;
932 else if (image
->type
== IMAGE_ELF
)
934 image_elf_t
*image_elf
= image
->type_private
;
936 fileio_close(&image_elf
->fileio
);
938 if (image_elf
->header
)
940 free(image_elf
->header
);
941 image_elf
->header
= NULL
;
944 if (image_elf
->segments
)
946 free(image_elf
->segments
);
947 image_elf
->segments
= NULL
;
950 else if (image
->type
== IMAGE_MEMORY
)
952 image_memory_t
*image_memory
= image
->type_private
;
954 if (image_memory
->cache
)
956 free(image_memory
->cache
);
957 image_memory
->cache
= NULL
;
960 else if (image
->type
== IMAGE_SRECORD
)
962 image_mot_t
*image_mot
= image
->type_private
;
964 fileio_close(&image_mot
->fileio
);
966 if (image_mot
->buffer
)
968 free(image_mot
->buffer
);
969 image_mot
->buffer
= NULL
;
972 else if (image
->type
== IMAGE_BUILDER
)
976 for (i
= 0; i
< image
->num_sections
; i
++)
978 free(image
->sections
[i
].private);
979 image
->sections
[i
].private = NULL
;
983 if (image
->type_private
)
985 free(image
->type_private
);
986 image
->type_private
= NULL
;
991 free(image
->sections
);
992 image
->sections
= NULL
;
998 static u32 crc32_table
[256] = {0, 0};
1000 int image_calculate_checksum(u8
* buffer
, u32 nbytes
, u32
* checksum
)
1002 u32 crc
= 0xffffffff;
1004 if (!crc32_table
[1])
1006 /* Initialize the CRC table and the decoding table. */
1009 for (i
= 0; i
< 256; i
++)
1012 for (c
= i
<< 24, j
= 8; j
> 0; --j
)
1013 c
= c
& 0x80000000 ? (c
<< 1) ^ 0x04c11db7 : (c
<< 1);
1021 crc
= (crc
<< 8) ^ crc32_table
[((crc
>> 24) ^ *buffer
++) & 255];
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)