- flash autoerase <on|off> cmd added, default is off - flash banks are calculated...
[openocd.git] / src / target / image.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26 #ifdef HAVE_ELF_H
27 #include <elf.h>
28 #endif
29
30 #include "image.h"
31
32 #include "types.h"
33 #include "replacements.h"
34 #include "log.h"
35
36 #include "fileio.h"
37 #include "target.h"
38
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))
43
44 #define field32(elf,field)\
45 ((elf->endianness==ELFDATA2LSB)? \
46 le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
47
48 static int autodetect_image_type(image_t *image, char *url)
49 {
50 int retval;
51 fileio_t fileio;
52 u32 read_bytes;
53 u8 buffer[9];
54
55 /* read the first 4 bytes of image */
56 if ((retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
57 {
58 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING, "cannot open image: %s", fileio.error_str);
59 ERROR(image->error_str);
60 return retval;
61 }
62 if ((retval = fileio_read(&fileio, 9, buffer, &read_bytes)) != ERROR_OK)
63 {
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;
67 }
68 if (read_bytes != 9)
69 {
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;
73 }
74 fileio_close(&fileio);
75
76 /* check header against known signatures */
77 if (strncmp((char*)buffer,ELFMAG,SELFMAG)==0)
78 {
79 DEBUG("ELF image detected.");
80 image->type = IMAGE_ELF;
81 }
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'))
91 {
92 DEBUG("IHEX image detected.");
93 image->type = IMAGE_IHEX;
94 }
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'))
100 {
101 DEBUG("S19 image detected.");
102 image->type = IMAGE_SRECORD;
103 }
104 else
105 {
106 image->type = IMAGE_BINARY;
107 }
108
109 return ERROR_OK;
110 }
111
112 int identify_image_type(image_t *image, char *type_string, char *url)
113 {
114 if (type_string)
115 {
116 if (!strcmp(type_string, "bin"))
117 {
118 image->type = IMAGE_BINARY;
119 }
120 else if (!strcmp(type_string, "ihex"))
121 {
122 image->type = IMAGE_IHEX;
123 }
124 else if (!strcmp(type_string, "elf"))
125 {
126 image->type = IMAGE_ELF;
127 }
128 else if (!strcmp(type_string, "mem"))
129 {
130 image->type = IMAGE_MEMORY;
131 }
132 else if (!strcmp(type_string, "s19"))
133 {
134 image->type = IMAGE_SRECORD;
135 }
136 else if (!strcmp(type_string, "build"))
137 {
138 image->type = IMAGE_BUILDER;
139 }
140 else
141 {
142 return ERROR_IMAGE_TYPE_UNKNOWN;
143 }
144 }
145 else
146 {
147 return autodetect_image_type(image, url);
148 }
149
150 return ERROR_OK;
151 }
152
153 int image_ihex_buffer_complete(image_t *image)
154 {
155 image_ihex_t *ihex = image->type_private;
156 fileio_t *fileio = &ihex->fileio;
157 u32 full_address = 0x0;
158 u32 cooked_bytes;
159 int i;
160 char lpszLine[1023];
161
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];
165
166 ihex->buffer = malloc(fileio->size >> 1);
167 cooked_bytes = 0x0;
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;
173
174 while (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK)
175 {
176 u32 count;
177 u32 address;
178 u32 record_type;
179 u32 checksum;
180 u8 cal_checksum = 0;
181 u32 bytes_read = 0;
182
183 if (sscanf(&lpszLine[bytes_read], ":%2x%4x%2x", &count, &address, &record_type) != 3)
184 {
185 return ERROR_IMAGE_FORMAT_ERROR;
186 }
187 bytes_read += 9;
188
189 cal_checksum += (u8)count;
190 cal_checksum += (u8)(address >> 8);
191 cal_checksum += (u8)address;
192 cal_checksum += (u8)record_type;
193
194 if (record_type == 0) /* Data Record */
195 {
196 if ((full_address & 0xffff) != address)
197 {
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
201 */
202 if (section[image->num_sections].size != 0)
203 {
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];
208 }
209 section[image->num_sections].base_address =
210 (full_address & 0xffff0000) | address;
211 full_address = (full_address & 0xffff0000) | address;
212 }
213
214 while (count-- > 0)
215 {
216 sscanf(&lpszLine[bytes_read], "%2x", (u32*)&ihex->buffer[cooked_bytes]);
217 cal_checksum += (u8)ihex->buffer[cooked_bytes];
218 bytes_read += 2;
219 cooked_bytes += 1;
220 section[image->num_sections].size += 1;
221 full_address++;
222 }
223 }
224 else if (record_type == 1) /* End of File Record */
225 {
226 /* finish the current section */
227 image->num_sections++;
228
229 /* copy section information */
230 image->sections = malloc(sizeof(image_section_t) * image->num_sections);
231 for (i = 0; i < image->num_sections; i++)
232 {
233 image->sections[i].private = section[i].private;
234 image->sections[i].base_address = section[i].base_address +
235 ((image->base_address_set) ? image->base_address : 0);
236 image->sections[i].size = section[i].size;
237 image->sections[i].flags = section[i].flags;
238 }
239
240 return ERROR_OK;
241 }
242 else if (record_type == 2) /* Linear Address Record */
243 {
244 u16 upper_address;
245
246 sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
247 cal_checksum += (u8)(upper_address >> 8);
248 cal_checksum += (u8)upper_address;
249 bytes_read += 4;
250
251 if ((full_address >> 4) != upper_address)
252 {
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
256 */
257 if (section[image->num_sections].size != 0)
258 {
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];
263 }
264 section[image->num_sections].base_address =
265 (full_address & 0xffff) | (upper_address << 4);
266 full_address = (full_address & 0xffff) | (upper_address << 4);
267 }
268 }
269 else if (record_type == 4) /* Extended Linear Address Record */
270 {
271 u16 upper_address;
272
273 sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
274 cal_checksum += (u8)(upper_address >> 8);
275 cal_checksum += (u8)upper_address;
276 bytes_read += 4;
277
278 if ((full_address >> 16) != upper_address)
279 {
280 /* we encountered a nonconsecutive location, create a new section,
281 * unless the current section has zero size, in which case this specifies
282 * the current section's base address
283 */
284 if (section[image->num_sections].size != 0)
285 {
286 image->num_sections++;
287 section[image->num_sections].size = 0x0;
288 section[image->num_sections].flags = 0;
289 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
290 }
291 section[image->num_sections].base_address =
292 (full_address & 0xffff) | (upper_address << 16);
293 full_address = (full_address & 0xffff) | (upper_address << 16);
294 }
295 }
296 else if (record_type == 5) /* Start Linear Address Record */
297 {
298 u32 start_address;
299
300 sscanf(&lpszLine[bytes_read], "%8x", &start_address);
301 cal_checksum += (u8)(start_address >> 24);
302 cal_checksum += (u8)(start_address >> 16);
303 cal_checksum += (u8)(start_address >> 8);
304 cal_checksum += (u8)start_address;
305 bytes_read += 8;
306
307 image->start_address_set = 1;
308 image->start_address = be_to_h_u32((u8*)&start_address);
309 }
310 else
311 {
312 ERROR("unhandled IHEX record type: %i", record_type);
313 return ERROR_IMAGE_FORMAT_ERROR;
314 }
315
316 sscanf(&lpszLine[bytes_read], "%2x", &checksum);
317 bytes_read += 2;
318
319 if ((u8)checksum != (u8)(~cal_checksum + 1))
320 {
321 /* checksum failed */
322 ERROR("incorrect record checksum found in IHEX file");
323 return ERROR_IMAGE_CHECKSUM;
324 }
325 }
326
327 ERROR("premature end of IHEX file, no end-of-file record found");
328 return ERROR_IMAGE_FORMAT_ERROR;
329 }
330
331 int image_elf_read_headers(image_t *image)
332 {
333 image_elf_t *elf = image->type_private;
334 u32 read_bytes;
335 u32 i,j;
336 int retval;
337
338 elf->header = malloc(sizeof(Elf32_Ehdr));
339
340 if ((retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (u8*)elf->header, &read_bytes)) != ERROR_OK)
341 {
342 ERROR("cannot read ELF file header, read failed");
343 return ERROR_FILEIO_OPERATION_FAILED;
344 }
345 if (read_bytes != sizeof(Elf32_Ehdr))
346 {
347 ERROR("cannot read ELF file header, only partially read");
348 return ERROR_FILEIO_OPERATION_FAILED;
349 }
350
351 if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG)!=0)
352 {
353 ERROR("invalid ELF file, bad magic number");
354 return ERROR_IMAGE_FORMAT_ERROR;
355 }
356 if (elf->header->e_ident[EI_CLASS]!=ELFCLASS32)
357 {
358 ERROR("invalid ELF file, only 32bits files are supported");
359 return ERROR_IMAGE_FORMAT_ERROR;
360 }
361
362
363 elf->endianness = elf->header->e_ident[EI_DATA];
364 if ((elf->endianness!=ELFDATA2LSB)
365 &&(elf->endianness!=ELFDATA2MSB))
366 {
367 ERROR("invalid ELF file, unknown endianess setting");
368 return ERROR_IMAGE_FORMAT_ERROR;
369 }
370
371 elf->segment_count = field16(elf,elf->header->e_phnum);
372 if (elf->segment_count==0)
373 {
374 ERROR("invalid ELF file, no program headers");
375 return ERROR_IMAGE_FORMAT_ERROR;
376 }
377
378 elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
379
380 if ((retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), (u8*)elf->segments, &read_bytes)) != ERROR_OK)
381 {
382 ERROR("cannot read ELF segment headers, read failed");
383 return retval;
384 }
385 if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr))
386 {
387 ERROR("cannot read ELF segment headers, only partially read");
388 return ERROR_FILEIO_OPERATION_FAILED;
389 }
390
391 /* count useful segments (loadable), ignore BSS section */
392 image->num_sections = 0;
393 for (i=0;i<elf->segment_count;i++)
394 if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
395 image->num_sections++;
396 /* alloc and fill sections array with loadable segments */
397 image->sections = malloc(image->num_sections * sizeof(image_section_t));
398 for (i=0,j=0;i<elf->segment_count;i++)
399 {
400 if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
401 {
402 image->sections[j].size = field32(elf,elf->segments[i].p_memsz);
403 image->sections[j].base_address = field32(elf,elf->segments[i].p_paddr);
404 image->sections[j].private = &elf->segments[i];
405 image->sections[j].flags = field32(elf,elf->segments[i].p_flags);
406 j++;
407 }
408 }
409
410 image->start_address_set = 1;
411 image->start_address = field32(elf,elf->header->e_entry);
412
413 return ERROR_OK;
414 }
415
416 int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
417 {
418 image_elf_t *elf = image->type_private;
419 Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
420 u32 read_size,really_read;
421 int retval;
422
423 *size_read = 0;
424
425 DEBUG("load segment %d at 0x%x (sz=0x%x)",section,offset,size);
426
427 /* read initialized data in current segment if any */
428 if (offset<field32(elf,segment->p_filesz))
429 {
430 /* maximal size present in file for the current segment */
431 read_size = MIN(size, field32(elf,segment->p_filesz)-offset);
432 DEBUG("read elf: size = 0x%x at 0x%x",read_size,
433 field32(elf,segment->p_offset)+offset);
434 /* read initialized area of the segment */
435 if ((retval = fileio_seek(&elf->fileio, field32(elf,segment->p_offset)+offset)) != ERROR_OK)
436 {
437 ERROR("cannot find ELF segment content, seek failed");
438 return retval;
439 }
440 if ((retval = fileio_read(&elf->fileio, read_size, buffer, &really_read)) != ERROR_OK)
441 {
442 ERROR("cannot read ELF segment content, read failed");
443 return retval;
444 }
445 buffer += read_size;
446 size -= read_size;
447 offset += read_size;
448 *size_read += read_size;
449 /* need more data ? */
450 if (!size)
451 return ERROR_OK;
452 }
453 /* if there is remaining zeroed area in current segment */
454 if (offset<field32(elf,segment->p_memsz))
455 {
456 /* fill zeroed part (BSS) of the segment */
457 read_size = MIN(size, field32(elf,segment->p_memsz)-offset);
458 DEBUG("zero fill: size = 0x%x",read_size);
459 memset(buffer,0,read_size);
460 *size_read += read_size;
461 }
462
463 return ERROR_OK;
464 }
465
466 int image_mot_buffer_complete(image_t *image)
467 {
468 image_mot_t *mot = image->type_private;
469 fileio_t *fileio = &mot->fileio;
470 u32 full_address = 0x0;
471 u32 cooked_bytes;
472 int i;
473 char lpszLine[1023];
474
475 /* we can't determine the number of sections that we'll have to create ahead of time,
476 * so we locally hold them until parsing is finished */
477 image_section_t section[IMAGE_MAX_SECTIONS];
478
479 mot->buffer = malloc(fileio->size >> 1);
480 cooked_bytes = 0x0;
481 image->num_sections = 0;
482 section[image->num_sections].private = &mot->buffer[cooked_bytes];
483 section[image->num_sections].base_address = 0x0;
484 section[image->num_sections].size = 0x0;
485 section[image->num_sections].flags = 0;
486
487 while (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK)
488 {
489 u32 count;
490 u32 address;
491 u32 record_type;
492 u32 checksum;
493 u8 cal_checksum = 0;
494 u32 bytes_read = 0;
495
496 /* get record type and record length */
497 if (sscanf(&lpszLine[bytes_read], "S%1x%2x", &record_type, &count) != 2)
498 {
499 return ERROR_IMAGE_FORMAT_ERROR;
500 }
501
502 bytes_read += 4;
503 cal_checksum += (u8)count;
504
505 /* skip checksum byte */
506 count -=1;
507
508 if (record_type == 0)
509 {
510 /* S0 - starting record (optional) */
511 int iValue;
512
513 while (count-- > 0) {
514 sscanf(&lpszLine[bytes_read], "%2x", &iValue);
515 cal_checksum += (u8)iValue;
516 bytes_read += 2;
517 }
518 }
519 else if (record_type >= 1 && record_type <= 3)
520 {
521 switch( record_type )
522 {
523 case 1:
524 /* S1 - 16 bit address data record */
525 sscanf(&lpszLine[bytes_read], "%4x", &address);
526 cal_checksum += (u8)(address >> 8);
527 cal_checksum += (u8)address;
528 bytes_read += 4;
529 count -=2;
530 break;
531
532 case 2:
533 /* S2 - 24 bit address data record */
534 sscanf(&lpszLine[bytes_read], "%6x", &address);
535 cal_checksum += (u8)(address >> 16);
536 cal_checksum += (u8)(address >> 8);
537 cal_checksum += (u8)address;
538 bytes_read += 6;
539 count -=3;
540 break;
541
542 case 3:
543 /* S3 - 32 bit address data record */
544 sscanf(&lpszLine[bytes_read], "%8x", &address);
545 cal_checksum += (u8)(address >> 24);
546 cal_checksum += (u8)(address >> 16);
547 cal_checksum += (u8)(address >> 8);
548 cal_checksum += (u8)address;
549 bytes_read += 8;
550 count -=4;
551 break;
552
553 }
554
555 if (full_address != address)
556 {
557 /* we encountered a nonconsecutive location, create a new section,
558 * unless the current section has zero size, in which case this specifies
559 * the current section's base address
560 */
561 if (section[image->num_sections].size != 0)
562 {
563 image->num_sections++;
564 section[image->num_sections].size = 0x0;
565 section[image->num_sections].flags = 0;
566 section[image->num_sections].private = &mot->buffer[cooked_bytes];
567 }
568 section[image->num_sections].base_address = address;
569 full_address = address;
570 }
571
572 while (count-- > 0)
573 {
574 sscanf(&lpszLine[bytes_read], "%2x", (u32*)&mot->buffer[cooked_bytes]);
575 cal_checksum += (u8)mot->buffer[cooked_bytes];
576 bytes_read += 2;
577 cooked_bytes += 1;
578 section[image->num_sections].size += 1;
579 full_address++;
580 }
581 }
582 else if (record_type >= 7 && record_type <= 9)
583 {
584 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
585 image->num_sections++;
586
587 /* copy section information */
588 image->sections = malloc(sizeof(image_section_t) * image->num_sections);
589 for (i = 0; i < image->num_sections; i++)
590 {
591 image->sections[i].private = section[i].private;
592 image->sections[i].base_address = section[i].base_address +
593 ((image->base_address_set) ? image->base_address : 0);
594 image->sections[i].size = section[i].size;
595 image->sections[i].flags = section[i].flags;
596 }
597
598 return ERROR_OK;
599 }
600 else
601 {
602 ERROR("unhandled S19 record type: %i", record_type);
603 return ERROR_IMAGE_FORMAT_ERROR;
604 }
605
606 /* account for checksum, will always be 0xFF */
607 sscanf(&lpszLine[bytes_read], "%2x", &checksum);
608 cal_checksum += (u8)checksum;
609 bytes_read += 2;
610
611 if( cal_checksum != 0xFF )
612 {
613 /* checksum failed */
614 ERROR("incorrect record checksum found in S19 file");
615 return ERROR_IMAGE_CHECKSUM;
616 }
617 }
618
619 ERROR("premature end of S19 file, no end-of-file record found");
620 return ERROR_IMAGE_FORMAT_ERROR;
621 }
622
623 int image_open(image_t *image, char *url, char *type_string)
624 {
625 int retval = ERROR_OK;
626
627 if ((retval = identify_image_type(image, type_string, url)) != ERROR_OK)
628 {
629 return retval;
630 }
631
632 if (image->type == IMAGE_BINARY)
633 {
634 image_binary_t *image_binary;
635
636 image_binary = image->type_private = malloc(sizeof(image_binary_t));
637
638 if ((retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
639 {
640 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
641 ERROR(image->error_str);
642 return retval;
643 }
644
645 image->num_sections = 1;
646 image->sections = malloc(sizeof(image_section_t));
647 image->sections[0].base_address = 0x0;
648 image->sections[0].size = image_binary->fileio.size;
649 image->sections[0].flags = 0;
650
651 if (image->base_address_set == 1)
652 image->sections[0].base_address = image->base_address;
653
654 return ERROR_OK;
655 }
656 else if (image->type == IMAGE_IHEX)
657 {
658 image_ihex_t *image_ihex;
659
660 image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
661
662 if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
663 {
664 strncpy(image->error_str, image_ihex->fileio.error_str, IMAGE_MAX_ERROR_STRING);
665 ERROR(image->error_str);
666 return retval;
667 }
668
669 if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
670 {
671 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
672 "failed buffering IHEX image, check daemon output for additional information");
673 ERROR(image->error_str);
674 fileio_close(&image_ihex->fileio);
675 return retval;
676 }
677 }
678 else if (image->type == IMAGE_ELF)
679 {
680 image_elf_t *image_elf;
681
682 image_elf = image->type_private = malloc(sizeof(image_elf_t));
683
684 if ((retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
685 {
686 strncpy(image->error_str, image_elf->fileio.error_str, IMAGE_MAX_ERROR_STRING);
687 ERROR(image->error_str);
688 return retval;
689 }
690
691 if ((retval = image_elf_read_headers(image)) != ERROR_OK)
692 {
693 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
694 "failed to read ELF headers, check daemon output for additional information");
695 ERROR(image->error_str);
696 fileio_close(&image_elf->fileio);
697 return retval;
698 }
699 }
700 else if (image->type == IMAGE_MEMORY)
701 {
702 image_memory_t *image_memory;
703
704 image->num_sections = 1;
705 image->sections = malloc(sizeof(image_section_t));
706 image->sections[0].base_address = 0x0;
707 image->sections[0].size = 0xffffffff;
708 image->sections[0].flags = 0;
709
710 image_memory = image->type_private = malloc(sizeof(image_memory_t));
711
712 image_memory->target = get_target_by_num(strtoul(url, NULL, 0));;
713 image_memory->cache = NULL;
714 image_memory->cache_address = 0x0;
715 }
716 else if (image->type == IMAGE_SRECORD)
717 {
718 image_mot_t *image_mot;
719
720 image_mot = image->type_private = malloc(sizeof(image_mot_t));
721
722 if ((retval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
723 {
724 strncpy(image->error_str, image_mot->fileio.error_str, IMAGE_MAX_ERROR_STRING);
725 ERROR(image->error_str);
726 return retval;
727 }
728
729 if ((retval = image_mot_buffer_complete(image)) != ERROR_OK)
730 {
731 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
732 "failed buffering S19 image, check daemon output for additional information");
733 ERROR(image->error_str);
734 fileio_close(&image_mot->fileio);
735 return retval;
736 }
737 }
738 else if (image->type == IMAGE_BUILDER)
739 {
740 image->num_sections = 0;
741 image->sections = NULL;
742 image->type_private = NULL;
743 }
744
745 return retval;
746 };
747
748 int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
749 {
750 int retval;
751
752 /* don't read past the end of a section */
753 if (offset + size > image->sections[section].size)
754 {
755 DEBUG("read past end of section: 0x%8.8x + 0x%8.8x > 0x%8.8x",
756 offset, size, image->sections[section].size);
757 return ERROR_INVALID_ARGUMENTS;
758 }
759
760 if (image->type == IMAGE_BINARY)
761 {
762 image_binary_t *image_binary = image->type_private;
763
764 /* only one section in a plain binary */
765 if (section != 0)
766 return ERROR_INVALID_ARGUMENTS;
767
768 /* seek to offset */
769 if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
770 {
771 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
772 return retval;
773 }
774
775 /* return requested bytes */
776 if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
777 {
778 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
779 return retval;
780 }
781 }
782 else if (image->type == IMAGE_IHEX)
783 {
784 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
785 *size_read = size;
786 image->error_str[0] = '\0';
787
788 return ERROR_OK;
789 }
790 else if (image->type == IMAGE_ELF)
791 {
792 return image_elf_read_section(image, section, offset, size, buffer, size_read);
793 }
794 else if (image->type == IMAGE_MEMORY)
795 {
796 image_memory_t *image_memory = image->type_private;
797 u32 address = image->sections[section].base_address + offset;
798
799 *size_read = 0;
800
801 while ((size - *size_read) > 0)
802 {
803 u32 size_in_cache;
804
805 if (!image_memory->cache
806 || (address < image_memory->cache_address)
807 || (address >= (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE)))
808 {
809 if (!image_memory->cache)
810 image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);
811
812 if (target_read_buffer(image_memory->target, address & ~(IMAGE_MEMORY_CACHE_SIZE - 1),
813 IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK)
814 {
815 free(image_memory->cache);
816 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
817 }
818 image_memory->cache_address = address & ~(IMAGE_MEMORY_CACHE_SIZE - 1);
819 }
820
821 size_in_cache = (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;
822
823 memcpy(buffer + *size_read,
824 image_memory->cache + (address - image_memory->cache_address),
825 (size_in_cache > size) ? size : size_in_cache
826 );
827
828 *size_read += (size_in_cache > size) ? size : size_in_cache;
829 address += (size_in_cache > size) ? size : size_in_cache;
830 }
831 }
832 else if (image->type == IMAGE_SRECORD)
833 {
834 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
835 *size_read = size;
836 image->error_str[0] = '\0';
837
838 return ERROR_OK;
839 }
840 else if (image->type == IMAGE_BUILDER)
841 {
842 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
843 *size_read = size;
844 image->error_str[0] = '\0';
845
846 return ERROR_OK;
847 }
848
849 return ERROR_OK;
850 }
851
852 int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data)
853 {
854 image_section_t *section;
855
856 /* only image builder supports adding sections */
857 if (image->type != IMAGE_BUILDER)
858 return ERROR_INVALID_ARGUMENTS;
859
860 /* see if there's a previous section */
861 if (image->num_sections)
862 {
863 section = &image->sections[image->num_sections - 1];
864
865 /* see if it's enough to extend the last section,
866 * adding data to previous sections or merging is not supported */
867 if (((section->base_address + section->size) == base) && (section->flags == flags))
868 {
869 section->private = realloc(section->private, section->size + size);
870 memcpy((u8*)section->private + section->size, data, size);
871 section->size += size;
872 return ERROR_OK;
873 }
874 }
875
876 /* allocate new section */
877 image->num_sections++;
878 image->sections = realloc(image->sections, sizeof(image_section_t) * image->num_sections);
879 section = &image->sections[image->num_sections - 1];
880 section->base_address = base;
881 section->size = size;
882 section->flags = flags;
883 section->private = malloc(sizeof(u8) * size);
884 memcpy((u8*)section->private, data, size);
885
886 return ERROR_OK;
887 }
888
889 int image_close(image_t *image)
890 {
891 if (image->type == IMAGE_BINARY)
892 {
893 image_binary_t *image_binary = image->type_private;
894
895 fileio_close(&image_binary->fileio);
896 }
897 else if (image->type == IMAGE_IHEX)
898 {
899 image_ihex_t *image_ihex = image->type_private;
900
901 fileio_close(&image_ihex->fileio);
902
903 if (image_ihex->buffer)
904 free(image_ihex->buffer);
905 }
906 else if (image->type == IMAGE_ELF)
907 {
908 image_elf_t *image_elf = image->type_private;
909
910 fileio_close(&image_elf->fileio);
911
912 if (image_elf->header)
913 free(image_elf->header);
914
915 if (image_elf->segments)
916 free(image_elf->segments);
917 }
918 else if (image->type == IMAGE_MEMORY)
919 {
920 image_memory_t *image_memory = image->type_private;
921
922 if (image_memory->cache)
923 free(image_memory->cache);
924 }
925 else if (image->type == IMAGE_SRECORD)
926 {
927 image_mot_t *image_mot = image->type_private;
928
929 fileio_close(&image_mot->fileio);
930
931 if (image_mot->buffer)
932 free(image_mot->buffer);
933 }
934 else if (image->type == IMAGE_BUILDER)
935 {
936 int i;
937
938 for (i = 0; i < image->num_sections; i++)
939 {
940 free(image->sections[i].private);
941 }
942 }
943
944 if (image->type_private)
945 free(image->type_private);
946
947 if (image->sections)
948 free(image->sections);
949
950 return ERROR_OK;
951 }

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)