- added manpage for OpenOCD (thanks to Uwe Hermann)
[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, void *source, char *type_string)
426 {
427 int retval = ERROR_OK;
428
429 if ((retval = identify_image_type(image, type_string, source)) != ERROR_OK)
430 {
431 return retval;
432 }
433
434 if (image->type == IMAGE_BINARY)
435 {
436 image_binary_t *image_binary;
437 char *url = source;
438
439 image_binary = image->type_private = malloc(sizeof(image_binary_t));
440
441 if ((retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
442 {
443 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
444 ERROR(image->error_str);
445 return retval;
446 }
447
448 image->num_sections = 1;
449 image->sections = malloc(sizeof(image_section_t));
450 image->sections[0].base_address = 0x0;
451 image->sections[0].size = image_binary->fileio.size;
452 image->sections[0].flags = 0;
453
454 if (image->base_address_set == 1)
455 image->sections[0].base_address = image->base_address;
456
457 return ERROR_OK;
458 }
459 else if (image->type == IMAGE_IHEX)
460 {
461 image_ihex_t *image_ihex;
462 char *url = source;
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 char *url = source;
486
487 image_elf = image->type_private = malloc(sizeof(image_elf_t));
488
489 if ((retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
490 {
491 strncpy(image->error_str, image_elf->fileio.error_str, IMAGE_MAX_ERROR_STRING);
492 ERROR(image->error_str);
493 return retval;
494 }
495
496 if ((retval = image_elf_read_headers(image)) != ERROR_OK)
497 {
498 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
499 "failed to read ELF headers, check daemon output for additional information");
500 ERROR(image->error_str);
501 fileio_close(&image_elf->fileio);
502 return retval;
503 }
504 }
505 else if (image->type == IMAGE_MEMORY)
506 {
507 image_memory_t *image_memory;
508 target_t *target = source;
509
510 image_memory = image->type_private = malloc(sizeof(image_memory_t));
511
512 image_memory->target = target;
513 }
514
515 return retval;
516 };
517
518 int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
519 {
520 int retval;
521
522 if (image->type == IMAGE_BINARY)
523 {
524 image_binary_t *image_binary = image->type_private;
525
526 /* only one section in a plain binary */
527 if (section != 0)
528 return ERROR_INVALID_ARGUMENTS;
529
530 if ((offset > image->sections[0].size) || (offset + size > image->sections[0].size))
531 return ERROR_INVALID_ARGUMENTS;
532
533 /* seek to offset */
534 if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
535 {
536 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
537 return retval;
538 }
539
540 /* return requested bytes */
541 if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
542 {
543 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
544 return retval;
545 }
546 }
547 else if (image->type == IMAGE_IHEX)
548 {
549 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
550 *size_read = size;
551 image->error_str[0] = '\0';
552
553 return ERROR_OK;
554 }
555 else if (image->type == IMAGE_ELF)
556 {
557 return image_elf_read_section(image, section, offset, size, buffer, size_read);
558 }
559 else if (image->type == IMAGE_MEMORY)
560 {
561 /* TODO: handle target memory pseudo image */
562 }
563
564 return ERROR_OK;
565 }
566
567 int image_close(image_t *image)
568 {
569 if (image->type == IMAGE_BINARY)
570 {
571 image_binary_t *image_binary = image->type_private;
572
573 fileio_close(&image_binary->fileio);
574 }
575 else if (image->type == IMAGE_IHEX)
576 {
577 image_ihex_t *image_ihex = image->type_private;
578
579 fileio_close(&image_ihex->fileio);
580
581 if (image_ihex->buffer)
582 free(image_ihex->buffer);
583 }
584 else if (image->type == IMAGE_ELF)
585 {
586 image_elf_t *image_elf = image->type_private;
587
588 fileio_close(&image_elf->fileio);
589
590 if (image_elf->header)
591 free(image_elf->header);
592
593 if (image_elf->segments)
594 free(image_elf->segments);
595 }
596 else if (image->type == IMAGE_MEMORY)
597 {
598 /* do nothing for now */
599 }
600
601 if (image->type_private)
602 free(image->type_private);
603
604 if (image->sections)
605 free(image->sections);
606
607 return ERROR_OK;
608 }

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)