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

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)