1f65e3ffb2599105ac117a04ce0705c449fae272
[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 int image_ihex_buffer_complete(image_t *image)
47 {
48 image_ihex_t *ihex = image->type_private;
49 fileio_t *fileio = &ihex->fileio;
50 u32 raw_bytes_read, raw_bytes;
51 int retval;
52 u32 full_address = 0x0;
53 char *buffer = malloc(fileio->size);
54 u32 cooked_bytes;
55 int i;
56
57 /* we can't determine the number of sections that we'll have to create ahead of time,
58 * so we locally hold them until parsing is finished */
59 image_section_t section[IMAGE_MAX_SECTIONS];
60
61 if ((retval = fileio_read(fileio, fileio->size, (u8*)buffer, &raw_bytes_read)) != ERROR_OK)
62 {
63 free(buffer);
64 ERROR("failed buffering IHEX file, read failed");
65 return ERROR_FILEIO_OPERATION_FAILED;
66 }
67
68 if (raw_bytes_read != fileio->size)
69 {
70 free(buffer);
71 ERROR("failed buffering complete IHEX file, only partially read");
72 return ERROR_FILEIO_OPERATION_FAILED;
73 }
74
75 ihex->buffer = malloc(fileio->size >> 1);
76 raw_bytes = 0x0;
77 cooked_bytes = 0x0;
78 image->num_sections = 0;
79 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
80 section[image->num_sections].base_address = 0x0;
81 section[image->num_sections].size = 0x0;
82 section[image->num_sections].flags = 0;
83 while (raw_bytes < raw_bytes_read)
84 {
85 u32 count;
86 u32 address;
87 u32 record_type;
88 u32 checksum;
89
90 if (sscanf(&buffer[raw_bytes], ":%2x%4x%2x", &count, &address, &record_type) != 3)
91 {
92 return ERROR_IMAGE_FORMAT_ERROR;
93 }
94 raw_bytes += 9;
95
96 if (record_type == 0) /* Data Record */
97 {
98 if ((full_address & 0xffff) != address)
99 {
100 /* we encountered a nonconsecutive location, create a new section,
101 * unless the current section has zero size, in which case this specifies
102 * the current section's base address
103 */
104 if (section[image->num_sections].size != 0)
105 {
106 image->num_sections++;
107 section[image->num_sections].size = 0x0;
108 section[image->num_sections].flags = 0;
109 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
110 }
111 section[image->num_sections].base_address =
112 (full_address & 0xffff0000) | address;
113 full_address = (full_address & 0xffff0000) | address;
114 }
115
116 while (count-- > 0)
117 {
118 sscanf(&buffer[raw_bytes], "%2hhx", &ihex->buffer[cooked_bytes]);
119 raw_bytes += 2;
120 cooked_bytes += 1;
121 section[image->num_sections].size += 1;
122 full_address++;
123 }
124 }
125 else if (record_type == 1) /* End of File Record */
126 {
127 /* finish the current section */
128 image->num_sections++;
129
130 /* copy section information */
131 image->sections = malloc(sizeof(image_section_t) * image->num_sections);
132 for (i = 0; i < image->num_sections; i++)
133 {
134 image->sections[i].private = section[i].private;
135 image->sections[i].base_address = section[i].base_address +
136 ((image->base_address_set) ? image->base_address : 0);
137 image->sections[i].size = section[i].size;
138 image->sections[i].flags = section[i].flags;
139 }
140
141 free(buffer);
142 return ERROR_OK;
143 }
144 else if (record_type == 4) /* Extended Linear Address Record */
145 {
146 u16 upper_address;
147
148 sscanf(&buffer[raw_bytes], "%4hx", &upper_address);
149 raw_bytes += 4;
150
151 if ((full_address >> 16) != upper_address)
152 {
153 /* we encountered a nonconsecutive location, create a new section,
154 * unless the current section has zero size, in which case this specifies
155 * the current section's base address
156 */
157 if (section[image->num_sections].size != 0)
158 {
159 image->num_sections++;
160 section[image->num_sections].size = 0x0;
161 section[image->num_sections].flags = 0;
162 section[image->num_sections].private = &ihex->buffer[cooked_bytes];
163 }
164 section[image->num_sections].base_address =
165 (full_address & 0xffff) | (upper_address << 16);
166 full_address = (full_address & 0xffff) | (upper_address << 16);
167 }
168 }
169 else if (record_type == 5) /* Start Linear Address Record */
170 {
171 u32 start_address;
172
173 sscanf(&buffer[raw_bytes], "%8x", &start_address);
174 raw_bytes += 8;
175
176 image->start_address_set = 1;
177 image->start_address = be_to_h_u32((u8*)&start_address);
178 }
179 else
180 {
181 free(buffer);
182 ERROR("unhandled IHEX record type: %i", record_type);
183 return ERROR_IMAGE_FORMAT_ERROR;
184 }
185
186 sscanf(&buffer[raw_bytes], "%2x", &checksum);
187 raw_bytes += 2;
188
189 /* consume new-line character(s) */
190 if ((buffer[raw_bytes] == '\n') || (buffer[raw_bytes] == '\r'))
191 raw_bytes++;
192
193 if ((buffer[raw_bytes] == '\n') || (buffer[raw_bytes] == '\r'))
194 raw_bytes++;
195 }
196
197 free(buffer);
198 ERROR("premature end of IHEX file, no end-of-file record found");
199 return ERROR_IMAGE_FORMAT_ERROR;
200 }
201
202 int image_elf_read_headers(image_t *image)
203 {
204 image_elf_t *elf = image->type_private;
205 u32 read_bytes;
206 u32 i,j;
207 int retval;
208
209 elf->header = malloc(sizeof(Elf32_Ehdr));
210
211 if ((retval = fileio_read(&elf->fileio, sizeof(Elf32_Ehdr), (u8*)elf->header, &read_bytes)) != ERROR_OK)
212 {
213 ERROR("cannot read ELF file header, read failed");
214 return ERROR_FILEIO_OPERATION_FAILED;
215 }
216 if (read_bytes != sizeof(Elf32_Ehdr))
217 {
218 ERROR("cannot read ELF file header, only partially read");
219 return ERROR_FILEIO_OPERATION_FAILED;
220 }
221
222 if (strncmp((char*)elf->header->e_ident,ELFMAG,SELFMAG)!=0)
223 {
224 ERROR("invalid ELF file, bad magic number");
225 return ERROR_IMAGE_FORMAT_ERROR;
226 }
227 if (elf->header->e_ident[EI_CLASS]!=ELFCLASS32)
228 {
229 ERROR("invalid ELF file, only 32bits files are supported");
230 return ERROR_IMAGE_FORMAT_ERROR;
231 }
232
233
234 elf->endianness = elf->header->e_ident[EI_DATA];
235 if ((elf->endianness==ELFDATANONE)
236 ||(elf->endianness>=ELFDATANUM))
237 {
238 ERROR("invalid ELF file, unknown endianess setting");
239 return ERROR_IMAGE_FORMAT_ERROR;
240 }
241
242 elf->segment_count = field16(elf,elf->header->e_phnum);
243 if (elf->segment_count==0)
244 {
245 ERROR("invalid ELF file, no program headers");
246 return ERROR_IMAGE_FORMAT_ERROR;
247 }
248
249 elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr));
250
251 if ((retval = fileio_read(&elf->fileio, elf->segment_count*sizeof(Elf32_Phdr), (u8*)elf->segments, &read_bytes)) != ERROR_OK)
252 {
253 ERROR("cannot read ELF segment headers, read failed");
254 return retval;
255 }
256 if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr))
257 {
258 ERROR("cannot read ELF segment headers, only partially read");
259 return ERROR_FILEIO_OPERATION_FAILED;
260 }
261
262 /* count useful segments (loadable) */
263 image->num_sections = 0;
264 for (i=0;i<elf->segment_count;i++)
265 if (field32(elf,elf->segments[i].p_type) == PT_LOAD)
266 image->num_sections++;
267 /* alloc and fill sections array with loadable segments */
268 image->sections = malloc(image->num_sections * sizeof(image_section_t));
269 for (i=0,j=0;i<elf->segment_count;i++)
270 {
271 if (field32(elf,elf->segments[i].p_type) == PT_LOAD)
272 {
273 image->sections[j].size = field32(elf,elf->segments[i].p_memsz);
274 image->sections[j].base_address = field32(elf,elf->segments[i].p_vaddr);
275 image->sections[j].private = &elf->segments[i];
276 image->sections[j].flags = field32(elf,elf->segments[i].p_flags);
277 j++;
278 }
279 }
280
281 image->start_address_set = 1;
282 image->start_address = field32(elf,elf->header->e_entry);
283
284 return ERROR_OK;
285 }
286
287 int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
288 {
289 image_elf_t *elf = image->type_private;
290 Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;
291 u32 read_size,really_read;
292 int retval;
293
294 *size_read = 0;
295
296 DEBUG("load segment %d at 0x%x (sz=0x%x)",section,offset,size);
297
298 /* read initialized data in current segment if any */
299 if (offset<field32(elf,segment->p_filesz))
300 {
301 /* maximal size present in file for the current segment */
302 read_size = MIN(size, field32(elf,segment->p_filesz)-offset);
303 DEBUG("read elf: size = 0x%x at 0x%x",read_size,
304 field32(elf,segment->p_offset)+offset);
305 /* read initialized area of the segment */
306 if ((retval = fileio_seek(&elf->fileio, field32(elf,segment->p_offset)+offset)) != ERROR_OK)
307 {
308 ERROR("cannot find ELF segment content, seek failed");
309 return retval;
310 }
311 if ((retval = fileio_read(&elf->fileio, read_size, buffer, &really_read)) != ERROR_OK)
312 {
313 ERROR("cannot read ELF segment content, read failed");
314 return retval;
315 }
316 buffer += read_size;
317 size -= read_size;
318 offset += read_size;
319 *size_read += read_size;
320 /* need more data ? */
321 if (!size)
322 return ERROR_OK;
323 }
324 /* if there is remaining zeroed area in current segment */
325 if (offset<field32(elf,segment->p_memsz))
326 {
327 /* fill zeroed part (BSS) of the segment */
328 read_size = MIN(size, field32(elf,segment->p_memsz)-offset);
329 DEBUG("zero fill: size = 0x%x",read_size);
330 memset(buffer,0,read_size);
331 *size_read += read_size;
332 }
333
334 return ERROR_OK;
335 }
336
337 int image_open(image_t *image, void *source, enum fileio_access access)
338 {
339 int retval = ERROR_OK;
340
341 if (image->type == IMAGE_BINARY)
342 {
343 image_binary_t *image_binary;
344 char *url = source;
345
346 image_binary = image->type_private = malloc(sizeof(image_binary_t));
347
348 if ((retval = fileio_open(&image_binary->fileio, url, access, FILEIO_BINARY)) != ERROR_OK)
349 {
350 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
351 ERROR(image->error_str);
352 return retval;
353 }
354
355 image->num_sections = 1;
356 image->sections = malloc(sizeof(image_section_t));
357 image->sections[0].base_address = 0x0;
358 image->sections[0].size = image_binary->fileio.size;
359 image->sections[0].flags = 0;
360
361 if (image->base_address_set == 1)
362 image->sections[0].base_address = image->base_address;
363
364 return ERROR_OK;
365 }
366 else if (image->type == IMAGE_IHEX)
367 {
368 image_ihex_t *image_ihex;
369 char *url = source;
370
371 if (access != FILEIO_READ)
372 {
373 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
374 "can't open IHEX file for writing");
375 ERROR(image->error_str);
376 return ERROR_FILEIO_ACCESS_NOT_SUPPORTED;
377 }
378
379 image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
380
381 if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
382 {
383 strncpy(image->error_str, image_ihex->fileio.error_str, IMAGE_MAX_ERROR_STRING);
384 ERROR(image->error_str);
385 return retval;
386 }
387
388 if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
389 {
390 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
391 "failed buffering IHEX image, check daemon output for additional information");
392 ERROR(image->error_str);
393 fileio_close(&image_ihex->fileio);
394 return retval;
395 }
396 }
397 else if (image->type == IMAGE_ELF)
398 {
399 image_elf_t *image_elf;
400 char *url = source;
401
402 image_elf = image->type_private = malloc(sizeof(image_elf_t));
403
404 if ((retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
405 {
406 strncpy(image->error_str, image_elf->fileio.error_str, IMAGE_MAX_ERROR_STRING);
407 ERROR(image->error_str);
408 return retval;
409 }
410
411 if ((retval = image_elf_read_headers(image)) != ERROR_OK)
412 {
413 snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
414 "failed to read ELF headers, check daemon output for additional information");
415 ERROR(image->error_str);
416 fileio_close(&image_elf->fileio);
417 return retval;
418 }
419 }
420 else if (image->type == IMAGE_MEMORY)
421 {
422 image_memory_t *image_memory;
423 target_t *target = source;
424
425 image_memory = image->type_private = malloc(sizeof(image_memory_t));
426
427 image_memory->target = target;
428 }
429
430 return retval;
431 };
432
433 int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
434 {
435 int retval;
436
437 if (image->type == IMAGE_BINARY)
438 {
439 image_binary_t *image_binary = image->type_private;
440
441 /* only one section in a plain binary */
442 if (section != 0)
443 return ERROR_INVALID_ARGUMENTS;
444
445 if ((offset > image->sections[0].size) || (offset + size > image->sections[0].size))
446 return ERROR_INVALID_ARGUMENTS;
447
448 /* seek to offset */
449 if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
450 {
451 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
452 return retval;
453 }
454
455 /* return requested bytes */
456 if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
457 {
458 strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
459 return retval;
460 }
461 }
462 else if (image->type == IMAGE_IHEX)
463 {
464 memcpy(buffer, (u8*)image->sections[section].private + offset, size);
465 *size_read = size;
466 image->error_str[0] = '\0';
467
468 return ERROR_OK;
469 }
470 else if (image->type == IMAGE_ELF)
471 {
472 return image_elf_read_section(image, section, offset, size, buffer, size_read);
473 }
474 else if (image->type == IMAGE_MEMORY)
475 {
476 /* TODO: handle target memory pseudo image */
477 }
478
479 return ERROR_OK;
480 }
481
482 int image_close(image_t *image)
483 {
484 if (image->type == IMAGE_BINARY)
485 {
486 image_binary_t *image_binary = image->type_private;
487
488 fileio_close(&image_binary->fileio);
489 }
490 else if (image->type == IMAGE_IHEX)
491 {
492 image_ihex_t *image_ihex = image->type_private;
493
494 fileio_close(&image_ihex->fileio);
495
496 if (image_ihex->section_pointer)
497 free(image_ihex->section_pointer);
498
499 if (image_ihex->buffer)
500 free(image_ihex->buffer);
501 }
502 else if (image->type == IMAGE_ELF)
503 {
504 image_elf_t *image_elf = image->type_private;
505
506 fileio_close(&image_elf->fileio);
507
508 if (image_elf->header)
509 free(image_elf->header);
510
511 if (image_elf->segments)
512 free(image_elf->segments);
513 }
514 else if (image->type == IMAGE_MEMORY)
515 {
516 /* do nothing for now */
517 }
518
519 if (image->type_private)
520 free(image->type_private);
521
522 if (image->sections)
523 free(image->sections);
524
525 return ERROR_OK;
526 }
527
528 int identify_image_type(image_type_t *type, char *type_string)
529 {
530 if (type_string)
531 {
532 if (!strcmp(type_string, "bin"))
533 {
534 *type = IMAGE_BINARY;
535 }
536 else if (!strcmp(type_string, "ihex"))
537 {
538 *type = IMAGE_IHEX;
539 }
540 else if (!strcmp(type_string, "elf"))
541 {
542 *type = IMAGE_ELF;
543 }
544 else
545 {
546 return ERROR_IMAGE_TYPE_UNKNOWN;
547 }
548 }
549 else
550 {
551 *type = IMAGE_BINARY;
552 }
553
554 return ERROR_OK;
555 }

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)