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

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)