1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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. *
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. *
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 ***************************************************************************/
31 #include "replacements.h"
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))
42 #define field32(elf,field)\
43 ((elf->endianness==ELFDATA2LSB)? \
44 le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
46 static int autodetect_image_type(image_t
*image
, char *url
)
53 /* read the first 4 bytes of image */
54 if ((retval
= fileio_open(&fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
56 snprintf(image
->error_str
, IMAGE_MAX_ERROR_STRING
, "cannot open image: %s", fileio
.error_str
);
57 ERROR(image
->error_str
);
60 if ((retval
= fileio_read(&fileio
, 9, buffer
, &read_bytes
)) != ERROR_OK
)
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
;
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
;
72 fileio_close(&fileio
);
74 /* check header against known signatures */
75 if (strncmp((char*)buffer
,ELFMAG
,SELFMAG
)==0)
77 DEBUG("ELF image detected.");
78 image
->type
= IMAGE_ELF
;
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'))
90 DEBUG("IHEX image detected.");
91 image
->type
= IMAGE_IHEX
;
95 image
->type
= IMAGE_BINARY
;
101 int identify_image_type(image_t
*image
, char *type_string
, char *url
)
105 if (!strcmp(type_string
, "bin"))
107 image
->type
= IMAGE_BINARY
;
109 else if (!strcmp(type_string
, "ihex"))
111 image
->type
= IMAGE_IHEX
;
113 else if (!strcmp(type_string
, "elf"))
115 image
->type
= IMAGE_ELF
;
117 else if (!strcmp(type_string
, "mem"))
119 image
->type
= IMAGE_MEMORY
;
123 return ERROR_IMAGE_TYPE_UNKNOWN
;
128 return autodetect_image_type(image
, url
);
134 int image_ihex_buffer_complete(image_t
*image
)
136 image_ihex_t
*ihex
= image
->type_private
;
137 fileio_t
*fileio
= &ihex
->fileio
;
138 u32 raw_bytes_read
, raw_bytes
;
140 u32 full_address
= 0x0;
141 char *buffer
= malloc(fileio
->size
);
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
];
149 if ((retval
= fileio_read(fileio
, fileio
->size
, (u8
*)buffer
, &raw_bytes_read
)) != ERROR_OK
)
152 ERROR("failed buffering IHEX file, read failed");
153 return ERROR_FILEIO_OPERATION_FAILED
;
156 if (raw_bytes_read
!= fileio
->size
)
159 ERROR("failed buffering complete IHEX file, only partially read");
160 return ERROR_FILEIO_OPERATION_FAILED
;
163 ihex
->buffer
= malloc(fileio
->size
>> 1);
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
)
178 if (sscanf(&buffer
[raw_bytes
], ":%2x%4x%2x", &count
, &address
, &record_type
) != 3)
180 return ERROR_IMAGE_FORMAT_ERROR
;
184 if (record_type
== 0) /* Data Record */
186 if ((full_address
& 0xffff) != address
)
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
192 if (section
[image
->num_sections
].size
!= 0)
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
];
199 section
[image
->num_sections
].base_address
=
200 (full_address
& 0xffff0000) | address
;
201 full_address
= (full_address
& 0xffff0000) | address
;
206 sscanf(&buffer
[raw_bytes
], "%2hhx", &ihex
->buffer
[cooked_bytes
]);
209 section
[image
->num_sections
].size
+= 1;
213 else if (record_type
== 1) /* End of File Record */
215 /* finish the current section */
216 image
->num_sections
++;
218 /* copy section information */
219 image
->sections
= malloc(sizeof(image_section_t
) * image
->num_sections
);
220 for (i
= 0; i
< image
->num_sections
; i
++)
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
;
232 else if (record_type
== 4) /* Extended Linear Address Record */
236 sscanf(&buffer
[raw_bytes
], "%4hx", &upper_address
);
239 if ((full_address
>> 16) != upper_address
)
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
245 if (section
[image
->num_sections
].size
!= 0)
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
];
252 section
[image
->num_sections
].base_address
=
253 (full_address
& 0xffff) | (upper_address
<< 16);
254 full_address
= (full_address
& 0xffff) | (upper_address
<< 16);
257 else if (record_type
== 5) /* Start Linear Address Record */
261 sscanf(&buffer
[raw_bytes
], "%8x", &start_address
);
264 image
->start_address_set
= 1;
265 image
->start_address
= be_to_h_u32((u8
*)&start_address
);
270 ERROR("unhandled IHEX record type: %i", record_type
);
271 return ERROR_IMAGE_FORMAT_ERROR
;
274 sscanf(&buffer
[raw_bytes
], "%2x", &checksum
);
277 /* consume new-line character(s) */
278 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
281 if ((buffer
[raw_bytes
] == '\n') || (buffer
[raw_bytes
] == '\r'))
286 ERROR("premature end of IHEX file, no end-of-file record found");
287 return ERROR_IMAGE_FORMAT_ERROR
;
290 int image_elf_read_headers(image_t
*image
)
292 image_elf_t
*elf
= image
->type_private
;
297 elf
->header
= malloc(sizeof(Elf32_Ehdr
));
299 if ((retval
= fileio_read(&elf
->fileio
, sizeof(Elf32_Ehdr
), (u8
*)elf
->header
, &read_bytes
)) != ERROR_OK
)
301 ERROR("cannot read ELF file header, read failed");
302 return ERROR_FILEIO_OPERATION_FAILED
;
304 if (read_bytes
!= sizeof(Elf32_Ehdr
))
306 ERROR("cannot read ELF file header, only partially read");
307 return ERROR_FILEIO_OPERATION_FAILED
;
310 if (strncmp((char*)elf
->header
->e_ident
,ELFMAG
,SELFMAG
)!=0)
312 ERROR("invalid ELF file, bad magic number");
313 return ERROR_IMAGE_FORMAT_ERROR
;
315 if (elf
->header
->e_ident
[EI_CLASS
]!=ELFCLASS32
)
317 ERROR("invalid ELF file, only 32bits files are supported");
318 return ERROR_IMAGE_FORMAT_ERROR
;
322 elf
->endianness
= elf
->header
->e_ident
[EI_DATA
];
323 if ((elf
->endianness
==ELFDATANONE
)
324 ||(elf
->endianness
>=ELFDATANUM
))
326 ERROR("invalid ELF file, unknown endianess setting");
327 return ERROR_IMAGE_FORMAT_ERROR
;
330 elf
->segment_count
= field16(elf
,elf
->header
->e_phnum
);
331 if (elf
->segment_count
==0)
333 ERROR("invalid ELF file, no program headers");
334 return ERROR_IMAGE_FORMAT_ERROR
;
337 elf
->segments
= malloc(elf
->segment_count
*sizeof(Elf32_Phdr
));
339 if ((retval
= fileio_read(&elf
->fileio
, elf
->segment_count
*sizeof(Elf32_Phdr
), (u8
*)elf
->segments
, &read_bytes
)) != ERROR_OK
)
341 ERROR("cannot read ELF segment headers, read failed");
344 if (read_bytes
!= elf
->segment_count
*sizeof(Elf32_Phdr
))
346 ERROR("cannot read ELF segment headers, only partially read");
347 return ERROR_FILEIO_OPERATION_FAILED
;
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
++)
359 if (field32(elf
,elf
->segments
[i
].p_type
) == PT_LOAD
)
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
);
369 image
->start_address_set
= 1;
370 image
->start_address
= field32(elf
,elf
->header
->e_entry
);
375 int image_elf_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
377 image_elf_t
*elf
= image
->type_private
;
378 Elf32_Phdr
*segment
= (Elf32_Phdr
*)image
->sections
[section
].private;
379 u32 read_size
,really_read
;
384 DEBUG("load segment %d at 0x%x (sz=0x%x)",section
,offset
,size
);
386 /* read initialized data in current segment if any */
387 if (offset
<field32(elf
,segment
->p_filesz
))
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
)
396 ERROR("cannot find ELF segment content, seek failed");
399 if ((retval
= fileio_read(&elf
->fileio
, read_size
, buffer
, &really_read
)) != ERROR_OK
)
401 ERROR("cannot read ELF segment content, read failed");
407 *size_read
+= read_size
;
408 /* need more data ? */
412 /* if there is remaining zeroed area in current segment */
413 if (offset
<field32(elf
,segment
->p_memsz
))
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
;
425 int image_open(image_t
*image
, void *source
, char *type_string
)
427 int retval
= ERROR_OK
;
429 if ((retval
= identify_image_type(image
, type_string
, source
)) != ERROR_OK
)
434 if (image
->type
== IMAGE_BINARY
)
436 image_binary_t
*image_binary
;
439 image_binary
= image
->type_private
= malloc(sizeof(image_binary_t
));
441 if ((retval
= fileio_open(&image_binary
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
443 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
444 ERROR(image
->error_str
);
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;
454 if (image
->base_address_set
== 1)
455 image
->sections
[0].base_address
= image
->base_address
;
459 else if (image
->type
== IMAGE_IHEX
)
461 image_ihex_t
*image_ihex
;
464 image_ihex
= image
->type_private
= malloc(sizeof(image_ihex_t
));
466 if ((retval
= fileio_open(&image_ihex
->fileio
, url
, FILEIO_READ
, FILEIO_TEXT
)) != ERROR_OK
)
468 strncpy(image
->error_str
, image_ihex
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
469 ERROR(image
->error_str
);
473 if ((retval
= image_ihex_buffer_complete(image
)) != ERROR_OK
)
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
);
482 else if (image
->type
== IMAGE_ELF
)
484 image_elf_t
*image_elf
;
487 image_elf
= image
->type_private
= malloc(sizeof(image_elf_t
));
489 if ((retval
= fileio_open(&image_elf
->fileio
, url
, FILEIO_READ
, FILEIO_BINARY
)) != ERROR_OK
)
491 strncpy(image
->error_str
, image_elf
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
492 ERROR(image
->error_str
);
496 if ((retval
= image_elf_read_headers(image
)) != ERROR_OK
)
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
);
505 else if (image
->type
== IMAGE_MEMORY
)
507 image_memory_t
*image_memory
;
508 target_t
*target
= source
;
510 image_memory
= image
->type_private
= malloc(sizeof(image_memory_t
));
512 image_memory
->target
= target
;
518 int image_read_section(image_t
*image
, int section
, u32 offset
, u32 size
, u8
*buffer
, u32
*size_read
)
522 if (image
->type
== IMAGE_BINARY
)
524 image_binary_t
*image_binary
= image
->type_private
;
526 /* only one section in a plain binary */
528 return ERROR_INVALID_ARGUMENTS
;
530 if ((offset
> image
->sections
[0].size
) || (offset
+ size
> image
->sections
[0].size
))
531 return ERROR_INVALID_ARGUMENTS
;
534 if ((retval
= fileio_seek(&image_binary
->fileio
, offset
)) != ERROR_OK
)
536 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
540 /* return requested bytes */
541 if ((retval
= fileio_read(&image_binary
->fileio
, size
, buffer
, size_read
)) != ERROR_OK
)
543 strncpy(image
->error_str
, image_binary
->fileio
.error_str
, IMAGE_MAX_ERROR_STRING
);
547 else if (image
->type
== IMAGE_IHEX
)
549 memcpy(buffer
, (u8
*)image
->sections
[section
].private + offset
, size
);
551 image
->error_str
[0] = '\0';
555 else if (image
->type
== IMAGE_ELF
)
557 return image_elf_read_section(image
, section
, offset
, size
, buffer
, size_read
);
559 else if (image
->type
== IMAGE_MEMORY
)
561 /* TODO: handle target memory pseudo image */
567 int image_close(image_t
*image
)
569 if (image
->type
== IMAGE_BINARY
)
571 image_binary_t
*image_binary
= image
->type_private
;
573 fileio_close(&image_binary
->fileio
);
575 else if (image
->type
== IMAGE_IHEX
)
577 image_ihex_t
*image_ihex
= image
->type_private
;
579 fileio_close(&image_ihex
->fileio
);
581 if (image_ihex
->buffer
)
582 free(image_ihex
->buffer
);
584 else if (image
->type
== IMAGE_ELF
)
586 image_elf_t
*image_elf
= image
->type_private
;
588 fileio_close(&image_elf
->fileio
);
590 if (image_elf
->header
)
591 free(image_elf
->header
);
593 if (image_elf
->segments
)
594 free(image_elf
->segments
);
596 else if (image
->type
== IMAGE_MEMORY
)
598 /* do nothing for now */
601 if (image
->type_private
)
602 free(image
->type_private
);
605 free(image
->sections
);
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)