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

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)