/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2009 by Franck Hereson *
* franck.hereson@secad.fr *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "image.h"
#include "target.h"
#include <helper/log.h>
/* convert ELF header field to host endianness */
#define field16(elf, field) \
((elf->endianness == ELFDATA2LSB) ? \
le_to_h_u16((uint8_t *)&field) : be_to_h_u16((uint8_t *)&field))
#define field32(elf, field) \
((elf->endianness == ELFDATA2LSB) ? \
le_to_h_u32((uint8_t *)&field) : be_to_h_u32((uint8_t *)&field))
static int autodetect_image_type(struct image *image, const char *url)
{
int retval;
struct fileio fileio;
size_t read_bytes;
uint8_t buffer[9];
/* read the first 4 bytes of image */
retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY);
if (retval != ERROR_OK)
return retval;
retval = fileio_read(&fileio, 9, buffer, &read_bytes);
if (retval == ERROR_OK) {
if (read_bytes != 9)
retval = ERROR_FILEIO_OPERATION_FAILED;
}
fileio_close(&fileio);
if (retval != ERROR_OK)
return retval;
/* check header against known signatures */
if (strncmp((char *)buffer, ELFMAG, SELFMAG) == 0) {
LOG_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')) {
LOG_DEBUG("IHEX image detected.");
image->type = IMAGE_IHEX;
} else if ((buffer[0] == 'S') /* record start byte */
&& (isxdigit(buffer[1]))
&& (isxdigit(buffer[2]))
&& (isxdigit(buffer[3]))
&& (buffer[1] >= '0') && (buffer[1] < '9')) {
LOG_DEBUG("S19 image detected.");
image->type = IMAGE_SRECORD;
} else
image->type = IMAGE_BINARY;
return ERROR_OK;
}
static int identify_image_type(struct image *image, const char *type_string, const 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 if (!strcmp(type_string, "s19"))
image->type = IMAGE_SRECORD;
else if (!strcmp(type_string, "build"))
image->type = IMAGE_BUILDER;
else
return ERROR_IMAGE_TYPE_UNKNOWN;
} else
return autodetect_image_type(image, url);
return ERROR_OK;
}
static int image_ihex_buffer_complete_inner(struct image *image,
char *lpszLine,
struct imagesection *section)
{