1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
33 #include "replacements.h"
39 /* convert ELF header field to host endianness */
40 #define field16(elf,field)\
41 ((elf->endianness==ELFDATA2LSB)? \
42 le_to_h_u16((u8*)&field):be_to_h_u16((u8*)&field))
44 #define field32(elf,field)\
45 ((elf->endianness==ELFDATA2LSB)? \
46 le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
48 static int autodetect_image_type(image_t
*image
, char *url
)
55 /* read the first 4 bytes of image */
56 if ((retval
= fileio_open(&fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
58 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
, "cannot open image: %s", fileio
.error_str
);
59 ERROR(image
->error_str
);
62 if ((retval
= fileio_read(&fileio
, 9, buffer
, &read_bytes
)) != ERROR_OK
)
64 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
, "cannot read image header: %s", fileio
.error_str
);
65 ERROR(image
->error_str
);
66 return ERROR_FILEIO_OPERATION_FAILED
;
70 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
, "cannot read image, only partially read");
71 ERROR(image
->error_str
);
72 return ERROR_FILEIO_OPERATION_FAILED
;
74 fileio_close(&fileio
);
76 /* check header against known signatures */
77 if (strncmp((char*)buffer
,ELFMAG
,SELFMAG
)==0)
79 DEBUG("ELF image detected.");
80 image
->type
= IMAGE_ELF
;
82 else if ((buffer
[0]==':') /* record start byte */
83 &&(isxdigit(buffer
[1]))
84 &&(isxdigit(buffer
[2]))
85 &&(isxdigit(buffer
[3]))
86 &&(isxdigit(buffer
[4]))
87 &&(isxdigit(buffer
[5]))
88 &&(isxdigit(buffer
[6]))
89 &&(buffer
[7]=='0') /* record type : 00 -> 05 */
90 &&(buffer
[8]>='0')&&(buffer
[8]<'6'))
92 DEBUG("IHEX image detected.");
93 image
->type
= IMAGE_IHEX
;
95 else if ((buffer
[0] == 'S') /* record start byte */
96 &&(isxdigit(buffer
[1]))
97 &&(isxdigit(buffer
[2]))
98 &&(isxdigit(buffer
[3]))
99 &&(buffer
[1] >= '0') && (buffer
[1] < '9'))
101 DEBUG("S19 image detected.");
102 image
->type
= IMAGE_SRECORD
;
106 image
->type
= IMAGE_BINARY
;
112 int identify_image_type(image_t
*image
, char *type_string
, char *url
)
116 if (!strcmp(type_string
, "bin"))
118 image
->type
= IMAGE_BINARY
;
120 else if (!strcmp(type_string
, "ihex"))
122 image
->type
= IMAGE_IHEX
;
124 else if (!strcmp(type_string
, "elf"))
126 image
->type
= IMAGE_ELF
;
128 else if (!strcmp(type_string
, "mem"))
130 image
->type
= IMAGE_MEMORY
;
132 else if (!strcmp(type_string
, "s19"))
134 image
->type
= IMAGE_SRECORD
;
136 else if (!strcmp(type_string
, "build"))
138 image
->type
= IMAGE_BUILDER
;
142 return ERROR_IMAGE_TYPE_UNKNOWN
;
147 return autodetect_image_type(image
, url
);
153 int image_ihex_buffer_complete(image_t
*image
)
155 image_ihex_t
*ihex
= image
->type_private
;
156 fileio_t
*fileio
= &ihex
->fileio
;
157 u32 raw_bytes_read
, raw_bytes
;
159 u32 full_address
= 0x0;
160 char *buffer
= malloc(fileio
->size
);
164 /* we can't determine the number of sections that we'll have to create ahead of time,
165 * so we locally hold them until parsing is finished */
166 image_section_t section
[IMAGE_MAX_SECTIONS
];
168 if ((retval
= fileio_read(fileio
, fileio
->size
, (u8
*)buffer
, &raw_bytes_read
)) != ERROR_OK
)
171 ERROR("failed buffering IHEX file, read failed");
172 return ERROR_FILEIO_OPERATION_FAILED
;
175 if (raw_bytes_read
!= fileio
->size
)
178 ERROR("failed buffering complete IHEX file, only partially read");
179 return ERROR_FILEIO_OPERATION_FAILED
;
182 ihex
->buffer
= malloc(fileio
->size
>> 1);
185 image
->num_sections
= 0;
186 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
187 section
[image
->num_sections
].base_address
= 0x0;
188 section
[image
->num_sections
].size
= 0x0;
189 section
[image
->num_sections
].flags
= 0;
190 while (raw_bytes
< raw_bytes_read
)
198 if (sscanf(&buffer
[raw_bytes
], ":%2x%4x%2x", &count
, &address
, &record_type
) != 3)
200 return ERROR_IMAGE_FORMAT_ERROR
;
204 cal_checksum
+= (u8
)count
;
205 cal_checksum
+= (u8
)(address
>> 8);
206 cal_checksum
+= (u8
)address
;
207 cal_checksum
+= (u8
)record_type
;
209 if (record_type
== 0) /* Data Record */
211 if ((full_address
& 0xffff) != address
)
213 /* we encountered a nonconsecutive location, create a new section,
214 * unless the current section has zero size, in which case this specifies
215 * the current section's base address
217 if (section
[image
->num_sections
].size
!= 0)
219 image
->num_sections
++;
220 section
[image
->num_sections
].size
= 0x0;
221 section
[image
->num_sections
].flags
= 0;
222 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
224 section
[image
->num_sections
].base_address
=
225 (full_address
& 0xffff0000) | address
;
226 full_address
= (full_address
& 0xffff0000) | address
;
231 sscanf(&buffer
[raw_bytes
], "%2hhx", &ihex
->buffer
[cooked_bytes
]);
232 cal_checksum
+= (u8
)ihex
->buffer
[cooked_bytes
];
235 section
[image
->num_sections
].size
+= 1;
239 else if (record_type
== 1) /* End of File Record */
241 /* finish the current section */
242 image
->num_sections
++;
244 /* copy section information */
245 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
246 for (i
= 0; i
< image
->num_sections
; i
++)
248 image
->sections
[i
].private = section
[i
].private;
249 image
->sections
[i
].base_address
= section
[i
].base_address
+
250 ((image
->base_address_set
) ? image
->base_address
: 0);
251 image
->sections
[i
].size
= section
[i
].size
;
252 image
->sections
[i
].flags
= section
[i
].flags
;
258 else if (record_type
== 4) /* Extended Linear Address Record */
262 sscanf(&buffer
[raw_bytes
], "%4hx", &upper_address
);
263 cal_checksum
+= (u8
)(upper_address
>> 8);
264 cal_checksum
+= (u8
)upper_address
;
267 if ((full_address
>> 16) != upper_address
)
269 /* we encountered a nonconsecutive location, create a new section,
270 * unless the current section has zero size, in which case this specifies
271 * the current section's base address
273 if (section
[image
->num_sections
].size
!= 0)
275 image
->num_sections
++;
276 section
[image
->num_sections
].size
= 0x0;
277 section
[image
->num_sections
].flags
= 0;
278 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
280 section
[image
->num_sections
].base_address
=
281 (full_address
& 0xffff) | (upper_address
<< 16);
282 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
285 else if (record_type
== 5) /* Start Linear Address Record */
289 sscanf(&buffer
[raw_bytes
], "%8x", &start_address
);
290 cal_checksum
+= (u8
)(start_address
>> 24);
291 cal_checksum
+= (u8
)(start_address
>> 16);
292 cal_checksum
+= (u8
)(start_address
>> 8);
293 cal_checksum
+= (u8
)start_address
;
296 image
->start_address_set
= 1;
297 image
->start_address
= be_to_h_u32((u8
*)&start_address
);
302 ERROR("unhandled IHEX record type: %i", record_type
);
303 return ERROR_IMAGE_FORMAT_ERROR
;
306 sscanf(&buffer
[raw_bytes
], "%2x", &checksum
);
309 if ((u8
)checksum
!= (u8
)(~cal_checksum
+ 1))
311 /* checksum failed */
313 ERROR("incorrect record checksum found in IHEX file");
314 return ERROR_IMAGE_CHECKSUM
;
317 /* consume new-line character(s) */
318 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
321 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
326 ERROR("premature end of IHEX file, no end-of-file record found");
327 return ERROR_IMAGE_FORMAT_ERROR
;
330 int image_elf_read_headers(image_t
*image
)
332 image_elf_t
*elf
= image
->type_private
;
337 elf
->header
= malloc(sizeof(Elf32_Ehdr
));
339 if ((retval
= fileio_read(&elf
->fileio
, sizeof(Elf32_Ehdr
), (u8
*)elf
->header
, &read_bytes
)) != ERROR_OK
)
341 ERROR("cannot read ELF file header, read failed");
342 return ERROR_FILEIO_OPERATION_FAILED
;
344 if (read_bytes
!= sizeof(Elf32_Ehdr
))
346 ERROR("cannot read ELF file header, only partially read");
347 return ERROR_FILEIO_OPERATION_FAILED
;
350 if (strncmp((char*)elf
->header
->e_ident
,ELFMAG
,SELFMAG
)!=0)
352 ERROR("invalid ELF file, bad magic number");
353 return ERROR_IMAGE_FORMAT_ERROR
;
355 if (elf
->header
->e_ident
[EI_CLASS
]!=ELFCLASS32
)
357 ERROR("invalid ELF file, only 32bits files are supported");
358 return ERROR_IMAGE_FORMAT_ERROR
;
362 elf
->endianness
= elf
->header
->e_ident
[EI_DATA
];
363 if ((elf
->endianness
!=ELFDATA2LSB
)
364 &&(elf
->endianness
!=ELFDATA2MSB
))
366 ERROR("invalid ELF file, unknown endianess setting");
367 return ERROR_IMAGE_FORMAT_ERROR
;
370 elf
->segment_count
= field16(elf
,elf
->header
->e_phnum
);
371 if (elf
->segment_count
==0)
373 ERROR("invalid ELF file, no program headers");
374 return ERROR_IMAGE_FORMAT_ERROR
;
377 elf
->segments
= malloc(elf
->segment_count
*sizeof(Elf32_Phdr
));
379 if ((retval
= fileio_read(&elf
->fileio
, elf
->segment_count
*sizeof(Elf32_Phdr
), (u8
*)elf
->segments
, &read_bytes
)) != ERROR_OK
)
381 ERROR("cannot read ELF segment headers, read failed");
384 if (read_bytes
!= elf
->segment_count
*sizeof(Elf32_Phdr
))
386 ERROR("cannot read ELF segment headers, only partially read");
387 return ERROR_FILEIO_OPERATION_FAILED
;
390 /* count useful segments (loadable), ignore BSS section */
391 image
->num_sections
= 0;
392 for (i
=0;i
<elf
->segment_count
;i
++)
393 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
394 image
->num_sections
++;
395 /* alloc and fill sections array with loadable segments */
396 image
->sections
= malloc(image
->num_sections
* sizeof(image_section_t
));
397 for (i
=0,j
=0;i
<elf
->segment_count
;i
++)
399 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
401 image
->sections
[j
].size
= field32(elf
,elf
->segments
[i
].p_memsz
);
402 image
->sections
[j
].base_address
= field32(elf
,elf
->segments
[i
].p_paddr
);
403 image
->sections
[j
].private = &elf
->segments
[i
];
404 image
->sections
[j
].flags
= field32(elf
,elf
->segments
[i
].p_flags
);
409 image
->start_address_set
= 1;
410 image
->start_address
= field32(elf
,elf
->header
->e_entry
);
415 int image_elf_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
417 image_elf_t
*elf
= image
->type_private
;
418 Elf32_Phdr
*segment
= (Elf32_Phdr
*)image
->sections
[section
].private;
419 u32 read_size
,really_read
;
424 DEBUG("load segment %d at 0x%x (sz=0x%x)",section
,offset
,size
);
426 /* read initialized data in current segment if any */
427 if (offset
<field32(elf
,segment
->p_filesz
))
429 /* maximal size present in file for the current segment */
430 read_size
= MIN(size
, field32(elf
,segment
->p_filesz
)-offset
);
431 DEBUG("read elf: size = 0x%x at 0x%x",read_size
,
432 field32(elf
,segment
->p_offset
)+offset
);
433 /* read initialized area of the segment */
434 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,segment
->p_offset
)+offset
)) != ERROR_OK
)
436 ERROR("cannot find ELF segment content, seek failed");
439 if ((retval
= fileio_read(&elf
->fileio
, read_size
, buffer
, &really_read
)) != ERROR_OK
)
441 ERROR("cannot read ELF segment content, read failed");
447 *size_read
+= read_size
;
448 /* need more data ? */
452 /* if there is remaining zeroed area in current segment */
453 if (offset
<field32(elf
,segment
->p_memsz
))
455 /* fill zeroed part (BSS) of the segment */
456 read_size
= MIN(size
, field32(elf
,segment
->p_memsz
)-offset
);
457 DEBUG("zero fill: size = 0x%x",read_size
);
458 memset(buffer
,0,read_size
);
459 *size_read
+= read_size
;
465 int image_mot_buffer_complete(image_t
*image
)
467 image_mot_t
*mot
= image
->type_private
;
468 fileio_t
*fileio
= &mot
->fileio
;
469 u32 raw_bytes_read
, raw_bytes
;
471 u32 full_address
= 0x0;
472 char *buffer
= malloc(fileio
->size
);
476 /* we can't determine the number of sections that we'll have to create ahead of time,
477 * so we locally hold them until parsing is finished */
478 image_section_t section
[IMAGE_MAX_SECTIONS
];
480 if ((retval
= fileio_read(fileio
, fileio
->size
, (u8
*)buffer
, &raw_bytes_read
)) != ERROR_OK
)
483 ERROR("failed buffering S19 file, read failed");
484 return ERROR_FILEIO_OPERATION_FAILED
;
487 if (raw_bytes_read
!= fileio
->size
)
490 ERROR("failed buffering complete IHEX file, only partially read");
491 return ERROR_FILEIO_OPERATION_FAILED
;
494 mot
->buffer
= malloc(fileio
->size
>> 1);
497 image
->num_sections
= 0;
498 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
499 section
[image
->num_sections
].base_address
= 0x0;
500 section
[image
->num_sections
].size
= 0x0;
501 section
[image
->num_sections
].flags
= 0;
503 while (raw_bytes
< raw_bytes_read
)
511 /* get record type and record length */
512 if (sscanf(&buffer
[raw_bytes
], "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(&buffer
[raw_bytes
], "%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(&buffer
[raw_bytes
], "%4x", &address
);
541 cal_checksum
+= (u8
)(address
>> 8);
542 cal_checksum
+= (u8
)address
;
548 /* S2 - 24 bit address data record */
549 sscanf(&buffer
[raw_bytes
], "%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(&buffer
[raw_bytes
], "%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
=
584 full_address
| address
;
585 full_address
= full_address
| address
;
590 sscanf(&buffer
[raw_bytes
], "%2hhx", &mot
->buffer
[cooked_bytes
]);
591 cal_checksum
+= (u8
)mot
->buffer
[cooked_bytes
];
594 section
[image
->num_sections
].size
+= 1;
598 else if (record_type
>= 7 && record_type
<= 9)
600 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
601 image
->num_sections
++;
603 /* copy section information */
604 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
605 for (i
= 0; i
< image
->num_sections
; i
++)
607 image
->sections
[i
].private = section
[i
].private;
608 image
->sections
[i
].base_address
= section
[i
].base_address
+
609 ((image
->base_address_set
) ? image
->base_address
: 0);
610 image
->sections
[i
].size
= section
[i
].size
;
611 image
->sections
[i
].flags
= section
[i
].flags
;
620 ERROR("unhandled S19 record type: %i", record_type
);
621 return ERROR_IMAGE_FORMAT_ERROR
;
624 /* account for checksum, will always be 0xFF */
625 sscanf(&buffer
[raw_bytes
], "%2x", &checksum
);
626 cal_checksum
+= (u8
)checksum
;
629 if( cal_checksum
!= 0xFF )
631 /* checksum failed */
633 ERROR("incorrect record checksum found in S19 file");
634 return ERROR_IMAGE_CHECKSUM
;
637 /* consume new-line character(s) */
638 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
641 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
646 ERROR("premature end of S19 file, no end-of-file record found");
647 return ERROR_IMAGE_FORMAT_ERROR
;
650 int image_open(image_t
*image
, char *url
, char *type_string
)
652 int retval
= ERROR_OK
;
654 if ((retval
= identify_image_type(image
, type_string
, url
)) != ERROR_OK
)
659 if (image
->type
== IMAGE_BINARY
)
661 image_binary_t
*image_binary
;
663 image_binary
= image
->type_private
= malloc(sizeof(image_binary_t
));
665 if ((retval
= fileio_open(&image_binary
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
667 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
668 ERROR(image
->error_str
);
672 image
->num_sections
= 1;
673 image
->sections
= malloc(sizeof(image_section_t
));
674 image
->sections
[0].base_address
= 0x0;
675 image
->sections
[0].size
= image_binary
->fileio
.size
;
676 image
->sections
[0].flags
= 0;
678 if (image
->base_address_set
== 1)
679 image
->sections
[0].base_address
= image
->base_address
;
683 else if (image
->type
== IMAGE_IHEX
)
685 image_ihex_t
*image_ihex
;
687 image_ihex
= image
->type_private
= malloc(sizeof(image_ihex_t
));
689 if ((retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
691 strncpy(image
->error_str
, image_ihex
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
692 ERROR(image
->error_str
);
696 if ((retval
= image_ihex_buffer_complete(image
)) != ERROR_OK
)
698 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
699 "failed buffering IHEX image, check daemon output for additional information");
700 ERROR(image
->error_str
);
701 fileio_close(&image_ihex
->fileio
);
705 else if (image
->type
== IMAGE_ELF
)
707 image_elf_t
*image_elf
;
709 image_elf
= image
->type_private
= malloc(sizeof(image_elf_t
));
711 if ((retval
= fileio_open(&image_elf
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
713 strncpy(image
->error_str
, image_elf
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
714 ERROR(image
->error_str
);
718 if ((retval
= image_elf_read_headers(image
)) != ERROR_OK
)
720 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
721 "failed to read ELF headers, check daemon output for additional information");
722 ERROR(image
->error_str
);
723 fileio_close(&image_elf
->fileio
);
727 else if (image
->type
== IMAGE_MEMORY
)
729 image_memory_t
*image_memory
;
731 image
->num_sections
= 1;
732 image
->sections
= malloc(sizeof(image_section_t
));
733 image
->sections
[0].base_address
= 0x0;
734 image
->sections
[0].size
= 0xffffffff;
735 image
->sections
[0].flags
= 0;
737 image_memory
= image
->type_private
= malloc(sizeof(image_memory_t
));
739 image_memory
->target
= get_target_by_num(strtoul(url
, NULL
, 0));;
740 image_memory
->cache
= NULL
;
741 image_memory
->cache_address
= 0x0;
743 else if (image
->type
== IMAGE_SRECORD
)
745 image_mot_t
*image_mot
;
747 image_mot
= image
->type_private
= malloc(sizeof(image_mot_t
));
749 if ((retval
= fileio_open(&image_mot
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
751 strncpy(image
->error_str
, image_mot
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
752 ERROR(image
->error_str
);
756 if ((retval
= image_mot_buffer_complete(image
)) != ERROR_OK
)
758 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
759 "failed buffering S19 image, check daemon output for additional information");
760 ERROR(image
->error_str
);
761 fileio_close(&image_mot
->fileio
);
765 else if (image
->type
== IMAGE_BUILDER
)
767 image
->num_sections
= 0;
768 image
->sections
= NULL
;
769 image
->type_private
= NULL
;
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 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
)
798 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
802 /* return requested bytes */
803 if ((retval
= fileio_read(&image_binary
->fileio
, size
, buffer
, size_read
)) != ERROR_OK
)
805 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
809 else if (image
->type
== IMAGE_IHEX
)
811 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
813 image
->error_str
[0] = '\0';
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 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE
;
845 image_memory
->cache_address
= address
& ~(IMAGE_MEMORY_CACHE_SIZE
- 1);
848 size_in_cache
= (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
) - address
;
850 memcpy(buffer
+ *size_read
,
851 image_memory
->cache
+ (address
- image_memory
->cache_address
),
852 (size_in_cache
> size
) ? size
: size_in_cache
855 *size_read
+= (size_in_cache
> size
) ? size
: size_in_cache
;
856 address
+= (size_in_cache
> size
) ? size
: size_in_cache
;
859 else if (image
->type
== IMAGE_SRECORD
)
861 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
863 image
->error_str
[0] = '\0';
867 else if (image
->type
== IMAGE_BUILDER
)
869 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
871 image
->error_str
[0] = '\0';
879 int image_add_section(image_t
*image
, u32 base
, u32 size
, int flags
, u8
*data
)
881 /* only image builder supports adding sections */
882 if (image
->type
!= IMAGE_BUILDER
)
883 return ERROR_INVALID_ARGUMENTS
;
885 /* see if it's enough to extend an existing section */
886 if (((image
->sections
[image
->num_sections
- 1].base_address
+ image
->sections
[image
->num_sections
- 1].size
) == base
)
887 && (image
->sections
[image
->num_sections
- 1].flags
== flags
))
889 u32 old_size
= image
->sections
[image
->num_sections
- 1].size
;
890 image
->sections
[image
->num_sections
- 1].size
+= size
;
891 image
->sections
[image
->num_sections
- 1].private = realloc(image
->sections
[image
->num_sections
- 1].private, image
->sections
[image
->num_sections
- 1].size
);
892 memcpy((u8
*)image
->sections
[image
->num_sections
- 1].private + old_size
, data
, size
);
897 /* allocate new section */
898 image
->num_sections
++;
899 image
->sections
= realloc(image
->sections
, sizeof(image_section_t
) * image
->num_sections
);
900 image
->sections
[image
->num_sections
- 1].base_address
= base
;
901 image
->sections
[image
->num_sections
- 1].size
= size
;
902 image
->sections
[image
->num_sections
- 1].flags
= flags
;
903 image
->sections
[image
->num_sections
- 1].private = malloc(sizeof(u8
) * size
);
904 memcpy((u8
*)image
->sections
[image
->num_sections
- 1].private, data
, size
);
909 int image_close(image_t
*image
)
911 if (image
->type
== IMAGE_BINARY
)
913 image_binary_t
*image_binary
= image
->type_private
;
915 fileio_close(&image_binary
->fileio
);
917 else if (image
->type
== IMAGE_IHEX
)
919 image_ihex_t
*image_ihex
= image
->type_private
;
921 fileio_close(&image_ihex
->fileio
);
923 if (image_ihex
->buffer
)
924 free(image_ihex
->buffer
);
926 else if (image
->type
== IMAGE_ELF
)
928 image_elf_t
*image_elf
= image
->type_private
;
930 fileio_close(&image_elf
->fileio
);
932 if (image_elf
->header
)
933 free(image_elf
->header
);
935 if (image_elf
->segments
)
936 free(image_elf
->segments
);
938 else if (image
->type
== IMAGE_MEMORY
)
940 image_memory_t
*image_memory
= image
->type_private
;
942 if (image_memory
->cache
)
943 free(image_memory
->cache
);
945 else if (image
->type
== IMAGE_SRECORD
)
947 image_mot_t
*image_mot
= image
->type_private
;
949 fileio_close(&image_mot
->fileio
);
951 if (image_mot
->buffer
)
952 free(image_mot
->buffer
);
954 else if (image
->type
== IMAGE_BUILDER
)
958 for (i
= 0; i
< image
->num_sections
; i
++)
960 free(image
->sections
[i
].private);
964 if (image
->type_private
)
965 free(image
->type_private
);
968 free(image
->sections
);
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)