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

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)