- Fixes '+' whitespace
[openocd.git] / src / target / image.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "image.h"
31 #include "target.h"
32 #include "log.h"
33
34
35 /* convert ELF header field to host endianness */
36 #define field16(elf,field)\
37 ((elf->endianness == ELFDATA2LSB)? \
38 le_to_h_u16((uint8_t*)&field):be_to_h_u16((uint8_t*)&field))
39
40 #define field32(elf,field)\
41 ((elf->endianness == ELFDATA2LSB)? \
42 le_to_h_u32((uint8_t*)&field):be_to_h_u32((uint8_t*)&field))
43
44 static int autodetect_image_type(image_t *image, char *url)
45 {
46 int retval;
47 fileio_t fileio;
48 uint32_t read_bytes;
49 uint8_t buffer[9];
50
51 /* read the first 4 bytes of image */
52 if ((retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
53 {
54 return retval;
55 }
56 retval = fileio_read(&fileio, 9, buffer, &read_bytes);
57
58 if (retval == ERROR_OK)
59 {
60 if (read_bytes != 9)
61 {
62 retval = ERROR_FILEIO_OPERATION_FAILED;
63 }
64 }
65 fileio_close(&fileio);
66
67 if (retval != ERROR_OK)
68 return retval;
69
70 /* check header against known signatures */
71 if (strncmp((char*)buffer,ELFMAG,SELFMAG) == 0)
72 {
73 LOG_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 LOG_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 LOG_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 static 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 static int image_ihex_buffer_complete(image_t *image)
148 {
149 image_ihex_t *ihex = image->type_private;
150 fileio_t *fileio = &ihex->fileio;
151 uint32_t full_address = 0x0;
152 uint32_t 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 uint32_t count;
171 uint32_t address;
172 uint32_t record_type;
173 uint32_t checksum;
174 uint8_t cal_checksum = 0;
175 uint32_t bytes_read = 0;
176
177 if (sscanf(&lpszLine[bytes_read], ":%2" SCNx32 "%4" SCNx32 "%2" SCNx32 , &count, &address, &record_type) != 3)
178 {
179 return ERROR_IMAGE_FORMAT_ERROR;
180 }
181 bytes_read += 9;
182
183 cal_checksum += (uint8_t)count;
184 cal_checksum += (uint8_t)(address >> 8);
185 cal_checksum += (uint8_t)address;
186 cal_checksum += (uint8_t)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 unsigned value;
211 sscanf(&lpszLine[bytes_read], "%2x", &value);
212 ihex->buffer[cooked_bytes] = (uint8_t)value;
213 cal_checksum += (uint8_t)ihex->buffer[cooked_bytes];
214 bytes_read += 2;
215 cooked_bytes += 1;
216 section[image->num_sections].size += 1;
217 full_address++;
218 }
219 }
220 else if (record_type == 1) /* End of File Record */
221 {
222 /* finish the current section */
223 image->num_sections++;
224
225 /* copy section information */
226 image->sections = malloc(sizeof(image_section_t) * image->num_sections);
227 for (i = 0; i < image->num_sections; i++)
228 {
229 image->sections[i].private = section[i].private;
230 image->sections[i].base_address = section[i].base_address;
231 image->sections[i].size = section[i].size;
232 image->sections[i].flags = section[i].flags;
233 }
234
235 return ERROR_OK;
236 }
237 else if (record_type == 2) /* Linear Address Record */
238 {
239 uint16_t upper_address;
240
241 sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
242 cal_checksum += (uint8_t)(upper_address >> 8);
243 cal_checksum += (uint8_t)upper_address;
244 bytes_read += 4;
245
246 if ((full_address >> 4) != upper_address)
247 {
248 /* we encountered a nonconsecutive location, create a new section,
249 * unless the current section has zero size, in which case this specifies
250 * the current section's base address
251 */
252 if (section[image->num_sections].size != 0)
253 {
254 image->num_sections++;
255 section[image->num_sections].size = 0x0;
256 section[image->num_sections].flags = 0;
257 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
258 }
259 section[image->num_sections].base_address =
260 (full_address & 0xffff) | (upper_address << 4);
261 full_address = (full_address & 0xffff) | (upper_address << 4);
262 }
263 }
264 else if (record_type == 3) /* Start Segment Address Record */
265 {
266 uint32_t dummy;
267
268 /* "Start Segment Address Record" will not be supported */
269 /* but we must consume it, and do not create an error. */
270 while (count-- > 0)
271 {
272 sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &dummy);
273 cal_checksum += (uint8_t)dummy;
274 bytes_read += 2;
275 }
276 }
277 else if (record_type == 4) /* Extended Linear Address Record */
278 {
279 uint16_t upper_address;
280
281 sscanf(&lpszLine[bytes_read], "%4hx", &upper_address);
282 cal_checksum += (uint8_t)(upper_address >> 8);
283 cal_checksum += (uint8_t)upper_address;
284 bytes_read += 4;
285
286 if ((full_address >> 16) != upper_address)
287 {
288 /* we encountered a nonconsecutive location, create a new section,
289 * unless the current section has zero size, in which case this specifies
290 * the current section's base address
291 */
292 if (section[image->num_sections].size != 0)
293 {
294 image->num_sections++;
295 section[image->num_sections].size = 0x0;
296 section[image->num_sections].flags = 0;
297 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
298 }
299 section[image->num_sections].base_address =
300 (full_address & 0xffff) | (upper_address << 16);
301 full_address = (full_address & 0xffff) | (upper_address << 16);
302 }
303 }
304 else if (record_type == 5) /* Start Linear Address Record */
305 {
306 uint32_t start_address;
307
308 sscanf(&lpszLine[bytes_read], "%8" SCNx32, &start_address);
309 cal_checksum += (uint8_t)(start_address >> 24);
310 cal_checksum += (uint8_t)(start_address >> 16);
311 cal_checksum += (uint8_t)(start_address >> 8);
312 cal_checksum += (uint8_t)start_address;
313 bytes_read += 8;
314
315 image->start_address_set = 1;
316 image->start_address = be_to_h_u32((uint8_t*)&start_address);
317 }
318 else
319 {
320 LOG_ERROR("unhandled IHEX record type: %i", (int)record_type);
321 return ERROR_IMAGE_FORMAT_ERROR;
322 }
323
324 sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &checksum);
325 bytes_read += 2;
326
327 if ((uint8_t)checksum != (uint8_t)(~cal_checksum + 1))
328 {
329 /* checksum failed */
330 LOG_ERROR("incorrect record checksum found in IHEX file");
331 return ERROR_IMAGE_CHECKSUM;
332 }
333 }
334
335 LOG_ERROR("premature end of IHEX file, no end-of-file record found");
336 return ERROR_IMAGE_FORMAT_ERROR;
337 }
338
339 static int image_elf_read_headers(image_t *image)
340 {
341 image_elf_t *elf = image->type_private;
342 uint32_t read_bytes;
343 uint32_t i,j;
344 int retval;
345
346 elf->header = malloc(sizeof(Elf32_Ehdr));
347
348 if (elf->header == NULL)
349 {
350 LOG_ERROR("insufficient memory to perform operation ");
351 return ERROR_FILEIO_OPERATION_FAILED;
352 }
353
354 if ((retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (uint8_t*)elf->header, &read_bytes)) != ERROR_OK)
355 {
356 LOG_ERROR("cannot read ELF file header, read failed");
357 return ERROR_FILEIO_OPERATION_FAILED;
358 }
359 if (read_bytes != sizeof(Elf32_Ehdr))
360 {
361 LOG_ERROR("cannot read ELF file header, only partially read");
362 return ERROR_FILEIO_OPERATION_FAILED;
363 }
364
365 if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG) != 0)
366 {
367 LOG_ERROR("invalid ELF file, bad magic number");
368 return ERROR_IMAGE_FORMAT_ERROR;
369 }
370 if (elf->header->e_ident[EI_CLASS]!=ELFCLASS32)
371 {
372 LOG_ERROR("invalid ELF file, only 32bits files are supported");
373 return ERROR_IMAGE_FORMAT_ERROR;
374 }
375
376 elf->endianness = elf->header->e_ident[EI_DATA];
377 if ((elf->endianness != ELFDATA2LSB)
378 &&(elf->endianness != ELFDATA2MSB))
379 {
380 LOG_ERROR("invalid ELF file, unknown endianess setting");
381 return ERROR_IMAGE_FORMAT_ERROR;
382 }
383
384 elf->segment_count = field16(elf,elf->header->e_phnum);
385 if (elf->segment_count == 0)
386 {
387 LOG_ERROR("invalid ELF file, no program headers");
388 return ERROR_IMAGE_FORMAT_ERROR;
389 }
390
391 if ((retval = fileio_seek(&elf->fileio, field32(elf,elf->header->e_phoff))) != ERROR_OK)
392 {
393 LOG_ERROR("cannot seek to ELF program header table, read failed");
394 return retval;
395 }
396
397 elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
398 if (elf->segments == NULL)
399 {
400 LOG_ERROR("insufficient memory to perform operation ");
401 return ERROR_FILEIO_OPERATION_FAILED;
402 }
403
404 if ((retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), (uint8_t*)elf->segments, &read_bytes)) != ERROR_OK)
405 {
406 LOG_ERROR("cannot read ELF segment headers, read failed");
407 return retval;
408 }
409 if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr))
410 {
411 LOG_ERROR("cannot read ELF segment headers, only partially read");
412 return ERROR_FILEIO_OPERATION_FAILED;
413 }
414
415 /* count useful segments (loadable), ignore BSS section */
416 image->num_sections = 0;
417 for (i = 0;i<elf->segment_count;i++)
418 if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
419 image->num_sections++;
420 /* alloc and fill sections array with loadable segments */
421 image->sections = malloc(image->num_sections * sizeof(image_section_t));
422 for (i = 0,j = 0;i<elf->segment_count;i++)
423 {
424 if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
425 {
426 image->sections[j].size = field32(elf,elf->segments[i].p_filesz);
427 image->sections[j].base_address = field32(elf,elf->segments[i].p_paddr);
428 image->sections[j].private = &elf->segments[i];
429 image->sections[j].flags = field32(elf,elf->segments[i].p_flags);
430 j++;
431 }
432 }
433
434 image->start_address_set = 1;
435 image->start_address = field32(elf,elf->header->e_entry);
436
437 return ERROR_OK;
438 }
439
440 static int image_elf_read_section(image_t *image, int section, uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *size_read)
441 {
442 image_elf_t *elf = image->type_private;
443 Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
444 uint32_t read_size,really_read;
445 int retval;
446
447 *size_read = 0;
448
449 LOG_DEBUG("load segment %d at 0x%" PRIx32 " (sz = 0x%" PRIx32 ")",section,offset,size);
450
451 /* read initialized data in current segment if any */
452 if (offset<field32(elf,segment->p_filesz))
453 {
454 /* maximal size present in file for the current segment */
455 read_size = MIN(size, field32(elf,segment->p_filesz)-offset);
456 LOG_DEBUG("read elf: size = 0x%" PRIx32 " at 0x%" PRIx32 "",read_size,
457 field32(elf,segment->p_offset) + offset);
458 /* read initialized area of the segment */
459 if ((retval = fileio_seek(&elf->fileio, field32(elf,segment->p_offset) + offset)) != ERROR_OK)
460 {
461 LOG_ERROR("cannot find ELF segment content, seek failed");
462 return retval;
463 }
464 if ((retval = fileio_read(&elf->fileio, read_size, buffer, &really_read)) != ERROR_OK)
465 {
466 LOG_ERROR("cannot read ELF segment content, read failed");
467 return retval;
468 }
469 buffer += read_size;
470 size -= read_size;
471 offset += read_size;
472 *size_read += read_size;
473 /* need more data ? */
474 if (!size)
475 return ERROR_OK;
476 }
477
478 return ERROR_OK;
479 }
480
481 static int image_mot_buffer_complete(image_t *image)
482 {
483 image_mot_t *mot = image->type_private;
484 fileio_t *fileio = &mot->fileio;
485 uint32_t full_address = 0x0;
486 uint32_t cooked_bytes;
487 int i;
488 char lpszLine[1023];
489
490 /* we can't determine the number of sections that we'll have to create ahead of time,
491 * so we locally hold them until parsing is finished */
492 image_section_t section[IMAGE_MAX_SECTIONS];
493
494 mot->buffer = malloc(fileio->size >> 1);
495 cooked_bytes = 0x0;
496 image->num_sections = 0;
497 section[image->num_sections].private = &mot->buffer[cooked_bytes];
498 section[image->num_sections].base_address = 0x0;
499 section[image->num_sections].size = 0x0;
500 section[image->num_sections].flags = 0;
501
502 while (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK)
503 {
504 uint32_t count;
505 uint32_t address;
506 uint32_t record_type;
507 uint32_t checksum;
508 uint8_t cal_checksum = 0;
509 uint32_t bytes_read = 0;
510
511 /* get record type and record length */
512 if (sscanf(&lpszLine[bytes_read], "S%1" SCNx32 "%2" SCNx32 , &record_type, &count) != 2)
513 {
514 return ERROR_IMAGE_FORMAT_ERROR;
515 }
516
517 bytes_read += 4;
518 cal_checksum += (uint8_t)count;
519
520 /* skip checksum byte */
521 count -=1;
522
523 if (record_type == 0)
524 {
525 /* S0 - starting record (optional) */
526 int iValue;
527
528 while (count-- > 0) {
529 sscanf(&lpszLine[bytes_read], "%2x", &iValue);
530 cal_checksum += (uint8_t)iValue;
531 bytes_read += 2;
532 }
533 }
534 else if (record_type >= 1 && record_type <= 3)
535 {
536 switch ( record_type )
537 {
538 case 1:
539 /* S1 - 16 bit address data record */
540 sscanf(&lpszLine[bytes_read], "%4" SCNx32, &address);
541 cal_checksum += (uint8_t)(address >> 8);
542 cal_checksum += (uint8_t)address;
543 bytes_read += 4;
544 count -=2;
545 break;
546
547 case 2:
548 /* S2 - 24 bit address data record */
549 sscanf(&lpszLine[bytes_read], "%6" SCNx32 , &address);
550 cal_checksum += (uint8_t)(address >> 16);
551 cal_checksum += (uint8_t)(address >> 8);
552 cal_checksum += (uint8_t)address;
553 bytes_read += 6;
554 count -=3;
555 break;
556
557 case 3:
558 /* S3 - 32 bit address data record */
559 sscanf(&lpszLine[bytes_read], "%8" SCNx32 , &address);
560 cal_checksum += (uint8_t)(address >> 24);
561 cal_checksum += (uint8_t)(address >> 16);
562 cal_checksum += (uint8_t)(address >> 8);
563 cal_checksum += (uint8_t)address;
564 bytes_read += 8;
565 count -=4;
566 break;
567
568 }
569
570 if (full_address != address)
571 {
572 /* we encountered a nonconsecutive location, create a new section,
573 * unless the current section has zero size, in which case this specifies
574 * the current section's base address
575 */
576 if (section[image->num_sections].size != 0)
577 {
578 image->num_sections++;
579 section[image->num_sections].size = 0x0;
580 section[image->num_sections].flags = 0;
581 section[image->num_sections].private = &mot->buffer[cooked_bytes];
582 }
583 section[image->num_sections].base_address = address;
584 full_address = address;
585 }
586
587 while (count-- > 0)
588 {
589 unsigned value;
590 sscanf(&lpszLine[bytes_read], "%2x", &value);
591 mot->buffer[cooked_bytes] = (uint8_t)value;
592 cal_checksum += (uint8_t)mot->buffer[cooked_bytes];
593 bytes_read += 2;
594 cooked_bytes += 1;
595 section[image->num_sections].size += 1;
596 full_address++;
597 }
598 }
599 else if (record_type == 5)
600 {
601 /* S5 is the data count record, we ignore it */
602 uint32_t dummy;
603
604 while (count-- > 0)
605 {
606 sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &dummy);
607 cal_checksum += (uint8_t)dummy;
608 bytes_read += 2;
609 }
610 }
611 else if (record_type >= 7 && record_type <= 9)
612 {
613 /* S7, S8, S9 - ending records for 32, 24 and 16bit */
614 image->num_sections++;
615
616 /* copy section information */
617 image->sections = malloc(sizeof(image_section_t) * image->num_sections);
618 for (i = 0; i < image->num_sections; i++)
619 {
620 image->sections[i].private = section[i].private;
621 image->sections[i].base_address = section[i].base_address;
622 image->sections[i].size = section[i].size;
623 image->sections[i].flags = section[i].flags;
624 }
625
626 return ERROR_OK;
627 }
628 else
629 {
630 LOG_ERROR("unhandled S19 record type: %i", (int)(record_type));
631 return ERROR_IMAGE_FORMAT_ERROR;
632 }
633
634 /* account for checksum, will always be 0xFF */
635 sscanf(&lpszLine[bytes_read], "%2" SCNx32 , &checksum);
636 cal_checksum += (uint8_t)checksum;
637 bytes_read += 2;
638
639 if ( cal_checksum != 0xFF )
640 {
641 /* checksum failed */
642 LOG_ERROR("incorrect record checksum found in S19 file");
643 return ERROR_IMAGE_CHECKSUM;
644 }
645 }
646
647 LOG_ERROR("premature end of S19 file, no end-of-file record found");
648 return ERROR_IMAGE_FORMAT_ERROR;
649 }
650
651 int image_open(image_t *image, char *url, char *type_string)
652 {
653 int retval = ERROR_OK;
654
655 if ((retval = identify_image_type(image, type_string, url)) != ERROR_OK)
656 {
657 return retval;
658 }
659
660 if (image->type == IMAGE_BINARY)
661 {
662 image_binary_t *image_binary;
663
664 image_binary = image->type_private = malloc(sizeof(image_binary_t));
665
666 if ((retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
667 {
668 return retval;
669 }
670
671 image->num_sections = 1;
672 image->sections = malloc(sizeof(image_section_t));
673 image->sections[0].base_address = 0x0;
674 image->sections[0].size = image_binary->fileio.size;
675 image->sections[0].flags = 0;
676 }
677 else if (image->type == IMAGE_IHEX)
678 {
679 image_ihex_t *image_ihex;
680
681 image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
682
683 if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
684 {
685 return retval;
686 }
687
688 if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
689 {
690 LOG_ERROR("failed buffering IHEX image, check daemon output for additional information");
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 return retval;
704 }
705
706 if ((retval = image_elf_read_headers(image)) != ERROR_OK)
707 {
708 fileio_close(&image_elf->fileio);
709 return retval;
710 }
711 }
712 else if (image->type == IMAGE_MEMORY)
713 {
714 target_t *target = get_target(url);
715
716 if (target == NULL)
717 {
718 LOG_ERROR("target '%s' not defined", url);
719 return ERROR_FAIL;
720 }
721
722 image_memory_t *image_memory;
723
724 image->num_sections = 1;
725 image->sections = malloc(sizeof(image_section_t));
726 image->sections[0].base_address = 0x0;
727 image->sections[0].size = 0xffffffff;
728 image->sections[0].flags = 0;
729
730 image_memory = image->type_private = malloc(sizeof(image_memory_t));
731
732 image_memory->target = target;
733 image_memory->cache = NULL;
734 image_memory->cache_address = 0x0;
735 }
736 else if (image->type == IMAGE_SRECORD)
737 {
738 image_mot_t *image_mot;
739
740 image_mot = image->type_private = malloc(sizeof(image_mot_t));
741
742 if ((retval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
743 {
744 return retval;
745 }
746
747 if ((retval = image_mot_buffer_complete(image)) != ERROR_OK)
748 {
749 LOG_ERROR("failed buffering S19 image, check daemon output for additional information");
750 fileio_close(&image_mot->fileio);
751 return retval;
752 }
753 }
754 else if (image->type == IMAGE_BUILDER)
755 {
756 image->num_sections = 0;
757 image->sections = NULL;
758 image->type_private = NULL;
759 }
760
761 if (image->base_address_set)
762 {
763 /* relocate */
764 int section;
765 for (section = 0; section < image->num_sections; section++)
766 {
767 image->sections[section].base_address += image->base_address;
768 }
769 /* we're done relocating. The two statements below are mainly
770 * for documenation purposes: stop anyone from empirically
771 * thinking they should use these values henceforth. */
772 image->base_address = 0;
773 image->base_address_set = 0;
774 }
775
776 return retval;
777 };
778
779 int image_read_section(image_t *image, int section, uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *size_read)
780 {
781 int retval;
782
783 /* don't read past the end of a section */
784 if (offset + size > image->sections[section].size)
785 {
786 LOG_DEBUG("read past end of section: 0x%8.8" PRIx32 " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "",
787 offset, size, image->sections[section].size);
788 return ERROR_INVALID_ARGUMENTS;
789 }
790
791 if (image->type == IMAGE_BINARY)
792 {
793 image_binary_t *image_binary = image->type_private;
794
795 /* only one section in a plain binary */
796 if (section != 0)
797 return ERROR_INVALID_ARGUMENTS;
798
799 /* seek to offset */
800 if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
801 {
802 return retval;
803 }
804
805 /* return requested bytes */
806 if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
807 {
808 return retval;
809 }
810 }
811 else if (image->type == IMAGE_IHEX)
812 {
813 memcpy(buffer, (uint8_t*)image->sections[section].private + offset, size);
814 *size_read = size;
815
816 return ERROR_OK;
817 }
818 else if (image->type == IMAGE_ELF)
819 {
820 return image_elf_read_section(image, section, offset, size, buffer, size_read);
821 }
822 else if (image->type == IMAGE_MEMORY)
823 {
824 image_memory_t *image_memory = image->type_private;
825 uint32_t address = image->sections[section].base_address + offset;
826
827 *size_read = 0;
828
829 while ((size - *size_read) > 0)
830 {
831 uint32_t size_in_cache;
832
833 if (!image_memory->cache
834 || (address < image_memory->cache_address)
835 || (address >= (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE)))
836 {
837 if (!image_memory->cache)
838 image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);
839
840 if (target_read_buffer(image_memory->target, address & ~(IMAGE_MEMORY_CACHE_SIZE - 1),
841 IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK)
842 {
843 free(image_memory->cache);
844 image_memory->cache = NULL;
845 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
846 }
847 image_memory->cache_address = address & ~(IMAGE_MEMORY_CACHE_SIZE - 1);
848 }
849
850 size_in_cache = (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;
851
852 memcpy(buffer + *size_read,
853 image_memory->cache + (address - image_memory->cache_address),
854 (size_in_cache > size) ? size : size_in_cache
855 );
856
857 *size_read += (size_in_cache > size) ? size : size_in_cache;
858 address += (size_in_cache > size) ? size : size_in_cache;
859 }
860 }
861 else if (image->type == IMAGE_SRECORD)
862 {
863 memcpy(buffer, (uint8_t*)image->sections[section].private + offset, size);
864 *size_read = size;
865
866 return ERROR_OK;
867 }
868 else if (image->type == IMAGE_BUILDER)
869 {
870 memcpy(buffer, (uint8_t*)image->sections[section].private + offset, size);
871 *size_read = size;
872
873 return ERROR_OK;
874 }
875
876 return ERROR_OK;
877 }
878
879 int image_add_section(image_t *image, uint32_t base, uint32_t size, int flags, uint8_t *data)
880 {
881 image_section_t *section;
882
883 /* only image builder supports adding sections */
884 if (image->type != IMAGE_BUILDER)
885 return ERROR_INVALID_ARGUMENTS;
886
887 /* see if there's a previous section */
888 if (image->num_sections)
889 {
890 section = &image->sections[image->num_sections - 1];
891
892 /* see if it's enough to extend the last section,
893 * adding data to previous sections or merging is not supported */
894 if (((section->base_address + section->size) == base) && (section->flags == flags))
895 {
896 section->private = realloc(section->private, section->size + size);
897 memcpy((uint8_t*)section->private + section->size, data, size);
898 section->size += size;
899 return ERROR_OK;
900 }
901 }
902
903 /* allocate new section */
904 image->num_sections++;
905 image->sections = realloc(image->sections, sizeof(image_section_t) * image->num_sections);
906 section = &image->sections[image->num_sections - 1];
907 section->base_address = base;
908 section->size = size;
909 section->flags = flags;
910 section->private = malloc(sizeof(uint8_t) * size);
911 memcpy((uint8_t*)section->private, data, size);
912
913 return ERROR_OK;
914 }
915
916 void image_close(image_t *image)
917 {
918 if (image->type == IMAGE_BINARY)
919 {
920 image_binary_t *image_binary = image->type_private;
921
922 fileio_close(&image_binary->fileio);
923 }
924 else if (image->type == IMAGE_IHEX)
925 {
926 image_ihex_t *image_ihex = image->type_private;
927
928 fileio_close(&image_ihex->fileio);
929
930 if (image_ihex->buffer)
931 {
932 free(image_ihex->buffer);
933 image_ihex->buffer = NULL;
934 }
935 }
936 else if (image->type == IMAGE_ELF)
937 {
938 image_elf_t *image_elf = image->type_private;
939
940 fileio_close(&image_elf->fileio);
941
942 if (image_elf->header)
943 {
944 free(image_elf->header);
945 image_elf->header = NULL;
946 }
947
948 if (image_elf->segments)
949 {
950 free(image_elf->segments);
951 image_elf->segments = NULL;
952 }
953 }
954 else if (image->type == IMAGE_MEMORY)
955 {
956 image_memory_t *image_memory = image->type_private;
957
958 if (image_memory->cache)
959 {
960 free(image_memory->cache);
961 image_memory->cache = NULL;
962 }
963 }
964 else if (image->type == IMAGE_SRECORD)
965 {
966 image_mot_t *image_mot = image->type_private;
967
968 fileio_close(&image_mot->fileio);
969
970 if (image_mot->buffer)
971 {
972 free(image_mot->buffer);
973 image_mot->buffer = NULL;
974 }
975 }
976 else if (image->type == IMAGE_BUILDER)
977 {
978 int i;
979
980 for (i = 0; i < image->num_sections; i++)
981 {
982 free(image->sections[i].private);
983 image->sections[i].private = NULL;
984 }
985 }
986
987 if (image->type_private)
988 {
989 free(image->type_private);
990 image->type_private = NULL;
991 }
992
993 if (image->sections)
994 {
995 free(image->sections);
996 image->sections = NULL;
997 }
998 }
999
1000 int image_calculate_checksum(uint8_t* buffer, uint32_t nbytes, uint32_t* checksum)
1001 {
1002 uint32_t crc = 0xffffffff;
1003 LOG_DEBUG("Calculating checksum");
1004
1005 uint32_t crc32_table[256];
1006
1007 /* Initialize the CRC table and the decoding table. */
1008 int i, j;
1009 unsigned int c;
1010 for (i = 0; i < 256; i++)
1011 {
1012 /* as per gdb */
1013 for (c = i << 24, j = 8; j > 0; --j)
1014 c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
1015 crc32_table[i] = c;
1016 }
1017
1018 while (nbytes>0)
1019 {
1020 int run = nbytes;
1021 if (run>32768)
1022 {
1023 run = 32768;
1024 }
1025 nbytes -= run;
1026 while (run--)
1027 {
1028 /* as per gdb */
1029 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
1030 }
1031 keep_alive();
1032 }
1033
1034 LOG_DEBUG("Calculating checksum done");
1035
1036 *checksum = crc;
1037 return ERROR_OK;
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)