bdd89b1c9e508fa9ff6a96380a1d4c0845fb28f9
[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->sections[i].size = section[i].size;
236 image->sections[i].flags = section[i].flags;
237 }
238
239 return ERROR_OK;
240 }
241 else if (record_type == 2) /* Linear Address Record */
242 {
243 u16 upper_address;
244
245 sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
246 cal_checksum += (u8)(upper_address >> 8);
247 cal_checksum += (u8)upper_address;
248 bytes_read += 4;
249
250 if ((full_address >> 4) != upper_address)
251 {
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
255 */
256 if (section[image->num_sections].size != 0)
257 {
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];
262 }
263 section[image->num_sections].base_address =
264 (full_address & 0xffff) | (upper_address << 4);
265 full_address = (full_address & 0xffff) | (upper_address << 4);
266 }
267 }
268 else if (record_type == 3) /* Start Segment Address Record */
269 {
270 u32 dummy;
271
272 /* "Start Segment Address Record" will not be supported */
273 /* but we must consume it, and do not create an error. */
274 while (count-- > 0)
275 {
276 sscanf(&lpszLine[bytes_read], "%2x", &dummy);
277 cal_checksum += (u8)dummy;
278 bytes_read += 2;
279 }
280 }
281 else if (record_type == 4) /* Extended Linear Address Record */
282 {
283 u16 upper_address;
284
285 sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
286 cal_checksum += (u8)(upper_address >> 8);
287 cal_checksum += (u8)upper_address;
288 bytes_read += 4;
289
290 if ((full_address >> 16) != upper_address)
291 {
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
295 */
296 if (section[image->num_sections].size != 0)
297 {
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];
302 }
303 section[image->num_sections].base_address =
304 (full_address & 0xffff) | (upper_address << 16);
305 full_address = (full_address & 0xffff) | (upper_address << 16);
306 }
307 }
308 else if (record_type == 5) /* Start Linear Address Record */
309 {
310 u32 start_address;
311
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;
317 bytes_read += 8;
318
319 image->start_address_set = 1;
320 image->start_address = be_to_h_u32((u8*)&start_address);
321 }
322 else
323 {
324 ERROR("unhandled IHEX record type: %i", record_type);
325 return ERROR_IMAGE_FORMAT_ERROR;
326 }
327
328 sscanf(&lpszLine[bytes_read], "%2x", &checksum);
329 bytes_read += 2;
330
331 if ((u8)checksum != (u8)(~cal_checksum + 1))
332 {
333 /* checksum failed */
334 ERROR("incorrect record checksum found in IHEX file");
335 return ERROR_IMAGE_CHECKSUM;
336 }
337 }
338
339 ERROR("premature end of IHEX file, no end-of-file record found");
340 return ERROR_IMAGE_FORMAT_ERROR;
341 }
342
343 int image_elf_read_headers(image_t *image)
344 {
345 image_elf_t *elf = image->type_private;
346 u32 read_bytes;
347 u32 i,j;
348 int retval;
349
350 elf->header = malloc(sizeof(Elf32_Ehdr));
351
352 if ((retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (u8*)elf->header, &read_bytes)) != ERROR_OK)
353 {
354 ERROR("cannot read ELF file header, read failed");
355 return ERROR_FILEIO_OPERATION_FAILED;
356 }
357 if (read_bytes != sizeof(Elf32_Ehdr))
358 {
359 ERROR("cannot read ELF file header, only partially read");
360 return ERROR_FILEIO_OPERATION_FAILED;
361 }
362
363 if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG)!=0)
364 {
365 ERROR("invalid ELF file, bad magic number");
366 return ERROR_IMAGE_FORMAT_ERROR;
367 }
368 if (elf->header->e_ident[EI_CLASS]!=ELFCLASS32)
369 {
370 ERROR("invalid ELF file, only 32bits files are supported");
371 return ERROR_IMAGE_FORMAT_ERROR;
372 }
373
374
375 elf->endianness = elf->header->e_ident[EI_DATA];
376 if ((elf->endianness!=ELFDATA2LSB)
377 &&(elf->endianness!=ELFDATA2MSB))
378 {
379 ERROR("invalid ELF file, unknown endianess setting");
380 return ERROR_IMAGE_FORMAT_ERROR;
381 }
382
383 elf->segment_count = field16(elf,elf->header->e_phnum);
384 if (elf->segment_count==0)
385 {
386 ERROR("invalid ELF file, no program headers");
387 return ERROR_IMAGE_FORMAT_ERROR;
388 }
389
390 elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
391
392 if ((retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), (u8*)elf->segments, &read_bytes)) != ERROR_OK)
393 {
394 ERROR("cannot read ELF segment headers, read failed");
395 return retval;
396 }
397 if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr))
398 {
399 ERROR("cannot read ELF segment headers, only partially read");
400 return ERROR_FILEIO_OPERATION_FAILED;
401 }
402
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++)
411 {
412 if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
413 {
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);
418 j++;
419 }
420 }
421
422 image->start_address_set = 1;
423 image->start_address = field32(elf,elf->header->e_entry);
424
425 return ERROR_OK;
426 }
427
428 int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
429 {
430 image_elf_t *elf = image->type_private;
431 Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
432 u32 read_size, really_read;
433 int retval;
434
435 *size_read = 0;
436
437 DEBUG("load segment %d at 0x%x (sz = 0x%x)", section, offset, size);
438
439 /* read initialized data in current segment if any */
440 if (offset < field32(elf, segment->p_filesz))
441 {
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)
448 {
449 ERROR("cannot find ELF segment content, seek failed");
450 return retval;
451 }
452 if ((retval = fileio_read(&elf->fileio, read_size, buffer, &really_read)) != ERROR_OK)
453 {
454 ERROR("cannot read ELF segment content, read failed");
455 return retval;
456 }
457 buffer += read_size;
458 size -= read_size;
459 offset += read_size;
460 *size_read += read_size;
461 /* need more data ? */
462 if (!size)
463 return ERROR_OK;
464 }
465 /* if there is remaining zeroed area in current segment */
466 if (offset < field32(elf, segment->p_memsz))
467 {
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;
473 }
474
475 return ERROR_OK;
476 }
477
478 int image_mot_buffer_complete(image_t *image)
479 {
480 image_mot_t *mot = image->type_private;
481 fileio_t *fileio = &mot->fileio;
482 u32 full_address = 0x0;
483 u32 cooked_bytes;
484 int i;
485 char lpszLine[1023];
486
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];
490
491 mot->buffer = malloc(fileio->size >> 1);
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 (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK)
500 {
501 u32 count;
502 u32 address;
503 u32 record_type;
504 u32 checksum;
505 u8 cal_checksum = 0;
506 u32 bytes_read = 0;
507
508 /* get record type and record length */
509 if (sscanf(&lpszLine[bytes_read], "S%1x%2x", &record_type, &count) != 2)
510 {
511 return ERROR_IMAGE_FORMAT_ERROR;
512 }
513
514 bytes_read += 4;
515 cal_checksum += (u8)count;
516
517 /* skip checksum byte */
518 count -=1;
519
520 if (record_type == 0)
521 {
522 /* S0 - starting record (optional) */
523 int iValue;
524
525 while (count-- > 0) {
526 sscanf(&lpszLine[bytes_read], "%2x", &iValue);
527 cal_checksum += (u8)iValue;
528 bytes_read += 2;
529 }
530 }
531 else if (record_type >= 1 && record_type <= 3)
532 {
533 switch( record_type )
534 {
535 case 1:
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;
540 bytes_read += 4;
541 count -=2;
542 break;
543
544 case 2:
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;
550 bytes_read += 6;
551 count -=3;
552 break;
553
554 case 3:
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;
561 bytes_read += 8;
562 count -=4;
563 break;
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 = address;
580 full_address = address;
581 }
582
583 while (count-- > 0)
584 {
585 sscanf(&lpszLine[bytes_read], "%2x", (u32*)&mot->buffer[cooked_bytes]);
586 cal_checksum += (u8)mot->buffer[cooked_bytes];
587 bytes_read += 2;
588 cooked_bytes += 1;
589 section[image->num_sections].size += 1;
590 full_address++;
591 }
592 }
593 else if (record_type == 5)
594 {
595 /* S5 is the data count record, we ignore it */
596 u32 dummy;
597
598 while (count-- > 0)
599 {
600 sscanf(&lpszLine[bytes_read], "%2x", &dummy);
601 cal_checksum += (u8)dummy;
602 bytes_read += 2;
603 }
604 }
605 else if (record_type >= 7 && record_type <= 9)
606 {
607 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
608 image->num_sections++;
609
610 /* copy section information */
611 image->sections = malloc(sizeof(image_section_t) * image->num_sections);
612 for (i = 0; i < image->num_sections; i++)
613 {
614 image->sections[i].private = section[i].private;
615 image->sections[i].base_address = section[i].base_address;
616 image->sections[i].size = section[i].size;
617 image->sections[i].flags = section[i].flags;
618 }
619
620 return ERROR_OK;
621 }
622 else
623 {
624 ERROR("unhandled S19 record type: %i", record_type);
625 return ERROR_IMAGE_FORMAT_ERROR;
626 }
627
628 /* account for checksum, will always be 0xFF */
629 sscanf(&lpszLine[bytes_read], "%2x", &checksum);
630 cal_checksum += (u8)checksum;
631 bytes_read += 2;
632
633 if( cal_checksum != 0xFF )
634 {
635 /* checksum failed */
636 ERROR("incorrect record checksum found in S19 file");
637 return ERROR_IMAGE_CHECKSUM;
638 }
639 }
640
641 ERROR("premature end of S19 file, no end-of-file record found");
642 return ERROR_IMAGE_FORMAT_ERROR;
643 }
644
645 int image_open(image_t *image, char *url, char *type_string)
646 {
647 int retval = ERROR_OK;
648
649 if ((retval = identify_image_type(image, type_string, url)) != ERROR_OK)
650 {
651 return retval;
652 }
653
654 if (image->type == IMAGE_BINARY)
655 {
656 image_binary_t *image_binary;
657
658 image_binary = image->type_private = malloc(sizeof(image_binary_t));
659
660 if ((retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
661 {
662 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
663 ERROR(image->error_str);
664 return retval;
665 }
666
667 image->num_sections = 1;
668 image->sections = malloc(sizeof(image_section_t));
669 image->sections[0].base_address = 0x0;
670 image->sections[0].size = image_binary->fileio.size;
671 image->sections[0].flags = 0;
672 }
673 else if (image->type == IMAGE_IHEX)
674 {
675 image_ihex_t *image_ihex;
676
677 image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
678
679 if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
680 {
681 strncpy(image->error_str, image_ihex->fileio.error_str, IMAGE_MAX_ERROR_STRING);
682 ERROR(image->error_str);
683 return retval;
684 }
685
686 if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
687 {
688 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
689 "failed buffering IHEX image, check daemon output for additional information");
690 ERROR(image->error_str);
691 fileio_close(&image_ihex->fileio);
692 return retval;
693 }
694 }
695 else if (image->type == IMAGE_ELF)
696 {
697 image_elf_t *image_elf;
698
699 image_elf = image->type_private = malloc(sizeof(image_elf_t));
700
701 if ((retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
702 {
703 strncpy(image->error_str, image_elf->fileio.error_str, IMAGE_MAX_ERROR_STRING);
704 ERROR(image->error_str);
705 return retval;
706 }
707
708 if ((retval = image_elf_read_headers(image)) != ERROR_OK)
709 {
710 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
711 "failed to read ELF headers, check daemon output for additional information");
712 ERROR(image->error_str);
713 fileio_close(&image_elf->fileio);
714 return retval;
715 }
716 }
717 else if (image->type == IMAGE_MEMORY)
718 {
719 image_memory_t *image_memory;
720
721 image->num_sections = 1;
722 image->sections = malloc(sizeof(image_section_t));
723 image->sections[0].base_address = 0x0;
724 image->sections[0].size = 0xffffffff;
725 image->sections[0].flags = 0;
726
727 image_memory = image->type_private = malloc(sizeof(image_memory_t));
728
729 image_memory->target = get_target_by_num(strtoul(url, NULL, 0));;
730 image_memory->cache = NULL;
731 image_memory->cache_address = 0x0;
732 }
733 else if (image->type == IMAGE_SRECORD)
734 {
735 image_mot_t *image_mot;
736
737 image_mot = image->type_private = malloc(sizeof(image_mot_t));
738
739 if ((retval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
740 {
741 strncpy(image->error_str, image_mot->fileio.error_str, IMAGE_MAX_ERROR_STRING);
742 ERROR(image->error_str);
743 return retval;
744 }
745
746 if ((retval = image_mot_buffer_complete(image)) != ERROR_OK)
747 {
748 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
749 "failed buffering S19 image, check daemon output for additional information");
750 ERROR(image->error_str);
751 fileio_close(&image_mot->fileio);
752 return retval;
753 }
754 }
755 else if (image->type == IMAGE_BUILDER)
756 {
757 image->num_sections = 0;
758 image->sections = NULL;
759 image->type_private = NULL;
760 }
761
762 if (image->base_address_set)
763 {
764 /* relocate */
765 int section;
766 for (section = 0; section < image->num_sections; section++)
767 {
768 image->sections[section].base_address += image->base_address;
769 }
770 /* we're done relocating. The two statements below are mainly
771 * for documenation purposes: stop anyone from empirically
772 * thinking they should use these values henceforth. */
773 image->base_address = 0;
774 image->base_address_set = 0;
775 }
776
777 return retval;
778 };
779
780 int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
781 {
782 int retval;
783
784 /* don't read past the end of a section */
785 if (offset + size > image->sections[section].size)
786 {
787 DEBUG("read past end of section: 0x%8.8x + 0x%8.8x > 0x%8.8x",
788 offset, size, image->sections[section].size);
789 return ERROR_INVALID_ARGUMENTS;
790 }
791
792 if (image->type == IMAGE_BINARY)
793 {
794 image_binary_t *image_binary = image->type_private;
795
796 /* only one section in a plain binary */
797 if (section != 0)
798 return ERROR_INVALID_ARGUMENTS;
799
800 /* seek to offset */
801 if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
802 {
803 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
804 return retval;
805 }
806
807 /* return requested bytes */
808 if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
809 {
810 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
811 return retval;
812 }
813 }
814 else if (image->type == IMAGE_IHEX)
815 {
816 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
817 *size_read = size;
818 image->error_str[0] = '\0';
819
820 return ERROR_OK;
821 }
822 else if (image->type == IMAGE_ELF)
823 {
824 return image_elf_read_section(image, section, offset, size, buffer, size_read);
825 }
826 else if (image->type == IMAGE_MEMORY)
827 {
828 image_memory_t *image_memory = image->type_private;
829 u32 address = image->sections[section].base_address + offset;
830
831 *size_read = 0;
832
833 while ((size - *size_read) > 0)
834 {
835 u32 size_in_cache;
836
837 if (!image_memory->cache
838 || (address < image_memory->cache_address)
839 || (address >= (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE)))
840 {
841 if (!image_memory->cache)
842 image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);
843
844 if (target_read_buffer(image_memory->target, address & ~(IMAGE_MEMORY_CACHE_SIZE - 1),
845 IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK)
846 {
847 free(image_memory->cache);
848 image_memory->cache = NULL;
849 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
850 }
851 image_memory->cache_address = address & ~(IMAGE_MEMORY_CACHE_SIZE - 1);
852 }
853
854 size_in_cache = (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;
855
856 memcpy(buffer + *size_read,
857 image_memory->cache + (address - image_memory->cache_address),
858 (size_in_cache > size) ? size : size_in_cache
859 );
860
861 *size_read += (size_in_cache > size) ? size : size_in_cache;
862 address += (size_in_cache > size) ? size : size_in_cache;
863 }
864 }
865 else if (image->type == IMAGE_SRECORD)
866 {
867 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
868 *size_read = size;
869 image->error_str[0] = '\0';
870
871 return ERROR_OK;
872 }
873 else if (image->type == IMAGE_BUILDER)
874 {
875 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
876 *size_read = size;
877 image->error_str[0] = '\0';
878
879 return ERROR_OK;
880 }
881
882 return ERROR_OK;
883 }
884
885 int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data)
886 {
887 image_section_t *section;
888
889 /* only image builder supports adding sections */
890 if (image->type != IMAGE_BUILDER)
891 return ERROR_INVALID_ARGUMENTS;
892
893 /* see if there's a previous section */
894 if (image->num_sections)
895 {
896 section = &image->sections[image->num_sections - 1];
897
898 /* see if it's enough to extend the last section,
899 * adding data to previous sections or merging is not supported */
900 if (((section->base_address + section->size) == base) && (section->flags == flags))
901 {
902 section->private = realloc(section->private, section->size + size);
903 memcpy((u8*)section->private + section->size, data, size);
904 section->size += size;
905 return ERROR_OK;
906 }
907 }
908
909 /* allocate new section */
910 image->num_sections++;
911 image->sections = realloc(image->sections, sizeof(image_section_t) * image->num_sections);
912 section = &image->sections[image->num_sections - 1];
913 section->base_address = base;
914 section->size = size;
915 section->flags = flags;
916 section->private = malloc(sizeof(u8) * size);
917 memcpy((u8*)section->private, data, size);
918
919 return ERROR_OK;
920 }
921
922 int image_close(image_t *image)
923 {
924 if (image->type == IMAGE_BINARY)
925 {
926 image_binary_t *image_binary = image->type_private;
927
928 fileio_close(&image_binary->fileio);
929 }
930 else if (image->type == IMAGE_IHEX)
931 {
932 image_ihex_t *image_ihex = image->type_private;
933
934 fileio_close(&image_ihex->fileio);
935
936 if (image_ihex->buffer)
937 {
938 free(image_ihex->buffer);
939 image_ihex->buffer = NULL;
940 }
941 }
942 else if (image->type == IMAGE_ELF)
943 {
944 image_elf_t *image_elf = image->type_private;
945
946 fileio_close(&image_elf->fileio);
947
948 if (image_elf->header)
949 {
950 free(image_elf->header);
951 image_elf->header = NULL;
952 }
953
954 if (image_elf->segments)
955 {
956 free(image_elf->segments);
957 image_elf->segments = NULL;
958 }
959 }
960 else if (image->type == IMAGE_MEMORY)
961 {
962 image_memory_t *image_memory = image->type_private;
963
964 if (image_memory->cache)
965 {
966 free(image_memory->cache);
967 image_memory->cache = NULL;
968 }
969 }
970 else if (image->type == IMAGE_SRECORD)
971 {
972 image_mot_t *image_mot = image->type_private;
973
974 fileio_close(&image_mot->fileio);
975
976 if (image_mot->buffer)
977 {
978 free(image_mot->buffer);
979 image_mot->buffer = NULL;
980 }
981 }
982 else if (image->type == IMAGE_BUILDER)
983 {
984 int i;
985
986 for (i = 0; i < image->num_sections; i++)
987 {
988 free(image->sections[i].private);
989 image->sections[i].private = NULL;
990 }
991 }
992
993 if (image->type_private)
994 {
995 free(image->type_private);
996 image->type_private = NULL;
997 }
998
999 if (image->sections)
1000 {
1001 free(image->sections);
1002 image->sections = NULL;
1003 }
1004
1005 return ERROR_OK;
1006 }
1007
1008 static u32 crc32_table[256] = {0, 0};
1009
1010 int image_calculate_checksum(u8* buffer, u32 nbytes, u32* checksum)
1011 {
1012 u32 crc = 0xffffffff;
1013
1014 if (!crc32_table[1])
1015 {
1016 /* Initialize the CRC table and the decoding table. */
1017 int i, j;
1018 unsigned int c;
1019 for (i = 0; i < 256; i++)
1020 {
1021 /* as per gdb */
1022 for (c = i << 24, j = 8; j > 0; --j)
1023 c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
1024 crc32_table[i] = c;
1025 }
1026 }
1027
1028 while (nbytes--)
1029 {
1030 /* as per gdb */
1031 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
1032 }
1033
1034 *checksum = crc;
1035 return ERROR_OK;
1036 }
1037
1038

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)