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 full_address
= 0x0;
162 /* we can't determine the number of sections that we'll have to create ahead of time,
163 * so we locally hold them until parsing is finished */
164 image_section_t section
[IMAGE_MAX_SECTIONS
];
166 ihex
->buffer
= malloc(fileio
->size
>> 1);
168 image
->num_sections
= 0;
169 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
170 section
[image
->num_sections
].base_address
= 0x0;
171 section
[image
->num_sections
].size
= 0x0;
172 section
[image
->num_sections
].flags
= 0;
174 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
183 if (sscanf(&lpszLine
[bytes_read
], ":%2x%4x%2x", &count
, &address
, &record_type
) != 3)
185 return ERROR_IMAGE_FORMAT_ERROR
;
189 cal_checksum
+= (u8
)count
;
190 cal_checksum
+= (u8
)(address
>> 8);
191 cal_checksum
+= (u8
)address
;
192 cal_checksum
+= (u8
)record_type
;
194 if (record_type
== 0) /* Data Record */
196 if ((full_address
& 0xffff) != address
)
198 /* we encountered a nonconsecutive location, create a new section,
199 * unless the current section has zero size, in which case this specifies
200 * the current section's base address
202 if (section
[image
->num_sections
].size
!= 0)
204 image
->num_sections
++;
205 section
[image
->num_sections
].size
= 0x0;
206 section
[image
->num_sections
].flags
= 0;
207 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
209 section
[image
->num_sections
].base_address
=
210 (full_address
& 0xffff0000) | address
;
211 full_address
= (full_address
& 0xffff0000) | address
;
216 sscanf(&lpszLine
[bytes_read
], "%2x", (u32
*)&ihex
->buffer
[cooked_bytes
]);
217 cal_checksum
+= (u8
)ihex
->buffer
[cooked_bytes
];
220 section
[image
->num_sections
].size
+= 1;
224 else if (record_type
== 1) /* End of File Record */
226 /* finish the current section */
227 image
->num_sections
++;
229 /* copy section information */
230 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
231 for (i
= 0; i
< image
->num_sections
; i
++)
233 image
->sections
[i
].private = section
[i
].private;
234 image
->sections
[i
].base_address
= section
[i
].base_address
;
235 image
->sections
[i
].size
= section
[i
].size
;
236 image
->sections
[i
].flags
= section
[i
].flags
;
241 else if (record_type
== 2) /* Linear Address Record */
245 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
246 cal_checksum
+= (u8
)(upper_address
>> 8);
247 cal_checksum
+= (u8
)upper_address
;
250 if ((full_address
>> 4) != upper_address
)
252 /* we encountered a nonconsecutive location, create a new section,
253 * unless the current section has zero size, in which case this specifies
254 * the current section's base address
256 if (section
[image
->num_sections
].size
!= 0)
258 image
->num_sections
++;
259 section
[image
->num_sections
].size
= 0x0;
260 section
[image
->num_sections
].flags
= 0;
261 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
263 section
[image
->num_sections
].base_address
=
264 (full_address
& 0xffff) | (upper_address
<< 4);
265 full_address
= (full_address
& 0xffff) | (upper_address
<< 4);
268 else if (record_type
== 3) /* Start Segment Address Record */
272 /* "Start Segment Address Record" will not be supported */
273 /* but we must consume it, and do not create an error. */
276 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
277 cal_checksum
+= (u8
)dummy
;
281 else if (record_type
== 4) /* Extended Linear Address Record */
285 sscanf(&lpszLine
[bytes_read
], "%4hx", &upper_address
);
286 cal_checksum
+= (u8
)(upper_address
>> 8);
287 cal_checksum
+= (u8
)upper_address
;
290 if ((full_address
>> 16) != upper_address
)
292 /* we encountered a nonconsecutive location, create a new section,
293 * unless the current section has zero size, in which case this specifies
294 * the current section's base address
296 if (section
[image
->num_sections
].size
!= 0)
298 image
->num_sections
++;
299 section
[image
->num_sections
].size
= 0x0;
300 section
[image
->num_sections
].flags
= 0;
301 section
[image
->num_sections
].private = &ihex
->buffer
[cooked_bytes
];
303 section
[image
->num_sections
].base_address
=
304 (full_address
& 0xffff) | (upper_address
<< 16);
305 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
308 else if (record_type
== 5) /* Start Linear Address Record */
312 sscanf(&lpszLine
[bytes_read
], "%8x", &start_address
);
313 cal_checksum
+= (u8
)(start_address
>> 24);
314 cal_checksum
+= (u8
)(start_address
>> 16);
315 cal_checksum
+= (u8
)(start_address
>> 8);
316 cal_checksum
+= (u8
)start_address
;
319 image
->start_address_set
= 1;
320 image
->start_address
= be_to_h_u32((u8
*)&start_address
);
324 ERROR("unhandled IHEX record type: %i", record_type
);
325 return ERROR_IMAGE_FORMAT_ERROR
;
328 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
331 if ((u8
)checksum
!= (u8
)(~cal_checksum
+ 1))
333 /* checksum failed */
334 ERROR("incorrect record checksum found in IHEX file");
335 return ERROR_IMAGE_CHECKSUM
;
339 ERROR("premature end of IHEX file, no end-of-file record found");
340 return ERROR_IMAGE_FORMAT_ERROR
;
343 int image_elf_read_headers(image_t
*image
)
345 image_elf_t
*elf
= image
->type_private
;
350 elf
->header
= malloc(sizeof(Elf32_Ehdr
));
352 if ((retval
= fileio_read(&elf
->fileio
, sizeof(Elf32_Ehdr
), (u8
*)elf
->header
, &read_bytes
)) != ERROR_OK
)
354 ERROR("cannot read ELF file header, read failed");
355 return ERROR_FILEIO_OPERATION_FAILED
;
357 if (read_bytes
!= sizeof(Elf32_Ehdr
))
359 ERROR("cannot read ELF file header, only partially read");
360 return ERROR_FILEIO_OPERATION_FAILED
;
363 if (strncmp((char*)elf
->header
->e_ident
,ELFMAG
,SELFMAG
)!=0)
365 ERROR("invalid ELF file, bad magic number");
366 return ERROR_IMAGE_FORMAT_ERROR
;
368 if (elf
->header
->e_ident
[EI_CLASS
]!=ELFCLASS32
)
370 ERROR("invalid ELF file, only 32bits files are supported");
371 return ERROR_IMAGE_FORMAT_ERROR
;
375 elf
->endianness
= elf
->header
->e_ident
[EI_DATA
];
376 if ((elf
->endianness
!=ELFDATA2LSB
)
377 &&(elf
->endianness
!=ELFDATA2MSB
))
379 ERROR("invalid ELF file, unknown endianess setting");
380 return ERROR_IMAGE_FORMAT_ERROR
;
383 elf
->segment_count
= field16(elf
,elf
->header
->e_phnum
);
384 if (elf
->segment_count
==0)
386 ERROR("invalid ELF file, no program headers");
387 return ERROR_IMAGE_FORMAT_ERROR
;
390 elf
->segments
= malloc(elf
->segment_count
*sizeof(Elf32_Phdr
));
392 if ((retval
= fileio_read(&elf
->fileio
, elf
->segment_count
*sizeof(Elf32_Phdr
), (u8
*)elf
->segments
, &read_bytes
)) != ERROR_OK
)
394 ERROR("cannot read ELF segment headers, read failed");
397 if (read_bytes
!= elf
->segment_count
*sizeof(Elf32_Phdr
))
399 ERROR("cannot read ELF segment headers, only partially read");
400 return ERROR_FILEIO_OPERATION_FAILED
;
403 /* count useful segments (loadable), ignore BSS section */
404 image
->num_sections
= 0;
405 for (i
=0;i
<elf
->segment_count
;i
++)
406 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
407 image
->num_sections
++;
408 /* alloc and fill sections array with loadable segments */
409 image
->sections
= malloc(image
->num_sections
* sizeof(image_section_t
));
410 for (i
=0,j
=0;i
<elf
->segment_count
;i
++)
412 if ((field32(elf
, elf
->segments
[i
].p_type
) == PT_LOAD
) && (field32(elf
, elf
->segments
[i
].p_filesz
) != 0))
414 image
->sections
[j
].size
= field32(elf
,elf
->segments
[i
].p_memsz
);
415 image
->sections
[j
].base_address
= field32(elf
,elf
->segments
[i
].p_paddr
);
416 image
->sections
[j
].private = &elf
->segments
[i
];
417 image
->sections
[j
].flags
= field32(elf
,elf
->segments
[i
].p_flags
);
422 image
->start_address_set
= 1;
423 image
->start_address
= field32(elf
,elf
->header
->e_entry
);
428 int image_elf_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
430 image_elf_t
*elf
= image
->type_private
;
431 Elf32_Phdr
*segment
= (Elf32_Phdr
*)image
->sections
[section
].private;
432 u32 read_size
,really_read
;
437 DEBUG("load segment %d at 0x%x (sz=0x%x)",section
,offset
,size
);
439 /* read initialized data in current segment if any */
440 if (offset
<field32(elf
,segment
->p_filesz
))
442 /* maximal size present in file for the current segment */
443 read_size
= MIN(size
, field32(elf
,segment
->p_filesz
)-offset
);
444 DEBUG("read elf: size = 0x%x at 0x%x",read_size
,
445 field32(elf
,segment
->p_offset
)+offset
);
446 /* read initialized area of the segment */
447 if ((retval
= fileio_seek(&elf
->fileio
, field32(elf
,segment
->p_offset
)+offset
)) != ERROR_OK
)
449 ERROR("cannot find ELF segment content, seek failed");
452 if ((retval
= fileio_read(&elf
->fileio
, read_size
, buffer
, &really_read
)) != ERROR_OK
)
454 ERROR("cannot read ELF segment content, read failed");
460 *size_read
+= read_size
;
461 /* need more data ? */
465 /* if there is remaining zeroed area in current segment */
466 if (offset
<field32(elf
,segment
->p_memsz
))
468 /* fill zeroed part (BSS) of the segment */
469 read_size
= MIN(size
, field32(elf
,segment
->p_memsz
)-offset
);
470 DEBUG("zero fill: size = 0x%x",read_size
);
471 memset(buffer
,0,read_size
);
472 *size_read
+= read_size
;
478 int image_mot_buffer_complete(image_t
*image
)
480 image_mot_t
*mot
= image
->type_private
;
481 fileio_t
*fileio
= &mot
->fileio
;
482 u32 full_address
= 0x0;
487 /* we can't determine the number of sections that we'll have to create ahead of time,
488 * so we locally hold them until parsing is finished */
489 image_section_t section
[IMAGE_MAX_SECTIONS
];
491 mot
->buffer
= malloc(fileio
->size
>> 1);
493 image
->num_sections
= 0;
494 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
495 section
[image
->num_sections
].base_address
= 0x0;
496 section
[image
->num_sections
].size
= 0x0;
497 section
[image
->num_sections
].flags
= 0;
499 while (fileio_fgets(fileio
, 1023, lpszLine
) == ERROR_OK
)
508 /* get record type and record length */
509 if (sscanf(&lpszLine
[bytes_read
], "S%1x%2x", &record_type
, &count
) != 2)
511 return ERROR_IMAGE_FORMAT_ERROR
;
515 cal_checksum
+= (u8
)count
;
517 /* skip checksum byte */
520 if (record_type
== 0)
522 /* S0 - starting record (optional) */
525 while (count
-- > 0) {
526 sscanf(&lpszLine
[bytes_read
], "%2x", &iValue
);
527 cal_checksum
+= (u8
)iValue
;
531 else if (record_type
>= 1 && record_type
<= 3)
533 switch( record_type
)
536 /* S1 - 16 bit address data record */
537 sscanf(&lpszLine
[bytes_read
], "%4x", &address
);
538 cal_checksum
+= (u8
)(address
>> 8);
539 cal_checksum
+= (u8
)address
;
545 /* S2 - 24 bit address data record */
546 sscanf(&lpszLine
[bytes_read
], "%6x", &address
);
547 cal_checksum
+= (u8
)(address
>> 16);
548 cal_checksum
+= (u8
)(address
>> 8);
549 cal_checksum
+= (u8
)address
;
555 /* S3 - 32 bit address data record */
556 sscanf(&lpszLine
[bytes_read
], "%8x", &address
);
557 cal_checksum
+= (u8
)(address
>> 24);
558 cal_checksum
+= (u8
)(address
>> 16);
559 cal_checksum
+= (u8
)(address
>> 8);
560 cal_checksum
+= (u8
)address
;
567 if (full_address
!= address
)
569 /* we encountered a nonconsecutive location, create a new section,
570 * unless the current section has zero size, in which case this specifies
571 * the current section's base address
573 if (section
[image
->num_sections
].size
!= 0)
575 image
->num_sections
++;
576 section
[image
->num_sections
].size
= 0x0;
577 section
[image
->num_sections
].flags
= 0;
578 section
[image
->num_sections
].private = &mot
->buffer
[cooked_bytes
];
580 section
[image
->num_sections
].base_address
= address
;
581 full_address
= address
;
586 sscanf(&lpszLine
[bytes_read
], "%2x", (u32
*)&mot
->buffer
[cooked_bytes
]);
587 cal_checksum
+= (u8
)mot
->buffer
[cooked_bytes
];
590 section
[image
->num_sections
].size
+= 1;
594 else if (record_type
== 5)
596 /* S5 is the data count record, we ignore it */
601 sscanf(&lpszLine
[bytes_read
], "%2x", &dummy
);
602 cal_checksum
+= (u8
)dummy
;
606 else if (record_type
>= 7 && record_type
<= 9)
608 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
609 image
->num_sections
++;
611 /* copy section information */
612 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
613 for (i
= 0; i
< image
->num_sections
; i
++)
615 image
->sections
[i
].private = section
[i
].private;
616 image
->sections
[i
].base_address
= section
[i
].base_address
;
617 image
->sections
[i
].size
= section
[i
].size
;
618 image
->sections
[i
].flags
= section
[i
].flags
;
625 ERROR("unhandled S19 record type: %i", record_type
);
626 return ERROR_IMAGE_FORMAT_ERROR
;
629 /* account for checksum, will always be 0xFF */
630 sscanf(&lpszLine
[bytes_read
], "%2x", &checksum
);
631 cal_checksum
+= (u8
)checksum
;
634 if( cal_checksum
!= 0xFF )
636 /* checksum failed */
637 ERROR("incorrect record checksum found in S19 file");
638 return ERROR_IMAGE_CHECKSUM
;
642 ERROR("premature end of S19 file, no end-of-file record found");
643 return ERROR_IMAGE_FORMAT_ERROR
;
646 int image_open(image_t
*image
, char *url
, char *type_string
)
648 int retval
= ERROR_OK
;
650 if ((retval
= identify_image_type(image
, type_string
, url
)) != ERROR_OK
)
655 if (image
->type
== IMAGE_BINARY
)
657 image_binary_t
*image_binary
;
659 image_binary
= image
->type_private
= malloc(sizeof(image_binary_t
));
661 if ((retval
= fileio_open(&image_binary
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
663 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
664 ERROR(image
->error_str
);
668 image
->num_sections
= 1;
669 image
->sections
= malloc(sizeof(image_section_t
));
670 image
->sections
[0].base_address
= 0x0;
671 image
->sections
[0].size
= image_binary
->fileio
.size
;
672 image
->sections
[0].flags
= 0;
674 else if (image
->type
== IMAGE_IHEX
)
676 image_ihex_t
*image_ihex
;
678 image_ihex
= image
->type_private
= malloc(sizeof(image_ihex_t
));
680 if ((retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
682 strncpy(image
->error_str
, image_ihex
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
683 ERROR(image
->error_str
);
687 if ((retval
= image_ihex_buffer_complete(image
)) != ERROR_OK
)
689 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
690 "failed buffering IHEX image, check daemon output for additional information");
691 ERROR(image
->error_str
);
692 fileio_close(&image_ihex
->fileio
);
696 else if (image
->type
== IMAGE_ELF
)
698 image_elf_t
*image_elf
;
700 image_elf
= image
->type_private
= malloc(sizeof(image_elf_t
));
702 if ((retval
= fileio_open(&image_elf
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
704 strncpy(image
->error_str
, image_elf
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
705 ERROR(image
->error_str
);
709 if ((retval
= image_elf_read_headers(image
)) != ERROR_OK
)
711 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
712 "failed to read ELF headers, check daemon output for additional information");
713 ERROR(image
->error_str
);
714 fileio_close(&image_elf
->fileio
);
718 else if (image
->type
== IMAGE_MEMORY
)
720 image_memory_t
*image_memory
;
722 image
->num_sections
= 1;
723 image
->sections
= malloc(sizeof(image_section_t
));
724 image
->sections
[0].base_address
= 0x0;
725 image
->sections
[0].size
= 0xffffffff;
726 image
->sections
[0].flags
= 0;
728 image_memory
= image
->type_private
= malloc(sizeof(image_memory_t
));
730 image_memory
->target
= get_target_by_num(strtoul(url
, NULL
, 0));;
731 image_memory
->cache
= NULL
;
732 image_memory
->cache_address
= 0x0;
734 else if (image
->type
== IMAGE_SRECORD
)
736 image_mot_t
*image_mot
;
738 image_mot
= image
->type_private
= malloc(sizeof(image_mot_t
));
740 if ((retval
= fileio_open(&image_mot
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
742 strncpy(image
->error_str
, image_mot
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
743 ERROR(image
->error_str
);
747 if ((retval
= image_mot_buffer_complete(image
)) != ERROR_OK
)
749 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
,
750 "failed buffering S19 image, check daemon output for additional information");
751 ERROR(image
->error_str
);
752 fileio_close(&image_mot
->fileio
);
756 else if (image
->type
== IMAGE_BUILDER
)
758 image
->num_sections
= 0;
759 image
->sections
= NULL
;
760 image
->type_private
= NULL
;
763 if (image
->base_address_set
)
767 for (section
=0; section
< image
->num_sections
; section
++)
769 image
->sections
[section
].base_address
+=image
->base_address
;
771 // we're done relocating. The two statements below are mainly
772 // for documenation purposes: stop anyone from empirically
773 // thinking they should use these values henceforth.
774 image
->base_address
=0;
775 image
->base_address_set
=0;
781 int image_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
785 /* don't read past the end of a section */
786 if (offset
+ size
> image
->sections
[section
].size
)
788 DEBUG("read past end of section: 0x%8.8x + 0x%8.8x > 0x%8.8x",
789 offset
, size
, image
->sections
[section
].size
);
790 return ERROR_INVALID_ARGUMENTS
;
793 if (image
->type
== IMAGE_BINARY
)
795 image_binary_t
*image_binary
= image
->type_private
;
797 /* only one section in a plain binary */
799 return ERROR_INVALID_ARGUMENTS
;
802 if ((retval
= fileio_seek(&image_binary
->fileio
, offset
)) != ERROR_OK
)
804 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
808 /* return requested bytes */
809 if ((retval
= fileio_read(&image_binary
->fileio
, size
, buffer
, size_read
)) != ERROR_OK
)
811 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
815 else if (image
->type
== IMAGE_IHEX
)
817 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
819 image
->error_str
[0] = '\0';
823 else if (image
->type
== IMAGE_ELF
)
825 return image_elf_read_section(image
, section
, offset
, size
, buffer
, size_read
);
827 else if (image
->type
== IMAGE_MEMORY
)
829 image_memory_t
*image_memory
= image
->type_private
;
830 u32 address
= image
->sections
[section
].base_address
+ offset
;
834 while ((size
- *size_read
) > 0)
838 if (!image_memory
->cache
839 || (address
< image_memory
->cache_address
)
840 || (address
>= (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
)))
842 if (!image_memory
->cache
)
843 image_memory
->cache
= malloc(IMAGE_MEMORY_CACHE_SIZE
);
845 if (target_read_buffer(image_memory
->target
, address
& ~(IMAGE_MEMORY_CACHE_SIZE
- 1),
846 IMAGE_MEMORY_CACHE_SIZE
, image_memory
->cache
) != ERROR_OK
)
848 free(image_memory
->cache
);
849 image_memory
->cache
= NULL
;
850 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE
;
852 image_memory
->cache_address
= address
& ~(IMAGE_MEMORY_CACHE_SIZE
- 1);
855 size_in_cache
= (image_memory
->cache_address
+ IMAGE_MEMORY_CACHE_SIZE
) - address
;
857 memcpy(buffer
+ *size_read
,
858 image_memory
->cache
+ (address
- image_memory
->cache_address
),
859 (size_in_cache
> size
) ? size
: size_in_cache
862 *size_read
+= (size_in_cache
> size
) ? size
: size_in_cache
;
863 address
+= (size_in_cache
> size
) ? size
: size_in_cache
;
866 else if (image
->type
== IMAGE_SRECORD
)
868 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
870 image
->error_str
[0] = '\0';
874 else if (image
->type
== IMAGE_BUILDER
)
876 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
878 image
->error_str
[0] = '\0';
886 int image_add_section(image_t
*image
, u32 base
, u32 size
, int flags
, u8
*data
)
888 image_section_t
*section
;
890 /* only image builder supports adding sections */
891 if (image
->type
!= IMAGE_BUILDER
)
892 return ERROR_INVALID_ARGUMENTS
;
894 /* see if there's a previous section */
895 if (image
->num_sections
)
897 section
= &image
->sections
[image
->num_sections
- 1];
899 /* see if it's enough to extend the last section,
900 * adding data to previous sections or merging is not supported */
901 if (((section
->base_address
+ section
->size
) == base
) && (section
->flags
== flags
))
903 section
->private = realloc(section
->private, section
->size
+ size
);
904 memcpy((u8
*)section
->private + section
->size
, data
, size
);
905 section
->size
+= size
;
910 /* allocate new section */
911 image
->num_sections
++;
912 image
->sections
= realloc(image
->sections
, sizeof(image_section_t
) * image
->num_sections
);
913 section
= &image
->sections
[image
->num_sections
- 1];
914 section
->base_address
= base
;
915 section
->size
= size
;
916 section
->flags
= flags
;
917 section
->private = malloc(sizeof(u8
) * size
);
918 memcpy((u8
*)section
->private, data
, size
);
923 int image_close(image_t
*image
)
925 if (image
->type
== IMAGE_BINARY
)
927 image_binary_t
*image_binary
= image
->type_private
;
929 fileio_close(&image_binary
->fileio
);
931 else if (image
->type
== IMAGE_IHEX
)
933 image_ihex_t
*image_ihex
= image
->type_private
;
935 fileio_close(&image_ihex
->fileio
);
937 if (image_ihex
->buffer
)
939 free(image_ihex
->buffer
);
940 image_ihex
->buffer
= NULL
;
943 else if (image
->type
== IMAGE_ELF
)
945 image_elf_t
*image_elf
= image
->type_private
;
947 fileio_close(&image_elf
->fileio
);
949 if (image_elf
->header
)
951 free(image_elf
->header
);
952 image_elf
->header
= NULL
;
955 if (image_elf
->segments
)
957 free(image_elf
->segments
);
958 image_elf
->segments
= NULL
;
961 else if (image
->type
== IMAGE_MEMORY
)
963 image_memory_t
*image_memory
= image
->type_private
;
965 if (image_memory
->cache
)
967 free(image_memory
->cache
);
968 image_memory
->cache
= NULL
;
971 else if (image
->type
== IMAGE_SRECORD
)
973 image_mot_t
*image_mot
= image
->type_private
;
975 fileio_close(&image_mot
->fileio
);
977 if (image_mot
->buffer
)
979 free(image_mot
->buffer
);
980 image_mot
->buffer
= NULL
;
983 else if (image
->type
== IMAGE_BUILDER
)
987 for (i
= 0; i
< image
->num_sections
; i
++)
989 free(image
->sections
[i
].private);
990 image
->sections
[i
].private = NULL
;
994 if (image
->type_private
)
996 free(image
->type_private
);
997 image
->type_private
= NULL
;
1000 if (image
->sections
)
1002 free(image
->sections
);
1003 image
->sections
= NULL
;
1009 static u32 crc32_table
[256] = {0, 0};
1011 int image_calculate_checksum(u8
* buffer
, u32 nbytes
, u32
* checksum
)
1013 u32 crc
= 0xffffffff;
1015 if (!crc32_table
[1])
1017 /* Initialize the CRC table and the decoding table. */
1020 for (i
= 0; i
< 256; i
++)
1023 for (c
= i
<< 24, j
= 8; j
> 0; --j
)
1024 c
= c
& 0x80000000 ? (c
<< 1) ^ 0x04c11db7 : (c
<< 1);
1032 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)