/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* 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., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_ELF_H
#include <elf.h>
#endif
#include "image.h"
#include "types.h"
#include "replacements.h"
#include "log.h"
#include "fileio.h"
#include "target.h"
/* convert ELF header field to host endianness */
#define field16(elf,field)\
((elf->endianness==ELFDATA2LSB)? \
le_to_h_u16((u8*)&field):be_to_h_u16((u8*)&field))
#define field32(elf,field)\
((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)
{
return retval;
}
if ((retval = fileio_read(&fileio, 9, buffer, &read_bytes)) != ERROR_OK)
{
return ERROR_FILEIO_OPERATION_FAILED;
}
if (read_bytes != 9)
{
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 if ((buffer[0] == 'S') /* record start byte */
&&(isxdigit(buffer[1]))
&&(isxdigit(buffer[2]))
&&(isxdigit(buffer[3]))
&&(buffer[1] >= '0') && (buffer[1] < '9'))
{
DEBUG("S19 image detected.");
image->type = IMAGE_SRECORD;
}
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 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;
}
int image_ihex_buffer_complete(image_t *image)
{
image_ihex_t *ihex = image->type_private;
fileio_t *fileio = &ihex->fileio;
u32 full_address = 0x0;
u32 cooked_bytes;
int i;
char lpszLine[1023];
/* we can't determine the number of sections that we'll have to create ahead of time,
* so we locally hold them until parsing is finished */
image_section_t section[IMAGE_MAX_SECTIONS];
ihex->buffer = malloc(fileio->size >> 1