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 ***************************************************************************/
35 /* convert ELF header field to host endianness */
36 #define field16(elf,field)\
37 ((elf->endianness==ELFDATA2LSB)? \
38 le_to_h_u16((u8*)&field):be_to_h_u16((u8*)&field))
40 #define field32(elf,field)\
41 ((elf->endianness==ELFDATA2LSB)? \
42 le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
44 static int autodetect_image_type(image_t
*image
, char *url
)
51 /* read the first 4 bytes of image */
52 if ((retval
= fileio_open(&fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
56 retval
= fileio_read(&fileio
, 9, buffer
, &read_bytes
);
62 retval
=ERROR_FILEIO_OPERATION_FAILED
;
65 fileio_close(&fileio
);
70 /* check header against known signatures */
71 if (strncmp((char*)buffer
,ELFMAG
,SELFMAG
)==0)
73 LOG_DEBUG("ELF image detected.");
74 image
->type
= IMAGE_ELF
;
76 else if ((buffer
[0]==':') /* record start byte */
77 &&(isxdigit(buffer
[1]))
78 &&(isxdigit(buffer
[2]))
79 &&(isxdigit(buffer
[3]))
80 &&(isxdigit(buffer
[4]))
81 &&(isxdigit(buffer
[5]))
82 &&(isxdigit(buffer
[6]))
83 &&(buffer
[7]=='0') /* record type : 00 -> 05 */
84 &&(buffer
[8]>='0')&&(buffer
[8]<'6'))
86 LOG_DEBUG("IHEX image detected.");
87 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'))
95 LOG_DEBUG("S19 image detected.");
96 image
->type
= IMAGE_SRECORD
;
100 image
->type
= IMAGE_BINARY
;
106 static int identify_image_type(image_t
*image
, char *type_string
, char *url
)
110 if (!strcmp(type_string
, "bin"))
112 image
->type
= IMAGE_BINARY
;
114 else if (!strcmp(type_string
, "ihex"))
116 image
->type
= IMAGE_IHEX
;
118 else if (!strcmp(type_string
, "elf"))
120 image
->type
= IMAGE_ELF
;
122 else if (!strcmp(type_string
, "mem"))
124 image
->type
= IMAGE_MEMORY
;
126 else if (!strcmp(type_string
, "s19"))
128 image
->type
= IMAGE_SRECORD
;
130 else if (!strcmp(type_string
, "build"))
132 image
->type
= IMAGE_BUILDER
;
136 return ERROR_IMAGE_TYPE_UNKNOWN
;
141 return autodetect_image_type(image
, url
);
147 static int image_ihex_buffer_complete(image_t
*image
)
149 image_ihex_t
*ihex
= image
->type_private
;
150 fileio_t
*fileio
= &ihex
->fileio
;
151 u32 full_address
= 0x0;
156 /* we can't determine the number of sections that we'll have to create ahead of time,
157 * so we locally hold them until parsing is finished */
158 image_section_t section
[IMAGE_MAX_SECTIONS
];
160 ihex
->buffer
= malloc(fileio
->size
>> 1);
162 image
->num_sections
= 0;
163 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
164 section
[image
->num_sections
].base_address
= 0x0;
165 section
[image
->num_sections
].size
= 0x0;
166 section
[image
->num_sections
].flags
= 0;
168 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
177 if (sscanf(&lpszLine
[bytes_read
], ":%2x%4x%2x", &count
, &address
, &record_type
) != 3)
179 return ERROR_IMAGE_FORMAT_ERROR
;
183 cal_checksum
+= (u8
)count
;
184 cal_checksum
+= (u8
)(address
>> 8);
185 cal_checksum
+= (u8
)address
;
186 cal_checksum
+= (u8
)record_type
;
188 if (record_type
== 0) /* Data Record */
190 if ((full_address
& 0xffff) != address
)
192 /* we encountered a nonconsecutive location, create a new section,
193 * unless the current section has zero size, in which case this specifies
194 * the current section's base address
196 if (section
[image
->num_sections
].size
!= 0)
198 image
->num_sections
++;
199 section
[image
->num_sections
].size
= 0x0;
200 section
[image
->num_sections
].flags
= 0;
201 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
203 section
[image
->num_sections
].base_address
=
204 (full_address
& 0xffff0000) | address
;
205 full_address
= (full_address
& 0xffff0000) | address
;
211 sscanf(&lpszLine
[bytes_read
], "%2x", &value
);
212 ihex
->buffer
[cooked_bytes
] = (u8
)value
;
213 cal_checksum
+= (u8
)ihex
->buffer
[cooked_bytes
];
216 section
[image
->num_sections
].size
+= 1;
220 else if (record_type
== 1) /* End of File Record */
222 /* finish the current section */
223 image
->num_sections
++;
225 /* copy section information */
226 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
227 for (i
= 0; i
< image
->num_sections
; i
++)
229 image
->sections
[i
].private = section
[i
].private;
230 image
->sections
[i
].base_address
= section
[i
].base_address
;
231 image
->sections
[i
].size
= section
[i
].size
;
232 image
->sections
[i
].flags
= section
[i
].flags
;
237 else if (record_type
== 2) /* Linear Address Record */
241 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
242 cal_checksum
+= (u8
)(upper_address
>> 8);
243 cal_checksum
+= (u8
)upper_address
;
246 if ((full_address
>> 4) != upper_address
)
248 /* we encountered a nonconsecutive location, create a new section,
249 * unless the current section has zero size, in which case this specifies
250 * the current section's base address
252 if (section
[image
->num_sections
].size
!= 0)
254 image
->num_sections
++;
255 section
[image
->num_sections
].size
= 0x0;
256 section
[image
->num_sections
].flags
= 0;
257 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
259 section
[image
->num_sections
].base_address
=
260 (full_address
& 0xffff) | (upper_address
<< 4);
261 full_address
= (full_address
& 0xffff) | (upper_address
<< 4);
264 else if (record_type
== 3) /* Start Segment Address Record */
268 /* "Start Segment Address Record" will not be supported */
269 /* but we must consume it, and do not create an error. */
272 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
273 cal_checksum
+= (u8
)dummy
;
277 else if (record_type
== 4) /* Extended Linear Address Record */
281 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
282 cal_checksum
+= (u8
)(upper_address
>> 8);
283 cal_checksum
+= (u8
)upper_address
;
286 if ((full_address
>> 16) != upper_address
)
288 /* we encountered a nonconsecutive location, create a new section,
289 * unless the current section has zero size, in which case this specifies
290 * the current section's base address
292 if (section
[image
->num_sections
].size
!= 0)
294 image
->num_sections
++;
295 section
[image
->num_sections
].size
= 0x0;
296 section
[image
->num_sections
].flags
= 0;
297 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
299 section
[image
->num_sections
].base_address
=
300 (full_address
& 0xffff) | (upper_address
<< 16);
301 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
304 else if (record_type
== 5) /* Start Linear Address Record */
308 sscanf(&lpszLine
[bytes_read
], "%8x", &start_address
);
309 cal_checksum
+= (u8
)(start_address
>> 24);
310 cal_checksum
+= (u8
)(start_address
>> 16);
311 cal_checksum
+= (u8
)(start_address
>> 8);
312 cal_checksum
+= (u8
)start_address
;
315 image
->start_address_set
= 1;
316 image
->start_address
= be_to_h_u32((u8
*)&start_address
);
320 LOG_ERROR("unhandled IHEX record type: %i", record_type
);
321 return ERROR_IMAGE_FORMAT_ERROR
;
324 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
327 if ((u8
)checksum
!= (u8
)(~cal_checksum
+ 1))
329 /* checksum failed */
330 LOG_ERROR("incorrect record checksum found in IHEX file");
331 return ERROR_IMAGE_CHECKSUM
;
335 LOG_ERROR("premature end of IHEX file, no end-of-file record found");
336 return ERROR_IMAGE_FORMAT_ERROR
;
339 static int image_elf_read_headers(image_t
*image
)
341 image_elf_t
*elf
= image
->type_private
;
346 elf
->header
= malloc(sizeof(Elf32_Ehdr
));
348 if(elf
->header
== NULL
)
350 LOG_ERROR("insufficient memory to perform operation ");
351 return ERROR_FILEIO_OPERATION_FAILED
;
354 if ((retval
= fileio_read(&elf
->fileio
, sizeof(Elf32_Ehdr
), (u8
*)elf
->header
, &read_bytes
)) != ERROR_OK
)
356 LOG_ERROR("cannot read ELF file header, read failed");
357 return ERROR_FILEIO_OPERATION_FAILED
;
359 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)
367 LOG_ERROR("invalid ELF file, bad magic number");
368 return ERROR_IMAGE_FORMAT_ERROR
;
370 if (elf
->header
->e_ident
[EI_CLASS
]!=ELFCLASS32
)
372 LOG_ERROR("invalid ELF file, only 32bits files are supported");
373 return ERROR_IMAGE_FORMAT_ERROR
;
376 elf
->endianness
= elf
->header
->e_ident
[EI_DATA
];
377 if ((elf
->endianness
!=ELFDATA2LSB
)
378 &&(elf
->endianness
!=ELFDATA2MSB
))
380 LOG_ERROR("invalid ELF file, unknown endianess setting");
381 return ERROR_IMAGE_FORMAT_ERROR
;
384 elf
->segment_count
= field16(elf
,elf
->header
->e_phnum
);
385 if (elf
->segment_count
==0)
387 LOG_ERROR("invalid ELF file, no program headers");
388 return ERROR_IMAGE_FORMAT_ERROR
;
391 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,elf
->header
->e_phoff
))) != ERROR_OK
)
393 LOG_ERROR("cannot seek to ELF program header table, read failed");
397 elf
->segments
= malloc(elf
->segment_count
*sizeof(Elf32_Phdr
));
398 if(elf
->segments
== NULL
)
400 LOG_ERROR("insufficient memory to perform operation ");
401 return ERROR_FILEIO_OPERATION_FAILED
;
404 if ((retval
= fileio_read(&elf
->fileio
, elf
->segment_count
*sizeof(Elf32_Phdr
), (u8
*)elf
->segments
, &read_bytes
)) != ERROR_OK
)
406 LOG_ERROR("cannot read ELF segment headers, read failed");
409 if (read_bytes
!= elf
->segment_count
*sizeof(Elf32_Phdr
))
411 LOG_ERROR("cannot read ELF segment headers, only partially read");
412 return ERROR_FILEIO_OPERATION_FAILED
;
415 /* count useful segments (loadable), ignore BSS section */
416 image
->num_sections
= 0;
417 for (i
=0;i
<elf
->segment_count
;i
++)
418 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
419 image
->num_sections
++;
420 /* alloc and fill sections array with loadable segments */
421 image
->sections
= malloc(image
->num_sections
* sizeof(image_section_t
));
422 for (i
=0,j
=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))
426 image
->sections
[j
].size
= field32(elf
,elf
->segments
[i
].p_filesz
);
427 image
->sections
[j
].base_address
= field32(elf
,elf
->segments
[i
].p_paddr
);
428 image
->sections
[j
].private = &elf
->segments
[i
];
429 image
->sections
[j
].flags
= field32(elf
,elf
->segments
[i
].p_flags
);
434 image
->start_address_set
= 1;
435 image
->start_address
= field32(elf
,elf
->header
->e_entry
);
440 static int image_elf_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
442 image_elf_t
*elf
= image
->type_private
;
443 Elf32_Phdr
*segment
= (Elf32_Phdr
*)image
->sections
[section
].private;
444 u32 read_size
,really_read
;
449 LOG_DEBUG("load segment %d at 0x%x (sz=0x%x)",section
,offset
,size
);
451 /* read initialized data in current segment if any */
452 if (offset
<field32(elf
,segment
->p_filesz
))
454 /* maximal size present in file for the current segment */
455 read_size
= MIN(size
, field32(elf
,segment
->p_filesz
)-offset
);
456 LOG_DEBUG("read elf: size = 0x%x at 0x%x",read_size
,
457 field32(elf
,segment
->p_offset
)+offset
);
458 /* read initialized area of the segment */
459 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,segment
->p_offset
)+offset
)) != ERROR_OK
)
461 LOG_ERROR("cannot find ELF segment content, seek failed");
464 if ((retval
= fileio_read(&elf
->fileio
, read_size
, buffer
, &really_read
)) != ERROR_OK
)
466 LOG_ERROR("cannot read ELF segment content, read failed");
472 *size_read
+= read_size
;
473 /* need more data ? */
481 static int image_mot_buffer_complete(image_t
*image
)
483 image_mot_t
*mot
= image
->type_private
;
484 fileio_t
*fileio
= &mot
->fileio
;
485 u32 full_address
= 0x0;
490 /* we can't determine the number of sections that we'll have to create ahead of time,
491 * so we locally hold them until parsing is finished */
492 image_section_t section
[IMAGE_MAX_SECTIONS
];
494 mot
->buffer
= malloc(fileio
->size
>> 1);
496 image
->num_sections
= 0;
497 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
498 section
[image
->num_sections
].base_address
= 0x0;
499 section
[image
->num_sections
].size
= 0x0;
500 section
[image
->num_sections
].flags
= 0;
502 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
511 /* get record type and record length */
512 if (sscanf(&lpszLine
[bytes_read
], "S%1x%2x", &record_type
, &count
) != 2)
514 return ERROR_IMAGE_FORMAT_ERROR
;
518 cal_checksum
+= (u8
)count
;
520 /* skip checksum byte */
523 if (record_type
== 0)
525 /* S0 - starting record (optional) */
528 while (count
-- > 0) {
529 sscanf(&lpszLine
[bytes_read
], "%2x", &iValue
);
530 cal_checksum
+= (u8
)iValue
;
534 else if (record_type
>= 1 && record_type
<= 3)
536 switch( record_type
)
539 /* S1 - 16 bit address data record */
540 sscanf(&lpszLine
[bytes_read
], "%4x", &address
);
541 cal_checksum
+= (u8
)(address
>> 8);
542 cal_checksum
+= (u8
)address
;
548 /* S2 - 24 bit address data record */
549 sscanf(&lpszLine
[bytes_read
], "%6x", &address
);
550 cal_checksum
+= (u8
)(address
>> 16);
551 cal_checksum
+= (u8
)(address
>> 8);
552 cal_checksum
+= (u8
)address
;
558 /* S3 - 32 bit address data record */
559 sscanf(&lpszLine
[bytes_read
], "%8x", &address
);
560 cal_checksum
+= (u8
)(address
>> 24);
561 cal_checksum
+= (u8
)(address
>> 16);
562 cal_checksum
+= (u8
)(address
>> 8);
563 cal_checksum
+= (u8
)address
;
570 if (full_address
!= address
)
572 /* we encountered a nonconsecutive location, create a new section,
573 * unless the current section has zero size, in which case this specifies
574 * the current section's base address
576 if (section
[image
->num_sections
].size
!= 0)
578 image
->num_sections
++;
579 section
[image
->num_sections
].size
= 0x0;
580 section
[image
->num_sections
].flags
= 0;
581 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
583 section
[image
->num_sections
].base_address
= address
;
584 full_address
= address
;
590 sscanf(&lpszLine
[bytes_read
], "%2x", &value
);
591 mot
->buffer
[cooked_bytes
] = (u8
)value
;
592 cal_checksum
+= (u8
)mot
->buffer
[cooked_bytes
];
595 section
[image
->num_sections
].size
+= 1;
599 else if (record_type
== 5)
601 /* S5 is the data count record, we ignore it */
606 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
607 cal_checksum
+= (u8
)dummy
;
611 else if (record_type
>= 7 && record_type
<= 9)
613 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
614 image
->num_sections
++;
616 /* copy section information */
617 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
618 for (i
= 0; i
< image
->num_sections
; i
++)
620 image
->sections
[i
].private = section
[i
].private;
621 image
->sections
[i
].base_address
= section
[i
].base_address
;
622 image
->sections
[i
].size
= section
[i
].size
;
623 image
->sections
[i
].flags
= section
[i
].flags
;
630 LOG_ERROR("unhandled S19 record type: %i", record_type
);
631 return ERROR_IMAGE_FORMAT_ERROR
;
634 /* account for checksum, will always be 0xFF */
635 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
636 cal_checksum
+= (u8
)checksum
;
639 if( cal_checksum
!= 0xFF )
641 /* checksum failed */
642 LOG_ERROR("incorrect record checksum found in S19 file");
643 return ERROR_IMAGE_CHECKSUM
;
647 LOG_ERROR("premature end of S19 file, no end-of-file record found");
648 return ERROR_IMAGE_FORMAT_ERROR
;
651 int image_open(image_t
*image
, char *url
, char *type_string
)
653 int retval
= ERROR_OK
;
655 if ((retval
= identify_image_type(image
, type_string
, url
)) != ERROR_OK
)
660 if (image
->type
== IMAGE_BINARY
)
662 image_binary_t
*image_binary
;
664 image_binary
= image
->type_private
= malloc(sizeof(image_binary_t
));
666 if ((retval
= fileio_open(&image_binary
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
671 image
->num_sections
= 1;
672 image
->sections
= malloc(sizeof(image_section_t
));
673 image
->sections
[0].base_address
= 0x0;
674 image
->sections
[0].size
= image_binary
->fileio
.size
;
675 image
->sections
[0].flags
= 0;
677 else if (image
->type
== IMAGE_IHEX
)
679 image_ihex_t
*image_ihex
;
681 image_ihex
= image
->type_private
= malloc(sizeof(image_ihex_t
));
683 if ((retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
688 if ((retval
= image_ihex_buffer_complete(image
)) != ERROR_OK
)
690 LOG_ERROR("failed buffering IHEX image, check daemon output for additional information");
691 fileio_close(&image_ihex
->fileio
);
695 else if (image
->type
== IMAGE_ELF
)
697 image_elf_t
*image_elf
;
699 image_elf
= image
->type_private
= malloc(sizeof(image_elf_t
));
701 if ((retval
= fileio_open(&image_elf
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
706 if ((retval
= image_elf_read_headers(image
)) != ERROR_OK
)
708 fileio_close(&image_elf
->fileio
);
712 else if (image
->type
== IMAGE_MEMORY
)
714 target_t
*target
= get_target_by_num(strtoul(url
, NULL
, 0));
717 LOG_ERROR("Target '%s' does not exist", url
);
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
= target
;
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 void 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
;
999 int image_calculate_checksum(u8
* buffer
, u32 nbytes
, u32
* checksum
)
1001 u32 crc
= 0xffffffff;
1002 LOG_DEBUG("Calculating checksum");
1004 u32 crc32_table
[256];
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);
1028 crc
= (crc
<< 8) ^ crc32_table
[((crc
>> 24) ^ *buffer
++) & 255];
1033 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)