summaryrefslogtreecommitdiff
path: root/src/target/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/target/image.c')
-rw-r--r--src/target/image.c137
1 files changed, 95 insertions, 42 deletions
diff --git a/src/target/image.c b/src/target/image.c
index 1f65e3ff..0cac1c10 100644
--- a/src/target/image.c
+++ b/src/target/image.c
@@ -43,6 +43,94 @@
((elf->endianness==ELFDATA2LSB)? \
le_to_h_u32((u8*)&field):be_to_h_u32((u8*)&field))
+static int autodetect_image_type(image_t *image, char *url)
+{
+ int retval;
+ fileio_t fileio;
+ u32 read_bytes;
+ u8 buffer[9];
+
+ /* read the first 4 bytes of image */
+ if ((retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
+ {
+ snprintf(image->error_str, IMAGE_MAX_ERROR_STRING, "cannot open image: %s", fileio.error_str);
+ ERROR(image->error_str);
+ return retval;
+ }
+ if ((retval = fileio_read(&fileio, 9, buffer, &read_bytes)) != ERROR_OK)
+ {
+ snprintf(image->error_str, IMAGE_MAX_ERROR_STRING, "cannot read image header: %s", fileio.error_str);
+ ERROR(image->error_str);
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+ if (read_bytes != 9)
+ {
+ snprintf(image->error_str, IMAGE_MAX_ERROR_STRING, "cannot read image, only partially read");
+ ERROR(image->error_str);
+ return ERROR_FILEIO_OPERATION_FAILED;
+ }
+ fileio_close(&fileio);
+
+ /* check header against known signatures */
+ if (strncmp((char*)buffer,ELFMAG,SELFMAG)==0)
+ {
+ DEBUG("ELF image detected.");
+ image->type = IMAGE_ELF;
+ }
+ else if ((buffer[0]==':') /* record start byte */
+ &&(isxdigit(buffer[1]))
+ &&(isxdigit(buffer[2]))
+ &&(isxdigit(buffer[3]))
+ &&(isxdigit(buffer[4]))
+ &&(isxdigit(buffer[5]))
+ &&(isxdigit(buffer[6]))
+ &&(buffer[7]=='0') /* record type : 00 -> 05 */
+ &&(buffer[8]>='0')&&(buffer[8]<'6'))
+ {
+ DEBUG("IHEX image detected.");
+ image->type = IMAGE_IHEX;
+ }
+ else
+ {
+ image->type = IMAGE_BINARY;
+ }
+
+ return ERROR_OK;
+}
+
+int identify_image_type(image_t *image, char *type_string, char *url)
+{
+ if (type_string)
+ {
+ if (!strcmp(type_string, "bin"))
+ {
+ image->type = IMAGE_BINARY;
+ }
+ else if (!strcmp(type_string, "ihex"))
+ {
+ image->type = IMAGE_IHEX;
+ }
+ else if (!strcmp(type_string, "elf"))
+ {
+ image->type = IMAGE_ELF;
+ }
+ else if (!strcmp(type_string, "mem"))
+ {
+ image->type = IMAGE_MEMORY;
+ }
+ else
+ {
+ return ERROR_IMAGE_TYPE_UNKNOWN;
+ }
+ }
+ else
+ {
+ return autodetect_image_type(image, url);
+ }
+
+ return ERROR_OK;
+}
+
int image_ihex_buffer_complete(image_t *image)
{
image_ihex_t *ihex = image->type_private;
@@ -334,10 +422,15 @@ int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8
return ERROR_OK;
}
-int image_open(image_t *image, void *source, enum fileio_access access)
+int image_open(image_t *image, void *source, char *type_string)
{
int retval = ERROR_OK;
+ if ((retval = identify_image_type(image, type_string, source)) != ERROR_OK)
+ {
+ return retval;
+ }
+
if (image->type == IMAGE_BINARY)
{
image_binary_t *image_binary;
@@ -345,7 +438,7 @@ int image_open(image_t *image, void *source, enum fileio_access access)
image_binary = image->type_private = malloc(sizeof(image_binary_t));
- if ((retval = fileio_open(&image_binary->fileio, url, access, FILEIO_BINARY)) != ERROR_OK)
+ if ((retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY)) != ERROR_OK)
{
strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
ERROR(image->error_str);
@@ -368,14 +461,6 @@ int image_open(image_t *image, void *source, enum fileio_access access)
image_ihex_t *image_ihex;
char *url = source;
- if (access != FILEIO_READ)
- {
- snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
- "can't open IHEX file for writing");
- ERROR(image->error_str);
- return ERROR_FILEIO_ACCESS_NOT_SUPPORTED;
- }
-
image_ihex = image->type_private = malloc(sizeof(image_ihex_t));
if ((retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT)) != ERROR_OK)
@@ -493,9 +578,6 @@ int image_close(image_t *image)
fileio_close(&image_ihex->fileio);
- if (image_ihex->section_pointer)
- free(image_ihex->section_pointer);
-
if (image_ihex->buffer)
free(image_ihex->buffer);
}
@@ -524,32 +606,3 @@ int image_close(image_t *image)
return ERROR_OK;
}
-
-int identify_image_type(image_type_t *type, char *type_string)
-{
- if (type_string)
- {
- if (!strcmp(type_string, "bin"))
- {
- *type = IMAGE_BINARY;
- }
- else if (!strcmp(type_string, "ihex"))
- {
- *type = IMAGE_IHEX;
- }
- else if (!strcmp(type_string, "elf"))
- {
- *type = IMAGE_ELF;
- }
- else
- {
- return ERROR_IMAGE_TYPE_UNKNOWN;
- }
- }
- else
- {
- *type = IMAGE_BINARY;
- }
-
- return ERROR_OK;
-}