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

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)