- added support for pseudo image type "mem", currently only used for etm analysis...
[openocd.git] / src / target / image.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <elf.h>
27
28 #include "image.h"
29
30 #include "types.h"
31 #include "replacements.h"
32 #include "log.h"
33
34 #include "fileio.h"
35 #include "target.h"
36
37 /* convert ELF header field to host endianness */
38 #define field16(elf,field)\
39 ((elf->endianness==ELFDATA2LSB)? \
40 le_to_h_u16((u8*)&field):be_to_h_u16((u8*)&field))
41
42 #define field32(elf,field)\
43 ((elf->endianness==ELFDATA2LSB)? \
44 le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
45
46 static int autodetect_image_type(image_t *image, char *url)
47 {
48 int retval;
49 fileio_t fileio;
50 u32 read_bytes;
51 u8 buffer[9];
52
53 /* read the first 4 bytes of image */
54 if ((retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
55 {
56 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING, "cannot open image: %s", fileio.error_str);
57 ERROR(image->error_str);
58 return retval;
59 }
60 if ((retval = fileio_read(&fileio, 9, buffer, &read_bytes)) != ERROR_OK)
61 {
62 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING, "cannot read image header: %s", fileio.error_str);
63 ERROR(image->error_str);
64 return ERROR_FILEIO_OPERATION_FAILED;
65 }
66 if (read_bytes != 9)
67 {
68 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING, "cannot read image, only partially read");
69 ERROR(image->error_str);
70 return ERROR_FILEIO_OPERATION_FAILED;
71 }
72 fileio_close(&fileio);
73
74 /* check header against known signatures */
75 if (strncmp((char*)buffer,ELFMAG,SELFMAG)==0)
76 {
77 DEBUG("ELF image detected.");
78 image->type = IMAGE_ELF;
79 }
80 else if ((buffer[0]==':') /* record start byte */
81 &&(isxdigit(buffer[1]))
82 &&(isxdigit(buffer[2]))
83 &&(isxdigit(buffer[3]))
84 &&(isxdigit(buffer[4]))
85 &&(isxdigit(buffer[5]))
86 &&(isxdigit(buffer[6]))
87 &&(buffer[7]=='0') /* record type : 00 -> 05 */
88 &&(buffer[8]>='0')&&(buffer[8]<'6'))
89 {
90 DEBUG("IHEX image detected.");
91 image->type = IMAGE_IHEX;
92 }
93 else
94 {
95 image->type = IMAGE_BINARY;
96 }
97
98 return ERROR_OK;
99 }
100
101 int identify_image_type(image_t *image, char *type_string, char *url)
102 {
103 if (type_string)
104 {
105 if (!strcmp(type_string, "bin"))
106 {
107 image->type = IMAGE_BINARY;
108 }
109 else if (!strcmp(type_string, "ihex"))
110 {
111 image->type = IMAGE_IHEX;
112 }
113 else if (!strcmp(type_string, "elf"))
114 {
115 image->type = IMAGE_ELF;
116 }
117 else if (!strcmp(type_string, "mem"))
118 {
119 image->type = IMAGE_MEMORY;
120 }
121 else
122 {
123 return ERROR_IMAGE_TYPE_UNKNOWN;
124 }
125 }
126 else
127 {
128 return autodetect_image_type(image, url);
129 }
130
131 return ERROR_OK;
132 }
133
134 int image_ihex_buffer_complete(image_t *image)
135 {
136 image_ihex_t *ihex = image->type_private;
137 fileio_t *fileio = &ihex->fileio;
138 u32 raw_bytes_read, raw_bytes;
139 int retval;
140 u32 full_address = 0x0;
141 char *buffer = malloc(fileio->size);
142 u32 cooked_bytes;
143 int i;
144
145 /* we can't determine the number of sections that we'll have to create ahead of time,
146 * so we locally hold them until parsing is finished */
147 image_section_t section[IMAGE_MAX_SECTIONS];
148
149 if ((retval = fileio_read(fileio, fileio->size, (u8*)buffer, &raw_bytes_read)) != ERROR_OK)
150 {
151 free(buffer);
152 ERROR("failed buffering IHEX file, read failed");
153 return ERROR_FILEIO_OPERATION_FAILED;
154 }
155
156 if (raw_bytes_read != fileio->size)
157 {
158 free(buffer);
159 ERROR("failed buffering complete IHEX file, only partially read");
160 return ERROR_FILEIO_OPERATION_FAILED;
161 }
162
163 ihex->buffer = malloc(fileio->size >> 1);
164 raw_bytes = 0x0;
165 cooked_bytes = 0x0;
166 image->num_sections = 0;
167 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
168 section[image->num_sections].base_address = 0x0;
169 section[image->num_sections].size = 0x0;
170 section[image->num_sections].flags = 0;
171 while (raw_bytes < raw_bytes_read)
172 {
173 u32 count;
174 u32 address;
175 u32 record_type;
176 u32 checksum;
177
178 if (sscanf(&buffer[raw_bytes], ":%2x%4x%2x", &count, &address, &record_type) != 3)
179 {
180 return ERROR_IMAGE_FORMAT_ERROR;
181 }
182 raw_bytes += 9;
183
184 if (record_type == 0) /* Data Record */
185 {
186 if ((full_address & 0xffff) != address)
187 {
188 /* we encountered a nonconsecutive location, create a new section,
189 * unless the current section has zero size, in which case this specifies
190 * the current section's base address
191 */
192 if (section[image->num_sections].size != 0)
193 {
194 image->num_sections++;
195 section[image->num_sections].size = 0x0;
196 section[image->num_sections].flags = 0;
197 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
198 }
199 section[image->num_sections].base_address =
200 (full_address & 0xffff0000) | address;
201 full_address = (full_address & 0xffff0000) | address;
202 }
203
204 while (count-- > 0)
205 {
206 sscanf(&buffer[raw_bytes], "%2hhx", &ihex->buffer[cooked_bytes]);
207 raw_bytes += 2;
208 cooked_bytes += 1;
209 section[image->num_sections].size += 1;
210 full_address++;
211 }
212 }
213 else if (record_type == 1) /* End of File Record */
214 {
215 /* finish the current section */
216 image->num_sections++;
217
218 /* copy section information */
219 image->sections = malloc(sizeof(image_section_t) * image->num_sections);
220 for (i = 0; i < image->num_sections; i++)
221 {
222 image->sections[i].private = section[i].private;
223 image->sections[i].base_address = section[i].base_address +
224 ((image->base_address_set) ? image->base_address : 0);
225 image->sections[i].size = section[i].size;
226 image->sections[i].flags = section[i].flags;
227 }
228
229 free(buffer);
230 return ERROR_OK;
231 }
232 else if (record_type == 4) /* Extended Linear Address Record */
233 {
234 u16 upper_address;
235
236 sscanf(&buffer[raw_bytes], "%4hx", &upper_address);
237 raw_bytes += 4;
238
239 if ((full_address >> 16) != upper_address)
240 {
241 /* we encountered a nonconsecutive location, create a new section,
242 * unless the current section has zero size, in which case this specifies
243 * the current section's base address
244 */
245 if (section[image->num_sections].size != 0)
246 {
247 image->num_sections++;
248 section[image->num_sections].size = 0x0;
249 section[image->num_sections].flags = 0;
250 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
251 }
252 section[image->num_sections].base_address =
253 (full_address & 0xffff) | (upper_address << 16);
254 full_address = (full_address & 0xffff) | (upper_address << 16);
255 }
256 }
257 else if (record_type == 5) /* Start Linear Address Record */
258 {
259 u32 start_address;
260
261 sscanf(&buffer[raw_bytes], "%8x", &start_address);
262 raw_bytes += 8;
263
264 image->start_address_set = 1;
265 image->start_address = be_to_h_u32((u8*)&start_address);
266 }
267 else
268 {
269 free(buffer);
270 ERROR("unhandled IHEX record type: %i", record_type);
271 return ERROR_IMAGE_FORMAT_ERROR;
272 }
273
274 sscanf(&buffer[raw_bytes], "%2x", &checksum);
275 raw_bytes += 2;
276
277 /* consume new-line character(s) */
278 if ((buffer[raw_bytes] == '\n') || (buffer[raw_bytes] == '\r'))
279 raw_bytes++;
280
281 if ((buffer[raw_bytes] == '\n') || (buffer[raw_bytes] == '\r'))
282 raw_bytes++;
283 }
284
285 free(buffer);
286 ERROR("premature end of IHEX file, no end-of-file record found");
287 return ERROR_IMAGE_FORMAT_ERROR;
288 }
289
290 int image_elf_read_headers(image_t *image)
291 {
292 image_elf_t *elf = image->type_private;
293 u32 read_bytes;
294 u32 i,j;
295 int retval;
296
297 elf->header = malloc(sizeof(Elf32_Ehdr));
298
299 if ((retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (u8*)elf->header, &read_bytes)) != ERROR_OK)
300 {
301 ERROR("cannot read ELF file header, read failed");
302 return ERROR_FILEIO_OPERATION_FAILED;
303 }
304 if (read_bytes != sizeof(Elf32_Ehdr))
305 {
306 ERROR("cannot read ELF file header, only partially read");
307 return ERROR_FILEIO_OPERATION_FAILED;
308 }
309
310 if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG)!=0)
311 {
312 ERROR("invalid ELF file, bad magic number");
313 return ERROR_IMAGE_FORMAT_ERROR;
314 }
315 if (elf->header->e_ident[EI_CLASS]!=ELFCLASS32)
316 {
317 ERROR("invalid ELF file, only 32bits files are supported");
318 return ERROR_IMAGE_FORMAT_ERROR;
319 }
320
321
322 elf->endianness = elf->header->e_ident[EI_DATA];
323 if ((elf->endianness==ELFDATANONE)
324 ||(elf->endianness>=ELFDATANUM))
325 {
326 ERROR("invalid ELF file, unknown endianess setting");
327 return ERROR_IMAGE_FORMAT_ERROR;
328 }
329
330 elf->segment_count = field16(elf,elf->header->e_phnum);
331 if (elf->segment_count==0)
332 {
333 ERROR("invalid ELF file, no program headers");
334 return ERROR_IMAGE_FORMAT_ERROR;
335 }
336
337 elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
338
339 if ((retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), (u8*)elf->segments, &read_bytes)) != ERROR_OK)
340 {
341 ERROR("cannot read ELF segment headers, read failed");
342 return retval;
343 }
344 if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr))
345 {
346 ERROR("cannot read ELF segment headers, only partially read");
347 return ERROR_FILEIO_OPERATION_FAILED;
348 }
349
350 /* count useful segments (loadable) */
351 image->num_sections = 0;
352 for (i=0;i<elf->segment_count;i++)
353 if (field32(elf,elf->segments[i].p_type) == PT_LOAD)
354 image->num_sections++;
355 /* alloc and fill sections array with loadable segments */
356 image->sections = malloc(image->num_sections * sizeof(image_section_t));
357 for (i=0,j=0;i<elf->segment_count;i++)
358 {
359 if (field32(elf,elf->segments[i].p_type) == PT_LOAD)
360 {
361 image->sections[j].size = field32(elf,elf->segments[i].p_memsz);
362 image->sections[j].base_address = field32(elf,elf->segments[i].p_vaddr);
363 image->sections[j].private = &elf->segments[i];
364 image->sections[j].flags = field32(elf,elf->segments[i].p_flags);
365 j++;
366 }
367 }
368
369 image->start_address_set = 1;
370 image->start_address = field32(elf,elf->header->e_entry);
371
372 return ERROR_OK;
373 }
374
375 int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
376 {
377 image_elf_t *elf = image->type_private;
378 Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
379 u32 read_size,really_read;
380 int retval;
381
382 *size_read = 0;
383
384 DEBUG("load segment %d at 0x%x (sz=0x%x)",section,offset,size);
385
386 /* read initialized data in current segment if any */
387 if (offset<field32(elf,segment->p_filesz))
388 {
389 /* maximal size present in file for the current segment */
390 read_size = MIN(size, field32(elf,segment->p_filesz)-offset);
391 DEBUG("read elf: size = 0x%x at 0x%x",read_size,
392 field32(elf,segment->p_offset)+offset);
393 /* read initialized area of the segment */
394 if ((retval = fileio_seek(&elf->fileio, field32(elf,segment->p_offset)+offset)) != ERROR_OK)
395 {
396 ERROR("cannot find ELF segment content, seek failed");
397 return retval;
398 }
399 if ((retval = fileio_read(&elf->fileio, read_size, buffer, &really_read)) != ERROR_OK)
400 {
401 ERROR("cannot read ELF segment content, read failed");
402 return retval;
403 }
404 buffer += read_size;
405 size -= read_size;
406 offset += read_size;
407 *size_read += read_size;
408 /* need more data ? */
409 if (!size)
410 return ERROR_OK;
411 }
412 /* if there is remaining zeroed area in current segment */
413 if (offset<field32(elf,segment->p_memsz))
414 {
415 /* fill zeroed part (BSS) of the segment */
416 read_size = MIN(size, field32(elf,segment->p_memsz)-offset);
417 DEBUG("zero fill: size = 0x%x",read_size);
418 memset(buffer,0,read_size);
419 *size_read += read_size;
420 }
421
422 return ERROR_OK;
423 }
424
425 int image_open(image_t *image, char *url, char *type_string)
426 {
427 int retval = ERROR_OK;
428
429 if ((retval = identify_image_type(image, type_string, url)) != ERROR_OK)
430 {
431 return retval;
432 }
433
434 if (image->type == IMAGE_BINARY)
435 {
436 image_binary_t *image_binary;
437
438 image_binary = image->type_private = malloc(sizeof(image_binary_t));
439
440 if ((retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
441 {
442 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
443 ERROR(image->error_str);
444 return retval;
445 }
446
447 image->num_sections = 1;
448 image->sections = malloc(sizeof(image_section_t));
449 image->sections[0].base_address = 0x0;
450 image->sections[0].size = image_binary->fileio.size;
451 image->sections[0].flags = 0;
452
453 if (image->base_address_set == 1)
454 image->sections[0].base_address = image->base_address;
455
456 return ERROR_OK;
457 }
458 else if (image->type == IMAGE_IHEX)
459 {
460 image_ihex_t *image_ihex;
461
462 image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
463
464 if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
465 {
466 strncpy(image->error_str, image_ihex->fileio.error_str, IMAGE_MAX_ERROR_STRING);
467 ERROR(image->error_str);
468 return retval;
469 }
470
471 if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
472 {
473 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
474 "failed buffering IHEX image, check daemon output for additional information");
475 ERROR(image->error_str);
476 fileio_close(&image_ihex->fileio);
477 return retval;
478 }
479 }
480 else if (image->type == IMAGE_ELF)
481 {
482 image_elf_t *image_elf;
483
484 image_elf = image->type_private = malloc(sizeof(image_elf_t));
485
486 if ((retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
487 {
488 strncpy(image->error_str, image_elf->fileio.error_str, IMAGE_MAX_ERROR_STRING);
489 ERROR(image->error_str);
490 return retval;
491 }
492
493 if ((retval = image_elf_read_headers(image)) != ERROR_OK)
494 {
495 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
496 "failed to read ELF headers, check daemon output for additional information");
497 ERROR(image->error_str);
498 fileio_close(&image_elf->fileio);
499 return retval;
500 }
501 }
502 else if (image->type == IMAGE_MEMORY)
503 {
504 image_memory_t *image_memory;
505
506 image->num_sections = 1;
507 image->sections = malloc(sizeof(image_section_t));
508 image->sections[0].base_address = 0x0;
509 image->sections[0].size = 0xffffffff;
510 image->sections[0].flags = 0;
511
512 image_memory = image->type_private = malloc(sizeof(image_memory_t));
513
514 image_memory->target = get_target_by_num(strtoul(url, NULL, 0));;
515 image_memory->cache = NULL;
516 image_memory->cache_address = 0x0;
517 }
518
519 return retval;
520 };
521
522 int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
523 {
524 int retval;
525
526 if (image->type == IMAGE_BINARY)
527 {
528 image_binary_t *image_binary = image->type_private;
529
530 /* only one section in a plain binary */
531 if (section != 0)
532 return ERROR_INVALID_ARGUMENTS;
533
534 if ((offset > image->sections[0].size) || (offset + size > image->sections[0].size))
535 return ERROR_INVALID_ARGUMENTS;
536
537 /* seek to offset */
538 if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
539 {
540 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
541 return retval;
542 }
543
544 /* return requested bytes */
545 if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
546 {
547 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
548 return retval;
549 }
550 }
551 else if (image->type == IMAGE_IHEX)
552 {
553 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
554 *size_read = size;
555 image->error_str[0] = '\0';
556
557 return ERROR_OK;
558 }
559 else if (image->type == IMAGE_ELF)
560 {
561 return image_elf_read_section(image, section, offset, size, buffer, size_read);
562 }
563 else if (image->type == IMAGE_MEMORY)
564 {
565 image_memory_t *image_memory = image->type_private;
566 u32 address = image->sections[section].base_address + offset;
567
568 *size_read = 0;
569
570 while ((size - *size_read) > 0)
571 {
572 u32 size_in_cache;
573
574 if (!image_memory->cache
575 || (address < image_memory->cache_address)
576 || (address >= (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE)))
577 {
578 if (!image_memory->cache)
579 image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);
580
581 if (target_read_buffer(image_memory->target, address & ~(IMAGE_MEMORY_CACHE_SIZE - 1),
582 IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK)
583 {
584 free(image_memory->cache);
585 return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;
586 }
587 image_memory->cache_address = address & ~(IMAGE_MEMORY_CACHE_SIZE - 1);
588 }
589
590 size_in_cache = (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;
591
592 memcpy(buffer + *size_read,
593 image_memory->cache + (address - image_memory->cache_address),
594 (size_in_cache > size) ? size : size_in_cache
595 );
596
597 *size_read += (size_in_cache > size) ? size : size_in_cache;
598 address += (size_in_cache > size) ? size : size_in_cache;
599 }
600 }
601
602 return ERROR_OK;
603 }
604
605 int image_close(image_t *image)
606 {
607 if (image->type == IMAGE_BINARY)
608 {
609 image_binary_t *image_binary = image->type_private;
610
611 fileio_close(&image_binary->fileio);
612 }
613 else if (image->type == IMAGE_IHEX)
614 {
615 image_ihex_t *image_ihex = image->type_private;
616
617 fileio_close(&image_ihex->fileio);
618
619 if (image_ihex->buffer)
620 free(image_ihex->buffer);
621 }
622 else if (image->type == IMAGE_ELF)
623 {
624 image_elf_t *image_elf = image->type_private;
625
626 fileio_close(&image_elf->fileio);
627
628 if (image_elf->header)
629 free(image_elf->header);
630
631 if (image_elf->segments)
632 free(image_elf->segments);
633 }
634 else if (image->type == IMAGE_MEMORY)
635 {
636 image_memory_t *image_memory = image->type_private;
637
638 if (image_memory->cache)
639 free(image_memory->cache);
640 }
641
642 if (image->type_private)
643 free(image->type_private);
644
645 if (image->sections)
646 free(image->sections);
647
648 return ERROR_OK;
649 }

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)